From e11911d655e64a27fd7aea5df96521075ad44ea3 Mon Sep 17 00:00:00 2001 From: Joseph Mearman Date: Mon, 9 Mar 2026 21:53:42 +0000 Subject: [PATCH 01/10] gitlint: enforce area format instead of conventional commits Require commit messages to use path-based areas (e.g., fw/drivers/hrm) or known short areas (e.g., ci, docs, treewide) rather than conventional commit types like feat:, fix:, chore:. Co-authored-by: Claude Signed-off-by: Joseph Mearman --- .gitlint | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitlint b/.gitlint index bf75b765a..fcae58189 100644 --- a/.gitlint +++ b/.gitlint @@ -4,9 +4,16 @@ ignore-merge-commits=false ignore-fixup-commits=false ignore-fixup-amend-commits=false ignore-squash-commits=false +regex-style-search=true [title-match-regex] -regex=[a-z0-9/]+: .* +# Format: "area: description" where area is either: +# - A path with at least one / (e.g., fw/drivers/hrm, third_party/nonfree) +# - One of the known short areas: ci, treewide, platform, sdk, tools, resources, +# docs, waftools, settings, libc, tests, notifications, build, wscript, fw, +# third_party, ancs, compositor, console, kernel, health +# Conventional commit types like feat:, fix:, chore: are NOT allowed. +regex=^([a-z0-9_]+/[a-z0-9_/]*|ci|treewide|platform|sdk|tools|resources|docs|waftools|settings|libc|tests|notifications|build|wscript|fw|third_party|ancs|compositor|console|kernel|health|gitlint|readme|requirements|python_libs|pbl-tool|pbl|moddable|libutil|iconography|gitignore|capabilities|asterix|activity|accel): .* [title-max-length] line-length=100 From ae6892b66dcf000330983624dd04bf0959dbce06 Mon Sep 17 00:00:00 2001 From: Joseph Mearman Date: Mon, 9 Mar 2026 21:53:49 +0000 Subject: [PATCH 02/10] tests/graphics: add macOS-specific fixture support Append -darwin suffix to fixture filenames on macOS to handle rendering differences in font libraries. Linux (CI) uses standard ~platform naming to match existing fixtures. Co-authored-by: Claude Signed-off-by: Joseph Mearman --- tests/fw/graphics/util.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/fw/graphics/util.h b/tests/fw/graphics/util.h index 8f180ce5a..a8037a361 100644 --- a/tests/fw/graphics/util.h +++ b/tests/fw/graphics/util.h @@ -59,8 +59,13 @@ static const char *namecat(const char* str1, const char* str2){ } else { #if !PLATFORM_DEFAULT // Add ~platform to files with unit-tests built for a specific platform + // On macOS, append -darwin suffix to allow different fixtures for local dev + // Linux (CI) uses the standard ~platform naming to match existing fixtures strcat(filename, "~"); strcat(filename, PLATFORM_NAME); +#if defined(__APPLE__) + strcat(filename, "-darwin"); +#endif #endif } From 564691371bfabff000576fc18d5b95d43f13f3f8 Mon Sep 17 00:00:00 2001 From: Joseph Mearman Date: Mon, 9 Mar 2026 21:53:56 +0000 Subject: [PATCH 03/10] tests/fakes: fix HCI whitelist address handling Use memcpy for BD_ADDR_t address fields instead of direct assignment, which was causing incorrect address comparisons in whitelist operations. Co-authored-by: Claude Signed-off-by: Joseph Mearman --- tests/fakes/fake_HCIAPI.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/tests/fakes/fake_HCIAPI.c b/tests/fakes/fake_HCIAPI.c index a5fee601c..2557f7e3b 100644 --- a/tests/fakes/fake_HCIAPI.c +++ b/tests/fakes/fake_HCIAPI.c @@ -10,6 +10,13 @@ #include "util/list.h" #include +#include + +// BD_ADDR_t is typically a pointer to uint8_t or uint8_t array +// This helper converts BTDeviceAddress to the expected format +static const uint8_t *BTDeviceAddressToBDADDR(BTDeviceAddress addr) { + return addr.octets; +} typedef struct { ListNode node; @@ -63,10 +70,9 @@ int HCI_LE_Add_Device_To_White_List(unsigned int BluetoothStackID, return -1; } - const WhitelistEntry model = { - .Address_Type = Address_Type, - .Address = Address, - }; + WhitelistEntry model; + model.Address_Type = Address_Type; + memcpy(model.Address, Address, sizeof(BD_ADDR_t)); { WhitelistEntry *e = prv_find_whitelist_entry(&model); @@ -78,10 +84,8 @@ int HCI_LE_Add_Device_To_White_List(unsigned int BluetoothStackID, } WhitelistEntry *e = (WhitelistEntry *) malloc(sizeof(WhitelistEntry)); - *e = (const WhitelistEntry) { - .Address_Type = Address_Type, - .Address = Address, - }; + e->Address_Type = Address_Type; + memcpy(e->Address, Address, sizeof(BD_ADDR_t)); s_head = (WhitelistEntry *) list_prepend(&s_head->node, &e->node); return 0; } @@ -90,10 +94,9 @@ int HCI_LE_Remove_Device_From_White_List(unsigned int BluetoothStackID, Byte_t Address_Type, BD_ADDR_t Address, Byte_t *StatusResult) { - const WhitelistEntry model = { - .Address_Type = Address_Type, - .Address = Address, - }; + WhitelistEntry model; + model.Address_Type = Address_Type; + memcpy(model.Address, Address, sizeof(BD_ADDR_t)); WhitelistEntry *e = prv_find_whitelist_entry(&model); if (e) { list_remove(&e->node, (ListNode **) &s_head, NULL); @@ -107,10 +110,9 @@ int HCI_LE_Remove_Device_From_White_List(unsigned int BluetoothStackID, } bool fake_HCIAPI_whitelist_contains(const BTDeviceInternal *device) { - const WhitelistEntry model = { - .Address_Type = device->is_random_address ? 0x01 : 0x00, - .Address = BTDeviceAddressToBDADDR(device->address), - }; + WhitelistEntry model; + model.Address_Type = device->is_random_address ? 0x01 : 0x00; + memcpy(model.Address, device->address.octets, sizeof(BD_ADDR_t)); return (prv_find_whitelist_entry(&model) != NULL); } From 6616c55bdae73182999b8b3ac180f071c775be99 Mon Sep 17 00:00:00 2001 From: Joseph Mearman Date: Mon, 9 Mar 2026 21:54:04 +0000 Subject: [PATCH 04/10] tests: add Docker testing scripts for CI-matched environment Add run-tests-docker.sh to run tests in Docker matching CI environment, and generate-linux-fixtures.sh to generate Linux-specific test fixtures. Co-authored-by: Claude Signed-off-by: Joseph Mearman --- tests/generate-linux-fixtures.sh | 42 ++++++++++++++++++++++++++++++++ tests/run-tests-docker.sh | 24 ++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100755 tests/generate-linux-fixtures.sh create mode 100755 tests/run-tests-docker.sh diff --git a/tests/generate-linux-fixtures.sh b/tests/generate-linux-fixtures.sh new file mode 100755 index 000000000..6e0f7ecef --- /dev/null +++ b/tests/generate-linux-fixtures.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# SPDX-FileCopyrightText: 2026 Core Devices LLC +# SPDX-License-Identifier: Apache-2.0 +# Generate Linux fixtures using Docker +# This script runs tests in Docker to generate Linux-specific test fixtures + +set -e + +DOCKER_IMAGE="ghcr.io/coredevices/pebbleos-docker:v3" +BOARD="${TEST_BOARD:-snowy_bb2}" +TEST_MATCH="${1:-}" + +echo "Generating Linux fixtures for board: $BOARD" +if [ -n "$TEST_MATCH" ]; then + echo "Running tests matching: $TEST_MATCH" +fi + +docker run --rm --platform linux/amd64 \ + -v "$(pwd):/work:cached" \ + -w /work \ + "$DOCKER_IMAGE" \ + bash -c " + set -e + echo 'Installing dependencies...' + pip install -U pip > /dev/null 2>&1 + pip install -r requirements.txt > /dev/null 2>&1 + + echo 'Configuring...' + rm -f .wafpickle* .lock-waf* 2>/dev/null + ./waf configure --board=$BOARD + + echo 'Running tests...' + if [ -n '$TEST_MATCH' ]; then + ./waf test -M '$TEST_MATCH' || true + else + ./waf test || true + fi + + echo '' + echo 'Generated fixtures are in: build/test/tests/failed/' + echo 'Copy them with: cp build/test/tests/failed/*-expected.pbi tests/fixtures/graphics/' + " diff --git a/tests/run-tests-docker.sh b/tests/run-tests-docker.sh new file mode 100755 index 000000000..acef44afe --- /dev/null +++ b/tests/run-tests-docker.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# SPDX-FileCopyrightText: 2026 Core Devices LLC +# SPDX-License-Identifier: Apache-2.0 +# Run tests in Docker to match CI environment +# This ensures consistent test results across different development platforms + +set -e + +DOCKER_IMAGE="ghcr.io/coredevices/pebbleos-docker:v3" +BOARD="${TEST_BOARD:-snowy_bb2}" + +echo "Running tests in Docker for board: $BOARD" +echo "This matches the CI environment for consistent test results" + +docker run --rm --platform linux/amd64 \ + -v "$(pwd):/work:cached" \ + -w /work \ + "$DOCKER_IMAGE" \ + ./waf configure --board="$BOARD" \ + && docker run --rm --platform linux/amd64 \ + -v "$(pwd):/work:cached" \ + -w /work \ + "$DOCKER_IMAGE" \ + ./waf test "$@" From a1e42b5d75965095b4036de66d36f7f95288ed46 Mon Sep 17 00:00:00 2001 From: Joseph Mearman Date: Mon, 9 Mar 2026 21:54:11 +0000 Subject: [PATCH 05/10] tests: add documentation for cross-platform testing Document the cross-platform fixture naming scheme, Docker testing workflow, and troubleshooting for CI vs local test discrepancies. Co-authored-by: Claude Signed-off-by: Joseph Mearman --- tests/README.md | 106 +++++++++++++++++++++++++++++++++++++++ tests/fw/graphics/util.h | 7 ++- 2 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 tests/README.md diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 000000000..16fae107a --- /dev/null +++ b/tests/README.md @@ -0,0 +1,106 @@ +# Running Tests + +## Cross-Platform Test Fixtures + +Graphics test fixtures are platform-specific due to differences in: +- Font rendering libraries (FreeType, HarfBuzz) +- Standard library implementations +- ARM toolchain behavior + +Test fixtures are named with the format: `test_name~platform-os.pbi` +- `~spalding-linux.pbi` - Generated on Linux (CI environment) +- `~spalding-darwin.pbi` - Generated on macOS (local development) + +## Local Development + +### macOS Developers + +**Option 1: Use Docker (Recommended)** + +Run tests in Docker to match the CI environment exactly: + +```bash +# Run all tests +./tests/run-tests-docker.sh + +# Run specific tests +./tests/run-tests-docker.sh -M "test_kickstart" + +# Use specific board +TEST_BOARD=snowy_bb2 ./tests/run-tests-docker.sh +``` + +This ensures your test results match CI exactly. + +**Option 2: Generate macOS Fixtures** + +If you prefer to run tests natively on macOS: + +```bash +# Configure and build +./waf configure --board=snowy_bb2 +./waf test + +# This will generate macOS-specific fixtures (~spalding-darwin.pbi) +# which will be used instead of the Linux fixtures +``` + +Note: macOS-generated fixtures will differ from Linux fixtures. This is expected +and doesn't indicate a problem with your changes. Use Docker to verify against CI. + +### Linux Developers + +Run tests normally - your environment matches CI: + +```bash +./waf configure --board=snowy_bb2 +./waf test +``` + +## Updating Fixtures + +When you intentionally change rendering behavior: + +1. **Run tests in Docker** to generate new Linux fixtures: + ```bash + ./tests/run-tests-docker.sh + ``` + +2. **Copy the generated fixtures** from the failed test directory: + ```bash + cp build/test/tests/failed/*-expected.pbi tests/fixtures/graphics/ + ``` + +3. **Update filenames** to include the `-linux` suffix if needed: + ```bash + # Rename from ~spalding.pbi to ~spalding-linux.pbi + ``` + +4. **Commit and push** the updated fixtures + +## CI Environment + +- Container: `ghcr.io/coredevices/pebbleos-docker:v3` +- OS: Ubuntu 24.04 (Linux) +- Board: snowy_bb2 +- Compiler: arm-none-eabi-gcc 14.2.Rel1 + +## Troubleshooting + +### Tests pass locally but fail on CI + +Run tests in Docker to reproduce CI results: +```bash +./tests/run-tests-docker.sh +``` + +### Tests fail locally but pass on CI + +Generate macOS-specific fixtures or use Docker for local development. + +### Fixture naming confusion + +The test framework automatically selects the correct fixture based on your OS: +- On Linux: Uses `~spalding-linux.pbi` +- On macOS: Uses `~spalding-darwin.pbi` +- Falls back to `~spalding.pbi` if OS-specific doesn't exist diff --git a/tests/fw/graphics/util.h b/tests/fw/graphics/util.h index a8037a361..6b3d9720d 100644 --- a/tests/fw/graphics/util.h +++ b/tests/fw/graphics/util.h @@ -58,12 +58,11 @@ static const char *namecat(const char* str1, const char* str2){ printf("filename and filename_xbit %s : %s\n", filename, filename_xbit); } else { #if !PLATFORM_DEFAULT - // Add ~platform to files with unit-tests built for a specific platform - // On macOS, append -darwin suffix to allow different fixtures for local dev - // Linux (CI) uses the standard ~platform naming to match existing fixtures + // On macOS, append ~platform-darwin suffix to allow different fixtures for local dev + // Linux (CI) uses the base fixture name without any platform suffix +#if defined(__APPLE__) strcat(filename, "~"); strcat(filename, PLATFORM_NAME); -#if defined(__APPLE__) strcat(filename, "-darwin"); #endif #endif From 4358b72ace85a4313d0f39191d183a3885601e89 Mon Sep 17 00:00:00 2001 From: Joseph Mearman Date: Mon, 9 Mar 2026 23:08:27 +0000 Subject: [PATCH 06/10] tests/fw/graphics/util: fix platform suffix for Linux CI Restore platform suffix on Linux (e.g. ~spalding) while keeping the additional -darwin suffix for macOS local development. This matches the naming convention of the PNG fixture files in the repository. Co-authored-by: Claude Signed-off-by: Joseph Mearman --- tests/fw/graphics/util.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/fw/graphics/util.h b/tests/fw/graphics/util.h index 6b3d9720d..405956cfd 100644 --- a/tests/fw/graphics/util.h +++ b/tests/fw/graphics/util.h @@ -58,11 +58,11 @@ static const char *namecat(const char* str1, const char* str2){ printf("filename and filename_xbit %s : %s\n", filename, filename_xbit); } else { #if !PLATFORM_DEFAULT - // On macOS, append ~platform-darwin suffix to allow different fixtures for local dev - // Linux (CI) uses the base fixture name without any platform suffix -#if defined(__APPLE__) + // Append platform suffix for non-default platforms strcat(filename, "~"); strcat(filename, PLATFORM_NAME); +#if defined(__APPLE__) + // On macOS, also append -darwin to differentiate local dev fixtures from CI strcat(filename, "-darwin"); #endif #endif From 4ffccdd868bd8f9d861328ad13c11e195a12bdff Mon Sep 17 00:00:00 2001 From: Joseph Mearman Date: Mon, 9 Mar 2026 22:56:44 +0000 Subject: [PATCH 07/10] tests/fixtures: add kickstart watchface test fixtures Add expected output fixtures for test_kickstart tests covering various display states including heart rate, steps, and obstructed areas. Co-authored-by: Claude Signed-off-by: Joseph Mearman --- .../test_kickstart__render_PBL_43681.pbi | Bin 0 -> 45612 bytes .../test_kickstart__render_PBL_43717.pbi | Bin 0 -> 45612 bytes .../graphics/test_kickstart__render_hr_bpm.pbi | Bin 0 -> 45612 bytes .../test_kickstart__render_hr_bpm_24h.pbi | Bin 0 -> 45612 bytes ...test_kickstart__render_hr_bpm_obstructed.pbi | Bin 0 -> 45612 bytes ..._kickstart__render_hr_bpm_obstructed_24h.pbi | Bin 0 -> 45612 bytes .../graphics/test_kickstart__render_no_data.pbi | Bin 0 -> 45612 bytes .../test_kickstart__render_obstructed_area.pbi | Bin 0 -> 45612 bytes ..._kickstart__render_steps_above_daily_avg.pbi | Bin 0 -> 45612 bytes ...kstart__render_steps_above_daily_avg_24h.pbi | Bin 0 -> 45612 bytes ...st_kickstart__render_steps_above_typical.pbi | Bin 0 -> 45612 bytes ...st_kickstart__render_steps_below_typical.pbi | Bin 0 -> 45612 bytes 12 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/fixtures/graphics/test_kickstart__render_PBL_43681.pbi create mode 100644 tests/fixtures/graphics/test_kickstart__render_PBL_43717.pbi create mode 100644 tests/fixtures/graphics/test_kickstart__render_hr_bpm.pbi create mode 100644 tests/fixtures/graphics/test_kickstart__render_hr_bpm_24h.pbi create mode 100644 tests/fixtures/graphics/test_kickstart__render_hr_bpm_obstructed.pbi create mode 100644 tests/fixtures/graphics/test_kickstart__render_hr_bpm_obstructed_24h.pbi create mode 100644 tests/fixtures/graphics/test_kickstart__render_no_data.pbi create mode 100644 tests/fixtures/graphics/test_kickstart__render_obstructed_area.pbi create mode 100644 tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg.pbi create mode 100644 tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg_24h.pbi create mode 100644 tests/fixtures/graphics/test_kickstart__render_steps_above_typical.pbi create mode 100644 tests/fixtures/graphics/test_kickstart__render_steps_below_typical.pbi diff --git a/tests/fixtures/graphics/test_kickstart__render_PBL_43681.pbi b/tests/fixtures/graphics/test_kickstart__render_PBL_43681.pbi new file mode 100644 index 0000000000000000000000000000000000000000..e339351de0e1b122a674a06d7df4f12a1449c27c GIT binary patch literal 45612 zcmeI2L2lzP3`K)E!QB5eT^8uJN0>zqQ6M8(B0ueDrm-tEit!8-qDYDQd{o?^=yzbY@6L!2;kE|n?(d+Y(^7thS{fOl`zW&CbIzmY@ z`>R(*>c}iAg$2v%Ua1M(D_xp9tdrdBqJ`_kYf*BVO~v_ND>)f@c96 zLuVSU`mVaUSJ`3C!y50|C{1~Fn3-u~2sT`&siQzQ^xg(H?qT|!HDX)(;khhe;}`vy zst#%Pa>7;fs2ed@cGQM=8{AOBF_tu?{HsYlPd>NY2pd8HIZ^$QQL_yjq$wX=)x^`Z zz%4f>twZ`kA#%Fq#+P+0TpDmf{!XSewXao_YVFdVU==-8a~|yH=YM~g&K05{)#448 zi4ApR*D|fXRo3nkX$s`yDO%u`8`@%8>uCCIj0wls(j-x>^})tg;=aCg_>JJz35^9Um+dLpOuvm59XB>Ktq*G~Xt`|Ds*W(R_^2^z zYMv1n6kWPavTCHhq3k{Nh&rTqU5@;2x$*xxQglh>HLer)ow+7AHu>du%Z)kf*c4Ew zEz!5{24@~y@Q8j$?xq|C+;U^Wen{J<4+^;DhS%ZksNYX&S7LKEczRDwlV24(KmikJ z9#^k#mbN5qUd%AJSD57;G*)qG(6bzsrZ#ROxeh&LkS4K2+^bo7LO*8dMA1P% z=*I{G+^Z2(kLRQx$Jve8Nk2wVJ)V<(9A`ITC;b>f^>|MDah%b;Xk{>ky literal 0 HcmV?d00001 diff --git a/tests/fixtures/graphics/test_kickstart__render_PBL_43717.pbi b/tests/fixtures/graphics/test_kickstart__render_PBL_43717.pbi new file mode 100644 index 0000000000000000000000000000000000000000..928886b4380295c0757242796c01cc20caa9044d GIT binary patch literal 45612 zcmeI5O>W~b3`T=F!QB5eT{in3p^F}(Kt_M$M>|StxN_ono`FJ?C{g?#X}603=Kb{N z?OnoWXfpbWzM`*g6X5;e{kYv7>pi8f z)*s)^Np$R{6eW?5RFIE-rL-=aukWvQ2RZd$5x86~MQ%n5;`(>E7o!9aS0!$8}f#?lLs8wSI^XuWsG`1QXFrxP>(3j@r^e&(h(%d z9G|@+q9e0t6bhC}U#ST6m6~ROb+EpY;@B#ARdcu82+s1c()a3Fef4`CSwlxhd~0;c zcuQ<+?D;$(cb6N%Sv8mtWiM-d?lGcrLPsG`O0k=I%*(UZ-5uf-SDjamhjDly`@jnKlMzXX!9HDs)5dWpHB&)8Fh7+gcBgWeyvEsK>5! zC})=wTFt#~L}xwG3gTsOLjkw3lv9d7nY8<~=9U}bKoF1vwI3NR+Gc}t%2&5+;%(aC zmK!_Oq5OgnExP5#k2(sM4xA8wkg1&dZ530sa_LO4YCbLJJlN0Ue}7n>6GS0Z^LLgk z*`OmYm1$d>L>)d+PJw*9MH}35Lq{yvHd_8R#(>+{%1KF0Zqf#~+|ZGI>6i#;lU~x+ zU_nRPR-bar>R@9p@YuC<`BlP`8#)_$OLnG4v;1u|?{;G+r|DZS5hG|>?z=HF_J zId$)d8){zaCRxqXzEJj^dWH_=JC&n#x7@g|BY8_G*EkJ4cIG*`F^jKtx7^sLj+uZq z?InHvZE)tX1kb34(w)hX!!0*Lz7}4zXBaC9wIF__hT#PjFfM ztEJFKPpXHd#s~ojKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## zAOL~aClLOD&YsNI2a5s-KmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_0DT?X)fFB`N3O*A{QC7ckdD_cNA0Ks=qT?6I`;K> zpdP!b2j$pRIS%mKyz->4=&KC~q(9v^i2C@D2a&<&>hY~}_eT2aE}n-w4^oeV$l!DJ z@E73zh4j^ZK6oJj0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_u!O)rT%$O^ literal 0 HcmV?d00001 diff --git a/tests/fixtures/graphics/test_kickstart__render_hr_bpm.pbi b/tests/fixtures/graphics/test_kickstart__render_hr_bpm.pbi new file mode 100644 index 0000000000000000000000000000000000000000..f624203a67ba2e568c1e98fa0ba79b4902b0de52 GIT binary patch literal 45612 zcmeI2O^)O?422sxLGFK=UQX}l2wBW>4$weHe?(^&8zmLxWpRWO*0cCs+DC29@QQv_zkNOVOceUNKo~GTiov!}LcDni}>uK6O z>uK6O+v)0`Y^SS#vYw{hv!15ivz@N~$#%N>C+lh2J?m-OJ=^K(pKPbAf3lwDa-LM= z<>=~xRvq=d8sWL-F`~=$Io3R4uYP`hg5g&AWKEQ9x5`Oj%N^PIr+WG)NJxl$?VU%W z12Vt~6nGS~;|@T=gRpz=IUs*9HZ*~0wbXD|2_V4+6R(>FeKb}b zp(n1PYaae5%I?(<{4l}x?e5jgI{dXd>R!1xIvkh>miPF2>rUr;E;qw2h*>d*X|>dl zr{k-JbwEjGDs;hEbx^y@E%q*jlfssFT=Q^USog|b8oV}9!##={g-cY}@{z7^uTl{n z2YxgCu4%Q@fWz>sWWT%mBZbvjl1J;Hd!>PmF>Tp~T59BV6zEqS+S)3^dK=wy4K3Fr zHQ+FgLN1m~!K~*v2j440l(e>^mKv)L>5{I8&qE?h(`AKUuEJLO&3(96enU1Ta&bMj z4kOenV_Ryep-w_8$Zn0M|CY@nzieKm4#W0jim!(7Zmmbxp?Rd~vN|~V6H*P^g7*6e zim!&o-7pTV!vHOt?Wv{4LmhI56kiPsShiLju`kwJr{&^c%gjM7H7+_2VAWgdnnHTczb)l$O_6F-%+ z>cBo$+SXgw+|o1Vpq3gi54RUTA%@&1SxbR=@3{BeVQ}cEY+EfgpbmL7#t?p4<#c0u;x0RUb8%dVakQJOCo9(Nm#`Ak6FWjmlYw0to zz16#td8-37Uw!pZdk*(%$~=@PE5qo`GGDc>TZbUZ3V*UcZfP0#o==)bHVA>0wX%-F zU#YCfECtGgey<#@eL{REWzA0f1+!0dGNkYnp_4F2wpJanAFi?9u>PhEdaLDBS}0n4 z<*&IRl76YT7|+(;c|40f@@&;HvfHn7t$Doe(MXRqkCEMeoomhGb&p1RyyZM@Toj>` z7nL=p;r`^yeaU z68*79Mj&(&BPsfG5ju(f*drqlI*E}K{kaI8M1Sm&5eS{cNQ(YkgifMA_Q(i?PGTfQ ze=b5N(I0zc1VSe=p=3c4~T?L z0-SDO5;}<+zyl(olK`h1n1oK^2JnDL=p?}D1}34CxB)yM5;_TRx`9dPByIo?h=fi8 zoNizeI*F6v|E7;i1Lj6j^Z5HWxu_8}p_AAMdDOO{-MtRqkRG;uVU~Fj53;YD&V?xJSzi!(JogX4l^g6@#<1l)&O1a{x|91cCKj=y5B+%;wJJeu>MAEH1zGDBm zWE~z_@MYa7Bv$bbbx47s7XOo#RZdrlggklD8aaeU){SI#>@D|-T(l13EEi(up^o@P zt~3G?XbCVan_2AKTk^uAJE4<6uM_NumH>^joXO6;b=f)$vs?ze)UgidmOVow zAh8khsO`vs-%lbNbg z)ly^CvE8?MCv=ra%wuZFOz0$9qRo4T&`Hc=YROFKBwC`)dxp?S%wuZFOz0$9qRo4T z&`Hc=YROFKBwC`)dxp?S%wuZFOz0$9qRo4T&`Hc=YROFKBwC`)dxp?S%wuZFOz0$9 zqRo4T&`FGC`ug(u1VC~p%_p`gZg4IUYz3zQ=DXG5TNZ0lD@dtRj?KsW*(7ZaV#V`8 z-!5sSv2V3j9bqJcCK1!T%RJIMfw$|H_iELVuD|>`J+4FFkBxZ*2Kb3J)2zt($S*q= ztOMY|OvMU!zFwpbhovNH;$}R}=}qg?LyU-s-^yqCrH;ok+`ZiT*yAHCtUz#m-lC10 z32v*3g6pZ}#C-UzfST8s%#y>)*8vj&dN5-p*RMkhA$Ah3lvRh^%wyKrU;Ng%(t26L z0SUKr?Rf;+gskMa3B_(zqAo*>NQvJ*Eh5LWY*X2`s?ev@^IQWfu-w5)Qg?Avp>9)$ zmO(>Wb!Z2UHDbH*+sB71bk})U31-FC>gXcxKM!+M7Lt2e~)WTz>%1%(+~9vuE%i_ePrQ58##TSH literal 0 HcmV?d00001 diff --git a/tests/fixtures/graphics/test_kickstart__render_hr_bpm_24h.pbi b/tests/fixtures/graphics/test_kickstart__render_hr_bpm_24h.pbi new file mode 100644 index 0000000000000000000000000000000000000000..92960e0e35e63dd7b67cc9655d38b87e4405ba86 GIT binary patch literal 45612 zcmeI2L2leS42FYug5Li$SvLC~;Vrt%0R~7d$rSl>=&>x2mOap*wfIvM`H}LZEzsW| z|NZ({KEFTy|M)!N^L4`Kgf>1;Xya@4(LRBBAMF!ppK5<(J57INKVAFDe!BLP?KJ(7 z?KJ(7{dDao`{~+Gw$t=Sw$t=S_S3bW?5Ar#*-q0R*-q0R*-zJgvY)Q~WIN5}BB9C4 z(X|83KH6t>M&!JYGp5{LW8TNptbX`Id+hlk7p=yY;iBl>)$cw8#m`D@xCqGDGF%kB zzs^4NjFxe(u4+}|lPw*?TO7ldF0!dz??W>(4_i8B_5pV@?*qoM2!3^{RSmH@-zz;h z(DS{5aV)}ki3}H=GPVpCMenckKJ<)?aT+c;WZ9VTp&&C+1;i6NhywU32l{ggVS@>*Tlu(#Oz1iIsxeLM|_he`jj zA^o$1K5O_Qi$(tG$Zr^VpOWu6{O)6~QtbZhBX+(=v(NiDIY;AY$u!X9si;-j!nW0Xm4-y589V9fWtK*nEHvBDSt~c0dQ=T`4vn zpo565>zy6YL3me+%?IcpV(WTm2XqkLm16S&I*8c1-q`^igmw0GgbP(Q^V)Fqyh}gQ`*#RAdccs{TfDR(Iu6K4o z2jN{QHXopah^_0L9ne8|SBlLC=pbV2dS?f85Z;wy^8q>tS(pAB&c#-N2XPKnHOHc!3D$AVkm&Oh5;519*W5=paPU4NO1>aRYdP2XPKnD>F|Gj>eGQ!*_$`Rk+Ye+SU26PY`DZSi`cK1HgMDkS2Xw`sW zUK~-Qs!;;r3P3<2f5B*_ne}NG;^5^Pa|o>z59lB$B4}l_*@qZ0Tmc9X6k*Q$$WwiT z???Kgr=QyJmcXk70>b=-c&|!w1qKy4cx~XieY|Qz{6xE4ADKOwX28tL&!d^1J?$k$?_DMg`cp z2X3U0Zq-R0r_Uw(NYI2&>qaA`i+AXQ8qB?CF%kU8y2yq~Pg_Q9BT z8{$h{`dGr$8Mp!v8!5fqg+o4HWM=4WEq5~ecrmV?EpZb(?X5%{QLSo}Gw>>b*vjeT z=Rcy;_cnjFGc$CxsxkZ6p4+$`c$GkmW9q34=pcHsjXMMAAjUEER0ebqJ=w;c0dx@K zn0hJ$I*6WZr?@PquMq03F0Qrk=`x4x%U9xHEtbVjNRXWk3hflWp7? zKnF37si!iagXqaN?hK%VIG5?`E7cA0wlKP}= zj!AKRlY9?kmHm^ROVL8Z&uYy+@|B!)6Q#_%+{gNzkZ;#5->ccj`ufvPr|0$5@5jb{ zWCrmgmQA(_=QBTfF4%{F7v|b5aqIOWeJog&q?*!Mb~QcgdioTjAj)UuMkY>h)-Gx!g^5)J4KVrZ&{kZ4E3@r7azSLRr*qtz9>kVi9(jThj`9LsgIx`G$-Xr{680$iD6xsFy>@IoHVG&Wvz>% literal 0 HcmV?d00001 diff --git a/tests/fixtures/graphics/test_kickstart__render_hr_bpm_obstructed.pbi b/tests/fixtures/graphics/test_kickstart__render_hr_bpm_obstructed.pbi new file mode 100644 index 0000000000000000000000000000000000000000..299daa45dc2e821e32fa7c72256e3960f8f977b3 GIT binary patch literal 45612 zcmeHPOOo3-4DFf|%>7T(i8z?@xF>p71<@#`_a!eC*(Hy*%hn=DJjf<%0V2M6$>26m*F9=S$@@oK1}c~6=BvtkMaXr*ZYvL$O7+2=AcA? z9??2}T_q3IuqXnpzqKC=8m@J0%>uVr-VN0R-GoRxXMH@VuK-c6L&hQtX6Di34?qX0 z`dzi~LlTk)Z~WcAU;(YcI)_(94W zA)D%71aj1t=LkQ5&)tZmMHYCHWlI%BdE{x$xieQn@_<}XTY1TKeVZTBQ$zd!JnuWQ z7Fht2Dn=a@zmERE_4t6k0z7{evKCn|D-Vxf;|R1inB$Sk%9Ho04?5~$_s6gMkzhpE zAZ?Kaj)!h7XDEIhb@l!@B@ajHK7&$m1ds5pNPKh777OBZfP=38*kEhn`CanMJPcBI zF!B~zu-;c`HJ?Quouq41)7E;WtF{6szSY{IY3?l;;fEpWXaGGT)LJwz4~3|s`^|Tm zG8+CpAM$=!tEe9eR>zGzf?ugXQqNu)zxaKX(BjG0q^XYGiZmFWQUqjqR|CD7pfHZe zqX-Cr;X_f(t*C^Hl#{$1rE8KO$Ae<><#a?W3FNN2JQQ9Q_!leRMPZh*TMu zqaWk6k8Y+Pkt*YI^kba%(alfy0sbnMINN3Y1nIVAqS z`XMiRYAgLg(&{#{uL_bI!15x@s|4odu|~sn-gG=NHV58?ZKuf0`|+Ops-_mDPw%U~ z$6tiUDvi#MPnqA?@O(d{(*Xw2qE!}sH5HG{0YvWc5YAGQ{@S02@zeb%z{{t;$Puud zD=ehgNa)UP&+I%DZssCiS>&OT95WU@tExA|wVSXmk-jLl?1Hg<1)L6&3$acfPL?CX zBC-EmIlcEIl_J&b8`@VlFaaP6a+KZ?@_;&rL`C8vujsq_bbd%JQq9f*eN}!)XGj({ zm@oloi!4BuMC8%xF?#lNKTaY{9w!OA^H}<^Q@E41(T|ga-FYni*eTpe+vvwh!tOkl ze(V&k+xC(F({)u-7wbGt-3pRg=0>e6=edO^g|Eg#WP_GD!be$g^QFjx{Yck?L5Xed za3e%b%Y{5zJ$BAs#gF<P|ea;1&6#D^6Pp&^U;3v z5MPBy&ui;^Hb1uF?(4{-S7hv*evH+>zny;cij18<=*REN@3DAq-ToMlpO?$!=dGiL z<{#scXk0Es@!qp7CJ#ThM7giF6i!}49&;H)Kj_C93j9iq^-B)^_u=QC$Db3w z!KeNG>O{^wnhH<>DnJFO02QDDRDcRl0V+TRr~nn90#twsPys4H1*iZOpaN8Y3Qz$m fKn17(6`%rCfC^9nDnJFO02QDDRDcRlfk=TrMIy=Z literal 0 HcmV?d00001 diff --git a/tests/fixtures/graphics/test_kickstart__render_hr_bpm_obstructed_24h.pbi b/tests/fixtures/graphics/test_kickstart__render_hr_bpm_obstructed_24h.pbi new file mode 100644 index 0000000000000000000000000000000000000000..c882cb5b04d317789c8a2620bc15b9b64182115e GIT binary patch literal 45612 zcmeI4O>!J55QP;!f$x8sUf2=VUK{Pb&{7BJ2${b}0+rPis43|7tMD|Cl|a7lWy|)& z#Qb^r@$-Thg$%BI=@`Vs|B(H9S@TzUZU0q{R*jK1p z3Bix-m9J6>wUr;UyXwcLtPCGiLJy%MNHXO|9c3u2FEK}EN(kA*V`> zwB9%-pE|~H?LF1`@dTz&M{fs=*+)OdaP2*ne)N(XvyXm^;o5sD{pck(W*_|+!?pKR z`q4{n%s%=thHLMs^rM&Dn0@qP4A8Gb z@R)*==}!5Q@%b52;w0Zf9XXG~E6>w?CexkmlHq42El%<+6a26RxN4-zye3&mhUqXD z#wa;{Mja)QgKI$?S|os0w@Wg7z*wf!kCMp2wIKdq{jgtj(^mM6BuY4stg}Ikv zUJ$UZj$1O4&Rb50t1T%$ndY5hSE(Nt*HX&W7{-u$?Z& z$ZXRpo4#5~htnWJYC5cDn`8cozcj_C`{4`spZFqcg}InlVUwc>>@4=It^?&dE%rwi zbpXkIM$a=)-GLi#lJ|CoFG_r!Oy>5L)R~l&OyxawBv|e_^@!8Y8>g3km{bX6`=<8Q zPEAsvB)FORj!=itxy#HW_INGdn@{0~&6QBLb3$MF-=tkhahla63n@Cz;zY9Sj5=~2 zvsb74F-S0V31Oib-z4iTqUW|$8}P-OeH7RLLE7e&egN{ z5xx_?Tcl^oJ}TE+YLoklItokH^urY?ZC3t7E;QKXL+DTyWJ=b92*<(_okorzQhkHED3IFTE4HSV{6*Lh{v6L zO83aj-(Rk?s#fVMUx)o>*gvj^s$`Z2GX;LJo(@~rLmPbA5Fraq%4LSj!;#K|e+icsGspZV&$5{QPQv2L1$J_Rm)XHS=f^ zAOR8}0TLhq5+DH*AOR8}0TLhq5+DH*AOR8}0TLhq5+DH*AOR8}0TLhq5+DH*AOR8} Q0TLhq5+DH*AOVfQKQ%nY;s5{u literal 0 HcmV?d00001 diff --git a/tests/fixtures/graphics/test_kickstart__render_no_data.pbi b/tests/fixtures/graphics/test_kickstart__render_no_data.pbi new file mode 100644 index 0000000000000000000000000000000000000000..e339351de0e1b122a674a06d7df4f12a1449c27c GIT binary patch literal 45612 zcmeI2L2lzP3`K)E!QB5eT^8uJN0>zqQ6M8(B0ueDrm-tEit!8-qDYDQd{o?^=yzbY@6L!2;kE|n?(d+Y(^7thS{fOl`zW&CbIzmY@ z`>R(*>c}iAg$2v%Ua1M(D_xp9tdrdBqJ`_kYf*BVO~v_ND>)f@c96 zLuVSU`mVaUSJ`3C!y50|C{1~Fn3-u~2sT`&siQzQ^xg(H?qT|!HDX)(;khhe;}`vy zst#%Pa>7;fs2ed@cGQM=8{AOBF_tu?{HsYlPd>NY2pd8HIZ^$QQL_yjq$wX=)x^`Z zz%4f>twZ`kA#%Fq#+P+0TpDmf{!XSewXao_YVFdVU==-8a~|yH=YM~g&K05{)#448 zi4ApR*D|fXRo3nkX$s`yDO%u`8`@%8>uCCIj0wls(j-x>^})tg;=aCg_>JJz35^9Um+dLpOuvm59XB>Ktq*G~Xt`|Ds*W(R_^2^z zYMv1n6kWPavTCHhq3k{Nh&rTqU5@;2x$*xxQglh>HLer)ow+7AHu>du%Z)kf*c4Ew zEz!5{24@~y@Q8j$?xq|C+;U^Wen{J<4+^;DhS%ZksNYX&S7LKEczRDwlV24(KmikJ z9#^k#mbN5qUd%AJSD57;G*)qG(6bzsrZ#ROxeh&LkS4K2+^bo7LO*8dMA1P% z=*I{G+^Z2(kLRQx$Jve8Nk2wVJ)V<(9A`ITC;b>f^>|MDah%b;Xk{>ky literal 0 HcmV?d00001 diff --git a/tests/fixtures/graphics/test_kickstart__render_obstructed_area.pbi b/tests/fixtures/graphics/test_kickstart__render_obstructed_area.pbi new file mode 100644 index 0000000000000000000000000000000000000000..c545ebc8f6358f4df49f93610cc2278833cb4fd7 GIT binary patch literal 45612 zcmeHPOOD$x3=MjM-v2b&v>0HvJwg{f!~m&&kECST@+fw~1kY$qij?H{k)5vkaryD{ z60VQS-^=v@*XIMS2hg}afX3$pkK65*R)vVG*#+egV<+-3B}40WlYwS&wv_iK4T3$x zg3cf-#IU&SL}2z(Z12d!dSG*9y_G@3{V^&VXO~cAd6!P7Q_6ef6=@Sm!`7OQvqWz^ zt(_4dk%zT02xNpesV%oEcE->5<95{pL>_Z~#Mk4f_ap2hh8RDrO`UVpmgacK2`_ZQ zuA1dX=vXpIs>u}(LrK#Xb8k!@r<^M_f#<4s>{e^#toM(6T-E7xN^xTPlOJSEFlp{> z-|u`sbaMq+Aj!8!I+7TYZ^I+LX6aRn^wk9GQWj?Wev}`ob$Ol^B$LGYkvM>eqStI2 zKf2@r4YMMu^-KG)pka=V^dvFO{BA%KJx!Y7 z_z?>zV&~0xj30_nq}GyTlE@^W1>_KO8t*7>;z#q@JQQ|BB=98x&QUyyhdc+OBL;Bz zWtT)tM*g^iz?Ve!9VCbFP=NY0tw|=yf(Oo!z?Vcf+|I}&N>(l$9E@Y^h~Ft$BjTd+ zSChEap6dud6rXvb7A2F!lFUnrDBzKXrDpcrNXbLx>K!X9Ir{tjh-d04ekeTayH+KW zL`g!75`iDlZn&KvaIO@deUw%ulf)|ziywIpG!B^I5vJuUt%DDU*lZk=A7ADAGoFtb z;o&9K480V!ESV&R2iD}>fFBXvajbZJ{TnYRGdh^+wVesQ5*AfF%mDpSta*Hmrc2*q zlA=xQgp5mF(5!UI7Yg60yLn9bp?EEey}#!@9)V@rN_zFi{ZZw|%=_VqN1x(mRp86} z-b|MX<`BtTX^Q67f@wb*2z!P=g1A_t4ap=i)UeJS4}e89Z_2VHcH}o4cS{OH2Qj@L zgE_r6Fv(HDBy9jBD(Zq{m=YGJ)Qs^7!@h%fCy#(puk@%eL~J?{ycyv2ZCbL#x$?Ak={wYI%z~**rd92e2RB>UGr^QyvJg#}Hf&+_olhp<1 zHChNu9(uqQD7^DXWR#(14U-q+vFZqUG{)XPY|o4yDbq1&^+XqbWN-@6jDatJPF0;$ z(eUxzHMkQx9fL;v`Fmv^S#;&)`#m=}8$ZY+EAZI+JNgkhZScyirOfg{So;U@a>?-( zfCxK>G~H4OPXe#1h-Qx1VvT1#`=k*-gzXa!Gfq!@6&^;OSv^60cD;dcNIHwd8;@Br z$YWNybJo$1b99~Em43`Bcg{NcagMIDyV8$Y<<410KhDv0c31U-85N)cRNyTY`2Fqc z*Y~g4Z!p(U0V+TRr~nn90#twsPys4H1*iZOpaN8Y3Qz$mKn17(6`%rCfC^9nDnJFO g02QDDRDcRl0V+TRr~nn90#twsPys4H1$Ha&AHRQcY5)KL literal 0 HcmV?d00001 diff --git a/tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg.pbi b/tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg.pbi new file mode 100644 index 0000000000000000000000000000000000000000..2c6a8d66a575f6cd4870f2182e50f0b1f586af37 GIT binary patch literal 45612 zcmeI4QIg{}3`D1Lg53W!^SS$JiD!AmVWM+lN0q-gCrxDeL;F<}11 z^H^KEcYWV-4~8<$QR#pyBU5#T(ulNhk~%D+pETPP)RNUJrJ{wL%YWT@UvTHJn>{C5{WQe2%UQT0vt z3L87)9`XPbL|?~%e%4_pgcjcv-rHvD=hSj6LC|753cFZ-3a)NqeAn-lC2>TJU=3o{ zVO_##w@61=ZVK=1X7e8_Td@i#!+#*ba-5T_#Z}08e&ApxckQ<;NE_xo$M}>G03gVA-;BL`|V~O^Q z82kIEGmT#lMz!PeXGpb;_XD-pBCC$R%4JTdu{zdwKBW#P=5jm=1>r?*z-!g*QRBCf zHymrZP6&+sebkv8>fmt$6ofx=tvU_`?2{3+T`;O+v9-_kn4N=-qm7R-v|q&0cQ#v+ z?@O)@UJpY-P#yM6+s*iGwAJ%b@DVtFhF1nmynOF_Zq3+Vke$Cpv3A_}I0Lqbqwj3S zbqqah*oj6VdzR4c|LnfD4u>Y6|hAdeP^=;XkBuyJ%G1CS4L*v{;G8_ zwb4>-EkrF(s>9H-N4ZW2WRu1616xFFpKQ0_BalrN%MWZ3v3;`Lf{#EpSu8)WMa1^W zb_+fN*<`W&z!nkPC)+Lf2xODR@&j8$Y@ckm;3JSt7RwK85wU%;-GYxmHd!n`utmi7 z$#x4q0@-A-{J<6w+b7#C_y}Z^#qtANL~NgIx8Ng?O%}@!Y!R`2vfYA@KsH${Kd?o_ z_Q`e&J_6ZfvHZXm5!)x*E%*pzlg07_TSRQ1Y`5SekWCiL4{Q;!eX`wxk3cqAEI+VC z#P-Q{3qAtbWU>6f77^Pg+b#GAWRu1616xFFpKQ0_BalrN%MWZ3v3;`Lf{#EpSu8)W zMa1^Wb_+fN*<`W&z!nkPC)+Lf2xODR@&j8$Y@ckm;3JSt7RwK85wU%;-GYw*lhI$$ zxsoJAV2dDA0V((h6o4m0V2dDA0V((h6o4m0V2dDA0V((h6o4m0V2dDA0V((h6o4m0 zV2dDA0V((h6o4m0V2dDA0V((h6o4m0V2dDA0V((h6o4m0V2dDA0V((h6o4m0V2dDA z0V((h6o4m0V2dDA0V((h6o4m0V2dDA0V((h6o4m0V2dDA0V((h6o4m0V2dDA0V((h z6o4m0V2dDA0V((h6o4m0V2dDA0V((h6o4m0V2dDA0V((h6o4m0V2dDA0V((h6o4m0 zV2dDA0V((h6o4m0V2dDA0V((h6o4m0V2dDA0V((h6o4m0V2dDA0V((h6o4m0V2dDA z0V((h6o4m0V2dDA0V((h6o4m0V2dDA0V((h6o4m0V2dDA0eQgx=sy1xC}2mtS;xnJ zWeT}n$Hxz;#`1Ruj}V zwK{FtJ*&^p%g@17TYu5_lC;tIH`J_SJCYZjL`(Bi&SQTk_;!`NSF?`&`rEIQjxT*b zPR?Uvpr2Tmt{SKETjYXu5Io7fSmW-;i`21TfdrC+ZMCQOIi7xrXo&m`KF@D;Xc^1B zJp1_LuTWfp;jVdynu9ysSrr58Q_E@j_#1%8>rAd}@$z-hi4Z->R>}42Kp_YA!(=IC z)?qjEd&bsZ{>Hx6dKrlMm>rlMm>rlMm>tj#{0}sYh3WtR literal 0 HcmV?d00001 diff --git a/tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg_24h.pbi b/tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg_24h.pbi new file mode 100644 index 0000000000000000000000000000000000000000..982e9f211dc725a90c5f7692f39733c2d4d9198a GIT binary patch literal 45612 zcmeHNTaMc>3=DdL-v2cD-2Lwn`q4uK*xHs!(KH>IL?}7ITNBR_b z8ZN3bLWYa7+b8tU92s;PE~+v@hKsV>C-l%98FU&hsxm@`i?Z7%^w1m`bUtxC3CUm8 z^pL}QZ#@Vy*r={2lm(zRLP|O*f9UuL7z2! zx)zK4>{#9~^6r|q9Iw-(H7PfaJ#zW=c84Bb#&YwaM=rnK?$E=_SZ+S_$mQ4D9eQ{f z%gu)#x%_&&Lk}-wx%to|mtSvp=;387Hy?WB^6TvmJ-m$N=0lHMe!bnHhnKP3eCUzO zueUq&@G_R04?S}E^>&9IUdD3sp+_#i-tN%D%UEtc^vLDc+Z}p%8OzN-rw9EvoQs`; znsa-If{U8i<66Q%59pD>0N$$%R^vUPN1VHiO6ZZnYP=`(h;x@w2|Y4cjrW8eaqcoI zp+^R*@t)8l&Rs?&^vGZ}-V=Jnxyz`89vQ60dqR&mcNvw?BZJj=Pv{ZnE~659WUw0V z2|eQ6WmH0s3|8Ykp+}s%j7sQ{!D_rG^oVnpQ3*XVSdI7mNIf3v^C!+v@5+rHYK_O^ zUvD_!dC&KFg!}d`e7?tr=<%-KkBvBe-;D3?c^(0v+3S59sZL50aq3V{k<`Kbv^{3Z z%1&%8SK5=pHD}JNN>&}nD)COwX=p)HpKM`|MUqZRlrf*8$NHU+Z`WJCSJ-2H{pqLE z{_OhwIM8FkAb!MFvswk`9zS_5xQ75Q%yn79tF~MRaY)WT|YV`Ha)m@ANQ9c=8 zolkr0*O=bRqfagGVaW{$?mXADrE>*$w1ttHx=xuVpA3-aR!r5R;N|xaiU{<=ESp?^ z4_;)0eRG*s!5;KxzUD0a$|v_F>gikpo6F?6wjK-G6*422POy^FI$)Mh54_;#<682yQUTYM(<#X;YUZHo@qpnb`LY=-Z z-m85-3ZCWPgGGP{7MFLr0xz!KPGj>0aAl6g<(;m; zi>tTO*n9z8nPYKzrz`N{>g_Z(UjSF;SX|!e3cR>_JB`g3z?C@`mv_1XFRtEBWAg=Y zWsb$=ovy%(tGCnGd;wgUV{v(>EAZm#?KC!D09WQ%T;AylJg#5>41fVJ00zJS7ytuc HV9&sRD=~w! literal 0 HcmV?d00001 diff --git a/tests/fixtures/graphics/test_kickstart__render_steps_above_typical.pbi b/tests/fixtures/graphics/test_kickstart__render_steps_above_typical.pbi new file mode 100644 index 0000000000000000000000000000000000000000..7e81c21f9d5dc542d3c388b1a1de043c79a5cd51 GIT binary patch literal 45612 zcmeHNOL8SC40Oy1`u?Z!(%$zGW-*6wgqvSVf`=b!xkTX!)#8x|AyS!CwPRx5UjF&@ zlAgDhe_viVJntKx4Q;$`XyZNl&?^vr=oQebYR}ZOv1i)Z>37=M>38bc*faHP?3s3U z`ki)m`ki_<_Dnq+d#0V8ey5$Cey5&|JyXxdo@r;N-)U#3->GMFTxQqgaqRSjq7S`R zJ2JzM9V+Y32tTS;pP!!vq!G^`BEo6J$|RJQc>R?!^NwzU665$?KN>s1OwcJTgNM;mDVO+T`N z@xA&KA0`q0arf%ZKJvA?>RzQfWRCDdw)gmYQ{~0eRCh~RSqDC%G2@MKA0h084eL5KuKT= z%4w`H{~|c$kKieNFzw8Y=o0|nug0tUpmQKP#zYSPLK5JRkUv)-`UI%%7vR!9m>{3V zF+v0$`oJ9``UJS(97P{h7uGh-adD(%oIr@cp?)ww(Fg|#5m@$-uNCf^s5yaG-Ye!O z4&opo0>}0t_ybNzPeKsA7|<+8_!d8y9(u?lM+p(&#m2vDC;E^&Dlu!D#GUQo1VRLa zA1PL!QUmu1kjJ5m3>Ulnu$-& z(PCws3JB`>FT1oht>1!|^+A+|(>P9u!1H^B7cTl3Bz-m|ZRxHI*_0r}r(9Yj&BeXC z#SdaMw888daW0{A`v66Z;$Qa15VaxS^PBt_i~w1T%04E4QgM^R5psIb_bRdFr_@hV zjKfO4VEoi1rc`!y)Vm2M_9*(OdL&^pV0~Mld#kYu2{A`5{>&|v=!dcao{iu2<5}&U zYthF}wby5bA8U{NSwR`{{jXlF+Fu~Y5!S>eZ8qn#Py$4<4^ zXN4bYjdo^)A3N1vpA~+rHQJdGe(Y3xeOCCf)@Wyj&JXcF=$r(FP`W1-G-t@DrTsT_@$rHEw~eMg9@;pek0L#Ee18W@eq@+`8MVbD{b*z>MO`1S zC%zw+K62A|Ysy$vxbe3bz%DQnx2XojQsEnYc-U4{W~mv4A0Be+YO)KA+RhxP!Ex!V z_oL8dii~O>WnP1iOQI8s8Q>W7X!XGI^Z#R(|< zIKc(x5Pq;0C!p}-1Q(b?_`zD7fWnUxTwo622WxQx3O`P8fjNX9tc5q~wAM_#2^s5a zsCPNWbG)~895oYfLdNRpcU9Pe!%N6o~Wkg>jodY5B7$9r4HQ8V!-WUQ~D-sKq2 q@!r;P)J(hy8S87PcR9v$ytj26H4|?_#`+rSU5@b_?`<7N&EyY!g2$i$ literal 0 HcmV?d00001 diff --git a/tests/fixtures/graphics/test_kickstart__render_steps_below_typical.pbi b/tests/fixtures/graphics/test_kickstart__render_steps_below_typical.pbi new file mode 100644 index 0000000000000000000000000000000000000000..2c49b56317edfc5b2952aac3c56945094c880c4c GIT binary patch literal 45612 zcmeHQL2l$Y3=H-K`~TPEI6$uZggxvd0%Rr2RisQNkrm7A4(LNjQ50FMlAXa|fcf+C z*WWMY`SbGc%j*r#+YQeRW4zul##_!Y&Oquh&cHaU^O@sl<}>Hfjh~!HH-2&)&3xuK zn)%FmbmJ%I(T$%RM>C%}j%Ge{9^LrKd356^$I;AZj-#2+oJTi)avt6I$#FCfm)Q;Z zaOlPXan9! z$P}Cnh2Co2bwq(w2UYaB=g@;_|0o03Kh&dAyR*KR+yiVNYkG9bRZ<|8uUviISkyW> z$Hqw^H1(*TD7jZ3>cgbMPj{~(=cw1}s(V%HP#mR)9?!nsjQsFD$IXxnB3|nuYkG8W zy1i<84mFav1noFEM@P3$aZPb{oKQ_nJqinXuj-}I*QTx2J!%2x5;>t-=@IVLK17A1 zzL_;DYkG9l=Jr*R?=C-5dOB%hy^HP@3k$|QBmsJKj&nHZa}H8F!}B@oe8BJ}9w9AJs|ay?KPq{FH&mlN8*x#nKg0D`FO+H2A~T1H7NvtLI=JkPchG;Ws252`Tz(1;VGpx}P|g z&LIG$o5bkRF>~M!5k4I$=zBRw<3+eFYg`;nnIzDo^PqYNJ~fC0>CyRij(V+d*Hlf% zz4BfOKGjHq^yob7911^N2ecCc>6-w%1jP^0L*QYCY9&gKj%@DuyK!<3&Eudi+!k`Z zGm=1$j?$yV+OyTbeS-B0_p$5V^8%wU-BuE&M@P+pqpb$;!(#Vy`_OZ!p+29W?OZvB z+sh-L%5k$HE(H{H{LL=+-1>X)vN;Ip&`sj>=zM*z@WP#+d{w=Tjd;a+Ji7i*E#j@Sc!|J9&y}zol_5wmAF{y z5y!pPIrZ>ZiHoHkaol^IQxA`oxLE2D$Gz7%_3&7Ui=`fM+%jM=sc3EXd9bD9e7YT=Xfk(QjgSQ1p|4nRGxeC~ zZpF#eV+E`8HB*my?pB;kJyx(fUo-WX=WfNx)MEv!^EFeCdG1!6Og&bxI$tyOnCEWA z$<$*7tMfHek9qD^oJ>7dusUBe^_b^w#mUrT1*`KlQ;&J>R-8;dRGxeC~ZpF#e zV+E`8HB*my?pB;kJyx(fUo-WX=WfNxU#Z6v57j~M7Aw?WSF?lOE!Op1QMrTOEmm~< zrY8C$?XZ4(+cx$nlA1-TwSC?#D}X?=!}^Klzy!_iz!7Y6l>aKK1P)vM{~v|9wAt#E}AvRBMrOyFG$z>wXRc%Hl`Fq}~}Mf9 z+Z=5InM19?wlmU30QRjVKleEb_YSU_8YR4aZN6AcFwR!#-XEXO(Qv5!<_bImp8?6a z%~LqHo?onUjvG|@g8!pFPoqZ#`o&xiK1X{y3;D&7uN1BV=Gw9lY?iOJar(SlR=`l2 zZIIP^>;EisD6$%475K)*$ku*yaPjtUnd2-?RtH4RR*KCBYHMS0o$YS%BXYJb6q^s!*2dyG+uh5jk5aHXo?1jm34gyTy;l*-EkbKy7U-uCv`Oeniezip>XVYh!Vp b?QZdBBpFBsl7VC(8At|_fn*>VI56-(t*Buo literal 0 HcmV?d00001 From 3fecf75900663ec83af28bc66a01596bb48e9051 Mon Sep 17 00:00:00 2001 From: Joseph Mearman Date: Mon, 9 Mar 2026 22:56:52 +0000 Subject: [PATCH 08/10] tests: enable test_kickstart with fixture support Remove test_kickstart.c from BROKEN_TESTS now that fixtures are available. Co-authored-by: Claude Signed-off-by: Joseph Mearman --- tests/wscript | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/wscript b/tests/wscript index 646549bef..aa566b11f 100644 --- a/tests/wscript +++ b/tests/wscript @@ -325,7 +325,6 @@ def build(bld): 'test_graphics_gtransform_8bit.c', 'test_hrm_manager.c', 'test_js.c', - 'test_kickstart.c', 'test_launcher_menu_layer.c', 'test_pfs.c', 'test_selection_windows.c', From 355cfb11893068790d990337ddc99226776088a5 Mon Sep 17 00:00:00 2001 From: Joseph Mearman Date: Tue, 10 Mar 2026 06:27:13 +0000 Subject: [PATCH 09/10] tests/fixtures: add platform suffix symlinks for kickstart fixtures Create symlinks with ~spalding suffix for Linux CI compatibility. Co-authored-by: Claude Signed-off-by: Joseph Mearman --- .../graphics/test_kickstart__render_PBL_43681~spalding.pbi | 1 + .../graphics/test_kickstart__render_PBL_43717~spalding.pbi | 1 + .../graphics/test_kickstart__render_hr_bpm_24h~spalding.pbi | 1 + .../test_kickstart__render_hr_bpm_obstructed_24h~spalding.pbi | 1 + .../test_kickstart__render_hr_bpm_obstructed~spalding.pbi | 1 + .../fixtures/graphics/test_kickstart__render_hr_bpm~spalding.pbi | 1 + .../graphics/test_kickstart__render_no_data~spalding.pbi | 1 + .../graphics/test_kickstart__render_obstructed_area~spalding.pbi | 1 + ...test_kickstart__render_steps_above_daily_avg_24h~spalding.pbi | 1 + .../test_kickstart__render_steps_above_daily_avg~spalding.pbi | 1 + .../test_kickstart__render_steps_above_typical~spalding.pbi | 1 + .../test_kickstart__render_steps_below_typical~spalding.pbi | 1 + 12 files changed, 12 insertions(+) create mode 120000 tests/fixtures/graphics/test_kickstart__render_PBL_43681~spalding.pbi create mode 120000 tests/fixtures/graphics/test_kickstart__render_PBL_43717~spalding.pbi create mode 120000 tests/fixtures/graphics/test_kickstart__render_hr_bpm_24h~spalding.pbi create mode 120000 tests/fixtures/graphics/test_kickstart__render_hr_bpm_obstructed_24h~spalding.pbi create mode 120000 tests/fixtures/graphics/test_kickstart__render_hr_bpm_obstructed~spalding.pbi create mode 120000 tests/fixtures/graphics/test_kickstart__render_hr_bpm~spalding.pbi create mode 120000 tests/fixtures/graphics/test_kickstart__render_no_data~spalding.pbi create mode 120000 tests/fixtures/graphics/test_kickstart__render_obstructed_area~spalding.pbi create mode 120000 tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg_24h~spalding.pbi create mode 120000 tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg~spalding.pbi create mode 120000 tests/fixtures/graphics/test_kickstart__render_steps_above_typical~spalding.pbi create mode 120000 tests/fixtures/graphics/test_kickstart__render_steps_below_typical~spalding.pbi diff --git a/tests/fixtures/graphics/test_kickstart__render_PBL_43681~spalding.pbi b/tests/fixtures/graphics/test_kickstart__render_PBL_43681~spalding.pbi new file mode 120000 index 000000000..7e9c39d13 --- /dev/null +++ b/tests/fixtures/graphics/test_kickstart__render_PBL_43681~spalding.pbi @@ -0,0 +1 @@ +test_kickstart__render_PBL_43681.pbi \ No newline at end of file diff --git a/tests/fixtures/graphics/test_kickstart__render_PBL_43717~spalding.pbi b/tests/fixtures/graphics/test_kickstart__render_PBL_43717~spalding.pbi new file mode 120000 index 000000000..bc949c35c --- /dev/null +++ b/tests/fixtures/graphics/test_kickstart__render_PBL_43717~spalding.pbi @@ -0,0 +1 @@ +test_kickstart__render_PBL_43717.pbi \ No newline at end of file diff --git a/tests/fixtures/graphics/test_kickstart__render_hr_bpm_24h~spalding.pbi b/tests/fixtures/graphics/test_kickstart__render_hr_bpm_24h~spalding.pbi new file mode 120000 index 000000000..8052b955c --- /dev/null +++ b/tests/fixtures/graphics/test_kickstart__render_hr_bpm_24h~spalding.pbi @@ -0,0 +1 @@ +test_kickstart__render_hr_bpm_24h.pbi \ No newline at end of file diff --git a/tests/fixtures/graphics/test_kickstart__render_hr_bpm_obstructed_24h~spalding.pbi b/tests/fixtures/graphics/test_kickstart__render_hr_bpm_obstructed_24h~spalding.pbi new file mode 120000 index 000000000..9fe12805e --- /dev/null +++ b/tests/fixtures/graphics/test_kickstart__render_hr_bpm_obstructed_24h~spalding.pbi @@ -0,0 +1 @@ +test_kickstart__render_hr_bpm_obstructed_24h.pbi \ No newline at end of file diff --git a/tests/fixtures/graphics/test_kickstart__render_hr_bpm_obstructed~spalding.pbi b/tests/fixtures/graphics/test_kickstart__render_hr_bpm_obstructed~spalding.pbi new file mode 120000 index 000000000..d754dc4ea --- /dev/null +++ b/tests/fixtures/graphics/test_kickstart__render_hr_bpm_obstructed~spalding.pbi @@ -0,0 +1 @@ +test_kickstart__render_hr_bpm_obstructed.pbi \ No newline at end of file diff --git a/tests/fixtures/graphics/test_kickstart__render_hr_bpm~spalding.pbi b/tests/fixtures/graphics/test_kickstart__render_hr_bpm~spalding.pbi new file mode 120000 index 000000000..34cf9dfb2 --- /dev/null +++ b/tests/fixtures/graphics/test_kickstart__render_hr_bpm~spalding.pbi @@ -0,0 +1 @@ +test_kickstart__render_hr_bpm.pbi \ No newline at end of file diff --git a/tests/fixtures/graphics/test_kickstart__render_no_data~spalding.pbi b/tests/fixtures/graphics/test_kickstart__render_no_data~spalding.pbi new file mode 120000 index 000000000..3151fbfd3 --- /dev/null +++ b/tests/fixtures/graphics/test_kickstart__render_no_data~spalding.pbi @@ -0,0 +1 @@ +test_kickstart__render_no_data.pbi \ No newline at end of file diff --git a/tests/fixtures/graphics/test_kickstart__render_obstructed_area~spalding.pbi b/tests/fixtures/graphics/test_kickstart__render_obstructed_area~spalding.pbi new file mode 120000 index 000000000..a1da6da94 --- /dev/null +++ b/tests/fixtures/graphics/test_kickstart__render_obstructed_area~spalding.pbi @@ -0,0 +1 @@ +test_kickstart__render_obstructed_area.pbi \ No newline at end of file diff --git a/tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg_24h~spalding.pbi b/tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg_24h~spalding.pbi new file mode 120000 index 000000000..86fbd7fb2 --- /dev/null +++ b/tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg_24h~spalding.pbi @@ -0,0 +1 @@ +test_kickstart__render_steps_above_daily_avg_24h.pbi \ No newline at end of file diff --git a/tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg~spalding.pbi b/tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg~spalding.pbi new file mode 120000 index 000000000..ecce38652 --- /dev/null +++ b/tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg~spalding.pbi @@ -0,0 +1 @@ +test_kickstart__render_steps_above_daily_avg.pbi \ No newline at end of file diff --git a/tests/fixtures/graphics/test_kickstart__render_steps_above_typical~spalding.pbi b/tests/fixtures/graphics/test_kickstart__render_steps_above_typical~spalding.pbi new file mode 120000 index 000000000..90babcd7b --- /dev/null +++ b/tests/fixtures/graphics/test_kickstart__render_steps_above_typical~spalding.pbi @@ -0,0 +1 @@ +test_kickstart__render_steps_above_typical.pbi \ No newline at end of file diff --git a/tests/fixtures/graphics/test_kickstart__render_steps_below_typical~spalding.pbi b/tests/fixtures/graphics/test_kickstart__render_steps_below_typical~spalding.pbi new file mode 120000 index 000000000..1e079b918 --- /dev/null +++ b/tests/fixtures/graphics/test_kickstart__render_steps_below_typical~spalding.pbi @@ -0,0 +1 @@ +test_kickstart__render_steps_below_typical.pbi \ No newline at end of file From 40f488bfd2bba05a2b8e8781820de43a4a717790 Mon Sep 17 00:00:00 2001 From: Joseph Mearman Date: Tue, 10 Mar 2026 07:36:03 +0000 Subject: [PATCH 10/10] tests: update kickstart fixtures for Linux rendering The kickstart tests were failing on Linux CI because the fixtures were generated on macOS which renders differently. Updated the spalding platform fixtures with Linux-rendered images for: - test_kickstart__render_PBL_43717 - test_kickstart__render_steps_above_daily_avg - test_kickstart__render_steps_above_daily_avg_24h Co-authored-by: Claude Signed-off-by: Joseph Mearman --- ...t_kickstart__render_PBL_43717~spalding.pbi | Bin 36 -> 32412 bytes ...der_steps_above_daily_avg_24h~spalding.pbi | Bin 52 -> 32412 bytes ..._render_steps_above_daily_avg~spalding.pbi | Bin 48 -> 32412 bytes ...t_kickstart__render_PBL_43717~spalding.png | Bin 2022 -> 2023 bytes ...der_steps_above_daily_avg_24h~spalding.png | Bin 2517 -> 2519 bytes ..._render_steps_above_daily_avg~spalding.png | Bin 2685 -> 2686 bytes 6 files changed, 0 insertions(+), 0 deletions(-) mode change 120000 => 100644 tests/fixtures/graphics/test_kickstart__render_PBL_43717~spalding.pbi mode change 120000 => 100644 tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg_24h~spalding.pbi mode change 120000 => 100644 tests/fixtures/graphics/test_kickstart__render_steps_above_daily_avg~spalding.pbi diff --git a/tests/fixtures/graphics/test_kickstart__render_PBL_43717~spalding.pbi b/tests/fixtures/graphics/test_kickstart__render_PBL_43717~spalding.pbi deleted file mode 120000 index bc949c35c..000000000 --- a/tests/fixtures/graphics/test_kickstart__render_PBL_43717~spalding.pbi +++ /dev/null @@ -1 +0,0 @@ -test_kickstart__render_PBL_43717.pbi \ No newline at end of file diff --git a/tests/fixtures/graphics/test_kickstart__render_PBL_43717~spalding.pbi b/tests/fixtures/graphics/test_kickstart__render_PBL_43717~spalding.pbi new file mode 100644 index 0000000000000000000000000000000000000000..034b7dafac9ea631cfce9d92d221a5a40fa25d82 GIT binary patch literal 32412 zcmeI4S(4j03_x9Tg1P@W<^cY1fA~MSLk^Lu9&T7jf+Q$Gq*c{Q(gd+SL9pC%SLgBg z=ii4r{&RmUk0%{}{qbgpWgVkjL>r}wIp7-=JD;Y+4SSjSGr&b)r|d90@bis2oS_9g zWZs3{0oE{Y!0r=|W+Tk?TIvz7vd@A1@L)~_Du}gxcGS=3RPjU3Dq=nJ%jY`;q7G6L z>zPwRHNd>18hLPkhS%Wx3o_2L=prD$X6?VHATvv)W0><|=@p`m8QUB(&haR`6`b59 zFh|7;yIKi6!pRDZ2^UEI`}c1U`zvEkjur4bO*79qfi!XjK9^nzT{HU}UpaV4o97&n zsO^CK%=4pK5M*ZWNZ4_ji=1kxt|KEV@-s^*wwVb###A}GFgjyK;|gT^=H{1!{?)X` zAxY*cr;e-R)vnvO{Q3K*@9++9+oDegM`IFmUar)TwR|pzYZhn`4fV~83k*Xz*t;l%tMO1?_HCIP7$hFMeL99&6paz91u(o25 zsc(LD-j(~2g0;<9ScF);>O~Kx`k=OFf!5l#6DTYZx&8f*B1P`fqRjMph-T+L41yye z`_G50jts7`nXmQ633kt`uEp`|d>%QXfyvc!U{~uNm*R6$c*K6$A}b!pyKoI-c*Juy zd_?u*{IVMl-cmtsQ1#XEvGfa(ebZgD`$02S0hFm`GNCU$N+;>Ha-(2gurwx1{=Pcx6!v>ggOZ z@JP_dnNvS|wU65R%rPtT(U*Z4&_}2}IZxf_lm;(_IxT&q9Nx3P`o~1t;L3O^=Gk1_ zANm~L`*0%*JZ@Glp=aZ{Khb$D?IelE&B_JyZ1^7k9C{DKY}MN{&z|ruf8OX_46}6^ z^K9roe}dk}FkAW7%(ExE(;phWlVP^@jhSapb+3PHw2tBX`#U(g6^AuX8{0|kqqiaBCLNP;3C8B*5L4>JrWwig9_z%IguKA&gyx6E+c z^r`4(!6$}_oRg?$F;BT?twa+F%ouqAnn+1H$H}9q{tq+E$$~zYZFi%I@53mez>FJb zgK%JgNP`jzpTb>fh$(Avn%R-j z5%Re$tcAs26FQ<3A%v(5Gux13DczI#QJzL)?;7SU)VHLd0cR%2QK?ufV><8*x%s9k z>wiAjOtIYX!@Q>DckT0IO?#}W_%`eBc2-r-<+(5O74%YMqeib~wt+TdR!oL> zv6yHpW+k!-v=Or!*#z3+Vm&92O{T*FdWQK!pr?>OV>%|0KLL6gc|Y_497CCK*3uvllBsplxWQLs02j#y&GDPOBzJL@`+7d5;Hb=gk`U+y76E33tdKK}7 z&=(?KM13u>&#oJc?5^7lxt>@_UA()sq1O++5TJkcvp`P^;p?wQ7uJ#Dhl~j7B#zH2H+khzLvBr8`2v+j)=qmknDGe|$V*Xcd&yud0d8hDg1>@(% z7D4AtFj#KQD@KzWuxAazk99fo`+K@118_JrLGFR&{-iJ_DO=;pIZ?$M*Dm9Mz_@CK zsUH*92QW2LSh7!3jR;%R2whZEZ}8@pkaLD{Z`7y4Xkvm=<4paGpp^mY zt3jPUz)VEYtWT*TaFwN-EH5tDYK7EOFtY5jTE-oFoYIdfOutdrE)Tw)OQw#Dkjs1V z=>Hl3uLABz2bA46k!PQfJJ1LjP6intA3JjSNzo-xXC7rDp+sHUYT{Rw3wh|b7f}xN zPEeZ*Driv^I?>$IhuJA7>9;|4PP#w=#NJQK+0H%8lq zwcFLc&JVFMy^EH90MLO38L}Xj&!kTc`FIu1t~C12EQj{Y7*knY(&Nrb1L&05buYa? z_^fT@`+m&bsgGBMu9-mVz+EfdXnop+Jh>l3(5`uHP%iDf*kivR;-MBQQ`#$|RSpN; zBASpDW?u`J!oxQ%J!wZ-S?H7_Xcx&?CCO8oiZ`GGX49a!%<^hn1#6JOsq9x8LfiV+ zds|xCI>qv0(I$ktf6frJV-D+C$CYW#_jHE?m|e{H^4)_p*_G|E%(dIx(TGxy_v}yk z!;mGa+YUEq>f6qwnsv3D{i$gR7Hn>!y8;&42Glo0V(tXClGYPO>vG#+n04Vzvju*K z?w~ZZb&rhsX_wO(v}Jx8$53HQrRHp%FEQrh7fVehp|$5Vwt0U>ESF%mt``||I%vy0 zv~*7mwq!hL<9V4e`$0EmgZvWrW_tE48$lcUz$Xo={JhhC>Ij&h2QX9F4D@0))|Xn1 z=yqqA`>(*C{GiFP|H*=1RS==k#@1SZM?E?}Z)a2mXW+1UE8 zK+qDHs5@{06Gej)y$TI;X*I6WTk}(D!aGYghFu)P5`eu-XgLgXoJ<~W)TAab*jzMa z$m?#&xfQh2fX#hQQf1SlBTk|Fe=hYs#fC;gZ%`CJZbAO!$R%_k_ z;atY-7urmoE-pC%ATUt@-~uL!hNnTCSZ6WH*1QSAd9?>FV1le<>@XMBSzxv1O%Tp? z%xzLiIg?i4kLfHubfr%;r7cfyYJ~gA& zaE`WumcT?gzy(YcjZaId^vX+6JpHYC6NK|>4_v^6S;=Z%gbKO#)jntmOw5Y7bn%gjvaIZX9~ff0&OkfuRBuO%$K$oNbiVjXqskIbiVjXqskJ|!>yDv;p#oDd-^-kSuKPdE`Ooiz z%XTCEeX#UzR$v{0i8d6tfQh2 z6pc^K_+h@VtK2w1OJJhzzy(Yc4Nr5cv)?~gZXBRxVoF@%*8s>$M)MN1%#{~mje?@+ z6o9})c<{8VVRoa)ymh@EXA{znvzZP7yVwdTwXw%sSZMCINez&#&2$KC&!RP?*33HZ ze;z^_JB=3RnlaNKZ(;M-M*K2!X1GH-SAz%5z&~DQpW!Qz7Fvw>b(YzG^GtKz zZg*d4i}&;2h3j~;6n+Kn;BqOxZ)-Es=!~YVqs&X+RN-MGg>_HLrn8Otjfed8a27t? zwQf&kwqvHd#*ThMe?N&g>_*fVh?!mrfq@$-FNGJ?ewrGMM(1 zn=Tkxe!VN=smwG&I^~%87ERvrpr6T{k9oV>na9AO_t5hh=jYw- zg4Ijq4U+pyan?UD=w~r^#_X4)eCv=CUOQ(yMtP$dGRU8eh4EOrHowJ$g4+zh?4iSQ${}e5+VQ5{0-IxdHk&aQ?DLM0J#%e4 zB4$NLq{^5wyUl>i9=fz0F*7p}a(OZKzlC8Q`u(J7CaQJf=0J*=B_CH}36v5hhteR8 z-~ubV7cvWIK`KOnXhlzAP+4`Mg_Vw(8?@q7ieV$;LHK7Hz-18 z+k0B4g5gt5IJm{+Fc;JHiWf6Pz{wslC;P>s zSHeF&V&oq`I?P{%U68&-&_71ZUw{owyu$p{83Ew5USob*vl;Qn$0LRoejVk?6*U*D zi$~1e`-Vy~S9#Y<6-(*~=358bBFDqgyFc4JyGkQM_C(iG{%$dTJW13lyu*4jp@rv>--rV~5;ZxG!%orl%KEwKMRA+`!`2?xfnZ^-8 zDFrlEgFIt^9gm>cm{NH7S&mLJKe%A31=2|Ik$IKVvR`q;$@jes+Yjow!*d_!oM|9? z$kTK27=I0LkHVdg0Vr)>MBY6iSD-y)w=GY-+*LTlzXmg4qSS&bEqe>~H&TyH?#|32f7qghP?Q9^| zUyRa$;q5Aq^Mg&y=%D$&12BMgB6vbyu0h`rxm<<2BklcW)`zytKBlmmpvRSwcA&e= zrux+L!A7N)=lR&XQUVsjmRe{N2=0{^PXajfd%66n( zXq~@3+q$XsCL3N~)B&Mx&zT2pn8SQ}qeW`-HQnGi%*JPZ_^v^!=$Yxz%yYN7QV2rJ zGy7ZrrN}y}nGVxvsEcbSo8H2hd}>hf1s&VbO#%(A9p)#4V`c)KN$MR&y=A6DG0VhB z(+R#pH&7B(8jE+ zFEtv`?M^WVSK#O8XK7Pf;icLJ=Cs0&V@g}J|BjwHLMV_zKfr6F6*D-iwUICiRyzAS zJC3P(Vs3#c6m(H|g<096EAS>}&dFs&re7`_XognI@o1Ek4LzkKspcmgB^0DHJ3&n3 zBSXagEm|>icP6LuU&O3GbU1xxoLqcm=FT{u>hmYNK}^hs9_ZIFF+G1 zNt&4bqqL;0T728!RZCLhxu03xI3)T1o7uFPoe11Rfo;}@$l7dl`)o%EEmYqh4TgoT zD6q{P=I)IH39Uf&8#B1T2CVqVWWty^Hy)Y~nQ4_1EH&~n5+UU+rhy16+jLBg4Dixg z#rzINQ~OMxi3ah>gc1tq1Ym%Ns3=(AWRabfnj27!R6pzdb8nN$0VNb(ftg_FD9MHr z3Wgcx0NaZKC1jH9tkjsB7O8&P5lZtU8%ij!fDD&jY$@V1m}_PJ?f^O_4%^V5!%Qp; znv5u+FzhpOvxH2P(;zkGrbVjnj|RtrE0kiGR1+7-IwCk0&890ST~bQTaR(Ds&CFnB zD>k^i!meDq z%v0a3h(u&2GfF6onArh{oK3m@eb8?+VUhF{=FY!aVSN--N63y63hXc-inq3Pp_;&f zt@1{pHRh;9tdBzEzyR@-U=VUWnOVU$6|rt-ev_S!Z+3tLs{yAClu%%Y0dWg`R<{lP zyJ&plfcmgPZN#Aslu#fi3M*10=LdiuD5%?pW{xjHsE;EGDQTltW*?zoi%j5>f{V!X zW`VS9m7|dUZ|lmyT&39Rr-fd{BdM^eo!nh|RVPY%jyW9YR6N%shGwAC&bKNWx3mM> zU{>Rt|2%+fbU4rr(ZPUeVOv0EOqINBPxsl3vu2J58aST5%BGgT!k|n~M;aDXfX=@i zhXXy#eUpPT&T5`_{ul8#!M3z&oaG8XWp362DBJ6>}X8VkY3aVYbj1-W5XTbmA}&MQ+4hSJ3C(L$=Iw(-AQXI$#z?7Zr?VGF)a0 zJvALMGn9urVbXz}wgPEtGV+CJPDhYXm?LJ+N2nx;Bt|hP@)1ayaioDXNzo88GiXN2 zL`-1?OG1=NGOiON9Wx`e;1r6bEtbh)F7$?Z;%|oBz-))vzW{5;H=xfmuOT~^;c%pV z=3=c|I3iVO#$YP4*)~p%uu`r62>Lj)gPO^!}Qo2%mL+>bU_1OW?j7E22GDP?q z_L+vENTj+co$?0J8k{IMdo!M8c8XghJ5?fTDM-qvii|F^b6+-J0X^JmTY}fE|7(xm|O}zSJx^NkQSES+@Q=->cT~vG6iWzr#hJA9<&{!s$tk~K(pgDgMr8q%MN1oqDnw@_odN8Kl*mX5VNo^d$gsmHVkniB zCVoorkHmdYLw-?yPk~ha>NEANekQQ)QR*nj7OZ_hy&EI}v#!0ZL&9*K9Fp!xl;qop zHZX+c8@i)X=boW#D_^mMW%P!5N`_B59l7*rdFoh9h2w@Pj76v8kRstC%(S~Ga#Wc{ zSa&?i$&#&;tVFOv$HbNTd%nj|TcSOR)u@xytFIuD@@y(dGLqqf3PPlR)}m_5AgEg>_xO|9`9d|e zm_pnYX`u&~d3paiq#){yq|iQO&bi#_O6GZ%y>!YqV(xHI7$c7SzK9 zQmdhSq;m-Gsd{ojY4i&1?Qt4=nejQ7Y9A$p_9Jr$@iJk5iBrl2sz;f(HJ?>j5$uUhD7noM+}Wm?GpB&vl5$OWOn75@SUgy4sjga%irKlObF2aT|Y zgmyy9X@4~Y8sEA3k5~PvhrrR1? z^6G1=SV>(;T-VSr9v?y<>k{iV^hoLCofJ2xV1HmebncW|iz&F&=S+E=f5?3V$gBvIJK+p1x=FKPcexP!0eI>QcS}2!fah1>jo6t7*FCEEE z^{dBAJ{SBl{r>X<`#!MD6apm&I0K=<6$lNk*bB{(2Uz9TT@o5xfzaTJqtKKcV2w9t zNoa5dLW3(}LQ{5t6+T=wzuHbMubUgie}CD&tE*NhIlvWX32ovwyCyg$@m+F5D$&xI zga%h!3C+QwG+R1TKi6{VCJ7C$V3wm5r0^r$B{XFRXyek!>V)P~XQ2jZe^P4b(|3f& zPo0H+6!>#nF>p}W3uZXFkSa8_G(1g`gH;Lb?Neu=FD?AZOM)&`1qZRJ$Zqav=2?oFPm_#35>EaD}AMq%@Qw=8kkiBQ@kA>P(B01F0buaaUT( z$5K!5H5_T`M30gKsbQnJ3%zP+q=qgI^gJj;>T&5d z_Pu90ka|42j`aIL4RR`c97J% zQR$A#Mjb$GU8r_OW65zubq5ZH`ms>ozyqZ9GnnzjOhXSKb|1|7VWH%RVXmVMVzQ4- zHu?Z*EsJRFxkh}653=Zt0bPzN6e*>=4F3aGQsm$gEFZ#36035>{Itj?lyZdRR@e(=ApA> zKJE@RmK!02@bz{5eVdIg-(RsVIq4>${v?ooSUrEeUSVC=@Bbfb$7^20+--Z0^7L-v z@eY6{Jm%F?8%E?Y=!A zV@x6LinP#!%e=h*98wTLpImrv4Ka5(D2$O(3%^~|8j(4KRtxIk z0;$zdKGHda_f$Q(pfq}g_VydNz0CNWOSO*@Li>?9gm{^-zr-o!0@b6;+aHr-0%ZZ0 zlgR>80b-LK0~vqox#75*gTo9ion<|A3CDw(@uX7AT|$qQ&R~U8Z%Jry1ww->u7sxC z0Ii(5NkW4w&V(kNK|4`LNoa5dLW3(}LQ`&l6+T=gp}`dh4X!u}O}PQqcyrdo0{?aW zYx6XHp2pw*{*Ku5OWIMpomOq$UN_}A>$+z5N6B+~V!nUm$PuID@h!H~tIZ>_7n)uh z5GQ{uzi&c)$sx6CmK-?A?euE11lrmY!+gmBum_>R6$tGJ?K2QP*o4+!906RjhM+v5 zEgXbsWSS=NzO$14s)e4W$wVhwriJ`ZqFQKxTo4*u@h@;d2!2>eXmEx4Q{Q)R&!;hh+;L>T?%b+AV3B;LXWgtZHe`%J2yfDgy2wU%8jx47rxhXn8xxh5=5C? zP1}FfVDXwlt1}TTaaD3KxN&k1^eo?K-h4vu2P)^*S5n)og>p$2R|yTU32k%#(vjR$ zzk0mnYr!wm?>|4V?*q$BAy9IFGY}eFfzaTJz0e$afK`6oC85C;2o0_{3QgGo)_8N4 zga%h2G`J!rG-U@^;low)tL@bCy17yOm+gPMx@v`z16*;I&?auPYl34E-z7Js5-p8M zXmG`q&>S2}v!yfjb1kQClF;A^W;t3x3O~YKLQ{5tHZGm4PG~-L7HW|8C#8ly{fqGU zsk6|J0)K8R1`Y~)!3;+iQiZ0LhNnq#uqvUwed;XqrG-Da$;;{RQYblUNcJ>0p(%eo zpf_30aZm`ZC=r^J&V?0rrDVHCLidFFxjCgmlhV+dBFAbH8mXZb#cok@fGcW+CZ$1| zDyJk88mU2wYL}!+4x~PVGlZ##I7AH%u8uUbq=sBXooP{WAT^{S?n+Df zSZWGaG;xoELU2V(p(#D!jAm}MPH2Cmh9ga#=uvVYHEc9@p;rx!)X>F&o(F|UJucnG zzV|E#QjbU1F@Iv(4ynhX`&d6M7bjnQ@|ago3mrnC)ZFz{7Qy~})F};T3bQ+ayPnD- z*q@IFqz0iwP|y)jjfyeU^pO->hfr7BLWRg1S`vECZ3l7JQ&}qdQBb*WDYl_CCoWuY@g@$a5j(afLZQ^I9ME*?TZ;VvsgYY5t|Z>$QRqFa z4|&I}$Q$n8V1%x6E2yD|8sj*j-fRS~$vy124*SL_lB>85MR%s|FFGFyADR1*_Gyxa#Kw{=iM^_N z>Qqlc8@#fSZ6G(0ULL33wUl#z?Y`d5z44mxV14GCynCD#dJjr|2oKCJa`NsWDfAwc z8~}yZm3WJ`&|5An_w{ysDNl*-tI3}$oK8HbQI4Op#^L6x%>*{p+DAb1XEEsloV3_YGY^ama(&-$b#Hgp}2yH!sMhT*j(((y?X_?`_t!L4= zpi7}Fm4E$&NH;J-iSZ)y`uh6-%|C^7T`ic@atWP9=AO>_By%Y~Z=I4rx^D#C@i{1* zoy<$awZtzq<&Mli?rW}R_t60|Q7@U!vk%lZRgdb%y#Z2v-BxCweJ+c$ui6+FI+M)6 zeg|#a)p94uyUg_i;9>tXa3u9u$&pRwBbM?ba(|1=*q1pol6^Pml#d$Pv&@x(wtMup zue(Y;4Y=vU^Fm9dbH^ z5oG>!n%tI30d~a&>uP#NX)8HcYCOp})n0y)5nWpH<+f-Zm_n$dL2nxfgyzfFY zonLvsVsr(tOlr%v9o~^BJ(lwLR!i$&%YTtc=E{4=M4pDU#K48mBgd=HITLx5=caWN zI%7JMF_fK97Fu=dBqGXA91A^KZZMt65uUyXbrw)gG%yjvs>EICLjC^Sh0 zg(j(B4Q&AHW;>YBBo!2zq=G_|R8VM=3JOh9L7_=1&I>K@mCc0gGT;^ynt!B%LX%Vs z2+f*xCNxO}2Zh8R9264rghG>4{D=E`{@O;C9YmTDr|#=*FrjI53+}$?(lujF zjR{Ski8O;wrM+WCG7T-0HEO%PFg_?`N)ssrTzU#UGB9*xbnm@;pI$GyE$R1qX}3HB zF8w$>UUC$;dWw={2T5(KWq&&!+ii|mLKBh%8KM1D9V9A34hbbRjV7bWIP@#D@QUHG z0FMVy=sIa(aD}k`Q?7AOkj0-$t?ysl4~34i&Ba5=hPV*Gsn zcP%S=xUaxUkx2{Bq&)xrof3IBp?k}U6~KKhZ@&q|^3(SFy8rtl-d}&T-EZ&h`8%!K zjDW&y!LHD)f9AfHeRZ8(-$5LrH1oA9^zDY*M`TNBB8O5s17DWD4{PLB z7=Gj(WhZp6hmNr39c^YHI?7Ib7JBH`tRDh6O^lFm;fs^{cdSH6X<~zc3*Tos?(40t z9G>Q?1H{&Hrl;(QS|Ulv+)y#t+*4S<(xaE7)ys$&_J5nuB7e2?#f@Hyyrdf2)W9g6 z0qeWIuPXI+@kUZ+>1}FY+~@5=OU-y()M)_i;`OAiYnfp(v$3Twp;>yIqe>^a%&xIb zX$(t^%A5zycj(?p`XqFz|+0GNUz8?5oZuD-`lF2dyUYc z0@<0HA*aR@no`RUVF`N=M=}FaB?qOxCeCCAywuR|P-_1;?ISs%B~u!3d%zAEnSF>> zZb%V{H+5=|Npnw?TJ3)1Ai|$&s-4>Liv(II;kTqzC=mb zGX#(sIC@y41d>S&)JHanZc>bBB||S7p`su&;B`>A$MaFBvs-aJmOy7nXeKlupVAc% zb#-<$N{ot9Is@851A0;ec~9}P(L56>$_!YP9GW}85=5TBG6NO~UC~TxfN4F7b~qTw z3|I;c=zmMi+PWXjTDf8*Ghi(=pf5GRv~I?esu zu12Ka!9QG0?h8n~is7M(@HA~PRpcasE&!ICVAd#ZZs zRZl`2d~%U(AUBYsJWjo9D(C*%eZHN0<2B*I+UK0SYn&B&4NATV56mBO@~$B%^cs{L z0EO0-c!{>qOD-(;^>%zJPl@ld$)79bDe`RS^9vV~`@hi*Fn^&+yrck7cDl+ul;yr( zKMvBG0o~*)gn!ZY7D>@pqy(k&On2 zrn4M91Q$DQ$-&Y>hv0SgztIgig`~_ug43L!ff4IdsCAGn%8n={#~OjsI!4J6G%eB) zs0?x6Kogk_W`8@rQt+G`_l|R^{Wi`rm1p=~Wbs(8I2GGvqlT0iR?~M9l;UGB>riTU z4H{N2dnh~3GBUxPN$saGqePCB%q@(P+lkmN8euN8_nKLP5oL)3sfRbfROW1H+{%S+ zE*LAcmCRQa`5h~<2TDEW4^!l^Bo^CVXbYJsavK(68-Gh}E3~%Ek*D59VX;DKD7Br? z+A=eh`$+Pb1skC?Wv0loXo_thwf^Bn-`2BeT+pRZ zmdbuYq<*XYPp2YBJ+{X+LO5ypSMm)Al)~D?)V%Oj!x#O z;acLCnsP;EAon%bqx)zBnW&dc=g|jhnW|fL=`GufiojU6}j5}H1fEfn2Y7n(eJ819qlG~Dgua|a$aOo*@*Zeb$CQ@{` z^y4rSn)pF1p$SPspU_NaB2A}Loqq{Uqlq+qPW|HwA#p|LiXm%gk_rkk_rwAi9b5r8u!)67h-wep3l2Q^1zaVq=G_|R8VM= z3f9mDux_@42~AQ#p-CzzG)V=8CaIv%Bo!2zq~g5L0$h(e=$?V0BcqSrySMjx$!$r$*Gs$Q>2T@C z;r^1Nz|~WfBs)lITP@r1*ne(w#1fj2B*+Nur|KY45pqZ@j%1p>E!hhxHdWrG#{ol2$ zIKq7fW{ON&cqZlf_pg-5s|kIyte64Z=koTOKukYvzt8Kx-{SrCTigBi-Xnjfb(;}T zm@QZpy7kZ8=d!M@v+FyELzHH|R)xOZaCH?brUxEh(|C()DNW>1N@w89()VVK+zP{w zyrb-d?)A_S*1V(53`9rSiG88FZq523fYZbX2^YRNsei{xgp?*W7`X6#mg7F(>dN71 zt~x+$EoY9DJyA;}37H!z2Ag{d3s`y_Woz{^B8L6nCbUQ`eSdMIry?(@#x^xDN@u|O zuJ5Z#y8uRy*KqBOHMj=K7XNEdVFU&Pu%)?V87frx=l+4%M5sV`l#0qBJDWo!#<&Q87&EklGQ>@^(83`mt6l=_-DlNs<*L%&0*{o}NcYit8~2IzvJ;p#k}nu6U@c zv!hXBRFu*g&=wldlN!i-iXV;UnNU$?z@p^P+yRy#@&uL{ut?~NW>N!8>t3|O!9Zrf zQfNS5YJb+&$I+~nD@HN{)A0ga+)Tu4GH?QFHSSWClD5 zT^S`d5LfPz3rtQ#uDEKyW`Dq|(0~uA-x-zQ9+&tX$_#iGy5dpn zcO+IQEmrI#a4K@eb>n`CAoUe+E;A5C=nBOiLjaL0VH)}Z#kL`k$dx#^U@ZxFpu-XL z7>8{13ruTSf{I)T-S`(Mb|1k-uB6zB7bx~Il89VMwKE@3?sbw$yd>?8y+E;_Bo?`n zenba9xSHG-ka)?ZcJ_m;a$ij1C70dt52DL`VTqUUAnf5)a>~0256n@lC8xZH_#c7U V!`{CxqvHSo002ovPDHLkV1h(b(k}o2 diff --git a/tests/test_images/test_kickstart__render_steps_above_daily_avg~spalding.png b/tests/test_images/test_kickstart__render_steps_above_daily_avg~spalding.png index 1e4135a1351a31b6ba22717bb3059f99e9c2fdb9..97e93f177ba61ff43df77cba4f80fd5c2736b20e 100644 GIT binary patch delta 2560 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 V8u=URVzdAN002ovPDHLkV1f%6<=_AS