Compare commits

..

1 Commits

Author SHA1 Message Date
Roberto Viola
d157685be4 crossqfile issue
https://github.com/mahdize/CrossQFile/issues/3
2023-03-26 17:56:25 +02:00
501 changed files with 5868 additions and 50514 deletions

View File

@@ -4,7 +4,6 @@ name: CI
env:
DISPLAY: ':99'
ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true'
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
@@ -14,18 +13,13 @@ on:
branches: [ master, github-workflow-playground ]
pull_request:
branches: [ master ]
schedule:
- cron: "0 0 * * *"
# schedule:
# - cron: "0 */12 * * *"
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
window-build:
runs-on: windows-latest
strategy:
matrix:
config:
- {python: true}
- {python: false}
steps:
- uses: actions/checkout@v2
@@ -42,7 +36,7 @@ jobs:
with:
repository: cagnulein/qmdnsengine
path: "src/qmdnsengine/"
ref: "zwift"
ref: "zwift"
- uses: actions/checkout@v2
- name: Checkout submodule repo
@@ -60,35 +54,9 @@ jobs:
path: "src/MSIX-Toolkit/"
ref: b82af826d29e93e4c85d34fad8a405b6c49905e7
- uses: actions/checkout@v2
- name: Checkout qHttpServer
uses: actions/checkout@v2
with:
repository: qt-labs/qthttpserver
path: "src/qthttpserver"
- uses: actions/setup-python@v4
with:
python-version: 3.7
- name: download python and paddleocr
run: |
python -VV
python -m pip install --upgrade pip
python -m pip install --upgrade setuptools
python -m pip install "protobuf<=3.20.2,>=3.1.0"
python -m pip install paddlepaddle==2.5.1
python -m pip install paddleocr
python -m pip install imutils
python -m pip install "Pillow<10.0.0"
python -m pip install opencv-python
python -m pip install numpy
python -m pip install pywin32
if: matrix.config.python
- uses: msys2/setup-msys2@v2
with:
install: mingw-w64-x86_64-toolchain mingw-w64-x86_64-qt5-webview
install: mingw-w64-x86_64-toolchain
msystem: mingw64
release: false
@@ -98,7 +66,7 @@ jobs:
cmake-version: '3.20.x'
- name: Install Qt
uses: jurplel/install-qt-action@v3
uses: jurplel/install-qt-action@v2
with:
version: '5.15.2'
host: 'windows'
@@ -107,35 +75,16 @@ jobs:
arch: win64_mingw81
dir: "${{github.workspace}}/qt/"
install-deps: "true"
cache: 'true'
cache-key-prefix: 'install-qt-action-windows'
- name: download 3rd party files for qthttpserver
run: |
cp qHttpServerBin/5.15.2/headers/* src/qthttpserver/src/3rdparty/http-parser/
- name: Build qthttpserver
run: |
cd src\qthttpserver
qmake
make -j8
make install
cd ../..
- name: Secrets
if: github.ref == 'refs/heads/main'
run: |
cd src
echo "#define STRAVA_SECRET_KEY ${{ secrets.strava_secret_key }}" > secret.h
echo "#define SMTP_USERNAME ${{ secrets.smtp_username }}" >> secret.h
echo "#define SMTP_PASSWORD ${{ secrets.smtp_password }}" >> secret.h
echo "#define SMTP_SERVER ${{ secrets.smtp_server }}" >> secret.h
echo "${{ secrets.cesiumkey }}" >> inner_templates/googlemaps/cesium-key.js
cd ..
- name: Build
run: |
qmake
cd src
echo "#define STRAVA_SECRET_KEY ${{ secrets.strava_secret_key }}" > secret.h
echo "#define SMTP_USERNAME ${{ secrets.smtp_username }}" >> secret.h
echo "#define SMTP_PASSWORD ${{ secrets.smtp_password }}" >> secret.h
echo "#define SMTP_SERVER ${{ secrets.smtp_server }}" >> secret.h
cd ..
make -j8
cd src/debug
mkdir output
@@ -143,118 +92,22 @@ jobs:
cp qdomyos-zwift.exe output/
cd output
windeployqt --qmldir ../../ qdomyos-zwift.exe
cp "C:/mingw64/bin/libwinpthread-1.dll" .
cp "C:/mingw64/bin/libgcc_s_seh-1.dll" .
cp "C:/mingw64/bin/libstdc++-6.dll" .
cp "${{github.workspace}}/qt/Qt/5.15.2/mingw81_64/bin/libwinpthread-1.dll" .
cp "${{github.workspace}}/qt/Qt/5.15.2/mingw81_64/bin/libgcc_s_seh-1.dll" .
cp "${{github.workspace}}/qt/Qt/5.15.2/mingw81_64/bin/libstdc++-6.dll" .
cp ../../../icons/iOS/iTunesArtwork@2x.png .
cp ../../AppxManifest.xml .
cp ../../windows/*.py .
cp ../../windows/*.bat .
cp ../../../windows_openssl/*.* .
mkdir adb
mkdir python
Copy-Item -Path C:\hostedtoolcache\windows\Python\3.7.9\x64 -Destination python -Recurse
cp ../../adb/* adb/
cd ..
cd appx
#../../MSIX-Toolkit/WindowsSDK/10/10.0.20348.0/x64/makeappx.exe pack /d ../output/ /p qz
if: matrix.config.python
- name: Build without python
run: |
qmake
make -j8
cd src/debug
mkdir output
mkdir appx
cp qdomyos-zwift.exe output/
cd output
windeployqt --qmldir ../../ qdomyos-zwift.exe
cp "C:/mingw64/bin/libwinpthread-1.dll" .
cp "C:/mingw64/bin/libgcc_s_seh-1.dll" .
cp "C:/mingw64/bin/libstdc++-6.dll" .
cp ../../../icons/iOS/iTunesArtwork@2x.png .
cp ../../AppxManifest.xml .
cp ../../../windows_openssl/*.* .
mkdir adb
cp ../../adb/* adb/
cd ..
cd appx
#../../MSIX-Toolkit/WindowsSDK/10/10.0.20348.0/x64/makeappx.exe pack /d ../output/ /p qz
if: matrix.config.python == false
- name: patching qt for bluetooth
run: cp qt-patches/windows/5.15.2/binary/mingw64/*.* ${{ github.workspace }}/src/debug/output/
- name: Zip artifact for deployment
run: Compress-Archive src/debug/output windows-binary.zip
if: matrix.config.python
- name: Zip artifact for deployment
run: Compress-Archive src/debug/output windows-binary-no-python.zip
if: ${{ ! matrix.config.python }}
#../../MSIX-Toolkit/WindowsSDK/10/10.0.20348.0/x64/makeappx.exe pack /d ../output/ /p qz
- name: Archive windows binary
uses: actions/upload-artifact@v2
with:
name: windows-binary
path: windows-binary.zip
if: matrix.config.python
- name: Archive windows binary
uses: actions/upload-artifact@v2
with:
name: windows-binary-no-python
path: windows-binary-no-python.zip
if: ${{ ! matrix.config.python }}
# - name: Exit if not on master branch
# if: github.ref == 'refs/heads/main'
# run: exit 1
# - uses: actions/checkout@v3
# with:
# fetch-depth: 0 # Required due to the way Git works, without it this action won't be able to find any or the correct tags
# - name: Get previous tag
# id: previoustag
# uses: 'WyriHaximus/github-action-get-previous-tag@v1'
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# - name: Create Release
# if: ${{ ! matrix.config.python }}
# id: create_release
# uses: actions/create-release@v1
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# with:
# tag_name: ${{ steps.previoustag.outputs.tag }}
# release_name: Release ${{ steps.previoustag.outputs.tag }}
# draft: false
# prerelease: false
# - name: upload windows artifact
# uses: actions/upload-release-asset@v1
# if: ${{ ! matrix.config.python }}
# env:
# GITHUB_TOKEN: ${{ github.token }}
# with:
# upload_url: ${{ steps.create_release.outputs.upload_url }}
# asset_path: release.zip
# asset_name: windows-binary-no-python.zip
# asset_content_type: application/zip
# - name: upload windows artifact
# uses: actions/upload-release-asset@v1
# if: ${{ matrix.config.python }}
# env:
# GITHUB_TOKEN: ${{ github.token }}
# with:
# upload_url: ${{ steps.create_release.outputs.upload_url }}
# asset_path: release.zip
# asset_name: windows-binary.zip
# asset_content_type: application/zip
path: src/debug/output
# window-steam-build:
# runs-on: windows-latest
@@ -306,7 +159,6 @@ jobs:
# echo "#define SMTP_USERNAME ${{ secrets.smtp_username }}" >> secret.h
# echo "#define SMTP_PASSWORD ${{ secrets.smtp_password }}" >> secret.h
# echo "#define SMTP_SERVER ${{ secrets.smtp_server }}" >> secret.h
# echo "${{ secrets.cesiumkey }}" >> inner_templates/googlemaps/cesium-key.js
# echo "#define STEAM_STORE" >> secret.h
# cd ..
# make -j8
@@ -341,19 +193,6 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- name: release
uses: actions/create-release@v1
if: startsWith(github.ref, 'refs/tags/')
id: create_release
with:
draft: false
prerelease: false
release_name: ${{ steps.version.outputs.version }}
tag_name: ${{ github.ref }}
body_path: CHANGELOG.md
env:
GITHUB_TOKEN: ${{ github.token }}
# - name: Cache Qt Linux Desktop
# id: cache-qt-linux-desktop
# uses: actions/cache@v1
@@ -398,36 +237,15 @@ jobs:
path: "tst/googletest/"
ref: "release-1.12.1"
- uses: actions/checkout@v2
- name: Checkout qHttpServer
uses: actions/checkout@v2
with:
repository: qt-labs/qthttpserver
path: "src/qthttpserver"
- name: Install packages required to run QZ inside workflow
run: sudo apt update -y && sudo apt-get install -y qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools qtquickcontrols2-5-dev libqt5bluetooth5 libqt5widgets5 libqt5positioning5 libqt5xml5 qtconnectivity5-dev qtpositioning5-dev libqt5charts5-dev libqt5charts5 libqt5networkauth5-dev libqt5websockets5* libxcb-randr0-dev libxcb-xtest0-dev libxcb-xinerama0-dev libxcb-shape0-dev libxcb-xkb-dev
- name: Install Qt
uses: jurplel/install-qt-action@v3
uses: jurplel/install-qt-action@v2
with:
version: '5.15.2'
host: 'linux'
modules: 'qtnetworkauth qtcharts'
cache: 'true'
cache-key-prefix: 'install-qt-action-linux'
- name: download 3rd party files for qthttpserver
run: |
cp qHttpServerBin/5.15.2/headers/* src/qthttpserver/src/3rdparty/http-parser/
- name: Build qthttpserver
run: |
cd src/qthttpserver
qmake
make -j8
make install
cd ../..
- name: Compile Linux Desktop
run: qmake; make -j8
@@ -530,12 +348,30 @@ jobs:
sudo apt-get install -y xvfb
Xvfb -ac ${{ env.DISPLAY }} -screen 0 1280x780x24 &
- name: Checkout repository
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
# This token is provided by Actions, you do not need to create your own token
token: ${{ secrets.GITHUB_TOKEN }}
submodules: recursive # or 'true' if you want to check out only immediate submodules
repository: bluetiger9/SmtpClient-for-Qt
path: "src/smtpclient/"
ref: 3fa4a0fe5797070339422cf18b5e9ed8dcb91f9c
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
repository: cagnulein/qmdnsengine
path: "src/qmdnsengine/"
ref: "zwift"
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
repository: google/googletest
path: "tst/googletest/"
ref: "release-1.12.1"
- name: Install packages required to run QZ inside workflow
run: sudo apt update -y && sudo apt-get install -y qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools qtquickcontrols2-5-dev libqt5bluetooth5 libqt5widgets5 libqt5positioning5 libqt5xml5 qtconnectivity5-dev qtpositioning5-dev libqt5charts5-dev libqt5charts5 libqt5networkauth5-dev libqt5websockets5* libxcb-randr0-dev libxcb-xtest0-dev libxcb-xinerama0-dev libxcb-shape0-dev libxcb-xkb-dev
@@ -570,36 +406,20 @@ jobs:
# waiting github.com/jurplel/install-qt-action/issues/63
- name: Install Qt Android
uses: jurplel/install-qt-action@v3
uses: jurplel/install-qt-action@v2
with:
version: '5.15.0'
version: '5.15.2'
host: 'linux'
target: 'android'
arch: 'android'
modules: 'qtcharts qtnetworkauth'
dir: '${{ github.workspace }}/output/android/'
cache: 'true'
cache-key-prefix: 'install-qt-action-android'
- name: Install Java
uses: actions/setup-java@v3
with:
distribution: 'temurin' # See 'Supported distributions' for available options
java-version: '11'
- name: patching qt for bluetooth
run: cp qt-patches/android/5.15.0/jar/*.* ${{ github.workspace }}/output/android/Qt/5.15.0/android/jar/
- name: download 3rd party files for qthttpserver
run: cp qHttpServerBin/5.15.2/headers/* src/qthttpserver/src/3rdparty/http-parser/
- name: Build qthttpserver
run: |
cd src/qthttpserver
qmake
make -j8
make install
cd ../..
- name: Set Android NDK 21 && build
run: |
@@ -611,436 +431,10 @@ jobs:
echo "y" | $SDKMANAGER "ndk;21.4.7075529"
export ANDROID_NDK="${ANDROID_SDK_ROOT}/ndk-bundle"
export ANDROID_NDK_ROOT="${ANDROID_NDK}"
cd src
echo "#define STRAVA_SECRET_KEY ${{ secrets.strava_secret_key }}" > secret.h
echo "#define SMTP_USERNAME ${{ secrets.smtp_username }}" >> secret.h
echo "#define SMTP_PASSWORD ${{ secrets.smtp_password }}" >> secret.h
echo "#define SMTP_SERVER ${{ secrets.smtp_server }}" >> secret.h
echo "${{ secrets.cesiumkey }}" >> inner_templates/googlemaps/cesium-key.js
echo "#define LICENSE" >> secret.h
cd ..
ln -sfn $ANDROID_SDK_ROOT/ndk/21.4.7075529 $ANDROID_NDK
rm -rf /usr/local/lib/android/sdk/ndk/25.1.8937393
qmake -spec android-clang 'ANDROID_ABIS=armeabi-v7a arm64-v8a x86 x86_64' 'ANDROID_NDK_ROOT=/usr/local/lib/android/sdk/ndk/21.4.7075529' && make -j4 && make INSTALL_ROOT=${{ github.workspace }}/output/android/ install
sed -i '1s|{|{\n "android-extra-libs": "${{ github.workspace }}/android_openssl/no-asm/latest/arm/libcrypto_1_1.so,${{ github.workspace }}/android_openssl/no-asm/latest/arm/libssl_1_1.so,${{ github.workspace }}/android_openssl/no-asm/latest/arm64/libcrypto_1_1.so,${{ github.workspace }}/android_openssl/no-asm/latest/arm64/libssl_1_1.so,${{ github.workspace }}/android_openssl/no-asm/latest/x86/libcrypto_1_1.so,${{ github.workspace }}/android_openssl/no-asm/latest/x86/libssl_1_1.so,${{ github.workspace }}/android_openssl/no-asm/latest/x86_64/libcrypto_1_1.so,${{ github.workspace }}/android_openssl/no-asm/latest/x86_64/libssl_1_1.so",|' src/android-qdomyos-zwift-deployment-settings.json
cat src/android-qdomyos-zwift-deployment-settings.json
- name: Build APK (not usable for production due to unpatched QT library)
run: cd src; androiddeployqt --input android-qdomyos-zwift-deployment-settings.json --output ${{ github.workspace }}/output/android/ --android-platform android-31 --gradle --aab
- name: Archive apk binary
uses: actions/upload-artifact@v2
with:
name: fdroid-android-trial
path: ${{ github.workspace }}/output/android/build/outputs/apk/debug/
# - name: Exit if not on master branch
# if: github.ref == 'refs/heads/main'
# run: exit 1
# - name: upload windows artifact
# uses: actions/upload-release-asset@v1
# env:
# GITHUB_TOKEN: ${{ github.token }}
# with:
# upload_url: ${{ steps.create_release.outputs.upload_url }}
# asset_path: ${{ github.workspace }}/output/android/build/outputs/apk/debug/android-debug.apk
# asset_name: fdroid-android-trial.zip
# asset_content_type: application/zip
ios-build:
# The type of runner that the job will run on
runs-on: macos-latest
permissions:
contents: write
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
repository: bluetiger9/SmtpClient-for-Qt
path: "src/smtpclient/"
ref: 3fa4a0fe5797070339422cf18b5e9ed8dcb91f9c
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
repository: cagnulein/qmdnsengine
path: "src/qmdnsengine/"
ref: "zwift"
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
repository: google/googletest
path: "tst/googletest/"
ref: "release-1.12.1"
- name: Install Qt iOS
uses: jurplel/install-qt-action@v3
with:
version: '5.15.2'
host: 'mac'
target: 'ios'
modules: 'qtcharts qtnetworkauth'
dir: '${{ github.workspace }}/output/ios/'
cache: 'true'
cache-key-prefix: 'install-qt-action-ios'
- name: fix qt
run: find ${{ github.workspace }}/output/ios/ -name 'ios.conf' -exec sed -i '' 's/ios-simulator/iphonesimulator/g' {} \;
- name: fix qt
run: find ${{ github.workspace }}/output/ios/ -name 'devices.py' -exec sed -i '' 's/\/usr\/bin\/python/\/usr\/bin\/python3/g' {} \;
- name: fix qt
run: find ./ -name 'qdomyos-zwift-lib.pro' -exec sed -i '' 's/TARGET = qdomyos-zwift/TARGET = qdomyoszwift/g' {} \;
- name: patching qt for bluetooth
run: cp qt-patches/ios/5.15.2/binary/*.* ${{ github.workspace }}/output/ios/Qt/5.15.2/ios/lib/
- name: Build
run: |
cd src
echo "#define STRAVA_SECRET_KEY ${{ secrets.strava_secret_key }}" > secret.h
echo "#define SMTP_USERNAME ${{ secrets.smtp_username }}" >> secret.h
echo "#define SMTP_PASSWORD ${{ secrets.smtp_password }}" >> secret.h
echo "#define SMTP_SERVER ${{ secrets.smtp_server }}" >> secret.h
echo "${{ secrets.cesiumkey }}" >> inner_templates/googlemaps/cesium-key.js
cd ..
qmake CONFIG+=debug && make -j4
# causes iOS build on Mac to fail
# - name: Commit moc files
# uses: EndBug/add-and-commit@v9
# with:
# message: 'moc files added'
# add: 'src/moc_*.cpp --force'
# if: github.ref == 'refs/heads/master'
window-msvc2019-build:
runs-on: windows-latest
strategy:
matrix:
config:
- {python: true}
- {python: false}
steps:
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
repository: bluetiger9/SmtpClient-for-Qt
path: "src/smtpclient/"
ref: 3fa4a0fe5797070339422cf18b5e9ed8dcb91f9c
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
repository: cagnulein/qmdnsengine
path: "src/qmdnsengine/"
ref: "zwift"
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
repository: google/googletest
path: "tst/googletest/"
ref: "release-1.12.1"
- uses: actions/checkout@v2
- name: Checkout qHttpServer
uses: actions/checkout@v2
with:
repository: qt-labs/qthttpserver
path: "src/qthttpserver"
- uses: actions/setup-python@v4
with:
python-version: 3.7
- name: download python and paddleocr
run: |
python -VV
python -m pip install --upgrade pip
python -m pip install --upgrade setuptools
python -m pip install "protobuf<=3.20.2,>=3.1.0"
python -m pip install paddlepaddle==2.5.1
python -m pip install paddleocr
python -m pip install imutils
python -m pip install "Pillow<10.0.0"
python -m pip install opencv-python
python -m pip install numpy
python -m pip install pywin32
if: matrix.config.python
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: '5.15.2'
host: 'windows'
modules: 'qtnetworkauth qtcharts'
target: "desktop"
arch: win64_msvc2019_64
dir: "${{github.workspace}}/qt/"
install-deps: "true"
cache: 'true'
cache-key-prefix: 'install-qt-action-windows'
- name: Install MSVC compiler
uses: ilammy/msvc-dev-cmd@v1
with:
# 14.1 is for vs2017, 14.2 is vs2019, following the upstream vcpkg build from Qv2ray-deps repo
toolset: 14.2
arch: x64
- name: download 3rd party files for qthttpserver
run: |
cp qHttpServerBin/5.15.2/headers/* src/qthttpserver/src/3rdparty/http-parser/
- name: Build qthttpserver
run: |
cd src\qthttpserver
qmake
nmake
nmake install
cd ../..
- name: Secrets
if: github.ref == 'refs/heads/main'
run: |
cd src
echo "#define STRAVA_SECRET_KEY ${{ secrets.strava_secret_key }}" > secret.h
echo "#define SMTP_USERNAME ${{ secrets.smtp_username }}" >> secret.h
echo "#define SMTP_PASSWORD ${{ secrets.smtp_password }}" >> secret.h
echo "#define SMTP_SERVER ${{ secrets.smtp_server }}" >> secret.h
echo "${{ secrets.cesiumkey }}" >> inner_templates/googlemaps/cesium-key.js
cd ..
- name: Build
run: |
qmake
nmake
cd src/debug
mkdir output
mkdir appx
cp qdomyos-zwift.exe output/
cd output
windeployqt --qmldir ../../ qdomyos-zwift.exe
cp ../../../icons/iOS/iTunesArtwork@2x.png .
cp ../../AppxManifest.xml .
cp ../../windows/*.py .
cp ../../windows/*.bat .
cp ../../../windows_openssl/*.* .
mkdir adb
mkdir python
Copy-Item -Path C:\hostedtoolcache\windows\Python\3.7.9\x64 -Destination python -Recurse
cp ../../adb/* adb/
cd ..
cd appx
#../../MSIX-Toolkit/WindowsSDK/10/10.0.20348.0/x64/makeappx.exe pack /d ../output/ /p qz
if: matrix.config.python
- name: Build without python
run: |
qmake
nmake
cd src/debug
mkdir output
mkdir appx
cp qdomyos-zwift.exe output/
cd output
windeployqt --qmldir ../../ qdomyos-zwift.exe
cp "C:/mingw64/bin/libwinpthread-1.dll" .
cp "C:/mingw64/bin/libgcc_s_seh-1.dll" .
cp "C:/mingw64/bin/libstdc++-6.dll" .
cp ../../../icons/iOS/iTunesArtwork@2x.png .
cp ../../AppxManifest.xml .
cp ../../../windows_openssl/*.* .
mkdir adb
cp ../../adb/* adb/
cd ..
cd appx
#../../MSIX-Toolkit/WindowsSDK/10/10.0.20348.0/x64/makeappx.exe pack /d ../output/ /p qz
if: matrix.config.python == false
- name: patching qt for bluetooth
run: cp qt-patches/windows/5.15.2/binary/msvc2019/*.* ${{ github.workspace }}/src/debug/output/
- name: Zip artifact for deployment
run: Compress-Archive src/debug/output windows-msvc2019-binary.zip
if: matrix.config.python
- name: Zip artifact for deployment
run: Compress-Archive src/debug/output windows-msvc2019-binary-no-python.zip
if: ${{ ! matrix.config.python }}
- name: Archive windows binary
uses: actions/upload-artifact@v2
with:
name: windows-msvc2019-binary
path: windows-msvc2019-binary.zip
if: matrix.config.python
- name: Archive windows binary
uses: actions/upload-artifact@v2
with:
name: windows-msvc2019-binary-no-python
path: windows-msvc2019-binary-no-python.zip
if: ${{ ! matrix.config.python }}
window-msvc2019-aiserver-build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
repository: bluetiger9/SmtpClient-for-Qt
path: "src/smtpclient/"
ref: 3fa4a0fe5797070339422cf18b5e9ed8dcb91f9c
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
repository: cagnulein/qmdnsengine
path: "src/qmdnsengine/"
ref: "zwift"
- uses: actions/checkout@v2
- name: Checkout submodule repo
uses: actions/checkout@v2
with:
repository: google/googletest
path: "tst/googletest/"
ref: "release-1.12.1"
- uses: actions/checkout@v2
- name: Checkout qHttpServer
uses: actions/checkout@v2
with:
repository: qt-labs/qthttpserver
path: "src/qthttpserver"
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: '5.15.2'
host: 'windows'
modules: 'qtnetworkauth qtcharts'
target: "desktop"
arch: win64_msvc2019_64
dir: "${{github.workspace}}/qt/"
install-deps: "true"
cache: 'true'
cache-key-prefix: 'install-qt-action-windows'
- name: Install MSVC compiler
uses: ilammy/msvc-dev-cmd@v1
with:
# 14.1 is for vs2017, 14.2 is vs2019, following the upstream vcpkg build from Qv2ray-deps repo
toolset: 14.2
arch: x64
- name: download 3rd party files for qthttpserver
run: |
cp qHttpServerBin/5.15.2/headers/* src/qthttpserver/src/3rdparty/http-parser/
- name: Build qthttpserver
run: |
cd src\qthttpserver
qmake
nmake
nmake install
cd ../..
- name: Secrets
if: github.ref == 'refs/heads/main'
run: |
cd src
echo "#define STRAVA_SECRET_KEY ${{ secrets.strava_secret_key }}" > secret.h
echo "#define SMTP_USERNAME ${{ secrets.smtp_username }}" >> secret.h
echo "#define SMTP_PASSWORD ${{ secrets.smtp_password }}" >> secret.h
echo "#define SMTP_SERVER ${{ secrets.smtp_server }}" >> secret.h
echo "${{ secrets.cesiumkey }}" >> inner_templates/googlemaps/cesium-key.js
cd ..
- name: Build
run: |
cd src
echo "#define AISERVER" >> aiserver.h
cd ..
qmake
nmake
cd src/debug
mkdir output
mkdir appx
cp qdomyos-zwift.exe output/
cd output
windeployqt --qmldir ../../ qdomyos-zwift.exe
cp ../../../icons/iOS/iTunesArtwork@2x.png .
cp ../../AppxManifest.xml .
cp ../../windows/zwift-incline-ai-server.py zwift-incline.py
cp ../../windows/zwift-incline-climb-portal-ai-server.py zwift-incline-climb-portal.py
cp ../../windows/zwift-workout-ai-server.py zwift-workout.py
cp ../../windows/*.bat .
cp ../../../windows_openssl/*.* .
mkdir adb
cp ../../adb/* adb/
cd ..
cd appx
#../../MSIX-Toolkit/WindowsSDK/10/10.0.20348.0/x64/makeappx.exe pack /d ../output/ /p qz
- name: patching qt for bluetooth
run: cp qt-patches/windows/5.15.2/binary/msvc2019/*.* ${{ github.workspace }}/src/debug/output/
- name: Zip artifact for deployment
run: Compress-Archive src/debug/output windows-msvc2019-ai-server-binary.zip
- name: Archive windows binary
uses: actions/upload-artifact@v2
with:
name: windows-msvc2019-ai-server-binary
path: windows-msvc2019-ai-server-binary.zip
upload_to_release:
permissions: write-all
runs-on: ubuntu-latest
if: github.event_name == 'schedule'
needs: [linux-x86-build, window-msvc2019-build, ios-build, window-build, android-build] # Specify the job dependencies
steps:
- name: Download artifacts
uses: actions/download-artifact@v3
- name: Update nightly release
uses: andelf/nightly-release@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: nightly
prerelease: false
name: 'QZ nightly build $$'
body: |
This is a nightly build of QZ.
You can use this if you want to try new features without waiting for releases.
From time to time, in development builds, old difficult-to-reproduce bugs are
fixed, but it is also true that in the development process with the introduction
of new complex code, the stability of the program may suffer compared to
official releases, so **use it with caution**!
__Please help us improve QZ by reporting any issues you encounter!__ :wink:
files: |
windows-msvc2019-binary-no-python/*
windows-msvc2019-binary/*
windows-msvc2019-ai-server-binary/*
windows-binary-no-python/*
windows-binary/*
fdroid-android-trial/*

3
.gitignore vendored
View File

@@ -25,6 +25,7 @@ src/secret.h
build-qdomyos-zwift-Android_Qt_5_15_2_Clang_Multi_Abi-Debug/*
**/node_modules/*
*.pro.user
template-examples/youtube-viewer/node_modules/*
template-examples/youtube-viewer/*.json
@@ -48,5 +49,3 @@ google_test/*
src/inner_templates/googlemaps/cesium-key.js
*.autosave
.vscode/settings.json
/tst/Devices/.vs
src/inner_templates/googlemaps/cesium-key.js

3
.gitmodules vendored
View File

@@ -13,6 +13,3 @@
path = tst/googletest
url = https://github.com/google/googletest.git
branch = tags/release-1.12.1
[submodule "src/qthttpserver"]
path = src/qthttpserver
url = https://github.com/qt-labs/qthttpserver

View File

@@ -1,128 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
roberto.viola83@gmail.com.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@@ -1,437 +0,0 @@
/** NimBLE_Server Demo:
*
This is working to broadcast Power and Cadence under the Cycling Power Service Profile
Data tested against Edge and Phone
*
*/
#include <Arduino.h>
#include <NimBLEDevice.h>
short powerInstantaneous = 0;
short cadenceInstantaneous = 0;
short speedInstantaneous = 0;
float powerScale = 1.28; // incoming power is multiplied by this value for correction
short resistance = 0; //Not currently doing anything with this value after receiving it
bool notify = false;
// Define stuff for the Client that will receive data from Fitness Machine
// The remote service we wish to connect to.
static BLEUUID serviceUUID("1826"); // Fitness Machine
// The characteristic of the remote service we are interested in.
static BLEUUID charUUID("2ad2"); // Indoor Bike (Fitness Machine)
static BLEUUID HRserviceUUID("180D"); // HR Service
static BLEUUID HRcharUUID("2a37"); // HR Measuremente
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic *pRemoteCharacteristic;
static BLEAdvertisedDevice *myDevice;
/*
* Server Stuff
*/
static NimBLEServer *pServer;
/** None of these are required as they will be handled by the library with defaults. **
** Remove as you see fit for your needs */
class ServerCallbacks : public NimBLEServerCallbacks
{
void onConnect(NimBLEServer *pServer)
{
Serial.println("Client connected");
Serial.println("Multi-connect support: start advertising");
NimBLEDevice::startAdvertising();
};
/** Alternative onConnect() method to extract details of the connection.
* See: src/ble_gap.h for the details of the ble_gap_conn_desc struct.
*/
void onConnect(NimBLEServer *pServer, ble_gap_conn_desc *desc)
{
Serial.print("Client address: ");
Serial.println(NimBLEAddress(desc->peer_ota_addr).toString().c_str());
/** We can use the connection handle here to ask for different connection parameters.
* Args: connection handle, min connection interval, max connection interval
* latency, supervision timeout.
* Units; Min/Max Intervals: 1.25 millisecond increments.
* Latency: number of intervals allowed to skip.
* Timeout: 10 millisecond increments, try for 5x interval time for best results.
*/
pServer->updateConnParams(desc->conn_handle, 24, 48, 0, 60);
};
void onDisconnect(NimBLEServer *pServer)
{
Serial.println("Client disconnected - start advertising");
NimBLEDevice::startAdvertising();
};
void onMTUChange(uint16_t MTU, ble_gap_conn_desc *desc)
{
Serial.printf("MTU updated: %u for connection ID: %u\n", MTU, desc->conn_handle);
};
};
/** Handler class for characteristic actions */
class CharacteristicCallbacks : public NimBLECharacteristicCallbacks
{
void onRead(NimBLECharacteristic *pCharacteristic)
{
Serial.print(pCharacteristic->getUUID().toString().c_str());
Serial.print(": onRead(), value: ");
Serial.println(pCharacteristic->getValue().c_str());
};
void onWrite(NimBLECharacteristic *pCharacteristic)
{
Serial.print(pCharacteristic->getUUID().toString().c_str());
Serial.print(": onWrite(), value: ");
Serial.println(pCharacteristic->getValue().c_str());
};
/** Called before notification or indication is sent,
* the value can be changed here before sending if desired.
*/
void onNotify(NimBLECharacteristic *pCharacteristic)
{
Serial.println("Sending notification to clients");
};
/** The status returned in status is defined in NimBLECharacteristic.h.
* The value returned in code is the NimBLE host return code.
*/
void onStatus(NimBLECharacteristic *pCharacteristic, Status status, int code)
{
String str = ("Notification/Indication status code: ");
str += status;
str += ", return code: ";
str += code;
str += ", ";
str += NimBLEUtils::returnCodeToString(code);
Serial.println(str);
};
void onSubscribe(NimBLECharacteristic *pCharacteristic, ble_gap_conn_desc *desc, uint16_t subValue)
{
String str = "Client ID: ";
str += desc->conn_handle;
str += " Address: ";
str += std::string(NimBLEAddress(desc->peer_ota_addr)).c_str();
if (subValue == 0)
{
str += " Unsubscribed to ";
}
else if (subValue == 1)
{
str += " Subscribed to notifications for ";
}
else if (subValue == 2)
{
str += " Subscribed to indications for ";
}
else if (subValue == 3)
{
str += " Subscribed to notifications and indications for ";
}
str += std::string(pCharacteristic->getUUID()).c_str();
Serial.println(str);
};
};
/** Handler class for descriptor actions */
class DescriptorCallbacks : public NimBLEDescriptorCallbacks
{
void onWrite(NimBLEDescriptor *pDescriptor)
{
std::string dscVal((char *)pDescriptor->getValue(), pDescriptor->getLength());
Serial.print("Descriptor witten value:");
Serial.println(dscVal.c_str());
};
void onRead(NimBLEDescriptor *pDescriptor)
{
Serial.print(pDescriptor->getUUID().toString().c_str());
Serial.println(" Descriptor read");
};
};
/*
* Client Stuff
*/
// This callback is for when data is received from Server
static void notifyCallback(
BLERemoteCharacteristic *pBLERemoteCharacteristic,
uint8_t *pData,
size_t length,
bool isNotify)
{
powerInstantaneous = pData[8] | pData[9] << 8; // 2 bytes of power
cadenceInstantaneous = 60; //(pData[4] | pData[5] << 8) / 2; // 2 bytes of power in 0.5 resolution RPM, convert to RPM
resistance = pData[6]; // 1 byte of resistance
Serial.printf("Power = %d | Cadence = %d | Resistance = %d\n", powerInstantaneous, cadenceInstantaneous, resistance);
}
/** None of these are required as they will be handled by the library with defaults. **
** Remove as you see fit for your needs */
class MyClientCallback : public BLEClientCallbacks
{
void onConnect(BLEClient *pclient)
{
}
void onDisconnect(BLEClient *pclient)
{
connected = false;
Serial.println("onDisconnect");
}
};
bool connectToServer()
{
Serial.print("Forming a connection to ");
Serial.println(myDevice->getAddress().toString().c_str());
BLEClient *pClient = BLEDevice::createClient();
Serial.println(" - Created client");
pClient->setClientCallbacks(new MyClientCallback());
// Connect to the remove BLE Server.
pClient->connect(myDevice); // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
Serial.println(" - Connected to server");
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService *pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr)
{
Serial.print("Failed to find our service UUID: ");
Serial.println(serviceUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our service");
// Obtain a reference to the characteristic in the service of the remote BLE server.
pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
if (pRemoteCharacteristic == nullptr)
{
Serial.print("Failed to find our characteristic UUID: ");
Serial.println(charUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our characteristic");
// Read the value of the characteristic.
if (pRemoteCharacteristic->canRead())
{
std::string value = pRemoteCharacteristic->readValue();
Serial.print("The characteristic value was: ");
Serial.println(value.c_str());
}
if (pRemoteCharacteristic->canNotify())
pRemoteCharacteristic->registerForNotify(notifyCallback);
connected = true;
return true;
}
/**
* Scan for BLE servers and find the first one that advertises the service we are looking for.
*/
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
{
/**
* Called for each advertising BLE server.
*/
/*** Only a reference to the advertised device is passed now
void onResult(BLEAdvertisedDevice advertisedDevice) { **/
void onResult(BLEAdvertisedDevice *advertisedDevice)
{
Serial.print("BLE Advertised Device found: ");
Serial.println(advertisedDevice->toString().c_str());
// We have found a device, let us now see if it contains the service we are looking for.
/********************************************************************************
if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {
********************************************************************************/
if (advertisedDevice->haveServiceUUID() && advertisedDevice->isAdvertisingService(serviceUUID))
{
BLEDevice::getScan()->stop();
/*******************************************************************
myDevice = new BLEAdvertisedDevice(advertisedDevice);
*******************************************************************/
myDevice = advertisedDevice; /** Just save the reference now, no need to copy the object */
doConnect = true;
doScan = true;
} // Found our server
} // onResult
}; // MyAdvertisedDeviceCallbacks
//delays for X ms, should not block execution
void softDelay(unsigned long delayTime)
{
unsigned long startTime = millis();
while ((millis() - startTime) < delayTime)
{
//wait
}
}
/** Define callback instances globally to use for multiple Characteristics \ Descriptors */
// This section is for the Server that will broadcast the data as Cycling Power
static DescriptorCallbacks dscCallbacks;
static CharacteristicCallbacks chrCallbacks;
NimBLECharacteristic *CyclingPowerFeature = NULL;
NimBLECharacteristic *CyclingPowerMeasurement = NULL;
NimBLECharacteristic *CyclingPowerSensorLocation = NULL;
NimBLECharacteristic *HRMeasurement = NULL;
unsigned char bleBuffer[8];
unsigned char slBuffer[1];
unsigned char fBuffer[4];
unsigned short revolutions = 0;
unsigned short timestamp = 0;
unsigned short flags = 0x20;
byte sensorlocation = 0x0D;
long lastNotify = 0;
long lastRevolution = 0;
void setup()
{
Serial.begin(115200);
Serial.println("Starting NimBLE Server");
/** sets device name */
NimBLEDevice::init("QZESP");
/** Optional: set the transmit power, default is 3db */
NimBLEDevice::setPower(ESP_PWR_LVL_P9); /** +9db */
pServer = NimBLEDevice::createServer();
pServer->setCallbacks(new ServerCallbacks());
fBuffer[0] = 0x00;
fBuffer[1] = 0x00;
fBuffer[2] = 0x00;
fBuffer[3] = 0x08;
slBuffer[0] = sensorlocation & 0xff;
NimBLEService *pDeadService = pServer->createService("1818");
CyclingPowerFeature = pDeadService->createCharacteristic(
"2A65",
NIMBLE_PROPERTY::READ);
CyclingPowerSensorLocation = pDeadService->createCharacteristic(
"2A5D",
NIMBLE_PROPERTY::READ);
CyclingPowerMeasurement = pDeadService->createCharacteristic(
"2A63",
NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
CyclingPowerFeature->setValue(fBuffer, 4);
CyclingPowerSensorLocation->setValue(slBuffer, 1);
CyclingPowerMeasurement->setValue(slBuffer, 1);
/** Start the services when finished creating all Characteristics and Descriptors */
pDeadService->start();
#if 0
// HR service
NimBLEService *pHRService = pServer->createService("180D");
HRMeasurement = pHRService->createCharacteristic(
"2A37",
NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
HRMeasurement->setValue(fBuffer, 2);
/** Start the services when finished creating all Characteristics and Descriptors */
pHRService->start();
#endif
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
/** Add the services to the advertisement data **/
// pAdvertising->addServiceUUID(pHRService->getUUID());
pAdvertising->addServiceUUID(pDeadService->getUUID());
pAdvertising->setScanResponse(true);
pAdvertising->start();
Serial.println("Advertising Started");
Serial.println("Starting Arduino BLE Client application...");
BLEDevice::init("");
// Retrieve a Scanner and set the callback we want to use to be informed when we
// have detected a new device. Specify that we want active scanning and start the
// scan to run for 5 seconds.
BLEScan *pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setInterval(1349);
pBLEScan->setWindow(449);
pBLEScan->setActiveScan(true);
pBLEScan->start(5, false);
}
void loop()
{
// If the flag "doConnect" is true then we have scanned for and found the desired
// BLE Server with which we wish to connect. Now we connect to it. Once we are
// connected we set the connected flag to be true.
if (doConnect == true)
{
if (connectToServer())
{
Serial.println("We are now connected to the BLE Server.");
}
else
{
Serial.println("We have failed to connect to the server; there is nothing more we will do.");
}
doConnect = false;
}
// If we are connected to a peer BLE Server, update the characteristic each time we are reached
// with the current time since boot.
if (connected)
{
//Stuff to do when connected to Client
}
else if (doScan)
{
BLEDevice::getScan()->start(0); // this is just sample to start scan after disconnect, most likely there is better way to do it in arduino
}
// convert RPM to timestamp
if (cadenceInstantaneous != 0 && (millis()) >= (lastRevolution + (60000 / cadenceInstantaneous)))
{
revolutions++; // One crank revolution should have passed, add one revolution
timestamp = (unsigned short)(((millis() * 1024) / 1000) % 65536); // create timestamp and format
lastRevolution = millis();
}
if (millis() - lastNotify >= 1000) // do this every second
{
//if (pServer->getConnectedCount() > 0)
{
bleBuffer[0] = flags & 0xff;
bleBuffer[1] = (flags >> 8) & 0xff;
bleBuffer[2] = powerInstantaneous & 0xff;
bleBuffer[3] = (powerInstantaneous >> 8) & 0xff;
bleBuffer[4] = revolutions & 0xff;
bleBuffer[5] = (revolutions >> 8) & 0xff;
bleBuffer[6] = timestamp & 0xff;
bleBuffer[7] = (timestamp >> 8) & 0xff;
CyclingPowerMeasurement->setValue(bleBuffer, 8);
CyclingPowerMeasurement->notify();
/*bleBuffer[0] = 0;
bleBuffer[1] = powerInstantaneous;
HRMeasurement->setValue(bleBuffer, 2);
HRMeasurement->notify();*/
lastNotify = millis();
}
}
/*if (pServer->getConnectedCount() == 0)
{
powerInstantaneous = 0;
}*/
}

112
README.md
View File

@@ -7,99 +7,35 @@ Zwift bridge for Treadmills and Bike!
[<img src="docs/img/app_store.png">](https://apps.apple.com/app/id1543684531?fbclid=IwAR10H6y3mEgwkTlGJON3e8voYOh2wt3kLFOpFzoIXaYZ_N0y0pDvKxHMUaM)
<a href="https://www.buymeacoffee.com/cagnulein" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>
<table>
<tr>
<td>
<img src="icons/AppScreen/iOS%20Phones%20-%206.5_/screenshot1.jpeg" style="height: 400px !important; box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" >
</td>
<td>
<img src="icons/AppScreen/iOS%20Phones%20-%206.5_/screenshot2.jpeg" style="height: 400px !important; box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" >
</td>
<td>
<img src="icons/AppScreen/iOS%20Phones%20-%206.5_/screenshot3.jpeg" style="height: 400px !important; box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" >
</td>
<td>
<img src="icons/AppScreen/iOS%20Phones%20-%206.5_/screenshot4.jpeg" style="height: 400px !important; box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" >
</td>
<td>
<img src="icons/AppScreen/iOS%20Phones%20-%206.5_/screenshot5.jpeg" style="height: 400px !important; box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" >
</td>
</tr>
</table>
![UI](docs/img/treadmill-bridge-schema.png)
[![Video](https://img.youtube.com/vi/GgG3dMhmo2Y/0.jpg)](https://www.youtube.com/watch?v=GgG3dMhmo2Y)
![UI](docs/img/ui.png)
![UI](docs/img/realtime-chart.png)
UI on Linux
![UI](docs/img/ui-mac.png)
UI on MacOS
### Features
# UI Features
|Feature|Bike|Treadmill|Elliptical|Rower|Notes|
|:---|:---:|:---:|:---:|:---:|---:|
|Tiles Customization|X|X|X|X|Order and visibility of each tile|
|Profiles|X|X|X|X|Different user or different fitness device profiles|
|UI Zoom Customization|X|X|X|X||
# Peloton Features
|Feature|Bike|Treadmill|Elliptical|Rower|Notes|
|:---|:---:|:---:|:---:|:---:|---:|
|Bike metrics on the peloton app|X||X|||
|Power zone with auto resistance|X|||||
|Peloton real-time resistance conversion|X||X||with the possibility to customize it|
|Peloton real-time auto-resistance|X||X||with the possibility to customize it|
|Peloton auto speed and auto inclination||X|X||with the possibility to customize it|
# Heart Rate Features
|Feature|Bike|Treadmill|Elliptical|Rower|Notes|
|:---|:---:|:---:|:---:|:---:|---:|
|Heart Rate support|X|X|X|X|Apple Watch, ANT+ devices and Bluetooth devices|
|Heart Rate Zones Customizations|X|X|X|X||
|Ability to calculate Wattage from HR and Cadence|X||||for the bikes that doesn't have a power sensor|
# 3rd Apps Compatibility
|Feature|Bike|Treadmill|Elliptical|Rower|Notes|
|:---|:---:|:---:|:---:|:---:|---:|
|Zwift Compatibility|X|X|X|X||
|Zwift Auto resistance|X||X|||
|Zwift Auto inclination and speed||X|X||https://www.youtube.com/watch?v=KTQ2n7yeDbo|
|Wahoo RGT Compatibility|X|X|X|X||
|VzFit Compatibility|X|X|X|X||
|Rouvy Compatibility|X|X|X|X||
|IFIT app Compatibility|X|||||
|Echelon app Compatibility|X|||||
|Wahoo Dircon Compatibility|X|X|X|X|in order to send data to Zwift or RGT with Wifi only!|
|One device only support for Zwift and Wahoo RGT|X|X|X|X|using Wahoo Dircon https://www.youtube.com/watch?v=gYYUXNWFAok|
# Training Program
|Feature|Bike|Treadmill|Elliptical|Rower|Notes|
|:---|:---:|:---:|:---:|:---:|---:|
|Builtin video support (Kinomap like)|X|X|X|X|Files could be local or on the cloud!|
|GPX auto following|X|X|X|X||
|2D/3D maps for GPX|X|X|X|X||
|ZWO (Zwift workout file) compatibility|X|X|X|X||
|XML Workout file compatibility|X|X|X|X||
|Auto follow workout based on your heart rate|X|X|X|X||
|Random workout|X|X|X|X||
# Statistics
|Feature|Bike|Treadmill|Elliptical|Rower|Notes|
|:---|:---:|:---:|:---:|:---:|---:|
|E-Mail report|X|X|X|X|at the end of the workout|
|Strava integration|X|X|X|X|press stop at the end of the workout to auto upload it|
# Misc
|Feature|Bike|Treadmill|Elliptical|Rower|Notes|
|:---|:---:|:---:|:---:|:---:|---:|
|Resistance shifting with bluetooth remote|X||X|||
|TTS support|X|X|X|X||
1. Domyos compatible
2. Toorx TRX Route Key compatible
3. Echelon Connect Sport compatible
4. Zwift compatible
5. Create, load and save train programs
6. Measure distance, elevation gain and watts
7. Gpx import (with difficulty slider)
8. Realtime Charts
![First Success](docs/img/first_success.jpg)
### Installation
You can install it on multiple platforms.
You can install on multiple platforms.
Read the [installation procedure](docs/10_Installation.md)
@@ -109,7 +45,7 @@ You can run the app on [Macintosh or Linux devices](docs/10_Installation.md). IO
QDomyos-Zwift works on every [FTMS-compatible application](docs/20_supported_devices_and_applications.md), and virtually any [bluetooth enabled device](docs/20_supported_devices_and_applications.md).
### No GUI version
### No gui version
run as
@@ -121,7 +57,7 @@ https://github.com/ProH4Ck/treadmill-bridge
https://www.livestrong.com/article/422012-what-is-10-degrees-in-incline-on-a-treadmill/
Icons used in this documentation come from [flaticon.com](https://www.flaticon.com)
Icons used in this documentation comes from [flaticon.com](https://www.flaticon.com)
### Blog

View File

@@ -2,4 +2,3 @@
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "swiftDebug.h"

View File

@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objectVersion = 46;
objects = {
/* Begin PBXAggregateTarget section */
@@ -143,9 +143,6 @@
87083D9626678EFA0072410D /* zwiftworkout.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87083D9526678EFA0072410D /* zwiftworkout.cpp */; };
87097D2F275EA9A30020EE6F /* sportsplusbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87097D2D275EA9A20020EE6F /* sportsplusbike.cpp */; };
87097D31275EA9AF0020EE6F /* moc_sportsplusbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87097D30275EA9AE0020EE6F /* moc_sportsplusbike.cpp */; };
8710706C29C48AEA0094D0F3 /* handleurl.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8710706B29C48AEA0094D0F3 /* handleurl.cpp */; };
8710706E29C48AF30094D0F3 /* moc_handleurl.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8710706D29C48AF30094D0F3 /* moc_handleurl.cpp */; };
8710707329C4A5E70094D0F3 /* GarminConnect.swift in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8710707229C4A5E70094D0F3 /* GarminConnect.swift */; };
871189132893C930006A04D1 /* libQt5Multimedia.a in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 871189122893C92F006A04D1 /* libQt5Multimedia.a */; };
871189152893CB52006A04D1 /* libdeclarative_multimedia.a in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 871189142893CB51006A04D1 /* libdeclarative_multimedia.a */; };
871189172893CC45006A04D1 /* libQt5MultimediaQuick.a in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 871189162893CC44006A04D1 /* libQt5MultimediaQuick.a */; };
@@ -170,23 +167,12 @@
872261F0289EA887006A6F75 /* moc_nordictrackelliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 872261EF289EA887006A6F75 /* moc_nordictrackelliptical.cpp */; };
8727A47727849EA600019B5D /* paferstreadmill.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8727A47627849EA600019B5D /* paferstreadmill.cpp */; };
8727A47927849EB200019B5D /* moc_paferstreadmill.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8727A47827849EB200019B5D /* moc_paferstreadmill.cpp */; };
8727C7D02B3BF1B8005429EB /* proformtelnetbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8727C7CC2B3BF1B8005429EB /* proformtelnetbike.cpp */; };
8727C7D12B3BF1B8005429EB /* QTelnet.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8727C7CF2B3BF1B8005429EB /* QTelnet.cpp */; };
8727C7D42B3BF1E4005429EB /* moc_QTelnet.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8727C7D22B3BF1E4005429EB /* moc_QTelnet.cpp */; };
8727C7D52B3BF1E4005429EB /* moc_proformtelnetbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8727C7D32B3BF1E4005429EB /* moc_proformtelnetbike.cpp */; };
872A20DA28C5EC380037774D /* faketreadmill.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 872A20D928C5EC380037774D /* faketreadmill.cpp */; };
872A20DC28C5F5CE0037774D /* moc_faketreadmill.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 872A20DB28C5F5CE0037774D /* moc_faketreadmill.cpp */; };
872BAB4E261750EE006A59AB /* libQt5Charts.a in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 872BAB4D261750EE006A59AB /* libQt5Charts.a */; };
872BAB50261751FB006A59AB /* libqtchartsqml2.a in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 872BAB4F261751FB006A59AB /* libqtchartsqml2.a */; };
872DCC392A18D4A800EC9F68 /* virtualdevice.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 872DCC382A18D4A800EC9F68 /* virtualdevice.cpp */; };
872DCC3B2A18D4C000EC9F68 /* moc_virtualdevice.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 872DCC3A2A18D4C000EC9F68 /* moc_virtualdevice.cpp */; };
873063BE259DF20000DA0F44 /* heartratebelt.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 873063BC259DF20000DA0F44 /* heartratebelt.cpp */; };
873063C0259DF2C500DA0F44 /* moc_heartratebelt.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 873063BF259DF2C500DA0F44 /* moc_heartratebelt.cpp */; };
8730A38B2B404081007E336D /* SwiftProtobuf in Link Binary With Libraries */ = {isa = PBXBuildFile; productRef = 8730A38A2B404081007E336D /* SwiftProtobuf */; };
8730A38D2B404081007E336D /* SwiftProtobufPluginLibrary in Link Binary With Libraries */ = {isa = PBXBuildFile; productRef = 8730A38C2B404081007E336D /* SwiftProtobufPluginLibrary */; };
8730A38F2B404081007E336D /* protoc-gen-swift in Link Binary With Libraries */ = {isa = PBXBuildFile; productRef = 8730A38E2B404081007E336D /* protoc-gen-swift */; };
8730A3922B404159007E336D /* zwift_protobuf_layer.swift in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8730A3912B404159007E336D /* zwift_protobuf_layer.swift */; };
8730A3932B4078E6007E336D /* zwift_messages.pb.swift in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8730A3902B4040AF007E336D /* zwift_messages.pb.swift */; };
87310B1E266FBB59008BA0D6 /* smartrowrower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87310B1B266FBB54008BA0D6 /* smartrowrower.cpp */; };
87310B1F266FBB59008BA0D6 /* homefitnessbuddy.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87310B1C266FBB57008BA0D6 /* homefitnessbuddy.cpp */; };
87310B22266FBB78008BA0D6 /* moc_homefitnessbuddy.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87310B20266FBB6E008BA0D6 /* moc_homefitnessbuddy.cpp */; };
@@ -252,8 +238,6 @@
873CD22D27EF8E4B000131BC /* iosinapppurchaseproduct.mm in Compile Sources */ = {isa = PBXBuildFile; fileRef = 873CD22927EF8E4B000131BC /* iosinapppurchaseproduct.mm */; };
873CD22F27EF8EC1000131BC /* StoreKit.framework in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 873CD22E27EF8EC1000131BC /* StoreKit.framework */; };
873CD23027EF8EF5000131BC /* iosinapppurchasetransaction.mm in Compile Sources */ = {isa = PBXBuildFile; fileRef = 873CD22727EF8E4B000131BC /* iosinapppurchasetransaction.mm */; };
873D388B29B0D745006A2611 /* ConnectIQ.xcframework in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 873D388A29B0D744006A2611 /* ConnectIQ.xcframework */; };
873D388C29B0D745006A2611 /* ConnectIQ.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 873D388A29B0D744006A2611 /* ConnectIQ.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
873F022F274BE471002D0349 /* mcfbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 873F022D274BE471002D0349 /* mcfbike.cpp */; };
873F0231274BE47D002D0349 /* moc_mcfbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 873F0230274BE47D002D0349 /* moc_mcfbike.cpp */; };
87420DF6269D770F000C5EC6 /* libQt5WebView.a in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 87420DF5269D770F000C5EC6 /* libQt5WebView.a */; };
@@ -263,16 +247,11 @@
87433F2127D8B722003D1672 /* simplecrypt.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87433F2027D8B722003D1672 /* simplecrypt.cpp */; };
87440FBD2640291700E4DC0B /* fitplusbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87440FBC2640291700E4DC0B /* fitplusbike.cpp */; };
87440FBF2640292900E4DC0B /* moc_fitplusbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87440FBE2640292900E4DC0B /* moc_fitplusbike.cpp */; };
8745B2762AFCB4A300991A39 /* android in Copy Bundle Resources */ = {isa = PBXBuildFile; fileRef = 8745B2752AFCB4A300991A39 /* android */; };
8745B2782AFCB87B00991A39 /* libadb.a in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 8745B2742AFCB3B300991A39 /* libadb.a */; };
87473A9627ECA9EE00C203F5 /* proformrower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87473A9527ECA9EE00C203F5 /* proformrower.cpp */; };
87473A9827ECAA0500C203F5 /* moc_proformrower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87473A9727ECAA0500C203F5 /* moc_proformrower.cpp */; };
874D272029AFA11F0007C079 /* apexbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 874D271E29AFA11F0007C079 /* apexbike.cpp */; };
874D272229AFA13B0007C079 /* moc_apexbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 874D272129AFA13B0007C079 /* moc_apexbike.cpp */; };
8752B4CD27F43D9200E2EC6C /* qz.storekit in Copy Bundle Resources */ = {isa = PBXBuildFile; fileRef = 8752B4CC27F43D9200E2EC6C /* qz.storekit */; };
8752C0E32B15D84100C3D1A5 /* moc_eliteariafan.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8752C0E22B15D84100C3D1A5 /* moc_eliteariafan.cpp */; };
8752C0E82B15D85600C3D1A5 /* eliteariafan.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8752C0E42B15D85600C3D1A5 /* eliteariafan.cpp */; };
8752C0E92B15D85600C3D1A5 /* ios_eliteariafan.mm in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8752C0E62B15D85600C3D1A5 /* ios_eliteariafan.mm */; };
87540FAD2848FD70005E0D44 /* libqtexttospeech_speechios.a in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 87540FAC2848FD70005E0D44 /* libqtexttospeech_speechios.a */; };
8754D24C27F786F0003D7054 /* virtualrower.swift in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8754D24B27F786F0003D7054 /* virtualrower.swift */; };
87586A4125B8340E00A243C4 /* proformbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87586A4025B8340E00A243C4 /* proformbike.cpp */; };
@@ -316,8 +295,6 @@
876F9B61275385D8006AE6FA /* moc_fitmetria_fanfit.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 876F9B60275385D8006AE6FA /* moc_fitmetria_fanfit.cpp */; };
8772A0E625E43ADB0080718C /* trxappgateusbbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8772A0E525E43ADA0080718C /* trxappgateusbbike.cpp */; };
8772A0E825E43AE70080718C /* moc_trxappgateusbbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8772A0E725E43AE70080718C /* moc_trxappgateusbbike.cpp */; };
8775008329E876F8008E48B7 /* iconceptelliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8775008129E876F7008E48B7 /* iconceptelliptical.cpp */; };
8775008529E87713008E48B7 /* moc_iconceptelliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8775008429E87712008E48B7 /* moc_iconceptelliptical.cpp */; };
877A080D2893DC4300C0F0AB /* CoreVideo.framework in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 879F74122893D705009A64C8 /* CoreVideo.framework */; };
877A7609269D8E9F0024DD2C /* WebKit.framework in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 877A7608269D8E9F0024DD2C /* WebKit.framework */; };
877FBA29276E684500F6C0C9 /* bowflextreadmill.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 877FBA27276E684400F6C0C9 /* bowflextreadmill.cpp */; };
@@ -334,14 +311,10 @@
878531652711A3E1004B153D /* activiotreadmill.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878531612711A3E1004B153D /* activiotreadmill.cpp */; };
878531682711A3EC004B153D /* moc_activiotreadmill.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878531662711A3EB004B153D /* moc_activiotreadmill.cpp */; };
878531692711A3EC004B153D /* moc_fakebike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878531672711A3EB004B153D /* moc_fakebike.cpp */; };
8785D5432B3DD105005A2EB7 /* moc_PlayerStateWrapper.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8785D5412B3DD105005A2EB7 /* moc_PlayerStateWrapper.cpp */; };
8785D5442B3DD105005A2EB7 /* moc_zwift_client_auth.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8785D5422B3DD105005A2EB7 /* moc_zwift_client_auth.cpp */; };
878A331A25AB4FF800BD13E1 /* yesoulbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878A331725AB4FF800BD13E1 /* yesoulbike.cpp */; };
878A331D25AB50C300BD13E1 /* moc_yesoulbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878A331B25AB50C200BD13E1 /* moc_yesoulbike.cpp */; };
878C9E6928B77E7C00669129 /* nordictrackifitadbbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878C9E6828B77E7B00669129 /* nordictrackifitadbbike.cpp */; };
878C9E6B28B77E9800669129 /* moc_nordictrackifitadbbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878C9E6A28B77E9800669129 /* moc_nordictrackifitadbbike.cpp */; };
878D83742A1F33C600D7F004 /* bkoolbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878D83732A1F33C600D7F004 /* bkoolbike.cpp */; };
878D83762A1F33D900D7F004 /* moc_bkoolbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 878D83752A1F33D900D7F004 /* moc_bkoolbike.cpp */; };
87900DC6268B672E000CB351 /* renphobike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87900DC5268B672E000CB351 /* renphobike.cpp */; };
87900DC8268B673C000CB351 /* moc_renphobike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87900DC7268B673C000CB351 /* moc_renphobike.cpp */; };
8790FDDF277B0ABA00247550 /* nautilustreadmill.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8790FDDD277B0ABA00247550 /* nautilustreadmill.cpp */; };
@@ -352,7 +325,6 @@
87917A7728E768D200F8D9AC /* Client.swift in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87917A7228E768D200F8D9AC /* Client.swift */; };
8791A8AA25C8603F003B50B2 /* moc_inspirebike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8791A8A925C8603F003B50B2 /* moc_inspirebike.cpp */; };
8791A8AB25C861BD003B50B2 /* inspirebike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8791A8A825C8602A003B50B2 /* inspirebike.cpp */; };
87943AB429E0215D007575F2 /* localipaddress.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87943AB229E0215D007575F2 /* localipaddress.cpp */; };
87958F1927628D4500124B24 /* elitesterzosmart.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87958F1827628D4500124B24 /* elitesterzosmart.cpp */; };
87958F1B27628D5400124B24 /* moc_elitesterzosmart.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87958F1A27628D5400124B24 /* moc_elitesterzosmart.cpp */; };
8798C8872733E103003148B3 /* strydrunpowersensor.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 8798C8862733E103003148B3 /* strydrunpowersensor.cpp */; };
@@ -374,11 +346,8 @@
87A0C4BC262329A600121A76 /* cscbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87A0C4B9262329A600121A76 /* cscbike.cpp */; };
87A0C4BF262329B500121A76 /* moc_cscbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87A0C4BD262329B500121A76 /* moc_cscbike.cpp */; };
87A0C4C0262329B500121A76 /* moc_npecablebike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87A0C4BE262329B500121A76 /* moc_npecablebike.cpp */; };
87A0D7522A3A4518005147F2 /* fakerower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87A0D7502A3A4517005147F2 /* fakerower.cpp */; };
87A0D7542A3A4547005147F2 /* moc_fakerower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87A0D7532A3A4547005147F2 /* moc_fakerower.cpp */; };
87A18F072660D5C1002D7C96 /* ftmsrower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87A18F052660D5C0002D7C96 /* ftmsrower.cpp */; };
87A18F092660D5D9002D7C96 /* moc_ftmsrower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87A18F082660D5D9002D7C96 /* moc_ftmsrower.cpp */; };
87A2E0222B2B053E00E6168F /* swiftDebug.mm in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87A2E0212B2B053E00E6168F /* swiftDebug.mm */; };
87A3BC222656429600D302E3 /* rower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87A3BC1F2656429400D302E3 /* rower.cpp */; };
87A3BC232656429600D302E3 /* echelonrower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87A3BC202656429400D302E3 /* echelonrower.cpp */; };
87A3BC26265642A300D302E3 /* moc_rower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87A3BC24265642A200D302E3 /* moc_rower.cpp */; };
@@ -397,8 +366,6 @@
87B617F425F260150094A1CB /* moc_screencapture.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87B617F125F260150094A1CB /* moc_screencapture.cpp */; };
87BB1774269E983200F46A1C /* moc_webserverinfosender.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87BB1773269E983200F46A1C /* moc_webserverinfosender.cpp */; };
87BB1776269E987100F46A1C /* libQt5HttpServer.a in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 87BB1775269E987000F46A1C /* libQt5HttpServer.a */; };
87BCE6BD29F28F72001F70EB /* ypooelliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87BCE6BC29F28F72001F70EB /* ypooelliptical.cpp */; };
87BCE6BF29F28F95001F70EB /* moc_ypooelliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87BCE6BE29F28F94001F70EB /* moc_ypooelliptical.cpp */; };
87BE6FDC272D2A3100C35795 /* horizongr7bike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87BE6FDA272D2A3100C35795 /* horizongr7bike.cpp */; };
87BE6FDE272D2A3E00C35795 /* moc_horizongr7bike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87BE6FDD272D2A3E00C35795 /* moc_horizongr7bike.cpp */; };
87BF116D298E28CA00B5B6E7 /* pelotonbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87BF116C298E28CA00B5B6E7 /* pelotonbike.cpp */; };
@@ -446,7 +413,6 @@
87D269A325F535340076AA48 /* moc_skandikawiribike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87D269A125F535300076AA48 /* moc_skandikawiribike.cpp */; };
87D269A425F535340076AA48 /* moc_m3ibike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87D269A225F535300076AA48 /* moc_m3ibike.cpp */; };
87D44181269DE979003263D5 /* webserverinfosender.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87D44180269DE979003263D5 /* webserverinfosender.cpp */; };
87D4693629B64D8100C9A382 /* ios_app_delegate.mm in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87D4693529B64D8100C9A382 /* ios_app_delegate.mm */; };
87D5DC402823047D008CCDE7 /* truetreadmill.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87D5DC3E2823047D008CCDE7 /* truetreadmill.cpp */; };
87D5DC4228230496008CCDE7 /* moc_truetreadmill.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87D5DC4128230496008CCDE7 /* moc_truetreadmill.cpp */; };
87D91F9A2800B9970026D43C /* proformwifibike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87D91F992800B9970026D43C /* proformwifibike.cpp */; };
@@ -491,8 +457,6 @@
87F02E4029178524000DB52C /* octaneelliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87F02E3E29178523000DB52C /* octaneelliptical.cpp */; };
87F02E4229178545000DB52C /* moc_octaneelliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87F02E4129178545000DB52C /* moc_octaneelliptical.cpp */; };
87F1179E26A5FBDE00541B3A /* libqtwebview_darwin.a in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 87420DF7269D7CE1000C5EC6 /* libqtwebview_darwin.a */; };
87F4FB5A29D550C00061BB4A /* schwinn170bike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87F4FB5829D550BF0061BB4A /* schwinn170bike.cpp */; };
87F4FB5C29D550E00061BB4A /* moc_schwinn170bike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87F4FB5B29D550DF0061BB4A /* moc_schwinn170bike.cpp */; };
87F527BE28EEB5AA00A9F8D5 /* qzsettings.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87F527BC28EEB5AA00A9F8D5 /* qzsettings.cpp */; };
87F93427278E0EC00088B596 /* domyosrower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87F93426278E0EC00088B596 /* domyosrower.cpp */; };
87F93429278E0ECF0088B596 /* moc_domyosrower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87F93428278E0ECF0088B596 /* moc_domyosrower.cpp */; };
@@ -622,7 +586,6 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
873D388C29B0D745006A2611 /* ConnectIQ.xcframework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@@ -859,10 +822,6 @@
87097D2D275EA9A20020EE6F /* sportsplusbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = sportsplusbike.cpp; path = ../src/sportsplusbike.cpp; sourceTree = "<group>"; };
87097D2E275EA9A20020EE6F /* sportsplusbike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sportsplusbike.h; path = ../src/sportsplusbike.h; sourceTree = "<group>"; };
87097D30275EA9AE0020EE6F /* moc_sportsplusbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_sportsplusbike.cpp; sourceTree = "<group>"; };
8710706A29C48AE90094D0F3 /* handleurl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = handleurl.h; path = ../src/handleurl.h; sourceTree = "<group>"; };
8710706B29C48AEA0094D0F3 /* handleurl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = handleurl.cpp; path = ../src/handleurl.cpp; sourceTree = "<group>"; };
8710706D29C48AF30094D0F3 /* moc_handleurl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_handleurl.cpp; sourceTree = "<group>"; };
8710707229C4A5E70094D0F3 /* GarminConnect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = GarminConnect.swift; path = ../src/ios/GarminConnect.swift; sourceTree = "<group>"; };
871189122893C92F006A04D1 /* libQt5Multimedia.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQt5Multimedia.a; path = ../../Qt/5.15.2/ios/lib/libQt5Multimedia.a; sourceTree = "<group>"; };
871189142893CB51006A04D1 /* libdeclarative_multimedia.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdeclarative_multimedia.a; path = ../../Qt/5.15.2/ios/qml/QtMultimedia/libdeclarative_multimedia.a; sourceTree = "<group>"; };
871189162893CC44006A04D1 /* libQt5MultimediaQuick.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQt5MultimediaQuick.a; path = ../../Qt/5.15.2/ios/lib/libQt5MultimediaQuick.a; sourceTree = "<group>"; };
@@ -898,26 +857,14 @@
8727A47527849EA600019B5D /* paferstreadmill.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = paferstreadmill.h; path = ../src/paferstreadmill.h; sourceTree = "<group>"; };
8727A47627849EA600019B5D /* paferstreadmill.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = paferstreadmill.cpp; path = ../src/paferstreadmill.cpp; sourceTree = "<group>"; };
8727A47827849EB200019B5D /* moc_paferstreadmill.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_paferstreadmill.cpp; sourceTree = "<group>"; };
8727C7CC2B3BF1B8005429EB /* proformtelnetbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = proformtelnetbike.cpp; path = ../src/proformtelnetbike.cpp; sourceTree = "<group>"; };
8727C7CD2B3BF1B8005429EB /* proformtelnetbike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = proformtelnetbike.h; path = ../src/proformtelnetbike.h; sourceTree = "<group>"; };
8727C7CE2B3BF1B8005429EB /* QTelnet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QTelnet.h; path = ../src/QTelnet.h; sourceTree = "<group>"; };
8727C7CF2B3BF1B8005429EB /* QTelnet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = QTelnet.cpp; path = ../src/QTelnet.cpp; sourceTree = "<group>"; };
8727C7D22B3BF1E4005429EB /* moc_QTelnet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_QTelnet.cpp; sourceTree = "<group>"; };
8727C7D32B3BF1E4005429EB /* moc_proformtelnetbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_proformtelnetbike.cpp; sourceTree = "<group>"; };
8729149E2B2B010600565E33 /* qdomyoszwift-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "qdomyoszwift-Bridging-Header.h"; sourceTree = "<group>"; };
872A20D828C5EC380037774D /* faketreadmill.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = faketreadmill.h; path = ../src/faketreadmill.h; sourceTree = "<group>"; };
872A20D928C5EC380037774D /* faketreadmill.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = faketreadmill.cpp; path = ../src/faketreadmill.cpp; sourceTree = "<group>"; };
872A20DB28C5F5CE0037774D /* moc_faketreadmill.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_faketreadmill.cpp; sourceTree = "<group>"; };
872BAB4D261750EE006A59AB /* libQt5Charts.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQt5Charts.a; path = ../../Qt/5.15.2/ios/lib/libQt5Charts.a; sourceTree = "<group>"; };
872BAB4F261751FB006A59AB /* libqtchartsqml2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libqtchartsqml2.a; path = ../../Qt/5.15.2/ios/qml/QtCharts/libqtchartsqml2.a; sourceTree = "<group>"; };
872DCC372A18D4A800EC9F68 /* virtualdevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = virtualdevice.h; path = ../src/virtualdevice.h; sourceTree = "<group>"; };
872DCC382A18D4A800EC9F68 /* virtualdevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = virtualdevice.cpp; path = ../src/virtualdevice.cpp; sourceTree = "<group>"; };
872DCC3A2A18D4C000EC9F68 /* moc_virtualdevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_virtualdevice.cpp; sourceTree = "<group>"; };
873063BC259DF20000DA0F44 /* heartratebelt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = heartratebelt.cpp; path = ../src/heartratebelt.cpp; sourceTree = "<group>"; };
873063BD259DF20000DA0F44 /* heartratebelt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = heartratebelt.h; path = ../src/heartratebelt.h; sourceTree = "<group>"; };
873063BF259DF2C500DA0F44 /* moc_heartratebelt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_heartratebelt.cpp; sourceTree = "<group>"; };
8730A3902B4040AF007E336D /* zwift_messages.pb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = zwift_messages.pb.swift; path = "../src/zwift-api/zwift_messages.pb.swift"; sourceTree = "<group>"; };
8730A3912B404159007E336D /* zwift_protobuf_layer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = zwift_protobuf_layer.swift; path = "../src/zwift-api/zwift_protobuf_layer.swift"; sourceTree = "<group>"; };
87310B1A266FBB54008BA0D6 /* homefitnessbuddy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = homefitnessbuddy.h; path = ../src/homefitnessbuddy.h; sourceTree = "<group>"; };
87310B1B266FBB54008BA0D6 /* smartrowrower.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = smartrowrower.cpp; path = ../src/smartrowrower.cpp; sourceTree = "<group>"; };
87310B1C266FBB57008BA0D6 /* homefitnessbuddy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = homefitnessbuddy.cpp; path = ../src/homefitnessbuddy.cpp; sourceTree = "<group>"; };
@@ -1017,7 +964,6 @@
873CD22927EF8E4B000131BC /* iosinapppurchaseproduct.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = iosinapppurchaseproduct.mm; path = ../src/purchasing/ios/iosinapppurchaseproduct.mm; sourceTree = "<group>"; };
873CD22A27EF8E4B000131BC /* iosinapppurchasetransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iosinapppurchasetransaction.h; path = ../src/purchasing/ios/iosinapppurchasetransaction.h; sourceTree = "<group>"; };
873CD22E27EF8EC1000131BC /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
873D388A29B0D744006A2611 /* ConnectIQ.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = ConnectIQ.xcframework; path = ../src/ConnectIQ/iOS/ConnectIQ.xcframework; sourceTree = "<group>"; };
873F022D274BE471002D0349 /* mcfbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mcfbike.cpp; path = ../src/mcfbike.cpp; sourceTree = "<group>"; };
873F022E274BE471002D0349 /* mcfbike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mcfbike.h; path = ../src/mcfbike.h; sourceTree = "<group>"; };
873F0230274BE47D002D0349 /* moc_mcfbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_mcfbike.cpp; sourceTree = "<group>"; };
@@ -1032,9 +978,6 @@
87440FBB2640291700E4DC0B /* fitplusbike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fitplusbike.h; path = ../src/fitplusbike.h; sourceTree = "<group>"; };
87440FBC2640291700E4DC0B /* fitplusbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fitplusbike.cpp; path = ../src/fitplusbike.cpp; sourceTree = "<group>"; };
87440FBE2640292900E4DC0B /* moc_fitplusbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_fitplusbike.cpp; sourceTree = "<group>"; };
8745B2742AFCB3B300991A39 /* libadb.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libadb.a; path = ../src/ios/libadb.a; sourceTree = "<group>"; };
8745B2752AFCB4A300991A39 /* android */ = {isa = PBXFileReference; lastKnownFileType = folder; name = android; path = ../src/ios/android; sourceTree = "<group>"; };
8745B2772AFCB52800991A39 /* AdbClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AdbClient.h; path = ../src/ios/AdbClient.h; sourceTree = "<group>"; };
87473A9427ECA9EE00C203F5 /* proformrower.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = proformrower.h; path = ../src/proformrower.h; sourceTree = "<group>"; };
87473A9527ECA9EE00C203F5 /* proformrower.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = proformrower.cpp; path = ../src/proformrower.cpp; sourceTree = "<group>"; };
87473A9727ECAA0500C203F5 /* moc_proformrower.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_proformrower.cpp; sourceTree = "<group>"; };
@@ -1042,11 +985,6 @@
874D271F29AFA11F0007C079 /* apexbike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = apexbike.h; path = ../src/apexbike.h; sourceTree = "<group>"; };
874D272129AFA13B0007C079 /* moc_apexbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_apexbike.cpp; sourceTree = "<group>"; };
8752B4CC27F43D9200E2EC6C /* qz.storekit */ = {isa = PBXFileReference; lastKnownFileType = text; path = qz.storekit; sourceTree = "<group>"; };
8752C0E22B15D84100C3D1A5 /* moc_eliteariafan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_eliteariafan.cpp; sourceTree = "<group>"; };
8752C0E42B15D85600C3D1A5 /* eliteariafan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = eliteariafan.cpp; path = ../src/eliteariafan.cpp; sourceTree = "<group>"; };
8752C0E52B15D85600C3D1A5 /* eliteariafan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = eliteariafan.h; path = ../src/eliteariafan.h; sourceTree = "<group>"; };
8752C0E62B15D85600C3D1A5 /* ios_eliteariafan.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ios_eliteariafan.mm; path = ../src/ios/ios_eliteariafan.mm; sourceTree = "<group>"; };
8752C0E72B15D85600C3D1A5 /* ios_eliteariafan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ios_eliteariafan.h; path = ../src/ios/ios_eliteariafan.h; sourceTree = "<group>"; };
87540FAC2848FD70005E0D44 /* libqtexttospeech_speechios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libqtexttospeech_speechios.a; path = ../../Qt/5.15.2/ios/plugins/texttospeech/libqtexttospeech_speechios.a; sourceTree = "<group>"; };
8754D24B27F786F0003D7054 /* virtualrower.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = virtualrower.swift; path = ../src/ios/virtualrower.swift; sourceTree = "<group>"; };
87586A3F25B8340D00A243C4 /* proformbike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = proformbike.h; path = ../src/proformbike.h; sourceTree = "<group>"; };
@@ -1116,9 +1054,6 @@
8772A0E425E43AD90080718C /* trxappgateusbbike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = trxappgateusbbike.h; path = ../src/trxappgateusbbike.h; sourceTree = "<group>"; };
8772A0E525E43ADA0080718C /* trxappgateusbbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = trxappgateusbbike.cpp; path = ../src/trxappgateusbbike.cpp; sourceTree = "<group>"; };
8772A0E725E43AE70080718C /* moc_trxappgateusbbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_trxappgateusbbike.cpp; sourceTree = "<group>"; };
8775008129E876F7008E48B7 /* iconceptelliptical.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = iconceptelliptical.cpp; path = ../src/iconceptelliptical.cpp; sourceTree = "<group>"; };
8775008229E876F7008E48B7 /* iconceptelliptical.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iconceptelliptical.h; path = ../src/iconceptelliptical.h; sourceTree = "<group>"; };
8775008429E87712008E48B7 /* moc_iconceptelliptical.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_iconceptelliptical.cpp; sourceTree = "<group>"; };
877A7606269D8E0F0024DD2C /* libqtwebview_darwin_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libqtwebview_darwin_debug.a; path = ../../Qt/5.15.2/ios/plugins/webview/libqtwebview_darwin_debug.a; sourceTree = "<group>"; };
877A7608269D8E9F0024DD2C /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
877FBA27276E684400F6C0C9 /* bowflextreadmill.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bowflextreadmill.cpp; path = ../src/bowflextreadmill.cpp; sourceTree = "<group>"; };
@@ -1142,10 +1077,6 @@
878531632711A3E1004B153D /* fakebike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fakebike.h; path = ../src/fakebike.h; sourceTree = "<group>"; };
878531662711A3EB004B153D /* moc_activiotreadmill.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_activiotreadmill.cpp; sourceTree = "<group>"; };
878531672711A3EB004B153D /* moc_fakebike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_fakebike.cpp; sourceTree = "<group>"; };
8785D53F2B3DD0EC005A2EB7 /* zwift_client_auth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = zwift_client_auth.h; path = "../src/zwift-api/zwift_client_auth.h"; sourceTree = "<group>"; };
8785D5402B3DD0EC005A2EB7 /* PlayerStateWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlayerStateWrapper.h; path = "../src/zwift-api/PlayerStateWrapper.h"; sourceTree = "<group>"; };
8785D5412B3DD105005A2EB7 /* moc_PlayerStateWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_PlayerStateWrapper.cpp; sourceTree = "<group>"; };
8785D5422B3DD105005A2EB7 /* moc_zwift_client_auth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_zwift_client_auth.cpp; sourceTree = "<group>"; };
8789DCDB6A4F681A76DF3F92 /* Qt5Widgets */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = Qt5Widgets; path = "/Users/cagnulein/Qt/5.15.2/ios/lib/libQt5Widgets$(QT_LIBRARY_SUFFIX).a"; sourceTree = "<absolute>"; };
878A331725AB4FF800BD13E1 /* yesoulbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = yesoulbike.cpp; path = ../src/yesoulbike.cpp; sourceTree = "<group>"; };
878A331825AB4FF800BD13E1 /* yesoulbike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = yesoulbike.h; path = ../src/yesoulbike.h; sourceTree = "<group>"; };
@@ -1153,9 +1084,6 @@
878C9E6728B77E7B00669129 /* nordictrackifitadbbike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = nordictrackifitadbbike.h; path = ../src/nordictrackifitadbbike.h; sourceTree = "<group>"; };
878C9E6828B77E7B00669129 /* nordictrackifitadbbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = nordictrackifitadbbike.cpp; path = ../src/nordictrackifitadbbike.cpp; sourceTree = "<group>"; };
878C9E6A28B77E9800669129 /* moc_nordictrackifitadbbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_nordictrackifitadbbike.cpp; sourceTree = "<group>"; };
878D83722A1F33C600D7F004 /* bkoolbike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bkoolbike.h; path = ../src/bkoolbike.h; sourceTree = "<group>"; };
878D83732A1F33C600D7F004 /* bkoolbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bkoolbike.cpp; path = ../src/bkoolbike.cpp; sourceTree = "<group>"; };
878D83752A1F33D900D7F004 /* moc_bkoolbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_bkoolbike.cpp; sourceTree = "<group>"; };
87900DC4268B672E000CB351 /* renphobike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = renphobike.h; path = ../src/renphobike.h; sourceTree = "<group>"; };
87900DC5268B672E000CB351 /* renphobike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = renphobike.cpp; path = ../src/renphobike.cpp; sourceTree = "<group>"; };
87900DC7268B673C000CB351 /* moc_renphobike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_renphobike.cpp; sourceTree = "<group>"; };
@@ -1169,8 +1097,6 @@
8791A8A725C8602A003B50B2 /* inspirebike.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = inspirebike.h; path = ../src/inspirebike.h; sourceTree = "<group>"; };
8791A8A825C8602A003B50B2 /* inspirebike.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = inspirebike.cpp; path = ../src/inspirebike.cpp; sourceTree = "<group>"; };
8791A8A925C8603F003B50B2 /* moc_inspirebike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_inspirebike.cpp; sourceTree = "<group>"; };
87943AB229E0215D007575F2 /* localipaddress.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = localipaddress.cpp; path = ../src/localipaddress.cpp; sourceTree = "<group>"; };
87943AB329E0215D007575F2 /* localipaddress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = localipaddress.h; path = ../src/localipaddress.h; sourceTree = "<group>"; };
87958F1727628D4500124B24 /* elitesterzosmart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = elitesterzosmart.h; path = ../src/elitesterzosmart.h; sourceTree = "<group>"; };
87958F1827628D4500124B24 /* elitesterzosmart.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = elitesterzosmart.cpp; path = ../src/elitesterzosmart.cpp; sourceTree = "<group>"; };
87958F1A27628D5400124B24 /* moc_elitesterzosmart.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_elitesterzosmart.cpp; sourceTree = "<group>"; };
@@ -1200,14 +1126,9 @@
87A0C4BA262329A600121A76 /* npecablebike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = npecablebike.h; path = ../src/npecablebike.h; sourceTree = "<group>"; };
87A0C4BD262329B500121A76 /* moc_cscbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_cscbike.cpp; sourceTree = "<group>"; };
87A0C4BE262329B500121A76 /* moc_npecablebike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_npecablebike.cpp; sourceTree = "<group>"; };
87A0D7502A3A4517005147F2 /* fakerower.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fakerower.cpp; path = ../src/fakerower.cpp; sourceTree = "<group>"; };
87A0D7512A3A4517005147F2 /* fakerower.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fakerower.h; path = ../src/fakerower.h; sourceTree = "<group>"; };
87A0D7532A3A4547005147F2 /* moc_fakerower.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_fakerower.cpp; sourceTree = "<group>"; };
87A18F052660D5C0002D7C96 /* ftmsrower.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ftmsrower.cpp; path = ../src/ftmsrower.cpp; sourceTree = "<group>"; };
87A18F062660D5C1002D7C96 /* ftmsrower.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ftmsrower.h; path = ../src/ftmsrower.h; sourceTree = "<group>"; };
87A18F082660D5D9002D7C96 /* moc_ftmsrower.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_ftmsrower.cpp; sourceTree = "<group>"; };
87A2E0202B2B024200E6168F /* swiftDebug.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = swiftDebug.h; path = ../src/ios/swiftDebug.h; sourceTree = "<group>"; };
87A2E0212B2B053E00E6168F /* swiftDebug.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = swiftDebug.mm; path = ../src/ios/swiftDebug.mm; sourceTree = "<group>"; };
87A3BC1E2656429300D302E3 /* echelonrower.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = echelonrower.h; path = ../src/echelonrower.h; sourceTree = "<group>"; };
87A3BC1F2656429400D302E3 /* rower.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rower.cpp; path = ../src/rower.cpp; sourceTree = "<group>"; };
87A3BC202656429400D302E3 /* echelonrower.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = echelonrower.cpp; path = ../src/echelonrower.cpp; sourceTree = "<group>"; };
@@ -1237,9 +1158,6 @@
87B617F125F260150094A1CB /* moc_screencapture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_screencapture.cpp; sourceTree = "<group>"; };
87BB1773269E983200F46A1C /* moc_webserverinfosender.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_webserverinfosender.cpp; sourceTree = "<group>"; };
87BB1775269E987000F46A1C /* libQt5HttpServer.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQt5HttpServer.a; path = ../../Qt/5.15.2/ios/lib/libQt5HttpServer.a; sourceTree = "<group>"; };
87BCE6BB29F28F72001F70EB /* ypooelliptical.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ypooelliptical.h; path = ../src/ypooelliptical.h; sourceTree = "<group>"; };
87BCE6BC29F28F72001F70EB /* ypooelliptical.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ypooelliptical.cpp; path = ../src/ypooelliptical.cpp; sourceTree = "<group>"; };
87BCE6BE29F28F94001F70EB /* moc_ypooelliptical.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_ypooelliptical.cpp; sourceTree = "<group>"; };
87BE6FDA272D2A3100C35795 /* horizongr7bike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = horizongr7bike.cpp; path = ../src/horizongr7bike.cpp; sourceTree = "<group>"; };
87BE6FDB272D2A3100C35795 /* horizongr7bike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = horizongr7bike.h; path = ../src/horizongr7bike.h; sourceTree = "<group>"; };
87BE6FDD272D2A3E00C35795 /* moc_horizongr7bike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_horizongr7bike.cpp; sourceTree = "<group>"; };
@@ -1312,7 +1230,6 @@
87D269A125F535300076AA48 /* moc_skandikawiribike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_skandikawiribike.cpp; sourceTree = "<group>"; };
87D269A225F535300076AA48 /* moc_m3ibike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_m3ibike.cpp; sourceTree = "<group>"; };
87D44180269DE979003263D5 /* webserverinfosender.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = webserverinfosender.cpp; path = ../src/webserverinfosender.cpp; sourceTree = "<group>"; };
87D4693529B64D8100C9A382 /* ios_app_delegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ios_app_delegate.mm; path = ../src/ios/ios_app_delegate.mm; sourceTree = "<group>"; };
87D5DC3E2823047D008CCDE7 /* truetreadmill.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = truetreadmill.cpp; path = ../src/truetreadmill.cpp; sourceTree = "<group>"; };
87D5DC3F2823047D008CCDE7 /* truetreadmill.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = truetreadmill.h; path = ../src/truetreadmill.h; sourceTree = "<group>"; };
87D5DC4128230496008CCDE7 /* moc_truetreadmill.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_truetreadmill.cpp; sourceTree = "<group>"; };
@@ -1376,9 +1293,6 @@
87F02E3E29178523000DB52C /* octaneelliptical.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = octaneelliptical.cpp; path = ../src/octaneelliptical.cpp; sourceTree = "<group>"; };
87F02E3F29178524000DB52C /* octaneelliptical.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = octaneelliptical.h; path = ../src/octaneelliptical.h; sourceTree = "<group>"; };
87F02E4129178545000DB52C /* moc_octaneelliptical.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_octaneelliptical.cpp; sourceTree = "<group>"; };
87F4FB5829D550BF0061BB4A /* schwinn170bike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = schwinn170bike.cpp; path = ../src/schwinn170bike.cpp; sourceTree = "<group>"; };
87F4FB5929D550BF0061BB4A /* schwinn170bike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = schwinn170bike.h; path = ../src/schwinn170bike.h; sourceTree = "<group>"; };
87F4FB5B29D550DF0061BB4A /* moc_schwinn170bike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_schwinn170bike.cpp; sourceTree = "<group>"; };
87F527BC28EEB5AA00A9F8D5 /* qzsettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = qzsettings.cpp; path = ../src/qzsettings.cpp; sourceTree = "<group>"; };
87F527BD28EEB5AA00A9F8D5 /* qzsettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qzsettings.h; path = ../src/qzsettings.h; sourceTree = "<group>"; };
87F93425278E0EC00088B596 /* domyosrower.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = domyosrower.h; path = ../src/domyosrower.h; sourceTree = "<group>"; };
@@ -1604,7 +1518,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8745B2782AFCB87B00991A39 /* libadb.a in Link Binary With Libraries */,
879F74112893D5B8009A64C8 /* libqavfcamera.a in Link Binary With Libraries */,
879F740F2893D592009A64C8 /* libqtmedia_audioengine.a in Link Binary With Libraries */,
879F740C2893D4FA009A64C8 /* libqtaudio_coreaudio.a in Link Binary With Libraries */,
@@ -1685,16 +1598,13 @@
4FA524144B680D741D33EACB /* qtgraphicaleffectsprivate in Link Binary With Libraries */,
879F74152893D732009A64C8 /* CoreMedia.framework in Link Binary With Libraries */,
1C823E40F377B93A664EAC1B /* modelsplugin in Link Binary With Libraries */,
8730A38D2B404081007E336D /* SwiftProtobufPluginLibrary in Link Binary With Libraries */,
B9DED9CC16B0F3339F363FBF /* workerscriptplugin in Link Binary With Libraries */,
023642106C14651D2E1F4D5D /* dialogplugin in Link Binary With Libraries */,
133CA0345CD2BFB03079A655 /* qmlfolderlistmodelplugin in Link Binary With Libraries */,
4AAA7380490CBDBAA8587CFA /* qmlsettingsplugin in Link Binary With Libraries */,
873D388B29B0D745006A2611 /* ConnectIQ.xcframework in Link Binary With Libraries */,
3BD5A5F95DF5239184791B58 /* dialogsprivateplugin in Link Binary With Libraries */,
EF98F8C34BE322582E9B73D7 /* qtquickcontrolsplugin in Link Binary With Libraries */,
7C8D236C48F2964061C3457C /* widgetsplugin in Link Binary With Libraries */,
8730A38B2B404081007E336D /* SwiftProtobuf in Link Binary With Libraries */,
401B341C04019FFA2146E79D /* Qt5Widgets in Link Binary With Libraries */,
61EC5BE7EEC8D905C63FF628 /* qmlplugin in Link Binary With Libraries */,
877A080D2893DC4300C0F0AB /* CoreVideo.framework in Link Binary With Libraries */,
@@ -1708,7 +1618,6 @@
5A4A6C1B12D4D769431E876E /* qtquickcontrols2materialstyleplugin in Link Binary With Libraries */,
A044AC393BA2327284BB63B4 /* qtquickcontrols2fusionstyleplugin in Link Binary With Libraries */,
B413AFE7A08F2D63D57F683E /* qtquickcontrols2universalstyleplugin in Link Binary With Libraries */,
8730A38F2B404081007E336D /* protoc-gen-swift in Link Binary With Libraries */,
7BA3E396471B90F086588B5C /* qtgraphicaleffectsplugin in Link Binary With Libraries */,
F020E5470020A5BF3EB828A3 /* qtquickcontrols2imaginestyleplugin in Link Binary With Libraries */,
964DFEF4056724121ED9A98D /* Qt5QuickControls2 in Link Binary With Libraries */,
@@ -1765,13 +1674,6 @@
25B08E2869634E9BCBA333A2 /* Generated Sources */ = {
isa = PBXGroup;
children = (
87A0D7532A3A4547005147F2 /* moc_fakerower.cpp */,
878D83752A1F33D900D7F004 /* moc_bkoolbike.cpp */,
872DCC3A2A18D4C000EC9F68 /* moc_virtualdevice.cpp */,
87BCE6BE29F28F94001F70EB /* moc_ypooelliptical.cpp */,
8775008429E87712008E48B7 /* moc_iconceptelliptical.cpp */,
8710706D29C48AF30094D0F3 /* moc_handleurl.cpp */,
87F4FB5B29D550DF0061BB4A /* moc_schwinn170bike.cpp */,
87B187BC29B8C577007EEF9D /* moc_ziprotreadmill.cpp */,
87A0771129B6420200A368BF /* moc_wahookickrheadwind.cpp */,
874D272129AFA13B0007C079 /* moc_apexbike.cpp */,
@@ -1933,42 +1835,6 @@
2EB56BE3C2D93CDAB0C52E67 /* Sources */ = {
isa = PBXGroup;
children = (
8730A3902B4040AF007E336D /* zwift_messages.pb.swift */,
8785D5412B3DD105005A2EB7 /* moc_PlayerStateWrapper.cpp */,
8785D5422B3DD105005A2EB7 /* moc_zwift_client_auth.cpp */,
8785D5402B3DD0EC005A2EB7 /* PlayerStateWrapper.h */,
8785D53F2B3DD0EC005A2EB7 /* zwift_client_auth.h */,
8727C7D32B3BF1E4005429EB /* moc_proformtelnetbike.cpp */,
8727C7D22B3BF1E4005429EB /* moc_QTelnet.cpp */,
8727C7CC2B3BF1B8005429EB /* proformtelnetbike.cpp */,
8727C7CD2B3BF1B8005429EB /* proformtelnetbike.h */,
8727C7CF2B3BF1B8005429EB /* QTelnet.cpp */,
8727C7CE2B3BF1B8005429EB /* QTelnet.h */,
87A2E0212B2B053E00E6168F /* swiftDebug.mm */,
8729149E2B2B010600565E33 /* qdomyoszwift-Bridging-Header.h */,
8752C0E42B15D85600C3D1A5 /* eliteariafan.cpp */,
8752C0E52B15D85600C3D1A5 /* eliteariafan.h */,
8752C0E72B15D85600C3D1A5 /* ios_eliteariafan.h */,
8752C0E62B15D85600C3D1A5 /* ios_eliteariafan.mm */,
8752C0E22B15D84100C3D1A5 /* moc_eliteariafan.cpp */,
8745B2772AFCB52800991A39 /* AdbClient.h */,
87A0D7502A3A4517005147F2 /* fakerower.cpp */,
87A0D7512A3A4517005147F2 /* fakerower.h */,
878D83732A1F33C600D7F004 /* bkoolbike.cpp */,
878D83722A1F33C600D7F004 /* bkoolbike.h */,
872DCC382A18D4A800EC9F68 /* virtualdevice.cpp */,
872DCC372A18D4A800EC9F68 /* virtualdevice.h */,
87BCE6BC29F28F72001F70EB /* ypooelliptical.cpp */,
87BCE6BB29F28F72001F70EB /* ypooelliptical.h */,
8775008129E876F7008E48B7 /* iconceptelliptical.cpp */,
8775008229E876F7008E48B7 /* iconceptelliptical.h */,
87943AB229E0215D007575F2 /* localipaddress.cpp */,
87943AB329E0215D007575F2 /* localipaddress.h */,
8710706B29C48AEA0094D0F3 /* handleurl.cpp */,
8710706A29C48AE90094D0F3 /* handleurl.h */,
87D4693529B64D8100C9A382 /* ios_app_delegate.mm */,
87F4FB5829D550BF0061BB4A /* schwinn170bike.cpp */,
87F4FB5929D550BF0061BB4A /* schwinn170bike.h */,
87B187B929B8C552007EEF9D /* ziprotreadmill.cpp */,
87B187BA29B8C552007EEF9D /* ziprotreadmill.h */,
87A0770F29B641D500A368BF /* wahookickrheadwind.cpp */,
@@ -2308,9 +2174,6 @@
68418A2D51B69FC30BF5A41C /* virtualbike.h */,
35E903698E72424585D33829 /* virtualtreadmill.h */,
C8CE72E7B224D8B886614E3F /* domyosbike.h */,
8710707229C4A5E70094D0F3 /* GarminConnect.swift */,
87A2E0202B2B024200E6168F /* swiftDebug.h */,
8730A3912B404159007E336D /* zwift_protobuf_layer.swift */,
);
name = Sources;
sourceTree = "<group>";
@@ -2403,8 +2266,6 @@
AF39DD055C3EF8226FBE929D /* Frameworks */ = {
isa = PBXGroup;
children = (
8745B2742AFCB3B300991A39 /* libadb.a */,
873D388A29B0D744006A2611 /* ConnectIQ.xcframework */,
879F74142893D732009A64C8 /* CoreMedia.framework */,
879F74122893D705009A64C8 /* CoreVideo.framework */,
879F74102893D5B7009A64C8 /* libqavfcamera.a */,
@@ -2793,7 +2654,6 @@
E8C543AB96796ECAA2E65C57 /* qdomyoszwift */ = {
isa = PBXGroup;
children = (
8745B2752AFCB4A300991A39 /* android */,
8752B4CC27F43D9200E2EC6C /* qz.storekit */,
2EB56BE3C2D93CDAB0C52E67 /* Sources */,
25B08E2869634E9BCBA333A2 /* Generated Sources */,
@@ -2838,11 +2698,6 @@
876E4E312594748100BD5714 /* PBXTargetDependency */,
);
name = qdomyoszwift;
packageProductDependencies = (
8730A38A2B404081007E336D /* SwiftProtobuf */,
8730A38C2B404081007E336D /* SwiftProtobufPluginLibrary */,
8730A38E2B404081007E336D /* protoc-gen-swift */,
);
productName = qdomyoszwift;
productReference = 040B10E2EF2CEF79F2205FE2 /* qdomyoszwift.app */;
productType = "com.apple.product-type.application";
@@ -2918,9 +2773,6 @@
Base,
);
mainGroup = E8C543AB96796ECAA2E65C57 /* qdomyoszwift */;
packageReferences = (
8730A3892B404081007E336D /* XCRemoteSwiftPackageReference "swift-protobuf" */,
);
productRefGroup = FE0A091FDBFB3E9C31B7A1BD /* Products */;
projectDirPath = "";
projectRoot = "";
@@ -2938,7 +2790,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8745B2762AFCB4A300991A39 /* android in Copy Bundle Resources */,
87C5F0BC26285E5F0067A1B5 /* SmtpMime in Copy Bundle Resources */,
2188AA0A52E9CD610922F82E /* Default-568h@2x.png in Copy Bundle Resources */,
8752B4CD27F43D9200E2EC6C /* qz.storekit in Copy Bundle Resources */,
@@ -3025,7 +2876,6 @@
87D269A425F535340076AA48 /* moc_m3ibike.cpp in Compile Sources */,
EA780CE97E201242E33E6EEE /* bike.cpp in Compile Sources */,
8738249827E646E3004F1B46 /* dirconmanager.cpp in Compile Sources */,
87D4693629B64D8100C9A382 /* ios_app_delegate.mm in Compile Sources */,
87C5F0D926285E7E0067A1B5 /* moc_mimeattachment.cpp in Compile Sources */,
87B617F225F260150094A1CB /* moc_fitshowtreadmill.cpp in Compile Sources */,
87473A9627ECA9EE00C203F5 /* proformrower.cpp in Compile Sources */,
@@ -3061,20 +2911,15 @@
87DF68BD25E2675100FCDA46 /* moc_eslinkertreadmill.cpp in Compile Sources */,
87646C2027B5064600F82131 /* bhfitnesselliptical.cpp in Compile Sources */,
8718CBAD263063CE004BF4EE /* moc_templateinfosender.cpp in Compile Sources */,
8752C0E32B15D84100C3D1A5 /* moc_eliteariafan.cpp in Compile Sources */,
8752C0E92B15D85600C3D1A5 /* ios_eliteariafan.mm in Compile Sources */,
87C5F0D326285E7E0067A1B5 /* moc_mimecontentformatter.cpp in Compile Sources */,
8718CBAB263063CE004BF4EE /* moc_templateinfosenderbuilder.cpp in Compile Sources */,
C6B3CD471768392E18F85819 /* fit_accumulated_field.cpp in Compile Sources */,
8730A3932B4078E6007E336D /* zwift_messages.pb.swift in Compile Sources */,
3D7395B0A17915A06361C7F3 /* fit_accumulator.cpp in Compile Sources */,
2A61806454201575EDB3F94F /* fit_buffer_encode.cpp in Compile Sources */,
87F02E4229178545000DB52C /* moc_octaneelliptical.cpp in Compile Sources */,
87E2F85D291ED308002BDC65 /* lifefitnesstreadmill.cpp in Compile Sources */,
8752C0E82B15D85600C3D1A5 /* eliteariafan.cpp in Compile Sources */,
87917A7328E768D200F8D9AC /* Browser.swift in Compile Sources */,
873CD20B27EF8D8A000131BC /* inapptransaction.cpp in Compile Sources */,
8727C7D52B3BF1E4005429EB /* moc_proformtelnetbike.cpp in Compile Sources */,
873824EF27E647A9004F1B46 /* query.cpp in Compile Sources */,
876F45FF279350D9003CDA5A /* moc_concept2skierg.cpp in Compile Sources */,
BE93C6EF2C2A6BFEEC9EA565 /* fit_buffered_mesg_broadcaster.cpp in Compile Sources */,
@@ -3085,14 +2930,12 @@
873063C0259DF2C500DA0F44 /* moc_heartratebelt.cpp in Compile Sources */,
DD5ED224478CB82859C61B9F /* fit_buffered_record_mesg_broadcaster.cpp in Compile Sources */,
87368825259C602800C71C7E /* watchAppStart.swift in Compile Sources */,
87BCE6BF29F28F95001F70EB /* moc_ypooelliptical.cpp in Compile Sources */,
876ED21925C3E9000065F3DC /* moc_ftmsbike.cpp in Compile Sources */,
87C5F0BD26285E5F0067A1B5 /* chronobike.cpp in Compile Sources */,
872A20DA28C5EC380037774D /* faketreadmill.cpp in Compile Sources */,
87900DC8268B673C000CB351 /* moc_renphobike.cpp in Compile Sources */,
87CC3B9E25A08812001EC5A8 /* moc_elliptical.cpp in Compile Sources */,
876BFC9C27BE35C5001D7645 /* proformelliptical.cpp in Compile Sources */,
878D83762A1F33D900D7F004 /* moc_bkoolbike.cpp in Compile Sources */,
E7F190E59DC975BA4CA65F0C /* fit_crc.cpp in Compile Sources */,
87A18F092660D5D9002D7C96 /* moc_ftmsrower.cpp in Compile Sources */,
DA1DC0B761BD7A3004BCF43D /* fit_date_time.cpp in Compile Sources */,
@@ -3102,7 +2945,6 @@
87CC3B9D25A08812001EC5A8 /* moc_domyoselliptical.cpp in Compile Sources */,
87900DC6268B672E000CB351 /* renphobike.cpp in Compile Sources */,
879F16462847E55C00CE4945 /* proformellipticaltrainer.cpp in Compile Sources */,
8730A3922B404159007E336D /* zwift_protobuf_layer.swift in Compile Sources */,
87917A7728E768D200F8D9AC /* Client.swift in Compile Sources */,
873824B927E64707004F1B46 /* moc_provider.cpp in Compile Sources */,
8727A47727849EA600019B5D /* paferstreadmill.cpp in Compile Sources */,
@@ -3121,10 +2963,8 @@
87646C2227B5065100F82131 /* moc_bhfitnesselliptical.cpp in Compile Sources */,
873824B127E64706004F1B46 /* moc_browser_p.cpp in Compile Sources */,
873824B627E64707004F1B46 /* moc_hostname_p.cpp in Compile Sources */,
87A0D7542A3A4547005147F2 /* moc_fakerower.cpp in Compile Sources */,
873824EA27E647A8004F1B46 /* browser.cpp in Compile Sources */,
87E34C2B2886F95400CEDE4B /* octanetreadmill.cpp in Compile Sources */,
87A0D7522A3A4518005147F2 /* fakerower.cpp in Compile Sources */,
87B187BB29B8C552007EEF9D /* ziprotreadmill.cpp in Compile Sources */,
87BF116D298E28CA00B5B6E7 /* pelotonbike.cpp in Compile Sources */,
87DAE16A26E9FF5000B0527E /* moc_kingsmithr2treadmill.cpp in Compile Sources */,
@@ -3154,7 +2994,6 @@
876ED21625C3E8DE0065F3DC /* schwinnic4bike.cpp in Compile Sources */,
879E5AAA289C05A500FEA38A /* moc_proformwifitreadmill.cpp in Compile Sources */,
87D269A325F535340076AA48 /* moc_skandikawiribike.cpp in Compile Sources */,
87F4FB5C29D550E00061BB4A /* moc_schwinn170bike.cpp in Compile Sources */,
87C5F0C226285E5F0067A1B5 /* emailaddress.cpp in Compile Sources */,
873824AF27E64706004F1B46 /* moc_characteristicwriteprocessor2ad9.cpp in Compile Sources */,
25F2400F80DAFBD41FE5CC75 /* fit_field.cpp in Compile Sources */,
@@ -3168,7 +3007,6 @@
87097D2F275EA9A30020EE6F /* sportsplusbike.cpp in Compile Sources */,
333C629F93DB3941862924F7 /* fit_field_base.cpp in Compile Sources */,
87473A9827ECAA0500C203F5 /* moc_proformrower.cpp in Compile Sources */,
8785D5442B3DD105005A2EB7 /* moc_zwift_client_auth.cpp in Compile Sources */,
EEC10275DF646075E08DDC9B /* fit_field_definition.cpp in Compile Sources */,
87062645259480AB00D06586 /* LocalNotificationHelper.swift in Compile Sources */,
8718CBA4263063BD004BF4EE /* templateinfosenderbuilder.cpp in Compile Sources */,
@@ -3182,14 +3020,12 @@
FE77C778768741F1A161682E /* fit_mesg_definition.cpp in Compile Sources */,
875F69B926342E8D0009FD78 /* spirittreadmill.cpp in Compile Sources */,
87DF68B825E2673B00FCDA46 /* eslinkertreadmill.cpp in Compile Sources */,
87BCE6BD29F28F72001F70EB /* ypooelliptical.cpp in Compile Sources */,
87C7074327E4CF5900E79C46 /* keepbike.cpp in Compile Sources */,
878C9E6928B77E7C00669129 /* nordictrackifitadbbike.cpp in Compile Sources */,
8798C8892733E10E003148B3 /* moc_strydrunpowersensor.cpp in Compile Sources */,
8781907E2615089D0085E656 /* peloton.cpp in Compile Sources */,
2B800DC34C91D8B080DEFBE8 /* fit_mesg_with_event_broadcaster.cpp in Compile Sources */,
6DC5D7C695B8763F9E2E029F /* fit_profile.cpp in Compile Sources */,
8710706C29C48AEA0094D0F3 /* handleurl.cpp in Compile Sources */,
87C5F0B726285E5F0067A1B5 /* mimecontentformatter.cpp in Compile Sources */,
23191C28CB29474279752FD3 /* fit_protocol_validator.cpp in Compile Sources */,
275D55B5D956B2E5F1B7E46E /* fit_unicode.cpp in Compile Sources */,
@@ -3198,7 +3034,6 @@
87061399286D8D6500D2446E /* moc_wobjectdefs.cpp in Compile Sources */,
873824BA27E64707004F1B46 /* moc_server_p.cpp in Compile Sources */,
87958F1927628D4500124B24 /* elitesterzosmart.cpp in Compile Sources */,
87943AB429E0215D007575F2 /* localipaddress.cpp in Compile Sources */,
87EB917627EE5FB3002535E1 /* nautilusbike.cpp in Compile Sources */,
ACB47DC464A2BC9D39C544AD /* gpx.cpp in Compile Sources */,
6361329E515248BB41640C07 /* homeform.cpp in Compile Sources */,
@@ -3210,7 +3045,6 @@
87EB918727EE5FE7002535E1 /* moc_nautilusbike.cpp in Compile Sources */,
873824B827E64707004F1B46 /* moc_cache.cpp in Compile Sources */,
873824E427E647A8004F1B46 /* cache.cpp in Compile Sources */,
87A2E0222B2B053E00E6168F /* swiftDebug.mm in Compile Sources */,
87310B1E266FBB59008BA0D6 /* smartrowrower.cpp in Compile Sources */,
87A3BC222656429600D302E3 /* rower.cpp in Compile Sources */,
C719682D8D421AF6B2DAAEA9 /* main.cpp in Compile Sources */,
@@ -3227,13 +3061,11 @@
E40895A73216AC52D35083D9 /* signalhandler.cpp in Compile Sources */,
873CD22427EF8E18000131BC /* inappproductqmltype.cpp in Compile Sources */,
87DF68BF25E2675100FCDA46 /* moc_schwinnic4bike.cpp in Compile Sources */,
8710707329C4A5E70094D0F3 /* GarminConnect.swift in Compile Sources */,
BE1D17BBF32F04829E1B3767 /* toorxtreadmill.cpp in Compile Sources */,
879A38C8281BD83300F78B2A /* characteristicnotifier2ad9.cpp in Compile Sources */,
4697729B15991E98D6A2533D /* treadmill.cpp in Compile Sources */,
87C481FC26DFA7D1006211AD /* moc_eliterizer.cpp in Compile Sources */,
20AA270C9F447F42F5DC2FF2 /* trainprogram.cpp in Compile Sources */,
8710706E29C48AF30094D0F3 /* moc_handleurl.cpp in Compile Sources */,
87F93429278E0ECF0088B596 /* moc_domyosrower.cpp in Compile Sources */,
87C5F0C026285E5F0067A1B5 /* mimepart.cpp in Compile Sources */,
47E45EE0BB22C1E4332F1D1D /* trxappgateusbtreadmill.cpp in Compile Sources */,
@@ -3251,7 +3083,6 @@
87C5F0CF26285E7E0067A1B5 /* moc_mimepart.cpp in Compile Sources */,
87EB918A27EE5FE7002535E1 /* qdomyoszwift_qmltyperegistrations.cpp in Compile Sources */,
87182A0B276BBB1200141463 /* moc_virtualrower.cpp in Compile Sources */,
872DCC3B2A18D4C000EC9F68 /* moc_virtualdevice.cpp in Compile Sources */,
0317752B0C295CAB82D37E45 /* virtualtreadmill.cpp in Compile Sources */,
8742C2B427C92C48007D3FA0 /* moc_wahookickrsnapbike.cpp in Compile Sources */,
878531692711A3EC004B153D /* moc_fakebike.cpp in Compile Sources */,
@@ -3260,14 +3091,12 @@
87097D31275EA9AF0020EE6F /* moc_sportsplusbike.cpp in Compile Sources */,
87819080261508B10085E656 /* moc_peloton.cpp in Compile Sources */,
7EC1321DD83EAAFAA2B7109C /* domyosbike.cpp in Compile Sources */,
8775008529E87713008E48B7 /* moc_iconceptelliptical.cpp in Compile Sources */,
614192CB787D12C3E98ADE55 /* lockscreen.mm in Compile Sources */,
87A0C4BB262329A600121A76 /* npecablebike.cpp in Compile Sources */,
873CD22D27EF8E4B000131BC /* iosinapppurchaseproduct.mm in Compile Sources */,
873CD20727EF8D8A000131BC /* inappproduct.cpp in Compile Sources */,
87A3BC26265642A300D302E3 /* moc_rower.cpp in Compile Sources */,
87EFE45B27A51901006EA1C3 /* moc_nautiluselliptical.cpp in Compile Sources */,
872DCC392A18D4A800EC9F68 /* virtualdevice.cpp in Compile Sources */,
0F974CB18B3E792B42270F19 /* FitDecode.mm in Compile Sources */,
87440FBF2640292900E4DC0B /* moc_fitplusbike.cpp in Compile Sources */,
87B617EC25F25FED0094A1CB /* screencapture.cpp in Compile Sources */,
@@ -3307,16 +3136,13 @@
87D2699F25F535200076AA48 /* m3ibike.cpp in Compile Sources */,
87917A7528E768D200F8D9AC /* Connection.swift in Compile Sources */,
87FFA13727BBE3FF00924E4E /* solebike.cpp in Compile Sources */,
87F4FB5A29D550C00061BB4A /* schwinn170bike.cpp in Compile Sources */,
7352E0F0EE5366AC809B9D64 /* qrc_qml.cpp in Compile Sources */,
873824E727E647A8004F1B46 /* record.cpp in Compile Sources */,
B38F3288D4AE4025465C1953 /* moc_bike.cpp in Compile Sources */,
87EFB57025BD704A0039DD5A /* moc_proformtreadmill.cpp in Compile Sources */,
8727C7D42B3BF1E4005429EB /* moc_QTelnet.cpp in Compile Sources */,
C3D1FD2587BF6F15B58BA675 /* moc_bluetooth.cpp in Compile Sources */,
87062648259480B700D06586 /* WorkoutTracking.swift in Compile Sources */,
8C3422A825EF7ECD78951307 /* moc_bluetoothdevice.cpp in Compile Sources */,
8785D5432B3DD105005A2EB7 /* moc_PlayerStateWrapper.cpp in Compile Sources */,
1FBBC7C86C436CAAAFD37E56 /* moc_domyostreadmill.cpp in Compile Sources */,
876BFCA027BE35D8001D7645 /* moc_proformelliptical.cpp in Compile Sources */,
873824BD27E64707004F1B46 /* moc_resolver_p.cpp in Compile Sources */,
@@ -3345,7 +3171,6 @@
E8B499F921FB0AB55C7A8A8B /* moc_gpx.cpp in Compile Sources */,
87E6A85825B5C88E00371D28 /* moc_flywheelbike.cpp in Compile Sources */,
8754D24C27F786F0003D7054 /* virtualrower.swift in Compile Sources */,
878D83742A1F33C600D7F004 /* bkoolbike.cpp in Compile Sources */,
873824B727E64707004F1B46 /* moc_characteristicwriteprocessor.cpp in Compile Sources */,
87310B1F266FBB59008BA0D6 /* homefitnessbuddy.cpp in Compile Sources */,
140BAAA8823E05940EF35A38 /* moc_treadmill.cpp in Compile Sources */,
@@ -3362,8 +3187,6 @@
87D269A025F535200076AA48 /* skandikawiribike.cpp in Compile Sources */,
8738249427E646E3004F1B46 /* characteristicnotifier2a5b.cpp in Compile Sources */,
8768D1FB285081FE00F58E3A /* nordictrackifitadbtreadmill.cpp in Compile Sources */,
8727C7D12B3BF1B8005429EB /* QTelnet.cpp in Compile Sources */,
8775008329E876F8008E48B7 /* iconceptelliptical.cpp in Compile Sources */,
87B187BD29B8C577007EEF9D /* moc_ziprotreadmill.cpp in Compile Sources */,
877FBA2B276E684E00F6C0C9 /* moc_bowflextreadmill.cpp in Compile Sources */,
874D272229AFA13B0007C079 /* moc_apexbike.cpp in Compile Sources */,
@@ -3394,7 +3217,6 @@
8703BAED273C67B60058E206 /* moc_pafersbike.cpp in Compile Sources */,
873824E627E647A8004F1B46 /* hostname.cpp in Compile Sources */,
74C43649C9C4E2E5F9378019 /* moc_domyosbike.cpp in Compile Sources */,
8727C7D02B3BF1B8005429EB /* proformtelnetbike.cpp in Compile Sources */,
87E0761D277A081A00FDA0F9 /* technogymmyruntreadmillrfcomm.cpp in Compile Sources */,
873824B327E64707004F1B46 /* moc_dirconprocessor.cpp in Compile Sources */,
87A0771229B6420200A368BF /* moc_wahookickrheadwind.cpp in Compile Sources */,
@@ -3750,11 +3572,11 @@
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
"ARCHS[sdk=iphoneos*]" = arm64;
"ARCHS[sdk=iphonesimulator*]" = "$(ARCHS_STANDARD)";
"ARCHS[sdk=iphonesimulator*]" = x86_64;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 704;
CURRENT_PROJECT_VERSION = 514;
DEVELOPMENT_TEAM = 6335M7T29D;
ENABLE_BITCODE = NO;
HEADER_SEARCH_PATHS = (
@@ -3828,9 +3650,8 @@
/Users/cagnulein/Qt/5.15.2/ios/plugins/mediaservice,
/Users/cagnulein/Qt/5.15.2/ios/plugins/playlistformats,
/Users/cagnulein/Qt/5.15.2/ios/plugins/audio,
"/Users/cagnulein/qdomyos-zwift/src/ios",
);
MARKETING_VERSION = 2.16;
MARKETING_VERSION = 2.13;
OTHER_CFLAGS = (
"-pipe",
"-g",
@@ -3907,7 +3728,6 @@
QT_LIBRARY_SUFFIX = "";
SDKROOT = iphoneos;
SWIFT_INSTALL_OBJC_HEADER = YES;
SWIFT_OBJC_BRIDGING_HEADER = "qdomyoszwift-Bridging-Header.h";
SWIFT_OBJC_INTERFACE_HEADER_NAME = "$(SWIFT_MODULE_NAME)-Swift2.h";
SWIFT_PRECOMPILE_BRIDGING_HEADER = YES;
SWIFT_VERSION = 5.0;
@@ -3920,11 +3740,11 @@
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
"ARCHS[sdk=iphoneos*]" = arm64;
"ARCHS[sdk=iphonesimulator*]" = "$(ARCHS_STANDARD)";
"ARCHS[sdk=iphonesimulator*]" = x86_64;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 704;
CURRENT_PROJECT_VERSION = 514;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 6335M7T29D;
ENABLE_BITCODE = NO;
@@ -4000,9 +3820,8 @@
/Users/cagnulein/Qt/5.15.2/ios/plugins/mediaservice,
/Users/cagnulein/Qt/5.15.2/ios/plugins/playlistformats,
/Users/cagnulein/Qt/5.15.2/ios/plugins/audio,
"/Users/cagnulein/qdomyos-zwift/src/ios",
);
MARKETING_VERSION = 2.16;
MARKETING_VERSION = 2.13;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = (
"-pipe",
@@ -4080,7 +3899,6 @@
QT_LIBRARY_SUFFIX = _debug;
SDKROOT = iphoneos;
SWIFT_INSTALL_OBJC_HEADER = YES;
SWIFT_OBJC_BRIDGING_HEADER = "qdomyoszwift-Bridging-Header.h";
SWIFT_OBJC_INTERFACE_HEADER_NAME = "$(SWIFT_MODULE_NAME)-Swift2.h";
SWIFT_PRECOMPILE_BRIDGING_HEADER = YES;
SWIFT_VERSION = 5.0;
@@ -4130,7 +3948,7 @@
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 704;
CURRENT_PROJECT_VERSION = 514;
DEVELOPMENT_TEAM = 6335M7T29D;
ENABLE_BITCODE = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -4150,12 +3968,8 @@
GCC_WARN_UNUSED_VARIABLE = YES;
IBSC_MODULE = watchkit_Extension;
INFOPLIST_FILE = watchkit/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
MARKETING_VERSION = 2.16;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
MARKETING_VERSION = 2.13;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
OTHER_CODE_SIGN_FLAGS = "--generate-entitlement-der";
@@ -4226,7 +4040,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 704;
CURRENT_PROJECT_VERSION = 514;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 6335M7T29D;
ENABLE_BITCODE = YES;
@@ -4242,12 +4056,8 @@
GCC_WARN_UNUSED_VARIABLE = YES;
IBSC_MODULE = watchkit_Extension;
INFOPLIST_FILE = watchkit/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
MARKETING_VERSION = 2.16;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
MARKETING_VERSION = 2.13;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
OTHER_CODE_SIGN_FLAGS = "--generate-entitlement-der";
@@ -4267,9 +4077,8 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OBJC_BRIDGING_HEADER = "watchkit-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 4;
VALIDATE_PRODUCT = YES;
@@ -4318,7 +4127,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 704;
CURRENT_PROJECT_VERSION = 514;
DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\"";
ENABLE_BITCODE = YES;
ENABLE_PREVIEWS = YES;
@@ -4358,12 +4167,8 @@
../../Qt/5.15.2/ios/include/QtMultimedia,
);
INFOPLIST_FILE = "watchkit Extension/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.16;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 2.13;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
OTHER_CODE_SIGN_FLAGS = "--generate-entitlement-der";
@@ -4432,7 +4237,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 704;
CURRENT_PROJECT_VERSION = 514;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\"";
ENABLE_BITCODE = YES;
@@ -4468,12 +4273,8 @@
../../Qt/5.15.2/ios/include/QtMultimedia,
);
INFOPLIST_FILE = "watchkit Extension/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.16;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 2.13;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
OTHER_CODE_SIGN_FLAGS = "--generate-entitlement-der";
@@ -4493,8 +4294,7 @@
PRODUCT_NAME = "${TARGET_NAME}";
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 4;
VALIDATE_PRODUCT = YES;
@@ -4542,35 +4342,6 @@
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
8730A3892B404081007E336D /* XCRemoteSwiftPackageReference "swift-protobuf" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/apple/swift-protobuf.git";
requirement = {
kind = exactVersion;
version = 1.25.2;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
8730A38A2B404081007E336D /* SwiftProtobuf */ = {
isa = XCSwiftPackageProductDependency;
package = 8730A3892B404081007E336D /* XCRemoteSwiftPackageReference "swift-protobuf" */;
productName = SwiftProtobuf;
};
8730A38C2B404081007E336D /* SwiftProtobufPluginLibrary */ = {
isa = XCSwiftPackageProductDependency;
package = 8730A3892B404081007E336D /* XCRemoteSwiftPackageReference "swift-protobuf" */;
productName = SwiftProtobufPluginLibrary;
};
8730A38E2B404081007E336D /* protoc-gen-swift */ = {
isa = XCSwiftPackageProductDependency;
package = 8730A3892B404081007E336D /* XCRemoteSwiftPackageReference "swift-protobuf" */;
productName = "protoc-gen-swift";
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 6DB9C3763D02B1415CD9D565 /* Project object */;
}

View File

@@ -87,6 +87,8 @@
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "876E4E102594747F00BD5714"
BuildableName = "watchkit.app"
BlueprintName = "watchkit"
ReferencedContainer = "container:qdomyoszwift.xcodeproj">

View File

@@ -104,9 +104,6 @@ extension MainController: WorkoutTrackingDelegate {
"\(heartRate)" as AnyObject])
WorkoutTracking.distance = WatchKitConnection.distance
WorkoutTracking.kcal = WatchKitConnection.kcal
WorkoutTracking.speed = WatchKitConnection.speed
WorkoutTracking.power = WatchKitConnection.power
WorkoutTracking.cadence = WatchKitConnection.cadence
if Locale.current.measurementSystem != "Metric" {
self.distanceLabel.setText("Distance \(String(format:"%.2f", WorkoutTracking.distance))")

View File

@@ -24,9 +24,6 @@ class WatchKitConnection: NSObject {
public static var distance = 0.0
public static var kcal = 0.0
public static var stepCadence = 0
public static var speed = 0.0
public static var cadence = 0.0
public static var power = 0.0
weak var delegate: WatchKitConnectionDelegate?
private override init() {
@@ -69,13 +66,6 @@ extension WatchKitConnection: WatchKitConnectionProtocol {
WatchKitConnection.distance = dDistance
let dKcal = Double(result["kcal"] as! Double)
WatchKitConnection.kcal = dKcal
let dSpeed = Double(result["speed"] as! Double)
WatchKitConnection.speed = dSpeed
let dPower = Double(result["power"] as! Double)
WatchKitConnection.power = dPower
let dCadence = Double(result["cadence"] as! Double)
WatchKitConnection.cadence = dCadence
}, errorHandler: { (error) in
print(error)
})

View File

@@ -31,10 +31,6 @@ class WorkoutTracking: NSObject {
public static var cadenceTimeStamp = NSDate().timeIntervalSince1970
public static var cadenceLastSteps = Double()
public static var cadenceSteps = 0
public static var speed = Double()
public static var power = Double()
public static var cadence = Double()
public static var lastDateMetric = Date()
var sport: Int = 0
let healthStore = HKHealthStore()
let configuration = HKWorkoutConfiguration()
@@ -150,37 +146,14 @@ extension WorkoutTracking: WorkoutTrackingProtocol {
HKSampleType.workoutType()
])
var infoToShare: Set<HKSampleType> = []
if #available(watchOSApplicationExtension 10.0, *) {
infoToShare = Set([
HKSampleType.quantityType(forIdentifier: .stepCount)!,
HKSampleType.quantityType(forIdentifier: .heartRate)!,
HKSampleType.quantityType(forIdentifier: .distanceCycling)!,
HKSampleType.quantityType(forIdentifier: .distanceWalkingRunning)!,
HKSampleType.quantityType(forIdentifier: .activeEnergyBurned)!,
HKSampleType.quantityType(forIdentifier: .cyclingPower)!,
HKSampleType.quantityType(forIdentifier: .cyclingSpeed)!,
HKSampleType.quantityType(forIdentifier: .cyclingCadence)!,
HKSampleType.quantityType(forIdentifier: .runningPower)!,
HKSampleType.quantityType(forIdentifier: .runningSpeed)!,
HKSampleType.quantityType(forIdentifier: .runningStrideLength)!,
HKSampleType.quantityType(forIdentifier: .runningVerticalOscillation)!,
HKSampleType.quantityType(forIdentifier: .walkingSpeed)!,
HKSampleType.quantityType(forIdentifier: .walkingStepLength)!,
HKSampleType.workoutType()
])
} else {
// Fallback on earlier versions
infoToShare = Set([
HKSampleType.quantityType(forIdentifier: .stepCount)!,
HKSampleType.quantityType(forIdentifier: .heartRate)!,
HKSampleType.quantityType(forIdentifier: .distanceCycling)!,
HKSampleType.quantityType(forIdentifier: .distanceWalkingRunning)!,
HKSampleType.quantityType(forIdentifier: .activeEnergyBurned)!,
HKSampleType.workoutType()
])
}
let infoToShare = Set([
HKSampleType.quantityType(forIdentifier: .stepCount)!,
HKSampleType.quantityType(forIdentifier: .heartRate)!,
HKSampleType.quantityType(forIdentifier: .distanceCycling)!,
HKSampleType.quantityType(forIdentifier: .distanceWalkingRunning)!,
HKSampleType.quantityType(forIdentifier: .activeEnergyBurned)!,
HKSampleType.workoutType()
])
HKHealthStore().requestAuthorization(toShare: infoToShare, read: infoToRead) { (success, error) in
if success {
@@ -195,7 +168,6 @@ extension WorkoutTracking: WorkoutTrackingProtocol {
}
func startWorkOut() {
WorkoutTracking.lastDateMetric = Date()
print("Start workout")
configWorkout()
workoutSession.startActivity(with: Date())
@@ -340,135 +312,6 @@ extension WorkoutTracking: HKLiveWorkoutBuilderDelegate {
handleSendStatisticsData(statistics)
}
}
if(sport == 0) {
if #available(watchOSApplicationExtension 10.0, *) {
let wattPerInterval = HKQuantity(unit: HKUnit.watt(),
doubleValue: WorkoutTracking.power)
if(WorkoutTracking.lastDateMetric.distance(to: Date()) < 1) {
return
}
guard let powerType = HKQuantityType.quantityType(
forIdentifier: .cyclingPower) else {
return
}
let wattPerIntervalSample = HKQuantitySample(type: powerType,
quantity: wattPerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([wattPerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
let cadencePerInterval = HKQuantity(unit: HKUnit.count().unitDivided(by: HKUnit.second()),
doubleValue: WorkoutTracking.cadence / 60.0)
guard let cadenceType = HKQuantityType.quantityType(
forIdentifier: .cyclingCadence) else {
return
}
let cadencePerIntervalSample = HKQuantitySample(type: cadenceType,
quantity: cadencePerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([cadencePerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
let speedPerInterval = HKQuantity(unit: HKUnit.meter().unitDivided(by: HKUnit.second()),
doubleValue: WorkoutTracking.speed * 0.277778)
guard let speedType = HKQuantityType.quantityType(
forIdentifier: .cyclingSpeed) else {
return
}
let speedPerIntervalSample = HKQuantitySample(type: speedType,
quantity: speedPerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([speedPerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
} else {
// Fallback on earlier versions
}
} else if(sport == 1) {
if #available(watchOSApplicationExtension 10.0, *) {
let wattPerInterval = HKQuantity(unit: HKUnit.watt(),
doubleValue: WorkoutTracking.power)
if(WorkoutTracking.lastDateMetric.distance(to: Date()) < 1) {
return
}
guard let powerType = HKQuantityType.quantityType(
forIdentifier: .runningPower) else {
return
}
let wattPerIntervalSample = HKQuantitySample(type: powerType,
quantity: wattPerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([wattPerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
let speedPerInterval = HKQuantity(unit: HKUnit.meter().unitDivided(by: HKUnit.second()),
doubleValue: WorkoutTracking.speed * 0.277778)
guard let speedType = HKQuantityType.quantityType(
forIdentifier: .runningSpeed) else {
return
}
let speedPerIntervalSample = HKQuantitySample(type: speedType,
quantity: speedPerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([speedPerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
} else {
// Fallback on earlier versions
}
} else if(sport == 2) {
if #available(watchOSApplicationExtension 10.0, *) {
let speedPerInterval = HKQuantity(unit: HKUnit.meter().unitDivided(by: HKUnit.second()),
doubleValue: WorkoutTracking.speed * 0.277778)
guard let speedType = HKQuantityType.quantityType(
forIdentifier: .walkingSpeed) else {
return
}
let speedPerIntervalSample = HKQuantitySample(type: speedType,
quantity: speedPerInterval,
start: WorkoutTracking.lastDateMetric,
end: Date())
workoutBuilder.add([speedPerIntervalSample]) {(success, error) in
if let error = error {
print(error)
}
}
} else {
// Fallback on earlier versions
}
}
WorkoutTracking.lastDateMetric = Date()
}
func workoutBuilderDidCollectEvent(_ workoutBuilder: HKLiveWorkoutBuilder) {

View File

@@ -12,4 +12,3 @@ ANDROID_PACKAGE_SOURCE_DIR = $$PWD/src/android
ANDROID_ABIS = armeabi-v7a arm64-v8a x86 x86_64
#QMAKE_CXXFLAGS += -Werror=suggest-override

View File

@@ -28,7 +28,7 @@ $ sudo ./qdomyos-zwift
You will need to (at a minimum) to install the xcode Command Line Tools (CLI) thanks to @richardwait
https://developer.apple.com/download/more/?=xcode
Download and install https://download.qt.io/archive/qt/5.12/5.12.12/qt-opensource-mac-x64-5.12.12.dmg and simply run the qdomyos-zwift release for MacOs
Download and install http://download.qt.io/official_releases/qt/5.12/5.12.9/qt-opensource-mac-x64-5.12.9.dmg and simply run the qdomyos-zwift release for MacOs
## On Raspberry Pi Zero W
@@ -77,7 +77,7 @@ Apply the changes `sudo systemctl restart dhcpcd.service` and ensure you have in
#### Enable SSH access
You might want to access your raspberry remotely while it is attached to your fitness equipment.
You might want to access your raspberry remotely while it is attached to your fitness equipement.
`sudo raspi-config` > `Interface Options` > `SSH`
@@ -175,7 +175,7 @@ Then reboot to check operations (`sudo reboot`)
### (optional) Enable overlay FS
Once that everything is working as expected, and if you dedicate your Raspberry pi to this usage, you might want to enable the read-only overlay FS.
Once that everything is working as expected, and if you dedicate your raspeberry pi to this usage, you might want to enable the read-only overlay FS.
By enabling the overlay read-only system, your SD card will be read-only only and every file written will be to RAM.
Then at each reboot the RAM is erased and you'll revert to the initial status of the overlay file-system.

View File

@@ -18,7 +18,7 @@ Please refer to this article for more information under [QML Operations](https:/
## Configuration in NativeQT mode
This is the list of settings available in the application. These settings need to be appended to the binary command line.
This is the list of settings available in the application. These settings needs to be appended to the binary command line.
*Example :* `sudo ./qdomyos-zwift -no-gui` for disabling any graphical interface.
| **Option** | **Type** | **Default** | **Function** |
@@ -35,8 +35,8 @@ This is the list of settings available in the application. These settings need t
| -heart-service | Boolean | True | Simulate HR service (required for applications not reading FTMS) |
| -only-virtualbike | Boolean | False | |
| -only-virtualtreadmill | Boolean | False | |
| -no-reconnection | Boolean | False | QZ will not try to reconnect your fitness equipment if enabled |
| -bluetooth-relaxed | Boolean | False | In case of deconnections from QZ to your fitness equipment |
| -no-reconnection | Boolean | False | QZ will not try to reconnect your fitness equipement if enabled |
| -bluetooth-relaxed | Boolean | False | In case of deconnections from QZ to your fitness equipement |
| -bike-cadence-sensor | Boolean | False | |
| -bike-power-sensor | Boolean | False | |
| -battery-service | Boolean | False | |
@@ -45,7 +45,7 @@ This is the list of settings available in the application. These settings need t
| -run-cadence-sensor | Boolean | False | |
| -nordictrack-10-treadmill | Boolean | False | Enable NordicTrack compatibility mode |
| -train | String | | Force training program |
| -name | String | | Force bluetooth device name (if QZ struggles to find your fitness equipment) |
| -name | String | | Force bluetooth device name (if QZ struggles finding your fitness equipment) |
| -poll-device-time | Int | 200 (ms) | Frequency to refresh information from QZ to Fitness equipment |
| -bike-resistance-gain | Int | | Adjust resistance from the fitness application |
| -bike-resistance-offset | Int | | Set another resistance point than default |

File diff suppressed because it is too large Load Diff

View File

@@ -1,449 +0,0 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* 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 http_parser_h
#define http_parser_h
#ifdef __cplusplus
extern "C" {
#endif
/* Also update SONAME in the Makefile whenever you change these. */
#define HTTP_PARSER_VERSION_MAJOR 2
#define HTTP_PARSER_VERSION_MINOR 9
#define HTTP_PARSER_VERSION_PATCH 4
#include <stddef.h>
#if defined(_WIN32) && !defined(__MINGW32__) && \
(!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__)
#include <BaseTsd.h>
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#elif (defined(__sun) || defined(__sun__)) && defined(__SunOS_5_9)
#include <sys/inttypes.h>
#else
#include <stdint.h>
#endif
/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
* faster
*/
#ifndef HTTP_PARSER_STRICT
# define HTTP_PARSER_STRICT 1
#endif
/* Maximium header size allowed. If the macro is not defined
* before including this header then the default is used. To
* change the maximum header size, define the macro in the build
* environment (e.g. -DHTTP_MAX_HEADER_SIZE=<value>). To remove
* the effective limit on the size of the header, define the macro
* to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff)
*/
#ifndef HTTP_MAX_HEADER_SIZE
# define HTTP_MAX_HEADER_SIZE (80*1024)
#endif
typedef struct http_parser http_parser;
typedef struct http_parser_settings http_parser_settings;
/* Callbacks should return non-zero to indicate an error. The parser will
* then halt execution.
*
* The one exception is on_headers_complete. In a HTTP_RESPONSE parser
* returning '1' from on_headers_complete will tell the parser that it
* should not expect a body. This is used when receiving a response to a
* HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
* chunked' headers that indicate the presence of a body.
*
* Returning `2` from on_headers_complete will tell parser that it should not
* expect neither a body nor any futher responses on this connection. This is
* useful for handling responses to a CONNECT request which may not contain
* `Upgrade` or `Connection: upgrade` headers.
*
* http_data_cb does not return data chunks. It will be called arbitrarily
* many times for each string. E.G. you might get 10 callbacks for "on_url"
* each providing just a few characters more data.
*/
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
typedef int (*http_cb) (http_parser*);
/* Status Codes */
#define HTTP_STATUS_MAP(XX) \
XX(100, CONTINUE, Continue) \
XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \
XX(102, PROCESSING, Processing) \
XX(200, OK, OK) \
XX(201, CREATED, Created) \
XX(202, ACCEPTED, Accepted) \
XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \
XX(204, NO_CONTENT, No Content) \
XX(205, RESET_CONTENT, Reset Content) \
XX(206, PARTIAL_CONTENT, Partial Content) \
XX(207, MULTI_STATUS, Multi-Status) \
XX(208, ALREADY_REPORTED, Already Reported) \
XX(226, IM_USED, IM Used) \
XX(300, MULTIPLE_CHOICES, Multiple Choices) \
XX(301, MOVED_PERMANENTLY, Moved Permanently) \
XX(302, FOUND, Found) \
XX(303, SEE_OTHER, See Other) \
XX(304, NOT_MODIFIED, Not Modified) \
XX(305, USE_PROXY, Use Proxy) \
XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \
XX(308, PERMANENT_REDIRECT, Permanent Redirect) \
XX(400, BAD_REQUEST, Bad Request) \
XX(401, UNAUTHORIZED, Unauthorized) \
XX(402, PAYMENT_REQUIRED, Payment Required) \
XX(403, FORBIDDEN, Forbidden) \
XX(404, NOT_FOUND, Not Found) \
XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \
XX(406, NOT_ACCEPTABLE, Not Acceptable) \
XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \
XX(408, REQUEST_TIMEOUT, Request Timeout) \
XX(409, CONFLICT, Conflict) \
XX(410, GONE, Gone) \
XX(411, LENGTH_REQUIRED, Length Required) \
XX(412, PRECONDITION_FAILED, Precondition Failed) \
XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \
XX(414, URI_TOO_LONG, URI Too Long) \
XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \
XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \
XX(417, EXPECTATION_FAILED, Expectation Failed) \
XX(421, MISDIRECTED_REQUEST, Misdirected Request) \
XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \
XX(423, LOCKED, Locked) \
XX(424, FAILED_DEPENDENCY, Failed Dependency) \
XX(426, UPGRADE_REQUIRED, Upgrade Required) \
XX(428, PRECONDITION_REQUIRED, Precondition Required) \
XX(429, TOO_MANY_REQUESTS, Too Many Requests) \
XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \
XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \
XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \
XX(501, NOT_IMPLEMENTED, Not Implemented) \
XX(502, BAD_GATEWAY, Bad Gateway) \
XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \
XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \
XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \
XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \
XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \
XX(508, LOOP_DETECTED, Loop Detected) \
XX(510, NOT_EXTENDED, Not Extended) \
XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \
enum http_status
{
#define XX(num, name, string) HTTP_STATUS_##name = num,
HTTP_STATUS_MAP(XX)
#undef XX
};
/* Request Methods */
#define HTTP_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \
XX(1, GET, GET) \
XX(2, HEAD, HEAD) \
XX(3, POST, POST) \
XX(4, PUT, PUT) \
/* pathological */ \
XX(5, CONNECT, CONNECT) \
XX(6, OPTIONS, OPTIONS) \
XX(7, TRACE, TRACE) \
/* WebDAV */ \
XX(8, COPY, COPY) \
XX(9, LOCK, LOCK) \
XX(10, MKCOL, MKCOL) \
XX(11, MOVE, MOVE) \
XX(12, PROPFIND, PROPFIND) \
XX(13, PROPPATCH, PROPPATCH) \
XX(14, SEARCH, SEARCH) \
XX(15, UNLOCK, UNLOCK) \
XX(16, BIND, BIND) \
XX(17, REBIND, REBIND) \
XX(18, UNBIND, UNBIND) \
XX(19, ACL, ACL) \
/* subversion */ \
XX(20, REPORT, REPORT) \
XX(21, MKACTIVITY, MKACTIVITY) \
XX(22, CHECKOUT, CHECKOUT) \
XX(23, MERGE, MERGE) \
/* upnp */ \
XX(24, MSEARCH, M-SEARCH) \
XX(25, NOTIFY, NOTIFY) \
XX(26, SUBSCRIBE, SUBSCRIBE) \
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
/* RFC-5789 */ \
XX(28, PATCH, PATCH) \
XX(29, PURGE, PURGE) \
/* CalDAV */ \
XX(30, MKCALENDAR, MKCALENDAR) \
/* RFC-2068, section 19.6.1.2 */ \
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
/* icecast */ \
XX(33, SOURCE, SOURCE) \
enum http_method
{
#define XX(num, name, string) HTTP_##name = num,
HTTP_METHOD_MAP(XX)
#undef XX
};
enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
/* Flag values for http_parser.flags field */
enum flags
{ F_CHUNKED = 1 << 0
, F_CONNECTION_KEEP_ALIVE = 1 << 1
, F_CONNECTION_CLOSE = 1 << 2
, F_CONNECTION_UPGRADE = 1 << 3
, F_TRAILING = 1 << 4
, F_UPGRADE = 1 << 5
, F_SKIPBODY = 1 << 6
, F_CONTENTLENGTH = 1 << 7
};
/* Map for errno-related constants
*
* The provided argument should be a macro that takes 2 arguments.
*/
#define HTTP_ERRNO_MAP(XX) \
/* No error */ \
XX(OK, "success") \
\
/* Callback-related errors */ \
XX(CB_message_begin, "the on_message_begin callback failed") \
XX(CB_url, "the on_url callback failed") \
XX(CB_header_field, "the on_header_field callback failed") \
XX(CB_header_value, "the on_header_value callback failed") \
XX(CB_headers_complete, "the on_headers_complete callback failed") \
XX(CB_body, "the on_body callback failed") \
XX(CB_message_complete, "the on_message_complete callback failed") \
XX(CB_status, "the on_status callback failed") \
XX(CB_chunk_header, "the on_chunk_header callback failed") \
XX(CB_chunk_complete, "the on_chunk_complete callback failed") \
\
/* Parsing-related errors */ \
XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
XX(HEADER_OVERFLOW, \
"too many header bytes seen; overflow detected") \
XX(CLOSED_CONNECTION, \
"data received after completed connection: close message") \
XX(INVALID_VERSION, "invalid HTTP version") \
XX(INVALID_STATUS, "invalid HTTP status code") \
XX(INVALID_METHOD, "invalid HTTP method") \
XX(INVALID_URL, "invalid URL") \
XX(INVALID_HOST, "invalid host") \
XX(INVALID_PORT, "invalid port") \
XX(INVALID_PATH, "invalid path") \
XX(INVALID_QUERY_STRING, "invalid query string") \
XX(INVALID_FRAGMENT, "invalid fragment") \
XX(LF_EXPECTED, "LF character expected") \
XX(INVALID_HEADER_TOKEN, "invalid character in header") \
XX(INVALID_CONTENT_LENGTH, \
"invalid character in content-length header") \
XX(UNEXPECTED_CONTENT_LENGTH, \
"unexpected content-length header") \
XX(INVALID_CHUNK_SIZE, \
"invalid character in chunk size header") \
XX(INVALID_CONSTANT, "invalid constant string") \
XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
XX(STRICT, "strict mode assertion failed") \
XX(PAUSED, "parser is paused") \
XX(UNKNOWN, "an unknown error occurred") \
XX(INVALID_TRANSFER_ENCODING, \
"request has invalid transfer-encoding") \
/* Define HPE_* values for each errno value above */
#define HTTP_ERRNO_GEN(n, s) HPE_##n,
enum http_errno {
HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
};
#undef HTTP_ERRNO_GEN
/* Get an http_errno value from an http_parser */
#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
struct http_parser {
/** PRIVATE **/
unsigned int type : 2; /* enum http_parser_type */
unsigned int flags : 8; /* F_* values from 'flags' enum; semi-public */
unsigned int state : 7; /* enum state from http_parser.c */
unsigned int header_state : 7; /* enum header_state from http_parser.c */
unsigned int index : 5; /* index into current matcher */
unsigned int uses_transfer_encoding : 1; /* Transfer-Encoding header is present */
unsigned int allow_chunked_length : 1; /* Allow headers with both
* `Content-Length` and
* `Transfer-Encoding: chunked` set */
unsigned int lenient_http_headers : 1;
uint32_t nread; /* # bytes read in various scenarios */
uint64_t content_length; /* # bytes in body. `(uint64_t) -1` (all bits one)
* if no Content-Length header.
*/
/** READ-ONLY **/
unsigned short http_major;
unsigned short http_minor;
unsigned int status_code : 16; /* responses only */
unsigned int method : 8; /* requests only */
unsigned int http_errno : 7;
/* 1 = Upgrade header was present and the parser has exited because of that.
* 0 = No upgrade header present.
* Should be checked when http_parser_execute() returns in addition to
* error checking.
*/
unsigned int upgrade : 1;
/** PUBLIC **/
void *data; /* A pointer to get hook to the "connection" or "socket" object */
};
struct http_parser_settings {
http_cb on_message_begin;
http_data_cb on_url;
http_data_cb on_status;
http_data_cb on_header_field;
http_data_cb on_header_value;
http_cb on_headers_complete;
http_data_cb on_body;
http_cb on_message_complete;
/* When on_chunk_header is called, the current chunk length is stored
* in parser->content_length.
*/
http_cb on_chunk_header;
http_cb on_chunk_complete;
};
enum http_parser_url_fields
{ UF_SCHEMA = 0
, UF_HOST = 1
, UF_PORT = 2
, UF_PATH = 3
, UF_QUERY = 4
, UF_FRAGMENT = 5
, UF_USERINFO = 6
, UF_MAX = 7
};
/* Result structure for http_parser_parse_url().
*
* Callers should index into field_data[] with UF_* values iff field_set
* has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
* because we probably have padding left over), we convert any port to
* a uint16_t.
*/
struct http_parser_url {
uint16_t field_set; /* Bitmask of (1 << UF_*) values */
uint16_t port; /* Converted UF_PORT string */
struct {
uint16_t off; /* Offset into buffer in which field starts */
uint16_t len; /* Length of run in buffer */
} field_data[UF_MAX];
};
/* Returns the library version. Bits 16-23 contain the major version number,
* bits 8-15 the minor version number and bits 0-7 the patch level.
* Usage example:
*
* unsigned long version = http_parser_version();
* unsigned major = (version >> 16) & 255;
* unsigned minor = (version >> 8) & 255;
* unsigned patch = version & 255;
* printf("http_parser v%u.%u.%u\n", major, minor, patch);
*/
unsigned long http_parser_version(void);
void http_parser_init(http_parser *parser, enum http_parser_type type);
/* Initialize http_parser_settings members to 0
*/
void http_parser_settings_init(http_parser_settings *settings);
/* Executes the parser. Returns number of parsed bytes. Sets
* `parser->http_errno` on error. */
size_t http_parser_execute(http_parser *parser,
const http_parser_settings *settings,
const char *data,
size_t len);
/* If http_should_keep_alive() in the on_headers_complete or
* on_message_complete callback returns 0, then this should be
* the last message on the connection.
* If you are the server, respond with the "Connection: close" header.
* If you are the client, close the connection.
*/
int http_should_keep_alive(const http_parser *parser);
/* Returns a string version of the HTTP method. */
const char *http_method_str(enum http_method m);
/* Returns a string version of the HTTP status code. */
const char *http_status_str(enum http_status s);
/* Return a string name of the given error */
const char *http_errno_name(enum http_errno err);
/* Return a string description of the given error */
const char *http_errno_description(enum http_errno err);
/* Initialize all http_parser_url members to 0 */
void http_parser_url_init(struct http_parser_url *u);
/* Parse a URL; return nonzero on failure */
int http_parser_parse_url(const char *buf, size_t buflen,
int is_connect,
struct http_parser_url *u);
/* Pause or un-pause the parser; a nonzero value pauses */
void http_parser_pause(http_parser *parser, int paused);
/* Checks if this is the final chunk of the body. */
int http_body_is_final(const http_parser *parser);
/* Change the maximum header size provided at compile time. */
void http_parser_set_max_header_size(uint32_t size);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,7 +1,7 @@
TEMPLATE = subdirs
CONFIG+=ordered
!ios: !android: {
!android: {
SUBDIRS = \
src/qdomyos-zwift-lib.pro \
src/qdomyos-zwift.pro \
@@ -10,15 +10,9 @@ SUBDIRS = \
tst.depends = src/qdomyos-zwift-lib.pro
}
android: {
android: {
SUBDIRS = \
src/qdomyos-zwift.pro
}
ios: {
SUBDIRS = \
src/qdomyos-zwift-lib.pro \
src/qdomyos-zwift.pro
}

View File

@@ -1,5 +0,0 @@
QMAKE_PRL_BUILD_DIR = C:/qt-everywhere-src-5.15.2/qtconnectivity/src/bluetooth
QMAKE_PRO_INPUT = bluetooth.pro
QMAKE_PRL_TARGET = Qt5Bluetooth.lib
QMAKE_PRL_CONFIG = lex yacc depend_includepath testcase_targets import_plugins import_qpa_plugin windows prepare_docs qt_docs_targets qt_build_extra file_copies qmake_use qt warn_on release link_prl flat debug_and_release precompile_header autogen_precompile_source embed_manifest_dll embed_manifest_exe shared shared release no_plugin_manifest win32 msvc copy_dir_files sse2 aesni sse3 ssse3 sse4_1 sse4_2 avx avx2 avx512f avx512bw avx512cd avx512dq avx512er avx512ifma avx512pf avx512vbmi avx512vl compile_examples f16c force_debug_info largefile precompile_header rdrnd rdseed shani x86SimdAlways prefix_build force_independent utf8_source create_prl link_prl no_private_qt_headers_warning QTDIR_build qt_example_installs exceptions_off testcase_exceptions release ReleaseBuild Release build_pass c++11 generated_privates relative_qt_rpath target_qt c++11 strict_c++ c++14 c++1z qt_install_headers need_fwd_pri qt_install_module debug_and_release build_all create_cmake skip_target_version_ext release ReleaseBuild Release build_pass have_target dll exclusive_builds debug_info no_autoqmake thread moc resources
QMAKE_PRL_VERSION = 5.15.2

View File

@@ -1,5 +0,0 @@
QMAKE_PRL_BUILD_DIR = C:/qt-everywhere-src-5.15.2/qtconnectivity/src/bluetooth
QMAKE_PRO_INPUT = bluetooth.pro
QMAKE_PRL_TARGET = Qt5Bluetoothd.lib
QMAKE_PRL_CONFIG = lex yacc debug depend_includepath testcase_targets import_plugins import_qpa_plugin windows prepare_docs qt_docs_targets qt_build_extra file_copies qmake_use qt warn_on link_prl flat debug_and_release precompile_header autogen_precompile_source embed_manifest_dll embed_manifest_exe shared shared no_plugin_manifest win32 msvc copy_dir_files sse2 aesni sse3 ssse3 sse4_1 sse4_2 avx avx2 avx512f avx512bw avx512cd avx512dq avx512er avx512ifma avx512pf avx512vbmi avx512vl compile_examples f16c force_debug_info largefile precompile_header rdrnd rdseed shani x86SimdAlways prefix_build force_independent utf8_source create_prl link_prl no_private_qt_headers_warning QTDIR_build qt_example_installs exceptions_off testcase_exceptions debug DebugBuild Debug build_pass c++11 generated_privates relative_qt_rpath target_qt c++11 strict_c++ c++14 c++1z qt_install_headers need_fwd_pri qt_install_module debug_and_release build_all create_cmake skip_target_version_ext debug DebugBuild Debug build_pass have_target dll no_plist exclusive_builds debug_info no_autoqmake thread moc resources
QMAKE_PRL_VERSION = 5.15.2

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,25 +0,0 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.15
import QtQuick.Controls.Material 2.0
import Qt.labs.settings 1.0
ColumnLayout {
anchors.fill: parent
Loader {
id: chartFooterLoader
sourceComponent: ChartFooterInnerJS
anchors.fill: parent
active: false
}
Loader {
anchors.fill: parent
source: CHARTJS ? "ChartFooterInnerJS.qml":"ChartFooterInnerNoJS.qml"
onLoaded: {
if(CHARTJS) {
chartFooterLoader.active = true;
}
}
}
}

View File

@@ -1,31 +0,0 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.15
import QtQuick.Controls.Material 2.0
import Qt.labs.settings 1.0
import QtWebView 1.1
ColumnLayout {
anchors.fill: parent
Settings {
id: settings
}
WebView {
id: webView
anchors.fill: parent
url: "http://localhost:" + settings.value("template_inner_QZWS_port") + "/chartjs/chartlive.htm"
visible: rootItem.chartFooterVisible
onLoadingChanged: {
if (loadRequest.errorString) {
console.error(loadRequest.errorString);
console.error("port " + settings.value("template_inner_QZWS_port"));
}
}
onVisibleChanged: {
console.log("onVisibleChanged" + visible)
if(visible === true) {
reload();
}
}
}
}

View File

@@ -1,12 +0,0 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.15
import QtQuick.Controls.Material 2.0
import Qt.labs.settings 1.0
ColumnLayout {
anchors.fill: parent
Settings {
id: settings
}
}

View File

@@ -380,7 +380,7 @@ void Computrainer::unpackTelemetry(int &ss1, int &ss2, int &ss3, int &buttons, i
* READING TELEMETRY AND ISSUING CONTROL COMMANDS WHILST UPDATING
* MEMBER VARIABLES AS TELEMETRY CHANGES ARE FOUND.
*
* run() - bg thread continuously reading/writing the device port
* run() - bg thread continuosly reading/writing the device port
* it is kicked off by start and then examines status to check
* when it is time to pause or stop altogether.
* ---------------------------------------------------------------------- */
@@ -632,7 +632,6 @@ void Computrainer::run() {
/* time to shut up shop */
if (!(curstatus & CT_RUNNING)) {
qDebug() << "time to shut up shop";
// time to stop!
closePort(); // need to release that file handle!!
quit(0);
@@ -640,14 +639,12 @@ void Computrainer::run() {
}
if ((curstatus & CT_PAUSED) && isDeviceOpen == true) {
qDebug() << "(curstatus & CT_PAUSED) && isDeviceOpen == true";
closePort();
isDeviceOpen = false;
} else if (!(curstatus & CT_PAUSED) && (curstatus & CT_RUNNING) && isDeviceOpen == false) {
qDebug() << "!(curstatus & CT_PAUSED) && (curstatus & CT_RUNNING) && isDeviceOpen == false";
if (openPort()) {
qDebug() << "quit(2)";
quit(2);
return; // open failed!
}
@@ -656,7 +653,6 @@ void Computrainer::run() {
// send first command to get computrainer ready
prepareCommand(curmode, curmode == CT_ERGOMODE ? curload : curgradient);
if (sendCommand(curmode) == -1) {
qDebug() << "quit(4)";
// send failed - ouch!
closePort(); // need to release that file handle!!
quit(4);
@@ -675,7 +671,6 @@ void Computrainer::run() {
prepareCommand(curmode, curmode == CT_ERGOMODE ? curload : curgradient);
if (sendCommand(curmode) == -1) {
qDebug() << "quit(4)";
// send failed - ouch!
closePort(); // need to release that file handle!!
quit(4);
@@ -749,9 +744,9 @@ int Computrainer::readMessage() {
}
#ifdef Q_OS_ANDROID
qDebug() << cleanFrame << QByteArray((const char *)buf, 7).toHex(' ');
qDebug() << cleanFrame << QByteArray((const char*)buf, 7).toHex(' ');
if (!cleanFrame)
if(!cleanFrame)
return 0;
#endif

View File

@@ -37,9 +37,12 @@
#include <QThread>
#ifdef WIN32
#include <windows.h>
#include <windef.h>
#endif
#ifdef WIN32
#include <winbase.h>
#include <windows.h>
#else
#include <sys/ioctl.h>
#include <termios.h> // unix!!
@@ -142,7 +145,7 @@ class Computrainer : public QThread {
double getLoad();
private:
void run() override; // called by start to kick off the CT comtrol thread
void run(); // called by start to kick off the CT comtrol thread
// 56 bytes comprise of 8 7byte command messages, where
// the last is the set load / gradient respectively

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>LibraryIdentifier</key>
<string>ios-armv7_arm64</string>
<key>LibraryPath</key>
<string>ConnectIQ.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>armv7</string>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-i386_x86_64-simulator</string>
<key>LibraryPath</key>
<string>ConnectIQ.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>i386</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>

View File

@@ -1,237 +0,0 @@
//
// ConnectIQ.h
// ConnectIQ
//
// Copyright (c) 2014 Garmin. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IQConstants.h"
#import "IQDevice.h"
#import "IQApp.h"
// --------------------------------------------------------------------------------
#pragma mark - PUBLIC TYPES
// --------------------------------------------------------------------------------
/// @brief SendMessage progress callback block
///
/// @param sentBytes The number of bytes that have been successfully transferred
/// to the device so far for this connection.
/// @param totalBytes The total number of bytes to transfer for this connection.
typedef void (^IQSendMessageProgress)(uint32_t sentBytes, uint32_t totalBytes);
/// @brief SendMessage completion callback block
///
/// @param result The result of the SendMessage operation.
typedef void (^IQSendMessageCompletion)(IQSendMessageResult result);
/// @brief Conforming to the IQUIOverrideDelegate protocol indicates that an
/// object handles one or more events triggered by the ConnectIQ SDK that
/// require user input.
@protocol IQUIOverrideDelegate <NSObject>
@optional
/// @brief Called by the ConnectIQ SDK when an action has been requested that
/// requires Garmin Connect Mobile to be installed.
///
/// The receiver should choose whether or not to launch the Apple App
/// Store page for GCM, ideally by presenting the user with a choice.
///
/// If the receiver of this message decides to install GCM, it must call
/// showAppStoreForConnectMobile.
- (void)needsToInstallConnectMobile;
@end
/// @brief Conforming to the IQDeviceEventDelegate protocol indicates that an
/// object handles ConnectIQ device status events.
@protocol IQDeviceEventDelegate <NSObject>
@optional
/// @brief Called by the ConnectIQ SDK when an IQDevice's connection status has
/// changed.
///
/// @param device The IQDevice whose status changed.
/// @param status The new status of the device.
- (void)deviceStatusChanged:(IQDevice *)device status:(IQDeviceStatus)status;
@end
/// @brief Conforming to the IQAppMessageDelegate protocol indicates that an
/// object handles messages from ConnectIQ apps on compatible devices.
@protocol IQAppMessageDelegate <NSObject>
@optional
/// @brief Called by the ConnectIQ SDK when a message is received from a device.
///
/// @param message The message that was received.
/// @param app The device app that sent the message.
- (void)receivedMessage:(id)message fromApp:(IQApp *)app;
@end
// --------------------------------------------------------------------------------
#pragma mark - CLASS DEFINITION
// --------------------------------------------------------------------------------
/// @brief The root of the ConnectIQ SDK API.
@interface ConnectIQ : NSObject
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
// --------------------------------------------------------------------------------
#pragma mark - SINGLETON ACCESS
// --------------------------------------------------------------------------------
/// @brief Exposes the single static instance of the ConnectIQ class.
///
/// @return The single status instance of the ConnectIQ class.
+ (ConnectIQ *)sharedInstance;
// --------------------------------------------------------------------------------
#pragma mark - INITIALIZATION
// --------------------------------------------------------------------------------
/// @brief Initializes the ConnectIQ SDK with startup parameters necessary for
/// its operation.
///
/// @param urlScheme The URL scheme for this companion app. When Garmin Connect
/// Mobile is launched, it will return to the companion app by
/// launching a URL with this scheme.
/// @param delegate The delegate that the SDK will use for notifying the
/// companion app about events that require user input. If this
/// is nil, the SDK's default UI will be used.
- (void)initializeWithUrlScheme:(NSString *)urlScheme uiOverrideDelegate:(id<IQUIOverrideDelegate>)delegate;
// --------------------------------------------------------------------------------
#pragma mark - EXTERNAL LAUNCHING
// --------------------------------------------------------------------------------
/// @brief Launches the Apple App Store page for the Garmin Connect Mobile app.
/// The companion app should only call this in response to a
/// needsToInstallConnectMobile event that gets triggered on the
/// IQUIOverrideDelegate.
- (void)showAppStoreForConnectMobile;
/// @brief Launches Garmin Connect Mobile for the purpose of retrieving a list of
/// ConnectIQ-compatible devices.
///
/// Once the user has chosen which ConnectIQ devices to share with the
/// companion app, GCM will return those devices to the companion app by
/// opening a URL with the scheme registered in
/// initializeWithUrlScheme:uiOverrideDelegate:.
///
/// The companion app should handle this URL by passing it in to the
/// parseDeviceSelectionResponseFromURL: method to get the list of devices
/// that the user permitted the companion app to communicate with.
- (void)showConnectIQDeviceSelection;
/// @brief Parses a URL opened from Garmin Connect Mobile into a list of devices.
///
/// @param url The URL to parse.
///
/// @return An array of IQDevice objects representing the ConnectIQ-compatible
/// devices that the user allowed GCM to share with the companion app.
///
/// @seealso showConnectIQDeviceSelection
- (NSArray *)parseDeviceSelectionResponseFromURL:(NSURL *)url;
/// @brief Launches Garmin Connect Mobile and shows the ConnectIQ app store page
/// for the given app.
///
/// The companion app should call this if the user would like to manage
/// the app on the device, such as to install, upgrade, uninstall, or
/// modify settings.
///
/// @param app The app to show the ConnectIQ app store page for.
- (void)showConnectIQStoreForApp:(IQApp *)app;
// --------------------------------------------------------------------------------
#pragma mark - DEVICE MANAGEMENT
// --------------------------------------------------------------------------------
/// @brief Registers an object as a listener for ConnectIQ device status events.
///
/// A device may have multiple device event listeners if this method is
/// called more than once.
///
/// @param device A device to listen for status events from.
/// @param delegate The listener which will receive status events for this device.
- (void)registerForDeviceEvents:(IQDevice *)device delegate:(id<IQDeviceEventDelegate>)delegate;
/// @brief Unregisters a listener for a specific device.
///
/// @param device The device to unregister the listener for.
/// @param delegate The listener to remove from the device.
- (void)unregisterForDeviceEvents:(IQDevice *)device delegate:(id<IQDeviceEventDelegate>)delegate;
/// @brief Unregisters the specified listener from all devices for which it had
/// previously been registered.
///
/// @param delegate The listener to unregister.
- (void)unregisterForAllDeviceEvents:(id<IQDeviceEventDelegate>)delegate;
/// @brief Gets the current connection status of a device.
///
/// The device must have been registered for event notifications by
/// calling registerForDeviceEvents:delegate: or this method will return
/// IQDeviceStatus_InvalidDevice.
///
/// @param device The device to get the status for.
///
/// @return The device's current connection status.
- (IQDeviceStatus)getDeviceStatus:(IQDevice *)device;
// --------------------------------------------------------------------------------
#pragma mark - APP MANAGEMENT
// --------------------------------------------------------------------------------
/// @brief Begins getting the status of an app on a device. This method returns
/// immediately.
///
/// @param app The IQApp to get the status for.
/// @param completion The completion block that will be triggered when the device
/// status operation is complete.
- (void)getAppStatus:(IQApp *)app completion:(void(^)(IQAppStatus *appStatus))completion;
/// @brief Registers an object as a listener for ConnectIQ messages from an app
/// on a device.
///
/// An app may have multiple message listeners if this method is called
/// more than once.
///
/// @param app The app to listen for messages from.
/// @param delegate The listener which will receive messages for this app.
- (void)registerForAppMessages:(IQApp *)app delegate:(id<IQAppMessageDelegate>)delegate;
/// @brief Unregisters a listener for a specific app.
///
/// @param app The app to unregister a listener for.
/// @param delegate The listener to remove from the app.
- (void)unregisterForAppMessages:(IQApp *)app delegate:(id<IQAppMessageDelegate>)delegate;
/// @brief Unregisters all previously registered apps for a specific listener.
///
/// @param delegate The listener to unregister.
- (void)unregisterForAllAppMessages:(id<IQAppMessageDelegate>)delegate;
/// @brief Begins sending a message to an app. This method returns immediately.
///
/// @param message The message to send to the app. This message must be one of
/// the following types: NSString, NSNumber, NSNull, NSArray,
/// or NSDictionary. Arrays and dictionaries may be nested.
/// @param app The app to send the message to.
/// @param progress A progress block that will be triggered periodically
/// throughout the transfer. This is guaranteed to be triggered
/// at least once.
/// @param completion A completion block that will be triggered when the send
/// message operation is complete.
- (void)sendMessage:(id)message toApp:(IQApp *)app progress:(IQSendMessageProgress)progress completion:(IQSendMessageCompletion)completion;
/// @brief Sends an open app request message request to the device. This method returns immediately.
///
/// @param app The app to open.
/// @param completion A completion block that will be triggered when the send
/// message operation is complete.
- (void)openAppRequest:(IQApp *)app completion:(IQSendMessageCompletion)completion;
// TODO *** Holding off on documenting this until this method actually works.
- (void)sendImage:(NSData *)bitmap toApp:(IQApp *)app progress:(IQSendMessageProgress)progress completion:(IQSendMessageCompletion)completion;
@end

View File

@@ -1,34 +0,0 @@
//
// IQApp.h
// ConnectIQ
//
// Copyright (c) 2014 Garmin. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IQDevice.h"
#import "IQAppStatus.h"
/// @brief Represents an instance of a ConnectIQ app that is installed on a
/// Garmin device.
@interface IQApp : NSObject <NSSecureCoding>
/// @brief The unique identifier for this app.
@property (nonatomic, readonly) NSUUID *uuid;
/// @brief The unique identifier for this app in the store.
@property (nonatomic, readonly) NSUUID *storeUuid;
/// @brief The device that this app is installed on.
@property (nonatomic, readonly) IQDevice *device;
/// @brief Creates a new app instance.
///
/// @param uuid The UUID of the app to create.
/// @param storeUuid The store UUID of the app to create.
/// @param device The device the app to create is installed on.
///
/// @return A new IQApp instance with the appropriate values set.
+ (IQApp *)appWithUUID:(NSUUID *)uuid storeUuid:(NSUUID *)storeUuid device:(IQDevice *)device;
@end

View File

@@ -1,20 +0,0 @@
//
// IQAppStatus.h
// ConnectIQ
//
// Copyright (c) 2014 Garmin. All rights reserved.
//
#import <Foundation/Foundation.h>
/// @brief Represents the current status of an app on a Garmin device.
@interface IQAppStatus : NSObject
/// @brief YES if the app is installed on the device, NO if it isn't.
@property (nonatomic, readonly) BOOL isInstalled;
/// @brief The version of the app that is currently installed on the device. If
/// the app is not installed, this value is unused.
@property (nonatomic, readonly) uint16_t version;
@end

View File

@@ -1,63 +0,0 @@
//
// IQConstants.h
// ConnectIQ
//
// Copyright (c) 2014 Garmin. All rights reserved.
//
#import <Foundation/Foundation.h>
/// @brief The current version of the ConnectIQ SDK.
extern int const IQSDKVersion;
/// @brief The bundle identifier for the Garmin Connect Mobile app.
extern NSString * const IQGCMBundle;
/// @brief The result of a SendMessage operation
typedef NS_ENUM(NSInteger, IQSendMessageResult){
///! @brief The message was sent successfully.
IQSendMessageResult_Success,
/// @brief The message failed to send due to an unknown error.
IQSendMessageResult_Failure_Unknown,
/// @brief The message failed to send. There was an error within the SDK or
/// on the device.
IQSendMessageResult_Failure_InternalError,
/// @brief The message failed to send. The device is not available right now.
IQSendMessageResult_Failure_DeviceNotAvailable,
/// @brief The message failed to send. The app is not installed on the
/// device.
IQSendMessageResult_Failure_AppNotFound,
/// @brief The message failed to send. The device is busy and cannot receive
/// the message right now.
IQSendMessageResult_Failure_DeviceIsBusy,
/// @brief The message failed to send. The message contained an unsupported
/// type.
IQSendMessageResult_Failure_UnsupportedType,
/// @brief The message failed to send. The device does not have enough memory
/// to receive the message.
IQSendMessageResult_Failure_InsufficientMemory,
/// @brief The message failed to send. The connection timed out while sending
/// the message.
IQSendMessageResult_Failure_Timeout,
/// @brief The message failed to send and was retried, but could not complete
/// after a number of tries.
IQSendMessageResult_Failure_MaxRetries,
/// @brief The message was received by the device but it chose not to display
/// a message prompt, ignoring the message.
IQSendMessageResult_Failure_PromptNotDisplayed,
/// @brief The message was received by the device but the app to open
/// was already running on the device.
IQSendMessageResult_Failure_AppAlreadyRunning,
};
NSString *NSStringFromSendMessageResult(IQSendMessageResult value);

View File

@@ -1,61 +0,0 @@
//
// IQDevice.h
// ConnectIQ
//
// Copyright (c) 2014 Garmin. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
/// @brief The current status of an IQDevice.
typedef NS_ENUM(NSInteger, IQDeviceStatus){
/// @brief No device with this UUID has been registered for status events
/// the SDK.
IQDeviceStatus_InvalidDevice,
/// @brief Bluetooth is either powered off or resetting.
IQDeviceStatus_BluetoothNotReady,
/// @brief This device could not be found by iOS. Perhaps the user removed
/// the device?
IQDeviceStatus_NotFound,
/// @brief The device is recognized by iOS, but it is not currently
/// connected.
IQDeviceStatus_NotConnected,
/// @brief The device is connected and ready to communicate.
IQDeviceStatus_Connected,
};
/// @brief Represents a ConnectIQ-compatible Garmin device.
@interface IQDevice : NSObject <NSSecureCoding>
/// @brief The unique identifier for this device.
@property (nonatomic, readonly) NSUUID *uuid;
/// @brief The model name of the device provided by Garmin Connect Mobile.
@property (nonatomic, readonly) NSString *modelName;
/// @brief The friendly name of the device, set by the user and provided by
/// Garmin Connect Mobile.
@property (nonatomic, readonly) NSString *friendlyName;
/// @brief Creates a new device instance.
///
/// @param uuid The UUID of the device to create.
/// @param modelName The model name of the device to create.
/// @param friendlyName The friendly name of the device to create.
///
/// @return A new IQDevice instance with the appropriate values set.
+ (IQDevice *)deviceWithId:(NSUUID *)uuid modelName:(NSString *)modelName friendlyName:(NSString *)friendlyName;
/// @brief Creates a new device instance by copying another device's values.
///
/// @param device The device to copy values from.
///
/// @return A new IQDevice instance with all values copied.
- (instancetype)initWithDevice:(IQDevice *)device;
@end

View File

@@ -1,6 +0,0 @@
framework module ConnectIQ {
umbrella header "ConnectIQ.h"
export *
module * { export * }
}

View File

@@ -1,237 +0,0 @@
//
// ConnectIQ.h
// ConnectIQ
//
// Copyright (c) 2014 Garmin. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IQConstants.h"
#import "IQDevice.h"
#import "IQApp.h"
// --------------------------------------------------------------------------------
#pragma mark - PUBLIC TYPES
// --------------------------------------------------------------------------------
/// @brief SendMessage progress callback block
///
/// @param sentBytes The number of bytes that have been successfully transferred
/// to the device so far for this connection.
/// @param totalBytes The total number of bytes to transfer for this connection.
typedef void (^IQSendMessageProgress)(uint32_t sentBytes, uint32_t totalBytes);
/// @brief SendMessage completion callback block
///
/// @param result The result of the SendMessage operation.
typedef void (^IQSendMessageCompletion)(IQSendMessageResult result);
/// @brief Conforming to the IQUIOverrideDelegate protocol indicates that an
/// object handles one or more events triggered by the ConnectIQ SDK that
/// require user input.
@protocol IQUIOverrideDelegate <NSObject>
@optional
/// @brief Called by the ConnectIQ SDK when an action has been requested that
/// requires Garmin Connect Mobile to be installed.
///
/// The receiver should choose whether or not to launch the Apple App
/// Store page for GCM, ideally by presenting the user with a choice.
///
/// If the receiver of this message decides to install GCM, it must call
/// showAppStoreForConnectMobile.
- (void)needsToInstallConnectMobile;
@end
/// @brief Conforming to the IQDeviceEventDelegate protocol indicates that an
/// object handles ConnectIQ device status events.
@protocol IQDeviceEventDelegate <NSObject>
@optional
/// @brief Called by the ConnectIQ SDK when an IQDevice's connection status has
/// changed.
///
/// @param device The IQDevice whose status changed.
/// @param status The new status of the device.
- (void)deviceStatusChanged:(IQDevice *)device status:(IQDeviceStatus)status;
@end
/// @brief Conforming to the IQAppMessageDelegate protocol indicates that an
/// object handles messages from ConnectIQ apps on compatible devices.
@protocol IQAppMessageDelegate <NSObject>
@optional
/// @brief Called by the ConnectIQ SDK when a message is received from a device.
///
/// @param message The message that was received.
/// @param app The device app that sent the message.
- (void)receivedMessage:(id)message fromApp:(IQApp *)app;
@end
// --------------------------------------------------------------------------------
#pragma mark - CLASS DEFINITION
// --------------------------------------------------------------------------------
/// @brief The root of the ConnectIQ SDK API.
@interface ConnectIQ : NSObject
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
// --------------------------------------------------------------------------------
#pragma mark - SINGLETON ACCESS
// --------------------------------------------------------------------------------
/// @brief Exposes the single static instance of the ConnectIQ class.
///
/// @return The single status instance of the ConnectIQ class.
+ (ConnectIQ *)sharedInstance;
// --------------------------------------------------------------------------------
#pragma mark - INITIALIZATION
// --------------------------------------------------------------------------------
/// @brief Initializes the ConnectIQ SDK with startup parameters necessary for
/// its operation.
///
/// @param urlScheme The URL scheme for this companion app. When Garmin Connect
/// Mobile is launched, it will return to the companion app by
/// launching a URL with this scheme.
/// @param delegate The delegate that the SDK will use for notifying the
/// companion app about events that require user input. If this
/// is nil, the SDK's default UI will be used.
- (void)initializeWithUrlScheme:(NSString *)urlScheme uiOverrideDelegate:(id<IQUIOverrideDelegate>)delegate;
// --------------------------------------------------------------------------------
#pragma mark - EXTERNAL LAUNCHING
// --------------------------------------------------------------------------------
/// @brief Launches the Apple App Store page for the Garmin Connect Mobile app.
/// The companion app should only call this in response to a
/// needsToInstallConnectMobile event that gets triggered on the
/// IQUIOverrideDelegate.
- (void)showAppStoreForConnectMobile;
/// @brief Launches Garmin Connect Mobile for the purpose of retrieving a list of
/// ConnectIQ-compatible devices.
///
/// Once the user has chosen which ConnectIQ devices to share with the
/// companion app, GCM will return those devices to the companion app by
/// opening a URL with the scheme registered in
/// initializeWithUrlScheme:uiOverrideDelegate:.
///
/// The companion app should handle this URL by passing it in to the
/// parseDeviceSelectionResponseFromURL: method to get the list of devices
/// that the user permitted the companion app to communicate with.
- (void)showConnectIQDeviceSelection;
/// @brief Parses a URL opened from Garmin Connect Mobile into a list of devices.
///
/// @param url The URL to parse.
///
/// @return An array of IQDevice objects representing the ConnectIQ-compatible
/// devices that the user allowed GCM to share with the companion app.
///
/// @seealso showConnectIQDeviceSelection
- (NSArray *)parseDeviceSelectionResponseFromURL:(NSURL *)url;
/// @brief Launches Garmin Connect Mobile and shows the ConnectIQ app store page
/// for the given app.
///
/// The companion app should call this if the user would like to manage
/// the app on the device, such as to install, upgrade, uninstall, or
/// modify settings.
///
/// @param app The app to show the ConnectIQ app store page for.
- (void)showConnectIQStoreForApp:(IQApp *)app;
// --------------------------------------------------------------------------------
#pragma mark - DEVICE MANAGEMENT
// --------------------------------------------------------------------------------
/// @brief Registers an object as a listener for ConnectIQ device status events.
///
/// A device may have multiple device event listeners if this method is
/// called more than once.
///
/// @param device A device to listen for status events from.
/// @param delegate The listener which will receive status events for this device.
- (void)registerForDeviceEvents:(IQDevice *)device delegate:(id<IQDeviceEventDelegate>)delegate;
/// @brief Unregisters a listener for a specific device.
///
/// @param device The device to unregister the listener for.
/// @param delegate The listener to remove from the device.
- (void)unregisterForDeviceEvents:(IQDevice *)device delegate:(id<IQDeviceEventDelegate>)delegate;
/// @brief Unregisters the specified listener from all devices for which it had
/// previously been registered.
///
/// @param delegate The listener to unregister.
- (void)unregisterForAllDeviceEvents:(id<IQDeviceEventDelegate>)delegate;
/// @brief Gets the current connection status of a device.
///
/// The device must have been registered for event notifications by
/// calling registerForDeviceEvents:delegate: or this method will return
/// IQDeviceStatus_InvalidDevice.
///
/// @param device The device to get the status for.
///
/// @return The device's current connection status.
- (IQDeviceStatus)getDeviceStatus:(IQDevice *)device;
// --------------------------------------------------------------------------------
#pragma mark - APP MANAGEMENT
// --------------------------------------------------------------------------------
/// @brief Begins getting the status of an app on a device. This method returns
/// immediately.
///
/// @param app The IQApp to get the status for.
/// @param completion The completion block that will be triggered when the device
/// status operation is complete.
- (void)getAppStatus:(IQApp *)app completion:(void(^)(IQAppStatus *appStatus))completion;
/// @brief Registers an object as a listener for ConnectIQ messages from an app
/// on a device.
///
/// An app may have multiple message listeners if this method is called
/// more than once.
///
/// @param app The app to listen for messages from.
/// @param delegate The listener which will receive messages for this app.
- (void)registerForAppMessages:(IQApp *)app delegate:(id<IQAppMessageDelegate>)delegate;
/// @brief Unregisters a listener for a specific app.
///
/// @param app The app to unregister a listener for.
/// @param delegate The listener to remove from the app.
- (void)unregisterForAppMessages:(IQApp *)app delegate:(id<IQAppMessageDelegate>)delegate;
/// @brief Unregisters all previously registered apps for a specific listener.
///
/// @param delegate The listener to unregister.
- (void)unregisterForAllAppMessages:(id<IQAppMessageDelegate>)delegate;
/// @brief Begins sending a message to an app. This method returns immediately.
///
/// @param message The message to send to the app. This message must be one of
/// the following types: NSString, NSNumber, NSNull, NSArray,
/// or NSDictionary. Arrays and dictionaries may be nested.
/// @param app The app to send the message to.
/// @param progress A progress block that will be triggered periodically
/// throughout the transfer. This is guaranteed to be triggered
/// at least once.
/// @param completion A completion block that will be triggered when the send
/// message operation is complete.
- (void)sendMessage:(id)message toApp:(IQApp *)app progress:(IQSendMessageProgress)progress completion:(IQSendMessageCompletion)completion;
/// @brief Sends an open app request message request to the device. This method returns immediately.
///
/// @param app The app to open.
/// @param completion A completion block that will be triggered when the send
/// message operation is complete.
- (void)openAppRequest:(IQApp *)app completion:(IQSendMessageCompletion)completion;
// TODO *** Holding off on documenting this until this method actually works.
- (void)sendImage:(NSData *)bitmap toApp:(IQApp *)app progress:(IQSendMessageProgress)progress completion:(IQSendMessageCompletion)completion;
@end

View File

@@ -1,34 +0,0 @@
//
// IQApp.h
// ConnectIQ
//
// Copyright (c) 2014 Garmin. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IQDevice.h"
#import "IQAppStatus.h"
/// @brief Represents an instance of a ConnectIQ app that is installed on a
/// Garmin device.
@interface IQApp : NSObject <NSSecureCoding>
/// @brief The unique identifier for this app.
@property (nonatomic, readonly) NSUUID *uuid;
/// @brief The unique identifier for this app in the store.
@property (nonatomic, readonly) NSUUID *storeUuid;
/// @brief The device that this app is installed on.
@property (nonatomic, readonly) IQDevice *device;
/// @brief Creates a new app instance.
///
/// @param uuid The UUID of the app to create.
/// @param storeUuid The store UUID of the app to create.
/// @param device The device the app to create is installed on.
///
/// @return A new IQApp instance with the appropriate values set.
+ (IQApp *)appWithUUID:(NSUUID *)uuid storeUuid:(NSUUID *)storeUuid device:(IQDevice *)device;
@end

View File

@@ -1,20 +0,0 @@
//
// IQAppStatus.h
// ConnectIQ
//
// Copyright (c) 2014 Garmin. All rights reserved.
//
#import <Foundation/Foundation.h>
/// @brief Represents the current status of an app on a Garmin device.
@interface IQAppStatus : NSObject
/// @brief YES if the app is installed on the device, NO if it isn't.
@property (nonatomic, readonly) BOOL isInstalled;
/// @brief The version of the app that is currently installed on the device. If
/// the app is not installed, this value is unused.
@property (nonatomic, readonly) uint16_t version;
@end

View File

@@ -1,63 +0,0 @@
//
// IQConstants.h
// ConnectIQ
//
// Copyright (c) 2014 Garmin. All rights reserved.
//
#import <Foundation/Foundation.h>
/// @brief The current version of the ConnectIQ SDK.
extern int const IQSDKVersion;
/// @brief The bundle identifier for the Garmin Connect Mobile app.
extern NSString * const IQGCMBundle;
/// @brief The result of a SendMessage operation
typedef NS_ENUM(NSInteger, IQSendMessageResult){
///! @brief The message was sent successfully.
IQSendMessageResult_Success,
/// @brief The message failed to send due to an unknown error.
IQSendMessageResult_Failure_Unknown,
/// @brief The message failed to send. There was an error within the SDK or
/// on the device.
IQSendMessageResult_Failure_InternalError,
/// @brief The message failed to send. The device is not available right now.
IQSendMessageResult_Failure_DeviceNotAvailable,
/// @brief The message failed to send. The app is not installed on the
/// device.
IQSendMessageResult_Failure_AppNotFound,
/// @brief The message failed to send. The device is busy and cannot receive
/// the message right now.
IQSendMessageResult_Failure_DeviceIsBusy,
/// @brief The message failed to send. The message contained an unsupported
/// type.
IQSendMessageResult_Failure_UnsupportedType,
/// @brief The message failed to send. The device does not have enough memory
/// to receive the message.
IQSendMessageResult_Failure_InsufficientMemory,
/// @brief The message failed to send. The connection timed out while sending
/// the message.
IQSendMessageResult_Failure_Timeout,
/// @brief The message failed to send and was retried, but could not complete
/// after a number of tries.
IQSendMessageResult_Failure_MaxRetries,
/// @brief The message was received by the device but it chose not to display
/// a message prompt, ignoring the message.
IQSendMessageResult_Failure_PromptNotDisplayed,
/// @brief The message was received by the device but the app to open
/// was already running on the device.
IQSendMessageResult_Failure_AppAlreadyRunning,
};
NSString *NSStringFromSendMessageResult(IQSendMessageResult value);

View File

@@ -1,61 +0,0 @@
//
// IQDevice.h
// ConnectIQ
//
// Copyright (c) 2014 Garmin. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
/// @brief The current status of an IQDevice.
typedef NS_ENUM(NSInteger, IQDeviceStatus){
/// @brief No device with this UUID has been registered for status events
/// the SDK.
IQDeviceStatus_InvalidDevice,
/// @brief Bluetooth is either powered off or resetting.
IQDeviceStatus_BluetoothNotReady,
/// @brief This device could not be found by iOS. Perhaps the user removed
/// the device?
IQDeviceStatus_NotFound,
/// @brief The device is recognized by iOS, but it is not currently
/// connected.
IQDeviceStatus_NotConnected,
/// @brief The device is connected and ready to communicate.
IQDeviceStatus_Connected,
};
/// @brief Represents a ConnectIQ-compatible Garmin device.
@interface IQDevice : NSObject <NSSecureCoding>
/// @brief The unique identifier for this device.
@property (nonatomic, readonly) NSUUID *uuid;
/// @brief The model name of the device provided by Garmin Connect Mobile.
@property (nonatomic, readonly) NSString *modelName;
/// @brief The friendly name of the device, set by the user and provided by
/// Garmin Connect Mobile.
@property (nonatomic, readonly) NSString *friendlyName;
/// @brief Creates a new device instance.
///
/// @param uuid The UUID of the device to create.
/// @param modelName The model name of the device to create.
/// @param friendlyName The friendly name of the device to create.
///
/// @return A new IQDevice instance with the appropriate values set.
+ (IQDevice *)deviceWithId:(NSUUID *)uuid modelName:(NSString *)modelName friendlyName:(NSString *)friendlyName;
/// @brief Creates a new device instance by copying another device's values.
///
/// @param device The device to copy values from.
///
/// @return A new IQDevice instance with all values copied.
- (instancetype)initWithDevice:(IQDevice *)device;
@end

View File

@@ -1,6 +0,0 @@
framework module ConnectIQ {
umbrella header "ConnectIQ.h"
export *
module * { export * }
}

View File

@@ -1,830 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict>
<key>Headers/ConnectIQ.h</key>
<data>
F1hICh90Ex4ADEjYLcSi0YPhrPA=
</data>
<key>Headers/IQApp.h</key>
<data>
R7+SmeArgBACIBWHRnEAugyFHKE=
</data>
<key>Headers/IQAppStatus.h</key>
<data>
WnybOSMMVqCKGns0rEz9C3EfQOg=
</data>
<key>Headers/IQConstants.h</key>
<data>
eI7keKSkaajUZACnuMhgtV1RuBA=
</data>
<key>Headers/IQDevice.h</key>
<data>
bl545C/cu0mw2KlRmzojKmHPom0=
</data>
<key>Info.plist</key>
<data>
sMY09qXRBL/m1OGNWejLjfNg04w=
</data>
<key>Modules/module.modulemap</key>
<data>
SSRVAtIAdFmowQqE4HzOpWYLubg=
</data>
<key>ar.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
1CDTE/Qaf1Z/HuhSt9CUnwitv4M=
</data>
<key>optional</key>
<true/>
</dict>
<key>cs.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
/jkyQ77G2Xd9wy6QptBphGNbtCY=
</data>
<key>optional</key>
<true/>
</dict>
<key>da.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
FYi0wjOu/Hw//Qe96yqxSb9yClc=
</data>
<key>optional</key>
<true/>
</dict>
<key>de.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
MitzVbGhXhTLjPvw9vuWcQQa50Q=
</data>
<key>optional</key>
<true/>
</dict>
<key>el.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
n82gLcjjjHszaroTFeJUvSrrc0o=
</data>
<key>optional</key>
<true/>
</dict>
<key>en.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
hcxxLyrTI+aElXlPc5dwr7jdqwc=
</data>
<key>optional</key>
<true/>
</dict>
<key>es.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
ff8DVQtNhO8pF7HFnXjh8foHXbo=
</data>
<key>optional</key>
<true/>
</dict>
<key>fi.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
R9cr8yqJmu91Xz31tGyprGR3t/s=
</data>
<key>optional</key>
<true/>
</dict>
<key>fr.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
PwFmqFeRTcjdHmkXYrPzNVYoe5o=
</data>
<key>optional</key>
<true/>
</dict>
<key>he.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
/jPUgFtYbbyELG5DZ3Sjoi/If9w=
</data>
<key>optional</key>
<true/>
</dict>
<key>hr.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
H2GtdTeORRPCnogvpWY69Dg9uME=
</data>
<key>optional</key>
<true/>
</dict>
<key>hu.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
QIimMhNyYmqp4ZW01hfj554WAMg=
</data>
<key>optional</key>
<true/>
</dict>
<key>id.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
2/54a0gkcVuk1I3m4ulDAXOLL5o=
</data>
<key>optional</key>
<true/>
</dict>
<key>it.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
hNIKYIcP/87e6g7AUP+zKRtJ52M=
</data>
<key>optional</key>
<true/>
</dict>
<key>ja.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
0iU2PbJ/3xgXMZ20ffsqaWpxKWc=
</data>
<key>optional</key>
<true/>
</dict>
<key>ko.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
ERH8oHR9H9jMHjP0EAgaTtVhnX4=
</data>
<key>optional</key>
<true/>
</dict>
<key>ms.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
DkbQA2+v/qSgQWma/fg3647Bkqs=
</data>
<key>optional</key>
<true/>
</dict>
<key>nb.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
T3zFOvuvrJt5Vnmfqt2Mf/du8as=
</data>
<key>optional</key>
<true/>
</dict>
<key>nl.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
t9PD5JEbfoSLaQ7f8M2cLghOReI=
</data>
<key>optional</key>
<true/>
</dict>
<key>pl.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
wfTnhBccAm6JfwH/JkZKNRKTUAU=
</data>
<key>optional</key>
<true/>
</dict>
<key>pt-PT.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
7yXkcZEpJ4UiRHAzhK+vw/Q857Y=
</data>
<key>optional</key>
<true/>
</dict>
<key>pt.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
tZPncsQs8weCDJa03AKLpijXSUw=
</data>
<key>optional</key>
<true/>
</dict>
<key>ru.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
Ct+byJ3rWeigvg0q6rB/kQaR+yE=
</data>
<key>optional</key>
<true/>
</dict>
<key>sk.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
1yTM1nAsAYpSH7NrYU6/nFlqk5E=
</data>
<key>optional</key>
<true/>
</dict>
<key>sv.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
i84z6vuHLrFpO0qZ2V0zYjixIws=
</data>
<key>optional</key>
<true/>
</dict>
<key>th.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
oW5npy+pDJM1wUOgTkw9FY1Ave4=
</data>
<key>optional</key>
<true/>
</dict>
<key>tr.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
76rD7PLrQMiT5YTlI8IjEFgsiU4=
</data>
<key>optional</key>
<true/>
</dict>
<key>zh-Hans.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
DNlMxUKypOvKArzi7ioJUiFfFXg=
</data>
<key>optional</key>
<true/>
</dict>
<key>zh-Hant.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
U6I+uL07KIv2b77w0c0glaJlhMg=
</data>
<key>optional</key>
<true/>
</dict>
</dict>
<key>files2</key>
<dict>
<key>Headers/ConnectIQ.h</key>
<dict>
<key>hash</key>
<data>
F1hICh90Ex4ADEjYLcSi0YPhrPA=
</data>
<key>hash2</key>
<data>
ABtgvHbvmly4QpZO/KmmrwYkL0N+AqV3gXdPVrseysY=
</data>
</dict>
<key>Headers/IQApp.h</key>
<dict>
<key>hash</key>
<data>
R7+SmeArgBACIBWHRnEAugyFHKE=
</data>
<key>hash2</key>
<data>
X4vXt0sO9gxQNzQalIaLqMpSGNRC9ue2USDcfjBYkec=
</data>
</dict>
<key>Headers/IQAppStatus.h</key>
<dict>
<key>hash</key>
<data>
WnybOSMMVqCKGns0rEz9C3EfQOg=
</data>
<key>hash2</key>
<data>
tg9qNXtTmFUvNoJtq7O/aEXBNngcGENVRhvxLJ8C/xo=
</data>
</dict>
<key>Headers/IQConstants.h</key>
<dict>
<key>hash</key>
<data>
eI7keKSkaajUZACnuMhgtV1RuBA=
</data>
<key>hash2</key>
<data>
bqDpm8yikc2FIqaSUHcLqPY6TPXLlXSUo+Dl9NUYwmA=
</data>
</dict>
<key>Headers/IQDevice.h</key>
<dict>
<key>hash</key>
<data>
bl545C/cu0mw2KlRmzojKmHPom0=
</data>
<key>hash2</key>
<data>
4N4+64IHeb9iBwyziNxo0SMuCM75ez9Em4UfmtgtTHA=
</data>
</dict>
<key>Modules/module.modulemap</key>
<dict>
<key>hash</key>
<data>
SSRVAtIAdFmowQqE4HzOpWYLubg=
</data>
<key>hash2</key>
<data>
lQGjVO5Q0wfztjETCwDkwAkQ7nZInCgWdStnHL3o6Co=
</data>
</dict>
<key>ar.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
1CDTE/Qaf1Z/HuhSt9CUnwitv4M=
</data>
<key>hash2</key>
<data>
CWyQue2TCS0heGoGbN4ffetM2QZSk7lqgc2Wer2fgTg=
</data>
<key>optional</key>
<true/>
</dict>
<key>cs.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
/jkyQ77G2Xd9wy6QptBphGNbtCY=
</data>
<key>hash2</key>
<data>
1mSn+EYeYcTV1dArgHz7PkmZrV6mHWfnuG5aDa6Y87E=
</data>
<key>optional</key>
<true/>
</dict>
<key>da.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
FYi0wjOu/Hw//Qe96yqxSb9yClc=
</data>
<key>hash2</key>
<data>
yLkvGzd+smkOjicvW/+Oe6wGGyirHS+/YfjuSzyVoMM=
</data>
<key>optional</key>
<true/>
</dict>
<key>de.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
MitzVbGhXhTLjPvw9vuWcQQa50Q=
</data>
<key>hash2</key>
<data>
DFHv7MWBJmyAkOj993NmSFKbS2t8/vtSev603sBUtjI=
</data>
<key>optional</key>
<true/>
</dict>
<key>el.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
n82gLcjjjHszaroTFeJUvSrrc0o=
</data>
<key>hash2</key>
<data>
i4FAK4mi+SgS6oZv8zM74kRZToakn49E8GD7FcJBLoQ=
</data>
<key>optional</key>
<true/>
</dict>
<key>en.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
hcxxLyrTI+aElXlPc5dwr7jdqwc=
</data>
<key>hash2</key>
<data>
vmBi9DFJzFcG0OwaWKSDjgklNi407U8u2pz3EnEENN4=
</data>
<key>optional</key>
<true/>
</dict>
<key>es.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
ff8DVQtNhO8pF7HFnXjh8foHXbo=
</data>
<key>hash2</key>
<data>
z6RjynaWjrRKHmv4sLirc4eXwKOtQdylzj5+TiHpaTc=
</data>
<key>optional</key>
<true/>
</dict>
<key>fi.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
R9cr8yqJmu91Xz31tGyprGR3t/s=
</data>
<key>hash2</key>
<data>
6BI0iPRVWaP63/XFdjLBz6z7DsvvuOoaEAS+mYzrx8E=
</data>
<key>optional</key>
<true/>
</dict>
<key>fr.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
PwFmqFeRTcjdHmkXYrPzNVYoe5o=
</data>
<key>hash2</key>
<data>
geXjZzXre2CRiALecPFBGz4JSJA7MbkDnB4qrEMKNwk=
</data>
<key>optional</key>
<true/>
</dict>
<key>he.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
/jPUgFtYbbyELG5DZ3Sjoi/If9w=
</data>
<key>hash2</key>
<data>
47mcrSx16SFjWPIiN7guCAG0va8NiJ6I5s45tSVEHlY=
</data>
<key>optional</key>
<true/>
</dict>
<key>hr.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
H2GtdTeORRPCnogvpWY69Dg9uME=
</data>
<key>hash2</key>
<data>
4bQvygPax6VBpoFlyS5by1N6otnDMliHu+bWsDaWSQc=
</data>
<key>optional</key>
<true/>
</dict>
<key>hu.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
QIimMhNyYmqp4ZW01hfj554WAMg=
</data>
<key>hash2</key>
<data>
0m2fIyz26vh3RlUqqSXvoNTLovxIixrUyJoL/IDSoVk=
</data>
<key>optional</key>
<true/>
</dict>
<key>id.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
2/54a0gkcVuk1I3m4ulDAXOLL5o=
</data>
<key>hash2</key>
<data>
hQf9SrG7d8aVWsXIbCIxkKEJjbnW1FLvS+MbOI1VtHQ=
</data>
<key>optional</key>
<true/>
</dict>
<key>it.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
hNIKYIcP/87e6g7AUP+zKRtJ52M=
</data>
<key>hash2</key>
<data>
XAbEWX6cicDxGzxGgSx3DhF4rjUHX4LV+dO0X3rUEqc=
</data>
<key>optional</key>
<true/>
</dict>
<key>ja.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
0iU2PbJ/3xgXMZ20ffsqaWpxKWc=
</data>
<key>hash2</key>
<data>
YOqOvZq0WEN4DCoSwc0lcTSRc4C812DqzjIsaid1SHg=
</data>
<key>optional</key>
<true/>
</dict>
<key>ko.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
ERH8oHR9H9jMHjP0EAgaTtVhnX4=
</data>
<key>hash2</key>
<data>
WJyaRCWn1KqmcDeajRnC41MdNrlpbI+1JbPkXhbKrKY=
</data>
<key>optional</key>
<true/>
</dict>
<key>ms.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
DkbQA2+v/qSgQWma/fg3647Bkqs=
</data>
<key>hash2</key>
<data>
gztYxa4Hn58HkKmcUIZI1jCz44IETZeMsqrpZSKxJvc=
</data>
<key>optional</key>
<true/>
</dict>
<key>nb.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
T3zFOvuvrJt5Vnmfqt2Mf/du8as=
</data>
<key>hash2</key>
<data>
Oy6UOwSN+/xPIrthAEvzV8PEn27kfsHpMMLU5w1rww0=
</data>
<key>optional</key>
<true/>
</dict>
<key>nl.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
t9PD5JEbfoSLaQ7f8M2cLghOReI=
</data>
<key>hash2</key>
<data>
XbijhSaZgmsW59Vo9ZEbhDuUQH18fHizWKzsLosiM0o=
</data>
<key>optional</key>
<true/>
</dict>
<key>pl.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
wfTnhBccAm6JfwH/JkZKNRKTUAU=
</data>
<key>hash2</key>
<data>
MQYgqA+Hl03JJ261Q19K5Lt64kSTBP+pfpD+jOVE3AU=
</data>
<key>optional</key>
<true/>
</dict>
<key>pt-PT.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
7yXkcZEpJ4UiRHAzhK+vw/Q857Y=
</data>
<key>hash2</key>
<data>
seINq3QazVameLGOW+pIAtGWLa6NDl5XWRtqnObxywo=
</data>
<key>optional</key>
<true/>
</dict>
<key>pt.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
tZPncsQs8weCDJa03AKLpijXSUw=
</data>
<key>hash2</key>
<data>
GnzdqEuQwORzVCih99bwr79UHIyzXm+zuN5b9m1NrKY=
</data>
<key>optional</key>
<true/>
</dict>
<key>ru.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
Ct+byJ3rWeigvg0q6rB/kQaR+yE=
</data>
<key>hash2</key>
<data>
yCN9s/JXYqsMNZ1icaH4hUwyMQ1NtxOmV6sIAtRd9pc=
</data>
<key>optional</key>
<true/>
</dict>
<key>sk.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
1yTM1nAsAYpSH7NrYU6/nFlqk5E=
</data>
<key>hash2</key>
<data>
OFHDtkGLLSfTuSx8GOTycKDCKOKmX0Wh2QG1CHhRz3I=
</data>
<key>optional</key>
<true/>
</dict>
<key>sv.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
i84z6vuHLrFpO0qZ2V0zYjixIws=
</data>
<key>hash2</key>
<data>
a3Gk+3USOT5uundOXrNCgnbcD0rDo2lkCO7b7+zg2Is=
</data>
<key>optional</key>
<true/>
</dict>
<key>th.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
oW5npy+pDJM1wUOgTkw9FY1Ave4=
</data>
<key>hash2</key>
<data>
qxGqAqRMwm0/dMd0W7DUsvbWb9x65GT+3d1zOQEql1w=
</data>
<key>optional</key>
<true/>
</dict>
<key>tr.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
76rD7PLrQMiT5YTlI8IjEFgsiU4=
</data>
<key>hash2</key>
<data>
Y6TnKQmqO/TAx+0KYqRRG6UOz7I/gM1YmbUwgSfZSQU=
</data>
<key>optional</key>
<true/>
</dict>
<key>zh-Hans.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
DNlMxUKypOvKArzi7ioJUiFfFXg=
</data>
<key>hash2</key>
<data>
BI3m4MTMHuPI4sQKPGeQnxIlBJJrXwgVuR7Ho1Q5o6Y=
</data>
<key>optional</key>
<true/>
</dict>
<key>zh-Hant.lproj/IQLocalizable.strings</key>
<dict>
<key>hash</key>
<data>
U6I+uL07KIv2b77w0c0glaJlhMg=
</data>
<key>hash2</key>
<data>
14dQnjX3pEz2Um4J/fOdQDRe/LSuXxqkg1hEkO8E5ys=
</data>
<key>optional</key>
<true/>
</dict>
</dict>
<key>rules</key>
<dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>

Some files were not shown because too many files have changed in this diff Show More