From d8456345a2409c7b01f4604ac3da597a7ae4cedf Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 9 May 2022 21:01:03 -0400 Subject: [PATCH 001/220] begin de-future-ifying the values --- lib/data/workoutsummary.dart | 53 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/lib/data/workoutsummary.dart b/lib/data/workoutsummary.dart index 3a9c0d9..c869347 100644 --- a/lib/data/workoutsummary.dart +++ b/lib/data/workoutsummary.dart @@ -64,27 +64,27 @@ class WorkoutSummary { /// Construct a WorkoutSummary from the bytes returned from the erg void _setBasicBytes(Uint8List data) { - _timestamp.completeIfNotAlready(Concept2DateExtension.fromBytes(data.sublist(0, 4))); - _workTime.completeIfNotAlready( + _timestamp = Concept2DateExtension.fromBytes(data.sublist(0, 4))); + _workTime = CsafeIntExtension.fromBytes(data.sublist(4, 7), endian: Endian.little) / 100); //divide by 100 to convert to seconds - _workDistance.completeIfNotAlready(CsafeIntExtension.fromBytes(data.sublist(7, 10), + _workDistance = CsafeIntExtension.fromBytes(data.sublist(7, 10), endian: Endian.little) / 10); //divide by 10 to convert to meters - _avgSPM.completeIfNotAlready(data.elementAt(10)); - _endHeartRate.completeIfNotAlready(data.elementAt(11)); - _avgHeartRate.completeIfNotAlready(data.elementAt(12)); - _minHeartRate.completeIfNotAlready(data.elementAt(13)); - _maxHeartRate.completeIfNotAlready(data.elementAt(14)); - _avgDragFactor.completeIfNotAlready(data.elementAt(15)); + _avgSPM = data.elementAt(10)); + _endHeartRate = data.elementAt(11)); + _avgHeartRate = data.elementAt(12)); + _minHeartRate = data.elementAt(13)); + _maxHeartRate = data.elementAt(14)); + _avgDragFactor = data.elementAt(15)); //recovery heart rate here int recHRVal = data.elementAt(16); // 0 is not a valid value here according to the spec if (recHRVal > 0) { - _recoveryHeartRate.completeIfNotAlready(recHRVal); + _recoveryHeartRate = recHRVal); } - _workoutType.completeIfNotAlready(WorkoutTypeExtension.fromInt(data.elementAt(17))); - _avgPace.completeIfNotAlready(CsafeIntExtension.fromBytes(data.sublist(18, 20), + _workoutType = WorkoutTypeExtension.fromInt(data.elementAt(17))); + _avgPace = CsafeIntExtension.fromBytes(data.sublist(18, 20), endian: Endian.little) / 10); //{ } @@ -96,21 +96,22 @@ class WorkoutSummary { // throw ArgumentError( // "Bytes passed to WorkoutSummary from multiple characteristics must have the same timestamp"); // } - _intervalType.completeIfNotAlready(IntervalTypeExtension.fromInt(data.elementAt(4))); - _intervalSize.completeIfNotAlready( - CsafeIntExtension.fromBytes(data.sublist(5, 7), endian: Endian.little)); - _intervalCount.completeIfNotAlready(data.elementAt(7)); - _totalCalories.completeIfNotAlready(CsafeIntExtension.fromBytes(data.sublist(8, 10), - endian: Endian.little)); - _watts.completeIfNotAlready(CsafeIntExtension.fromBytes(data.sublist(10, 12), - endian: Endian.little)); - _totalRestDistance.completeIfNotAlready(CsafeIntExtension.fromBytes( + + intervalType = IntervalTypeExtension.fromInt(data.elementAt(4)); + intervalSize = + CsafeIntExtension.fromBytes(data.sublist(5, 7), endian: Endian.little); + intervalCount = data.elementAt(7); + totalCalories = CsafeIntExtension.fromBytes(data.sublist(8, 10), + endian: Endian.little); + watts = CsafeIntExtension.fromBytes(data.sublist(10, 12), + endian: Endian.little); + totalRestDistance = CsafeIntExtension.fromBytes( data.sublist(12, 15), - endian: Endian.little)); - _intervalRestTime.completeIfNotAlready(CsafeIntExtension.fromBytes(data.sublist(15, 17), - endian: Endian.little)); - _avgCalories.completeIfNotAlready(CsafeIntExtension.fromBytes(data.sublist(17, 19), - endian: Endian.little)); + endian: Endian.little); + intervalRestTime = CsafeIntExtension.fromBytes(data.sublist(15, 17), + endian: Endian.little); + avgCalories = CsafeIntExtension.fromBytes(data.sublist(17, 19), + endian: Endian.little); } @override From ac60bfe059ecdad76257c524d48693cdca47136e Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 9 May 2022 21:05:55 -0400 Subject: [PATCH 002/220] add and use classes for Time and Duration-stamped packets --- lib/data/workoutsummary.dart | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/lib/data/workoutsummary.dart b/lib/data/workoutsummary.dart index c869347..1fbf525 100644 --- a/lib/data/workoutsummary.dart +++ b/lib/data/workoutsummary.dart @@ -7,11 +7,28 @@ import 'package:csafe_fitness/csafe_fitness.dart'; import '../helpers.dart'; import 'package:c2bluetooth/enums.dart'; + +///Represents a data packet from Concept2 that is stamped with a date. +class TimestampedData { + DateTime timestamp; + + TimestampedData.fromBytes(Uint8List bytes): timestamp = Concept2DateExtension.fromBytes(bytes.sublist(0, 4)); + +} + +///Represents a data packet from Concept2 that is stamped with a duration. + +class DurationstampedData { + Duration elapsedTime; + + DurationstampedData.fromBytes(Uint8List data) : elapsedTime = Concept2DurationExtension.fromBytes(data.sublist(0, 3)); +} + + /// Represents a summary of a completed workout /// /// This takes care of processesing the raw byte data from workout summary characteristics into easily accessible fields. This class also takes care of things like byte endianness, combining multiple high and low bytes .etc, allowing applications to access things in terms of flutter native types. -class WorkoutSummary { - Completer _timestamp = new Completer(); +class WorkoutSummary extends TimestampedData { Completer _workTime = new Completer(); Completer _workDistance = new Completer(); Completer _avgSPM = new Completer(); @@ -33,7 +50,6 @@ class WorkoutSummary { Completer _avgCalories = new Completer(); // external getters for clients to get futures for the data they want - Future get timestamp => _timestamp.future; Future get workTime => _workTime.future; Future get workDistance => _workDistance.future; Future get avgSPM => _avgSPM.future; @@ -63,8 +79,7 @@ class WorkoutSummary { } /// Construct a WorkoutSummary from the bytes returned from the erg - void _setBasicBytes(Uint8List data) { - _timestamp = Concept2DateExtension.fromBytes(data.sublist(0, 4))); + WorkoutSummary.fromBytes(Uint8List data) : super(data) { _workTime = CsafeIntExtension.fromBytes(data.sublist(4, 7), endian: Endian.little) / 100); //divide by 100 to convert to seconds From 2ff4a79acea3f8eab5fde891cd71784b77d36d2b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 9 May 2022 21:06:09 -0400 Subject: [PATCH 003/220] split workout summary into a second class for the part 2 data --- lib/data/workoutsummary.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/data/workoutsummary.dart b/lib/data/workoutsummary.dart index 1fbf525..ae1a0fe 100644 --- a/lib/data/workoutsummary.dart +++ b/lib/data/workoutsummary.dart @@ -103,8 +103,10 @@ class WorkoutSummary extends TimestampedData { endian: Endian.little) / 10); //{ } +} - void _setExtendedBytes(Uint8List data) { +class WorkoutSummary2 { + WorkoutSummary2.fromBytes(Uint8List data) { // if (data.length > 20) { // var timestamp2 = Concept2DateExtension.fromBytes(data.sublist(20, 24)); // if (timestamp != timestamp2) { From f2d3c6a160c593e8e2a1e6f699107a42bf830c00 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 9 May 2022 21:09:12 -0400 Subject: [PATCH 004/220] remove completer fields and split into appropriate classes --- lib/data/workoutsummary.dart | 68 +++++++++++------------------------- 1 file changed, 20 insertions(+), 48 deletions(-) diff --git a/lib/data/workoutsummary.dart b/lib/data/workoutsummary.dart index ae1a0fe..c32e62a 100644 --- a/lib/data/workoutsummary.dart +++ b/lib/data/workoutsummary.dart @@ -29,54 +29,17 @@ class DurationstampedData { /// /// This takes care of processesing the raw byte data from workout summary characteristics into easily accessible fields. This class also takes care of things like byte endianness, combining multiple high and low bytes .etc, allowing applications to access things in terms of flutter native types. class WorkoutSummary extends TimestampedData { - Completer _workTime = new Completer(); - Completer _workDistance = new Completer(); - Completer _avgSPM = new Completer(); - Completer _endHeartRate = new Completer(); - Completer _avgHeartRate = new Completer(); - Completer _minHeartRate = new Completer(); - Completer _maxHeartRate = new Completer(); - Completer _avgDragFactor = new Completer(); - Completer _recoveryHeartRate = new Completer(); - Completer _workoutType = new Completer(); - Completer _avgPace = new Completer(); - Completer _intervalType = new Completer(); - Completer _intervalSize = new Completer(); - Completer _intervalCount = new Completer(); - Completer _totalCalories = new Completer(); - Completer _watts = new Completer(); - Completer _totalRestDistance = new Completer(); - Completer _intervalRestTime = new Completer(); - Completer _avgCalories = new Completer(); - - // external getters for clients to get futures for the data they want - Future get workTime => _workTime.future; - Future get workDistance => _workDistance.future; - Future get avgSPM => _avgSPM.future; - Future get endHeartRate => _endHeartRate.future; - Future get avgHeartRate => _avgHeartRate.future; - Future get minHeartRate => _minHeartRate.future; - Future get maxHeartRate => _maxHeartRate.future; - Future get avgDragFactor => _avgDragFactor.future; - //recoveryHeartRate is sent as an amended packet later. zero is not valid - Future get recoveryHeartRate => _recoveryHeartRate.future; - Future get workoutType => _workoutType.future; - Future get avgPace => _avgPace.future; - Future get intervalType => _intervalType.future; - Future get intervalSize => _intervalSize.future; - Future get intervalCount => _intervalCount.future; - Future get totalCalories => _totalCalories.future; - Future get watts => _watts.future; - Future get totalRestDistance => _totalRestDistance.future; - Future get intervalRestTime => _intervalRestTime.future; - Future get avgCalories => _avgCalories.future; - - WorkoutSummary.fromBytes(Uint8List data) { - _setBasicBytes(data.sublist(0, 20)); - if (data.length > 20) { - _setExtendedBytes(data.sublist(20)); - } - } + double workTime; + double workDistance; + int avgSPM; + int endHeartRate; + int avgHeartRate; + int minHeartRate; + int maxHeartRate; + int avgDragFactor; + int recoveryHeartRate; + WorkoutType workoutType; + double avgPace; /// Construct a WorkoutSummary from the bytes returned from the erg WorkoutSummary.fromBytes(Uint8List data) : super(data) { @@ -106,6 +69,15 @@ class WorkoutSummary extends TimestampedData { } class WorkoutSummary2 { + IntervalType intervalType; + int intervalSize; + int intervalCount; + int totalCalories; + int watts; + int totalRestDistance; + int intervalRestTime; + int avgCalories; + WorkoutSummary2.fromBytes(Uint8List data) { // if (data.length > 20) { // var timestamp2 = Concept2DateExtension.fromBytes(data.sublist(20, 24)); From f60c3c073b182485d512ad59efaca27f92334850 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 9 May 2022 21:10:30 -0400 Subject: [PATCH 005/220] syntax and stuff --- lib/data/workoutsummary.dart | 44 +++++++++++++++++------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/lib/data/workoutsummary.dart b/lib/data/workoutsummary.dart index c32e62a..7b59790 100644 --- a/lib/data/workoutsummary.dart +++ b/lib/data/workoutsummary.dart @@ -7,13 +7,12 @@ import 'package:csafe_fitness/csafe_fitness.dart'; import '../helpers.dart'; import 'package:c2bluetooth/enums.dart'; - ///Represents a data packet from Concept2 that is stamped with a date. class TimestampedData { DateTime timestamp; - TimestampedData.fromBytes(Uint8List bytes): timestamp = Concept2DateExtension.fromBytes(bytes.sublist(0, 4)); - + TimestampedData.fromBytes(Uint8List bytes) + : timestamp = Concept2DateExtension.fromBytes(bytes.sublist(0, 4)); } ///Represents a data packet from Concept2 that is stamped with a duration. @@ -21,10 +20,10 @@ class TimestampedData { class DurationstampedData { Duration elapsedTime; - DurationstampedData.fromBytes(Uint8List data) : elapsedTime = Concept2DurationExtension.fromBytes(data.sublist(0, 3)); + DurationstampedData.fromBytes(Uint8List data) + : elapsedTime = Concept2DurationExtension.fromBytes(data.sublist(0, 3)); } - /// Represents a summary of a completed workout /// /// This takes care of processesing the raw byte data from workout summary characteristics into easily accessible fields. This class also takes care of things like byte endianness, combining multiple high and low bytes .etc, allowing applications to access things in terms of flutter native types. @@ -43,28 +42,28 @@ class WorkoutSummary extends TimestampedData { /// Construct a WorkoutSummary from the bytes returned from the erg WorkoutSummary.fromBytes(Uint8List data) : super(data) { - _workTime = + _workTime = CsafeIntExtension.fromBytes(data.sublist(4, 7), endian: Endian.little) / - 100); //divide by 100 to convert to seconds + 100; //divide by 100 to convert to seconds _workDistance = CsafeIntExtension.fromBytes(data.sublist(7, 10), endian: Endian.little) / - 10); //divide by 10 to convert to meters - _avgSPM = data.elementAt(10)); - _endHeartRate = data.elementAt(11)); - _avgHeartRate = data.elementAt(12)); - _minHeartRate = data.elementAt(13)); - _maxHeartRate = data.elementAt(14)); - _avgDragFactor = data.elementAt(15)); + 10; //divide by 10 to convert to meters + _avgSPM = data.elementAt(10); + _endHeartRate = data.elementAt(11); + _avgHeartRate = data.elementAt(12); + _minHeartRate = data.elementAt(13); + _maxHeartRate = data.elementAt(14); + _avgDragFactor = data.elementAt(15); //recovery heart rate here int recHRVal = data.elementAt(16); // 0 is not a valid value here according to the spec if (recHRVal > 0) { - _recoveryHeartRate = recHRVal); + _recoveryHeartRate = recHRVal; } - _workoutType = WorkoutTypeExtension.fromInt(data.elementAt(17))); + _workoutType = WorkoutTypeExtension.fromInt(data.elementAt(17)); _avgPace = CsafeIntExtension.fromBytes(data.sublist(18, 20), endian: Endian.little) / - 10); //{ + 10; } } @@ -85,17 +84,16 @@ class WorkoutSummary2 { // throw ArgumentError( // "Bytes passed to WorkoutSummary from multiple characteristics must have the same timestamp"); // } - + intervalType = IntervalTypeExtension.fromInt(data.elementAt(4)); - intervalSize = + intervalSize = CsafeIntExtension.fromBytes(data.sublist(5, 7), endian: Endian.little); intervalCount = data.elementAt(7); - totalCalories = CsafeIntExtension.fromBytes(data.sublist(8, 10), - endian: Endian.little); + totalCalories = + CsafeIntExtension.fromBytes(data.sublist(8, 10), endian: Endian.little); watts = CsafeIntExtension.fromBytes(data.sublist(10, 12), endian: Endian.little); - totalRestDistance = CsafeIntExtension.fromBytes( - data.sublist(12, 15), + totalRestDistance = CsafeIntExtension.fromBytes(data.sublist(12, 15), endian: Endian.little); intervalRestTime = CsafeIntExtension.fromBytes(data.sublist(15, 17), endian: Endian.little); From 9b16ef52d05a0d856e8fe04d7da698f16501f402 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 9 May 2022 21:10:46 -0400 Subject: [PATCH 006/220] use fromBytes in super call --- lib/data/workoutsummary.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/data/workoutsummary.dart b/lib/data/workoutsummary.dart index 7b59790..2c4a02f 100644 --- a/lib/data/workoutsummary.dart +++ b/lib/data/workoutsummary.dart @@ -41,7 +41,7 @@ class WorkoutSummary extends TimestampedData { double avgPace; /// Construct a WorkoutSummary from the bytes returned from the erg - WorkoutSummary.fromBytes(Uint8List data) : super(data) { + WorkoutSummary.fromBytes(Uint8List data) : super.fromBytes(data) { _workTime = CsafeIntExtension.fromBytes(data.sublist(4, 7), endian: Endian.little) / 100; //divide by 100 to convert to seconds From 1f9f93d8093563c6e20495737b968f7f5c176700 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 9 May 2022 21:12:18 -0400 Subject: [PATCH 007/220] move WorkoutSummary to internal packets folder --- {lib/data => src/packets}/workoutsummary.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename {lib/data => src/packets}/workoutsummary.dart (99%) diff --git a/lib/data/workoutsummary.dart b/src/packets/workoutsummary.dart similarity index 99% rename from lib/data/workoutsummary.dart rename to src/packets/workoutsummary.dart index 2c4a02f..1f4842c 100644 --- a/lib/data/workoutsummary.dart +++ b/src/packets/workoutsummary.dart @@ -4,7 +4,7 @@ import 'dart:async'; import 'package:c2bluetooth/extensions.dart'; import 'package:csafe_fitness/csafe_fitness.dart'; -import '../helpers.dart'; +import '../../helpers.dart'; import 'package:c2bluetooth/enums.dart'; ///Represents a data packet from Concept2 that is stamped with a date. From 4e0f13de8ec5e7f4fa9d6dc805d9377473fdb652 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 9 May 2022 21:15:06 -0400 Subject: [PATCH 008/220] move base packet classes to a base file --- src/packets/base.dart | 19 +++++++++++++++++++ src/packets/workoutsummary.dart | 19 +------------------ 2 files changed, 20 insertions(+), 18 deletions(-) create mode 100644 src/packets/base.dart diff --git a/src/packets/base.dart b/src/packets/base.dart new file mode 100644 index 0000000..6b2fbbd --- /dev/null +++ b/src/packets/base.dart @@ -0,0 +1,19 @@ +import 'dart:typed_data'; +import 'package:c2bluetooth/extensions.dart'; + +///Represents a data packet from Concept2 that is stamped with a date. +class TimestampedData { + DateTime timestamp; + + TimestampedData.fromBytes(Uint8List bytes) + : timestamp = Concept2DateExtension.fromBytes(bytes.sublist(0, 4)); +} + +///Represents a data packet from Concept2 that is stamped with a duration. + +class DurationstampedData { + Duration elapsedTime; + + DurationstampedData.fromBytes(Uint8List data) + : elapsedTime = Concept2DurationExtension.fromBytes(data.sublist(0, 3)); +} diff --git a/src/packets/workoutsummary.dart b/src/packets/workoutsummary.dart index 1f4842c..dff21ed 100644 --- a/src/packets/workoutsummary.dart +++ b/src/packets/workoutsummary.dart @@ -1,28 +1,11 @@ import 'dart:typed_data'; import 'dart:async'; -import 'package:c2bluetooth/extensions.dart'; import 'package:csafe_fitness/csafe_fitness.dart'; import '../../helpers.dart'; import 'package:c2bluetooth/enums.dart'; - -///Represents a data packet from Concept2 that is stamped with a date. -class TimestampedData { - DateTime timestamp; - - TimestampedData.fromBytes(Uint8List bytes) - : timestamp = Concept2DateExtension.fromBytes(bytes.sublist(0, 4)); -} - -///Represents a data packet from Concept2 that is stamped with a duration. - -class DurationstampedData { - Duration elapsedTime; - - DurationstampedData.fromBytes(Uint8List data) - : elapsedTime = Concept2DurationExtension.fromBytes(data.sublist(0, 3)); -} +import './base.dart'; /// Represents a summary of a completed workout /// From 26bc8461d93ba81c61b03914d00fa21563256c56 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 9 May 2022 21:15:14 -0400 Subject: [PATCH 009/220] update helpers import --- src/packets/workoutsummary.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packets/workoutsummary.dart b/src/packets/workoutsummary.dart index dff21ed..2a66d63 100644 --- a/src/packets/workoutsummary.dart +++ b/src/packets/workoutsummary.dart @@ -3,7 +3,7 @@ import 'dart:async'; import 'package:csafe_fitness/csafe_fitness.dart'; -import '../../helpers.dart'; +import 'package:c2bluetooth/helpers.dart'; import 'package:c2bluetooth/enums.dart'; import './base.dart'; From 035a1775efbe49e231acf3fc7542bd7b57ff34e6 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 9 May 2022 21:17:46 -0400 Subject: [PATCH 010/220] bring in status data stub classes --- src/packets/statusdata.dart | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/packets/statusdata.dart diff --git a/src/packets/statusdata.dart b/src/packets/statusdata.dart new file mode 100644 index 0000000..658cc24 --- /dev/null +++ b/src/packets/statusdata.dart @@ -0,0 +1,33 @@ +import 'dart:typed_data'; + +import 'package:csafe_fitness/csafe_fitness.dart'; + +import './base.dart'; + +class StatusData extends DurationstampedData { + double distance; + + StatusData.fromBytes(Uint8List data) + : distance = CsafeIntExtension.fromBytes(data.sublist(3, 6), + endian: Endian.little) / + 10, + super.fromBytes(data); +} + +class StatusData1 extends DurationstampedData { + double speed; + + StatusData1.fromBytes(Uint8List data) + : speed = CsafeIntExtension.fromBytes(data.sublist(3, 5), + endian: Endian.little) / + 1000, + super.fromBytes(data); +} + +class StatusData2 extends DurationstampedData { + int intervalCount; + + StatusData2.fromBytes(Uint8List data) + : intervalCount = data.elementAt(3), + super.fromBytes(data); +} From 1fec0b1339680f300f3f320737f74f40a31443bb Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 10:53:43 -0400 Subject: [PATCH 011/220] document the data multiplex thing --- docs/internals.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/internals.md b/docs/internals.md index 72cb15e..bb7033f 100644 --- a/docs/internals.md +++ b/docs/internals.md @@ -33,3 +33,15 @@ If you need to create your own datatype, you should look at the existing datatyp This section intends to give a broad overview of various components of how c2bluetooth solves certain problems and why they were solved that way +### Subscription Data Multiplex + +In order to provide c2bluetooth with the most flexibility and control over data coming from the PM5, it is useful to insert an additional layer between the incoming data from the bluetooth streams from the PM5 and the stream going out to the user so that c2bluetooth can take on and abstract as much of the complexity as possible. + +This is similar to how a library might add a custom class of its own that wraps an existing API from one of its dependencies so that, even if the API being depended on by the library changes, users of the library are more insulated as the library has a locaton where it can perform changes to keep the API as consistent for the end user as possible. + +Within the context of c2bluetooth, this additional layer is intended to also add functionality by managing both the data requested by implementors of the c2bluetooth library and the data available to it via the concept2's bluetooth interface so as to provide the implementors with the data that they requested for use in their own apps. + +This layer has a few general objectives: +- to keep track of what data the implementor wants ("requested data") +- to keep track of what data we are currently receiving ("subscriptions" to bluetooth notifications from the PM) +- to route data that comes in via bluetooth subscriptions to "outgoing streams" that the implementor is listening to while conserving bluetooth bandwidth as much as possible From 6d905e2dfdfe2d48f53972398c14c891694a3da7 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 12:26:40 -0400 Subject: [PATCH 012/220] create a basic passthrough wrapper for a stream controller --- lib/models/cachedstreamcontroller.dart | 87 ++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 lib/models/cachedstreamcontroller.dart diff --git a/lib/models/cachedstreamcontroller.dart b/lib/models/cachedstreamcontroller.dart new file mode 100644 index 0000000..9ad48eb --- /dev/null +++ b/lib/models/cachedstreamcontroller.dart @@ -0,0 +1,87 @@ +import 'dart:async'; + +/// A wrapper around StreamController to aid in delivering data from bluetooth to the user +class CachedStreamController implements StreamController { + StreamController _controller; + + ///called when the controller loses its last subscriber + ///https://dart.dev/articles/libraries/creating-streams#using-a-streamcontroller + @override + FutureOr Function()? get onCancel => _controller.onCancel; + + set onCancel(FutureOr Function()? newValue) { + _controller.onCancel = newValue; + } + + ///called when the stream gets its first subscriber + ///https://dart.dev/articles/libraries/creating-streams#using-a-streamcontroller + @override + void Function()? get onListen => _controller.onListen; + + set onListen(Function()? newValue) { + _controller.onListen = newValue; + } + + @override + void Function()? get onPause => _controller.onPause; + + set onPause(Function()? newValue) { + _controller.onPause = newValue; + } + + @override + void Function()? get onResume => _controller.onResume; + + set onResume(Function()? newValue) { + _controller.onResume = newValue; + } + + CachedStreamController( + {void onListen()?, + void onPause()?, + void onResume()?, + FutureOr onCancel()?}) + : _controller = new StreamController( + onListen: onListen, + onPause: onPause, + onResume: onResume, + onCancel: onCancel); + + @override + void add(T event) { + _controller.add(event); + } + + @override + void addError(Object error, [StackTrace? stackTrace]) { + _controller.addError(error, stackTrace); + } + + @override + Future addStream(Stream source, {bool? cancelOnError}) { + return _controller.addStream(source, cancelOnError: cancelOnError); + } + + @override + Future close() { + return _controller.close(); + } + + @override + Future get done => _controller.done; + + @override + bool get hasListener => _controller.hasListener; + + @override + bool get isClosed => _controller.isClosed; + + @override + bool get isPaused => _controller.isPaused; + + @override + StreamSink get sink => _controller.sink; + + @override + Stream get stream => _controller.stream; +} From 4ffa22db68e2366d225b6f6631f21e527cb91fda Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 12:33:07 -0400 Subject: [PATCH 013/220] rename and expand on dartdoc --- ...streamcontroller.dart => c2datastreamcontroller.dart} | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) rename lib/models/{cachedstreamcontroller.dart => c2datastreamcontroller.dart} (84%) diff --git a/lib/models/cachedstreamcontroller.dart b/lib/models/c2datastreamcontroller.dart similarity index 84% rename from lib/models/cachedstreamcontroller.dart rename to lib/models/c2datastreamcontroller.dart index 9ad48eb..717331b 100644 --- a/lib/models/cachedstreamcontroller.dart +++ b/lib/models/c2datastreamcontroller.dart @@ -1,7 +1,12 @@ import 'dart:async'; /// A wrapper around StreamController to aid in delivering data from bluetooth to the user -class CachedStreamController implements StreamController { +/// +/// This is intended to add functionality enabling: +/// - filtering of data sent to the `add` function so this stream can only send datapoints that it was created to send +/// - caching of data in the event that users want a full set of data any time any value is updated +/// and possibly more. +class C2DataStreamController implements StreamController { StreamController _controller; ///called when the controller loses its last subscriber @@ -36,7 +41,7 @@ class CachedStreamController implements StreamController { _controller.onResume = newValue; } - CachedStreamController( + C2DataStreamController( {void onListen()?, void onPause()?, void onResume()?, From 306bcacd8657db9f2da946a17450f5a586fe9e3a Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 12:35:37 -0400 Subject: [PATCH 014/220] add datapoint identifiers field --- lib/models/c2datastreamcontroller.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/models/c2datastreamcontroller.dart b/lib/models/c2datastreamcontroller.dart index 717331b..bb95aef 100644 --- a/lib/models/c2datastreamcontroller.dart +++ b/lib/models/c2datastreamcontroller.dart @@ -9,6 +9,9 @@ import 'dart:async'; class C2DataStreamController implements StreamController { StreamController _controller; + /// A list of the identifying strings for datapoints that this controller should pass on as stream updates. + Set datapoint_identifiers; + ///called when the controller loses its last subscriber ///https://dart.dev/articles/libraries/creating-streams#using-a-streamcontroller @override @@ -41,7 +44,7 @@ class C2DataStreamController implements StreamController { _controller.onResume = newValue; } - C2DataStreamController( + C2DataStreamController(this.datapoint_identifiers, {void onListen()?, void onPause()?, void onResume()?, From 730927e4fa4562894a242ff3a3abb5a5aba58cca Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 12:48:53 -0400 Subject: [PATCH 015/220] deprecate monitorForWorkoutSummary --- lib/models/ergometer.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index 8beef74..92564f0 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -40,6 +40,7 @@ class Ergometer { } /// Returns a stream of [WorkoutSummary] objects upon completion of any programmed piece or a "just row" piece that is longer than 1 minute. + @Deprecated("This API is being deprecated soon") Stream monitorForWorkoutSummary() { Stream ws1 = _peripheral .monitorCharacteristic(Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID, From 876f86e5e55cc63be742222c1df28ccf062668a9 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 13:26:17 -0400 Subject: [PATCH 016/220] move src underneath lib per https://dart.dev/guides/libraries/create-library-packages#what-makes-a-library-package --- {src => lib/src}/packets/base.dart | 0 {src => lib/src}/packets/statusdata.dart | 0 {src => lib/src}/packets/workoutsummary.dart | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename {src => lib/src}/packets/base.dart (100%) rename {src => lib/src}/packets/statusdata.dart (100%) rename {src => lib/src}/packets/workoutsummary.dart (100%) diff --git a/src/packets/base.dart b/lib/src/packets/base.dart similarity index 100% rename from src/packets/base.dart rename to lib/src/packets/base.dart diff --git a/src/packets/statusdata.dart b/lib/src/packets/statusdata.dart similarity index 100% rename from src/packets/statusdata.dart rename to lib/src/packets/statusdata.dart diff --git a/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart similarity index 100% rename from src/packets/workoutsummary.dart rename to lib/src/packets/workoutsummary.dart From 514b9197f52a849ab693492380fdbf1fb94eacd5 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 13:32:16 -0400 Subject: [PATCH 017/220] move definitions from internal to src folder --- lib/models/ergometer.dart | 4 ++-- lib/models/workout.dart | 2 +- lib/{internal => src}/commands.dart | 0 lib/{internal => src}/datatypes.dart | 0 lib/{internal => src}/validators.dart | 2 +- test/internal/datatypes_test.dart | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) rename lib/{internal => src}/commands.dart (100%) rename lib/{internal => src}/datatypes.dart (100%) rename lib/{internal => src}/validators.dart (93%) diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index 92564f0..8d590e9 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -1,8 +1,8 @@ import 'dart:typed_data'; import 'package:c2bluetooth/c2bluetooth.dart'; -import '../internal/commands.dart'; -import '../internal/datatypes.dart'; +import '../src/commands.dart'; +import '../src/datatypes.dart'; import 'package:csafe_fitness/csafe_fitness.dart'; import '../helpers.dart'; import 'workout.dart'; diff --git a/lib/models/workout.dart b/lib/models/workout.dart index de58e0d..ae71812 100644 --- a/lib/models/workout.dart +++ b/lib/models/workout.dart @@ -1,4 +1,4 @@ -import '../internal/datatypes.dart'; +import '../src/datatypes.dart'; import 'package:csafe_fitness/csafe_fitness.dart'; import 'package:equatable/equatable.dart'; diff --git a/lib/internal/commands.dart b/lib/src/commands.dart similarity index 100% rename from lib/internal/commands.dart rename to lib/src/commands.dart diff --git a/lib/internal/datatypes.dart b/lib/src/datatypes.dart similarity index 100% rename from lib/internal/datatypes.dart rename to lib/src/datatypes.dart diff --git a/lib/internal/validators.dart b/lib/src/validators.dart similarity index 93% rename from lib/internal/validators.dart rename to lib/src/validators.dart index 758394c..6c8de99 100644 --- a/lib/internal/validators.dart +++ b/lib/src/validators.dart @@ -1,5 +1,5 @@ import 'package:c2bluetooth/c2bluetooth.dart'; -import '../internal/datatypes.dart'; +import '../src/datatypes.dart'; import 'package:csafe_fitness/csafe_fitness.dart'; //TODO: validate data as a big endian IntegerWithUnits-like type with DurationType as the unit diff --git a/test/internal/datatypes_test.dart b/test/internal/datatypes_test.dart index a947c4a..3d1d931 100644 --- a/test/internal/datatypes_test.dart +++ b/test/internal/datatypes_test.dart @@ -2,7 +2,7 @@ import 'dart:typed_data'; import 'package:c2bluetooth/c2bluetooth.dart'; import 'package:c2bluetooth/enums.dart'; -import '../../lib/internal/datatypes.dart'; +import '../../lib/src/datatypes.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { From 567e14dc02b0c45e67f79c1b12b2b7df6cca19e9 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 13:34:02 -0400 Subject: [PATCH 018/220] add and hook up initial stubs of the internal dataplex class --- lib/models/ergometer.dart | 8 ++++++ lib/src/dataplex.dart | 56 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 lib/src/dataplex.dart diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index 8d590e9..c8512b7 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -5,6 +5,7 @@ import '../src/commands.dart'; import '../src/datatypes.dart'; import 'package:csafe_fitness/csafe_fitness.dart'; import '../helpers.dart'; +import '../../src/dataplex.dart'; import 'workout.dart'; import 'package:c2bluetooth/constants.dart' as Identifiers; import 'package:flutter_ble_lib_ios_15/flutter_ble_lib.dart'; @@ -16,6 +17,8 @@ class Ergometer { Peripheral _peripheral; Csafe? _csafeClient; + Dataplex _dataplex = new Dataplex(); + /// Get the name of this erg. i.e. "PM5" + serial number /// /// Returns "Unknown" if the erg does not report a name @@ -39,6 +42,11 @@ class Ergometer { return _peripheral.disconnectOrCancelConnection(); } + Stream> monitorForData( + Set datapointIdentifiers) { + return _dataplex.createStream(datapointIdentifiers); + } + /// Returns a stream of [WorkoutSummary] objects upon completion of any programmed piece or a "just row" piece that is longer than 1 minute. @Deprecated("This API is being deprecated soon") Stream monitorForWorkoutSummary() { diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart new file mode 100644 index 0000000..04d2349 --- /dev/null +++ b/lib/src/dataplex.dart @@ -0,0 +1,56 @@ +import 'dart:typed_data'; + +import './packets/statusdata.dart'; +import './packets/strokedata.dart'; + +/// Handles mapping between data coming from bluetooth notfications and the data the user requested. +/// This gives c2bluetooth a layer of flexibility and decouples the incoming bluetooth data from the output going to an application so that c2bluetooth has space to potentially optimize the data being used +class Dataplex { + // data access speed + + ///Keeps track of how many characteristics we are currently receiving notifications for + int _currentSubscriptionCount = 0; + + Stream> createStream(Set keysRequested) { + + } + + // String _packetType(Uint8List data) { + // switch (data[0]) { + // case 0x31: + // StatusData parsed = StatusData.fromBytes(data.sublist(1)); + // print(parsed.elapsedTime.toString()); + // print("distance ${parsed.distance.toString()}"); + + // return "status"; + // case 0x32: + // StatusData1 parsed = StatusData1.fromBytes(data.sublist(1)); + // print(parsed.elapsedTime.toString()); + // print("speed ${parsed.speed.toString()}"); + + // return "Status 1"; + // case 0x33: + // StatusData2 parsed = StatusData2.fromBytes(data.sublist(1)); + // print(parsed.elapsedTime.toString()); + // // print("intervalcount ${parsed.intervalCount.toString()}"); + // return "Status 2"; + // case 0x35: + // return "stroke data"; + // case 0x36: + // return "stroke data 1"; + // case 0x37: + // return "split/interval data"; + // case 0x38: + // return "split/interval data 2"; + // case 0x39: + // return "workout data"; + // case 0x3A: + // return "workout data 1"; + // case 0x3C: + // print(data); + // return "workout data 2"; + // default: + // return "Unknown"; + // } + // } +} From 2b2758f4fc1453c1d1fa0eab571f51a5aa5d5e19 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 13:53:12 -0400 Subject: [PATCH 019/220] add basic stream creation flow to Dataplex --- lib/src/dataplex.dart | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 04d2349..2cd5579 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -1,4 +1,5 @@ import 'dart:typed_data'; +import 'package:c2bluetooth/models/c2datastreamcontroller.dart'; import './packets/statusdata.dart'; import './packets/strokedata.dart'; @@ -8,11 +9,20 @@ import './packets/strokedata.dart'; class Dataplex { // data access speed + List outgoingStreams = []; + ///Keeps track of how many characteristics we are currently receiving notifications for int _currentSubscriptionCount = 0; Stream> createStream(Set keysRequested) { - + C2DataStreamController controller = + new C2DataStreamController(keysRequested); + + //TODO: set up close listener. + + outgoingStreams.add(controller); + + return controller.stream; } // String _packetType(Uint8List data) { From c0ae41184b71a201665cfe509a1b41db9f55a464 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 13:59:33 -0400 Subject: [PATCH 020/220] pass peripheral to dataplex --- lib/models/ergometer.dart | 6 ++++-- lib/src/dataplex.dart | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index c8512b7..ff67a50 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -17,7 +17,7 @@ class Ergometer { Peripheral _peripheral; Csafe? _csafeClient; - Dataplex _dataplex = new Dataplex(); + Dataplex _dataplex; /// Get the name of this erg. i.e. "PM5" + serial number /// @@ -27,7 +27,9 @@ class Ergometer { /// Create an Ergometer from a FlutterBleLib peripheral object /// /// This is mainly intended for internal use - Ergometer(this._peripheral); + Ergometer(Peripheral peripheral) + : _peripheral = peripheral, + _dataplex = new Dataplex(peripheral); /// Connect to this erg and discover the services and characteristics that it offers Future connectAndDiscover() async { diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 2cd5579..37d35b0 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -1,5 +1,6 @@ import 'dart:typed_data'; import 'package:c2bluetooth/models/c2datastreamcontroller.dart'; +import 'package:flutter_ble_lib_ios_15/flutter_ble_lib.dart'; import './packets/statusdata.dart'; import './packets/strokedata.dart'; @@ -9,8 +10,12 @@ import './packets/strokedata.dart'; class Dataplex { // data access speed + Peripheral device; + List outgoingStreams = []; + Dataplex(this.device); + ///Keeps track of how many characteristics we are currently receiving notifications for int _currentSubscriptionCount = 0; From 5b14581ff907c0a353ce0576104919386e229677 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 14:12:22 -0400 Subject: [PATCH 021/220] add some basic methods for creating new subscriptions to data from the erg --- lib/src/dataplex.dart | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 37d35b0..5bbb245 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:typed_data'; import 'package:c2bluetooth/models/c2datastreamcontroller.dart'; import 'package:flutter_ble_lib_ios_15/flutter_ble_lib.dart'; @@ -14,6 +15,8 @@ class Dataplex { List outgoingStreams = []; + Map currentSubscriptions = Map(); + Dataplex(this.device); ///Keeps track of how many characteristics we are currently receiving notifications for @@ -30,6 +33,14 @@ class Dataplex { return controller.stream; } + void _addSubscription(String serviceUuid, String characteristicUuid) { + StreamSubscription sub = device + .monitorCharacteristic(serviceUuid, characteristicUuid) + .listen((data) => data.read().then((bytes) => _readPacket(bytes))); + currentSubscriptions.addEntries({characteristicUuid: sub}.entries); + } + + void _readPacket(Uint8List data) {} // String _packetType(Uint8List data) { // switch (data[0]) { // case 0x31: @@ -68,4 +79,16 @@ class Dataplex { // return "Unknown"; // } // } + + void dispose() { + // clear current subscriptions + for (var entry in currentSubscriptions.entries) { + var key = entry.key; + var subscription = entry.value; + + subscription.cancel(); + currentSubscriptions.remove(key); + } + // end all current output streams + } } From 9da47ebf3762eea2addfafd5d056bcadc3a12e4e Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 14:24:27 -0400 Subject: [PATCH 022/220] add a base class covering all concept2 data packet types --- lib/src/packets/base.dart | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/src/packets/base.dart b/lib/src/packets/base.dart index 6b2fbbd..fe85b46 100644 --- a/lib/src/packets/base.dart +++ b/lib/src/packets/base.dart @@ -1,8 +1,11 @@ import 'dart:typed_data'; import 'package:c2bluetooth/extensions.dart'; +/// An empty superclass to represent all types of data formats that come from Concept2 bluetooth characteristics +class Concept2CharacteristicData {} + ///Represents a data packet from Concept2 that is stamped with a date. -class TimestampedData { +class TimestampedData extends Concept2CharacteristicData { DateTime timestamp; TimestampedData.fromBytes(Uint8List bytes) @@ -11,7 +14,7 @@ class TimestampedData { ///Represents a data packet from Concept2 that is stamped with a duration. -class DurationstampedData { +class DurationstampedData extends Concept2CharacteristicData { Duration elapsedTime; DurationstampedData.fromBytes(Uint8List data) From 5d9b70c373d1317f081230a5d0f789bc0df44a2a Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 14:25:07 -0400 Subject: [PATCH 023/220] inject a data identifier into packets that dont have it --- lib/src/dataplex.dart | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 5bbb245..bbfb69a 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -33,10 +33,17 @@ class Dataplex { return controller.stream; } - void _addSubscription(String serviceUuid, String characteristicUuid) { + void _addSubscription( + String serviceUuid, String characteristicUuid, int? dataIdentifier) { StreamSubscription sub = device .monitorCharacteristic(serviceUuid, characteristicUuid) - .listen((data) => data.read().then((bytes) => _readPacket(bytes))); + .listen((data) => data.read().then((bytes) { + // manually insert an identification byte if this characteristic doesnt have one already + if (dataIdentifier != null) { + bytes.insert(0, dataIdentifier); + } + _readPacket(bytes); + })); currentSubscriptions.addEntries({characteristicUuid: sub}.entries); } From a6680c467e694dbf4c781d9cb3e07527a788a104 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 14:31:34 -0400 Subject: [PATCH 024/220] fix fromBytes WorkoutSummary Constructor --- lib/src/packets/workoutsummary.dart | 43 +++++++++++++---------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index 2a66d63..80bdf11 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -24,30 +24,25 @@ class WorkoutSummary extends TimestampedData { double avgPace; /// Construct a WorkoutSummary from the bytes returned from the erg - WorkoutSummary.fromBytes(Uint8List data) : super.fromBytes(data) { - _workTime = - CsafeIntExtension.fromBytes(data.sublist(4, 7), endian: Endian.little) / - 100; //divide by 100 to convert to seconds - _workDistance = CsafeIntExtension.fromBytes(data.sublist(7, 10), - endian: Endian.little) / - 10; //divide by 10 to convert to meters - _avgSPM = data.elementAt(10); - _endHeartRate = data.elementAt(11); - _avgHeartRate = data.elementAt(12); - _minHeartRate = data.elementAt(13); - _maxHeartRate = data.elementAt(14); - _avgDragFactor = data.elementAt(15); - //recovery heart rate here - int recHRVal = data.elementAt(16); - // 0 is not a valid value here according to the spec - if (recHRVal > 0) { - _recoveryHeartRate = recHRVal; - } - _workoutType = WorkoutTypeExtension.fromInt(data.elementAt(17)); - _avgPace = CsafeIntExtension.fromBytes(data.sublist(18, 20), - endian: Endian.little) / - 10; - } + WorkoutSummary.fromBytes(Uint8List data) + : workTime = CsafeIntExtension.fromBytes(data.sublist(4, 7), + endian: Endian.little) / + 100, //divide by 100 to convert to seconds + workDistance = CsafeIntExtension.fromBytes(data.sublist(7, 10), + endian: Endian.little) / + 10, + avgSPM = data.elementAt(10), + endHeartRate = data.elementAt(11), + avgHeartRate = data.elementAt(12), + minHeartRate = data.elementAt(13), + maxHeartRate = data.elementAt(14), + avgDragFactor = data.elementAt(15), + recoveryHeartRate = data.elementAt(16), + workoutType = WorkoutTypeExtension.fromInt(data.elementAt(17)), + avgPace = CsafeIntExtension.fromBytes(data.sublist(18, 20), + endian: Endian.little) / + 10, + super.fromBytes(data); } class WorkoutSummary2 { From 90d99b46e839543824b17fb8009b4f3ee7e694ab Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 14:31:56 -0400 Subject: [PATCH 025/220] rename workoutsummary to workoutsummarypacket --- lib/src/packets/workoutsummary.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index 80bdf11..1118b19 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -10,7 +10,7 @@ import './base.dart'; /// Represents a summary of a completed workout /// /// This takes care of processesing the raw byte data from workout summary characteristics into easily accessible fields. This class also takes care of things like byte endianness, combining multiple high and low bytes .etc, allowing applications to access things in terms of flutter native types. -class WorkoutSummary extends TimestampedData { +class WorkoutSummaryPacket extends TimestampedData { double workTime; double workDistance; int avgSPM; @@ -24,7 +24,7 @@ class WorkoutSummary extends TimestampedData { double avgPace; /// Construct a WorkoutSummary from the bytes returned from the erg - WorkoutSummary.fromBytes(Uint8List data) + WorkoutSummaryPacket.fromBytes(Uint8List data) : workTime = CsafeIntExtension.fromBytes(data.sublist(4, 7), endian: Endian.little) / 100, //divide by 100 to convert to seconds From 0551f9a919bb07372e5dbac8926c65d4a3dd5ece Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 14:36:02 -0400 Subject: [PATCH 026/220] uncomment packet type parsing function and update types --- lib/src/dataplex.dart | 77 ++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index bbfb69a..75de7ac 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -5,6 +5,7 @@ import 'package:flutter_ble_lib_ios_15/flutter_ble_lib.dart'; import './packets/statusdata.dart'; import './packets/strokedata.dart'; +import 'packets/base.dart'; /// Handles mapping between data coming from bluetooth notfications and the data the user requested. /// This gives c2bluetooth a layer of flexibility and decouples the incoming bluetooth data from the output going to an application so that c2bluetooth has space to potentially optimize the data being used @@ -48,44 +49,44 @@ class Dataplex { } void _readPacket(Uint8List data) {} - // String _packetType(Uint8List data) { - // switch (data[0]) { - // case 0x31: - // StatusData parsed = StatusData.fromBytes(data.sublist(1)); - // print(parsed.elapsedTime.toString()); - // print("distance ${parsed.distance.toString()}"); - - // return "status"; - // case 0x32: - // StatusData1 parsed = StatusData1.fromBytes(data.sublist(1)); - // print(parsed.elapsedTime.toString()); - // print("speed ${parsed.speed.toString()}"); - - // return "Status 1"; - // case 0x33: - // StatusData2 parsed = StatusData2.fromBytes(data.sublist(1)); - // print(parsed.elapsedTime.toString()); - // // print("intervalcount ${parsed.intervalCount.toString()}"); - // return "Status 2"; - // case 0x35: - // return "stroke data"; - // case 0x36: - // return "stroke data 1"; - // case 0x37: - // return "split/interval data"; - // case 0x38: - // return "split/interval data 2"; - // case 0x39: - // return "workout data"; - // case 0x3A: - // return "workout data 1"; - // case 0x3C: - // print(data); - // return "workout data 2"; - // default: - // return "Unknown"; - // } - // } + Concept2CharacteristicData _identifyPacketType(Uint8List data) { + switch (data[0]) { + case 0x31: + StatusData parsed = StatusData.fromBytes(data.sublist(1)); + print(parsed.elapsedTime.toString()); + print("distance ${parsed.distance.toString()}"); + + return parsed; + case 0x32: + StatusData1 parsed = StatusData1.fromBytes(data.sublist(1)); + print(parsed.elapsedTime.toString()); + print("speed ${parsed.speed.toString()}"); + + return parsed; + case 0x33: + StatusData2 parsed = StatusData2.fromBytes(data.sublist(1)); + print(parsed.elapsedTime.toString()); + // print("intervalcount ${parsed.intervalCount.toString()}"); + return parsed; + case 0x35: + return "stroke data"; + case 0x36: + return "stroke data 1"; + case 0x37: + return "split/interval data"; + case 0x38: + return "split/interval data 2"; + case 0x39: + return "workout data"; + case 0x3A: + return "workout data 1"; + case 0x3C: + print(data); + return "workout data 2"; + default: + return "Unknown"; + } + } void dispose() { // clear current subscriptions From fe2340e6492c98f99ff49fc50082420496c0dd0d Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 14:36:34 -0400 Subject: [PATCH 027/220] parse packet type when reading incoming packet from erg --- lib/src/dataplex.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 75de7ac..9477f88 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -48,7 +48,10 @@ class Dataplex { currentSubscriptions.addEntries({characteristicUuid: sub}.entries); } - void _readPacket(Uint8List data) {} + void _readPacket(Uint8List data) { + Concept2CharacteristicData packetType = _identifyPacketType(data); + } + Concept2CharacteristicData _identifyPacketType(Uint8List data) { switch (data[0]) { case 0x31: From 8226ec644447036a6536d74d66efdf198bc75879 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 14:39:00 -0400 Subject: [PATCH 028/220] rename second packet --- lib/src/packets/workoutsummary.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index 1118b19..2902ce3 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -45,7 +45,7 @@ class WorkoutSummaryPacket extends TimestampedData { super.fromBytes(data); } -class WorkoutSummary2 { +class WorkoutSummaryPacket2 { IntervalType intervalType; int intervalSize; int intervalCount; @@ -55,7 +55,7 @@ class WorkoutSummary2 { int intervalRestTime; int avgCalories; - WorkoutSummary2.fromBytes(Uint8List data) { + WorkoutSummaryPacket2.fromBytes(Uint8List data) { // if (data.length > 20) { // var timestamp2 = Concept2DateExtension.fromBytes(data.sublist(20, 24)); // if (timestamp != timestamp2) { From 17d415874aadb7f4155fb3e096036109fb7e48a1 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 14:40:02 -0400 Subject: [PATCH 029/220] update byte parsing syntax for WorkoutSummaryPacket2 --- lib/src/packets/workoutsummary.dart | 39 +++++++++++------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index 2902ce3..88184a4 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -55,30 +55,21 @@ class WorkoutSummaryPacket2 { int intervalRestTime; int avgCalories; - WorkoutSummaryPacket2.fromBytes(Uint8List data) { - // if (data.length > 20) { - // var timestamp2 = Concept2DateExtension.fromBytes(data.sublist(20, 24)); - // if (timestamp != timestamp2) { - // throw ArgumentError( - // "Bytes passed to WorkoutSummary from multiple characteristics must have the same timestamp"); - // } - - intervalType = IntervalTypeExtension.fromInt(data.elementAt(4)); - intervalSize = - CsafeIntExtension.fromBytes(data.sublist(5, 7), endian: Endian.little); - intervalCount = data.elementAt(7); - totalCalories = - CsafeIntExtension.fromBytes(data.sublist(8, 10), endian: Endian.little); - watts = CsafeIntExtension.fromBytes(data.sublist(10, 12), - endian: Endian.little); - totalRestDistance = CsafeIntExtension.fromBytes(data.sublist(12, 15), - endian: Endian.little); - intervalRestTime = CsafeIntExtension.fromBytes(data.sublist(15, 17), - endian: Endian.little); - avgCalories = CsafeIntExtension.fromBytes(data.sublist(17, 19), - endian: Endian.little); - } - + WorkoutSummaryPacket2.fromBytes(Uint8List data) + : intervalType = IntervalTypeExtension.fromInt(data.elementAt(4)), + intervalSize = CsafeIntExtension.fromBytes(data.sublist(5, 7), + endian: Endian.little), + intervalCount = data.elementAt(7), + totalCalories = CsafeIntExtension.fromBytes(data.sublist(8, 10), + endian: Endian.little), + watts = CsafeIntExtension.fromBytes(data.sublist(10, 12), + endian: Endian.little), + totalRestDistance = CsafeIntExtension.fromBytes(data.sublist(12, 15), + endian: Endian.little), + intervalRestTime = CsafeIntExtension.fromBytes(data.sublist(15, 17), + endian: Endian.little), + avgCalories = CsafeIntExtension.fromBytes(data.sublist(17, 19), + endian: Endian.little); @override String toString() => "WorkoutSummary (" "Timestamp: $timestamp, " From 380943bcc089eb2f282b398c0f2696770ff37207 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 19:23:12 -0400 Subject: [PATCH 030/220] add TODO notes for expanding statusdata types --- lib/src/packets/statusdata.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/src/packets/statusdata.dart b/lib/src/packets/statusdata.dart index 658cc24..813cbdc 100644 --- a/lib/src/packets/statusdata.dart +++ b/lib/src/packets/statusdata.dart @@ -12,6 +12,8 @@ class StatusData extends DurationstampedData { endian: Endian.little) / 10, super.fromBytes(data); + + //TODO: add more data fields here } class StatusData1 extends DurationstampedData { @@ -22,6 +24,7 @@ class StatusData1 extends DurationstampedData { endian: Endian.little) / 1000, super.fromBytes(data); + //TODO: add more data fields here } class StatusData2 extends DurationstampedData { @@ -30,4 +33,6 @@ class StatusData2 extends DurationstampedData { StatusData2.fromBytes(Uint8List data) : intervalCount = data.elementAt(3), super.fromBytes(data); + //TODO: add more data fields here + } From 6e2d0c94e363884bf90f76378df1d23c858c8018 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 19:23:40 -0400 Subject: [PATCH 031/220] update second workout summary packet to inherit from TimestampedData --- lib/src/packets/workoutsummary.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index 88184a4..37b9bdc 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -45,7 +45,7 @@ class WorkoutSummaryPacket extends TimestampedData { super.fromBytes(data); } -class WorkoutSummaryPacket2 { +class WorkoutSummaryPacket2 extends TimestampedData { IntervalType intervalType; int intervalSize; int intervalCount; @@ -69,7 +69,9 @@ class WorkoutSummaryPacket2 { intervalRestTime = CsafeIntExtension.fromBytes(data.sublist(15, 17), endian: Endian.little), avgCalories = CsafeIntExtension.fromBytes(data.sublist(17, 19), - endian: Endian.little); + endian: Endian.little), + super.fromBytes(data); + @override String toString() => "WorkoutSummary (" "Timestamp: $timestamp, " From 60a5be81362bce05a1ebcc1d7fdb829b622af8dc Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 19:25:22 -0400 Subject: [PATCH 032/220] remove string implementation from workoutSummary --- lib/src/packets/workoutsummary.dart | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index 37b9bdc..c430343 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -71,11 +71,4 @@ class WorkoutSummaryPacket2 extends TimestampedData { avgCalories = CsafeIntExtension.fromBytes(data.sublist(17, 19), endian: Endian.little), super.fromBytes(data); - - @override - String toString() => "WorkoutSummary (" - "Timestamp: $timestamp, " - "elapsedTime: $workTime, " - "distance: $workDistance, " - "avgSPM: $avgSPM)"; } From e90ffe67f63f5db9d395f321fee5049d2637d0c9 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 19:28:05 -0400 Subject: [PATCH 033/220] add stub for workout summary packet 3 --- lib/src/packets/workoutsummary.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index c430343..fbaa9a3 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -72,3 +72,7 @@ class WorkoutSummaryPacket2 extends TimestampedData { endian: Endian.little), super.fromBytes(data); } + +class WorkoutSummaryPacket3 extends TimestampedData { + WorkoutSummaryPacket3.fromBytes(Uint8List data) : super.fromBytes(data); +} From 65be514ec71679d7dec06a92e39e6e26d8918025 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 20:12:02 -0400 Subject: [PATCH 034/220] stub out the remaining types --- lib/src/dataplex.dart | 20 +++++++++-------- lib/src/packets/segmentdata.dart | 10 +++++++++ lib/src/packets/strokedata.dart | 37 ++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 lib/src/packets/segmentdata.dart create mode 100644 lib/src/packets/strokedata.dart diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 9477f88..ef38d08 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -5,6 +5,9 @@ import 'package:flutter_ble_lib_ios_15/flutter_ble_lib.dart'; import './packets/statusdata.dart'; import './packets/strokedata.dart'; +import './packets/segmentdata.dart'; +import './packets/workoutsummary.dart'; + import 'packets/base.dart'; /// Handles mapping between data coming from bluetooth notfications and the data the user requested. @@ -72,22 +75,21 @@ class Dataplex { // print("intervalcount ${parsed.intervalCount.toString()}"); return parsed; case 0x35: - return "stroke data"; + return StrokeData.fromBytes(data.sublist(1)); case 0x36: - return "stroke data 1"; + return StrokeData2.fromBytes(data.sublist(1)); case 0x37: - return "split/interval data"; + return SegmentData.fromBytes(data.sublist(1)); case 0x38: - return "split/interval data 2"; + return SegmentData2.fromBytes(data.sublist(1)); case 0x39: - return "workout data"; + return WorkoutSummaryPacket.fromBytes(data.sublist(1)); case 0x3A: - return "workout data 1"; + return WorkoutSummaryPacket2.fromBytes(data.sublist(1)); case 0x3C: - print(data); - return "workout data 2"; + return WorkoutSummaryPacket3.fromBytes(data.sublist(1)); default: - return "Unknown"; + return null; } } diff --git a/lib/src/packets/segmentdata.dart b/lib/src/packets/segmentdata.dart new file mode 100644 index 0000000..26d25d5 --- /dev/null +++ b/lib/src/packets/segmentdata.dart @@ -0,0 +1,10 @@ +import 'dart:typed_data'; +import 'package:c2bluetooth/src/packets/base.dart'; + +class SegmentData extends TimestampedData { + SegmentData.fromBytes(Uint8List data) : super.fromBytes(data); +} + +class SegmentData2 extends TimestampedData { + SegmentData2.fromBytes(Uint8List data) : super.fromBytes(data); +} diff --git a/lib/src/packets/strokedata.dart b/lib/src/packets/strokedata.dart new file mode 100644 index 0000000..4268cbc --- /dev/null +++ b/lib/src/packets/strokedata.dart @@ -0,0 +1,37 @@ +import 'dart:typed_data'; + +import './base.dart'; + +class StrokeData extends TimestampedData { + StrokeData.fromBytes(Uint8List data) : super.fromBytes(data) { + // _workTime.completeIfNotAlready( + // CsafeIntExtension.fromBytes(data.sublist(4, 7), endian: Endian.little) / + // 100); //divide by 100 to convert to seconds + // _workDistance.completeIfNotAlready(CsafeIntExtension.fromBytes( + // data.sublist(7, 10), + // endian: Endian.little) / + // 10); //divide by 10 to convert to meters + // _avgSPM.completeIfNotAlready(data.elementAt(10)); + // _endHeartRate.completeIfNotAlready(data.elementAt(11)); + // _avgHeartRate.completeIfNotAlready(data.elementAt(12)); + // _minHeartRate.completeIfNotAlready(data.elementAt(13)); + // _maxHeartRate.completeIfNotAlready(data.elementAt(14)); + // _avgDragFactor.completeIfNotAlready(data.elementAt(15)); + // //recovery heart rate here + // int recHRVal = data.elementAt(16); + // // 0 is not a valid value here according to the spec + // if (recHRVal > 0) { + // _recoveryHeartRate.completeIfNotAlready(recHRVal); + // } + // _workoutType + // .completeIfNotAlready(WorkoutTypeExtension.fromInt(data.elementAt(17))); + // _avgPace.completeIfNotAlready(CsafeIntExtension.fromBytes( + // data.sublist(18, 20), + // endian: Endian.little) / + // 10); //{ + } +} + +class StrokeData2 extends TimestampedData { + StrokeData2.fromBytes(Uint8List data) : super.fromBytes(data); +} From 40e75943503a38d9bd0702a69acc9b59d834311a Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 20:38:11 -0400 Subject: [PATCH 035/220] rename identifyPacket function --- lib/src/dataplex.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index ef38d08..718817a 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -52,10 +52,10 @@ class Dataplex { } void _readPacket(Uint8List data) { - Concept2CharacteristicData packetType = _identifyPacketType(data); + Concept2CharacteristicData? packet = _parsePacket(data); } - Concept2CharacteristicData _identifyPacketType(Uint8List data) { + Concept2CharacteristicData? _parsePacket(Uint8List data) { switch (data[0]) { case 0x31: StatusData parsed = StatusData.fromBytes(data.sublist(1)); From 7a9ce263da436901ca016fbaad9ac01e66c9495b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 20:39:02 -0400 Subject: [PATCH 036/220] add packet parsing logic --- lib/src/dataplex.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 718817a..07e6ab4 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -53,6 +53,16 @@ class Dataplex { void _readPacket(Uint8List data) { Concept2CharacteristicData? packet = _parsePacket(data); + + if (packet != null) { + //send the data to + for (var stream in outgoingStreams) { + stream.add(data.sublist(1)); + } + } else { + print("unknown packet found"); + print("packet data: $data"); + } } Concept2CharacteristicData? _parsePacket(Uint8List data) { From e70f7e198192fe7f4a75c7b50fa0b2e607757782 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 21:33:04 -0400 Subject: [PATCH 037/220] define type for custom streamcontroller --- lib/models/c2datastreamcontroller.dart | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/models/c2datastreamcontroller.dart b/lib/models/c2datastreamcontroller.dart index bb95aef..0a90718 100644 --- a/lib/models/c2datastreamcontroller.dart +++ b/lib/models/c2datastreamcontroller.dart @@ -6,8 +6,8 @@ import 'dart:async'; /// - filtering of data sent to the `add` function so this stream can only send datapoints that it was created to send /// - caching of data in the event that users want a full set of data any time any value is updated /// and possibly more. -class C2DataStreamController implements StreamController { - StreamController _controller; +class C2DataStreamController implements StreamController> { + StreamController> _controller; /// A list of the identifying strings for datapoints that this controller should pass on as stream updates. Set datapoint_identifiers; @@ -49,14 +49,14 @@ class C2DataStreamController implements StreamController { void onPause()?, void onResume()?, FutureOr onCancel()?}) - : _controller = new StreamController( + : _controller = new StreamController>( onListen: onListen, onPause: onPause, onResume: onResume, onCancel: onCancel); @override - void add(T event) { + void add(Map event) { _controller.add(event); } @@ -66,7 +66,7 @@ class C2DataStreamController implements StreamController { } @override - Future addStream(Stream source, {bool? cancelOnError}) { + Future addStream(Stream> source, {bool? cancelOnError}) { return _controller.addStream(source, cancelOnError: cancelOnError); } @@ -88,8 +88,8 @@ class C2DataStreamController implements StreamController { bool get isPaused => _controller.isPaused; @override - StreamSink get sink => _controller.sink; + StreamSink> get sink => _controller.sink; @override - Stream get stream => _controller.stream; + Stream> get stream => _controller.stream; } From ee03d5e40b55416ba5c94d1067cf2cc802fa938e Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 21:43:44 -0400 Subject: [PATCH 038/220] apply filtering when adding values to the stream --- lib/models/c2datastreamcontroller.dart | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/models/c2datastreamcontroller.dart b/lib/models/c2datastreamcontroller.dart index 0a90718..67186ca 100644 --- a/lib/models/c2datastreamcontroller.dart +++ b/lib/models/c2datastreamcontroller.dart @@ -57,7 +57,13 @@ class C2DataStreamController implements StreamController> { @override void add(Map event) { - _controller.add(event); + //source: https://stackoverflow.com/a/21131220 + final filteredMap = new Map.fromIterable( + event.keys.where((k) => datapoint_identifiers.contains(k)), + value: (k) => event[k]); + if (filteredMap.length > 0) { + _controller.add(filteredMap); + } } @override From 5a4e24f4a419d4334a00c42c9e9044ab27035491 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 22:00:47 -0400 Subject: [PATCH 039/220] generate close listener/callback --- lib/src/dataplex.dart | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 07e6ab4..4192b1f 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -30,6 +30,8 @@ class Dataplex { C2DataStreamController controller = new C2DataStreamController(keysRequested); + controller.onCancel = _generateOutputCloseListener(controller); + //TODO: set up close listener. outgoingStreams.add(controller); @@ -37,6 +39,16 @@ class Dataplex { return controller.stream; } + /// Generate a function that removes the provided controller from the outgoing streams list + FutureOr Function()? _generateOutputCloseListener( + C2DataStreamController controller) { + FutureOr remove() { + outgoingStreams.remove(controller); + } + + return remove; + } + void _addSubscription( String serviceUuid, String characteristicUuid, int? dataIdentifier) { StreamSubscription sub = device From 6105ea3883153ed34e229c4663ac9f5286a92639 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 May 2022 22:01:02 -0400 Subject: [PATCH 040/220] add todo for converting packet to a map --- lib/src/dataplex.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 4192b1f..0c39a72 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -69,7 +69,8 @@ class Dataplex { if (packet != null) { //send the data to for (var stream in outgoingStreams) { - stream.add(data.sublist(1)); + // TODO: get packet as Map + // stream.add(packet); } } else { print("unknown packet found"); From 74fab4ea14f5e0ae3a2636588b4b1d2d14139663 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 16 May 2022 07:42:52 -0400 Subject: [PATCH 041/220] add maps to constants for mapping the different keys to the characteristics --- lib/constants.dart | 26 ++++++++++++++++++++++++++ test/constants_test.dart | 20 ++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 test/constants_test.dart diff --git a/lib/constants.dart b/lib/constants.dart index 683c343..6f0bbf9 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -38,3 +38,29 @@ const String C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC2_UUID = // CE060013-43E5-11E4-916C-0800200C9A66 //C2 hardware revision string characteristic // CE060014-43E5-11E4-916C-0800200C9A66 //C2 firmware revision string characteristic // CE060015-43E5-11E4-916C-0800200C9A66 //C2 manufacturer string characteristic + +const Map dataKeyToCharacteristicMap = { + "something.something": 0xAB, + "something.something.average": 0xAB +}; + +Map> getCharacteristicToDataKeysMap( + Map keyToCharacteristicMap) { + Map> out = Map(); + for (var entry in dataKeyToCharacteristicMap.entries) { + var key = entry.key; + var value = entry.value; + + var currentSet = out[value]; + + if (currentSet != null) { + currentSet.add(key); + } else { + out[value] = {key}; + } + } + return out; +} + +Map> characteristicToDataKeysMap = + getCharacteristicToDataKeysMap(dataKeyToCharacteristicMap); diff --git a/test/constants_test.dart b/test/constants_test.dart new file mode 100644 index 0000000..f162f69 --- /dev/null +++ b/test/constants_test.dart @@ -0,0 +1,20 @@ +import 'package:c2bluetooth/constants.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + Map dummyDataKeyToCharacteristicMap = { + "something.something": 0xAB, + "something.something.average": 0xAB + }; + + Map> dummySwappedMap = { + 0xAB: {"something.something", "something.something.average"} + }; + + group("getCharacteristicToDataKeysMap - ", () { + test("test returns expected value", () { + expect(getCharacteristicToDataKeysMap(dummyDataKeyToCharacteristicMap), + dummySwappedMap); + }); + }); +} From 7f1f8c02c262f820322eb0f4ecdfdcb88cf9cb34 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 18 May 2022 21:21:21 -0400 Subject: [PATCH 042/220] replace nonexistnet third packet with force curve data instead (thats what its for) --- lib/src/dataplex.dart | 3 ++- lib/src/packets/forcecurvepacket.dart | 10 ++++++++++ lib/src/packets/workoutsummary.dart | 4 ---- 3 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 lib/src/packets/forcecurvepacket.dart diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 0c39a72..a8cdee8 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -7,6 +7,7 @@ import './packets/statusdata.dart'; import './packets/strokedata.dart'; import './packets/segmentdata.dart'; import './packets/workoutsummary.dart'; +import './packets/forcecurvepacket.dart'; import 'packets/base.dart'; @@ -110,7 +111,7 @@ class Dataplex { case 0x3A: return WorkoutSummaryPacket2.fromBytes(data.sublist(1)); case 0x3C: - return WorkoutSummaryPacket3.fromBytes(data.sublist(1)); + return ForceCurveData.fromBytes(data.sublist(1)); default: return null; } diff --git a/lib/src/packets/forcecurvepacket.dart b/lib/src/packets/forcecurvepacket.dart new file mode 100644 index 0000000..cb7c447 --- /dev/null +++ b/lib/src/packets/forcecurvepacket.dart @@ -0,0 +1,10 @@ +import 'dart:typed_data'; +import './base.dart'; + +/// Represents a series of force curve data for a stroke +class ForceCurveData extends Concept2CharacteristicData { + List data; + + /// Construct a set of ForceCurveData from the bytes returned from the erg + ForceCurveData.fromBytes(Uint8List data) : this.data = data.toList(); +} diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index fbaa9a3..c430343 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -72,7 +72,3 @@ class WorkoutSummaryPacket2 extends TimestampedData { endian: Endian.little), super.fromBytes(data); } - -class WorkoutSummaryPacket3 extends TimestampedData { - WorkoutSummaryPacket3.fromBytes(Uint8List data) : super.fromBytes(data); -} From 8ba71756a55acb1c2594c9ff268b68dcbf907256 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 18 May 2022 21:23:19 -0400 Subject: [PATCH 043/220] remove IdempotentCompleter helper --- lib/helpers.dart | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/lib/helpers.dart b/lib/helpers.dart index 1ed7d9c..86109f9 100644 --- a/lib/helpers.dart +++ b/lib/helpers.dart @@ -91,17 +91,3 @@ String wattsToSplit(double watts) { var split = durationToSplit(Duration(milliseconds: millis)); return split; } - -extension IdempotentCompleter on Completer { - void completeIfNotAlready([FutureOr? value]) { - if (!this.isCompleted) { - this.complete(value); - } - } - - void completeErrorIfNotAlready(Object error, [StackTrace? stackTrace]) { - if (!this.isCompleted) { - this.completeError(error, stackTrace); - } - } -} From 567759107b31a00bcdfefe7b1861ce34cc102108 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 20 May 2022 21:27:14 -0400 Subject: [PATCH 044/220] return workout summary packets as maps --- lib/src/packets/workoutsummary.dart | 34 +++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index c430343..ee4d46b 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -43,6 +43,25 @@ class WorkoutSummaryPacket extends TimestampedData { endian: Endian.little) / 10, super.fromBytes(data); + + Map asMap() { + + return { + "workout.timestamp": timestamp, + // "workout.time": workTime, + // workDistance + "workout.stroke_rate.average": avgSPM, + "workout.heart_rate.last": endHeartRate, + "workout.heart_rate.average": avgHeartRate, + "workout.heart_rate.min": minHeartRate, + "workout.heart_rate.max": maxHeartRate, + "workout.pace.average": avgPace, + "workout.drag_factor.average": avgDragFactor, + "workout.heart_rate.recovery": recoveryHeartRate, + // workoutType, + // "something.something.average": + }; + } } class WorkoutSummaryPacket2 extends TimestampedData { @@ -71,4 +90,19 @@ class WorkoutSummaryPacket2 extends TimestampedData { avgCalories = CsafeIntExtension.fromBytes(data.sublist(17, 19), endian: Endian.little), super.fromBytes(data); + + Map asMap() { + return { + "workout.timestamp": timestamp, + + "workout.spl-int_count": intervalSize, + "workout.spl-int_size": intervalCount, + "workout.calories": totalCalories, + "workout.watts": watts, + "workout.rest_distance": totalRestDistance, + // "workout.interval_rest_distance": , + "workout.rest_time": intervalRestTime, + "workout.calories.average": avgCalories + }; + } } From 07d79beeafc0e1bf27b4f7b68c3c985f633b8801 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 20 May 2022 21:26:11 -0400 Subject: [PATCH 045/220] create unit test for parsing the CSV data --- lib/src/helpers.dart | 47 ++++++++ pubspec.yaml | 1 + test/dataparsing_test.dart | 75 ++++++++++++ test/test-multiplex-data6.csv | 221 ++++++++++++++++++++++++++++++++++ 4 files changed, 344 insertions(+) create mode 100644 lib/src/helpers.dart create mode 100644 test/dataparsing_test.dart create mode 100644 test/test-multiplex-data6.csv diff --git a/lib/src/helpers.dart b/lib/src/helpers.dart new file mode 100644 index 0000000..10fa9bc --- /dev/null +++ b/lib/src/helpers.dart @@ -0,0 +1,47 @@ +import 'dart:typed_data'; + +import './packets/statusdata.dart'; +import './packets/strokedata.dart'; +import './packets/segmentdata.dart'; +import './packets/workoutsummary.dart'; +import './packets/forcecurvepacket.dart'; + +import './packets/base.dart'; + +Concept2CharacteristicData? parsePacket(Uint8List data) { + switch (data[0]) { + case 0x31: + StatusData parsed = StatusData.fromBytes(data.sublist(1)); + print(parsed.elapsedTime.toString()); + print("distance ${parsed.distance.toString()}"); + + return parsed; + case 0x32: + StatusData1 parsed = StatusData1.fromBytes(data.sublist(1)); + print(parsed.elapsedTime.toString()); + print("speed ${parsed.speed.toString()}"); + + return parsed; + case 0x33: + StatusData2 parsed = StatusData2.fromBytes(data.sublist(1)); + print(parsed.elapsedTime.toString()); + // print("intervalcount ${parsed.intervalCount.toString()}"); + return parsed; + case 0x35: + return StrokeData.fromBytes(data.sublist(1)); + case 0x36: + return StrokeData2.fromBytes(data.sublist(1)); + case 0x37: + return SegmentData.fromBytes(data.sublist(1)); + case 0x38: + return SegmentData2.fromBytes(data.sublist(1)); + case 0x39: + return WorkoutSummaryPacket.fromBytes(data.sublist(1)); + case 0x3A: + return WorkoutSummaryPacket2.fromBytes(data.sublist(1)); + case 0x3C: + return ForceCurveData.fromBytes(data.sublist(1)); + default: + return null; + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 102e190..43cd2c2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,6 +17,7 @@ dependencies: rxdart: ^0.27.3 dev_dependencies: + csv: ^5.0.1 flutter_test: sdk: flutter diff --git a/test/dataparsing_test.dart b/test/dataparsing_test.dart new file mode 100644 index 0000000..5acff3f --- /dev/null +++ b/test/dataparsing_test.dart @@ -0,0 +1,75 @@ +import 'dart:typed_data'; +import 'dart:convert'; +import 'dart:io'; + +import '../lib/src/packets/statusdata.dart'; +import '../lib/src/packets/strokedata.dart'; +import '../lib/src/packets/segmentdata.dart'; +import '../lib/src/packets/workoutsummary.dart'; +import '../lib/src/packets/forcecurvepacket.dart'; + +import '../lib/src/packets/base.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:csv/csv.dart'; +// import '../lib/src/helpers.dart'; +// import '../lib/models/ergblemanager.dart'; + +void main() { + group("test-multiplex-data6", () { + test('- print', () async { + final input = new File('./test/test-multiplex-data6.csv').openRead(); + final fields = await input + .transform(utf8.decoder) + .transform(new CsvToListConverter(eol: '\n')) + .toList(); + // print(fields); + + for (List row in fields) { + List ints = row.cast(); + Uint8List data = Uint8List.fromList(ints); + print(parsePacket(data)); + } + }); + }); +} + +Concept2CharacteristicData? parsePacket(Uint8List data) { + switch (data[0]) { + case 0x31: + StatusData parsed = StatusData.fromBytes(data.sublist(1)); + print("elapsed time :${parsed.elapsedTime.toString()}"); + print("distance ${parsed.distance.toString()}"); + + return parsed; + case 0x32: + StatusData1 parsed = StatusData1.fromBytes(data.sublist(1)); + print("elapsed time :${parsed.elapsedTime.toString()}"); + print("speed ${parsed.speed.toString()}"); + + return parsed; + case 0x33: + StatusData2 parsed = StatusData2.fromBytes(data.sublist(1)); + print("elapsed time :${parsed.elapsedTime.toString()}"); + // print("intervalcount ${parsed.intervalCount.toString()}"); + return parsed; + case 0x35: + return StrokeData.fromBytes(data.sublist(1)); + case 0x36: + return StrokeData2.fromBytes(data.sublist(1)); + case 0x37: + return SegmentData.fromBytes(data.sublist(1)); + case 0x38: + var parsed = SegmentData2.fromBytes(data.sublist(1)); + print("elapsed time :${parsed.elapsedTime.toString()}"); + + return parsed; + case 0x39: + return WorkoutSummaryPacket.fromBytes(data.sublist(1)); + case 0x3A: + return WorkoutSummaryPacket2.fromBytes(data.sublist(1)); + case 0x3C: + return ForceCurveData.fromBytes(data.sublist(1)); + default: + return null; + } +} diff --git a/test/test-multiplex-data6.csv b/test/test-multiplex-data6.csv new file mode 100644 index 0000000..881f8a6 --- /dev/null +++ b/test/test-multiplex-data6.csv @@ -0,0 +1,221 @@ +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +49, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 127, 0, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 127, 0, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 127, 0, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 176, 0, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 176, 0, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 176, 0, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 225, 0, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 225, 0, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 225, 0, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 19, 1, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 19, 1, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 19, 1, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 68, 1, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 68, 1, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 68, 1, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 118, 1, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 118, 1, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 118, 1, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 167, 1, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 167, 1, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 167, 1, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +53, 205, 1, 0, 111, 0, 0, 106, 108, 69, 1, 2, 1, 165, 2, 196, 1, 1, 0 +51, 220, 1, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 220, 1, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 15, 2, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 15, 2, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 15, 2, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 64, 2, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 64, 2, 0, 0, 0, 0, 72, 82, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 +54, 95, 2, 0, 41, 0, 183, 1, 2, 0, 0, 0, 0, 48, 0, 0, 172, 7 +54, 95, 2, 0, 41, 0, 183, 1, 2, 0, 0, 0, 0, 48, 0, 0, 172, 7 +51, 115, 2, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 115, 2, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 163, 2, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 163, 2, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 163, 2, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 215, 2, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 215, 2, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 215, 2, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 7, 3, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 7, 3, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 7, 3, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +50, 57, 3, 0, 132, 9, 12, 255, 87, 80, 139, 80, 0, 0, 0, 0, 0, 40, 0, 0 +51, 57, 3, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 57, 3, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 57, 3, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 105, 3, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 105, 3, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 156, 3, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 156, 3, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 156, 3, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 208, 3, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 208, 3, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 208, 3, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 2, 4, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 2, 4, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 2, 4, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 50, 4, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 50, 4, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 50, 4, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 99, 4, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 99, 4, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 99, 4, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 150, 4, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 150, 4, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +51, 150, 4, 0, 0, 0, 0, 139, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0 +49, 200, 4, 0, 15, 1, 0, 5, 0, 1, 0, 1, 0, 0, 0, 208, 7, 0, 0, 124 +51, 200, 4, 0, 0, 1, 0, 64, 88, 30, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 200, 4, 0, 0, 1, 0, 64, 88, 30, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 250, 4, 0, 0, 1, 0, 64, 88, 30, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 250, 4, 0, 0, 1, 0, 64, 88, 30, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 250, 4, 0, 0, 1, 0, 64, 88, 30, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 44, 5, 0, 0, 1, 0, 64, 88, 30, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 44, 5, 0, 0, 1, 0, 64, 88, 30, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 44, 5, 0, 0, 1, 0, 64, 88, 30, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 97, 5, 0, 0, 1, 0, 64, 88, 30, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 97, 5, 0, 0, 1, 0, 64, 88, 30, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 97, 5, 0, 0, 1, 0, 64, 88, 30, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 148, 5, 0, 0, 1, 0, 64, 88, 30, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 148, 5, 0, 0, 1, 0, 64, 88, 30, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 148, 5, 0, 0, 1, 0, 64, 88, 30, 0, 1, 0, 0, 0, 0, 27, 0, 0 +54, 199, 5, 0, 23, 0, 122, 1, 3, 0, 0, 0, 0, 40, 0, 0, 22, 1 +54, 199, 5, 0, 23, 0, 122, 1, 3, 0, 0, 0, 0, 40, 0, 0, 22, 1 +54, 199, 5, 0, 23, 0, 122, 1, 3, 0, 0, 0, 0, 40, 0, 0, 22, 1 +51, 247, 5, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 247, 5, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 247, 5, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 42, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 42, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 42, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 42, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 90, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 90, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 140, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 140, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 140, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 188, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 188, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 188, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 241, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 241, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 241, 6, 0, 0, 1, 0, 198, 96, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +54, 46, 7, 0, 22, 0, 118, 1, 4, 0, 0, 0, 0, 40, 0, 0, 6, 3 +54, 46, 7, 0, 22, 0, 118, 1, 4, 0, 0, 0, 0, 40, 0, 0, 6, 3 +51, 85, 7, 0, 0, 1, 0, 43, 97, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 85, 7, 0, 0, 1, 0, 43, 97, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 85, 7, 0, 0, 1, 0, 43, 97, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 133, 7, 0, 0, 1, 0, 43, 97, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 133, 7, 0, 0, 1, 0, 43, 97, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 133, 7, 0, 0, 1, 0, 43, 97, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 133, 7, 0, 0, 1, 0, 43, 97, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +51, 182, 7, 0, 0, 1, 0, 43, 97, 23, 0, 1, 0, 0, 0, 0, 27, 0, 0 +56, 208, 7, 0, 12, 0, 0, 196, 9, 2, 0, 121, 1, 208, 7, 22, 0, 122, 1, 0 +56, 208, 7, 0, 12, 0, 0, 196, 9, 2, 0, 121, 1, 208, 7, 22, 0, 122, 1, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +60, 133, 44, 14, 14, 4, 10, 0, 0, 0, 0 +60, 133, 44, 14, 14, 4, 10, 0, 0, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +50, 208, 7, 0, 184, 7, 17, 255, 255, 98, 237, 97, 0, 0, 0, 0, 0, 22, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +49, 208, 7, 0, 142, 1, 0, 5, 0, 12, 0, 1, 0, 0, 0, 208, 7, 0, 0, 120 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 +51, 208, 7, 0, 1, 2, 0, 237, 97, 22, 0, 2, 0, 0, 0, 0, 40, 0, 0 \ No newline at end of file From adf00a5775bbf50d02556a9910e2ee62c4c4ccfb Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 22 May 2022 12:30:49 -0400 Subject: [PATCH 046/220] use packet parsing/identifying function in helpers --- lib/src/dataplex.dart | 41 ++--------------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index a8cdee8..d35ce4e 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -9,6 +9,7 @@ import './packets/segmentdata.dart'; import './packets/workoutsummary.dart'; import './packets/forcecurvepacket.dart'; +import 'helpers.dart'; import 'packets/base.dart'; /// Handles mapping between data coming from bluetooth notfications and the data the user requested. @@ -65,7 +66,7 @@ class Dataplex { } void _readPacket(Uint8List data) { - Concept2CharacteristicData? packet = _parsePacket(data); + Concept2CharacteristicData? packet = parsePacket(data); if (packet != null) { //send the data to @@ -79,44 +80,6 @@ class Dataplex { } } - Concept2CharacteristicData? _parsePacket(Uint8List data) { - switch (data[0]) { - case 0x31: - StatusData parsed = StatusData.fromBytes(data.sublist(1)); - print(parsed.elapsedTime.toString()); - print("distance ${parsed.distance.toString()}"); - - return parsed; - case 0x32: - StatusData1 parsed = StatusData1.fromBytes(data.sublist(1)); - print(parsed.elapsedTime.toString()); - print("speed ${parsed.speed.toString()}"); - - return parsed; - case 0x33: - StatusData2 parsed = StatusData2.fromBytes(data.sublist(1)); - print(parsed.elapsedTime.toString()); - // print("intervalcount ${parsed.intervalCount.toString()}"); - return parsed; - case 0x35: - return StrokeData.fromBytes(data.sublist(1)); - case 0x36: - return StrokeData2.fromBytes(data.sublist(1)); - case 0x37: - return SegmentData.fromBytes(data.sublist(1)); - case 0x38: - return SegmentData2.fromBytes(data.sublist(1)); - case 0x39: - return WorkoutSummaryPacket.fromBytes(data.sublist(1)); - case 0x3A: - return WorkoutSummaryPacket2.fromBytes(data.sublist(1)); - case 0x3C: - return ForceCurveData.fromBytes(data.sublist(1)); - default: - return null; - } - } - void dispose() { // clear current subscriptions for (var entry in currentSubscriptions.entries) { From 7ae43f520e5892f118703ae030d617ae72401289 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 22 May 2022 12:40:07 -0400 Subject: [PATCH 047/220] refactor CSV retrieval into function --- test/dataparsing_test.dart | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/test/dataparsing_test.dart b/test/dataparsing_test.dart index 5acff3f..8f8c613 100644 --- a/test/dataparsing_test.dart +++ b/test/dataparsing_test.dart @@ -14,16 +14,22 @@ import 'package:csv/csv.dart'; // import '../lib/src/helpers.dart'; // import '../lib/models/ergblemanager.dart'; +Future> getCsvData(String filename) async { + final input = new File(filename).openRead(); + final fields = await input + .transform(utf8.decoder) + .transform(new CsvToListConverter(eol: '\n')) + .toList(); + return fields; +} + void main() { group("test-multiplex-data6", () { test('- print', () async { - final input = new File('./test/test-multiplex-data6.csv').openRead(); - final fields = await input - .transform(utf8.decoder) - .transform(new CsvToListConverter(eol: '\n')) - .toList(); // print(fields); + final fields = await getCsvData('./test/test-multiplex-data6.csv'); + for (List row in fields) { List ints = row.cast(); Uint8List data = Uint8List.fromList(ints); From fbf1694a640a2671b8206561fd8c3f887aa3ad22 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 22 May 2022 13:10:43 -0400 Subject: [PATCH 048/220] rename DurationStampedDate -> ElapsedTimeStampedData --- lib/src/packets/base.dart | 7 +++---- lib/src/packets/statusdata.dart | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/src/packets/base.dart b/lib/src/packets/base.dart index fe85b46..cd11618 100644 --- a/lib/src/packets/base.dart +++ b/lib/src/packets/base.dart @@ -12,11 +12,10 @@ class TimestampedData extends Concept2CharacteristicData { : timestamp = Concept2DateExtension.fromBytes(bytes.sublist(0, 4)); } -///Represents a data packet from Concept2 that is stamped with a duration. - -class DurationstampedData extends Concept2CharacteristicData { +///Represents a data packet from Concept2 that begins with the current elapsed time +class ElapsedtimeStampedData extends Concept2CharacteristicData { Duration elapsedTime; - DurationstampedData.fromBytes(Uint8List data) + ElapsedtimeStampedData.fromBytes(Uint8List data) : elapsedTime = Concept2DurationExtension.fromBytes(data.sublist(0, 3)); } diff --git a/lib/src/packets/statusdata.dart b/lib/src/packets/statusdata.dart index 813cbdc..86984db 100644 --- a/lib/src/packets/statusdata.dart +++ b/lib/src/packets/statusdata.dart @@ -4,7 +4,7 @@ import 'package:csafe_fitness/csafe_fitness.dart'; import './base.dart'; -class StatusData extends DurationstampedData { +class StatusData extends ElapsedtimeStampedData { double distance; StatusData.fromBytes(Uint8List data) @@ -16,7 +16,7 @@ class StatusData extends DurationstampedData { //TODO: add more data fields here } -class StatusData1 extends DurationstampedData { +class StatusData1 extends ElapsedtimeStampedData { double speed; StatusData1.fromBytes(Uint8List data) @@ -27,7 +27,7 @@ class StatusData1 extends DurationstampedData { //TODO: add more data fields here } -class StatusData2 extends DurationstampedData { +class StatusData2 extends ElapsedtimeStampedData { int intervalCount; StatusData2.fromBytes(Uint8List data) From 119bcc411fc0a6b42b9ee5ed901dfaa28f93b7f3 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 22 May 2022 13:11:03 -0400 Subject: [PATCH 049/220] remove printing from parsing helper --- lib/src/helpers.dart | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/lib/src/helpers.dart b/lib/src/helpers.dart index 10fa9bc..882ad1b 100644 --- a/lib/src/helpers.dart +++ b/lib/src/helpers.dart @@ -11,22 +11,11 @@ import './packets/base.dart'; Concept2CharacteristicData? parsePacket(Uint8List data) { switch (data[0]) { case 0x31: - StatusData parsed = StatusData.fromBytes(data.sublist(1)); - print(parsed.elapsedTime.toString()); - print("distance ${parsed.distance.toString()}"); - - return parsed; + return StatusData.fromBytes(data.sublist(1)); case 0x32: - StatusData1 parsed = StatusData1.fromBytes(data.sublist(1)); - print(parsed.elapsedTime.toString()); - print("speed ${parsed.speed.toString()}"); - - return parsed; + return StatusData1.fromBytes(data.sublist(1)); case 0x33: - StatusData2 parsed = StatusData2.fromBytes(data.sublist(1)); - print(parsed.elapsedTime.toString()); - // print("intervalcount ${parsed.intervalCount.toString()}"); - return parsed; + return StatusData2.fromBytes(data.sublist(1)); case 0x35: return StrokeData.fromBytes(data.sublist(1)); case 0x36: From cb11f79f086ce1270e12334ebdfc6e3bda0ed0c1 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 22 May 2022 13:11:34 -0400 Subject: [PATCH 050/220] use central parsing helper and separate printing --- test/dataparsing_test.dart | 57 ++++++++++---------------------------- 1 file changed, 15 insertions(+), 42 deletions(-) diff --git a/test/dataparsing_test.dart b/test/dataparsing_test.dart index 8f8c613..aefd213 100644 --- a/test/dataparsing_test.dart +++ b/test/dataparsing_test.dart @@ -9,6 +9,7 @@ import '../lib/src/packets/workoutsummary.dart'; import '../lib/src/packets/forcecurvepacket.dart'; import '../lib/src/packets/base.dart'; +import '../lib/src/helpers.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:csv/csv.dart'; // import '../lib/src/helpers.dart'; @@ -33,49 +34,21 @@ void main() { for (List row in fields) { List ints = row.cast(); Uint8List data = Uint8List.fromList(ints); - print(parsePacket(data)); + Concept2CharacteristicData? packet = parsePacket(data); + if (packet != null) { + if (packet is ElapsedtimeStampedData) { + print("elapsed time :${packet.elapsedTime.toString()}"); + } + + if (packet is StatusData1) { + print("speed ${packet.speed.toString()}"); + } + + if (packet is StatusData2) { + print("intervalcount ${packet.intervalCount.toString()}"); + } + } } }); }); } - -Concept2CharacteristicData? parsePacket(Uint8List data) { - switch (data[0]) { - case 0x31: - StatusData parsed = StatusData.fromBytes(data.sublist(1)); - print("elapsed time :${parsed.elapsedTime.toString()}"); - print("distance ${parsed.distance.toString()}"); - - return parsed; - case 0x32: - StatusData1 parsed = StatusData1.fromBytes(data.sublist(1)); - print("elapsed time :${parsed.elapsedTime.toString()}"); - print("speed ${parsed.speed.toString()}"); - - return parsed; - case 0x33: - StatusData2 parsed = StatusData2.fromBytes(data.sublist(1)); - print("elapsed time :${parsed.elapsedTime.toString()}"); - // print("intervalcount ${parsed.intervalCount.toString()}"); - return parsed; - case 0x35: - return StrokeData.fromBytes(data.sublist(1)); - case 0x36: - return StrokeData2.fromBytes(data.sublist(1)); - case 0x37: - return SegmentData.fromBytes(data.sublist(1)); - case 0x38: - var parsed = SegmentData2.fromBytes(data.sublist(1)); - print("elapsed time :${parsed.elapsedTime.toString()}"); - - return parsed; - case 0x39: - return WorkoutSummaryPacket.fromBytes(data.sublist(1)); - case 0x3A: - return WorkoutSummaryPacket2.fromBytes(data.sublist(1)); - case 0x3C: - return ForceCurveData.fromBytes(data.sublist(1)); - default: - return null; - } -} From 04d9906f886669070c0001b671abd0731f8ed11e Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 22 May 2022 13:23:42 -0400 Subject: [PATCH 051/220] parse elapsedTime from more packets --- lib/src/packets/segmentdata.dart | 14 +++++++++++--- lib/src/packets/strokedata.dart | 4 ++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/src/packets/segmentdata.dart b/lib/src/packets/segmentdata.dart index 26d25d5..10ceb4b 100644 --- a/lib/src/packets/segmentdata.dart +++ b/lib/src/packets/segmentdata.dart @@ -1,10 +1,18 @@ import 'dart:typed_data'; -import 'package:c2bluetooth/src/packets/base.dart'; +import 'package:csafe_fitness/csafe_fitness.dart'; -class SegmentData extends TimestampedData { +import './base.dart'; + +/// Represents a packet containing data for a "Segment" of a workout. +/// +/// Segment refers to the concept of "split or interval" from Concept2's specification since the two are mutually exclusive +class SegmentData extends ElapsedtimeStampedData { SegmentData.fromBytes(Uint8List data) : super.fromBytes(data); } -class SegmentData2 extends TimestampedData { +/// Represents a packet containing data for a "Segment" of a workout. +/// +/// Segment refers to the concept of "split or interval" from Concept2's specification since the two are mutually exclusive +class SegmentData2 extends ElapsedtimeStampedData { SegmentData2.fromBytes(Uint8List data) : super.fromBytes(data); } diff --git a/lib/src/packets/strokedata.dart b/lib/src/packets/strokedata.dart index 4268cbc..7023c83 100644 --- a/lib/src/packets/strokedata.dart +++ b/lib/src/packets/strokedata.dart @@ -2,7 +2,7 @@ import 'dart:typed_data'; import './base.dart'; -class StrokeData extends TimestampedData { +class StrokeData extends ElapsedtimeStampedData { StrokeData.fromBytes(Uint8List data) : super.fromBytes(data) { // _workTime.completeIfNotAlready( // CsafeIntExtension.fromBytes(data.sublist(4, 7), endian: Endian.little) / @@ -32,6 +32,6 @@ class StrokeData extends TimestampedData { } } -class StrokeData2 extends TimestampedData { +class StrokeData2 extends ElapsedtimeStampedData { StrokeData2.fromBytes(Uint8List data) : super.fromBytes(data); } From 4d188e7e3b260f1302feba800da9ce265f838659 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 22 May 2022 13:48:07 -0400 Subject: [PATCH 052/220] parse more datapoints out of segmentData --- lib/src/packets/segmentdata.dart | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/src/packets/segmentdata.dart b/lib/src/packets/segmentdata.dart index 10ceb4b..d2fcd10 100644 --- a/lib/src/packets/segmentdata.dart +++ b/lib/src/packets/segmentdata.dart @@ -7,7 +7,26 @@ import './base.dart'; /// /// Segment refers to the concept of "split or interval" from Concept2's specification since the two are mutually exclusive class SegmentData extends ElapsedtimeStampedData { - SegmentData.fromBytes(Uint8List data) : super.fromBytes(data); + double distance; + // double segmentTime; + int segmentDistance; + int segmentRestTime; + int segmentRestDistance; + int segmentNumber; + + SegmentData.fromBytes(Uint8List data) + : distance = CsafeIntExtension.fromBytes(data.sublist(3, 6), + endian: Endian.little) / + 10, + // segmentTime = 6,9, + segmentDistance = CsafeIntExtension.fromBytes(data.sublist(9, 12), + endian: Endian.little), + segmentRestDistance = CsafeIntExtension.fromBytes(data.sublist(12, 14), + endian: Endian.little), + segmentRestTime = CsafeIntExtension.fromBytes(data.sublist(14, 16), + endian: Endian.little), + segmentNumber = data.elementAt(18), + super.fromBytes(data); } /// Represents a packet containing data for a "Segment" of a workout. From 731297594fd053db440e784e7a5499b0578217bd Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 22 May 2022 14:01:02 -0400 Subject: [PATCH 053/220] refactor segment data to pull out a shared data field for segment Number --- lib/src/helpers.dart | 2 +- lib/src/packets/segmentdata.dart | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/src/helpers.dart b/lib/src/helpers.dart index 882ad1b..bd856d7 100644 --- a/lib/src/helpers.dart +++ b/lib/src/helpers.dart @@ -21,7 +21,7 @@ Concept2CharacteristicData? parsePacket(Uint8List data) { case 0x36: return StrokeData2.fromBytes(data.sublist(1)); case 0x37: - return SegmentData.fromBytes(data.sublist(1)); + return SegmentData1.fromBytes(data.sublist(1)); case 0x38: return SegmentData2.fromBytes(data.sublist(1)); case 0x39: diff --git a/lib/src/packets/segmentdata.dart b/lib/src/packets/segmentdata.dart index d2fcd10..09d7825 100644 --- a/lib/src/packets/segmentdata.dart +++ b/lib/src/packets/segmentdata.dart @@ -5,16 +5,25 @@ import './base.dart'; /// Represents a packet containing data for a "Segment" of a workout. /// -/// Segment refers to the concept of "split or interval" from Concept2's specification since the two are mutually exclusive +/// Segment refers to the concept of "split or interval" from Concept2's specification since the two are mutually exclusive. +/// +/// Both segment data packets seem to start with the elapsed time have the [segmentNumber] stored at byte 18, so this class abstracts those two fields class SegmentData extends ElapsedtimeStampedData { + int segmentNumber; + SegmentData.fromBytes(Uint8List data) + : segmentNumber = data.elementAt(18), + super.fromBytes(data); +} + +/// Represents the first kind of [SegmentData] packet containing part of the full set of data about a segment of a workout +class SegmentData1 extends SegmentData { double distance; // double segmentTime; int segmentDistance; int segmentRestTime; int segmentRestDistance; - int segmentNumber; - SegmentData.fromBytes(Uint8List data) + SegmentData1.fromBytes(Uint8List data) : distance = CsafeIntExtension.fromBytes(data.sublist(3, 6), endian: Endian.little) / 10, @@ -25,13 +34,10 @@ class SegmentData extends ElapsedtimeStampedData { endian: Endian.little), segmentRestTime = CsafeIntExtension.fromBytes(data.sublist(14, 16), endian: Endian.little), - segmentNumber = data.elementAt(18), super.fromBytes(data); } -/// Represents a packet containing data for a "Segment" of a workout. -/// -/// Segment refers to the concept of "split or interval" from Concept2's specification since the two are mutually exclusive -class SegmentData2 extends ElapsedtimeStampedData { +/// Represents the second kind of [SegmentData] packet containing the remaining part of the full set of data about a segment of a workout +class SegmentData2 extends SegmentData { SegmentData2.fromBytes(Uint8List data) : super.fromBytes(data); } From 38803d56edb83de77a5806ec65f56638e0f277d9 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 25 May 2022 18:50:23 -0400 Subject: [PATCH 054/220] its called elapsed time in the spec i think --- lib/src/packets/workoutsummary.dart | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index ee4d46b..d178d93 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -1,6 +1,7 @@ import 'dart:typed_data'; import 'dart:async'; +import 'package:c2bluetooth/extensions.dart'; import 'package:csafe_fitness/csafe_fitness.dart'; import 'package:c2bluetooth/helpers.dart'; @@ -11,7 +12,7 @@ import './base.dart'; /// /// This takes care of processesing the raw byte data from workout summary characteristics into easily accessible fields. This class also takes care of things like byte endianness, combining multiple high and low bytes .etc, allowing applications to access things in terms of flutter native types. class WorkoutSummaryPacket extends TimestampedData { - double workTime; + Duration elapsedTime; double workDistance; int avgSPM; int endHeartRate; @@ -25,9 +26,7 @@ class WorkoutSummaryPacket extends TimestampedData { /// Construct a WorkoutSummary from the bytes returned from the erg WorkoutSummaryPacket.fromBytes(Uint8List data) - : workTime = CsafeIntExtension.fromBytes(data.sublist(4, 7), - endian: Endian.little) / - 100, //divide by 100 to convert to seconds + : elapsedTime = Concept2DurationExtension.fromBytes(data.sublist(4, 7)), workDistance = CsafeIntExtension.fromBytes(data.sublist(7, 10), endian: Endian.little) / 10, From 919a3d9761c3f71f00fad677d26794d3c5bd3691 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 4 Jun 2022 11:19:53 -0400 Subject: [PATCH 055/220] move datatypes test to new folder --- test/{internal => src}/datatypes_test.dart | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{internal => src}/datatypes_test.dart (100%) diff --git a/test/internal/datatypes_test.dart b/test/src/datatypes_test.dart similarity index 100% rename from test/internal/datatypes_test.dart rename to test/src/datatypes_test.dart From 71948421927be500a0285f8f3b074d5171017c8f Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 4 Jun 2022 11:47:31 -0400 Subject: [PATCH 056/220] start adding data keys to a constants file --- lib/src/packets/keys.dart | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 lib/src/packets/keys.dart diff --git a/lib/src/packets/keys.dart b/lib/src/packets/keys.dart new file mode 100644 index 0000000..60310a3 --- /dev/null +++ b/lib/src/packets/keys.dart @@ -0,0 +1,20 @@ +const ELAPSED_TIME_KEY = "workout.timestamp"; + +const WORKOUT_TIMESTAMP_KEY = "workout.timestamp"; +const WORKOUT_AVG_SPM_KEY = "workout.stroke_rate.average"; +const WORKOUT_LAST_HR_KEY = "workout.heart_rate.last"; +const WORKOUT_AVG_HR_KEY = "workout.heart_rate.average"; +const WORKOUT_MIN_HR_KEY = "workout.heart_rate.min"; +const WORKOUT_MAX_HR_KEY = "workout.heart_rate.max"; +const WORKOUT_AVG_PACE_KEY = "workout.pace.average"; +const WORKOUT_AVG_DRAGFACTOR_KEY = "workout.drag_factor.average"; +const WORKOUT_RECOVERY_HR_KEY = "workout.heart_rate.recovery"; + +const WORKOUT_SEGMENT_COUNT_KEY = "workout.segment_count"; +const WORKOUT_SEGMENT_SIZE_KEY = "workout.segment_size"; +const WORKOUT_CALORIES_KEY = "workout.calories"; +const WORKOUT_WATTS_KEY = "workout.watts"; +// rests are only applicable for intervals workouts +const WORKOUT_REST_DISTANCE_KEY = "workout.rest_distance"; +const WORKOUT_REST_TIME_KEY = "workout.rest_time"; +const WORKOUT_AVG_CALORIES_KEY = "workout.calories.average"; From 4740e1d8482880ad68961188af418d246a980197 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 4 Jun 2022 11:48:43 -0400 Subject: [PATCH 057/220] start implementing asMap() for WorkoutSummaries --- lib/src/packets/base.dart | 20 +++++++++- lib/src/packets/workoutsummary.dart | 59 ++++++++++++++++++----------- 2 files changed, 56 insertions(+), 23 deletions(-) diff --git a/lib/src/packets/base.dart b/lib/src/packets/base.dart index cd11618..05f9a0e 100644 --- a/lib/src/packets/base.dart +++ b/lib/src/packets/base.dart @@ -1,8 +1,14 @@ import 'dart:typed_data'; import 'package:c2bluetooth/extensions.dart'; +import 'keys.dart' as Keys; + /// An empty superclass to represent all types of data formats that come from Concept2 bluetooth characteristics -class Concept2CharacteristicData {} +class Concept2CharacteristicData { + Map asMap() { + return {}; + } +} ///Represents a data packet from Concept2 that is stamped with a date. class TimestampedData extends Concept2CharacteristicData { @@ -10,6 +16,12 @@ class TimestampedData extends Concept2CharacteristicData { TimestampedData.fromBytes(Uint8List bytes) : timestamp = Concept2DateExtension.fromBytes(bytes.sublist(0, 4)); + + Map asMap() { + Map map = super.asMap(); + map.addAll({Keys.WORKOUT_TIMESTAMP_KEY: timestamp}); + return map; + } } ///Represents a data packet from Concept2 that begins with the current elapsed time @@ -18,4 +30,10 @@ class ElapsedtimeStampedData extends Concept2CharacteristicData { ElapsedtimeStampedData.fromBytes(Uint8List data) : elapsedTime = Concept2DurationExtension.fromBytes(data.sublist(0, 3)); + + Map asMap() { + Map map = super.asMap(); + map.addAll({Keys.ELAPSED_TIME_KEY: elapsedTime}); + return map; + } } diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index d178d93..be6d97e 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -7,6 +7,7 @@ import 'package:csafe_fitness/csafe_fitness.dart'; import 'package:c2bluetooth/helpers.dart'; import 'package:c2bluetooth/enums.dart'; import './base.dart'; +import 'keys.dart' as Keys; /// Represents a summary of a completed workout /// @@ -44,22 +45,34 @@ class WorkoutSummaryPacket extends TimestampedData { super.fromBytes(data); Map asMap() { + // workout.date + // workout.time - return { - "workout.timestamp": timestamp, + // workout.heart_rate + // workout.spl-int_count + // workout.spl-int_size + // workout.calories + // workout.watts + // workout.rest_distance + // workout.interval_rest_distance + // workout.rest_time + // workout.calories.average + Map map = super.asMap(); + map.addAll({ // "workout.time": workTime, // workDistance - "workout.stroke_rate.average": avgSPM, - "workout.heart_rate.last": endHeartRate, - "workout.heart_rate.average": avgHeartRate, - "workout.heart_rate.min": minHeartRate, - "workout.heart_rate.max": maxHeartRate, - "workout.pace.average": avgPace, - "workout.drag_factor.average": avgDragFactor, - "workout.heart_rate.recovery": recoveryHeartRate, + Keys.WORKOUT_AVG_SPM_KEY: avgSPM, + Keys.WORKOUT_LAST_HR_KEY: endHeartRate, + Keys.WORKOUT_AVG_HR_KEY: avgHeartRate, + Keys.WORKOUT_MIN_HR_KEY: minHeartRate, + Keys.WORKOUT_MAX_HR_KEY: maxHeartRate, + Keys.WORKOUT_AVG_PACE_KEY: avgPace, + Keys.WORKOUT_AVG_DRAGFACTOR_KEY: avgDragFactor, + Keys.WORKOUT_RECOVERY_HR_KEY: recoveryHeartRate, // workoutType, // "something.something.average": - }; + }); + return map; } } @@ -91,17 +104,19 @@ class WorkoutSummaryPacket2 extends TimestampedData { super.fromBytes(data); Map asMap() { - return { - "workout.timestamp": timestamp, - - "workout.spl-int_count": intervalSize, - "workout.spl-int_size": intervalCount, - "workout.calories": totalCalories, - "workout.watts": watts, - "workout.rest_distance": totalRestDistance, + // workout.heart_rate + // workout.interval_rest_distance + Map map = super.asMap(); + map.addAll({ + Keys.WORKOUT_SEGMENT_COUNT_KEY: intervalSize, + Keys.WORKOUT_SEGMENT_SIZE_KEY: intervalCount, + Keys.WORKOUT_CALORIES_KEY: totalCalories, + Keys.WORKOUT_WATTS_KEY: watts, + Keys.WORKOUT_REST_DISTANCE_KEY: totalRestDistance, // "workout.interval_rest_distance": , - "workout.rest_time": intervalRestTime, - "workout.calories.average": avgCalories - }; + Keys.WORKOUT_REST_TIME_KEY: intervalRestTime, + Keys.WORKOUT_AVG_CALORIES_KEY: avgCalories + }); + return map; } } From eccf9a745496c5f504572ad52fdb00154a05696e Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 8 Jun 2022 17:54:24 -0400 Subject: [PATCH 058/220] send data to outgoing streams --- lib/src/dataplex.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index d35ce4e..9bc7b6d 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -69,10 +69,9 @@ class Dataplex { Concept2CharacteristicData? packet = parsePacket(data); if (packet != null) { - //send the data to + //send the data to the outgoing streams for (var stream in outgoingStreams) { - // TODO: get packet as Map - // stream.add(packet); + stream.add(packet.asMap()); } } else { print("unknown packet found"); From b89c436e3f6f17bf5305db419af5ca0bd295c007 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 8 Jun 2022 18:21:44 -0400 Subject: [PATCH 059/220] add basic map of characteristics to packets --- lib/src/dataplex.dart | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 9bc7b6d..e509620 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -23,6 +23,13 @@ class Dataplex { Map currentSubscriptions = Map(); + Map characteristicToPacketMap = { + Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC_UUID: + WorkoutSummaryPacket, + Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC2_UUID: + WorkoutSummaryPacket2, + }; + Dataplex(this.device); ///Keeps track of how many characteristics we are currently receiving notifications for From 97fe1d2e0437379527109a52c4cf4144feae661a Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 8 Jun 2022 18:22:48 -0400 Subject: [PATCH 060/220] add some docs and tweak error messages --- lib/src/dataplex.dart | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index e509620..fa74936 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -35,14 +35,14 @@ class Dataplex { ///Keeps track of how many characteristics we are currently receiving notifications for int _currentSubscriptionCount = 0; + /// Create and return a new stream that provides the requested data Stream> createStream(Set keysRequested) { C2DataStreamController controller = new C2DataStreamController(keysRequested); + //set up close listener. controller.onCancel = _generateOutputCloseListener(controller); - //TODO: set up close listener. - outgoingStreams.add(controller); return controller.stream; @@ -58,6 +58,7 @@ class Dataplex { return remove; } + /// set up a new subscription to data from an erg. void _addSubscription( String serviceUuid, String characteristicUuid, int? dataIdentifier) { StreamSubscription sub = device @@ -72,6 +73,7 @@ class Dataplex { currentSubscriptions.addEntries({characteristicUuid: sub}.entries); } + /// Read a packet from an incoming stream (from the erg) and redistribute it to all outgoing streams void _readPacket(Uint8List data) { Concept2CharacteristicData? packet = parsePacket(data); @@ -81,11 +83,12 @@ class Dataplex { stream.add(packet.asMap()); } } else { - print("unknown packet found"); + print("Couldnt parse packet from data"); print("packet data: $data"); } } + /// closes down this instance by cancelling all streams void dispose() { // clear current subscriptions for (var entry in currentSubscriptions.entries) { From 23af539a9f8d39d3cdc767aa631af7dfd6cabc0d Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 8 Jun 2022 18:23:09 -0400 Subject: [PATCH 061/220] add stub for stream validation function --- lib/src/dataplex.dart | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index fa74936..83cc286 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -88,6 +88,14 @@ class Dataplex { } } + /// Ensure that we have enough data coming in from the erg to satisfy all the currently requested data + /// + /// if there isnt enough data, set up some new subscriptions for data from the erg. + /// if we have too many subscriptions and the same data can be had with less, then readjust the streams so we are being efficient. + /// + /// For now this will likely just use the multiplexed data since that basically contains everything in one stream and will be easy to implement + void _validateStreams() {} + /// closes down this instance by cancelling all streams void dispose() { // clear current subscriptions From bc5134465ee8a3317458360896bec41ed7f9fe7f Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 8 Jun 2022 18:23:37 -0400 Subject: [PATCH 062/220] import constants --- lib/src/dataplex.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 83cc286..a965940 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -3,6 +3,7 @@ import 'dart:typed_data'; import 'package:c2bluetooth/models/c2datastreamcontroller.dart'; import 'package:flutter_ble_lib_ios_15/flutter_ble_lib.dart'; +import '../constants.dart' as Identifiers; import './packets/statusdata.dart'; import './packets/strokedata.dart'; import './packets/segmentdata.dart'; From 271b62e454af9f3010033becf54e606356b06926 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 8 Jun 2022 18:24:15 -0400 Subject: [PATCH 063/220] close output streams too --- lib/src/dataplex.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index a965940..26e0512 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -108,5 +108,8 @@ class Dataplex { currentSubscriptions.remove(key); } // end all current output streams + for (var stream in outgoingStreams) { + stream.close(); + } } } From c1cf68d8f67ddc68321672a77b32dcffd9e03438 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 4 Jul 2022 14:00:06 -0400 Subject: [PATCH 064/220] change UUID to type mao into a UUID to dataKey map --- lib/src/dataplex.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 26e0512..0e73adc 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -24,11 +24,12 @@ class Dataplex { Map currentSubscriptions = Map(); - Map characteristicToPacketMap = { + /// A map of incoming UUID's to the data keys they support. + Map> characteristicToDataKeyMap = { Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC_UUID: - WorkoutSummaryPacket, + WorkoutSummaryPacket.datapointIdentifiers, Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC2_UUID: - WorkoutSummaryPacket2, + WorkoutSummaryPacket2.datapointIdentifiers, }; Dataplex(this.device); From 0b57d66ab232065178b248c946e764a6d776d613 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 4 Jul 2022 14:00:23 -0400 Subject: [PATCH 065/220] start implementing validation logic --- lib/src/dataplex.dart | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 0e73adc..a66cc3a 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -96,7 +96,37 @@ class Dataplex { /// if we have too many subscriptions and the same data can be had with less, then readjust the streams so we are being efficient. /// /// For now this will likely just use the multiplexed data since that basically contains everything in one stream and will be easy to implement - void _validateStreams() {} + void _validateStreams() { + //loop over all outgoingStreams and collect a set of every key that is requested + + Set requestedKeys = {}; + for (var outgoingStream in outgoingStreams) { + requestedKeys.addAll(outgoingStream.datapoint_identifiers.toSet()); + } + + //get a set of what keys are coming in from the active subscriptions + Set incomingUUIDs = currentSubscriptions.keys.toSet(); + + Set incomingKeys = {}; + + for (var uuid in incomingUUIDs) { + Set? identifiers = characteristicToDataKeyMap[uuid]; + if (identifiers != null) { + incomingKeys.addAll(identifiers); + } + } + + // dind the difference of the two to see what we are missing + Set missingKeys = requestedKeys.difference(incomingKeys); + + // do magic to figure out what characteristics to add to get those additional keys + + //make a list of those characteristics + + //find out if we have any unused characteristics + + // + } /// closes down this instance by cancelling all streams void dispose() { From 623270f26fcb394d3172cb970ecb6c2e2274c6e6 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 4 Jul 2022 14:01:19 -0400 Subject: [PATCH 066/220] add datapointIdentifiers getter to WorkourSummary packets --- lib/src/packets/workoutsummary.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index be6d97e..507c11b 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -25,6 +25,9 @@ class WorkoutSummaryPacket extends TimestampedData { WorkoutType workoutType; double avgPace; + static Set get datapointIdentifiers => + WorkoutSummaryPacket.zero().asMap().keys.toSet(); + /// Construct a WorkoutSummary from the bytes returned from the erg WorkoutSummaryPacket.fromBytes(Uint8List data) : elapsedTime = Concept2DurationExtension.fromBytes(data.sublist(4, 7)), @@ -44,6 +47,8 @@ class WorkoutSummaryPacket extends TimestampedData { 10, super.fromBytes(data); + WorkoutSummaryPacket.zero() : this.fromBytes(Uint8List(20)); + Map asMap() { // workout.date // workout.time @@ -86,6 +91,9 @@ class WorkoutSummaryPacket2 extends TimestampedData { int intervalRestTime; int avgCalories; + static Set get datapointIdentifiers => + WorkoutSummaryPacket2.zero().asMap().keys.toSet(); + WorkoutSummaryPacket2.fromBytes(Uint8List data) : intervalType = IntervalTypeExtension.fromInt(data.elementAt(4)), intervalSize = CsafeIntExtension.fromBytes(data.sublist(5, 7), @@ -103,6 +111,8 @@ class WorkoutSummaryPacket2 extends TimestampedData { endian: Endian.little), super.fromBytes(data); + WorkoutSummaryPacket2.zero() : this.fromBytes(Uint8List(19)); + Map asMap() { // workout.heart_rate // workout.interval_rest_distance From 04a1af6657dee4f16da51161784899f762c4580b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 8 Jul 2022 21:15:16 -0400 Subject: [PATCH 067/220] docs and some comments --- lib/models/c2datastreamcontroller.dart | 1 + lib/src/dataplex.dart | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/models/c2datastreamcontroller.dart b/lib/models/c2datastreamcontroller.dart index 67186ca..976ed07 100644 --- a/lib/models/c2datastreamcontroller.dart +++ b/lib/models/c2datastreamcontroller.dart @@ -58,6 +58,7 @@ class C2DataStreamController implements StreamController> { @override void add(Map event) { //source: https://stackoverflow.com/a/21131220 + // filter keys so that only ones that affect this stream get added to the controller final filteredMap = new Map.fromIterable( event.keys.where((k) => datapoint_identifiers.contains(k)), value: (k) => event[k]); diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index a66cc3a..e75d2df 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -22,6 +22,7 @@ class Dataplex { List outgoingStreams = []; + /// Map of characteristic UUID's to the sunscription instance for that characteristic Map currentSubscriptions = Map(); /// A map of incoming UUID's to the data keys they support. @@ -50,7 +51,8 @@ class Dataplex { return controller.stream; } - /// Generate a function that removes the provided controller from the outgoing streams list + /// Generates a function to remove the provided controller from the outgoing streams list + /// This is useful for handling when consumers of outging streams cloose the streams themselves FutureOr Function()? _generateOutputCloseListener( C2DataStreamController controller) { FutureOr remove() { @@ -139,6 +141,7 @@ class Dataplex { currentSubscriptions.remove(key); } // end all current output streams + // it is assumed that this also triggers their close handlers and removes them. for (var stream in outgoingStreams) { stream.close(); } From 78f2f3544da0c1a2e451db24229bba0423e8bcfb Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 11 Nov 2022 15:59:21 -0500 Subject: [PATCH 068/220] install reactive_ble --- pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/pubspec.yaml b/pubspec.yaml index 5326386..658ba2e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,6 +15,7 @@ dependencies: flutter_ble_lib_ios_15: ^2.5.2 csafe_fitness: ^0.1.0 rxdart: ^0.27.3 + flutter_reactive_ble: ^5.0.2 dev_dependencies: flutter_test: From 345b7adcc061547f0ca47fa7c92a499ed74dfaa4 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 11 Nov 2022 17:05:28 -0500 Subject: [PATCH 069/220] first pass at migrating bluetooth scanning over to reactive ble --- lib/models/ergblemanager.dart | 18 +++++------------- lib/models/ergometer.dart | 2 +- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/lib/models/ergblemanager.dart b/lib/models/ergblemanager.dart index ccc0a1b..96dcbb3 100644 --- a/lib/models/ergblemanager.dart +++ b/lib/models/ergblemanager.dart @@ -1,32 +1,24 @@ import 'package:c2bluetooth/constants.dart' as Identifiers; -import 'package:flutter_ble_lib_ios_15/flutter_ble_lib.dart'; +import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'ergometer.dart'; class ErgBleManager { - BleManager _manager = BleManager(); - - /// perform set up to get the Bluetooth client ready to scan for devices - void init() { - _manager.createClient(); - } + final _manager = FlutterReactiveBle(); /// Begin scanning for Ergs. /// /// This begins a scan for bluetooth devices with a filter applied so that only Concept2 Performance Monitors show up. /// Bluetooth must be on and adequate permissions must be granted to the app for this to work. Stream startErgScan() { - return _manager.startPeripheralScan(uuids: [ + return _manager.scanForDevices(withServices: [ Identifiers.C2_ROWING_BASE_UUID - ]).map((scanResult) => Ergometer(scanResult.peripheral)); + ]).map((scanResult) => Ergometer(scanResult)); } /// Stops scanning for ergs - Future stopErgScan() { - return _manager.stopPeripheralScan(); - } /// Clean up/destroy/deallocate resources so that they are availalble again Future destroy() { - return _manager.destroyClient(); + return _manager.deinitialize(); } } diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index 8beef74..f6ee0bf 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -13,7 +13,7 @@ import 'package:rxdart/rxdart.dart'; enum ErgometerConnectionState { connecting, connected, disconnected } class Ergometer { - Peripheral _peripheral; + DiscoveredDevice _peripheral; Csafe? _csafeClient; /// Get the name of this erg. i.e. "PM5" + serial number From 707a6b984c078e6e793bbab9a0d4b0c9ee309803 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 11 Nov 2022 17:45:10 -0500 Subject: [PATCH 070/220] update connection and IO related stuff to use reactive --- lib/models/ergometer.dart | 54 +++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index f6ee0bf..e09b9cc 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -27,29 +27,30 @@ class Ergometer { Ergometer(this._peripheral); /// Connect to this erg and discover the services and characteristics that it offers - Future connectAndDiscover() async { - await _peripheral.connect(); - await _peripheral.discoverAllServicesAndCharacteristics(); - + Stream connectAndDiscover() async { + //having this first might cause problems _csafeClient = Csafe(_readCsafe, _writeCsafe); + + //this may cause problems if the device goes out of range between scenning and trying to connect. maybe use connectToAdvertisingDevice instead to mitigate this and prevent a hang on android + + //if no services are specified in the `servicesWithCharacteristicsToDiscover` parameter, then full service discovery will be performed + return connectToDevice(id: _peripheral.id) + } /// Disconnect from this erg or cancel the connection - Future disconnectOrCancel() async { - return _peripheral.disconnectOrCancelConnection(); - } /// Returns a stream of [WorkoutSummary] objects upon completion of any programmed piece or a "just row" piece that is longer than 1 minute. Stream monitorForWorkoutSummary() { - Stream ws1 = _peripheral - .monitorCharacteristic(Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID, - Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC_UUID) - .asyncMap((datapoint) => datapoint.read()); + + var workoutSummaryCharacteristic1 = QualifiedCharacteristic(serviceId: Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID, characteristicId: Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC_UUID, deviceId: _peripheral.id); + + var workoutSummaryCharacteristic2 = QualifiedCharacteristic(serviceId: Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID, characteristicId: Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC2_UUID, deviceId: _peripheral.id); - Stream ws2 = _peripheral - .monitorCharacteristic(Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID, - Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC2_UUID) - .asyncMap((datapoint) => datapoint.read()); + Stream ws1 = flutterReactiveBle.subscribeToCharacteristic(workoutSummaryCharacteristic1).asyncMap((datapoint) => Uint8List.fromList(datapoint)); + + + Stream ws2 = flutterReactiveBle.subscribeToCharacteristic(workoutSummaryCharacteristic2).asyncMap((datapoint) => Uint8List.fromList(datapoint)); return Rx.zip2(ws1, ws2, (Uint8List ws1Result, Uint8List ws2Result) { List combinedList = ws1Result.toList(); @@ -81,10 +82,9 @@ class Ergometer { /// /// Intended for passing to the csafe_fitness library to allow it to read data from the erg Stream _readCsafe() { - return _peripheral - .monitorCharacteristic(Identifiers.C2_ROWING_CONTROL_SERVICE_UUID, - Identifiers.C2_ROWING_PM_TRANSMIT_CHARACTERISTIC_UUID) - .asyncMap((datapoint) { + var csafeRxCharacteristic = QualifiedCharacteristic(serviceId: Identifiers.C2_ROWING_CONTROL_SERVICE_UUID, characteristicId: Identifiers.C2_ROWING_PM_TRANSMIT_CHARACTERISTIC_UUID, deviceId: _peripheral.id) + + return flutterReactiveBle.subscribeToCharacteristic(csafeRxCharacteristic).asyncMap((datapoint) => Uint8List.fromList(datapoint)).asyncMap((datapoint) { print("reading data: ${datapoint.value}"); return datapoint.value; }); @@ -94,12 +94,16 @@ class Ergometer { /// /// Intended for passing to the csafe_fitness library to allow it to write data to the erg Future _writeCsafe(Uint8List value) { - return _peripheral.writeCharacteristic( - Identifiers.C2_ROWING_CONTROL_SERVICE_UUID, - Identifiers.C2_ROWING_PM_RECEIVE_CHARACTERISTIC_UUID, - value, - true); - //.asyncMap((datapoint) => datapoint.read()); + var csafeTxCharacteristic = QualifiedCharacteristic(serviceId: Identifiers.C2_ROWING_CONTROL_SERVICE_UUID, characteristicId: Identifiers.C2_ROWING_PM_RECEIVE_CHARACTERISTIC_UUID, deviceId: _peripheral.id) + + // return _peripheral.writeCharacteristic( + // Identifiers.C2_ROWING_CONTROL_SERVICE_UUID, + // Identifiers.C2_ROWING_PM_RECEIVE_CHARACTERISTIC_UUID, + // value, + // true); + // //.asyncMap((datapoint) => datapoint.read()); + + await flutterReactiveBle.writeCharacteristicWithResponse(csafeTxCharacteristic, value.asList()) } @Deprecated("This is a temporary function for development/experimentation and will be gone very soon") From e2179dc46a6f0861b44be69c638805ce89614fed Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 11 Nov 2022 17:49:13 -0500 Subject: [PATCH 071/220] add flutterReactiveBle class --- lib/models/ergometer.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index e09b9cc..f811119 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -13,6 +13,7 @@ import 'package:rxdart/rxdart.dart'; enum ErgometerConnectionState { connecting, connected, disconnected } class Ergometer { + final _manager = FlutterReactiveBle(); DiscoveredDevice _peripheral; Csafe? _csafeClient; From d001e45ca31cf3a41d9fe9c8d0bd0fe7d112f386 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 11 Nov 2022 17:50:06 -0500 Subject: [PATCH 072/220] combine MonitorConnectionState with connection function --- lib/models/ergometer.dart | 40 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index f811119..52bf962 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -28,14 +28,31 @@ class Ergometer { Ergometer(this._peripheral); /// Connect to this erg and discover the services and characteristics that it offers - Stream connectAndDiscover() async { + /// this returns a stream of events to enable monitoring the erg's connection state + /// This acts as a wrapper around the state provided by the internal bluetooth library. + Stream connectAndDiscover() async { //having this first might cause problems _csafeClient = Csafe(_readCsafe, _writeCsafe); //this may cause problems if the device goes out of range between scenning and trying to connect. maybe use connectToAdvertisingDevice instead to mitigate this and prevent a hang on android //if no services are specified in the `servicesWithCharacteristicsToDiscover` parameter, then full service discovery will be performed - return connectToDevice(id: _peripheral.id) + return connectToDevice(id: _peripheral.id).asyncMap((connectionStateUpdate) { + switch (connectionStateUpdate.connectionState) { + case DeviceConnectionState.connecting: + return ErgometerConnectionState.connecting; + case DeviceConnectionState.connected: + return ErgometerConnectionState.connected; + case DeviceConnectionState.disconnecting: + return ErgometerConnectionState.disconnected; + case DeviceConnectionState.disconnected: + return ErgometerConnectionState.disconnected; + default: + return ErgometerConnectionState.disconnected; + } + }); + + } } @@ -60,25 +77,6 @@ class Ergometer { }); } - /// Expose a stream of events to enable monitoring the erg's connection state - /// This acts as a wrapper around the state provided by the internal bluetooth library to aid with swapping it out later. - Stream monitorConnectionState() { - return _peripheral.observeConnectionState().asyncMap((connectionState) { - switch (connectionState) { - case PeripheralConnectionState.connecting: - return ErgometerConnectionState.connecting; - case PeripheralConnectionState.connected: - return ErgometerConnectionState.connected; - case PeripheralConnectionState.disconnecting: - return ErgometerConnectionState.disconnected; - case PeripheralConnectionState.disconnected: - return ErgometerConnectionState.disconnected; - default: - return ErgometerConnectionState.disconnected; - } - }); - } - /// A read function for the PM over bluetooth. /// /// Intended for passing to the csafe_fitness library to allow it to read data from the erg From a3cbd3a2b8b10be16d164f0e5792228f3c7f7d97 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Fri, 11 Nov 2022 22:05:11 -0500 Subject: [PATCH 073/220] converted to reactive calls and removed various errors --- example/ios/Runner/Info.plist | 14 ++++++++++++++ example/lib/main.dart | 28 +++++++++++++--------------- lib/models/ergblemanager.dart | 2 +- lib/models/ergometer.dart | 28 +++++++++++++--------------- 4 files changed, 41 insertions(+), 31 deletions(-) diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index f12a5c4..bd276d0 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -41,5 +41,19 @@ UIViewControllerBasedStatusBarAppearance + CADisableMinimumFrameDurationOnPhone + + NSBonjourServices + + _dartobservatory._tcp + + NSBluetoothAlwaysUsageDescription + The app uses bluetooth to find, connect and transfer data between different devices + NSBluetoothPeripheralUsageDescription + The app uses bluetooth to find, connect and transfer data between different devices + UIBackgroundModes + + bluetooth-central + diff --git a/example/lib/main.dart b/example/lib/main.dart index 97d8f46..b767d79 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -49,8 +49,6 @@ class _SimpleErgViewState extends State { @override void initState() { super.initState(); - bleManager.init(); //ready to go! - startScan(); } @@ -72,7 +70,7 @@ class _SimpleErgViewState extends State { stopScan() { scanSub?.cancel(); scanSub = null; - bleManager.stopErgScan(); +// bleManager.stopErgScan(); } connectToDevice() async { @@ -82,7 +80,7 @@ class _SimpleErgViewState extends State { displayText = "Device Connecting"; }); - await targetDevice!.connectAndDiscover(); + targetDevice!.connectAndDiscover(); // if (!connected) { // targetDevice! @@ -132,16 +130,16 @@ class _SimpleErgViewState extends State { targetDevice?.configureWorkout(Workout.single(WorkoutGoal.meters(10000))); } - disconnectFromDevice() async { - if (targetDevice == null) return; - - // targetDevice!.disconnect(); - await targetDevice?.disconnectOrCancel(); - - setState(() { - displayText = "Device Disconnected"; - }); - } + // disconnectFromDevice() async { + // if (targetDevice == null) return; + // + // // targetDevice!.disconnect(); + // await targetDevice?.disconnectOrCancel(); + // + // setState(() { + // displayText = "Device Disconnected"; + // }); + // } subscribeToStreams() async { if (targetDevice == null) return; @@ -217,7 +215,7 @@ class _SimpleErgViewState extends State { @override void dispose() { - disconnectFromDevice(); + //disconnectFromDevice(); bleManager .destroy(); //remember to release native resources when you're done! super.dispose(); diff --git a/lib/models/ergblemanager.dart b/lib/models/ergblemanager.dart index 96dcbb3..071a851 100644 --- a/lib/models/ergblemanager.dart +++ b/lib/models/ergblemanager.dart @@ -11,7 +11,7 @@ class ErgBleManager { /// Bluetooth must be on and adequate permissions must be granted to the app for this to work. Stream startErgScan() { return _manager.scanForDevices(withServices: [ - Identifiers.C2_ROWING_BASE_UUID + Uuid.parse(Identifiers.C2_ROWING_BASE_UUID) ]).map((scanResult) => Ergometer(scanResult)); } diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index 52bf962..8eb360c 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -1,26 +1,26 @@ import 'dart:typed_data'; import 'package:c2bluetooth/c2bluetooth.dart'; +import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import '../internal/commands.dart'; import '../internal/datatypes.dart'; import 'package:csafe_fitness/csafe_fitness.dart'; import '../helpers.dart'; import 'workout.dart'; import 'package:c2bluetooth/constants.dart' as Identifiers; -import 'package:flutter_ble_lib_ios_15/flutter_ble_lib.dart'; import 'package:rxdart/rxdart.dart'; enum ErgometerConnectionState { connecting, connected, disconnected } class Ergometer { - final _manager = FlutterReactiveBle(); + final flutterReactiveBle = FlutterReactiveBle(); DiscoveredDevice _peripheral; Csafe? _csafeClient; /// Get the name of this erg. i.e. "PM5" + serial number /// /// Returns "Unknown" if the erg does not report a name - String get name => _peripheral.name ?? "Unknown"; + String get name => _peripheral.name; /// Create an Ergometer from a FlutterBleLib peripheral object /// @@ -30,14 +30,14 @@ class Ergometer { /// Connect to this erg and discover the services and characteristics that it offers /// this returns a stream of events to enable monitoring the erg's connection state /// This acts as a wrapper around the state provided by the internal bluetooth library. - Stream connectAndDiscover() async { + Stream connectAndDiscover() { //having this first might cause problems _csafeClient = Csafe(_readCsafe, _writeCsafe); //this may cause problems if the device goes out of range between scenning and trying to connect. maybe use connectToAdvertisingDevice instead to mitigate this and prevent a hang on android //if no services are specified in the `servicesWithCharacteristicsToDiscover` parameter, then full service discovery will be performed - return connectToDevice(id: _peripheral.id).asyncMap((connectionStateUpdate) { + return flutterReactiveBle.connectToDevice(id: _peripheral.id).asyncMap((connectionStateUpdate) { switch (connectionStateUpdate.connectionState) { case DeviceConnectionState.connecting: return ErgometerConnectionState.connecting; @@ -54,16 +54,14 @@ class Ergometer { } - } - /// Disconnect from this erg or cancel the connection /// Returns a stream of [WorkoutSummary] objects upon completion of any programmed piece or a "just row" piece that is longer than 1 minute. Stream monitorForWorkoutSummary() { - var workoutSummaryCharacteristic1 = QualifiedCharacteristic(serviceId: Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID, characteristicId: Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC_UUID, deviceId: _peripheral.id); + var workoutSummaryCharacteristic1 = QualifiedCharacteristic(serviceId: Uuid.parse(Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID), characteristicId: Uuid.parse(Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC_UUID), deviceId: _peripheral.id); - var workoutSummaryCharacteristic2 = QualifiedCharacteristic(serviceId: Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID, characteristicId: Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC2_UUID, deviceId: _peripheral.id); + var workoutSummaryCharacteristic2 = QualifiedCharacteristic(serviceId: Uuid.parse(Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID), characteristicId: Uuid.parse(Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC2_UUID), deviceId: _peripheral.id); Stream ws1 = flutterReactiveBle.subscribeToCharacteristic(workoutSummaryCharacteristic1).asyncMap((datapoint) => Uint8List.fromList(datapoint)); @@ -81,19 +79,19 @@ class Ergometer { /// /// Intended for passing to the csafe_fitness library to allow it to read data from the erg Stream _readCsafe() { - var csafeRxCharacteristic = QualifiedCharacteristic(serviceId: Identifiers.C2_ROWING_CONTROL_SERVICE_UUID, characteristicId: Identifiers.C2_ROWING_PM_TRANSMIT_CHARACTERISTIC_UUID, deviceId: _peripheral.id) + var csafeRxCharacteristic = QualifiedCharacteristic(serviceId: Uuid.parse(Identifiers.C2_ROWING_CONTROL_SERVICE_UUID), characteristicId: Uuid.parse(Identifiers.C2_ROWING_PM_TRANSMIT_CHARACTERISTIC_UUID), deviceId: _peripheral.id); return flutterReactiveBle.subscribeToCharacteristic(csafeRxCharacteristic).asyncMap((datapoint) => Uint8List.fromList(datapoint)).asyncMap((datapoint) { - print("reading data: ${datapoint.value}"); - return datapoint.value; + print("reading data: $datapoint"); + return datapoint; }); } /// A write function for the PM over bluetooth. /// /// Intended for passing to the csafe_fitness library to allow it to write data to the erg - Future _writeCsafe(Uint8List value) { - var csafeTxCharacteristic = QualifiedCharacteristic(serviceId: Identifiers.C2_ROWING_CONTROL_SERVICE_UUID, characteristicId: Identifiers.C2_ROWING_PM_RECEIVE_CHARACTERISTIC_UUID, deviceId: _peripheral.id) + void _writeCsafe(Uint8List value) { + var csafeTxCharacteristic = QualifiedCharacteristic(serviceId: Uuid.parse(Identifiers.C2_ROWING_CONTROL_SERVICE_UUID), characteristicId: Uuid.parse(Identifiers.C2_ROWING_PM_RECEIVE_CHARACTERISTIC_UUID), deviceId: _peripheral.id); // return _peripheral.writeCharacteristic( // Identifiers.C2_ROWING_CONTROL_SERVICE_UUID, @@ -102,7 +100,7 @@ class Ergometer { // true); // //.asyncMap((datapoint) => datapoint.read()); - await flutterReactiveBle.writeCharacteristicWithResponse(csafeTxCharacteristic, value.asList()) + flutterReactiveBle.writeCharacteristicWithResponse(csafeTxCharacteristic, value: value); } @Deprecated("This is a temporary function for development/experimentation and will be gone very soon") From de7d632d77b403183bb3671417ecb71ce86f114d Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 11 Nov 2022 22:29:51 -0500 Subject: [PATCH 074/220] make flutterReactiveBle property private --- lib/models/ergometer.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index 8eb360c..fb0bd14 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -13,7 +13,7 @@ import 'package:rxdart/rxdart.dart'; enum ErgometerConnectionState { connecting, connected, disconnected } class Ergometer { - final flutterReactiveBle = FlutterReactiveBle(); + final _flutterReactiveBle = FlutterReactiveBle(); DiscoveredDevice _peripheral; Csafe? _csafeClient; From e6392942e1b9a6d22556723f9712efc2f32dc857 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 14 Nov 2022 19:07:24 -0500 Subject: [PATCH 075/220] fix other uses of the flutterReactiveBle field --- lib/models/ergometer.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index fb0bd14..d8f056f 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -37,7 +37,7 @@ class Ergometer { //this may cause problems if the device goes out of range between scenning and trying to connect. maybe use connectToAdvertisingDevice instead to mitigate this and prevent a hang on android //if no services are specified in the `servicesWithCharacteristicsToDiscover` parameter, then full service discovery will be performed - return flutterReactiveBle.connectToDevice(id: _peripheral.id).asyncMap((connectionStateUpdate) { + return _flutterReactiveBle.connectToDevice(id: _peripheral.id).asyncMap((connectionStateUpdate) { switch (connectionStateUpdate.connectionState) { case DeviceConnectionState.connecting: return ErgometerConnectionState.connecting; @@ -63,10 +63,10 @@ class Ergometer { var workoutSummaryCharacteristic2 = QualifiedCharacteristic(serviceId: Uuid.parse(Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID), characteristicId: Uuid.parse(Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC2_UUID), deviceId: _peripheral.id); - Stream ws1 = flutterReactiveBle.subscribeToCharacteristic(workoutSummaryCharacteristic1).asyncMap((datapoint) => Uint8List.fromList(datapoint)); + Stream ws1 = _flutterReactiveBle.subscribeToCharacteristic(workoutSummaryCharacteristic1).asyncMap((datapoint) => Uint8List.fromList(datapoint)); - Stream ws2 = flutterReactiveBle.subscribeToCharacteristic(workoutSummaryCharacteristic2).asyncMap((datapoint) => Uint8List.fromList(datapoint)); + Stream ws2 = _flutterReactiveBle.subscribeToCharacteristic(workoutSummaryCharacteristic2).asyncMap((datapoint) => Uint8List.fromList(datapoint)); return Rx.zip2(ws1, ws2, (Uint8List ws1Result, Uint8List ws2Result) { List combinedList = ws1Result.toList(); @@ -81,7 +81,7 @@ class Ergometer { Stream _readCsafe() { var csafeRxCharacteristic = QualifiedCharacteristic(serviceId: Uuid.parse(Identifiers.C2_ROWING_CONTROL_SERVICE_UUID), characteristicId: Uuid.parse(Identifiers.C2_ROWING_PM_TRANSMIT_CHARACTERISTIC_UUID), deviceId: _peripheral.id); - return flutterReactiveBle.subscribeToCharacteristic(csafeRxCharacteristic).asyncMap((datapoint) => Uint8List.fromList(datapoint)).asyncMap((datapoint) { + return _flutterReactiveBle.subscribeToCharacteristic(csafeRxCharacteristic).asyncMap((datapoint) => Uint8List.fromList(datapoint)).asyncMap((datapoint) { print("reading data: $datapoint"); return datapoint; }); @@ -100,7 +100,7 @@ class Ergometer { // true); // //.asyncMap((datapoint) => datapoint.read()); - flutterReactiveBle.writeCharacteristicWithResponse(csafeTxCharacteristic, value: value); + _flutterReactiveBle.writeCharacteristicWithResponse(csafeTxCharacteristic, value: value); } @Deprecated("This is a temporary function for development/experimentation and will be gone very soon") From dae2d91acbb9474fcfff3c0f879fdf6b92d352bc Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 15 Nov 2022 16:21:23 -0500 Subject: [PATCH 076/220] bump minsdkversion on android to make the example app compile --- example/android/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 5a1c3ea..d9584b6 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -35,7 +35,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.fresh_example" - minSdkVersion 18 + minSdkVersion 21 targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName From 89bb0356ec01caf6ff06dc5286228e83bea85e41 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 15 Nov 2022 16:27:00 -0500 Subject: [PATCH 077/220] remove now-unused flutter_ble_lib dependency --- pubspec.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 658ba2e..dab0f9c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,7 +12,6 @@ dependencies: flutter: sdk: flutter - flutter_ble_lib_ios_15: ^2.5.2 csafe_fitness: ^0.1.0 rxdart: ^0.27.3 flutter_reactive_ble: ^5.0.2 From e07ba7f9f3922b56b5d7a2c59f5b004481b9ffe0 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 15 Nov 2022 16:48:34 -0500 Subject: [PATCH 078/220] add android bluetooth permissions to demo app --- example/android/app/src/main/AndroidManifest.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 99c6fb1..78ad24b 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,15 @@ + + + + + + + From 305f47bb8dce093b636713edc1638409b72973ef Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 15 Nov 2022 16:48:54 -0500 Subject: [PATCH 079/220] other android build parameter changes --- example/android/app/build.gradle | 2 +- example/android/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index d9584b6..8b1b141 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 30 + compileSdkVersion 33 sourceSets { main.java.srcDirs += 'src/main/kotlin' diff --git a/example/android/build.gradle b/example/android/build.gradle index 9b6ed06..1881064 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.3.50' + ext.kotlin_version = '1.6.21' repositories { google() jcenter() From 4a32c113b578f449ee773a958d2bd30ac1bb5e37 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 15 Nov 2022 16:49:10 -0500 Subject: [PATCH 080/220] request permissions android --- example/lib/main.dart | 19 ++++++++++++++++++- example/pubspec.yaml | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index b767d79..3e15b60 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,8 +1,10 @@ import 'dart:async'; +import 'dart:io'; import 'package:c2bluetooth/c2bluetooth.dart'; import 'package:c2bluetooth/models/workout.dart'; import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; void main() { runApp(MyApp()); @@ -52,7 +54,22 @@ class _SimpleErgViewState extends State { startScan(); } - startScan() { + startScan() async { + var goForIt = false; + + if (Platform.isAndroid) { + PermissionStatus locationPermission = await Permission.location.request(); + PermissionStatus finePermission = + await Permission.locationWhenInUse.request(); + // TODO user feedback on no location + if (locationPermission == PermissionStatus.granted && + finePermission == PermissionStatus.granted) { + goForIt = true; + } + } else if (Platform.isIOS) { + goForIt = true; + } + setState(() { displayText = "Start Scanning"; }); diff --git a/example/pubspec.yaml b/example/pubspec.yaml index bc45844..c669235 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -31,6 +31,7 @@ dependencies: c2bluetooth: path: ../ + permission_handler: ^10.2.0 dev_dependencies: flutter_test: From 3788c119d78ad998a6d453b14ba9efff5a754bd4 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 15 Nov 2022 20:45:27 -0500 Subject: [PATCH 081/220] misc updates to settings, mainly concerning hooking up cocoapods --- example/ios/Runner.xcodeproj/project.pbxproj | 92 +++++++++++++++++-- .../xcshareddata/xcschemes/Runner.xcscheme | 8 +- 2 files changed, 86 insertions(+), 14 deletions(-) diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 4877c65..98a11af 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,12 +3,13 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 71E0CED985FD1762BCF30DDE /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 534834C7320293612BB51C2B /* Pods_Runner.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; @@ -29,9 +30,11 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 05A57BCE264DB95F63255FBC /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 534834C7320293612BB51C2B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; @@ -42,6 +45,8 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B8D80978C7D3224A89929ED7 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + B8D95075A9661C60A4AD023F /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -49,12 +54,21 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 71E0CED985FD1762BCF30DDE /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 1E4F1236A3F1929EB4383FE3 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 534834C7320293612BB51C2B /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -72,6 +86,8 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, + F0E4278F0E8B08CD7FD47A28 /* Pods */, + 1E4F1236A3F1929EB4383FE3 /* Frameworks */, ); sourceTree = ""; }; @@ -98,6 +114,16 @@ path = Runner; sourceTree = ""; }; + F0E4278F0E8B08CD7FD47A28 /* Pods */ = { + isa = PBXGroup; + children = ( + B8D95075A9661C60A4AD023F /* Pods-Runner.debug.xcconfig */, + B8D80978C7D3224A89929ED7 /* Pods-Runner.release.xcconfig */, + 05A57BCE264DB95F63255FBC /* Pods-Runner.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -105,12 +131,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + EBEC1DE42650B27D75C6CB9F /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + AECB0AC27820DCCC1649CDF1 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -127,7 +155,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1020; + LastUpgradeCheck = 1300; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -197,6 +225,45 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + AECB0AC27820DCCC1649CDF1 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + EBEC1DE42650B27D75C6CB9F /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -272,7 +339,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -290,8 +357,11 @@ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.example.freshExample; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -346,7 +416,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -395,7 +465,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -414,8 +484,11 @@ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.example.freshExample; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -433,8 +506,11 @@ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.example.freshExample; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a28140c..fb2dffc 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -27,8 +27,6 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> - - - - + + - - Date: Tue, 15 Nov 2022 20:46:27 -0500 Subject: [PATCH 082/220] xcode recommended updates --- example/ios/Runner.xcodeproj/project.pbxproj | 15 ++++++++++----- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 98a11af..3514c05 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -155,7 +155,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1340; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -321,6 +321,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -339,7 +340,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -355,13 +356,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = UJPCPV3425; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.example.freshExample; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); + PRODUCT_BUNDLE_IDENTIFIER = com.adriancedwards.c2bluetooth.freshExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -392,6 +394,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -416,7 +419,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -447,6 +450,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -465,10 +469,11 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index fb2dffc..a0f6453 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ Date: Tue, 15 Nov 2022 21:05:34 -0500 Subject: [PATCH 083/220] more pod stuff maybe? --- example/ios/Flutter/Debug.xcconfig | 1 + example/ios/Flutter/Release.xcconfig | 1 + example/ios/Runner.xcworkspace/contents.xcworkspacedata | 3 +++ 3 files changed, 5 insertions(+) diff --git a/example/ios/Flutter/Debug.xcconfig b/example/ios/Flutter/Debug.xcconfig index 592ceee..ec97fc6 100644 --- a/example/ios/Flutter/Debug.xcconfig +++ b/example/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/example/ios/Flutter/Release.xcconfig b/example/ios/Flutter/Release.xcconfig index 592ceee..c4855bf 100644 --- a/example/ios/Flutter/Release.xcconfig +++ b/example/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + From f6ce67a8a559c03bd6263a3c9bd5143e4a5d1b49 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 15 Nov 2022 21:08:49 -0500 Subject: [PATCH 084/220] commit podfile --- example/ios/Podfile | 41 ++++++++++++++++++++++++++++++++++++++++ example/ios/Podfile.lock | 39 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 example/ios/Podfile create mode 100644 example/ios/Podfile.lock diff --git a/example/ios/Podfile b/example/ios/Podfile new file mode 100644 index 0000000..88359b2 --- /dev/null +++ b/example/ios/Podfile @@ -0,0 +1,41 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '11.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock new file mode 100644 index 0000000..2f24574 --- /dev/null +++ b/example/ios/Podfile.lock @@ -0,0 +1,39 @@ +PODS: + - Flutter (1.0.0) + - permission_handler_apple (9.0.4): + - Flutter + - Protobuf (3.21.9) + - reactive_ble_mobile (0.0.1): + - Flutter + - Protobuf (~> 3.5) + - SwiftProtobuf (~> 1.0) + - SwiftProtobuf (1.20.3) + +DEPENDENCIES: + - Flutter (from `Flutter`) + - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) + - reactive_ble_mobile (from `.symlinks/plugins/reactive_ble_mobile/ios`) + +SPEC REPOS: + trunk: + - Protobuf + - SwiftProtobuf + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + permission_handler_apple: + :path: ".symlinks/plugins/permission_handler_apple/ios" + reactive_ble_mobile: + :path: ".symlinks/plugins/reactive_ble_mobile/ios" + +SPEC CHECKSUMS: + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce + Protobuf: 02524ec14183fe08fb259741659e79683788158b + reactive_ble_mobile: 9ce6723d37ccf701dbffd202d487f23f5de03b4c + SwiftProtobuf: b02b5075dcf60c9f5f403000b3b0c202a11b6ae1 + +PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 + +COCOAPODS: 1.11.3 From 89b888084b093bfc31beb244ef95d1c3afdbaa3d Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Wed, 16 Nov 2022 09:55:15 -0500 Subject: [PATCH 085/220] fixed scanning issue and added scan button --- example/lib/main.dart | 55 ++++++++++++++----------------------------- 1 file changed, 18 insertions(+), 37 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 3e15b60..6492257 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -51,11 +51,11 @@ class _SimpleErgViewState extends State { @override void initState() { super.initState(); - startScan(); + //startScan(); } startScan() async { - var goForIt = false; + bool goForIt = false; if (Platform.isAndroid) { PermissionStatus locationPermission = await Permission.location.request(); @@ -87,6 +87,9 @@ class _SimpleErgViewState extends State { stopScan() { scanSub?.cancel(); scanSub = null; + setState(() { + displayText = "Stopped Scanning"; + }); // bleManager.stopErgScan(); } @@ -97,30 +100,11 @@ class _SimpleErgViewState extends State { displayText = "Device Connecting"; }); - targetDevice!.connectAndDiscover(); - - // if (!connected) { - // targetDevice! - // .observeConnectionState( - // emitCurrentValue: true, completeOnDisconnect: true) - // .listen((connectionState) { - // print( - // "Peripheral ${targetDevice!.name} connection state is $connectionState"); - // }); - // try { - // await targetDevice!.connect(); - // } catch (BleError) { - // print("a"); - // } - // print('CONNECTING'); - // } else { - // print('DEVICE Already CONNECTED'); - // } - // setState(() { - // displayText = "Device Connected"; - // }); - // discoverServices(); - subscribeToStreams(); + targetDevice!.connectAndDiscover().listen((event) { + if(event == ErgometerConnectionState.connected) { + subscribeToStreams(); + } + }); } setup2kH() async { @@ -147,17 +131,6 @@ class _SimpleErgViewState extends State { targetDevice?.configureWorkout(Workout.single(WorkoutGoal.meters(10000))); } - // disconnectFromDevice() async { - // if (targetDevice == null) return; - // - // // targetDevice!.disconnect(); - // await targetDevice?.disconnectOrCancel(); - // - // setState(() { - // displayText = "Device Disconnected"; - // }); - // } - subscribeToStreams() async { if (targetDevice == null) return; @@ -193,6 +166,14 @@ class _SimpleErgViewState extends State { title: Text("hello"), ), body: Column(children: [ + Visibility( + visible: scanSub == null && targetDevice == null, + child: ElevatedButton(onPressed: () { + startScan(); + }, + child: Text("Start Scan"), + ), + ), Center( child: Text( displayText, From 9ae13caa5e1a0fa14c8495ad6f41e0b7e7b2d4e1 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Thu, 17 Nov 2022 08:47:21 -0500 Subject: [PATCH 086/220] code cleaning --- example/ios/Runner/Info.plist | 4 ++-- example/lib/main.dart | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index bd276d0..672d7e3 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -48,9 +48,9 @@ _dartobservatory._tcp NSBluetoothAlwaysUsageDescription - The app uses bluetooth to find, connect and transfer data between different devices + The app uses bluetooth to connect and pull data from Concept2 Ergometer PM5 monitors NSBluetoothPeripheralUsageDescription - The app uses bluetooth to find, connect and transfer data between different devices + The app uses bluetooth to connect and pull data from Concept2 Ergometer PM5 monitor UIBackgroundModes bluetooth-central diff --git a/example/lib/main.dart b/example/lib/main.dart index 6492257..850e6b2 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -69,7 +69,11 @@ class _SimpleErgViewState extends State { } else if (Platform.isIOS) { goForIt = true; } - + if(!goForIt) { + print('Your device is experiencing a permission issue. Make sure you allow location services.'); + displayText = "Permission Issue Stopped Scanning"; + return; + } setState(() { displayText = "Start Scanning"; }); @@ -87,10 +91,6 @@ class _SimpleErgViewState extends State { stopScan() { scanSub?.cancel(); scanSub = null; - setState(() { - displayText = "Stopped Scanning"; - }); -// bleManager.stopErgScan(); } connectToDevice() async { From 1942a5f9dc5e51dcd0cfa82503c38b187f575fc3 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 16 Nov 2022 18:42:13 -0500 Subject: [PATCH 087/220] some updates to README --- README.md | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 97b6130..e90b126 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,6 @@ Similar to how the underlying bluetooth library works, pretty much everything be ```dart ErgBleManager bleManager = ErgBleManager(); -bleManager.init(); //ready to go! ``` ### Scanning for devices Next, you need to start scanning for available devices. This uses a Stream to return an instance of the `Ergometer` class for each erg found. Each of these instances represents an erg and should be stored for later reuse as these act as the base upon which everything else (retrieving data, sending workouts .etc) is based. @@ -54,27 +53,43 @@ Next, you need to start scanning for available devices. This uses a Stream to re ```dart Ergometer myErg; -bleManager.startErgScan().listen((erg) { +StreamSubscription ergScanStream = bleManager.startErgScan().listen((erg) { //your code for detecting an erg here. - myErg = erg + + //you can store the erg instance somewhere + myErg = erg; + + //or connect to it (see later examples) + + //or stop scanning + ergScanStream.cancel(); + + return erg; }); ``` This block of code is where you can do things like: - determine what erg(s) you want to work with (this can be based on name, user choice, or basicaly anything) - store the erg instance somewhere more permanent, like the `myErg` variable to allow you to be able to access it after you stop scanning. - - call `bleManager.stopErgScan()` if you know you are done scanning early. As an example, one way to immediately connect to the first erg found is to unconditionally call `stopErgScan` within this function so the scan stops after the first erg is received. Don't forget to close the stream too! + - cancel the stream if you are done scanning. ### Connecting and disconnecting -Once you have the `Ergometer` instance for the erg you want to connect to, you can call `connectAndDiscover()` on it to connect. +Once you have the `Ergometer` instance for the erg you want to connect to, you can call `connectAndDiscover()` on it to connect. This will provide you with a stream indicating the connection state of the erg. ```dart -await myErg.connectAndDiscover(); +StreamSubscription ergConnectionStream = myErg.connectAndDiscover().listen((event) { + if(event == ErgometerConnectionState.connected) { + //do stuff here once the erg is connected + } else if (event == ErgometerConnectionState.disconnected) { + //handle disconnection here + } + }); +} ``` -When you are done, make sure to disconnect from your erg: +When you are done, disconnect from your erg by cancelling the stream: ```dart -await myErg.disconnectOrCancel(); +ergConnectionStream.cancel(); ``` ### Getting data from the erg From 91aad2d4a2c6b1de2b6746865027e4f6b2065e1e Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Thu, 17 Nov 2022 08:53:49 -0500 Subject: [PATCH 088/220] missed setState --- example/lib/main.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 850e6b2..5df5de7 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -71,7 +71,9 @@ class _SimpleErgViewState extends State { } if(!goForIt) { print('Your device is experiencing a permission issue. Make sure you allow location services.'); - displayText = "Permission Issue Stopped Scanning"; + setState(() { + displayText = "Permission Issue Stopped Scanning"; + }); return; } setState(() { From 712e5375af7a90ede26a57dcdcd887de6953a434 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Thu, 17 Nov 2022 11:55:56 -0500 Subject: [PATCH 089/220] ignore use of old deprecated functions --- example/lib/main.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/example/lib/main.dart b/example/lib/main.dart index 5df5de7..f635457 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -112,12 +112,14 @@ class _SimpleErgViewState extends State { setup2kH() async { if (targetDevice == null) return; + // ignore: deprecated_member_use targetDevice?.configure2kWorkout(); } setup10kH() async { if (targetDevice == null) return; + // ignore: deprecated_member_use targetDevice?.configure10kWorkout(); } From 897f30bb6e20d8563a5a9f6cc353efdd62b21b75 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Thu, 17 Nov 2022 11:58:26 -0500 Subject: [PATCH 090/220] misc formatting --- example/lib/main.dart | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index f635457..086f197 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -69,8 +69,9 @@ class _SimpleErgViewState extends State { } else if (Platform.isIOS) { goForIt = true; } - if(!goForIt) { - print('Your device is experiencing a permission issue. Make sure you allow location services.'); + if (!goForIt) { + print( + 'Your device is experiencing a permission issue. Make sure you allow location services.'); setState(() { displayText = "Permission Issue Stopped Scanning"; }); @@ -103,7 +104,7 @@ class _SimpleErgViewState extends State { }); targetDevice!.connectAndDiscover().listen((event) { - if(event == ErgometerConnectionState.connected) { + if (event == ErgometerConnectionState.connected) { subscribeToStreams(); } }); @@ -172,10 +173,11 @@ class _SimpleErgViewState extends State { body: Column(children: [ Visibility( visible: scanSub == null && targetDevice == null, - child: ElevatedButton(onPressed: () { - startScan(); - }, - child: Text("Start Scan"), + child: ElevatedButton( + onPressed: () { + startScan(); + }, + child: Text("Start Scan"), ), ), Center( From 5ebad8b727b6853f137d558f7d55f01b80523717 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 18 Nov 2022 14:08:16 -0500 Subject: [PATCH 091/220] unused import --- test/helpers_test.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/helpers_test.dart b/test/helpers_test.dart index 8474a59..adbdf45 100644 --- a/test/helpers_test.dart +++ b/test/helpers_test.dart @@ -1,5 +1,3 @@ -import 'dart:typed_data'; - import 'package:c2bluetooth/helpers.dart'; import 'package:c2bluetooth/models/workout.dart'; import 'package:flutter_test/flutter_test.dart'; From a5b5698156646761cc18d8e4a0af39e2097ac902 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 07:06:00 -0500 Subject: [PATCH 092/220] add location permission to android manifest --- example/android/app/src/main/AndroidManifest.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 78ad24b..88b2d57 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -10,6 +10,10 @@ location information, you can strongly assert that your app doesn't derive physical location. --> + + + + From 42a3c8576288a08e3baada7a91e40fa2e54dc080 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 12:10:10 -0500 Subject: [PATCH 093/220] remove old doc comment --- lib/models/ergometer.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index d8f056f..05bd1e5 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -54,8 +54,6 @@ class Ergometer { } - /// Disconnect from this erg or cancel the connection - /// Returns a stream of [WorkoutSummary] objects upon completion of any programmed piece or a "just row" piece that is longer than 1 minute. Stream monitorForWorkoutSummary() { From 0801f51e9e0cb1295974c585d2d11b7675d1f11d Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 13:20:15 -0500 Subject: [PATCH 094/220] update doc comments for Ergometer and ErgBleManager to account for new bluetooth backend --- lib/models/ergblemanager.dart | 4 +--- lib/models/ergometer.dart | 23 +++++++++++------------ 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/lib/models/ergblemanager.dart b/lib/models/ergblemanager.dart index 071a851..6fc3ca9 100644 --- a/lib/models/ergblemanager.dart +++ b/lib/models/ergblemanager.dart @@ -8,15 +8,13 @@ class ErgBleManager { /// Begin scanning for Ergs. /// /// This begins a scan for bluetooth devices with a filter applied so that only Concept2 Performance Monitors show up. - /// Bluetooth must be on and adequate permissions must be granted to the app for this to work. + /// Bluetooth must be on and adequate permissions must be granted for this to work. Stream startErgScan() { return _manager.scanForDevices(withServices: [ Uuid.parse(Identifiers.C2_ROWING_BASE_UUID) ]).map((scanResult) => Ergometer(scanResult)); } - /// Stops scanning for ergs - /// Clean up/destroy/deallocate resources so that they are availalble again Future destroy() { return _manager.deinitialize(); diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index 05bd1e5..4d258ae 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -18,18 +18,17 @@ class Ergometer { Csafe? _csafeClient; /// Get the name of this erg. i.e. "PM5" + serial number - /// - /// Returns "Unknown" if the erg does not report a name String get name => _peripheral.name; - /// Create an Ergometer from a FlutterBleLib peripheral object + /// Create an [Ergometer] from a discovered bluetooth device object /// - /// This is mainly intended for internal use + /// This is intended only for internal use by [ErgBleManager.startErgScan]. + /// Consider this method a private API that is subject to unannounced breaking + /// changes. There are likely much better methods to use for whatever you are trying to do. Ergometer(this._peripheral); /// Connect to this erg and discover the services and characteristics that it offers - /// this returns a stream of events to enable monitoring the erg's connection state - /// This acts as a wrapper around the state provided by the internal bluetooth library. + /// this returns a stream of [ErgometerConnectionState] events to enable monitoring the erg's connection state and disconnecting. Stream connectAndDiscover() { //having this first might cause problems _csafeClient = Csafe(_readCsafe, _writeCsafe); @@ -54,7 +53,7 @@ class Ergometer { } - /// Returns a stream of [WorkoutSummary] objects upon completion of any programmed piece or a "just row" piece that is longer than 1 minute. + /// Returns a stream of [WorkoutSummary] objects upon completion of any workout that would normally be saved to the Erg's memory. This includes any pre-programmed piece and any "just row" pieces longer than 1 minute. Stream monitorForWorkoutSummary() { var workoutSummaryCharacteristic1 = QualifiedCharacteristic(serviceId: Uuid.parse(Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID), characteristicId: Uuid.parse(Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC_UUID), deviceId: _peripheral.id); @@ -73,9 +72,9 @@ class Ergometer { }); } - /// A read function for the PM over bluetooth. + /// An internal read function for accessing the PM's CSAFE API over bluetooth. /// - /// Intended for passing to the csafe_fitness library to allow it to read data from the erg + /// Intended for passing to the csafe_fitness library to allow it to read response data from the erg Stream _readCsafe() { var csafeRxCharacteristic = QualifiedCharacteristic(serviceId: Uuid.parse(Identifiers.C2_ROWING_CONTROL_SERVICE_UUID), characteristicId: Uuid.parse(Identifiers.C2_ROWING_PM_TRANSMIT_CHARACTERISTIC_UUID), deviceId: _peripheral.id); @@ -85,9 +84,9 @@ class Ergometer { }); } - /// A write function for the PM over bluetooth. + /// An internal write function for accessing the PM's CSAFE API over bluetooth. /// - /// Intended for passing to the csafe_fitness library to allow it to write data to the erg + /// Intended for passing to the csafe_fitness library to allow it to write commands to the erg void _writeCsafe(Uint8List value) { var csafeTxCharacteristic = QualifiedCharacteristic(serviceId: Uuid.parse(Identifiers.C2_ROWING_CONTROL_SERVICE_UUID), characteristicId: Uuid.parse(Identifiers.C2_ROWING_PM_RECEIVE_CHARACTERISTIC_UUID), deviceId: _peripheral.id); @@ -140,7 +139,7 @@ class Ergometer { /// Program a workout into the PM with particular parameters /// - ///Currently only the more basic of workout types are supported, such as basic single intervals, single distance, and single time pieces + /// Currently only the more basic of workout types are supported, such as basic single intervals, single distance, and single time pieces void configureWorkout(Workout workout, [bool startImmediately = true]) async { //Workout workout From d61a021295a71948a1da4b855a60b50aa2812af8 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 13:33:25 -0500 Subject: [PATCH 095/220] update READMEs to reflect the newer version of the demo app --- README.md | 6 +++--- docs/images/demo/completed.png | Bin 0 -> 99941 bytes docs/images/demo/demo1-small.jpg | Bin 86522 -> 0 bytes docs/images/demo/pre-scan.png | Bin 0 -> 85203 bytes example/README.md | 23 +++++++++++++++-------- 5 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 docs/images/demo/completed.png delete mode 100644 docs/images/demo/demo1-small.jpg create mode 100644 docs/images/demo/pre-scan.png diff --git a/README.md b/README.md index e90b126..f61067d 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,11 @@ C2Bluetooth is a flutter package designed to provide an easy API for accessing data from Concept2 PM5 Indoor fitness machines via bluetooth. This library implements the [Concept2 Performance Monitor Bluetooth Smart Communications Interface Definition](https://www.concept2.com/files/pdf/us/monitors/PM5_BluetoothSmartInterfaceDefinition.pdf) Specification ([newer versions](https://www.c2forum.com/viewtopic.php?f=15&t=193697#p527068) are also available). It also relies heavily on the [CSAFE specification](https://web.archive.org/web/20060718175014/http://www.fitlinxx.com/csafe/specification.htm) from FitLinxx. ## Demo +This package comes with a demo app in the `example/` directory. -![A demo showing the distance completed after a workout](docs/images/demo/demo1-small.jpg) +See the [`example/README.md`](example/README.md) for more detailed information about the demo app and how to use it. -This is a relatively old screenshot of the included example app using an older version of the library to display the completed distance from a short 20-second test workout. Many improvements to expose more datapoints have been made since this screenshot was taken. -## Key Features +## Key Library Features Currently this library supports a few basic features such as: - retrieving workout summary information from the erg after a workout diff --git a/docs/images/demo/completed.png b/docs/images/demo/completed.png new file mode 100644 index 0000000000000000000000000000000000000000..deacd080b8a939df4ad989f63a2f618ed6660dc3 GIT binary patch literal 99941 zcmeFZXE&dU&ny$|NO{0y?1lAeb1n!&L_*w&&Mmu$Is2nC(NxNCc>+u zrJ*CDsQX#~wBzfI|6K1OI4LhS=0Dr`!hE85U+?{An-IL;7)$g&@AIE)^Yilai}Ue` z^NKR?35p8}i}Q-%aq$X?^YVg5|34c3zZ#4B-yh=YD*x{q_!=X?2oApHuBjl0S2{qm z0d{V<%PDFT5fRNUsV(B+G2kh_l-2f5+nV?B*FJ8>?YmnkTE+G;#YMi6yH5Pxngsvm zQTF039ohO?oj*0(CG}(WM&ypWWzGLaW>h*(YMnYtYQO6zG=4NBkI|V3=KA=Y|0A9O zOD|JZ8iJmcCZxOjee4?+);(Y8GjBn$fj0wpy8F=37R2Bh=M1dc5VQvmk87CZg!pRX zIYZ#pAmjBvDY$wWqWQnO|A%{n@6HMFbEB6Uyi~`o!vwNqhBHznv6)7aJ!=A zBa0=o-Z>lr?MzmAuZU?z~y z`VC*U{M((Ip1qwtzL@%hn?pvrReWCh#TsQM28$Qt}|@YQoj8j?|tC45vM$%=L%w+PEwG?NX@U;^QFIj4 zJr)yn^{|r(CmbV7P5}1D5oZ@kTr0%y$KVMa?p@b#3W1(}#;1wD_n7$xM4i0-{{$4w zqGmnoho@KfJygPnGUVXMVN8dt6EAaDZP(IUEnUh^dc${hP2NUf4EK@A82CzO+&i&i>kdt_sA#MWP!QiKBqS>gE|yp|Dg)2(^R&Ib z-|+^Y*sH=dOIE*1qf4w_*w&T^&ax26L7=lKm5oW0v=d{!Q#sw!wK0l(v~-BPpyQ>> zp$6Ct+o>0|My_ru zEKHBq9d0Bnvdfd<<2W0hM~8T-Q#lFXP9!Y4?$i-9s8q{(8MtnKX!Y8V~>Vcjg{OtjZihS_cik8JWZ0c?LAJWBzP5L*WIPW&*7qMv5W*Oj z^Ykh=euq_Q898tb8^eigTLWjupFWoJOHcUPV#zFMk{>b>$;HcxNDD~6m9?zzznFqi zs6CD$TM<6-9z|PyX>xe8$%vafL}DK_`(6Z);$iD;evfH{8AmHnLnbpblkFl~&d0Z* z-umyzNS40G#@#r+4012~j^y)5MqMUH?FkAO@ctOBXtmEEyKjjmv_|OCw3wmUp+I z8z+ic?-M!%+~dEGtQ-`x7o|!Jm-_a~!8`2ukKC_KjbP*tl}2vLev7s6+YE6{lEzrl z)2+0L`5fRum7=ygW|f?L0+jVDd*<%LCAn(-jmN=NNiL(%g9C6|-^2?Da6=3QY`{2! z4dmIWh*udeQ`^}3Yo)|n3*evsdHD3u4r~(W{gPD7nvczR$Dw|no~#!uUB(3M-)Rih z-5EK(E`xha+^|`RoJPzJV=OVCuNoIjit$ZIn8)RK29ZyFepz65=Zl zUyn-6(g0fxo$Z@^Q@utS@c@4*HhXLqXR+drlb)*UA|&WgC*jZ_m|wmfeyPsDzaO=H&1-M=cHmbt z0U1bp{i5X)wRv8X23eJ$qQMZT6dR+cyJMVZnEILPjAxu#dqh-+Ldb%@<~s2$+n zu^w~z=m&OC=;k$NO}KrUvr{SN-P-Vje%kr@qCpQkO2~0G8&M#WN6V*f+~jP;(SlaO zeNBCyUDnQ5muIsU2}sUt1Sa$nrEPx{&E4CKKF$)9cNz)ZTqzCbwhudggD`EwCIF^OrFh6LTPiZa}23T}^=xJJ+d%4_9J{!TSj`VLzbb#5|BhxsF zY(OQnl$~=_8)Y<_z5VqGmfu?iW?msz)DY^;%GV|b75S`rx8*dZMMLO zWHE70pZ1+Dg*BV#6vY2zB9;T*YOlL?I~21Q*!YA>+dSuZG9d#SC+(4aJfK(m6KmYi zJQBp|Y02F2rF;F25XROu?iGuNW4hT`giJk~-@$7mcer&&-lke_Gx%(>H1V z?8m}Dk-wi(CnUE$!8vtSsuj2Q%N|9zX`Z0^@E?3kYg3+&>xp661AFQjqtT{Vrg6b) zs$=n-Cu3_*Zw1Qc7ZuodD@Pn+@D*~DAKui`_U3S`jO|l&y;1*<^TQ@TVj-5P4S90L z)ct-8ZC%Lqp^LQ!4rVa-%%kB2^YtLs6WimH9GpbiYZGnVchRWF+5zGcY9`OtPEO_2*nMnWp|9DEEm=}hXXXf_ z>rQZ4E+@@Z5O-{}`I4UsC~WX>zYf?z5aNy$ky`ZhryaA%?!@)v zo9t#{Yc@dx1-oem*j{VG=&`y_b#(2^$J@nDGyVkvZ6Q;SScx*3#)TWPwM%~wanjZK zwGH#MAr#56OrpjaC83Y8r;5l~gsA>{uB*H9)}{$f%$3uC562U1>;)h8u zNduPpi=ezkyvW>HmU%vbuE%mUI`nV9CdJ!D>b5{PdS4W>%deg&?K&3ewDc=|=~mpR zb+@V~z*BlyX0L1d3eq?2(}a@ik+8Drh3SISt4j}^y=wOjVLzf~Ml31HNzzS~aOkFL zx-C6Dvai;vc3X#jx3tK4qrAh@D%EVC17=9M!pv@}K<$x4k?$n-a5IY8>vUVSJiiu` zX+)b8tw^%p638$o#>x65?=UiFe%a5ZqqJ?tq1TQdd$AcP1J%TIPAc5--M`QX^D^b< zID&(`FF;hF%UrlvM%@%KqLF6SymZkww$~iP?l~!%d5&&#R(TCSkJZ?>vcRDCZW0k7k5Rz2n0Kq5-g2pN-G$zxu7b#&)p0Pi`p8s&E@9`0t zmE2(K4QwlG?}TnJXD+atu7%m0 zXX9GTT?5zs(mKX4RN6Z(;>H;%+~gzKO*7-|*AG+zmI*Z;x`lS=jMWq@@V~u*hx9VqTuu3Q zaGRdDS%zP1HE)A)r40COJ7-7tbs52D9Tt^~w;5fzsbgh3aE?%%#<2_*uSR8CNj*%< z9`D~t+J4vk67lhwmsz9baP@$idfg-%AZaTL9;KdQtDMUI&kRH`gv-idb2G~7(W`8> zA04S!#N2Ob1oWHGSxc{byPs|$@ct-NG#EDAVbLLL)a%b95%~jIUJ!O*R{$g#o$X{y z2+aD2UBc%!_c15*_Ay%F{kS{9FrTp_cDxO%T`|uEAol@6VLt>(s#$Ymmg%XBUPvZ0BYN~wh+7&OtU%UGiMFa3tzq_L78R=TNi3n=OE(E& z8(&d3m^`>ls#P6S@dY`In+Au+_^~6vxQ@HS6wdW^N)P3Szdy*iBhI{E>*rroJElEW zBk7@oEf||(gBBEVGb`G-`_<9e>7VV;;h3AU*PxWA{GsDQSYM)E$ule2K(;Gx7i6d zdC&eZ%GmAQEOQIh%6P)=CF&gDtEju&^u$ zFAh^@$nwjbn_Yq{_qBivb@tob8Xo_I$-iyYGUxU5%X!SF->ix%ju|Ik^P}aSw9mJ-}qshH%2@j#0myr;ezJDAYIZjKLIm-z(47fJv|1)6Aon#KcbVjzrE4jCrxe8%ua&@* zl~rS*Vle-p2z_SS9#=OGH}5N#-3a+Yc3fW%AlTcQ4h<93vwmIM>k^*{IE#Q?V|daH zXS6s2S#@_4ig+3)tWG(rjdn8A&-YT{No7TkKNn$@b+=-f6qAS6U+DUHIszcUgs2!a zKvtknbSL5Xvidc-dG<;hhqcil+L$_LR%c}gOwWXWs6UuUOmPc!x6^aM-vAulG zIUt%-TLnMXHlx9FkkrQkoOn~VJcR^2W6Qxfl@7Ov%3v(dq*CnnEfh$No7P4K#^*uA zxisI?b;pyv)BSzKh;oGmW9npTn$>bXvgW6DWH$i;6dKz4eXpr<>|W~K6LePfSnK=} zJOJtSpz@!)ra3a>8h`+`baq=#pX_0RH9i3codXL_>9Zn$&S_gY0uyEz_ae6=HLkp)*8FCM%V*@KrFHV!Lehq;YgY|BYrpbvbXAqsPu&zKM!3R8Ltl{cxM)R=_=D_FrW9W-sI~D}~67XAfR!{?bLc>F)E$ ze=Y|&K&s_&&$LtVR@M&}6U8%DOGxv!#|UjvH?J5#tN#j7#ww0ZOYx0AvJ#>KV7>{~ZZF@^&OR6nEI?-xeruZ|V)~sB6>w(+e^%MWYDcyd zK`eYw?gbp17?W^eba`*Mnx4_PV11*J-J{NHzbO6Gwj^erIn$soBPzXgMcC&z2k8^M z+sEEuP$fDfJ*|^4Q|TEx=ll3s1Jl@*^K)O!!;eH_tbsi>0jVY++IVcwO^Vzd=+=`? zl%9iZUD7J}of83oAAh}af^?S^2~l*_kZBTK`}h03U()m}Umxv;Dl%@x53k4{!f-R0^!d*Yp=_nnqbKEd|_LSG7#{QAlqIWmLWS7H`AdRe*}o zUNq39!xu3!ky%e)&&=x^ARx!XFF3s@XSjlN{?b|VOG4Ydaknul+-koX^FCLk+yP^B z`|>2~?Eq|L<{wFd=?QG2@t2d&My;Y$X~wN7Q|5Rda$GS;p{r8vTq3exLRd3F)CV5c z01oF~+)waI1pvXwrtYnld8S@$>6@U4?7d%G7lDGkFPu-B+K>%f{{rI;0xShUW~$L_ zFhz)WmBZ|o(c6!qVwbZ`njA+4HuK{8X}c2(_^5O-H%jNX&)XFUSE$vxD~#PYcYUW* z!aq)xk`P5y$rQZ#8{RtQj5+90*>t9Ah5+8-Q~u*m=?)v-{>K@Mb$ZBFYvfX#quv+V zld7VFglrsMj-~}nT*BE(V-pIS)u3#-2Sa?$em92tayCle5X)5U=`FAEc?5MQpi9bx zy-B(E0`SFUGO*LJ;jrkIsx?%299`zv$c}MKsh#6=1x}>SX5{aw&5N~z!U@m8O>O!mq_DZpKMq)N-29%?;^wct{EzPSf*52Uzu7_y6Oun0BE zx$L1w()~eks$#M2m)GRkt#Sg)b$`be9Wb{3;}jUaNZtKHyIhxH_9g`KCgd0(zn$}0 z(s5)w5kC`jReN}I?*92)*v3_+#p57zvary)AkEI7Kbg?9zMho;zd(@?Fc?w)ISaX-K4mI@$3z>yis4I=As+-1mQHj>|*Dh(_O^!gA1eE;)b+G z46p8#t_DN#_7r{Q<92u9yWw+e&D=BJQ$1F>Z*MyxM!e8$21ogNo=#~8kdE%w(6{lo zUoIHXX=mSQ3@zhOfAx_ts;22c=aCgth(XTo0c!TVFC{!D5~@fl7Lc0!=M{?HNS$V0 zrIoY;kPNUEpMP9~&UAB9f?s^+kA@ZFs?=KV)>ivv7#mSJ4w;I1POY1z5B9Fb0ifms z&&Lj5#;4O%ISiln6H)_L92LjqBuf@G1`nwBM;*=mKm_;|vn#>Amm(J?YxU@ybyfu{ z@AtP}?$pb{nQ0!dN&&_(wm3MSG77emen3KgtmMZRt#-ERvaE({Ic(`w7-V~$sLTP4 z^_ZKkFxNVcFr~T0rUVKDCYteQqnz#*<1-T^)gR)sAH|tn_Iq`jptnN)X2zaCL~<(a zieAuh>#KwiTCExNhg^qSE<3k4*tz%meLUaQxo@UhwFKaFQt=#8CNa`qw;}KS^MHxp zKa+bWb&jo#*ZQ&_7X74zO85$uxpnoWHRS8UZ`zX4G!m|^VDjUWz(KVT=eXX(t(ow; zI`NDavo!umy?Cc&BlEk=+rh?wA9maK(XGn**)IT_o(wX2oH*?Gr$j;GCV7qD^KOCPyh>X0^5-vNe|q&Uzl+%=Z!&of*S! z%_zCY?=-SgEek9og8=$wwd^8%T7W;6`EmmSI6SPyzRw`kb8ovOYJ#-v?RyziH;>f{ zE3EwR+sG!D824tUtwBVdWq0%Apslj|omJ%WPo&z8R_eN1_Aps`6FOp-O1dCRlQGpf z*&g|_YZ^~WT~g-g0NY%?fld8H9Qb`Qti5;`(aLt-IP!%zLucIyU^F|Wn8@z(1>Ys2 zi4Tx*<2wN-V;(&>5SwqM0ciy=XCh$?NV1wdX1}Wx{#_};Vi|`4AcU!wDD{B`ak{5c1wFk`0+X1|N(mc9|fJ)Ts58>CZ%njSp}sPh*W zi3)3!?DOMkjzI#c6*h)>2dq^#hO5sVlJ7U-8uA$aHX$a-Sz-I0K40f22yO7nop9Zt z;K$PWiagh-*y@Evk+q&m9ITuwna2I_W;%6#)7khE9oqXQ!Q?cJw$rzihIa=WALs2& zX*E)ekGc{pLfIj1T-zDgCJoQ@6-Nhm+)mKtwZn24W@~ZFwLO5ZPQ4*Mz*b{Z{$_Vi z;$tX9qSBYo`!WXOP>rqqyi8+bUYJ`a7+90}Apm=z5k^!Fpdj;c{$ML|`O@gur^-pC z^}zhpZ)}&K9zm0E{~Uf7Jt^EMnV;u1Bi>Y2DpT27ip;Y$XvM96s5}QW%YkO&aQnXi zH~CUKE{FGT`8@TbMHmV^$S=@YLrx7=zc+k>K511g%=}~X66Ffwv&j33J_qG4K-W*1 z^Rp$49)$n-n-+wteUznD`*dT!jnVX?Bt_?>29y5GP)~$r~M*t z+@Wc3*Ua?d-%v|V^HitM^S4J-Bz9`G9?t@NW^3Ccjh!2O&o$iRv9L9WXECL`+0t0C zG$FZSuHPQnqRjHWml}qeToj{12K)M=@W=TL8u z{R>$_+*$K7lbb(*I0FzusdM|0iz}e{r0OukH#^)}XXw-7OyAY9wWB^0`$3d`1x1(- zrsuSm+Ur)F9ow}c%G`f}0?YQ{n8F9pr4pvod1sk{yFWEoUAS?T9Pjww#s&jkF!2+z z@Ape={+EkZtLV~*sI|3v@>lX! zkARrU=Z7|0=V}X6REaWwGfk3<1RdveMvokDC)P&@*$Gy~)(h)~&D3}YWL`=U>r_Gq z3J|qF^s@{K?kvtdSv82TjLYbNAHF^w}H z-+^`+a`&kDtQTI8)#+2&fU3w7fhE1kNX$0jxeTXFX;a9xmm06bB23g%0(x&U66CVo zyqugrWpB4K5#%aD?R!_bF8uJ2B}?O0)Ayv=6v$;`{!Syw&wo~(*;iRZj@>1j-&P*2 zBfJ~&p*VXi&`2fZixy`O;NV`qgP|LkJsU&|;nWWSdC$dWA}EDgN`P-j&!tngh%!+= z+knWut>)wGe*4Wy4U}{(qb~- zM~iH{tSD``jDWJ9>H6Fbo;MK1dz?&j2ylvyu&ONpt$WewvJ+t;JHMNL6saY|f%H8Z z?FT7_DbImONxvgWadE;ati!phHB2xMyaDdf4=Y*#2^8Q_LK%i99K^r(S4n|-LZS(P zn#ajwJ{SZmu?}ndUXK?xeg~zf-Ab4I9^1>sOj5G*XNnC+`s<0bYP~9)Q{y40B(LBJ$3_=`o=-K4-hUkOk<-Z+%~8>+}%wr^>wu%Dmdr3rAJROnQrBYysa%J zxst~-iW?EuNH$kwO4vzwV`6K;wjDj@+Ak>RYq8^TG1ElU#3y?1^oIgs{tzN6tjb4q43NBDZIgaQh3{b- zUF{=O!V6Ykx}nzA<@LcbZuQbK%DhnbPo*ZTDPODwyB*P|P14^5u z>b*R-Qg@vZT?>bdxA5m5AORr>;D=7VT&Fo&3^zW=?3}yr_Z4}JB+X|cR^cAB*xm8* zT{S?sh_j||NWWx#oMho@;twx9->m7#k=@Mn$*EORo8+3>V%1VD zo@yhLCg=#)pd;P);t>dSKgjRLDHM|1*~0_J--EgmX7|Jf)Pj;tt5;(N17(WG-+S+$ zD7xJa4it=Fo*_$qU(}Xs3UZKXbq!pS5lfUPq-|$)!@$|0fVAbK8a@G@mYajSn$W19 zmC7ec>Nqn2ob7P1#?OjtBEsu`B5rGTzSrLcLWxROCSEo{blWI>#qb%>rigIl9;&Iv z1|wkgt?=eVU(`bHD|X2BP}OSeYS85+>`f-(+@6imqE1iTBU@#|BGHOuc3d}|ZDv^o zAqA^<`-41bZfMA>9TwscI{Q+nZBN9yI!Q&sW4swLXUJi+()Pf(o!!woQxy-J60~(WW-k8?r zWp^VDfcOKW+u>@R7XvsYz;l9HThLVRlg|wgwiQ%sn=4BTQROBO*YsDC;;s4*U*hEA z!2mS_NsCwusf}*MDHoc5202EtCsYJ=QQXQy)Sgb1tHq4q8}P4n0OTzbg~Qoktt zZgT|Zc+i=ByIJ+wo4Pr-Ldz@$BH&R5(R4BsV;Kn#AGlofLRnAf9m8Dw{#Ehh{so?d zhigYIf~Bb@cQv)JlM2)Q*kFfzv88oeeO}4Z8ZrvlaW~S?(D-59Y|1-;0iTDjB{;6aT zvYMSp9Op6s;QU!ND3k)$3nVFOYP?bvzGVzVx^YV>_x&1j#2BWC0{4!7?;Fo5qG272 zHxNBZbvwzi7PHGXx?Bmvi(kUGMh}(=)v7rtMF6QXB~WAG6ZPj52|NVF6TWX#)JN4N07_Srj1O>{6gMZaP0mq^} z1_6B(qIh@OIO)p)B5VWL?V;QK7fricuK8W*k&aHd?;}J1bQ|+S>x+M{Nn9otJGcjM z6MfSN`!#vv+<)MG)QBl8VD)&-`qe?`Ne@WxC#B#^6Soxry8AY_Z13!NcrFpepL9PQ z(6%OF@n!;uN52!W65Inmei6&Bp|hYn+(HF@JL`1pPtuA5iMvNrY4nhMAfj#G7Bgo zlLX9fe2D4ht9v`;Q?pOr8mVQK*%-WO;{lA+x>_Czy^P`P%2T0BW+3`qoUI*ri(nY9 z)-Lh~uEoC^SK7V1D|!}D*Xwso1e{N3S&wPOX%iBW>VF*kYw+))-t+UVz3x$GbfNQm zV+>Euc$sl~Iciu$HZMv$ z?w>410B|@h043pK0FncsO^ly)^f;wCkM3e0eX?-eQwz8sGnf$IzAwt)cZW)opp4N! zO00rlL4-x!-~A6t4^qYST1c4_(Wdy)vBg#v<__@}tyAk?^Z3&OXlX6RSl&Dp#`Au6 zvJt73h&fLCOFJ>Gi!Hijm5}^cVZFUG@DE!`{_HtZI*9;>h}vM|_V1XUI@2u)SDcLJ z$%!o8w{#hpn|0VyaPg_dz)ATQDb*Zck2uwgNB+JM3>|Ug71%$THEw8QvAJR2pQ(>Y2bsDIq|^f5t(p-(u9f`Ggy^#%M9 zLd}xYS|!MyK|BML7tCyH;d#ZS@K^euJbSf7zMy7xd2^?QaS+Rxt=mAE>m57*EOH2{_gW6;QR)s|4Bk<>vr4~4Zmt}@!yVU8gda$=!m z&2=ThU!p^*I=|lKxH<`aFx+!KCZZFGZfR-0Ym^s%HvWm)<6p`tkrBQ1<4?i^#Y_9pj!*Q3ccxnKuEe7H;Ow|ERQr$s&WhqxXEi&^n1dy zZ#!XPTc%>l*`7CAuTXN~-#(^RS7_mQ^JL1Vxx1juy%yd)(zaaUn_lmxb-d;mje?k~ zDmlD~#|E4F{o7iZA}w>)gTyhVSL9KMPX3+E1F(z;hqc_6Ra4-$PF7JFz0FoXUj+Nr^% zLry+tA^Sbn)0H(bMh=IIX_7vh%fR~rOK;GNQ=ODPgiHoy@$jPZKaUrrIY>dtdAOv1 z5N#s_a$0nd?!4Ep!0~BLuQ=iBUB|LZbcVpm=dsL9^Fs0WZVhS*DMMW{&!UfKT6zKaTd>zlStbK($fE_+sS%eb*d{zBLVP>z7=eEiLp z+bq^i*y9+28ZW_VuZvq}sWXzOlg#yN~UCkzn zWcZm(={7r{Fm_Y6puj$csSSln3z*iP{=Q|%tSC20jFgs$u-A5(@OvK+Gt#AqK^ns0 zs^55s0@aNX6E($R?N$LteaCt+dNxuIU{*UGacZE362MlOKES%%b3uzf#?y`N~o{Ji(p~Ri`hwqcr?3T;0COey&erY zrc$3Vh<|C;QXFm*!us z0#-I~*Ye&g5W#B({b|o8!a@066I%i#YCIcOJcrkSRxtj}qotP|e(zKlBDJbsR=7)Z z97%A*#ogG>G466oS)f|GBfbyBWDD4Ti41kEYa^p1-b{-6v;A^y*J$y;OehsQCanUj z#3aO$Yuls&UA@V#jEpUsWE~eiDbk}Gq7TBcPl*^Pt|CljRBiG7i+^5bOxB|978rkp ztBjvV2?NSq%sAr;!@KD)HeqX)*X#1{=o#XhNLx+CArb>X&-{uX_~fG)J;0+|o9eK= zN3i8Mr{6@&&g$|u$Ot`#cfld4DYUh)P=1v%(xYRYFG2YprE72KTwlEAJ+9WzB0`* zX@YsS!0HCeNYl2QV(kD&gEp2H-vq7}c7FDHlA1M2#WKoFFN%nrCk>MBNX*b+v}j+FcNqdEn_V?} z$ZDH@OOhg)KG;26^05}llN2Qu<8A{aNb?zW^E7ShR`NfUNVCfHYksu~d+*b@1*{J( zngVhv$`!<<9sl2&H-QX5E+3OQs$bJlQBeu#&g!+kOzf|;rV)o(;7yr1)du(e)(GlW znSom0g>?&Quky^AP(aMw-hLPi=xS>fdw!berit6W{2dC9a+DfVA6+~+`%&#Z3WRY$ zKy_inE?CVUsa^nL6=CO#K_Av-sWz{Y6`i%8PSAZwPm;I|0-T1x^_-ze_Tfi?0hNyPO75FSHD7U{}GV>BVZ3}RlM=~51iR+ z^YianXU!h~R|eF*?)V|+03yd=sX-zxRWy)2K^OplS3yWiz>cCfcGW3d3?>p@e zeJpA6^B0|$hHUuTdbjGI>B2{k-oD^3NP|kVm%%|u2CBBdbk&UcU92F1T*Z}eP=C-` z&yuQeYs%_hK2cKg`!`zW47nW$A_qV_Zjw#gVJM?{9A+yd%wV4-$K+A@<1?`01Au@R z6`n)wTTLf6u#A@&Lt7#0m6LnaJFVX5Kg#PQ;?%H}tgVmY*&`MutfZ^m(5BA2O@=(y z389ENsdZYZ#Nw&kYJBxqYdw@#iZF)RrlwLmU5!lvds3p9``uLJvSck&e*Y#Yg=K(_ z<4#TsEA}80Ir~CCkI&@>UY(v{oy^p$+jpBA&Ox3v_25l5Tbc|9kW*Q2z2Elm z!CLDWWGcfxmNOLCbTnSFuJN3oftZ~XO_lhNl6=q9*l8C$1njKZ?E}RwfwS5cY;HTj zQ%8h-JM1$0cHq#~!NtM$fwq0MKkwFd7?Ap9+Il}WjKz;u<1c`yQ>|yB+|D_oi$s#z zr`x858QM`G^Q`<3Fiz2R!`=5Y;k~~cSKO~wIFO}c8u~Yg^B8VimVyNO0HVVKGe9Ds zy>`NLqEhzL?;NU{^NM$XqWQe;Sd z3tBj3EisLS@}pJ0bG91Y98hdlo54lMftwOgH36ZyGVHQrF7}9SP(6yRs8)0Zb$RWD zBZ|TCJ3EnFa=XvrVQQvs~2m5rbWsI~eIS8G`Wlpfefx`>N zY&)fmyOzk*MasXa7qLE=pC>K$o|EjCtlYm4UXsqEAY{-^Z9xKH>;@uPz4fcCTs6w?7|59TEpJgv*&bjFoFWV7Sp!Fv??Mwx6@2~t>hyqs=9Dnpt~$T5Wg7|6!KP{- zP4}V-wY{QARA}quBrU#%shlzc@sDdC8d~Xkp@Xn z0OT^&)3K=o;UB0{L9PTAgsvl&XfPr-pHELzB zMI+2jTUX<*vx68QT{U_W@^N8Q>Pm}saGT9Kp*;VgEEy2oo^Mch8uWKsPwKMa=7284 z9{7gs?F5Z201tsGcg6OXj*;C;5Kus@$W(*WuqR&iMUmg^Qs-}vh}q>?4_=2<#`8G8 z;1Dz)qX6D|VRmUQoCFc5Uz=yHR9k{8!3gV4+&#N^BB)%AvpIg3dE+Tp&v&^0n@!DD z&(M2}{}ICMbIt}%Qj*%fYAzLJbc2WWM(jU5SsvodW_y-yD(RKoEOQrBPnSW2JF9BR z9dgnjNHOLzGFp;R^0rz!11$6zFvd=y7qJsbEhYOMHVo& z{_xysWSGCmb(=X*S7(<03ALYJ_3#1N&a8Ep6s=YHd!lM{V z6It4rH_-opSypshOO@3APsQ+qkLsIzYM~1 zO|Q&KFchqk1}~8{Z8Jp79j(3_Tlg4is^b@3_i0VxW#`x(Xh61;e(@vwhk%8G-0m`j z5^i37KHD4wbp!4EHGNOJk6@`)DZ53e=WF_Re%Y0M;@K#lq+O5Js=?8^F15&el#xOv z{3E^QC42>%oe)XW-ZVunAoPN#E)pQ>ZpM)vz5q z?s%mffA-fTZ<5$T)5AhDyOfhx65et7Dj80x#_*K8UwF>wvCh}AcBR%wIif-@WQ1Pe znu$AQ><+@NZbZXZZLhtPe*bvPGLM111M%hAC2I1UW8S-%c2l$1oe~V6%(qA6lDVh7 z)thv1wzG}iHw67nr3C4F>tEJoOq@3Pz(UcVDKC?Z6o}J^zOmAi;r! zPexH>Zp4wmNZ;Y2fM37=yo@_aHBv*3ojba`VZvy1%ii^Nw-sOe(Fri$$B637Z)oq-m1E+ceCB4A+`Wa^@JPjBDM_g_Yn&5(xxkhC zzfOYr?$)H@>*?M_ZMpNo(3fYeHniczk`6!frRSU94ObwB6zWBaVKfn>q5+J|UngYkAlB7ScMJe-0L) zooDzKqZ;E1twA^6c)Vjn06L+nm(1jhnMe*pj2P!MG@ZHk4XoKb{XXJ8yII@mnIM=w zNlY23u4a?Swjc5oID%LP$uphv%gk!8NRioSjFW%<_WUJB&}ka}d_oQZ>n*H{x%L;s zm_Dp8;zDG$F%KXVUHZK~rUxnU_VL^8FJk(4}N1FGLH9=az|MHQ(=U>8Vk+n~y82Q>+xNgm-#w zcu|W7;ux$$kItMD)CI*H$xN1vI;nJe5vB_p+!Dj>(or>BBLb=8rq$G4cjVTAx&3Oe z1)NtTX@b1cHO~o*_?S~}qtN-MWZ&_W#Aptw8ZIg42bc+yx;o`spCj%M>J@oYsZ$m} z&g^WGu=Tm2^~~pf$$qBIN*T!xlc6oScR&+|=s^>M3x2*}wsb9luC*Ethrx%}n^Qhw7PH?}$t)Jg!isyYh7m7Cy?_W*vYeXFR$zzjmj`iNWw=U_kn+56)xn{#X zqU`<>H@~=#SKj@@Ylea}D@o2<9XjXu)qZ|Sz~F53IBog%&aXcG{BF^w*0rc)FMRXz zeaxonvka4G^jBYLau#KNHace_i$EURpl`vZ9*vwZ&i}NHT3=s4Y9veYtp}glR8%xm z9&!{GHEGk+fK!Mh0()$^oPMI#{jJl{YDVYe+E2IYXH2*Q8CF;}<#yE_gbV5@M5lY@ zD8bR+o%PQkDVv^=Vs@#lcGGRIj-P21*DAm9V#(dmu{VwqCB6zupM#$W-=bG1C*iQK zc3^Rx*~`+l#6co`m;4nCc{1d^)O@-sOtv0heXYk4l`OKFt7bE2k2?IzJ?S`Xf!zVE zw(?sofuk(+RwJ*LrOLZhh12Tr|Jf}k1JcoUY75DXByqk1v@!Oh#t9PNI%G`gG<+U+ zTkW6hYh=w`_Gl1{L(Eg{n+He}13<4c+y}i*>l`O7y}scqX~-if&L}P|{)4oY@gD@1 z?09zEk+*wiL9#DGVy-X@HL>4$Z(r&nqDvt{hC^piplr(njhh3l{h&^!J+Qa68bw<3 zB)}nim=LHX5Vla`)%%W?UQPo^f1pv&Ldx;YX^T59aVIH#XU`!%o&<;_}~ z2@|QATJ_ZYywKee-#IVWMDl^AefaoXUF^j)F=F$^X8S%Ldn1hda|5(V1H$^J>E(Q! zfC{W>PH=7n6Z_cX_h7yPLOj5wvM00Fv$|0y(UzQLL$^OVIW@nMe>?lxW#LUe%7TR9 zbEYL+h<3CUXz?A$R?hu(O4Dk}{B><>^4R`=v9`lrDp50@!^9zg{=I%-uS|9(|ql*4ZXtp`6d)` zo@77dMQeLVB+@#0QaA5pn#n(zud}e*GVl54XC>!ta4X*L`e)-M?J6x8=UOfrizdgn zgT_$u0a9D}hBZADp<{<0UbLG2fx$Ve&VrwE&aGHED1}h}e`Dt_yXtDXXi;?G9^4_g zySoGk?oMzI?(XjH9w4|waCetLaCdhNdS;$?@6+yYxc9ckht-%?vuf6;K6>vpW{H}e zJKCar2Y@@^5J0AU?x>%8YhJ%Njfze?#2G3%F^WD3p(E5Yyp-Bp5zXD_Tc=uOZ>HOk zNXZ2vp~fNJ!2vE+(J{T!$#ma7s_P$*&6=x@CMy&?;C>(wJj;vLp+R1Myx|NSFb@iC z+Wz3MEC7n%%pXRMCWLwU&2D7mBHh&zvm;;x`i%y0f~X?{$H@rnl0N-;=_-F{D&^q# z*N>#p|7HyU6{(B=6&w2hCnEpLEdReK4+{<9kFn&Ar?GK74ByPwzc_1oIwc1@oAQDEN@ zERB(1S2dA0@@TI74|fT-I3v;CV86q-@aB9eL7-Q;&f~w1V+p#Z|95q^+5j8PD7k^& z;E%;qs4uYLq&GgL|0TUBuIoh@A9hIZTq)gGdB!9~|4xT(_y4h@-$lCFv*lOl??rps zMe4Wl@4%Fiu7=+z8?CfD3-yN_jda2#Wz7qkd`jiNgTgIOHHRlFC7KvtgJxIg3Dv%!MYtRW zfBY#L`8#lUJKC)NIsCsvKl0k5FvqaLOlhHWGiAxiI)V zPSb(`{rQF8>BZy2cVIo`caoZae!(Q!d=vENXtr<~mLLaCASuw9H?CLIf2Q~dBZj&I zg_aTy7ZFvtzz}p8w7ic--32)c0?pHfQY|0R$A5Km!BA)<$4Zw6n}X-LsKeQ zJpH$V5*LVMsG`2^jN!7;f;}SFM^&SC^KZd z;r@f;i`~(-Jm|Ua6upVy)<>6&@OwNhK81PM%t?ZGqQOE`Dm6`i0X`~IGUA+^6uJ$i zV2BzJFS_`5R(*BKzhhYDbeT2JTwoU58)Ylii$(EV8!6Q@lc;eqhBPx9TtQ7^2l({h z;p4Y!Uw`dpGAPy7*wubbpxWBdU}&Zkn=lborpyNKR-o!y+g z+P!XzJGe+PbOa@{Q)gWWFAC?a6>u3U&8be7Mxnpk*P6w!m(k0Hs%fmWRpL%r(--6s z{&7uVJ?V|S|HJGk<>xqPz%mi~h8yfX>Jsko{8PFeH>IiDN*m71+X7Jo8Pts4kW*e7Akgsj?Ht3#CXUJ{sQ}vD3i;(E zyvaVBosH1W6!x!w7|GDbL+P&}x;E;;LCm-Sc#(D3ZKgLz^iqOS;vsXeo(*_bUNFCP z)Ejj@q;|V1WzAs_B=bjMTQh;}tCo*@rSpCKrw!|3WzFP59}h{oN~;(JSnikKR9%Rw zO?f}N^=sxE?Jw+XQ@DCXPa9>Rdy>#8P%q74T^JVswnf)P4&d9^aMc)jQ;L+f69+F& zKiLT)nL`F_@}aH^ppxt@G$q}=yOisKm9Y535MbynRnPNm#VS>&I%L)trN5hIeVf56 zXtBY!YihDOqt1V@MU`Lu=H`lq^_X*&KoHdImLhJWlkc4;=SXZ3y#1$aFYNJNOH z0o@K3N+q3?Y1~_!JksZLn=ggTH%VCQK@PpO7bl>+Uoa%qo%?t1jpe#fyCKW8yx~8? zlEOhKu<*zY;F+vdx<`M5vN>hLo=TJK%fUWtR&Z3v zZ}JKRk_X2h5r0?8FUNJHwP^6o+VHC!Gru(X-Ok1WMJgh=^$b1x(4CEo8LT+no1+BA z6)=Vw^pnWxxHr6z3-b*}HTPRR;~Q8ZMbspGP+;XBB| z;Me;H?U}Wy;M?5~bVBRI^pTj9j9K zkoTZU1bZ@CvC*!hx`~Gv{0MvBDKT$w~r^rvXO z%dabToB!}g@~ljC+8zO4;}m)BMir?QvfXv*0w_5p4VzpoIWX_$Duu^HKdC@ zUG#tB%aWJrm%d}1M3ZB67MbUIsO5Kd=nq;FHn6;tH_M+TxBnr;b6{sSx`MIZyDii5m zmd+i_W8P5nJe^QkhIb#D3>9wfcek766H|JdMfxJpAW@@{H0-~|$py+wnm<4MNdvM% zGqNOrXFGYF#_^cew)s1;qlgerS+{IwRT9FI1kYp`>*G>Irl(r&KXOS1BI>1`aV<5r3Y!2=m?TKpRH+(bNn|R~g3)AELrtdM zunYxVW005h@qtmMZm;~G21h>jGTA~D>IB7%qF{tK($OVILuJ?HoG4M%Hu+3kbQE<`7qNRvcl!LkTa@Fk!DonGYj&hYV^@pYLdaIek9`dGh@fZ=q zNsZA%%4otMd5$bJgq?yO(T#P4qIxqoz1S zsrk3wniMgb^kr<7FmMGcRe$_h?CBC!_-I0m;M2xAI?0}SQ_fGj^99#rd*3PrY)r{& zJo*hzk?(Rr4Q1gQZ6e*5uHuKDr5wFXVFU;c)E7nag}|_05qBxiDD&CON;guKIKF9`_ZDk_v$f z8J&te>p}$St@f+N-u6oVP7?aZqa0zmiQR?zBDV76zLo*{cAxJ~PT{~Wdpj>(yda`j zOMMe77}_|b@)%T& zujEsow*@CJ95jC_Eh$QJVa$%w^dYG1KN-~E&Ae{nG)RSDH&^KI+e7!o5a4;ciM{;g z_HoGElN+|OV(~Gn@a$NabMOr5tLF!56*>GRzD72WT2t~v)<3LTUy*oGQwY=smD-vS zT`qR<$Py8dG2)yYTNElit=g4eH+0s?bb9|lv2DDb5_3I5;5>pM0)ad|IAfa5aBNrz zmfFRo-U*7RF{1k+BS;3mC4+-}JUGl9D`=pBcgF9aM7^;Jxj&n|#6&Jk=ERgct5!RC z@#@TUy&3|5MBpWcijs8J7-f@v;qwgd;8Mt!o^yIsu9s4pE%0_)SM>wRh-<}~mO#I3CU6^c#1Pio(m zb96MP4?ecs-Qr4s$3Vk)xmI{iTMqV99jMloQ_3S`sgCT}ct6tp?YN{EZ8&R_LE=gp z0XbfSHscUl6ji6Asr*Dr@0XZZf^XMm#dnQiNr?J|p-4W|G^eX|3osV6k2zWVyDw)1 zoBk-=&jK$Lt0oOqgMHL$I(&3a=Yv&2P-(FE`qRCBV>IN%%ym_oqvDTee{Q-AA?f-1WWz?n*K zO>C${N~5-CnSx(cJA>AnL}+&3M4I6m64Hs|VO2RrZ4k_79HK_$%OBxSmUJsHj7P)O z>p?!GQX;T$C_P{De{qVaHJ+3EcqiR7A3Gj4rqY!}uD>=Yul5Pu6oC4@;2e5q z=+e2_OTP#9@n#;9$Jf%G1-OhMr>zu#S4F?4a@J?1(V2$6ql1MbgkFJ+G&I%N*m?49 z^AU5GDyuvCC_Oo82Z2J3dRp3Bcfa70f4Ff+AdrB8vzN!~%P4SOebh^Zw5yjzF($uA zc-$=`tJPpejXO?cmDhJ>(g zxcIh`TRtWuq~s^cXi&{lvr2aRzy!M=QGKPwHviG&O^4*hz2@#-q6F+;lz$&?SxGbZ z`ezhu*=j=4iBq}?B zGH9{-RW$?oQYGFeVl zbAkk(qHfj)IgJBEavb^Eol=6b@G9&e0rZr+sW4-6J5ptsXKn?Ak=VZqt#_>uT6r|xr-8#NVl89gZaJM?L62^DM9?tzRfwaMDz(gO9QSjw9TP5d{S;H zGi!M2a}y^7!nlw!}!S%n8caE-K7xu6|zE6PFQhDiTC0- zv1TdcABwU!HQZezF-TASzMFy-mqg6XZ9ORMsA&JOq4Ghgq!$wRW4j9mZMEg^^j*KM zxAn5Nnt(D^haVPgPJsGtttn}4r43%I@|POqAtK79UD`u(!I;=U3T%eqZk#rxYwogd z;IPfjvSh!ceIG|27n^o)k9wg!o&nPG7Hc>DnZBd@$i;}0n?dh@PEH<{xGFBqg&bzy zd=t0L6;?(SFt$zm0A2IV;|HXIY;ty|h%}DJ7X9^2K;N4cPt<;_Dp26X^3kl#<1qw( z9?>HGZpFM~|G@5TcR8E#zGB+(?q@ZMY^O8BC=IjL?m({1v*ATZc+W;*r-)h@_HSyp!V{@8ux8?uTXD>%jOH-)9MpUMcFn=gF)UqmsE7>PLn17r!FQ$_m{UGTW1{7a~0)=c@mq-orCTc(`4 z%ZFN9P%`M-W)3)~q~OT(^-Qud$2=b6922Dl9tNRq%n!%4YZ^LPMO|MQULvKpuP0Bq!tSY*Yatcn zZm3&~KoaHm`U6`y;Gn;aXE#KIk2Pxi%gSGIUmZo-UnPctPpEo%y6|e_>s`T-@{a+J z>M?t9D3b0VAiMTGOhdmb%@+a#-NHn=McL23xora>~Z-^Q>Cw<-cvQKSf0H_kMJ@lj<;hC>%FSy)JVtD|tA?1*R_Av6ksfoY}5 zW;z-th+7a2g^6!K3$BaE#`N(GWYyFaW_q2vZZvF*2Js82J=Dq?DhaUJ+Ts$(bqPr` zy=^$mn4G|l82|_>l8CVS@wW@?plTmq1^Yn>6-dOK6;T!ChA)qB@9sodWR#5(yQqV? zQ3kt?pv-9KUIVvNvVK@g>??TlEh&pG((zP7(4tDWVR~!+DxG^fRIECimDVqC3U{lf z5+!&Ld1y~EhCIX?CBl1n8u7)>dtZkjr7tBZ_{eQX!$pZs32J|VXts1_nc-engKT!E zlPAJ%(%pHbwGm@I_!DMGUoX7tGf=OotuEd-wMw8(DW|J+KX-nNr9YA>pl27o==Rz3 z84B~NiMfie7t2<$a(@fjzhCWag+jW>jpqGTEKN)lmc;4RlZ8>l{Kpuj+1eF6$j$tO zi=`dYj4TZi#g}{Kt52h)p4n&HPH^nv5_m}AMMLi8nXdxjq7r%=UCgK#xyR&D6G&L2#vgH+%SGG0!izyR&F2%FnV{r1wqa)ED zeoY5>{mNA1U@_izhc;N7`UIMCWpB0LW&Yj5WTn>STAd+0t`T{<{7U4W0hx`^oPb>{ zeVCrXu}{hC*0eyUN%=-fLh4_NL3>8u9qYjMv$5-Jy<&cvDcJ-6530xr-M^TqzksE< z+aYEIt64GPs;6H!4xVDLaUQHKvKm4RSB*=HH+T6RvF!)`-HPn8VfvFK2QC#z*gM?5 z{)^wzDFI^7oyjgN{3K`}s;ivxo z9esP}eWwT_cp}*KHXKM^S@XJ*imnTDSf4K;Rwn!3+VK!XO7Z*tL8iXR1r9phUkh@N zM(t%55ginITBen~y*gC-vmTBG(-$&Q`35AZKuJovuZsq@1Fu5-G_m>U_!EC&hbG}l zR>$~G5AN!gE(wxGES&R6h{62T{$@XR{vfg|Y2d2|nNvlaD*VdIqiGN|MUP^c*n7$n zPuq;0sv;YJ8J5J7M_i;q0vR}WT+KR1WaaSu5og4wo;oGt@0NQ>ZQebaTwn2c8+bC9 zs}g}F!EWo#<`ywerteo|2c>`8+NPt)C!eiN>8q}#YAQ8f*|EE5-d8JfV*~dH$ZaUk z1oePi(@yZI(9$!F>ijmTzz-gpry#S#2ZN z?|O5%%{nl&k7m;PI>hbOBhb59+NV{USG4NhaY4bUZuq1ns04uU5frsfjRx2k$ z9&h286|4{r4geAyHVmfmLQL2F>xfyEpU}I7$~o|d)SB}Ouo+x|ycFnXc{vJ0GxfmysZ@>02&2k#c@~Q1&?Gn;VGPu& zP|USuf5)^er&lpC(AvD9-Iu7bOjYjX9>)p`7N%hc5XM3SekvW4e3F3d>%O)6d3o>7 zdIlvg1mqU*=1q2lZ8SOJA#dJmg|h`ff06vxD2kZuM%*{jHy{2MxjfjLm%7>8Zbx;0 zMQH8F<5VMB1ZG}6ZayWPEMeB&kPEaRjPKUQ_6JR#}MBw z&ZX@y2DlmKywhiXMIaQ_wgi^uHqZ5QYwd*1zXTdrfbui@&jya}JWP)m|&O z-)@rk)3??91d57tHEF!{l;J^qmG)*{oEJLV0IR zVe4zT;hsFi%ypw1h*}*F=bmzE;3JvLoZ!Q6b(2AM(CBsOCkc+X`!`bEr^Q0K*S%LO z^d9pmO{Z)FuyG9K2{hPi9Z=@+mrPkf_7X{qo{>diKP$&1W|wLo3#7s z&P`oREvLfmt*i+GApXsc3*w1naS{v@?r`GHENmWS!*TLPzQwvVB%MGnTWIYNT00{_ z1lEO7=Q$*vD8a*&aGmkTjXAKA*1^s8Ib5AewH5o@G8U|jEr`?I9#<>xuk*}aEin=* zj8+&nSI;n2S+J3Z0y)4CWqelx08t&(Lv8^Rp0pl~=m+^VbmHW~Q7ve=hC!QIbxG%^ zP%psiY<}?0>m&k*; zejXM)e{my$XXe=#>hCdiU2=%LpfB>0v5@C*s+;L3h*)pYdAsxGDb&DrA!dh0u2gAJ z8jEJXzW6PIEg`2%CcNdnF*K!+irEu&>&x}6ZPU~a9}K`0EW&@Vz4;a8wb?bS9$Mhg zI;1#zVu((7wkD@`xssil@^~TYv7KRU-L(we?yHJ!6CDVv zn%=)I0u^@yf5u*33`2|lFw|^J#Gv<(vC|5 z?@X*pHsj4#h-{nmOCIGu$G9`rs z)kbOFHF-V&{(3#-KlLbXVTm~HP$S!c+y$Gi{(%Sedv={-xK<^V^DrUdNJq5=-zvg43u$gVrU)iRt4d5Xdg|WsrtJ$2U4V3F5N>k;MTiK~h9&R+2}6Dv+4S^+ zeQ>Jp+*8t@ejikqyFMP+x(qt_aP7=z)Q99=Jeh23R&}ipQJ415-)xYM%*Ho!jazsd z870=%DSq4o?Dy2ERnc6Aww%yP%?C8P=%{MHzPt0g{fmw9NS;nYWT zW!QgM7p2;CYU#2~BkMs@9X3KGS?k(FrJx=Sp3D&8qT1YjyoYA;5Z8s&yKAXztm>)7 z&w1ZH6(*iV%qlTGQvKo}Nt}oJ=+H?%SlM)8*;KjcD$U1{3L|o#cuS&4F)tLW9m+zf zjKDi>V<^^|a_=fn#*ee-4X(`(@6ltj3e^whcA)9^`7$%-oC&OC1YwwmW43f>l5w}9E{TB zaA0y0N0Q@WrKBwPYAOs>T_TZv0Wp(xO33Yy{4oafpLjpG#H~QzY=qmG_424hG99Xu zbcghgr06Y794&2wqIRw22@mFl^>V}jH#U`wh+g#z!FPRyOg?|at?NlfH};pJCxdhY zoH})yj`ra@uBD%jeY*x3(NbI9qGg6AiTNYEppFhvK2w*xJAmTFPoqi6Q6yT&-*ra^ zAM&6=_Q{>}*cmW+6gsNwHHkI631)ToZm>LYS7WcML3Uz{xurkHxt>`Q%+}mFr*|4= zE{U{ZSZL-~3@oE*xj-QC3;r*eE$_|V+RyL{KL1ZPJ&s z62?i+xON+|>F{Sdg)`XFu7sc3WOt0(N|dzBktC3H-eIR?*}34rAaVHGi$T z62E&)Ce}mGH`CuFCHnDc$KUx@_b?1A4QGSE`0Kyid&6y>wzKb|#zVGbU_&+X@+qY! z4E^0)FS>h3DL<@>9NL=CS<(N%pGaFV>{Z^^M(*=(!)mGszM##|`DWz^=xY3_PM?Gt z)HpcKJz63K+5*@NSOny*nAy{oFg(=ctcPhb z)uiRBlFo=myIBOgwDybfIX#`y9`Ko3H}7%(jk8b)FwXBs5fO=XJ-DD(m-gr3dt32L zC#xkjAsVbyTd(6T+0iA1GN)SnG`gs`mQ9Wy%KxZDSF93r*FoaAS>K-_PPX4a)=n+F znTaD24<=U$N(~kn9Wc0={6|2kgoW7NB`vvvmS=5$8KORCQICd-YF-*>yzM>FEKVM) zu1^3o?O&M7({_vWBVLb{xg_!n_lHpV2h4$VXfZSLvo9D~+ zb$}0{;;Psca?@#7ZFMbUy=EIW&Qg^q8B9Ws+s_{Qgmm$(3Yav7AvtuhbEm1aE};tK za91-p=w%M??DFtj1oqHZOO*GQeC*h2S$LQaduI2Y0@-#R_Usu#Gd^zJN`}bQDwMt# znzgd6o)N4UD#KB$a;j2oAM~Rw8RbfbiwtV6xQUS2v8?X%qvxh(nLWC#ktjDXJG*g0 z7pI)W!FQzKu*S7-7>6*g_Lwj4r3;lJs>Bh9bX+Q?wND)qczd!C^`KSrs+v_U1Z zWgBFnvJ5%oaQ%ehNMR@UEi0W^`P9GD^qJENaRF;4FHT9x|45i*BEJ0I1cH8Y?(?^j zcgMiFc}e(?v=W(m7~{rP4*Ck!j|&fuGfkvZLXrVURPY~)+)981__zI|5FE~}wB^qy z{lo9eDTqMoLJF25(n?rAw$vQf2=wG8!NS?aPP}2~$dZ^w*xNb14>vY-!m2x6p-zQG zz%-&4j#1!9qv%?PY7H?!XWjpN$0^59Kb-T~rziFQ8GLM&n9A8_zI;NoVC99VF90$b zh)**cnOg8^gm3(E30uE|b2zg2s|Q)a!j>Znkvt;*x!DZVE_2lG^=p{3Y%mnllQf{& ze0+j;ARYuha`9*f+8pvdK%Sm zB+8QJ!j0b4y;&iBMw@t~SDESlGl39Zs}kI+zdozIgy8gK2CUJvRs=s+^933rhYX zhmgE_EY<(5h7)ot$Z3DH<848lPv*!)CMOgj5d=nRp=;?lNPOK&^GasFDqWPsilQT+ z>Frrx(Jy${kEQz)4Oh5H|MDOmAHX`Tn@8PU0l!T~y&stdLB8GcT0>E|-=L&txB>^D z(X&9VnDCZb3AYml4!u|RgJ2OPpE+Lgyynx~S~90#6Qn+<(Xb&o;W9BwtwYx=53J8o zz}y`Zonvm7D%&#Tp8E{5hf(0HTZRtWh$BqlL$rO>TPosK24F-zgHdRMgnuZ76!5CA zZCO^#|5Dvv=c#wd?XALYD*NEwy7ONZlSCweBLUK4Q&;ts5rwG56M)ce6kV721L$@9 z{TXneFKDl>KK_#p@f}hj<9^OKY-G(5pGc3l$!S4nw8s?L{rQ;b4ni8w2*o4F$5rrx^wJxaKNB2*ATM%dXjV z#4iH%Y}3kz>Vsx*Of>2(a?ndhz&rRP+Pq?(D@d+Y@u!(kK&H0S0Kq)lvJqGD%G+QpELqvXK&yndGq*uOQU!Z*uMH?SL@b(&#&Aj~7&ViQT_;zqnE`2D>-yS%$HLa23m z(K`4=yNu#nZ3lMId0tGSb?%G`f<{WPm!7}TN+N@HlY(oQnjFvv4^)*J;EH`j(6%O* zZy5Ro)^R2|ShSuljI=G&TNhg_TAnrtcxY!Th)F2JJGeAl35!7fQS;xMrd|yZ6Gp?F z_PtnnRs&=cAX}(Zy#1=Jt4zp2DE^1Vl8+{iu0HM?p(T`3k0zcg;Ml`DoVPTIqNCW@ zD>`=Gj;GbXXUTT$E3ruY!v3KW2HJRUhkTn}MR@^1Y)_~Jw}TP4m{brkZ)wBIfo!d; zUIs}wuZsMYJG-vAcxKCMr2p+?+Slo5Z2mIUNu6SNdBgxarUa%FyNmT8@)jnQSNGgC zx^ToeiXl$+irVGB+->@(u>7p@&+fU_`Aj&t!nx_xKI{syt{TswR+i;gxBEA*UN+IEne!wXUIMkAEYfa&*0Y_NrP|Y%mQ-!^F8qERRiJha}dOUQ*hVRTiS@1Ngmu`4O79J%56QQ!${lj8(dc{-`ug+aR|dDk35T5>SUr(qhjMX`gCRJQE_DJ zu&K&^BBMa6Tr>3yRj=#a`v{F4zbpSBAWvBC47q)d_yix~^0~+*74n}ZWm@d* z6N*FXb$3t?>P53=Cm()!(>%6L<3Z+?mPKjxj_0QM`dyu*JGON?3WgXZJ(rSSK+5yU znr0&?=k&8Q0+j|bYCptC9iE1UTo!8GUc&W_F*-#9pNELa&dkWv!^;J14_lIHb4X$| zIau*eShl%AteE{p7VOcn74ne2bF#s1xwKW=I9L*)u&iUiIR)s{W4kNW$|F?;YLk^( z5LvL>oRUb`p<+o=G<|c8(iPgq79iR?+5ac*HC(dl&$dx85 z%kqF)9LfzkAW;OP0AzXa>!(=8|Mw>#os<0c@Bfsw|9+2L0;$!1X9Dum|HoDTKYwcM zpJlsv?SALDaL8w|_$gog|MjQh<5z-D5{I2_;)X{O3~ex?HYSTmO;cVf|L3qLlrWG>A&|FeM`jgL=SQ%$x-@_hs`5Lp;;{Yfq|0FvE?{-;FwcReIJ8xz-*B{fP^ zz{w^C0&KHg2_`zExM|do<2m)UbJevBgVqvo0y=|{r&=xufRzo4ctTvnR1$#-w=)>E zj+sX5S47VBdzTQnpdILjVeB6d>=1cgWAN4GR|j0Cs`#=WW55$i;_s;Fa7;>yq|zRF z9x$AqeCeh#MLx~mn^R2>^d-z&dryk0_Xw~gDL2qJBtYKJ+V{4;TJoI2>yc%ct9g%;V}o{}3$gY*MjO zmCb{|zC-_P^bqSqxPaugjJ0Pkqrclhaod1FV$ z8n@Hlx7(byx#4B8tX;a4iwO-=QZJKHPO1)v4j>)*)Oli6wT=s$@jlCJWRVR+YVpYU z_(FPb_)qQ57`TAFZI?C`gCX#m>upI^1@>U4Ck2Z&;@E_^K+xppe3oh~5-URSSO zeROPZrnQsk|1<4%Tb`Cl&2os!S~Ky`5_TKU-WyM-4o7o`=LP>w4&gAm#{QlDlepG9_bNM52w-Fb0c&12&ca#~Tw_8P z>I_{t(+_HDq^LijYU+eg3y za4q^Ug9fBV0~xDQMT3yO-u3%@Q>Q7>E>wK#_cR^#)-D~6@ZT7leMocS6(|6uAz>UM zqlgbT^Zmu?d3OZdhBj(~92aKGzL7wt_R@{|8S3zVF9>7#+dxfF*IR7WHSxAH8xE<~ z+KT1v5zIFkFwwTSmU1(w&DfyQmz)2y5*;YE8*<5*qI+2%7bLE!v(QN-{)Ev34`^*q!AJ6f>zXH(}gjLnBd_R|ZFu^4S zBJS}*#cfqG?_YUrd?@&`8`*<)5MY41)*&dfq$x?HSCji$wb_$TrrpGUYt#%gj|eP} z>xbwWZGKeTEatF9P!T&w;0M^o55)I+U5+Mgv@Ia>NeTL^Zv^;%OtPKN6(8E?BONC9 zn5cdsg#?CqeH}YH%Mo~GK7K|7+(z%z^WmD?DH(ksZ^uN76)vIudb6+}BePhs!;CN@ zBLru*q>q3`2pDe$(^gU^nmbvvhp3Byux)gShXoHVEY5UuKUm+ucynBhOWGx%o$Brf zD0`FrjJteVXE}@oyDJ$#q z$;j?f4GOBFvEP&^bE~Cj&A#|!j6U$5dme$e5XJAvY5wQolwf72I`80?Z0i=SV23rWO)Ck#B!-_z-Aj$#OQ^{VZ5un5ioOA6FYpjk)WZqa8J%Prf6j-ad3G$YI*z zAOH52yo9}Z#hB9Ptf*y2cAF;)p17Xl;}9vOQ-a?7eBd1CE2JKcz}Z~+x`3)|iE~I} z1;2)T#5h^#Dykqr7CJ%n-Dq-FO_Y27^C^LK%J}Qo|9$D$C{XFi^c~!C8;&_P+uTHz z;5Qx+YrN{?(c5A_AdzqT?98FXlcHW67&9(oTjJ1Nvv-nHFreHm6C|zXr6X&-u0d$opRPZHi#S;A9lqzVoSE zDr8gMVJLB0ifcXG=>>MEh)G+46?>iif75{NfB1VpZ52!3vfZ@hc*7O>yT2BGBzH;g z*EhKj<;Pg!pu&5irh*95TV;;y*meOkqr_uq6G~X6fM;lS+RB#CqL{()aPQoYF(@ZS zVIG}Ha0gygReC93h-JN*TtioQHR>9L& zZZ;JJfyff44f(^5d|9bLsDdt26W&gjR0P%`13{HGb14(Ntt$O_Tq{iYyNGt_90oF(|$so%d=;;ac-aabeE|VV;Q*R#}iR&?2NtwZwddNiggT20WC( z-FXT-ANOP&MuHLWRw)Z=PWp$67ds|hL({%a(%lIWNK&gIVaW1W*V9z zu&qD3-KW1NWX+Ar3|n%a3PAH6&v}tD;*=u^d^Z0Ir|nQNZaSoG-5<_fUnusmmCMRY z9=a)W`xo`f1A zLE%kz4W9`|JZd)#w^M*n!KeU{0{By(&~1%4f*Unop%P`FVVmPn3fJ#zseCW4 zm~VFh8(>M(kry3+;!dIQA1{S?e!Q7xyQZP`5STcLmI`bg?Sn%nWiJPCvVb^a0=AyNmD}zc!r(|C=E+03OvZfoC^$>u5Vm zHbmHe5xQ?Mj zqnHKVCa_TqkWrjykK3J0E>~-e&jcjF-5caX@#R8bT0F;oTTa38vkw{hIcYM13Hw1i zZWg5c59*TiS)0h)>3>4|+X1$*#n_H#*?{ zT1HoM*u!4<*PsHgf7;ZOd(|BB{(tKVaUR_kh57}y=`~vTrycqaI(uKZUpt}o9Fr4L zu)ER>b~gjJVynOgL|cdyO3VxW3TtZiG&=G8t1)>SKc1IWXFKB*VBdykRNH{%&Hd}Q zCWDNd5{Fr&4HsEHF++iFvs!JWPY-A6F4`P);^h{1970bUa_FmeYnfhVomJxHSM$6gFUPhSw&t3s*P-cQQ@m%G zUiXIaA>b>pd>t^R-N5IVDqf_x{L|0gAUVr$c?Vi_I8#`sc93)6HdoWgJ&Nn4hc~>x5y@ z&DG3=MZdIkg)j9F=L3&cuv~Xp2OX1Vr3YAJ@$#Ju4xx^2g@?jV+nJ|?!ib-sv3vY8}2 zfBG$3lQ@LB&$^UXxu>4+o)~sueKk~aA6I(|%)6xFT?ym^`sku$!LLabU-pG;6kStW z+617&0bVZ9q}0MpZSn`+yKCV*F$@Tg;H-FGy6JYFT`%gvjHV9Ux&3Z` zNRYOiwtUm6+RaQA0jGHLaaTcQXviAJe#EpR|89GE(LoL(*+Ym%sP!&K;G103 zdju`u1}&3eYQS~7S?Bo%obVyloNMyI`=fhW96BDm#Nndhc)MCqvNdPDbxdhkyK0py zkbVSZ`jYA>_55I=cDkXl#*uyU3h6ajrlfcl;pLc*fJq@O8se(va)+RQ`4~uL?iAA6 zyu*xZh#lt*9OQ`%4OH8+IYaKP_Z`klbjBtZq;c1}#c3LwUzot{_4Ky^bJ||AYng8( z{?d?08+)AN?l~5c;7W}E-|`%k!N-Vlt5PI&PZ7kxUx?s_6=aR(@3lMJK7MhQYn_%F z+mGGULOPaCIq65S39~*{_cZQ_qTAkjlNKM_Gg}h<0n&&8Qlr&^3~oGL;cfwu^oa|< z;7cmpYNzxl?9O5DenJylogjAWfVL(vf@83gxmqULF)hge;3Bl&#OFtV$KR~x)4w|( z5k|YL5n4yCT(YuPQJSx3+WULF&xyMq<+%?_lc;dj$y0=Z(C;PnTN5V`NDov#q z8|dThy?xx-aLuV;(?@ZY*o>ZmAh zVSABdPx8BYsyV|7_UprFtgpb%_{t}Zohk9)8tb5jmt&wzsRJB#7S?7}VNut@F9LsN z|IOaa5~T$!T|F6C&Q#^dxm1gQMyenmpOH%DQQfw2rI)6&U&!^R%Q;Ou+S`!2(0bTSK&nSF3Z%KV|5MXYeX06d)8MuVp}jE;D<6$-RFWom<8TPS zufWJk`u6v_#rbw13#UBSO3zcExjQS>2yH2igCB(&A`)kDuUeoFd4Ep$a!WJ)Zxw)S zFMkMrpm76TxgZ6FwKG=uxP=}Y><(C$Rrz>Trk0HD7N^YfYTcL6i+!9kZ@7!XUd^X* z=X@MI&M#sto^pd8lFaI318McPB6dfisxIrl0knmqN@?Z-&1yc@^#}I@Kn2BMCbqF> z>y~1}3w?VAA|St@8fB;`4t3 zQFV~N>Bqw2K5felaC%!IKbg~E&C8832Y~p8d_(NZRNwhH122Tzh9{c#%kGix5!}o@ zJ&l&RWC=IDAM8V9S9v5|bqs&aJboi{qpGAz6%!nrJx6J8W)|Mcy|5u>B=hvnFivPQ&) zKR-rSk|(i6t%M^xQk!cD5^36ToDU3uauc_k!lb9d_a*OOr2h8Wq#kzA1fXwhxZt%9 zPDBu-h(qaTQW8|}H8_X{HRS(<2pW1~`Y*YqE$M`C#^pO|7r)0XJ;0Q;#70%Cstnb0 zY1Vc5%=(L83WfY8-IOc<5YPj%H5+R`S=!Y3#W$XInJ1iLRva{c8M?&H@rX_au;s2+ zfN65_sb$*GtyWPL@nyM>JD3EY+%tnimE!N7yJZK?ru?h!?JQF0q9m;cUK!H+3kgyUx1T?I~~<|43~A!b2o;c z#t{SBZM$ssR--yW4Fq7ED7Wg3p}k(iw5|r)wLXL-hR+C;h8)i36I<9F3lys}{v$+v zp#y34j86KRxieM9(+zUez0By$pMkU4@1Iop z|BGe6dd89>2ykh%IemJO(3t7wcsFqxWf6{QIds0)A?+ILamhlK1sT=YS+)&5)=rqz-E$H2~Em#O+A z8XA#`yfvuCu219JFN~a-=afPL@rq8v73WqK$OY0t)=J;fct%EOr+I&d{|#+MK5s&% zM=0uv<%_D@Wb~90AVU*Ll50gEuUuES>wUz|FU|})fZ!|e(|@mnc}To z1A$M_5z6Qy`ja>H*YS=`bJdg0+aXMxxKyTk(@a|@HOX^x8{<0w+X;vEw;1Z0?_0|{ z>%Mq6PJF zplE@5a3e+*2^Vx(5>!RESHqe$&35yH^8A-pX={A=%FJ>De^;>$Tg|1; z*K*DzSoaVpAj5Qvr)H8%a!3WB8+@OvScAU1T;U1#aAvCdpz3M|A?(UDjLhbxf|h}e zk}Hs{rmSpgDSbYN!m1Q1KR1VRC!Y^mBax5mz|4KbjsX7TB#8i(^U+2pLaoTIHd z0#L15Hc((1q+6+{>EEG38Tt5;L0~b4JMfT*=+-DCcUTb?4pir%NIn^Va?4L#`sD_q z7TJRZCl)hjCXM5igOC@#6JNSzy}AFFeEb;yD-Yp^JS5-IWk$9qAkuEn-f=371Zovi zwpb?7;nUU>ex?~UyG0h${mxOoee%2tma#qaWjzT+KfqaBaY?zn+5>?^e25B75+9CLh0XhjD|d_&~6%%guV{Rke0;zdVChl`iS&5+Id-w#uliT zgWDa<-MsSCo$1b43KP@@K<~vBX~LG64blsbZ@gi8hJKpmy47L}dIt)JO?>Nnu|^Tn zK)L#Sx&?NV8NcCN8Us;&Rp?5KZqX-`bA9-HF}K6vo$21PJj!e(&O6<)Nn*up07k@wF+5FhHecCdz6pz> z!^=5ecw+VxXITnpYaqg92W>HoZY#Y@1ZBVu%jeZo z)RfH7K#?<6Y{0V;1w$HF^YLpbVe`z!4wwnNW>Z~=;v33C8|XD#2!}G`W%9a*n|sdP z!S6CK+g{tHf6o20ANxBxgm1b?GE0XI1TGE%QL|APS)L=;9|M@uT|; zw;oh1UpecanNuWF8zQ(5Altu7b1OlX)kyLbT0W_D>lj+UJV2knkIVcuF0ayg<0_c-agh{`W zJ}b?H{Fymkc}K=?F^o)5o5dA8aIEq}?xPLY$RLqz){SRiT}8jo=;$^vS}yj@N_)rY zGLfF2lC;~mh`&IXc`~2cI}{HP+>7k&&`QBSe^9)yUf`g$Ig817VaO;nu7{`|1^u9B z)pvKUqj&AxIrddb(+A3SdWl*bAj7B&L4<7xAASrk@$JaYkwE!bgAP13DluLD+_i>_ ztY2BT^3Tf=Lj(24wk$y^amQq$280p5UA-bZlPHScrEKzZ*PBmPak%e1A75mELgxC% z()ZOC$Wb2wapD^u^9v5BpJ~I~i)$pzJ_FuvKUJPBJ&QwKAGY9c)!zP482-HJvf($# z{v-payO9nqsT9`WH;keYLCD(-(3-~c><8ISyqk=I1ZKW49|3;9r_n%{`{xBg!)=IJ zY2ZE$7xueP+M$?SxS#`8`b$cDoj{AGMuXyrd9zWWP*EA{qA`LH~0!~;R~AOOZXbDjWQ zS{k80QaC@aKjcnp%U}BujYs&iSpK14?(Pi#5HPBk);!6*FH&O&6(sWKxmG$nd2}Xx zX-1bSe_QYU`<^?LGApBBu5R>0xuaH-tYg~P{W>=4rYuE(V1nCc8PFTlL{+DCK@?Ce zPECqvUef`!XY@WInxcOL>+UY7?ukKT4zY+ zpo+0i^mFl%h`M3A0FJ&D*)1rFon4J>hZQIs&~Qs>xN2#Zq+^ZG05sVHE#KafuMtD} zS%A*7L%zP4pN?+kQlAQb^~+3N7$L$GK?RDwZnD1;I+4GjU5CtgT9;gFl+Vt3PA?Wi zX0;*O5DkdBczki8qPWo350w)-^s*lTKT>s5k4A?t9-n`|S@3YJ)~Ld|Z83PtEnQeS z9UVOp$n;=z%_vpbPQD7FT1V?hF|s>`H5Ajhvd*SDX|a?3ZhD~N&-h%!v3JPwP~6k* zCQX~MLeTmRgbqD`oAYa&!Jo4Jv=qHv{}-GSzdrgC*#EBVNTyi4RheRQI&@FLI-)Bv z%7#v5d?+=-fN9PrvJAnYJE|tARgJ7rK0zrxfo6rmU@%qs?l?T+cXb%e-rea)!OM+` z(m~E4?%oT+moKT8YDXdC?k%i+<&r?%VMEqK;z2kXjN_+^;_hhNJt}qI)as!Y-)#L8 zt3Pbx+{cCJhtjt(vunYU==>GB2F42yEuzR?ha%?vsXw6QOjtjdTK55A2SxVa^H>pIME zqMy^wXiW#Lik=&8(j{ocztIG9A12}#nP9v9creDtWXJNPTj&a-uHi~n%{Z-jh|v*6 z{m{iF$0KjtrR2Nd?UQb!hQriz^?F^2PD*5>Tk7TVjahifgp6Ne8{JNGC9}h)pgg+C z+3Jq{)%<&sxtcU?n2BcIkrKfRLK^`lZxx!C`P26mH?9CvzuRckw%Z$cAK!RF!Za>Q z%=tc~U=|;V!GlyjckY+9kBI?1-h{?+>}Rp9$({~;=}1#O z6JA6tC9^kAmN~9tm;*6kYs;W1@ts3aIJcEKueS#yL5dLS{+;;gy z$t)EVDf5&Kewv=G%PH~uC-T~hrpis$?@^87`uXn@i@pSvF}33t*)nd=UUXnzo~G|? zi0;Vw*Cw|nM7W>2_PHq82@aVb{u%OLC4bLJye)V)d2zQrI;(lM z9|`H@t!f=(-B@U^OMO`+u9RZ$VoA^my5*bMAUcY1Cc0s~YNN1m^7O8){0nN|qzBv7 zZ78NZ6}%JQY2o)Sitcc4$2*2M+5TNf@~sdT#BnzM-d3)%&r|Do%DXMQ`=Z+LpoTbX z&U=*T-9}t1a82wQ5?NDmJ5QmCkT54@(35Y=^^iS<56jDfF(dD=-?Tycg3f^4nJ-%s zqdEx&$xd=x8P)Y+{|SCnH7e-)=EdAY8vQnv=nSU`)_DqYO7&1$^^od2>G1sb3GDc) z$2c+g4w=b9FK%`BX*Q}&q>JwH_Q+ss7&2M}cc@A!?!h{zQ+#B3zcrIbpE!&XjE6O$ zD)R!aCW?C-Zu!&fWkF>hSO3RtZ;u~-9zUqKH0@}ILdXjwB6-v}CfckrQ^B8dB>Su; zwW9Sg36Ij~O^-27yVOoF(HQ4KsaHE(E`rZ&==_dq>Z<>66-bxMI_o|Jn)tF}B(RN7 z9Yz$)Dam6VPJE-}4n-=S+aG6E(mi!nS6z!bvfs6=xqn+ zt+P#1@?G0dPk>tXS!V$EQkC(vM0$>3-aUTJH@?p@K6Q|%mql20mNe|}=@`skQqNN2 z2B@_TBuNiozRGP;RIWuj^HCFYsHrj$Ygslc=L1sbwmo%%hX|B6z_1T~q;JW-g74h$XF;7@1OSMuLUe)i&SY26p#k=O|)AOxgH1}<(?vRmXu0_W=VGD2hwIog-n_KG)1(qM?ehZn|Tg6z+ob%wk zLOc-5#Tf6UpF>t$oBy~!&wVnz^%b8iVz1IM#f65p zhybo=Hp{8A$T$)DL;h_X@z~C=>+*U2iFs&9ClAK@hPw}Mm7l@Z=g2FM;l`|1feZ_C z@e=5FIw)}7-Yx2?RI?B72^K5}*Os!kVZ}XG{-zYJGjy9_V2EQ4nlnYP) z%4$_JvIiB&7I0nfz(jrF^!Ia*Fmv)8yZJJ7@Dbxy+dF+@ehHVmsh&*~7W8}2z&RL$ zpSNdXgXcq=>~UF(OIvQ->93zJ1-^#G#wj*wcBEBU`zy&&hp@%77%U$Ph`uo-&(K6Y zd20%l^Z!Wbwj<7I<5)51VnerdJgUWu`mKV9A$ME`kgG?ZauTLvBiuPojrxWwL_3F9 z2jQxlz-a~ z7^n1zmrf&ySNjy|Tvt`I)fOlHdTt5TB0|OMO|7E-! ztL&gaeo#q&(ZsiHY*(>x(?~UCLZ#6>z;y#t-b!|_hdF0yY?ARHzpZLP*F7t+z)UQz zspuwB5iT$NQJ**yas)X)Y0>u%dGS=ug5l%siAgnTshdGIr#i<{HeOJPt63UTUt6^E z1(Rl}!LbFJU8?%Jy6#y&=XF;!Rue^+bF|Ix+W$x)6@LHp?&n1_or;su&MB+lyscgR za7EIfluXo|e&8{fQAm%^ZEK!-G%44@_^nvMPHXLk?ipiwv8KbtOj%S$EGn3WWpPOar^ zsgQ8P+5Bt#^8${quPSHg-Q8oeQCmTn1}6qCc5Y>j=0S4jsI*4eUO`aBOxdU7ClfXPfnSk)XZPZY@=-Ce@Csf6ySy^O z{UE(l!h{A`L71nQp@Xe^ipkmX0x=2c`7@d*D}~eN1Ih+}Tq@$D zEDha-rw)(g=S-ldW6hW9UX>XZmwzxU;Pjtz>+!Zuo>%HXvJ!6%w&L%^#xAIwem^K> z_I7H%pPr-48eIuJ%V$A-lrui$c-wo8S!ojoOnm+mJ6G8W8GN^<(A!NoE8X5{7snC* z7feako`O65_&3$mA#6f3N7RIhmY-*Q+{IK^17=DIM5_E9>9xBE@MjB}BYr*S9`xJw zzpilq_s9Ro8Z{QUpz-fcNt*iooJpZiecdrU`nw-Fi#etjx~k-UAVj3(*2?j3qO2B9kI&v`W7Gi`Q)j6m0#Eun z{wcZ-D+Z1QhJk4-^N2kO_ndch@&uo_a_w>K=FGsaMDk!Fs<|clewxB7u!gEfHxqOGV-C6wAO#-U92Dy?rrBI-<-69B7ku@oxdMn}z*5uuONEmd_r8Z3>VNOI#c zyg1gIxSASlFG5*4A@kZI!b|EWxI33rHhks81O6$EoI0b^=vcAH&u!F``)UJtNof2- zuj1}LuaUq94{>7qaTFxf?!IIQq9qKD?a20x%UC*AYFT@o!Jw;@2=v5*@vuZnuL@;8H zdNKElcXC7INK@$5@zF7a;oikfaRxq4weEy^|Imcp^9_eDqFq@Xn2E~!ewGmHSA76m-o@SDCW$t*!jtFCUn(94%P za(0frbEVgB5|c(3Hr2?#b&qcR3o5s>nsT+%GS(5$(P8D{Z|St~->N8zUu#xn0@%{& z7|$l_%0E;TmwUgfFg3La+3{3o#G2`R%6o_2pA3&xZcCHmKW0=kw^m6o9A(ffHpz**t5C{3rv z?3c~M7eg;_c(TFD0n^_ny&Vvc?aNCLf4qY1B(e-x1D7-B6A;7_cY{h_&CqVoQJ*9ertz*Rr`*$ny zJZ8Hy7fewCQ%d*eWzi0{_Q%_Q-VcA?c#za#X$kd0ky%d9;-7BgbMyCe***J_ZGFj| z_~Dse0+LtI%q%!Uy?eOR_H1b{)?YGesZe6cJ1#}u&J8Cz&j0EV&o&No zu{?W{e(8QasXFp9IY5VaSKgK|JRs#z(W3#!qxSZn{Y(bDRA-6*+%U371+pb`RUPnm znp%29oD7#8&7CkgI|)aZetIm3|2wj<%>Ydc$ufit4v(~VsEh5FK3&58_GSXgUeH2Sf-4#rWn)t29tkJ`J#tB|E? zCEC=iSiH63u?3v4gKi{(R&uevkf={ZHz5F~5k!x;!Xx&yhgkq|Reo_V&trB!2GyDe zlSU0Z<+6>Or_2)m$wxWP`szSGKL#O+_Me>J_VK@Uf42B)Qr@K59O91m%FODlIbl8#ulCS$eB5| z-b5ni_Vrq|<1tt&NXB$nipRK-so|~gaW#D4}z-l?uvs!-WX3Q=ZI-i&2&u%ozD0O(CL0(IORWs9|GKP4%ec?ozU>vahBetl{h*!_b zk~cM0q`anD2e~uDXSZ`Kl((e-y2J=59(cFAG-p_jqbTPS5LB>X?4 z^rss6C?^vsBVr`z)a8%KT3kh?OZeMq7W!2z(L2X<6y+!lkL?QHFB3g`j)bE*9)7up zleCUWmv|XP9hl{GL(x#t_Iul>aB-&>el=p+GLiMs-&H*fu5D&*akUfu<&pN(NloG{ zZ=gFYYV69yOIgaR%_b#@f8rRO`HOOSntQ))B;)utF%pl|ZXWe$Roa4u-VHicKwlTn z``x+j=4&Qyqo*F zRq)_lXdEo7Rsd}@?*|h8Q@v>)_FUQY zm0=;1n<7l2_@?>1!HaocKdG^M%&jp;6=i3r4=@k&z_kvuyutdPPXa5(aG+Mv&+#^9 z8QVEFs1p`qdOz8)bNxn`>=ns(-AXxTKlGI?6Nb=P#!eR1m`6^!bgRvG2Ui@}Hm92c!3twylA6&A9s7D#t&+Eh+0?)Y zg0!Uw>_Rd5_UkUwvG6b&<+PQ5Yv5imMBTL;TO^wcWLE5_b zP?n@Zuu3|kk!s=*_DWpBv!#uQhN%tifE^}-bd;gSjRxeQUUyz);B3WFmE5|cFL+`+ zB1TW9-Y(84^G&DHX3X+WbbZ#9Y!DH5I8mr#aj=dwYqCKq<{dn zh!br#P1yC0k56JVZRhyOaDh2+BCs`{>S?sgGBy&?IbdQ2H+OJnVDFj%m^#d0!;fDM z1wM&QTL91wHu`8T;9WuvHbkn@1QfXqX1+(2QI~)7g>mieSOr&yNQg>Cj^2qaIjfqR zo<*lUM28|KeU3EsQP#3xAn~6fr$Z?hCI?WW=HU9lycoVAmS!=wLM$vXdmDEBWneAs ziKBI%FyQ>@?3Sva;1qE{*zM>{4Set76Zy=eRR_%WuPPk!97b!4Vna4IWA*_b6shmk zGEjeh;FJe&=BP9+CwIWaY=N_1UBrU24wZI0k@y`WbpS(KNoqG!`$T<05gJT&IT`t& zoMB^CzS-NGL9;1qdK_|3BkysbEz6?yf*|i|2PTorln8$Spce<-T3CO`i)=5RLPy@{I9EvL@Ks|SQ{DRzaZ(~!0MTC655}BTKV|YCg*A{$k?vk z(l+CT`ZV)2lXXx1U0LA;@^lY80l(uQ&+z3hewW$WF#1qz50RW6G$UZmITD-Y zj_Khp92JGBJ!epi@^bZ`pbPxvV!fvII$=SJ7&>qXEDMAQo3LOb+$-fEQ)=#kQc+|T zJT(sG3_a3+u3cGHKhf(s?d6V5gIrC2OhQhq25dNo zrp&Zg>v#Uh*7<)0V|Xi<)u=Dp@0 z70tf0P^8-t<=D~fDwJ}Ra(~+k7Vp~8CtN+xXP_y?VzNCazGR04vp~G)>~vLTraQfl zH6wjJqFgt>+^M?*nYId6ZMYZRD=~5iNod-$Cm0F#Pu_a%2MR)G(Xqefa;tkyz48bt z&-_}^m9aYSLn-3FH2jUpA=1{{$@#BrS9RING!{B| zOvMFSt#9?%6EXM&^i|&bROnQB?|U^5hjK&SP3{~s&k>)YinJ5w*Ii%#on29q-;4ch zZ?H8Sg0|=A6gxk(Ydyy>-m0#~!R^!1*HQw;QGe}c2;xeBc&W-O;-L(wn!%+h%e%Wr zB&O0fP8E~s6Hid~$OHU?`K*UzF2H1!__&;k{gAB7hQ^@eUP#4-PEn2`NG#G_)lmLR z<%L4;^KU?GvwWZvesHVZ``hpvsf>r^sN+3d1)oMN?(h>-;`4K7GkBJH!z37_!FP zyNi8u8vL}dV0E)qXR+k~w2Uf8C}J&8AtXp*;O4K3muOJPw_Wr@ywGw5w#!q)rNXBp zYdfs}T;Ay(?j2c^Do2>5hG_sn6uaG7H~wit+r68KAQAp{sE}2m{dr(3MW3y;N5I<* zQI4!JfJiUKuDr74Ho;KH%w*wcDUi`GLc&?fK zn{t!Ga=$4i+0XrftP^NLe1tsU<0i?oF16%G%zA0gY=S46B4MK}#6?(DO_#PYVE#l+ znidS$?`u{%Mtds&Awv(z2f`M>j}{ncb?@$a)!W&<&qF<#cHI=uGyZblKZ^;k7>ydc zsm`#p{E;xUih3I%S5(w<&3%nv_cbH@9Pak;6M{{;Z&Kh+^7Q?`U2OmlL-oCqcG}i8 zemg-l^k{zg8f3E7?kJ`IgttI0m7}uC9Lc;JgZ$wAp^tGoRVTmFfc(HFy9dcA>9hw0 zr)$U=-h2*_O2?+h5_HjIgy7S=&0%{G|4X08JxAli18A6C=ADe=K9I2_+?Nv!lV7cJ z;>?6suSE%AdYZMK4SSvzF^Sb2C;t4oW1OgLB4;R=S^}LTiu`Vty}1Wl^%Ubz1oZ{k zif&aE&1F^ez)32m@!FeCi~^-J3H|19^*|*)j2Z1wy#1oUe_@DPItD+jSl*x+e8uNd z+?sOj;h1BZh3hIz3eMSvE~`o@Ds?f}I&t;yTNL!R@U2HINn5?hYt6P2tzSQBabkk; zvf-wU?SQkOdiH%e{|NsVy^Y3aDbrb(_emJxWyZo{>|lz<#1eKX8@KA%jx^TU~hdcd&+`Tr9$sio5h zi}To$_OL+ZwjRz+G;^CGE~*oIDi+le)<-$gSMk$E^f!&kg5#)d;m@GZra$YKXF_ZM zga7md|KM}#FR?!r#Bn+MZ!G=g{0IB}yzX1~1+M(+nGk(EZGa1_>Hlu4ZpUFQ)>gAp z*zf(CMAxXGwau~`(tKeI&F23p=wm7qXG?=rd6fPxmKXKB`B58~A(DOzzP~=$yH)GC z_I*o#^ij%sT^TG;IMQV^<79d1QdX)ORRj1gd`e1t7D_}-Tx&){%vn9feqmJa{b;eI z^zq&oSlD$nEVnyrJ1g;jd!z01y>(QiTxH`5} zuanpTre%B7QO^Z=wPY_{Y9ua)=h%?nmw4BuaUrUyh@(=M2xGO#5&hE)+RFS08D5=7 z9c5B2iZAYFz{?mneYVo^?)P@F8Lu{MW5AwmeU>n(`@8rG5P23<)o`gVJj$)1@6)g&vf@yy5ykhVNrdi=(8mvHKiu4TOeY8a3s`Hmhv!7rU}qnuKN% z{+1sLlQe19-!4veb%pf0MLs$n#toK|4+3{9rrrzR$UI4CnWS0K`Rw_+!$(+n*X7|c zK)TzbZ{E+!3UU_&Zv2CaYG6}2W~p{R%_uJx-2DO7BV{8gQ=qZUamA^R)bbC3FDfP-Ygv8QebGRO4+bDAl&8JBT~z*_8)9K{EH5 zF<9X=8@h_$6!5XWZbJ61stL(fNxl~!bm7AphF@T~pNyeUSK0sKsSvJ*XV8ln2ea`X zsOR%vLeMlSivi>7Q!tD$l6b+~Y}*+?xlMu{oF}&)1{NSn^7qv|DQ?bPdQ5 z-f~Bx^+V*~*4VjWhNT{bkd+#SpKZxjuG2ASzZm7e;ZOJR z9}J=2o)m~Z*IzafXd1L|#Og|a2gnvYeQUSI7>|l-8q|;OF$IoA$A(|r?e5D34vojA z8&7H_MRdgqkGFqSq{7MI+cwkn)EeyZGB^h+)HeMzX#ef3S{K;=HkWAjaZ`Nva-P6NQtBa!U8Zi| zKQwE*zx_}BAU7oQFOG+4T7~_$UG^)J_*_mnoV4f5YEltKpOgYo^EY_5s%jR&Or2&i zSM?Bui^e5%tXk6TyXKFu>>bqO3+$O2>pGB2NBvV8PsD8rv74o__f%+bUD~EhF zd!+4I1t~@g_x#@haQslZMd#OMRl=W+ay)hx871(bN}a&@Vi=2G@w7+XfH zw4W~GEOfzxO%$}VECE^Df!-q+6Esn#RFx`TaI*44NF(i~oCd2l2UVokx9*bbOYQ#_ z%MkjVv;J!vwD~38;R5;#i4)?o6?Q(BI6MH8=EXgn)mou4=~lThq2vximVd{nq^dAm zbU{@ZvD)x^V#Cuwp^SNTg{BeO>lk!(v#EV{Zgo3^m01j!?JBw5gT~Ua)EPLYOcS8V zElCB_RafE``jU9G(=3!$D0)ZEG?`>dA`%S_WzoLi_~r_0`0gxF9m4UJ851663@aP= zn<{GgQy1grMi1|CvASE{>($U2d@7Q!wy@KWKTEVLsNx59g6fZ7~BujCPd~`#e`_PD*H8n6?AV%D_2B=C)-XF%*t`u}aY4Dp4Ohe$9&}`Vt%v z0@D>^O%}2Ak=S}QTAUG43rlH1TI>iiyAQe8w7Eq2RBtCO<6Zv-Bl&XrmI{nYIte7Cd zuO~B?kPm#cFt^+;QC}t#MYHG3xke9hW|MhnBt4viaNIdj|4o+JaeP zfzrKYcd(npTL8W6ikCp?moX9Z(|xMf6a0n5;Gp4GyH)zf6N3n8L6ToSpO)}$dujZ6 zXhN(07@pyyjKFW~JIBtOC-K_j6S|Cu#bYP{;*DiavQiGSCEQPBaZ=UN5`0Lm_E%hy z&&(@lThMa%`nR~blRo6r0A1bvkly`YfP^yd$?{Z`Mw_~*m%N}und8rn-7lhy8u)RS z+Al3@#WxYZzds)fHm{Ni?eF4_3M?QJ*q72SofY^vl{r{cMY9r5voc-$QAu&?TzN=J z-qlp_s;6kQXeA*_`v5g?gI(K@o8*L~2*yjm0#Rvi@*b!Cnws(8$!ojnMj>dS{y)KHHxUTNO}M+zJd<~bTyNk zMLL)Sv7@~}S(SN>x}QesyT2WF&ZBl0ijj(VSEq%`zIFIJ=pV^gxO_B*>k~tX-nC?@ zPkR;4lFJG^;>$#4rzEA! z{ofyeJ^mLXNQS!tQM<#hpU*J`S?V<-&iUOHU{0>LcSHX}nqDt3o#qO#BeYk5K!(DA z7#Nf`5ykP>A_=%3COj>0tpuH$cry_H{18@z0)3rAH~#i)+E@}PkqZS9QhepY*V))O zc*paUXXlFp0l*>T(+nB_boA#D=GS~UU%`E_?ryU>4Q{ploF(XB3Q@!afdbH8hi$Q+ ze79~edek)2v&9Z?MhkD6W}G--P~tQT@Hr>Lu?h*o%RThJ{j4C+U#Nc2POg9XS(C8b7 zqQ=CPULO6H0IT)!_3+2K*82L?lO66rj1^4p zj_pL-eO9bbCrF^*IIs34Gn){8ewdL+Fnud*AS*9}bUXP*ptkvZo=cJ|T+TyQSj;Z& z#NZc`z!v}M2DF)FKx!I5hHKLKI_5f>8c=fgMnSGUqkpFEKH*b=RlH!@M~oVW9`em! z2WQ?N;&lxLT14`nDo@(aOHbBu5 zP_rZ9&yf^(uD$p>ZN)6TuenYKHuyYT-O%G$3*m!0;HWWyfbGy3a=53`Ti0|!nLAb|-%rf9JEKR!g z+5tX#{WaSFVD9gqtTqYOpvd_%z%ph7^2&HKo_mUs)YZtGJfp^wKt%fD9LmbczBeHW zXDuddJJiv6-_S@StJ41?L6CGL%0FvoH+43@$qo;Ha7-)N^gAMksTS~uHiG2r~ukqWbRU<*=6oUDmte}yyf(`$2$n^ek zC~cNmo1scTTbmFdlED%A!1?sZwAOiB?@!yM{vqzWN9Vo>xYw#qNA;)Kr1!fVr^?ls zdpQ}|VsQTp8xYBLHD8Pfmip4gx)4Bk^>`vp==&K8qz%_*00rti@3tC{y^L_b?{nE* zmp>2k1td>rXN!P<4saw%f|i%V3|eNvHDoIMNddAv8ujV_py%vz@?v?P znktgcx7>N3h3L7vAwxxaf{G}R@UBJH+)pfA{B?u3MuPU^+e8Nc3%n1h8D<0hPL2SS zRTgsqFQpHm`@_jN-D(%1wC}$#Dh!~HMTk~CGnxB+%d03G0I>%Il~2nPO?+nvtt#_t z1>7Q@u`d2&CLO)2V++d(~+PeO0M~HYa*#pMMPh4_}Syl$h|rCwWvCR zG$49&Ddnifg$;lLiD9;>L4ibWAU0NmrK?t?G=U*aRMk{epLrNvRYP)`6xEk`=tS@S zZYTnr9ne_>h~WB1!)#Rs7s;3DfG83WhmHSZ^E_1>;Cb@VmB4Yg+no0*)(lt|P#{v| z*U6r}q{9%3#ri#&i5U`1md?}8ew+V|x3@BB6s^)eThD!pg;!i{?^j25bj(Fm*O1rs9$v531}^r9bT>=ki1v8 zEjz&VT>JjiTBlZJ(P1mv^uxjH$Ihs$z$fX{_*{x-d!sQRpzWkfV<=l=XVbge!`zL&A3~bf?bX1B z6{G|j7N>NbcLO6r=N2kO;$BJz)5kl{-!%iULXhbpL%j@5!rey_{ zcWhTD12z*g7&@H4v1=d^xHD6ws~yKRcMqo#Xs$9J^JM|CWac+{;QK4GBw;|LF8gOk zu>!F}2aI}rt)oBr<}T(?dQS%H_VlC#d~hG`Z{$}kv}6x=I;@}#Dh4eyf3fiP$BT%e zMNi~~*Fk7EwlVaSkwNRo0k7-btGdCAYVbv+Q3ha8S}s+_^3aw6<+R{}HO^e_89reW zW2qhvki;T-l@hM2?xSr|RP)OT)6rYUzeWb1l8Hg2^a!Ze<>6`dk8>)zrx*579ODId zk5k_AVtSaC07+#O#ZyVg8+pSQ8XtY`4vuqcYBu|dZycT`BIY8W$U+@?TyvQUq1n;6 ztd&auc2#uG*VSx>KY65ep1astXsuB4z|vRX1#tSGH+=O>lej0lJY_8pUz|L>f^Q1T zfnp63i*k~38Pjhj8mY*4Z$Vs<3y00bpse)45TLrog^zUs<2ErIwqQH(F=^eoO|x#XfCD=NQ|(Jfm=;DneV4?k}J(2zU#`BBVx)18RwSSQpFKeHFu` zzf6;wy8+4K{>5b=+<5)uaOzS^v&#Dkh+(-jq2nuD9ehJz=g{fx3Hs{rB?=KFL{Wq| zas(MZg2Z!-Yru_|271dBnM}}@I3>MK;YIQTl3q(;CIK*yw(Ii+=)W%U+Tvz!R@gLKEi0^?76I`i;dZKYPo0y}!rmz@(5%=j zmoX##I|J8Vq;2eTz7FhC8Si#O{Cggo#>xS7vAS?Iz_>8qf!8`zeutk}ggo?USZJ%C zpy}DKTaigp7(35J~!Zza9C~H9uKzula{<^KQWZub)PWFFxDJhT2~6 zfI#x(*R4D-AcsYOsJx_*6o$0r4>#+z6^9t`t|PaSzVxbhE%G})38{ta%H!SHE7)EL zlmKM~hpZxL_^K-ugY-z=+-lO*3oL_x1(04XK&{&}uk>eyLoUkji5GT`L+$+vm*&cO zq?_V`wbtJQWTgW#YkTDue{qhwZHlSUFtd6a#&;jayw|J-lEnaxtr-x71i-wy2sR~( zOP9#$m4#P9#f$zv@^yBvYYdx(^~wjF|A)P^`f4lc+C5cTDAtxzpg@ZjclY8J+^x8~ zJ1ttYxVr`k?poX}cnB2N5ZvYLzTf!H)%gR?#ha@zMzRN4Ywb1XeCF@jYj*kGDJ@4k z^&W_7u|}i|2PD4>56a9rFbZeMPH1}lYZWq0#A3)*F%OJaepmwk+S7J%AX3B-Q#Dmp zf}U5Kge6UDeE1_QhX6)!1h!73tRl`S;i)ZI+srSEf@T${_ZBX!ij)K$4eeIAh>a(@Vd7IbnYEs1ooTH|9+;qQq%_RS;A;AyUSI>#_tVGpM!=+Ppi}9 zvj^M3oJJS(4Ln?+0Ug)u+2Lawm#Ign6Rn|`;qH*P!JyniOGL_}hVj3XHec(%|S z5KPU3h~3qwT_(}16Awi-(JWQ}uTmLj^Lpwf(8;4EY|HZ0D0FlcFZ~pjHE=TC_3Um_ z?uRK*J2-65HOpLV3*v`SX9Iaw7bi7PkleT$L%qI+)7^i`LarBJ+~^l_v8-#m2i{o% zny5UGyl#iy zUJ{t3TIyZnj}ySbyq;1JN7vxBnYB4?8@{3K?KI$jD=fQQYsaztxuWK1eD4s+%!xFX zWO^|QGkQA-^ehfJ*M>x12+QC2K$0wAMP`bsI zMcnGd^bQkxsFNyj)H!_ZK$pNy=>APUh@P=07Cbs{x$WlsAXm}$-rI+fNn zTE$(6OB}*~YE5oZRBWJ&nR$mGDKayIs zU0$p6bx~$U!ZPY{!?q>o8%wxt27up=^)_cUkdb9JQ_&7G8{3!I|H}2O24x5eo1FE% zz%09b0T88)d(VJ4bJ{}dm%8Kb9yDII#z9>njs1e{*hqoE>)N}VJ_G{+eme`qsKRXB z1Vg2?=LxD}OQ}jqhV!^S+HJjlw)H1dD*d`L&JEE8zlL>Gw$RLnVup5hr6j3QP;df} z%D{fByC~t|6AUn>OC0yf3`4xEWJg@W$2CFWHRZmf%kz{{uhlQ@3=$>tWk-N;x;h~J zYF{`u{Qy7#!<~*xfk9)wl74{_>JKoMj0|o%>7{|Q)u3MnfI!sd6hk(+FdJ8i>Z0`4 zM4q4m08r|`nwkY^c=falcY&uO0~QbQEM@UbR&mE@O@yEpAKgzH?LCRqI`}$ zDhDo)4@7OoIHD}Qt=86P0>Y!l#U+)C33Hp{nJC)Zx>W-0qEP5gJ5Fp-yIJ5Y$GaPS z7-`C9mYSp~Q>amtjB~XhXad+~J?@3rI~#Wtc3N$R000ee@#((RZV>`{#F&)OXDFhX zu>3lStLC@9e?J0_xc;SS^H=bEQ7Rcng%FLsw4t#fgt+(-XLn3)F9iFD)QmsB`Nl~X1X4Ado1{AUCH z6~Mr&-f2sZ=|4yS3hWz@O8$Gn{^gYaee>Tz`2S%g_(T8Pyd_4wMfuvH1#tA{>QC%b zg@CE?zd$5wFJ0F;bbq_IrzZ%-Hu2N6(_xZ-yumhP6?*>9hkyW_zK51ehJSn?beVyE zC=EeSf4)X!L9e1M8epSd>JjeB)m}%@yLcLxzY;Vx|WRp!P!lfeZSPhY~{!Rc?KC(L{UlC13!r1UO zQTqvC)zk^k73P%LZ)t zqqdwFmMo%8GS&#eNa zqe0gfUhpRXrJW#gv0i#|^g z%lS9sjeb}ZbO(q$&-33`h5%pRc6(f1-#j>L=4TtKgnU&dLT38Nkv zb{&a+erd`RYqY2=vKIg^RBvuxw?-_lmMrqcHp*$a1yYH5OmGFR1;Dr7l|JK7crgih zI}XS^` z$=%7PK`fgH>32@KD~>_m5xkTSwe<_&kx)uEWwT4Q>bQZwwJl1m9m9MY&;!{AD1nhB zr$jF65cqFhxoOjWNEbk6$puV4f9^FHYQ~A7rnh+3?TA@n#|}BHFzz7(J$nu`06r`5 z6y0_lgQ%g+w9%2!DSAOctFUXk#H{o!8PQ?P(+bQJbkF)Uj{BS~ZKaXD$ojt)n~eK% zFG<$sZgp4HUM;3vK(%A3lf0)wkYLF)-( zio~{$V`FjQCPjVK!#AJ51rSm2ENuG7`xb6(rp#9nf7SqI<;m*LW!M6p>DgW?T@6ISrVSl`U?QmBHFW&bjRF1lL>kHLoR)3E&(mzASE`26}LR)F`oR zzl^odxqFlVaNAz%Pg1g~Dz~Acsm2#Mpaj9s)*?9?t4NDH<(^T^%J4oCrGmMyV?nn` z^le%@_BV73ot5=74o|~-H)`|!8JFx1A#ZURgd+-ir?NrTYIZJ`Zej*!UE-(H1qGRc z;|_`yaUoVK%qVn=3;)XkFrNyJUTA7x8x>U;tSE1LhV997fB|AwSMbO+=x&mfaR;ZZEeFEbwcdTme8WBUW;0STEpgLlgoJpXmcAe2#(^ zmbQ@C_c_#`B=&YsefqXo7PU=gJ(FSB;3_)$sIf7HvHik`{gObw4GTAuno8#CQ>@Yk zsq_8$1B*QueZTpiSgvUuj}Xm8Wa@xGb5G0%yq@8CogsN5MeY{23Fd-gkau;GpVvI! zl+ZbG%%^Tg<@qbfLI1O9p{?a%&9Un z+Wb|O%V(KoP6X_GK#Bc=e`dtrEuGF~@~*9~x;wW~4~Vhx8nf&%a)>dYw0h}c`)Qkb zH?7-y@QagKP_cPFrE-3cg6UI2sAkHtGCsjP%bysYzxO=Vz_y(E=+f)w^Lxd^wUY7G z--zJsr`W$$M?+f3c^5q3S`UAKEEsSMMoP#pyE%dHES=jVTC01#-OOq%o{6eV2~l8p zJK_78u*w}4KA6@nmWl`o#+~z!(XJ%#?gFEAv1ZJf0%dq@Ebp4A={T1cdn|bTEqafJ zg4;zZd(2|xA%Jwe_Vgj?{9vqRChcViyIpSWkB3HaeI5I~npdPWPQO_25D+$CnOz_T zfWsjOV{oNIzL^-+__>0P)XUU|c|qu#{93NbUgb=Q1jEa%OpQPpq))_m{Su%{nO3S+ z!q7d9N{=r`M+Hp&p#zF#v^fp+r`v_*Mn0TSLJUunn(ISQUe&dxgLij|Pk)a(st2Gx ze~GxnQFoJ7f9jL~u`LTWaiD>t zm=ZpuW9Zd%-N)esun9*W%Zpa*CSMWTlM*DAAAoOG17VufX#3CAil4pu^b-x(o&*JI5C1T1{Nw_JZO#8S)r(Z_3E$E)WK<`G5x#5fo;^lxtV#^-3j>4t}NH5;~mr0!(f_U4zIKX ztCr(cT;kj<%d5&G1Oe%Au{hs_;%+-Ul1CnWyL*|&;r`owg>tG3&x@TPaOxlVb|k0+ zTvA!TV6dC`=?rQ^yWMdmF6dILStkCNJp0W{(Q+^+uIQ{%_JhiZuW`_^RQtHRs7qX< zPmF+By@=;z+q77N@9u&+yemx!PEM?4U|oS7{bHhPS@Fv<%w(3+FHiGS{cPpgo%*md zGNJ3Sf8z`oI8_IsXVP+@jvKW{+6z?tOj0?jYwl*m zj{HeDOIW?EZmFX?R$AAs+1gN^2Farf4FjP~%eGPedq;+-^Dy>#;+Kb5p%fXN)25=4 z&24#*CCkpX%vn<5jkQQRVB@r-vAKS-vSbRFC3iDUx`9)-CHo)!G9)x)c#h5fKtS3W zREKxXoA=EB%KEUePno%%$1&DdS75|nK)AX82KT!?2n<4XkA+?ZtZ2$A-IfHgO@h&= z6PrYICIW`f$6iNe^Lz;XDqfK6-{P(Ip2KS}k2mDxFl!M#hvjBJKHG{icg@pb@72gE zzOYJlWx-1xoZWQa)AHk$($;Y#;EdAS;r`wf-x+GiCe;7~6tD*Jt;Ya)(F!dN6^dNt zl|fgXPF}E zKy;AzyaG{}74P`%R6rx^u4qDe#E&a$kFTw|TA7 zc~z4YH+;oh&bq}0IBozDuClI@WL1` ztZq!twr}fxWn2${auBstzD(pighj9$>Kad)3?qCTldQPM#XO(p3R`tmtFt9j#PDw9 z%)5jXDi)XhStoJU<`Db!uaMXd{XG^8HqSft`qw{V>(zN9$f&$1gYQUbifEgUCc)C* z$Z^#tZ$6E(g)x?jKG=WLvAvsJUdTyN8tNIlyLcG#Cxqu#nO7Wip@ zFe-{OsXeN!7brSJrCB=bq?wztLfpL23oqTsnr)J!Hj(5NsNt2j8cqLsfj7j6WqvcZ z+9iEGL2yZ>4ldM5R|na-s|X)t44AsA^YpXGO|?H|MrL!ZGGmXGHleaBOG||sa-J!@ zq+$(;bfh)kRJ7@>YNnM9N+Z_YhNL8_(YEros?}ytG~_P+Fy=iiAn%%I^#2Sr(4VU* z**pkN8fY~+EGQo5IlTWfZF|?GXo(ov%0cX=5)YXPTFF1|K-!G5$`cu_9ou*qI>kj7 zcIq7JtH3VNE>!uGaz63+r|DwN!Fd)2{gtpxDp^+V=DzAnhyw5KOUvx<9(HNwh~sz##nQI+ud7Tc95&}ze(>Y?WDEOMNi zx9<1Pp{ln|x{ccsr8n1W7Uc_%EhCB8gUd^La|5sx#;C*r&o_B!l5uCX4u*sA46P#0 zl^uHJlW^Llg}xUardTRxsu6RS|akon{ z&_lzyFN{7((w~t_Axs)F!^#)*Lu$Emb-pO+qR^kWmZbK1yC7J>B)5Kwg{^-4sB9eLMI(C0ip>U?da0HT99ZmV$| zzWk2@y<5;PqM^e)C%AJktH+THi_04$%!CxmuUVM3fwGc`B)B98ENpP%#-0z}e{#(@ zo7M44zhNLd11#Kbau{Vl;SGM%g%xEzsd*0zDy1@7$qS}a`-N&Jq& zf=@tOM@84pq(QJBj~1!h2L6qPtWVJ;)`ftHw1Gf{QC&MbfarRCMfj+QxBt1aH?V>j zNZNdKYn0+$zes10P+E!Z26ivS1BF@)5#zbc3 zjE2R<+d8`xu;>?Yn(swf=_gysZtoy||GQU`qLyf%%CL@|p;uXN1yfu(=9m8rS@88& zJ~2_$u!7yWinBJuh({N%KsJ&!M&W9g1DUU5Hzg_QW;eP|+=QdADi7!_^TU|{DfDHkGq?0`S zC9a?=e*cj*7qzX%j?;{Y^0DD#UBt6iBtGD!ZR$`k&PXT#(KtypjN8$q%Vn)^Z}9ig z*kl+j$QW4**N^!!#1{q;{o2V=pU-Q%#0nA;6lbQHALSlbcSG|~F>}2sCvwSEVHlmd zct6nHTV0$wlu^AnH;#G(dU*}eavk6zEJ_%fTHi|%bCNCqKdsK9K*t3=Hcxp~B<*@` znyoGpB-O6>kIx_od^A{8Jq}@%odx63MAuv4$E<{K*A?C6LMwQRwB`P1w0+D=V*(nT z$z&0mCk#x0B=VzIJo!=H!v}ABmbQ%Lj-7tOcn9JT+>yvrAmc7Y#Qu$jbJ|@N>b2N_ zR{0>S^PCrE4(B~LrO^@-O%awAEOr>fzcS-1=V8!WUb`p@fjvK=-KnP-dkPQxErogW zJ#5c!Q-Hq$H$88LX_{wBBD5IWP9K8=;!!Cn(6P|AYOF!5jD3Cos?c}fFZxIK6FyIv zyY?t`HtG6#iBtBzYLZ4)hn^u{KQG63(=5-Gw7wN~JYH7bj>yVNreO4Zfoc%Fo0&Ure^WVK$_)QunhEe)X z<9_%HZXa-F#F=xU$86YB^OT9ar`Q^X)7KQ3mPEX?Wxr49=g$BBsSTQyl>bs{+m#3? ziR{q5#VQoba5UZH!-vLb3!n(EmyS=N#JRd?rE|f|9pTZ28rZgv!ry} z8jq^>5O~^=PlRQcHc!9vpla*GZV)s{yFM**4>G|V)c2ieZ=p$VlzQ1i9tOx7PcN;L)F)vjt-pt@E)22W1$NQ(!4oYrG$n0gp zZTKjH-dMWN07=9BTi>J|H7&_dw!4jEA#~eMyk=Kcwfq|=Wpa#@^E9LMNvY(54ZBPr z1?tx;GQAQ6;(i%lZOR^MuR{V0t#(|)jVdCQeN@XZ$)wH(w2~}z$BHBtpQ;6)1B%<) zNA^BYP14+EFDvfJFC^SAOXKl}Kot(%WzrNxZZ@xaH=e725Zz3D2QH=e;VD|h^V47N z>XS%wb4vi%7%quaLi0WLk!ONUs~&~;43UgOpPZ#+(=rFd!=GH9;>yymhRN~niu%R(gp;p@r z!M%>gV_NO@@7Ho1y&$HU$7^tVP|h=!au`e7{93`XAe}cImsA*`Nl8!>)d&n zALavWv%a+Xc#`_=MlTpo(?e&3U*qu)&rQih0fdt0pVgCmaom;LrcqX;G+89%Yr*! zTWBiBCPUNQW9c?5as$ zCphf-FFBq{zwn$PDCaWO8O_s0e?>#hJW{(c(A9lzSL8Xia$aUW{gHvSZ<+-3T+gn( zOfOGUwl0D{D`*aFUFCMpmt{QcT32urB8;(Tmo>BQE#PsWRFGHYKUI@f8+Wdo2_$tO zzo6k(QF$_EA8Lp8er*UBLH!?h_<9PMa(;>~iz@2TzXu(OlXt{IaVTEe*RXxxN6R`f#8x9~1|aO7kfoX#_Z_>`Gx^$z5lJ!RER5nLwxi$>NK zd4L8i;do`st5?*_U+y_N#V`Ol|0@TmgF}FD*+;y+wReT-`dz_Eq)o84Zol~y<8CtX z_zeN?C%t>A(*)nGgXyzK#~|nooL=xKJT$bAFa*n|X~m4!#Ruf?s<;2@gTdVdA;{BC zHhI?0B3mk>>A{CxD!Rh$b`Y#d;dr7BDahf}mTT&nQz=Gx7+7KZ)oOd0g{(4VW{!~% zE@#K*lB@uUiBq2Hy+S%m(cSu@Cnk(VwUvLCJZSRgol;n-vGA2)P1la&`bhGPR^ zXWS7*C~{6vno@L3D-YadzY{_uza-z@1hB40{$b-+m!Sq$Ak887oOHL5wHbZ69~JgQ zif=HPVR`BBzF_I+?2BePSq?~G%TXm0h9TSa{>w{bQj?q}MJtfB7fm0{*{*8my!iVQ zz|67BV7E@twb{p|g8OT)Q;dqf;J7u;@bvA7%cfgK=JD@sKG`{9$thG1t;?HDcWbR8 zYvr=tk$#4$ezx;)r_T=q99f?-^c+MOpcx@hiWbH`wH5RzF zt*+maEb`3Lt#cKZH?6fNK%AC|%OHcZwt5>h#qn4b4&{8rTDeT+a?Fpvx%MVMtT;s-WacCAZAG-ZAxn2}AGLe%tl$$v zVt7 zUb0gr{()aP$l#Syk4q+p;bf$86Uu^(ocJxmwg|K25gqKb$|YkxKlSHPqZ+6Zln4iT;#!C*<8)Xur{%BDJ@v+iBhp+Ln_F ztRoDneOs?n%wHqk+b;YbNKs<20*KnjOO%!Wv$c(xAHlMJ0cxt+3Wv3l8HA+4wNV4~ z*vFm6J1)6}nKn|Mjdbcs{nX9ps4wmU)NU?*^kwmLBTmcn+F$VZHs_tE1A^heVV%}_(T`kx+ zR(yE;W!ll*JsENPE_mX+&(+2`Y>KR>tN&SCau@i5YaxLV0t~>LD=QPtskW(w^OVG(nM?k1S>1%+s2Wy3iNVT3=M|MrssMJw7NV zQ42gKXNBThjzkD`ba{nUGI9hDy3OMUAD-=?x3Vc}MbmPS)lN0xs$Fcz-S;GLMLtXV zT3RFaz-Y8;IeVv>N>NyJT01KnSKA@!>mtNT&nL+AD=kwEdlGp|tAB`hBf*VCOmU>Y zg+dc*XH|AhL&7#WQJ301ea~WvoG(9by69fI1j#J7b+OX~$?tZx^suNJ6b*0o#TiN^ z7Dt*1ZiW^4I=3-3AATd~BZ4HU+kWIvj){nWiv1L5m17%|pC5iZ3vJ=xOshi!@zL& zBY+<-bXzAmFhzAyT(z$AHYpts$WapmEU194065^6mvoDOz*7LLF`QDMYNQ=a;jxwJrF7on^nT6+Y-`mTH2FxkvtRRKGpKK#`^w@ z6yN_iJbs+imzalW?@W_8df=W#kKBAh%$+IBnuc#SZ@;+4-PrDNnBR$fUD7?@l8D`# zNn+Dt)wKGw@w#^Yz{^qBo7~H!Y_x__)bPERaq>wIRxrlA_UFqF)7wyZoB>Sxa|f&I zcgQ%7uXvm|Y{BLpV{YT<@JOpLgSFm3=JgXDYo;^w&uq#q#|@Mv4moG=Xt_-ic~$M( zs{}w~GxQXl`hM=NrpT9Ati;O`Y@y63}2YwNU1=qpLJB#I>nh`mDe zxvu^oyD zT9JoMIuCcFj6`il8@Djg#OyFu^v=MxtXf`xHmqHQ&4)uy?wDEf{6=r+;Kz^gP3@bP zwhOGez`_j6I zNCJ?idY22}w1ki45YbN53Q+oxuZb+m~i_VZf3KDu$?yq2=6 z-uGN)Kn@TYWIlaq|D$_?(f=ki{JVT)B|OdG_M)<$U7eWb?F-c@uwvl1azy-x;oAn2 zJZ1NzQqKmZh3;&^(Ij;xL`mi0FLR@~b0EZzZ$C{jo(Q=SY(*kn-GC zs2!G-7urS&+TcekLa~6@`7`H&LIV|>be%QYCf$rN372ZWYI&HwwCTS(d_mgeS4@1& z2$kDvo-!9s9ok`zUGdwz`M9KoLt0eW${1)@Yh%-M1!yh zufKS1%xxC))7#jG#<6n*o!1e10TuWBglnrS*Jwis`#4xX^2@gzDux>PyhMtd0?b}% zLruY=E+Xdqp9m(4DUlsswkf*ou7;LSEMe!vJ2bj#6Kap=Ue)shkEOMs5-JiD^aUzp{w_>Ktm$H|cTzfkW>ul#C3rcngWI|PI$eMBH)S&`g5Ar2c0Ualvinlo z_@iTi2vN+PO+X$iZjg-YwL;)*^J_gy`IhJW=XtzP4I9^&eNF*b>dvcqN@FV>CG4Iz z{Y;GYuO@_m)tYoWF6dz(>PKW@HPFiLAO2yh7)2*wygXc+IeT|>2ko1pE2x!|4 zgXb~3c}mWW!RcOS{^@Mo5Ao&z=e@-KFQD^bEv>1)d!8ThlnNgz2m{Bx?T3`oZ9$b$eI?bHT z+f%$O<$cQb5n#YlyA!p9Z;LhGL z`km#3L!kQ_5{8rZQmQ!`|AN}H#gk#)>OTMj zkP0M>1P4f19cM$!FLM_T)n;lmH$iiO6(YP|)#}DDi2jbJPr8i?S|-6W_x^N{nUmc! z6t?KmqTZ~z7ANU@{;BY)8od7bzJfIYGz=HS)9pi67gQKOe*I&+s6}dnuT#s#C1RUb z>AkrAc;%&(v1q*h7skhF`*%9N8EsAnLHMJBi+TJFUKuOD zoTD=5te!~-A2FC7r)=wx@p2fxMt<8oyC6S50X6nLb^l=|jiT51qI?i%->GMrbegw13glEbT^1uKIEokC+{oV=_5(h0 zSTLUek#IEN8jGK*=+)n=Of6XA=Trilb;f|W^BT1I*t`W-J}f9i%tpG3_Uy*Jj&P6ac{6M+xv=jga= z+}V(|fH^zNey^FQIGFfExm(Em1=y~194!~TV5b>JheQo~4dbmDGfX?vOn28fZJ-<$ zwf!=z>zpeK;bYKS>LUJFc2}R(Rqot+KpXG(u&jDJ*Ab;M$^T02XhLDr{g;NXEVg2b z@|fPCj(a43U#ucYHa-wPrm0Kff!=`G7OHJu0{3Qm#$qhlTDg?vc;E+DD+hGXHPj^2 z2x>(Rg4s;B2m=oBO$HuC8m#w&H8a)9Z>(|*-dLLdoXx;K#kAaa6s=Pm2h>qnzS_Rc z$2nS^lcv!__=~k(<`S_jc8j0H`bfuz>IDEoFm;uXep2f0TWd3izrE{7nyYMbHuV8f zK{iSAjH#3QiT&~*iwErO+_BS_>F?Z%lzue>=f^5_ZsB`Q8gcZF!x)d-C!o6m=K3qi z?jr2ii}#^?(U}zH)WCA~2&tve%&n{zP6z`2LRD+2{o8Etfe1$m^OA(Iu4mL_40Jgj zv@PgW9YBmfE2?aW@^e*T0ZKNr06hNU%BM*`Z81`Rkyw);JBs3v0%a5enHQ*{gm$&d(XdCm94W`sU1UFmv2tHC$^ao5rFoC+~GtTnRWJbfkAU+DPeu({KkhoUQ1Db##H(Lif& zwMntw%5&OPuF?Qup(gL!{ml$f%kX8lTo!?l8vUdqut-MZ3wD@cPBqQX<9$)K)BdJ_ zvKV{v2WbmcWpMw|u|nzdD^f6|}E3J?NoQg11?iY;t;uU=9YkReZFGD#5z>M|s|v#f%K5#bo64@;CdFXW z6qyN5RIL%mIR>L=Q&Fg+co5g}9k=`ViVC%k+q(OlochMliJ#Jn1xwyTOndu4_n(Ae z9oi^xj0PY_d&=5$I_>CpTqHrHpsK_jV6-^zS_nB&yz zEi0_cy@EO2g4^r}#YJhOe%*GImhKbSn8AGa?T*gsb*jF~SaZ{lsVF39Q;I5S(Pb^A z$jfg}y4LT;U%_LW)ms3qX!=$6`F6E@`VIFAW3;LdI|GUKcBWUcZ2*hAlU&R0q)$_#^V(?H=qFM!xEq{GrT_LhvAKT~d}EJDrzBVBHiGR$@_PiH0p z%XThX>ksTCUtp$Byz+;Xfc9OU(t97OzAfn5V&<2S?^0(ImUC-#-PGJ12_5W;7`t(F za~ad!JV*6W6RrW27UvFCe}7*%2oSN}=6w^u#{2-xeQ&TbX@$;v)tLDAc*5{^ zSD{gW!fRX7wi^Ds78v!z#(|M{FA`LADDn_=Ut&F{Kkb3P&`H)+D2xf_13kEtVel0F zyS!pAzN{(LrV>JRk?|afv7rLZMJ%dKu#%#VTnt)xbUyL1wKYN3bP6i>Hj_>oTN|OD z1NzL^b8Sx*V{$UBXV}2jZOuoK(U*Dg89f;j`TZ453wj{sfRp>L-)Eao5Ro>i;1ea^ zpplB~d$Gl$+ghN(SR`X343X8@G8C=dtaaa$xQwX@p5s#$FB8SqknXUvMJT`~M8f56O27>)`9 zB)1)=UZ+6SBU7w5<8}AnV^(<)1pRmUL3(|QZiQe4VW19z#VY~o#av%dqSBb!Fn!U! zp0Q}iM0-WI*(S+c^TqpV8^1crVVNC`UmTaeIqGQrY-R~siUq#w>Je)Pbq~ zH&nf02B#>ySAA4wBUoiH4-45UmpURpuI#3uq?&A$cAzg@Agkl6}se6%=78 ztVT<)oM|)8erIfuAj=}q=wf-cQmR|ZcX&w|623_^taE8R|8N`IX#+(|0-(c(#@Wr2 z`;s*Ia4+@dM^^UQE#3PK^?|f@m(BPa>x3=U2{^5ea9?HL(Y3Egk|G8)lNu81R$-4k zY6*)3nATXa*Xo`Di{!=bb%`S_2w8GISxUlVHD<^=Bb+WxrH0tK(-A77Jpc>IS$D8%jWV`jMO}mL-^X*nmDvI?i<8W=8Ol|IJI`8@0jAiCkBeC74U zLzQ(861zPgQC}wB*z9`V95!C9L%s-ZUrX8f?l~!q+hCl@51?II z)#~BkAFpKPkaz`qiNxDrvQ?soo=_8lIAAZ{bt(a@2wuz6b-B`-{z{~$7caDJ(!IvQ z#;nHkL@@mHQKLPkuHjA3WDzw%U^6e^sRe`kD2@mR}YXSiod{Yu!zJNUuAK3Sdj zbYHJnh7O%cU@(oL>L8W4b*rj3$MAaQNsNt-@$PzCsznsE$?|$cTm;I;90pIz(U}Zt z_+^-yt!vhk24lac5vLk99|Iv`49>Z4EwTQ#I(izVHSxoFV@3}k&QT_*`93cUmxUd2 z>5c%7WM{ID0XorN1s(!2&3ucZcud{a1p*R_V7L5n9&^3f?H$>s1-0l#S zt6JfrWik&^KqmqHUj%qn~N_d#pn_o)K9-tGEn^C{767cWB`;?6uj-nO`IXz!%H zo`}F!`D>`YR%X$diAPjeSARmYV`G#snECpkZScYvUVJvFdllK%t4q67C$CB|sVvy6 zUhw>5m7M4$hT6k#gHoHah%e0r6^<~aBwzD~AEcTp)bGA!i4x{ZbGCKB?7Lm(cL0Td zm}eF~SFzKD#3x5;t(Fk^!s%2%bC*hmF6;d7l0{5zIC?JlfR6R5^2othR#U6(K>rb@ zvk2qnCjH^1b6%{#LJ^#wsrKA#iUnu{&5hgRq1 za@cV2k6slpcaY4Tl9Vp741I9NBchGDEOXu$iRsz}z~~!#{M`@n<@;-;688aVH(!A? ztCSz5uW*XqXSbdLA`2HeBf4JGsk1Imds)vVvqShNhU3OMRSP&AdliuVSF*b704+41 zHoyMJUO|`wSR9Md@;hbuJxoE93nk4BzT-w}GXP`hcdZKVHPE5S;{W|{*Jic4ih{NK zSl7>lhy;{Ht(lPDiqy_VcE0^ANe{<8u$05akk9Oyi+^WHxF=mN4$0HnU;UX^xzQE$ zxOALb?rP4uwQq2>k?&>uaEOFqWXTzvO?^})!2t%<3@hG^&gsPgQi3E&2#ayO)urb5zKj<5s9W2g^<`H zaRMdj$eynkhxyoB2^_&#Ma7Ru7H#p9YjYf%3ffW=t-5SCQZLu|q#wIj7&W`J>_Dlz zCZr#y7bGLTprN(jEU34Chl%V&B@CBFys;J1B8$P`_5OK%o-6Iq&!S%C5V4?~w9xkw zSU~|70$uX{E@eflsW>-r(3nYhX^!o%&O&fS^3o-WI z#C`(qnkSh|faxL2Cs^Lih@|%v$6v&RF`9Yg*P{30M9POgITiy^qP+c!zFn3QYi3;J z69Sx{Xgbq;A%I2l;<}-4wi{SGnE*3g{NC1bX`KJ#ck9alk=A~&u+);lT~cm|5aA+9 z;Vvh9ec{X*nH29CFOHE1I58$JmO0BBrG5Rnj;Mhf^K>zzHx$C2xXMD$w3a1eLJMiw zf4oY?nCaKxrES=xBiF(LMILGyWUf2g1tV_s&XJ-+^qj3)j-?Y(ZT;RV+RgbyoN^R2 z#cX%ynQzh_ZtwRckrmL2at|+1(hIKNdiYi{j_!{|BYXx!?f?|LOjOF0n!JUK>L6QT z;)}S35Y2HXMzZNu14*J!phw@sV1%*2pZ;4)?)mcjH;=VDm4#R-rBQ^Cz;YGWZ4@Nq z=Kh|Rl~2?}v__3XGh_EH^Xz~4=w&g%P3nlW4R9Mnv1IO+E(>laDWK(aAqO-qQY*N- z?FNmMzbuaMb@$-P`);-LixE6{GEAtzgXc}kM3@S~JK~cjy>YF55iK(<*R|70UtNl= zWlP2p2R0Gdk<;2HTEYc;KYdGXdaxk6eat@qaf|p>?nMSkq5U#V&lummvJJm@Ja$yv za812SC+fCuaAyi;7l-1A{I8lX0&AX;SrO-0UgS)IV#|~+TS@g5x9`A&e;eq>E2SQi z7Sm^-Ol*~1a=b3;32lAyoYi?9=RtRKY_RX%WlUxKm#1evD(2dLp}`Jud?`1l0qJL0 z_6FUba2ty~qO$N-8`+bC_j@EfE9z9Ok{xtJgVHeH%RuAKKZBQ;HVcV+!9SfLT3du9 z7y4^%Us`*L`xayU@7Pr33cLW6BvDKN&l}7#HvhHk>^$H{#@7Uynp*xBC-zlzC54Vf zWfwEyuB-K`?ei75`06$I$vx+%u6zA#zqnaKrC5YnGIT&IL|L}NKwcr3j*S{-3<7_3 zszOUTbFr}iIDZ1;nTE(m3(<#UaklFYV_lf?adYZ6nC1VlcV1CVc2S=Pc@-5Y7DTBp zDk307=`|`U0s<;cYD9Voy_dv7Q4vt8bdlbBCy9de-U$#Qy%PvEq|NbL^Uc-F#gv;_ z>tp4D#RBp?C+F<5_y7Of=keI}&%<>;sCci?DiM@085t-qM1keYcRYSC(wG zJH+M_QL|Zf78(7L*uC?62&i+&Y`_YdaSNDl05O(R?E$^5<_m;lN zT!=Aw9^1P;W-EMSR3uL-v2t{YHY`xHxIb{&|2FB{)xDH2cXKb@T_}IY7{0KZjOEe} z6*w>3a4Z|}{%HSNRBAd~r&7XG<~Sk3BTSN~PUA_6W7NTnSg+i*!t$D5de}Nk?23CQZNnqSh{ zyOaUy%L|33OTSDC&sS_lGz=+GN5@~hK^1k5UFMrj(~VJmJ^3X2t%b-Xfl)%q;?^IN zpTD-ztlghkvG40gj$R9Yw%}a8d_#BgTIa{TiT9rLRJna1hYL5(ud z^IYC+<|8YtU)Mx3Y?I6q_!sDPjJq{2;jLCj-YU_sBJ1*h=O^ zq@P|K8i^l&#LNc&dvWXIp?J|eM+DE#OS$O;u>UeyO7}xp4Ck(0Ip6yD3jFT3j5cer zmhHp3)8IIPGso;V9AfL6$${l(zU7ooPnh^QJj^s@msZ!I+SzsFwpRiSC5_!lc3ETn zpE$XB;}~kfb6Mr+sEE9Njc_ocI_suy zhjQhbW2#l;|NR@Rx?YCf&6+WO!^D0<(RAaKAXncz@>!yX#WPuwG{$|4zxbg4U5jy# zctoL0+bkCI*595Wl4UQSAk%ByFMDN&_jy;9r%(7R&JPIT52KCiw!=ahP_dShfyS7o ztV@M=U>P*yPWkLmwD+EwWPw584HKnq_%fYpxKoSz4qka5zxGM;v7IhNXFk#Kc6R_w z2k@m4$uByttEY*T(!!)u2h$`!yqlG;T=Z3cGcIpKe)|wB=m49}ieX;ak`c(e2msp4 zY;9Tut0exbeD?e64EHYHd-gUQTdLqb?12jjd+%^#HGKWz^Zwulzn=`B7axWTXVV@x z<$t%$5?yGB*DCe;$I;gG*1wYdI3)VtXA!qUu6n;q|H$n(TR3Si42w+^lT&HZ)6_iZyBo_tKLE1;6nin0aDY@$J&-@ahW zwK@JfqX~{l6rrqoYs?a9Px*JG(kDH%as zA2>HZ*0y;1tZ*Qe93|Lt`KB1&>ge=xiu?WV-;B*m1^05^<-$V`isc;Q+@K5PT^1q9 zGRG6dXh1H8nl0B~sqb7&_0?i_jvEH#4}~s6SXQ}WY!M;N4^?QrGIMD4-3!<9BTpl# zM&_4Vt{p`sR{YpT`FyHaF4i^>_3IQ`GuHg|hRKZKzm(f@M_mT6W{$o|$ni{;W;Anh z)yk7Mn(3&c`>_$HRxg{b;o7!e;L^9vTBkBy%Rbsa$MR`^cmu|1rfo0;1iDp{-!<4s z4N;?k;ia0U9W%XD1@1udvr@k6FrwI<k(-FBpM?f zhlR>-PPvvQf1SD8c2j5V^+X>s#63UivA2XsLLx7p^Uh9(krLyTRH8*#EXH>C7Xv?Q7~4f72bGGnJmCVfn0 zAMU3)MjawKwoTGT64!GB?V^FLaxkp?P5+u8Vv*4F9gNpg({}_Z!VvgVEJb_T{lt$5VSg(;nJ>SJA z^v>$cxt4`>kTmbU9)Iq_uwJPFD0k(NP9LxF3O#W3J9xp+dxxgK&;SwA3*nJCI4`LEPL|#b$MGq z$vbCCQV&t377%12C((au3he!f&3t-hh=e0kSpo)4PEUvNiTN9$EAV zz#|n0tTT$=_uegeRxfP``a!+=raFE~Vn6*LDAYW4>G zyJ<40{QeSUxEIXON!b!3Wn!84ZJBrMdV@*xuV*d5<2BorrC-2~l6Eha{I z^_IIQG{HVPx^t)qKT`jY^+R|vQ5={UO)Nhot|oUaZ4{9TZ#4L1uTQ3FJiZWB-Yv;q zm3vQ2;o6!kp(_g1)g9VoMzdQA2G?@?y|lrhBwC9+Ka8qx>ckIrWlkn>KX3eJDy*@Z zcL&H5zYc=5R(hb5uU}r79jq?d^y~U9#mm)6=xRN_=uYK-KD)DO+KarqFrk+X<$~$l z$J#ViJ(^0=93K8FH+T)j56{H}h2kGAE*){43mIgx9C2KdcWfWBdk0#O%_Vfbf?qN? zxn7ux51^uTV!J9w?~aVJnwW++ELDZD!jPn7kDl z)QZNJ2G&DUhErev&p=*3I1~R!U3EHa>;CiPA%Ve6M>EaJSb)cd87z$0`Mf=vvvq5J z>GAsDo~rEW>;CS+o1g}t%tU4xQ*FxE3rYe_lcG1iduUIl38EFgCxQ+FGf1mcOz?*- zzM|>!qOEDqGYu};j;5UHU)nBazI0>X?BHNxv1h-pBwGhjC2oDoL3fn?FF0)L!~ely zhi~0iy&|jbVu*6%G*R5krTZ)Lk9>%Dg@;<8gA(}*?cSjvvy1g8b4SGhpNh3=rEcU^ z&<>mhe@eqR5UFCD6f+g*Ch)u5@?54T=*mdH{hM#8lnTyuG6cZ7uxOsdWA0 zdP0V)!yeEMhl3&-$Ie{$w=UY8B!;p`mbT5>U+8+DPP7`dQky)W3AiIJ>PXL4|EFpv*Zv`cz-JXN-OWx z9HpK2vk}0&MV{o3x>G3vI*O)5!_AKI{#rFPZHGQV)`oCRsD~*U^bQEB5*xSfMBKFd zWig9^=sG^TfUx?O;6eoMaDlTaj&kdx0S`x^lER%68XsP}d^U73b2#!0iF5DM?j8SE z_FB?pgwGxCFi`sJ)vSGr_IRABYdjP|_kHKjQ#!d)!09?ADSvzMs2cRD_vaP{T|m;# z+Dh3*1Ae&77PIlTYre%~qLSh9Uf&Iq(tE`(!n!7F3AF1EAJP;jFK=V&Ba%flWKB)~ zAq6%ho!{$b(U|+oBZnM)qlu#{n3<)}DUzJY4t58N(%=6$)n&Dp%eEJO{l$|kyZ@Xj zQAdp_a^`y_8H7&9A98$Z;+%|JX9{%Lxe_^X1&Hb6ZNl`8s-zothuz}^yEz;DfRY7F z6!O0B&9gdy<3MP$98B;gbU``iDQb8=rvN*YEZBfP#73e+EaZ>5qj`W(oAZWwo7nxDeT8YyY47x!KRLjeW5;89h>d#lm%oYTS&rT${gaSorNnukBHta(y9_1Ea;Z-gn& zw7m~m%g6xKAq;imvFSenentLJS9*850MsAO(M#X7jHfW*24~W;j`MZo0={qJbVpGt zY4al=qO77=Ymq)7=)oZGkfo;vE~|w{Nv3JM?J8*nk!MQ8{qLEmAaW=g3ueaOs-xo{aK4av>-xti z&H3w!iR13}M#gGo;CO`Ey*Lk62jJ6^-3!L7USINxS_WX}@DO`kjP4cQPo&9!psBLO zakU;u7T|-nL6*+|1g^$Htx(xc6(=UsoP`=cl)>OZ`og5=h3T(3eO0 zKq$_1y4|OZoGOEQ{V~klUAf0U7Iiu#t**!0lFxePKCDIktI7TB(YrG5ymVe&96It+ zjyoN4<9S8PGn#Gdb5Z3zAwG+7#jin=>F0C1@I}I*XLZz<#dJQEjw8_XWl}`byufC&kufxG=)k#wg?#&hge)CaQO>?>jDkkYx9JM ziAp8{^Vf`WK_wa2yOuE$s~P#MLq{HK4Bj0a{G#$3j&W{^gp!r z6qHe}yJ+z;fZF?%w4^)NIR84JL{3+|Reva>BKXPL`TjN^gSOm?SLT8bGSK9%gLU(+ zamK2M+=tHc`t|)#i;|6kr<-m1+M{p>->U+T%LTco*#G@)Y&;sEcje;Z1GV(>U($3zy_)0rha$ARE%ly zt@(t8_W3!6h;=b+Rm91#>Q`On^is%HBd?H=OWKu;HJ`nz=#oxNo~0Z3mtD+n{y_o_ zfHf1vs~iJ*a%Ph#fhe!{@vk1(&dev=1w!8p=KNUo1N!FsPg=gpUpL#4Za?#9?k|4I zOh~|E6Nz&N)?37|Cfm4DRy)2cI}O%R|PAlXHE z*By~9jCAcA{AwA0I!J(%?$_{uq47vw<7H&A>n>T#IrsE6jHf6o33&FzFlma$-G^55 zd%foZetv4Bv)HL+-lCB!UTT&8b1*u3@Nf4kI;k2<0rxf~+eLB10mJru-Nw0{J8$T3 zI?>;wu}CT^oAif`xL?9^0SzSBMR@bYizEngNCyisqRhsBlof=pwG##;z zet3U>qMg2eulkvnBCFs=j&kN&=iuZ~AaR;UAHoZl~GK0kr$?R~h$zee+*~ z@Lx0G|9%x5(KfI?DW;pm+{vGj;co96m_!>K8_i~D8dJyC z{_)~rlAPPd_=H=#_Y)_^&#S{EK5eeA0nB|Y$XR&aDIrliKUbvN)xt#ELw zXX9=F%A*UMejfSv%<3Q4!J{VLteghR_+Nzw;K@k;n?KgBN8{<}lzn}Tyyu%X2H7#q z5f+w?X*Vr=E${mIx_3-0#C}}uB;8Quil(BX=*r#;6c-m$g81lGrsuSXxm!guwKvw6 zWSH%J$7dJOiZxZ;TkJb_`5`Tc=^^TMh`;h*=U9sRs_$xdU0z`?e_ zAWie$mM`uV<6m5Vb}SqrhdmC&HzkYE_&IRyqtQWHa)DM{6De80V&KbxE7$9q5&`sV z$VSN{%&sG0v^OI=NjAQD<=5=b=c{f3f*jhSQMgPr{@Oi+MCOTeO044Ds6fR2$2e?6 zpQgQ>t%g7G3^Rk2VZ3Zec&WWvb++M20@kBT@@De$tG>cUM}0+;I%!2-F`3ynn%w+X z3G<=B=zVX$TqD zprIb)`n%3^GSA9YUdphAkh4urnvB-s4|bh+8FzQP$gWGgF`qE9#%o*^9|l!1Y4maP zUOXAWP}M+R6Y-4x)aQ8PqhyGli^+gTw$rE{Gas^gNKXiQH|SsH#c`QsS@g?^gbIAw z!Y2>ToQRSD9c0rhRXAxd-+FE{iOGMrC8E8d#Ll8*_~fh2}#;W%*1M+)Wj1o>T;SsCbwk zOx0IAG^QWQJMQ8k29!U8a5n~V4s-mQx3k9_6^_f7gsn&ZETn4-qYr*IkZ-|C7NGU$ zgKqEc76+rFkpAHv2naeuziE`5&p0$MC+_T*r?JVll-5&RLBtcN? zDbC~JY`d?uF4a>fz?jaP>%qw@ba2JonufYc^01%}>XJiYx6Z97@vZ42Yw?;tYCnvh z3Qt||mh`zT9QYpR{-j~~dmrK(&i_fiGu5ikIO9Z<>C5Aj=jb4ahJh=?YJ#Q7lP#p% z%=UG5#>9ZAn%)+rIw{A31v9hX%H1tNniVEXwv_-A8==v#-X) zC^sOFN%Cl?RCEUHAHUsXF2SfL4^Fe*?kz#^2e{hT{19@=U%JjHIQ&>Z@@B4!N}W{R zH$I)>E^(^X@^UM#ULu+LzUI1}I0Qv5Y0=~l-WMhAKtw=usknoZlT*T>$FETGq&$X) z$+24|%&V8!@vCztAXxHd+>C^1s@&~PRk@8YQIo?qZn?Yl)abSY8u@yy9_XoUrD+Xo zLVfj@(GN=!Q-cVRU1N~QtI^ZD2hF(+3zK7jgQTrAh3ekS5lJG5q!&>v;5AkrGhc4H z$lao}$0!iV#nrCs?>6E&9KqEZ!p`(o2QGY!M%2jj_d?CtOE8ekX9IIS& z&1B{hnELO#I#+&K3~et|sjt?P5^g%JS8Ewag*2>fE!nM>t45crHh;>gi7Ilz#6L5_ zMWgq9_5%(faMM*~wJWFSb_i!r{&wDvCnwIiCyet>6zU%fYCS<6+D-9^82JWT!{<~| z$-|_0D=4b;cq6IV&}b^96vpB)z9`$%{g_!>#aC|?78b98GzqRQm%cp{i#XU?<6&aL zrU; z7GGNHS#z}B7-c}CWbhh<6vO(^t}gqLAs9rO(UyaD4$?@Z08j5W(D2&wcM@v8Xf>=)Sj zA8BLjB?3JC78Pw1qLRx*S#y&@qOb<5Zi>3nOc38DZ`#m?Er--WwLZ($7$t&X$mEJm zMM-=Jduy2=z)}tgY$|Rhiy77-YMux1)P4i{hpp?E*c#OgFSWgVuaS{}Pr%FHswcb) z-E!G2Rx7~4vuXnj!K^~=wypJx+ub^pIz=TbkMcU7Z=PHtiyZ2scGe)+mS2mme>xz_ zC6Ni^6UT=9!Go&DGI|s;a@1May0Af{c0&UfR27q3=uBAS!xxz=HyYydnTv@5E(N9m zZkEvYJ^o-FEXFUp$@6Qkf=*En#NTo8lZXG&)xwyY*f{mnfOspD$slaTqU%B(>f}TM zzHsJQ;6t?t9rT^dUxOC+$iZjX8XK6ZbhzX9+$s7|yrxNJcM2sAL7=|hjMIyL3 z$7&Z?MY|Cc)0z@&$s40?Fd_7iu!< zE}iY?)E~I%bS!V>Q-5GbMrjn6Fx`J5xf4*%4hnw0FFKng3oCIw zeV3g-+l3!!YNk#`WtGBF28KeJVK-dl>pb_4tnB1(JD!#8FYFDxGu7Z(oX;tS&OC;c zu202y_s<<)FJrwL6S%!X5c-ewLUeSy{Sn3xUs{7GaW?ycEtgOX8tO~>e7tipL@j8B zKAZP?Ju+R%h_o6L(qBeP>-6atQcR=2!uEGK_C-S=Ecm&=EZBBpK*6Su^*P6-?+d=cAPw z1&XT&^oYY0=Yj<&677m(;fW#tk!H4>?7eN~de49A-NyS`JqH9!1o$i%<89gxt?4I9 z(+eS$vjyYT#T%S2SZwhLyppI{FGIu0_FWg7aqky-(^BG%0d6L8anaj-Eu?2xWP7_& z{s;?ByV8tK)_%t;_48EL6BGH|I_G{ntM1$?f=!^N^QSmQ*0lX8YpWp|ew}q0V3=Tb z2!E&eadba6ADk~Vu+wz~;qf$o>%C6N^hc(W%dj52$%`YhONv2WY(nhtcD*i%7*wdk z4L#nHUmO<9zRoD1e)_$J#mFCs@^iFr!x;R9qpN)2a!T7Bo-uUqw-nU;K(idGbam8} zN%!#$6B?h^Nb=SF zDW+mx6odW{-C^y7mDpj|k)wsa5LlF5Z@kJ39#v-zAES1Pp#Ee zPU1J$l~x+teA+Qv!I;@I zLW^30Segwo!7Bxrzp`eyn9Cf+R#U6D?(K9JKLBH2URZblD|@!m#-VGxglQ6nIk45 zZWEd3hc+2*GQ(}ftCV#4+jvp8xI_w%^BGbPXG5g>_ADQrppJmpPkp!M&~^mdx;PS5QIZWuP79H4 z>Z)b8a5igl#ce_3p?4hBde+&oa^i)J+AE(sv&EYn7|BV_1))0A<`n$6^hO>N8~q07 zgOeYyvjN%sRm_Ga4i?nVCRvVL+(Z&$b*5SFP>V5FElNlAbmk|;NfU>R=#WrnA9|;P zOH?^`SB~27&a$?F5$Bc0`k{R-OX()x^M?lst<$q8cSLni_BofQRM_MCO2;fK!;Ka3 zpu@S1i?xQ6Iy7!&70OcLB2V1qsFIG7Z~ByhLHH^IgL)R12z||(FDzz?V{dH&BWSQ> z*k4jjD_!i*JcukjST4m|d|GIoV{SXgONZBv5}xTKu9G(RW??clzE3d~y^2dxA(2VK zL{ae2jec~>kbU-sFL(zPPmgR${5Si|7<{TOZ&k4)iUlX)w=K>Y#R;w3HB>SVa2S2_ zjq#tOiy0?=JCk`coT&>99RAh3E2!)c3nL->#uIJ7E!08FMMYENeR6@QA1M{=uGbq> z@`QPZAG2>+kuJK_-mjN)F4>G;lg~S1lQAUZ8f?ajlYbX9Q9{&CCA9dF@SmVxJ;oLj zdW&k(kCNnWleeXruh+~U?}$@&OH<9A5gPZUnbPZ!6(R{k^iF~qC(hBi$Y)7BhQGFk zo9M&{kKQ)j4YX*b&CU-UyhmHMah!UGPM^XGHhFu`c70Usn(cTQbqvFI%mu6+igu29 zBDKgnX(eSUKYV$jM$KG2(#MDQ^zd4IsT=w!dPIz_^5^PZwj|*o6hq;saTxd57f=7r zKDK5i#jQb6%%vH>pxNd~%g`GT6?A!WH+F9Y(nr=^c*^@VaHFo-xU_zqP>My*`;3Ed z!0?Ad^k;HTZp)|41w>O}gRid7d~4}6w7AjgC^?tId}roaQ^jwJW~Jg~Zgg$uy}HK<^!oEpEa!4(*$Y1fo1u$R-&az&nVDj~Lb4xRBWbERzqx)b6$470ML+ZDBHs)TY&CbM#XO=>)@ zW@Z@k#nD56w#QfKg>Tfk`qfmfdi$!)Q*Bmmqbuj(a|dfhEKEPgoI1smjbM=TUxT+x zS{U0FcR>u#)e@c_ElkU&9DO`)%Cni}+gkC<48qjO& zET`XTKB{WkbF2?4YuyXX}!&10UwrIV&Xl7XFe}nPiN#u(XCBv4N&dPVn#819JXGnoi8|1fyVWEfwni#%tEz=X#4vx zHPK?1P8{59v6?ZfH0=c^M9RsIIqG&lV&AlQD|H_vJN9cG^kw%K1;9qX+V`mXfTRvq zzSmMX<|JbdiG?Y-uyeYaC|y~oDYH+`kHjeQ41RO6g9XTdn#b!P$*FC@lg!(hv?SpY zM4iHnW+(e>t6qUfnR;8TCT~`NTZYP1x=&{9HBp8shfg^*I){3R$neT_Xh)4$raw?` z5*tOJ%E*lHeq;QXJDpjxA&&l30%nrXOH5`J)8dXVg7w*o_QS#T4y%nPh42UY;YzD7 zizOQc`FqVSucd}1gvs7SV(_Tt?`8Py8R|dU6W0UReh=ktIgy~R{dA9du%j+b4YmE} z?jg<#|9rDkY8#7_tu(G(rzDONB?}v;s=fqohv;^hTF;d?JPG`7WrMV+=@-dq_3%F(eI zp5_|m8H64&Uw=Q>9aJWbmEoiQ{J|Cxoltaz3oak6SVA5&VUpDJxxL|j|5ZS;2=R+M z-{d}yuRx`)h&pV3r_jH($egn4ai~e#EmE;+1843!!|$MB_ormH8aOH>54*+Weioel z*TFpN4ZY>>?+b#^?~#I-nwpq}LtIiv zw~-!Qq2$A zH;sm2)>ZR56up%_yRSQpGn+1hB`d3Vn-VK?;~S5~SjEDk_zaKxFwB|Zwk9si_5F=M z%~fM`(oK(Yid;G&nD7X7I*Q%DqOa(DJFmuQf&f5qd+t5eyzwy(^CQAS)iEu&OilGJ zJj(S?TIU&3*78K5ABfw;C@P%GXO?{s$Egz)@*%*U1(LmllIxne1sCogK1iV6#v zBRNz4-m4;q4LVgf!1EExK{IU;WYrS(zW&Eq3(fB}=0k6aBzuqjq!bCQ77EJFRLV7a zJU`g3aC)SRDiMf{miTdpTS8dbInaIfe)bF=w=!bFB9^Kwfb`b(-VMjhMPQPaz#UcK zx3>$_vuk;xQJ${b>KCKe&Fum{Bfh00=LaVG4eS2A@my-!Yx9F?_H7xZQ1&_}p~!0o z0W3{U|3lnGKrru)u2CT4L>Y+` zrYH=`g2u|ht(V`F(K%lv1@SA)J9Gnr2YGZGOC|m}-n|k)ls05(*Am+s{=vELmdUW21aG50<_1S)?pOLJt2v9T8$~ELRdxJoFwv!nr zw%yB{gr<)kY@!4(9*z}2aE=a9?&|zKJ6l%1dNpR)P)9@421EZL^gl%Sd939Bq5l5= zM8yBEfAW88gZzIuf{RoX1D!aONp=aHXa;0DYIB2AkY?VJMU?wpi&x^ z>oU|4I5oNzK6OV&M+A=XO+spp2DOxR3@ps}MY9=@RvevKjpLBoXePC8tsb1LJ_MOC zt-}M)I|B7N^*x~{k8aSY?he{{D}Cwem{i!9@fE$Z*BQeo2T!B86Vjvwl$|zyrrEx% z6hL(2g?D8=vA6hx*$8aWZz=ck4SSo5nJNm?ORO>aM-NU7>dOTo@+%2*%X?n6n6 zaLbEPe(z*k9`b&UY0Y#OM-VWRa z5A{qdfC)YQ6fA8*0Izm~V3G8KR0)2{bp9gcV2^=eLj}BPI51{Nb3vm^4*j)(o{tV9 zakhA+roEl{uGM>7-zfc+)r<+&UVKWg`WHU9b$+<7?kEaUndOph@TyeeRQXEK|COn^~^w2e)$vE+FRvv> zsbzlh_Ri#*DA7=d@0E!h^$^qC!mW3frjR+CLRn)>a7^B9W(k-g6f754J1Z6?euj-P6{$i3M+9>_GJL2#}^9;sRRj7sas8>TvJ-E!%An_Kgh7XeO2? z=$&Vqz(&DtfLUy7kg(x=!kghTI~`?1^H4uo7}j!lBUl_+FpG~YE{$b-Aan-d_Hvc0 zRIF&hfUdPlj99Maevw3cJ$1!d*OB^jXhWamEzcI{tOW0Wo;dkRE5+Zv$6o^E>}kbT8UuoZlkW2td*uYavcOwM+hJp4`DMmO@}H9HhNgV zFiT}60(@g%o?;~B?bG)*!@S+)iIyc!*pbQ3v^CLD2@0dA2~Ez@eYFuWW47H;Xp-(y zo4iPv@5U=Mb=%qmX;Q(2=;5d&u2+usTG+{h?VTH~<3BsH*WqS=dUg|Csx-2dR~~?y zk@J5tl}aWKSNG$FWkjT{AKu;VjYx%OWGA;=HLR|pb$BI6Y4czX@`2#FuclL_Y=&2? zAP-tCxZyG>m}G{Mnlaeh|6e%y?1vwhC#D3&ZPM`KJfQ+UFC`9&@^|shEFjdzgdP$LA=Sc&cDzaQWbZQ;;SfGl&aVuXduTS{ zdx(YrH;Y@|gx}z4ZJFdq@b6@@GKRL&`;61j4mfS+dRI$o9I3!->Z@vptYLF=1Q8ov z31)rJI)64RkJ%(>R)6fpWxNZd@Ce32v~P}q@6k^_0BR#nxva!y%{e% ztt`YxmG+=Kp)dnCJCuzkczvs^IVfCqV2pgK;@4c$qgf^E=ywnjP^eQMf+238%p}a*(9RrU=NB$NQcM-9w)jzJ~_k1zlDmacO-~qADeHocEg;2K-Ii3qgh* zh**~jIjs5Aw@6{5Izs+r@optwDo(=sVSh33n0*f;LNFf{dPlc+ri8C^a@BY|!D`|V zMaQMA-nD(pYs-$BGK-sGWsO5gOJoYTYa_Fx%Qtw^mK<$tX`Y7Jlbe_KfIb5Dw?INL z0g8Oh#p*{IyjWd|g>IHlP$eJ%zDDc%r7m*cq2g(E4w~k*-`!r+LefD7YA98${9e2S zKb2rI9*riob#>)55APnfCqOIF8uZ7&z(4M_6j>9$a|gM8_<21rJGVP`8Y$Q4WRpGA zIG=DC)`dH6>?##=`X*Ntrs%q;t6WO$S3TO}6RAa64~%7NfDb^XI+U$>+G~G)fnlmR zIZ2|(@X))EYsnf5;<~>ddt@rG(G`e8ULtiRaMVG*V!&1y+k?NVg&~ikRQ;bfDp6@P zJaN(xk6#!Fxu5;4^8uE14yYSg*(&qh&^GhF%FT0*N$ZfiRa3Z$mQUfU=Eg%~n!s(v z^sF__{nM9Sddp0~m4$lBTl2xm71_d?5yZlquZlLNbv5#|1)k9c4S8?;9y4P$Q2C3E ze7(J>-OCP}31dYw(TI(jHF5K)f#e9b_uaGa7&LO9K2>93SvP4$YX05*tJB$l*)**H zQ6%*zQxU{ti1jFl6Rfx)Z^HN&_d05HpO537ovJ1^Bw$T#hIEc8;i(AET^UgU3t&Ts z`e9nkbf|j?Rai+STNt%I;B4Fr?G`Q;VUXQN@^TxSVCKL@0PadC}cGFH-5E{K65<=C+fw4UHOAaSKFK;-`l!Zn{3H zJ+yvSE|laS2j>s|61F`!CF~Wx)i(v9EPQ-?`W|HW?mv6U)jTrVpC|6Syh7~GPJWuZ z7LSlC543L-P|baM4nh1hl#4Ggm289s%7BH`ZR_ZwoE7Ht6`1pX6)*Va*vVAHJ^zE) zJ)|sqXuOZOGgDmZ?6S`Ini#?l{M6AlHcX}pTMi_#J+LgntcCF5lwh8O62o|%q;HWt z7as7ARgqAL9h3u!={k$cQ+S{`F)pB5*~L~%9q0XonlN51M%!Jh27bPNzZIWC1FOpc z*jdKlC;$9$uUqqiiBL4`-sORD$nPwHl5=F?cov2|t88zV+kPA&897tcEp?h#TQt;IAVCY!$%e>gFZ}a|uOBwGGYYL(!gvE(%mX&Al zGeeb%XY+PK#EHX#j>@R>l;K^j!}YR&*(!B=Y{pZa(wUE>@m)45zP|a7`&!-tSE=)r zNef?M&T4k*q^7b$fQJA6qX-V3*hoH34fR{u7VCazbV|DLLTNeMt%mHvivpz0L~^%K zNE{sPU*fV_T_T@;_ZsFH7ow}lb9h~V-_-lzY?##}T{|?Z1ILtfE+2X2<79uj7`gwh zmlYwkvYVyv)azG|!TcVb>wClFb+oZBZncTi=AHcFxxW=4bS8lh>c5VkZ0p(`TaFUz zUt7!WQ!(4PArF7xKK`QyQsO-MQMGq@d?8$hU4<4FB_`{Ar+s_ox`vlaB3=WknA!at zFWt`(+5zZ}W$$t?64-zaa*ajT=XV*CuL`#*=8zmuziVw`Ip@+qqn2Y66soNLqgYJC#KlP$v= zZ_40%_6;fxE^RFggf8?5naz~nR}`kNRc}{ME8Y@;=QhZ{5-V_jgzG_Th?i zuG)js?Hj3mK-(On&WkiQ@?|pm5DmSiwgdeBOw`yTL_64;K@LV=Yml2C-EU^%dkLhp z-pkEm>0}PsOH_x}8ts?*m9FDIHlo5Smd6&DWNng#)pZ3*A@HsKGsQm`6vk@wK$ze%bv%V2XZ9Z>`U3vo1ZWj~d{8*gs!|%HAH)+G=Hg zb=>;Pj5W|u)+d_YOY#wRWq7AiJl|$ES7!`G^DXxMq?&an+8I|{MM^#74?fAY#^;;P z@`7RF{G`YWC|f;MaB#IF@0L-AxP(*5 zB&tMJ3%iy{BeKTUW5-3&TRSQZ8iSbswT4T7^@{Fy^ZNM#7jw+)m+a;7rS=VMA%f(> zI%ZHkmF>C_ybv+0!5-Jy2IR0H*6 zUhpN1{^751a0zWJ>TBBHkRBGL@o9P$+nIs|z#4*4TxQ#9(8XLodhunK(S7fjLjVJG zm(Ki(8oL^iNtUGvJV%M=@ld$zW|5lP{zh~EsKBr$Uh(dl#u@(4oGBy45vD_%K7MXH z(c(x<&EA-*h7Yp1oMPBX*go{pTT5d6jz0GW*Z$LaW8q_nVFo}ZkeCPCKZlC88nC6@ zQ!*3&trN}5fmOK_Ol3TW^Y*85WjKZEv;D1EVsBO752onN5gU#^TeGaYKQochnfEJ5 z?uvi1wV!X3FWYp8E@K-WMNzw)mM&=MMI-|&Z`?_U93=_UW6f~ixu1=Y&sK7_Bdo?S zIf{T330miKs2q3o%Cl2#;nHP|{-lhM@Jlj=Ek58NKLPk@{$QG4j%zZ&Mw)|bER3+t zaf+9hl10qg`hl$}zkU`GFr>opC!~BUIu_)9Q;lh#9adNWEH|w86v0*rH;Rl8xf)2< z&V=BNPtPXw+bGKn$uwcmIrXTy2IE&Xj%SMxwQo~z&CKj$dVR!%r}uYMTTseo%)8;a z6nlbxGE*@()rRLY5bdLYi*NCwQzs90M(E^)Nw zyGQ95k zmah&Eq6Fi(rkD#I{QmNih+`|kN;)InlE8w4ohc^8cCMlAUzuke4FP^2mSlV-kMd_{ zQlIDXMD^{!rKnNTr|t-`phsx)R;2ih6mt7Yx=|{ET%(~G=0-(8u&PHPY%E;KW5v|t zV}|NTj0ctpbI6DLngO7@)vCD=0~E<_e=15(QG3eD?`S4-6gajMq=)a&aL0~2W zo#2PoEa0xXSTd`Cu)0>~a^w;zgl+hDN+GLT^{+(&R1kBBbn4w}`HQm{X<}(wVXqLX z68^hxPn7Wx7Cas` z-Ue2vjNvW_YlaY zfT&TfDjJAg=KBJQ$K`1iM~%P5=cGI=eGNzgg=y+D{vB_KkP{P>)9l}A$mI_NLNCa^ zIA(sC&0K=-c(USG%>$o-_~%Jbknw*)h#T(4H|D$2H{=k)X8e4Rhq*BO42rkM) zi?zOcUl!7JX4-HY=_>VsxahG(Ef^nhk}?WVN~HX~bFXZ#$f0B2Vht}e=jw>ju;tnA zrO=q68-aiF2npJFLWMU-%4zG?^9p2z859U09J*cbheiT_7B%ze%Ih{d z2-O_2X?M$)$FnaUsw09d=5gG^E#HU>A6H#w2A=u+c%JIcIRm#_O_G%w+tlK_1(xg{ z;I_S5){8aN0dk&Qnld(fZ8?>=k-vyu^AFcf3YOIp528)G%Z_tT+ax>{ryT!i8xG)% zY6w#5LAU?0EA@UuHC8+z{{2#0V_^A^cMKona?-R=i^ zO0naa>f7hU1T8~@fjJ3ZpM54^W2C)mI2BxGOY+eAk`16tmx{YVm7~lV?WWq&d2v`)TZBhS*srPO zy!m^DfK73MSzW<+oD$M=RPwJvsVNg8Itr*+EAoKr(Cu(Yq21% z&=hL_1_V*@F#ws0&%_oxvWzNi$lppVQ&Bo={rbLnCg6tP(l&u-s5F8$f@{12z+jo~iv<-y6TF|<80-G;`07pm#J ze z^hWp$k+z;~gFNa0$T)D!ZMC&;Mm*sfD)aP!FE?+{()s~VB)lk1 z%Ec*F8iu{0zel?uOvf z)3n}IVTE!1dRp?i9i6`2IzBzyn@e=+(7#%Zw|w386tT7L5%OkP(6PYze|j7Z{WUxE zvfrlcyscRg2RUWL@1BS@t!ex|Wrj0J?vqN{FGNcLO|K(Hre5VO^6o9Zj$fV`;yG$U z8&^Gb!m5SpOEnH^K0s;`s7atEf!Z@bY7(ePpe6x$$@lkJ7&?Ju=%NWhHOhhCR4*F; zKBoO|m(W}62@sTbi0XIZ`Dw49Ai?x-gLJmjC)cVynne#PKY~K_<#a(&Hb|`ti?g${ zPq1tTn~gtvb~2PSVqLv#>*|_5P@8pbv{6WJT2ok;1d<)$o9+-6M#wzV`uyhxD;zg% zVRC>*qwR7s#sox0j$T=Bl%KJ(D3M6y>;_hhV1u#461nlEs$=_UHAfw$dHTK zgY`Lba?WvN7WjF$*%L4ARn%z0KBo~BOS1dU_?5-c0^bA&W@&CH;f$!GY&fyvsY&(H zIK9|2r;*3geYu1AxVN`A$91U$oP#&giYc4xz{a1^vsL(%@Q+Kma>*r_Yl>*>fyXsd z!q=kk`WyCj1AGFU@{znP{Z*W>vhLc}trgPEr~@_*4h!|$GL~nW5FQep*kNUWHw}$> zosxjZ&!Z5Ewi;TPm1N1|lFRbs8+OQ57h}v}6soDWiYQ-NGJHmEZ0p<0l3t{$bl`bt$S^4{e}cp5f-@(ob%#wsWiTS z9siG!(%XJCG`&5$VC|OLkZNdm0Gy%~_;F}xh++}M2(C!<#6_0}(!s!4<~CRaK6xd+ zi=XJ6T9HdphY$a_Jd>Hq^EapZjZF@`(Q4Av*@=dBuZO{!{LNVy@z94`k&X8%Ql`EL zaZ+w{ducm82rqhK2A!c5QB9TZ&`{O=WXDF+>b-P<*ErwfB z2uo0hgP;UrvKkv3gK#94#D|56O-V@s4bBhp-tl<66@{EkCYza=iMS^l{NFHIOywaJuhl14E2!~?D zl%P-=hfAE7oU)26xO2zAz<@^VE3(AC)ZGIyO)1D2kV{PWqb1?-O`%GFn{>Y7w$jeV zCZWG3vr9Cb*j1K2aD=9d0Z}wjIFySFEtJJqD_-_{-7t3an}7H*c(X<_czjj$7!1k1 zs+93I+Su6GMYB71?l`7S4^7BCO;aECdljaFY`>|pCGYK@9c!&a`N1iT_Z;^Ur>>gi z?@r$obttCe$uV=Les!@1pF18}m^ju#{bFWL@je%#=TAdtBi?9!8m<`4@8OcC;6skxS_%@Y`j+GCM&*Mj3CPWf zf;0jjpP=T__VEK0TYGz|Uz8Wv2yA7iMAO}>Xr+JQmlvi| zF+YPDkICv#Z6B6*A+SgYb`ZNTQWy|r0m>GhiPGyP12p{y2M1ql1#{tq%9v)j${7Bm zh=>S77mZ0=3!JH`>Q6MQ`|G!=GMIc-w<{|v4PVJys6LU_9g1wjqad4;su)NS)^jqM z9^!*#vU^=nTbL;(Ys)Us|cZ<-U9OF2Z`l z=^7Uq1g#18I`|WM-8x-_7Yz-jazWK`di#hrynjm>(gz?RrpJ{$39YJJ@EYmHCnYh# zh!~vF!{n@zquhU+vGEf$Tnp9G)wNiwW6cXiWUQq9=a$(W|SM@WW3Cb(9i2m;!5!^C-5k+Oyipi9mN4r>ycW8W%nHtP9-KL&Jikt zO$`hx`bGnm88%Md>{9f*t4%M(601cTfzsT%o|XYcOro{TdwTumk>F6SpY zff`GvAN&r02kCJ^I)NdMGc+=CCd_^n{<7w_Hx+n`TyLtlhbkEp54DuC>l+ ziZy5Qssmoe_UyB_PhOfGJ4L>z1+cvhXf-Dhaw41Z84N}bcM(Ah2R^a)h#$TE3Yn}h zbouN)!~Xcl_wHrwJHf>oZZtI9_weC$FqohUn{YBNFdMt+jmv(e41UwAgdbK7^d>ea z`@nK-mW~d>7{hz}_HE;RXViVC_M1Z0un0nlzSJ6$Z4f=UiojYp8TQ>udvkO1SA(dS z&6_tjxymOVcqrwTZ$*OgjOD5N45b2Jyg@m13$-QPfte4a_uhfj#H6IzXZ5CcMd`uw z!DWH+FW0Q+#69@Ich^syzdUCL9Jy?~9VmYvhSnavEp0LrK{!3W5pEX@yc|&STubcv z#p&TUWEjfV*S>jxUkg~pNu3!RiV8V?UF=MNLr*#X(vjA z`km`}yzb(5-}m?Z$M5mUE5rmVor@Ph;Mc%#p40va~Bj|_)1Un%?tTwao zaNW9lw;J(}f1eu&goz+(g#p*BtQL`xTN1(7Sk1j@*5|YQV>jHuW@+VNK@c>&sJPm~ z)!h@lZzl-0P;XCH^v+&~>K9npnpvXv9`wG>9Wh7{a~43oIezDdcN_e^3Etgxw6-Cb z-RPayX2!eujCTuLcP9knieOedS$UeF_ltaI4Yrh4;ivEtH_s13<L+VgOM$+KZf3)+EPduXM$kdZHF+UKh(;2 z&ko}`LJ+gW?2ty$pBH-1vd28EL*no|xRCY83Yc^pF$}`Vbj;bDtVeWbGr3~ANUqt( zT|E`GPz!>YJ>-t*A{m+8Jse1QM3?!C2j8a z{cN{sAQ+@Ww!MC~I{N6H3%z?1I)p7@hqTR$`nwY@gf%KT5>}{;YpqeO6`Zr_?h)NXx~Bv$`Yu7=_vuRMO6bbzGUy6XDH}bD=`!i^ z(R(Ip%cLtr|1#dskkn~`a=A_1{Huq^NjLId<3>R{g!2+h|h82Qy zM^gV?@J!XCl@DzQDO1s8kh9DTjguX+IH(7k2OG7cVIyJfQHd9QsB_-~S)?7Bm6#UH8JNc+ zNM=70?spzwj$?ZVsmw?y@PJV7PRVGp9>I=; zgE?V~q_sxaoJmV|NAOk2!ZtWj)GtX}MY6#U2QBumR^ir7C|Wy!U$3tAW)k$y%d7qhm>iqtagbjp$ne$szYsdaa+*Z$@P)#5c$U z(gW15vKXMX4=-xph9DG>lv{u53F}r2DE?*Hz~Qg<^$u}1GbeHB5tJ9n z?~49G4u`X%ccd4Z&WiwYIxhlGril9dP6<3RSeHBc2201*4zm(!A@7B}3;9MGaiEXB zJoI-U};f(_JjRJ8$srxNv z^%7(i4XY|zE4`hX`Xq?fK-UQ3$BC(_Z?~qVe#D?P*DHd!e{s6M3tA6K525;V({-yO z(K_)cLFC+?4TzFVLFE5U)8=8?+NK zjRc|NPY`O)2;$0Bf>?{-=NMVqS>P2ITD&2kx#)w|O~fMfL2E3s9FCp~&?gyvR-(^S z^nvzH^kGFG#4}pE6U2A)K{#k=(G#t!XqKTTTD#J$MNb4zvk5(!k#%oHb9pOaibfr+ zJ&*-hARB<_2)+_**d2XuBh(3H1OrwBUeulRqLzg4Pn&_v#|o8Z&JU}4n14!ZiecBc(Pauax6PKR_s7lzm6wAYcUu3D0#N1KJ#wUT&UPK)*$SbFffoK6g> zRnf|Mhawu>0|de0j@Rh4@6h-T;q^D|ZKT?lc%4m)>}kmnytbxMLqlMI*U+@_1i=%J z*U)rme0bIH8k!F60j$!(>t@=$$R3{Jbu%p*e}UC_-As$@SLh;MH`Af@vT*Cqb#o;_ zh_A!zW*Rj1;-AsT@}hs!t7nLyI95VN1^xxb8ZuYV{IC87%HBxh)K~@jwIO>$wrh^Y zo)_&XSs@tkMvzqrqf8P;2(mC3SMcRvJ-oSItSix+ke?7Wa)pmO&DpM6+;XLO~VQeqAV3Nbx(*& z2iqs)XE=%ie=4NxGp&#c4Hg1g{B;bemI(PbPy@Z;-6*hFymJJ6d7#}Rut}hSGXNNM z7)RjH3TN}E?RpUK?{TZPPGAzsG4Isbfi?B} zJebaF!KZ_EL8kVMno7&2Yh0Rf+hS3Q6eB1DGosj&_2-mbc;3Z(4ge;QAg|q{}{)3!5 z;1T|4V@PHge^1m3aR96wtOi!{6l9ybNeiToB2WNZ1HFL%2aG_&9l_e5Hyj_J2K0g@ z0!yc63jl3~BJh7_3$Ro5XDh@lR7#i*_VBQG0do^aQ!2#ond?lu#52Vet5I9zX zEWj<4D8E=AmI-?y7-66S`Uf8eUK7UxYKA_|Gme1do(>6(F<6tML#2ergW3YNNR^GM zK}-Yd!G_$ohujfn2Hu6i)UkdbuYmaLNZJu~H*@-w1~dhhhOJZO%MJ&?8HZX!dy{uE1-|9Dm4aA?wA`gXQC_ z?%y+6yodN_>%?=y8)1UeB5Yq&cyGiD&V}(l@9*9a&nt*r+DK-c55ss^{>HO4TFJqv z176S^z(N*_Er)8S%Ba>I&BR}MfbvZH!%@wh)DGn5fDJMMtVM`zc%Kh&gKmK4Ouq=a zhUko26%lSna$Fz}1ZlCA!cH^n_G2jUonX7aP4Ph{XB!pM4V?J%n#8S6`Xe6 zLA^846J&h;^VABJsVgW{{{*#UkQ9OAycuU+)Dtu43#VGt6R)QT->)1{Wd+Dwq_unm zU4mdr&>Nh|J^ZPQGSK8qk4hI!N=!X(D?@#sB4{{$%O-g$0`1Xdk(>cebcTm;=b{gA zhha((*H8Z{%{&7n>7mv%7+r)1oeiSzY}C6PVJt?Rl_7kO$P+xoBPka?`J2fJ)K8xp zLJ6z`bOm@pR;c?;!>ENkp+q+Rm%jy?2$HI;Ohozr?JTp1)Cin5rjc4HM_iZwd@llC zeqt@4OGj^1n<+t~4`r$ifGq?4Y|=iSq49xJ&s;LErLHEiw}-g}UK}!(|Es+Q@UeIw z0%8k9I`A3)xBCpB3*dsv*+1_xz>KHv0f3MCb;Si<`2XJ>hG|a!yvOiso(g0Af3?4$ zL`DIKGI*s;&0uk)$2ov2T7BVt1<2ojw^2ANg#Hj)Afp*U;{*9QV8nYJzptZqBZ!$h zUa*S!gNG(pH?ZD^>>1(~1@!~XK~x0W1R9V*{mwg;F31461?(_jScqhR2`qq`zd~<_ zqJSHASHZ%jcNwtVV;_QP0}hD(Gj|#w%K#~;{oxD{B0QW1U~K?a97$(pwA1?tzKAkl z!Mp%}cpZ<|!_XUAfOD`GSVcqKpZ61R8)T)x>;Jl+fH@gN6s9@&vsUnkgSH`$|F``F z7&ELld=3tK(Rf6t+4Zm1hqVqf7r6MReFMNaJ$5s94DhZtU=cwu_+|j?Nx&F&Anjo- zb|Cyz$$C-k1c`6@{to2ma0&!A=1Yz_l>amLKACP>SQ=kTGe-$LrOxwm52b@4o39AeXwCCW2vbf&AsQ;CX zAg*CY0AEobn{U7FMdI% zpk2sjF@CBB@R;EBAnZ(lR$>1B`GyJXH^C_)@CT8F99zUM$b&}!_JHu5gT&@{rf!&n02tenD#Kh;qQJK{6`P^!2AOI0D&zAuY{&+@oDRS`DnoR zCu_!$6e#`55tXI~s{gxPVh;-=NaYI09V(ZA6?`{X96sd-IK1YV_RXM&Y0nIr25=#&LE{E=@O~9=0P_HQUa-{PGYbq076YVCOahCV9wjUXwm#U&H6ujec23d7@}!w}bQ(A0p`E!}f#>h;HkWT9 zc=I1uc)oDVGb#JCvH zSbVGk-IXXBeY|icrR)U{V(VG+m_Uk(xaWJJch*Jpj>V4rMxd%Dm+tfJh`9$l;nguF1+P5j|PG2G<}eyVmrZGXVgGnzn|cJuo&SziSI2T zPIZvZVN`yN0i^4c*bz7W;5Q(yK#K>WOrbeIQkdQ$hneC;_|h1Xl2EBrZ4&mP zZu}PM;A93Y*%I{tD+CFx5SD4F!CI;JmtY?rpQC?5xc;&ok|P{xVP6Y!H@Ktq%Zi!M zM>n~aAnib;aG^1zne`Vn*ki-<8Fn$Jbq8||Vh8NNfi^KsbViBf2A;i1Nr4_@1BibT zCo2Dq&hLDKp3wLqIM@ZJN(b7Z+7-@VVAOG6Oa=CEK+eD04~#rm1b7#)2RJdq{>~4L zlrMTG`9%>Fyd};ksD2Ihhky#U8L%+8lL^>B%3t$4yt;t(8+aIqNYoWCoH~Qfr!5iu z3Z?-#@c90h)d9snM=L5PkW<1e!RN2wOX1X*+Dcsof!~6=wr|Nc?C(@iKalB9>j%IC zdVxG>W@N(qyU+(PLo3$6OnB%85`rxQ6hsz0!eBl4?k+yV#M;2x$0G@O297Dy^f3jn zNbH$sM%4E|CBi2eGo#{GLyCO`P?NkDwu@d4J>e#y6!{JJ6ctek?kUQWx5MCG7~C?{gqvcBkN=n-B+MV?2h@|d z8pTM8aQAOB`s_fschPS`Z4&6S7?t3r;}-PX2yZ{@;jSd`4YwlE?a03{$)j6sVh9@U zO2REdxIsz169@M%LBo=IyXNI~$UvBWFsf4|crfT)2+esYJn+KT8Zz&$>aKe$y%Y8}CVWTd4%swb-bhBR$P=LN-)Gu3R3}BY;5jhUSAZnE^z-RC&=bZJOM)qa{y-Yi z*3c7R0oP1>l|m4hL$F?KtpEph3|xVoE0ZuAAy1~Chw2Tf& z8elge?$De@Z+Ps49>%fokH0b=VYjeuA?X zY8C;phkCXTF&)Q3xP|hco*Km&oIn1-TmRLDqd$&PkOe^8#H&f_$uvYZ$aiqduji!H zJg^IK1MAgaa~o^4U*nEia9o8`eYm@gGd8^D2fVQ30%xrFqyWlPxL-9vl?I@_e%|$l z*!z2y4f+KfAQ|QzBJRxm8l=U#1m6Sq#$jcSV?DqD4>%)&xC}b~9Us;|l~2G&UC-jX zYcP5+##H`h<`(bB%mHX%Sin!UhhHVe`=Y=PoHziNkZHiKA8^%$B>eT{9=OCBhhJJk zPVa#14c~01TACy3i*KjDCmhMU=`(4fIq+ZcpXC0}88X-jXx19x#r6VHLM_guz`mW) zy%}*DQ&bQ66PAbiYbCIA*d?Q8zhH-O5)LB?HxQ_Os5vK${d@EQT7V0FZHQ-)GvWYK zgKy9q74lDZ`kl-%fdUm1>|4S*4CA1#DDa$wEYcnP*gyPc0B5WqIsP>l{&m1Kef*2C z?_@h*0vog<<$z2dXyUtuFyCN2@ErTqexVll!27yrl|^dQh8+FxND5DMdtq8@kS#-L zI?{p`aLwQQ;GH!mgaP(?0h=Xx7eeG8f0cmZ3W~;%U8o_iI5STJe+Zc=&PnCTd<}l9 zfcz!$kPx*XD}}5A;v?#dYG-DpdjHQ^sUDKE$_T7Sd%c7ALnf|Q}MSOp|wX;sJY5G~0GxyHioMNT$YlPYe+Ri$2+w0i$_+Gw# z#9b%&>MLgk%EnXW8p2bohDS9BuTg7Jjj%wSLwhusy^ck_IulF%4UZVDk-Y!S8FUa< zb8T%`(?HWe)JO0@+ktwoW9Md@_fD~DD(~a6az!*(I9PZcvsUnx)w4bKLwi`G3*Prk z%+M*XhOpPMeS8299Es67Sf1me@Z(-ghv)c;$B?lnZ{fq!d+)csj^P9Tuu6A2tG0X5O)L=>kT48w| zyFB-_FfLEAYIJE=lGO2fh!^ysd5FRv$V%B~xcBfUjY=_El5Za)E|AnY{G0~D-~zIG z9oHU)H`JeMJ4jCLVd(F545&`Ax=9AII#~LNV0!1cOr)(vwOzHOtQEbE*$}3|=X@+H z#Av79px?OR52M5jwn z(9x_UXgO%;IB2FG5k6T#} zIzFt~xZUFDT1iXK3uPm^lw&cSQcAT5`%<7w{!wY8UrN!@GcwFVjq5oOPqc_SJp&y* zViAGR&~nV9TOm%rXa0h%nG6e8N@$rKuG!#r{=?0Y^@<&(Q%wXb=8uEeOnfr*tUTeA zb7b+(k%^Jf%D2qAhv{4|jX5Qj^%UA=ddu8WZ_zq<-l*op?r1TQtkq9G)u`rI#dz62 zi!quMuIjO1zcKrGO75JS3j6hU@I8N2Ty7JiaA{>j|GR~w$2;m)^W4v3RXF=(cFcwD zTQA>l(=6V*xB1G_GrbBccD!TodR?=8uAuvYS9^`VUlJ}G((q5|UHkm(A_m%~bJ4sj zo_q>7i&%eIZ(OiXf~DtaZbE5HzNHhhZy7CjwB-28_dn>J+1!;+B-2jlZ>bJjFsk$Z z8I${g=KbE{=>eyo-FIH4crR2y`}sEAqXLJQsd7iljMKi&$Y-o>Ji7XQ-M!$YJC~n6 zztc*1Sp9mmoOQKc=iBD=mg{L1z5#TtQ^fWpn(Hf!FYpCUhSWy~r?y;8q^$A(@cJ>G z{OM=08o_P@cIwxoXbLxKdAJFdSx4j1}{7Ngt?3{?xSMG4}trK=_>5sSHA9%%%H6vZfYwiHrA#@ zG@stQn)g9s2(eeAp;f~j5B_7dCCu|((;RLbl)~qe7RI_KKN>J0LO^V8Ln-e3=icfK^l6E?{<9897~=e zG(J3EpLg@K*U*Mh2I8v9qp)eL{GiD$E{Xc|4gPU8+A3Z~_^7f8u0uN##{z z{aYgjro6m4aq;aYmV;y0r-(v_3gi2eO4_*%*TpIma^6o79UF>UV;&_P2#gZde8=AP zt|fO=L1eMN`jbgreV;7}Bd(df>BH?;laj~oiSBwwzhTKo#gR70MImAZhbF4GcFewQ z!{Rum ze^+pQe(%S?J)UF!A8F{GPS)4(2(0s^R_DyU%q9 zyYil3-#@aorg8&wzPr(hw-sa;Z>+<7e(R|<1B zJX!V3z*2E^d;#6zCvGBxArd>6seY|C?Ge>zP0%bGm?CC>H=)G#jAisqm>!xU4i4yz zJ(JpLT)6Ap=aWM0l>>v0UVTX$4INIrVf&U+a7FUM!7Lw!)`}0!66qWcXB?ju*UNcO zI#)(+F>>DNcsh;i$q^=_V$QT;mI~3P{x2CFulzFVPYi!UW4B zN=a_*%n8?N*X5M*SSIA`9VOdrPM9hbKWa0$aC<<$I?k@US!b=FQQm==(hD(+Mrx5_ zH3@q{PFsyONsA2y1z){z(4_R6cEEg%D%M*s*9x^h8Iu;2vv-rc<9k<3tM=mP&}u)a z#_%}j@}3$VgVYD-uDI+z6_{B#)V6rE%+AfujrINw5C8VhJY6xleDorFTw4 zQHAnjh8q+&J+?shH0?{{(iJzQCj~#g=)X>L;flBNCmz+*icCJ=@jSNm#mkT8Rhx20 z(6dPyxwq@|U(CJDHviK2MxM7JopA{s^GlV78DEEK`e^^)eOR`t<$#>{Dvvp{YAzeG zvEC0K;nv}J7t+zAq2K(Lr_mxW(@bH|fQHERy3g~r@!h**ucJ#C-dt`eay`TN{>SwQ zu2sD9D({|~?CICgZ=vuUy}S6a$J=FgXD?Wm%3l$@v%K8<=9e)&No%D$n~zO!if!O1 zTf^4!F+VD{OJ&t9@d3A*!m}+jvZvS4`-Mwc?Co{rKKRYEk9W3#FX3~v;z$UydwdM# zRgT2IDZ)ow*jg&)WztZ%K#}p#q@c(7;fDbZdfPwB@<0CJ%O_|rDQGTzUVLb1UAJ3n zp6f)tdRLFg6yacAcztbGlXsf8bA^_RJMa7Cth90w=M0t=ufkXMJf?FW^lzZ;`}T0@ zn+MY0zMXBz+S!$yq@a;JxN&jc#)seKOC7)4$ELc(GChym$+fHUDepW+`#a$Wolh0m zrQ1q+c%0=mN_4V&eq6Spde38izV%@Z&o%~SODpUO5a_Ji@o>qfeF?&}+=n}_sg}Ob zp8rnLf5A0Bj}^CkQxo;#lsS~H6Bj9KO9$Jt!enM&d_PM>AoI*EI~mul8f)nno?Ed> zq260rAy}xvBW3Qcy)SAC=(q?PzRhVgo!1sDD0iPL=Fa@?LesI28l8s&Ri4O-KQYl! zeG&i8uK8NNZH55vkt5fxbYHu7B>l#Mxr><;pDeLVXAa!0?UBS{u_bl(bJZihHv%PI z2oUZnD#zw+c*d#{w40(r7n%tN51)MN)M6 z6l{eG!w*Ys?T*)(cjQ`9L52*!I0J*!*4@hXubnS3Nb(!_T~OMjvoP}X`6yeiRZ5oX z!5Z8iEH{J9DZ<7z^|aY{f(tI(mA5$GZ{V8Ttrp2#oH!x5Jdj)KS?=Bd8iUsp(rk0) z`p!-FQteq@dMHcZbl^a_QjWMbbKdGVCOvbQk1EP}4w)Xx2r}&U7~VTL=AKje{e_ou zPp|#K)8{kCqr;ZpDB1Dtic`bUIXUnA>j$o)b6rJ~l;+^j*!( zxfeZIpf_%vEz9o2c|q^2D$lZ=;@uaXc?_|Qr4=tdovYM1C$XWRd4uy31=~t@Zode{ zx~2ABpNn~RFz%VZd(PS|CkKt*_>I{cFHNZuYWe&)PEG5)nn$D5GKYPwFAZC+^Z8p2 zyeW2azM9h4#(R|~9@LjKS}8BynA}*HsBUm^=)<_t z?m)Xm+HG~#tUY=MR$j7~rf_+$e|gt>_T~BKqQq7>ET7z!v3z{8-2F%76fyi`BIS_V zo@~1}FFXW_2Sq9Rrxv`Du8`2_94oBQA$r;fkooW+lw51T9R~2Zw!sFu{G#TvA1*)nBHLPxXeW1$VySe$J3EjbWKQen~BAo+u4at z>TzAOT!vh^qE*LI%HPJvxQs9>myTW8_tYnm<~-eHF8iXWtjSZ8!=^D8km77KEr-*c zm$4}0(#gAGetqhj{SN@iUH0y3% zvsT~M`1aYvSl9W^0=eY|X$MyMW$(~&P3#bnuvqgf!0&D*OQn=vw#k#E7kU=61Kam6 zuCwVe<_V3{3gsx&4Ydf_F_)XST-9^)SIXv$DWbff?YsV=+9{$>e38-B^pPVI!Jh&b z`Z2F_>?#^G(kqS;bh+C!Uqg*Kr;)K(%vV0WqoJ71enY>QWXj?X>>t?Y(Qqw%8X%Nn zkaIkQnUXC3CcCfJHlb*J;11FDLYtQjMkV8uMy`Fs%QlaHm%W=iAvs!DyqayWg)d1- zH8}Q#{iY3^j7NMg5Q2s;H%zF%&wum${91RTT@fa&I%bq&J#BfG0_k&&%*O+E>l;m6 zw+S8E>-n`!{+hJak6lld)v~VSiu81ES$WfOBK-L(y^LT3!##<1Tti-CTWEMUsLk%w z-%OK}raYLQqB7vJrTYm-w5po7Nc1C+$M5mq$24} z8AGJuaidlPg~Zeeb%);KPF7iWPs*{fXL>n;s8)%9SC|E$I4O}o7^@8b_iWbSVZtlWNR`D=b1sB;=L z&|g!ZT=&slr`K+g@49$C&!aroJubaW(8@SO`GfEx=*a?sP~CC&C*0)Fgve^aFk5wK1bbhI>%;Jkv01Ag4SCmn{iLbVgU?4!-4}K{ zQ*fjHW15oTE?55cj}r3BVz0+F-|hbp0hz14**N9HuFuUcY?F5R#;47?kgt2=dH)Fx zna>%KW35L<$Lo5(1ekV|oYLIGwU8Fj@RVmJWST6>}V1j zx;GN?DJAF1C(ErZZ<9YsdaoE{)UR>q+k+@ocM9g%@}>t#9pS7Uowy*A_hl$!mq?U8cYNx>xPsRXOM?|V zQw9ZO>IG#UMy-Hg(+o=uNsYv&fKY<#d7w#rl56{XrOF&zVb(#zp zxo@qejO_I?G4}{{U2uZu1-ns~&ip0)+=_|oV;|Qg7FxGS4A!iaW*SWj^ghP^=$K5w z;!O*4KlZ%{+K_s6!`TgX9Jj7;Nl8C3zfg62ds3Kz&n1Qyjt4vD28QuoC>Fn!$jh`O zw4QyX<$`%X%so0|X<{$w<(%lYdd%N1qan6nW#AJ z<{OLG`rHzhd8b9uq2H>wgJJ&@K|Wpe_Ssvu3$FDE9b28uxrLdJzw<~FMd0$e6q#f6 zw7d6SnJr(r+Ewt*;}rhevI#f!+#9#ke+s&}KHQc)>&D_er3@$RHB>L8DqiVl65dof zyW>{uQ33g#*9=7s!j#=^#g6lj-g2^QU+A5^r*!M(hTR4}DqAep?5jEw#k7vy?Gc}_ z?kv62lq)rCsnSW;PwB4JvdCN{EMtAMLU-Trwq=)xPp)IKHuq0bCYK5pgSo>6{nleY_(Uq$x83ih@;H>QY7>Irq3V;+^>4wXTCx>_l+2OPOHgQI4Fi;i9SEMPuAY^V-mwwelce!{v$V zaZzoypAw5XPrf-&HUFX0J*zXL3MSu*mW!Xg^ZeGR$ttH$>olP&Usan&xAlFT_uM9B=*_91um}yhZl&0aA#c=zn6T&g2X*eTpRY)qm(f zxk9z%U_($blU#VD^v0a)wB7H;%sXQfB_~e&G z>)LiX?43vwJ#n&ZSmd_QCvR(kyhR0(s=7;yDuZRS%T5Zlw(m`Iv|!-8IIynGO}RH* zGCU;K*vXt*Vad~ZDzYkL*7>>8R)ts1&*-l`S5WF~>=C4w;;=j9WuFFb#j2;G*S_!g zkXm5aH~KxmqQ7MJcZ)gN=_d^OMdM0Ldv)IU)g_r4WRKeIF1O398(Fj`eu-Kg`$r?9 zO0x9a-E~9T-Xu39DV}b`|lO+sG_z zmfz}YQE@inf^C?)mc--Pqsfs9x6+N*9qqE4b#8~!?8oPMRRcSl-yK>=|2{1J1Kk$J ztOcCxv^%U*%!7)b>3wU-wh43>j^Cf&O&6pcw>3gay)E_ot47!7o1nJ&m*VcPT0d;H^-e+jhej=b(}%J&3PHso7P><96c&S^@Ikq_ zr(*UT<-Q{8w^s#+Q37WRHP%!mU2N6X@U=Hqe#9!oNzv-w+i>*Jeb&N;XKEr7mjtuz z-^d5YzZ~bzqB9Z9^Wrm|liaB75xHaA&MWi*O8zW;sd@KZ1Z#L}1M-DMxOp=+o7PeM z_NiFbyKuWzZc1_8v@^`mrHFn1aPF666Ep8{9Y4c(?bx!|I>)HeM}CD>4X-*@7Ujk^ z+gfOHatw49DLwMbT^OlXyiF@6OGKvYu{(=NbXtACp>sBC?CA?D7u@Y{$Pr7GeZTOY zRrqqvxb*M$WeCRDC>sBXZ_AGkbk8>BC~wjFI(mORN4nPGx~FaM(Se98v+fN)UZ~r1$*WrE1p?y?%xoXDtO?t(O!;+RyHvJHK)ak=u;IHd; z)a+U#W$A9oE0sF~hxvO}ddRDG)Q7+Jw|#pcFRjjjpK`R%RAutGng8Y^&E`HG0Y3~D zjEAh1u1zQw<65o`hwU)U5FqBJJ<@ev6XzZEj16mY^u+;P>C z*9I20Lj%qtON!spzIQw8a?#@aCvzr~rItB5PRoRR`WBk*nsrkrH*QsxhviWAosl#9 zFO=?Ui2SN<+cEI5_Hnl-x9Zj4B=viSf)bu>b}rcg-VUZVnTC>#vm6v#hdMe#1mkX2 z&ysi_=CO8`wV8HlK!d;;v&MS2g8B?6qt7`ljaw8n{A*T;C&bxwi!SpUD4BCFdX;1T z{SBP+_7kha?kK$Mz1Te7)SMaeG{5dT!E?K~mF3v$vn;w-jvx1lyVxk~aum9pOo#Zy5R5e@tO$FWg zXZu1#g)O*@-Y;gORpAR{Su7)5#K(~q)Ttwyc1@)|ab7obTB~E}{3RYHDR1ut`(58$ z+8}CjE{USo^ejQX@>qU5<#2-E>x}j{bDdW9A5eUm5*i}x!B>0P=)g9fik#v)*BX_x zYrb_}y2Ij~x9gNFdr`!T9P0<6<&G^o%p+21s(Y99$_0xrP35`}!KOMgCL5`yQ2Zlu zq=NfiWb}%M>(a%(734(Rja2Qta$>_bzY2rN8CG@MC4vj1R2(&9L{~^?&Y0{>;<>hHb!N0 zFSOB>)ihX_GDl0(QSfNb)|*OiRtGhfd0B8i9C+hlWo^IPbEq)j*8bAEbbi?kihAzC z1B>^4xtwaB)qDT6ws_H`(R!8$eYw!Pt@Esm4Aah4IN27Y8Oh$X*dAH2@u45hrRSv| z{F}|QRedPpdq$g<_4+u{TAVc)T{=gTJK?V0n~;(Pd~J`6e>{8DUumNuQBb&{Tl&mAJ2RCNL7#3 zB3k`swWyCR?SAXRr4*%zjq5TC_Y5x%nfqQjB#~ZvSxLLTiMC~sj~Qo7j-P70 zyggo-=9=&nTbc%Q$X7^ma2mVJts*m2$naz58fmth>=+ zaiN-^uHf{2>c;CB9fXvP9e8A3^xV1YZeaDIRAcb5tmrGRIc=qm%Ri>QI+Vrvwn$Xy zCd=4o`Vnnw*MtzZw9P|7XS#wDD9s+aT7x=*RqqcjzQ@8im^R7qNq01Z)s*3=7dp?S z{hItu^TFnqW87!W;FWh^tRFe^p$SoeNsn5G)06zadLW-ct8X1h~Knuo+pXa+7Z5+{dsT$gOA-zCQ}y2Dq5 z*K3W|6tO6E;?V58AFVAf^S>-wTh+%F|8c2jDZ69$@Jp8D8b+qt!=}PfOFZwqz4+mC zl|*E;T>S8gtkv6Tv)DE?Di-)WXVa=o>Dz5ax%qU_sSOjsuKh;mJ}@fXsn|Fgpb#&w z=4<}ZYF$CfJSq3qs_;F4NXMPgYQ#>VME2b%-(7_O7C0C>_<&Gc^#KMu61uHJ3G6DV?gNXZK=-w zX8~MkL2}Kj4I3;TdvJLNellLN!~DamC=TBf^&Sp;e65ef(5zF4PI7oLmU*Y6O`xv) z`Eaby^4uF@*S^J<<^>!)RdK=K#g@@9)tV2F4s~_B@@FM@+;+2XURcs;B4y+DttGmU z^62Q*Zk@wgA$#7{(M7L%9Q3;U^EJkbApv9ay&J!Y>@8Irm2z@0dZ9v8*_<+-T&A5= z)#Dz)BYjzfGsNU{_U&B`je*+)6o-phtKz7v$0-mpUJ1|QQ|CTkDBLR7Va0hU0KXy9a4KSdl2&V zCobzGs+Z2&C)9gyaRwVJb3;w&QHrT=S!h4~w_W;?AC!)Nc`oO6uw7k9)i7;y{Pz4N?QJLc6@nf5m(#k?v9NWL|n7^_$Qv8a8(e}KLRZ6dlleW>kZpuiY4GAeZ z-&pX9r(3SE%yqz|yNWC3w67GWqwm2nU$0LmS8BLZjD!81GL39lk}N#m7ck2t@(xq&Zq_@c_7r*}r8&(0FbrF_1Of<{V( zn*Ga#zOATwEA707a@@4G=ypm?v-V}roxCS`LwP?MtNA;M8@b;%F#VFDxU4ZWG_*gK z@?=aTf7E$j)u>8cnBCZNMv7D4fYZ5L;j2mm$u%jaMJiD*wwg+Rxard$l96w5_JV`@ z#Vvelxo6X=P8{tV|FZE-N=Jm|jrYEtQddXHd=pj{4l3-z6a>~?9U->Otev*^X zJEQ7g8IGGgDf>pV`YclXFTYdq{Z4>&2M||&2pXav@;*S+sB+5p!Y^Axgq>S zc77PmQx)NQ`!DuRE}wVhYMzmbW%njN70&Oe(KpX&V=R?)Z>{XS)RAZB-{`OZY%>Lo!MNR><)&iF(-{dX8fjrK79r4O8Om1l(HD#Pt{eN3e6UyPM5fRG}sg` z97xs+Z)aNO>R==CO1{6daj~$?{#>7-^`;N|nsr2Ta{V_IMo5S4oX=~M>S~~OO+D1W zP@?tCqN2F1AuSeMQ^W>$`co{?-rjD$`|5{<>hn?u?R9;96~ZD#jvLE$xj(mBTq;($ zRQyhE;WjTjLmG{vObea4H(fpS@FU9^nWXD6(oqgI7jwMaBa2G5?7z$wPj{lAjV)%5 zYlLpfdtGlSjy*V_G3+;wy^UD3 z=u)!2)4l%Xd)jGD=XKBpUN*XIv7+CkjrMhs1Ud_`GuBVhZM^iZApYw|*0PurVVe?M z?2E)!9b2B}ce~Q0_4&SCa;faTiBZ}6=EeFidbO95_)>>9A#>k$joS&ix*S(SMo}{^NXw(4aj6SuZz}>rSQ)+eokr6AM-mf z+PcIo{Zebg+i{&p)pP+Trm!o&OT%Hbl zr5;%JdH9aeH@jY!G`q$RA-;;)U4|>P3XeKyi?w&w(E4bEWp!SgeCtA$FmGKIyy4j}OsLTGKe$9dT@NlxVnFP<+Ew-!;GMJtf}ac!JW~(4c@_ z_9Fw^=wHi6jEm&mn8=Co?FcNOGo;mIsI7lrSCR5Ea&uaVu_k9#bZl8d#I6*-XcdKP z_YR(osI%xTewtVzKKMBM0n_NZBMt3uMmt+`w|+?zHt>_EC%Q&ctL>L6ER;t%WU1qEHj9%3&tDq1ycEs56U(FY=AmE=ffmjwSrHfhK3^t*(hhGtsg7FSjb(uxnGx%SP^kJduF6 z44TN{&2C{YX^GN$e`@d7;9-6LERTxZ(Y#^x=f~&ArS0;uYMXePof~x1!OgW%HmKM> z%{lI3Rp4OYZP5g$?#+j?UPVSN3@py^^2!6C186 zr~ODw*%vZbDyzD&&m{dsT2)dwcV=C+-|*n@k0_0jn2LnZ1MV$lhJ(WcA0D49+1mae zmzsXR^2A{DnuS4?rYR`vTwK`KeU1kcT%tM}N>+W*`k2!;zgl!j(x7SD>-UA(2X}n9 z(&ZGt_Rz>iY09PVottAUGT7it|ytLUgIB zC#x0sh3MxQo{yTPFjlgS^WolCBb6_t=PT65`o;cGeYXBu(ePN<`>4fT-Rp9ET)t(V z9JcZ`@H?p^9aIys^u#c0_x3cI`RCMC+GS5a?R|Upq@OWp8?4{o zq1V?j=zX0>=bXP@p~jU&hrp9!en$>$I?&T)Xd>k%cf8oH>*eLpFS-=(yrHX?cD@x| z?XO2{4P3k6xiYKYg17P^b;C^SWyTW2mY&y`+s^d9E~WT^d)G7DrfRPp8%-pVS?w8B zXFvD7#m8U2G=fJ)P-C|mgIt-4!X?jjFZniwnOU?}8!w3T&{wS3$J3Wi_hO+Am-Ha?@4@XRGu%Sb)UG%`ec2>wbz0l81~q4xwWS(VHcG15$Jfdhu7Md zpLVX*t#bkV%*;_Jz2oP#V^UUCv|-eJ70M``$n)gJGa9~iF=4lK>|@<`?>3Sjh@Egs z98rIrfAiriuMp;hh3n;2CAQz?;;-vY$Y#89Yu;S`HFH%Jk3OQIyE=Q6Ushme-?M#6 zTnSCrJ@rC#Uu7`ujy=YsEg-so2|YTTVS4=3UH8RmrmEBD4)0Z)8-9A?g~0O#Hn*s**$R{vduZua$SfiYs4AdyEI-jIr({V zi<+{52(9Qr<4x|BRyMvJ?G;Jk(#=+b2Z}}3XJ5)FE(^$BzAz(5o7HN|kHJnUkCRo; zYSSn}gE>pRjZ94jp2a!p>?q-i6@Sh(@6|IOOC!;nJ+Idm9WvZBUZU^Y@AvXeiR{F# zw|6Jx*DlOv&nz41x3E#KSh(b>bF1S@Xi`6}D!g#Wba-vT3PFBsgn&uQ$*L`zMSxg@P-&$S6S&x^(or~nz@3G z9ghDHJVi9@I(+xlV8e?}>yHB)&%LPheBE7Z+s?UWL9d@i#4ZsZjVYon_nZGAt3JPb z8T!kXw6?t|`G!tr-8eXJzW*Ox0lEx%Fy1C=sQxSGgRSgM-*@(oKhhjtIMEyBfflx+ zOi_9bZBc7G;}6}{|Ku}yep68!F?%feeA(%{)#8E~22R=;3A*&oHMI`6ZrRPZ z>B$ta(dn%$>m?f#KDC$bCwCi|tEryiRl8rmgD%5{L0{Km(>S5Ik7MTCUfsQ_`&n!Ko<9ma2fT4HF0sJBbMCOq+<=R>2rZ!llsV3N+KL+Wa98;XMMJA0Xv^;Hpm2s%Q4| z%JUExC9R5|h!&AgjR;uI0gM^o098M}cAW1z1WpR`^NA^2uZ6f3YcMr>W*K4C)(_Pm=TidAbQ zj#bZwDt<;S&~Og&W&F#ct~>%hZsSQCct-&v@{~{tl@JmpdBMMg%+tMrX>Ct$as+Vy zqVu`i%PWhL=CwYd6oM2l@x5)RnTBz2RHh0pbtjFsGBU2T zy^CWt%5R}KNKKAJllRkolG}0DuX(rLNYC0vhrGp@+}9v?cT)9$7N~Brh6-~!IbUcb zEYN`E1~=5&_X|{yMSdRQeC`8PZtC=9zs2a8Jl~JRDR)OgA`7`F`o`LdtRe-ewdcH7nOPXu+I9hMB_f?yOi&< zI2*m4wYpf6RRc*WE;18g+j$8x_(A^;GO6|r_M2~iezAkeo(5Zbc)5RIxM}VQ zU~9bR`mA;5fS}DS*stj>%c)rFZ1?R%NQU3XHI@xafc&ioV}vBc=!uMFrz83A)A&&P z=d*`^)Cjrb=Xs&{ZQu)#I{5FaYmEA_Tt4JNygN5u3iv<}z4Y`yu8@4}67j6-aAlmE zaj&s^E6H{p(0%-D@{X+WKZ;-6C44Mj+iRBOzsemy@z*_gk$o*aw#j^O_>bcMec%4J z`;xiKkI>l{(ysBZ=XaB}|0w?7cl|g&6(HICR}cF9*5TqDtG)Bz#Y_ChUH`2rd=7BA zsM33sSlj+zRZH^!RV%yyr&9i(@5=wFl>fyC^xrGxAEfnvzmtCL9X_d>PwlS9YUeK+ zMxBRV|6jB(&C+Ij*&HF?& z>K|j83@~Y7bL1l|0!B-G1EpCOaojv%3w9CI97{b+VwU2_cRk68*<`+Ngtl?U5p)?_ zv0^Y$;Jv^0oek3Cc7INJ4|(>n2LHa}5q-AuYnQT+G3EU_w1&5l4sg|$g`ql{Ha=>E zR)te8q9a5F70w_+yn78i79$-ww383ea_J}_pC=pcRyEJ#+kMoVxB1c#=#QiDITOb@ z4&C|!$6D)XFSz$w=z(K@@ot661IVbuIiOP1RV}TV8Drp>x9A~5BYPl|Ee>^d{YxnX~kIgLTv6BU#aD%!AuTwuv3 z`2w54727)QN4?2%gNRE%TZ5ZG>Wr#>jc{7bUhoN$wTRVNaGoK6ayr2I*1m3FuSR5? z6J_S`Sg7qweYtD#=AOZty_iWd#Wy)AC7+Sq0o&^j+IG0sP(;?o=O`yHQ}CIw_gf*U z^a~%7TzeHtDp~lHC12>iTp4O`2-q{Bs#i^HMbt3XHG|W=!*LK)PrW$mmA^8&u7Z&` z=#5V-*6*B4%v-7vW%COv+flGQ#A&9H!A}=JVyVrEdg`7;DZS-3KG&K*5t2?bB&MS) z@va0t<-}HTuZx*ijCeNx0Ag~kR)HtX-;C6{%3kSTgfcITwpG=`ceyjUi}+n<2jVdj zhgP}CjhMP-%fiAI-v~j^UklOCE>l)=8XL8?2oF+J?$zhK=eQoVLU3g%7>U7QF_{TL z*jKE&MeQwULegl8>~)A>-j6j=oY@mc4?1a^(Rx-%iC}+?B6qRRa4};Ia=o-!3-Amq zmW}7vfn~NDmS>Ju(ySY%a2~;$6te4@TFhmHLy?|ymif)@T=A9Nm>-LHx2GT-RkE2} zM##x~z*@fkyauJ6;|X183uli!*w>hrb;RYZ+?bb3UQ^aO@{#_d{%+C{HfrFgg48?V zIE5&P-ckZ?Wv3Jp8#+dUIs1sCk=pM9bpw*ga=)`8uymy-0^8PxT)rJCN2y1tSF^?m0IBNskC6$UW7Oum256bY1d(u1*S%mEaT@ ztV^m~AeO@CV*jUFA}9w>QhRiwF{wZN5w+9k0LS8Mi`ho}PY1?5qd{{yl7Ih_CBG-V zP!DZOk(K`c(Jrl*2Oo-foxST`)lc=+%9<-OV*m3KqSNfLWA<*z7Vk#bNmA&s)4DP- za=VX(iGT-D5(lQ4fnV9_$2sPmvw3YnMIML=gq#j_7Rz6ap;XVONl{8qI-a_e`bkW+ zn!kiQ$~`qbkNcsf6(%2F(yTxAeU2#m)5Tuiz%cYXQSW*COsSYKmCO5dTef9w2*XSR z>*QALG-{v`-+nDV>O#|UMvSXX(!1fG-~k7~Zy3Q8(nsLRM7?Q>bFSQt4>|Ey7|(KyJINF^Tmv3?8V{!I<)|1Eeu%{$mhByVLv6Gk)FV zyC^sXbRzSr&JDc9dXoeiOg*hlt1#l*zzu4>ypHn4m!^YR{nUG7qh8JMGS9M^t6g;I z+racbI9!Qec=sdl7-9-~qUwkILQXmW*4yrjp_m7gbC0NuGyj|pz23fZ_!4tms?+I_aWw0NRxR#iKPzfg2yOw4_zLEhT)&c zNe14e&7lIL-X0byk)m%h6>iM^yu^i6V08n+W25>~L3gv@`Q8^Qx72gs2Da!`?HmeQ z!M^&GR3$rA+h+*#X^AVa0~X-_m>YmF&jI1r@>(_yePU!1{ll$aghSZL?F_fa9qFjI ziYYHQ>+2AH(QO%_9_Ywvp>fS6@`-+`8A7nEC-%g60O#I*2=Z^`-MC}2}Rn__E2m-*gd!q1tFXBv0=>xyp!we;C$#jG1bj>s>@lrOD0O!l1;uPn!@fw z>3V<}7HN|J+(33|_Bi_J`lY8le5gAmV6U6w;3ro z>2kUV4^7-ldbbQ)u1+3{q7=ZmQ>MxXfdqM5E;`fz$593?@rW#9CALWFsB87v@rwfI;wB6r>q!xQ8&zg+gXDstRpi& zR8MZV|BUAR5WjHpx3ec*n94F|Hy~rwOcK8eK#@?xaV`4>z8vS{`th`D<-XUB(^&M( z<$l=a>tEOYUlCF7BO#G()JA#*C=i1?g2 z`!qWxP`1Nk#5b6gPg=yV+(7PpU~H?^tP*DHoW79?o+$Q$WvIuASOP&z4wIt!JXf5> zB4~#=^2sG~HEPQ|$NDu>f;I{2&9Sy;ahO%Hhlv!5x-DMPak4vA!U@i6 zO(x6LAv}-@x&cFl_e|7Wg(sJrKMPYQAg()q8j8uV_|ljRHD9y9Onp;^mV93kuEN1i zgZ9F}A~n)T_!s}nPnK446Xnbr=oR~8d`5ly;k;DwZ#)k9t=Cb&dPg`u)C@h;bbm*0 zD(zosRW$jis1Ov z@+Z8syISIA3xK2DbbYt)eW>kYMRb3=)qBIOpf&K%YCWftqevD>%cr4MdnYYe>;s@* zofXIf0EyW{b^vbiu83(~a<7+Q{qouj-<3;r-7u5LXRSkuOsg{0!;CP?)h0EWt#EXZ zdihWYmmw4*j4$BNHLkkU{oFRkeq9AR^aaOiJ#_c81%G$tc+zaVqM$ki_)zXN5z-y9 zUE~8O$Mfg39Ie;eo+%{6rLtL)u4Wb5o4sO0#Jpp2<61Tl@fyD>nJ3H-K%pLd?8$N3 zYsGB1jl9P?IOW2?EATv3{SGG4$J&l5II{xq_~+>F(+C$EF*1}dE*PGbli7YM!+!?biVg8|@GWg;&c}ef83n-WcozlP^=UC# zn7f0vgi(v~Zi<0B=Ws?g)r-MzOtc`i$Y#z3wwDn`qnXH?Ml`4@ugrJrk)`OeQZ@zj zHW0euvaPg*AKC0}_o1OQz}TDS_zvVB)eU84$xlLBfHAjd?5&t-5PH|GGds zO;*g)Uuz5kUaNmheA7$RG0{5`zoIB2B@w?SzJV-8&}=Ab7ABSf6!^x!vo#-EuljT= z7#KCA*=Z!(~ny{? zAq#+tYcYv)BW<|yV$)^RtOv;pyZ*1>@~y1n!kh5mj1|8Q6TZ;5&S z$HCY@Zuy!6r)!eCVG3UV%ehnVQ>q&T*0t5|gZ*d`v+cRJDKR@uCj5|rVXAdLryG}E z-nLEciQXtjQ>@UgjU}$U6{-~Ij0sbwv#9!sVJ4eQ5d;5$sXw0-+;chUd>~X?*mE{M z)gl!_d2?ah8kUp%(Pdm>s*+>Au?tP}%K=XPm~CXRkSj-4EhvQ+{&(f`@;(*d0)y1s zienB+leAF0krExNzf_FiXBRc`$b-p?asq)#%H7V5`(lZ7<4iSj2!=#MTvyyVZ~Kr! zrr1poavF&b%p*uRje!651aNpmnn3Xhn*@neY_Tcm}i_9 zo#sLTW?SLmFe!)YAX&qqBGNh6Wz@&EGb1A~@9?aOaUNWl)t1mb>GA@Yx|YJ(nE9*j zXHbRHH!>tC@ChJmp6`z~iAsnOuZVSH70r1m z`^7%o&a8_j#5WK#ugZfMsYItmEOraj} zuJX%OWh!fB-*CAM4D;iGtnwuW#7AW57|q`L&ZKna%j9wVoZ+9|;gGR(sCA zy7LZDWV_q0_a{`T^KzP%9~2+La2d3{yKV^Z)t0O;J$z8}{hH2sC2 z&X{!f$aI~=VojAyu%3jzO$Nl3TUaU!lT?7GQt{cv0&$QUDo=agv=-kd!%Otz8s6Kj zPz=R7D$hOOg=PzOe z)}vI^la_c%M76c!3)J(R!?w=u-JkJ=7B_JFg^3bNB%6sxc8=-SQj0zzF0%HMW9BwC zYOf#3b9wBzby<+9WS&BySX_6u%bQXZ>=->|wkbhhLuka$*7JckHJrPIKY>70x$n291@?wrXg$S;5>L#s)&}>$ zT#@V-(AE4OB=k!z%;0Q6_{tEr` z#RRV;Wg8$+?<+37hr>=`^ufREK+oQmU5`o+T$}BXQ+8mGu3j>(dn#{{F+x*@!_G#f zc7FwTkz}sa&yOYT>(?1t-yL;$taU z*urWz1-uTmC=#Gr1XFl7x=i4AB`aYAv;m^0q+jpMT@!^ zP|zyfF#YAf_Obi`($(3QPE)Xmz|h)9IJZbPO{@bOwV~8_)J(&Tm0QU2J+C;CsHvDt z%p(!+G}ErysM6)yRaBon*vX}J=t@2N*5p+A8>_l&+4$G02<>Fz{o4=xoA~L;sfLTc z*@X~%kt2gM*Q}1U49y7QrfKtQewA-!s5`uSp$!ahYXsSGoeQ$5`&FM){%&kzy}W{v z_FK|iM;!7ZS)yz@Kb-NEwb>>rIH+x6A1M&-tv!zW@eaDvz+;i2eq~= zQPpFf%zb#@-EPbF!kR07zoU|Tgtlkga8sHp$girfZsvbq=(CBF zD&6bZt2NIWY6bBRV>rIal=2?%{0&w3LBcoD6W&p)(T9`dQnJrp74^w@%&2>@8UGSA zgJ`{aq|ZQmkIcZh-V!CWoyF0FZW6cCByx%#6M1Y{<8~YCcG*%~Td`kRSjQ?4^?vsTTJDf8D7_(T zIFo-Gh5zRL2Pp!zji60wn(3g8a%S(Q5u2CLP2*vRH}|+|mdxu-eWX!ihm#?Tb{t*~ z)gAZK*M^j0ikG$7k&!LgaKlT=V=Y-(DOp*x|J;HytvQDIMQS@(_B7Q=fv`FaVZTuq zFvIAH#|tjGRerRIB-|7~EaouVE_ZvUIi^`vrYmwC+A!mBk3(^Yy@d{1_uL7tGtd5@*gCF%I}xLTz(FstnrtMFHzysDQDn>{aI1x%RZ^+)A_<$1#NV$YYYir4E^;=^nUcp|~I-2IJkTmI#!fqCyAHDyM~ zzX7L~@a{Y!TF942xR(3EJ{=f)Ym;9?aX^^#$=0<=0n3LnHqZXea@3l-Jv^GI zTqQ4Em$Q81U0hsVjn2gZyhO%~X*qvl(X^7`9Zmx%Wkm?DNM9r2sGlhl*KEoAm2Ku$ zB6}Tf1fjTc5zK}W_ix2=Bj2twb-)C6=)fl0Safm}f}hhi?4zJ-J$28yK|jq3uV{Dwa;8#XDtpPBA@1)DS10PI*Jxpr z4-{KokP8(~^%zA6al~w9n zjAeY66NVAgsRqYGwyRTC@lhoHDHqUz?(spZJ4D&RRh4h2HZ1mw2bW%%YesJY+^zCt#dJc?J1( zV_9e8)C6M$^DFj(Ky9x!J1Mc00f~ebi%LH4IAOYJUDTOu84E9&fM9y$Q6yRebY3nk zO1d!_9IQwwz^enP=s&#W6A$hZN_io?!|l?;jJnEDsa0)Vg)C8ESQvN8{sz6z zJnN=N!PU^grrD~jd!^aqLB81#sKuY+zUH-?Cg6OSZ`}nXr#M7H`|Iq}_fQBBubFO! zhQB7|FW@QKevQnHo2tjX3qLDR+-Y`9Ya|(+`zWq)0=ZivxN}6SY---z zt|IEygqC;mm&gfOmKySJ!5C?Km3ZH?#F@ag2ucveb=1UpboY89omrCeB$M~^5}Pb| z;}ylMCQvlTy$s>XC4BFVFD0v)>5%1O)erbO!&>PrHx;pyreBAq7|NVm0#*7KR;FxCZ~GWw`68ac|;6) z`NTdaZd{n)nGb@zby~Fx0d&E*glTLL+tjvXv}7j3(01i~qXZ-Vv)cE`YGYjU{7a5Y z>X6Mn;W0CWysw@EUi*0qV@iV2Yi2hSlad5Q9+75_CcBA-X4@=K>rYe|Pq&NH2M?%A z(+9zNtJC7Q6Zi9Z_`?R&bJ#NmfZ;&y5iTJU!Ea(t!q#NfH6E)o7k59+&P9ydRYWm1 z1*HZ!cXJsRtuii_WF!|cQ`Yb2OIet!lkQpIFm6%UfbXfJ2GQNZTyDba3n4>&rvT$@2Y`H`MBu z%In4xe%PT9Oe@1^<(*YTwkBis2($jk&&I}$9A$c-2no6}ZYi1rANf`#p7&N;4x#c1 z-=26k&xG>DyneQAlzQ>S%DnAslk)1d;+;5pvRoln6p>Gq)~#1Z_i>Z4P;bX7ZfWt!u==_%QKuY&N{4npoYa z(o0B)3MJ8}2^VAU@S#!+gV2RO=OQsOiu=yVBhdZJXAVs*Qk(>^tD?_KMI>n>?PR>) zfp$#z=A+=0Vd};JizsHSys@u3j5GiRhL$v5tP@Wv1WoypEO0W_pZYEU zG#cDc|Bq!wVP5A3l+KXY68c&}PGbG$qzO+KBYk0xRvXFz33%xVyBY3K=TC|ucmF<@ z#^d*$+d4Ma=*8O^T~Exf!rQFc9bVW{a}JGJkl5t(i%|{3<1qJ&k*x;KBl&a94SG}a z8rQ-dA)(y=zFg}6KEwGYmouw(_X6Cx!hYUB=l3j({y+sD`PRo1a5fvzqPLle@cjar zCleE!YZ4m>)xlP^IRvoqUUQ1jWep@}{5$}P>H0;`=&a^lmr*K)QeSHSVwc$*KiXbw zY#LLM-(-o{zAon2-q=6WBF-#vKCY84N35S@*u@HQ&GIJfw28kU4-^@0*wYM5@_&bp zx$`&W`qIk?pk2bhH1!qG8CYla_|h~%MH*rcbK*xcrHomTEOboP9Vdf*YL>*khW9Cj z+OERI>gI|jy0bLn{7WU%%S+ngeywHVnKLTJ(?2T0%;a`I#(c{2Pynh>J9Gcc{d%-) zGF7BFvyU3$$rlV5#$mJh)!%63zwwrsWOy}L6zKC%VhmjKuc5#i(&ezhzQuh>$j9I7 zT{tH`dss?QI3JLy z<*E-aOsCiXX4f1B=7JHN6*A|yZqeC0@%(Ki!Tr{K9f(Xt0%PP;lNc*%pLktUt%~l_ z=CRjQ!4_bjMk!Pd=)p6)<;8Si^&X{%Aw8Y5iQ<@Z^G3|Dd%T&c>+q1e-$x@1EOy>Z zF|wrYDzG6SWoH_yGz@o#n(?8tWXQG@TC`1}m3h0H3~ZZ?qC9Z4B_11Z{5;aDGMFtF z9%oGQ+{NJx?Tj(5&HZ7hO1_bFEU8M{u{M-HC`oKtOG9EK=oC~Ch|15P-Ij@!GN^wz zZ_!SF|2-_GmZ*F{kM|8TY?jK|?|3~)q%T_AJ}&IiU-ML_jb4eWy_pMxMtQDCprP*1 zR4VDonD&sm=&*` z1@4z}f)G})O_ndt^vWk=riBJvvtiTljq1gm>$yi2Xhu!TTA!jBn=(-uq;H>Py@eU zqn5}w?uF{lN)5|VPSg4O+xi5z+SAUR)JJT$kYb(cO;`Q(kc^?J>gs)p3j=Z& z5!_UH|B4()#;=FFkn(OCY4cic=U$=@`13v@&&d{!;g|I#PZPD0x&<}(`vO$x?wvk- z9v0V}yD@XCYAyPo*TFszok={mrVl`AB=JVa?k9TiXezqxvuKxb`9N`LK@X-<@orQ;ryk3b!2*LWcYI1e_ z3i!od(n>y0KXT&vlq|OXg^3((q0Oz~lNg{fw^%mfj zHzjBBWU@0(i4LpP*V>qQB8qNrwSyU{H3T0f%-xEQGeO$;d}z~ya6`p-Il}Q6`<2+x z^{oIOw95sVK}lbH;Ad`o{mlp2gYojVR`OdfnA6dlc3S*!*H4Ae-4}D*k&UKpqdwX} zLts#snb`3$1y*9l2I9{C`Pz_SXfp-cOlQT=F3rgxh<6?1T-VYjuIy0!wZM4FlSJ;w z)@W&F^ofEYi-UP;ve{?N6I7x(J!-T#Q(+OyMT8c*U%ez?I6Xm@t-dJ+EMq0igMU?6tzaD%V*vznB#3p@3J!=?scp}y8`5Y&&!)9 z)p>5G@v!p%TAn8wH>8hj3|D}4HX^N+Y<#3qG0RAYi}CnS>4u;2=+!s_7tThndpONl za`OSv55~hDkxw$2`3=X8?UlQNgB;eFFvH2XFD-Re)c!7nhUkdIBu zpqbS_NUwEXU`=SPh&?9L1CgD^Q)0j5#jJR!zi9KFwll~oTujpKD-+;+T{oOWrhf0| zka8939PC&(+YN%I4(6X!FXf^5jrEZUJb(H9F{^cG@d{GrcK*fjeu~M%ar7S~5|rc+ z&=`|_y@~JH+iKEEoHI^P#up?v6V=B?N;|Tevwx5lu)7+o{r|p|;=G9*fYw`jr*f$@ zit${9+z#Hq6a2vQaJ(kP6&1*zHJ#Wp!FT#f(yv7lz;-1V0Fi9sN|gRhyk$4S=YanR zQar-4UbWeD<2k@7N*Kj7m^G1K?vgpZXld^fGdz&Qh2=8j?^8#GR2ILSGInm1JIwxq z%)BlddE0U5w$q}?_al-p!@2k{72$#T%+=rrrm-*%5!8K{2Z|=gYdaS&|Fkf~U(NF_luA*vL~gaM_-b#A zbCqb;6mCr*$1AVC*-~pMz-P=2sJa^R$@~XNpmCZ#QG>V{AN|^R9WRW`<8}M_oY)D* z2>~629*1+!N!Q7j5lV=Ey3UD(1Q+ybXtA@^qKN+X?fZB}7xvMa9a}@%$(Gjp=R)Ss3b*jd2-|BHL{`{4xm+g2!aoV5 zQv9*R^{T~v+)C9Y`P9LKgvH=Lp~4(r_m*a7V3VPa#1+S`zilElDKdtj)R#c5vZ!b5 zJ@zrNQ_`~wfB1fl)N5$%dfW6!N@DTpTszGN+|O)qBM=GIsNzm*{x5S=tr0vl^59x4 zk*&O-@4|_lJARsBLwWwAEspc{jY&p7oo& zdAv+xi~IR5?e?QfO)T2kCtk2Z!WN6BJjx*rQyi zgjx^cUL_EfEs(NUS6DW(N5&QeHQAUK#OLy9z5o{3s;4FV5gS_ghIY(i)_&2d-n>=I z8>3qBX{JiUc+wzn*f=RgH_iKZ=^(l3@%B5y`;cGLw>Q{ne@PA+=kVv+#Xk#so+4MR zEpG1eP?iln|J_R&`s?vu6_$jIA9uwj^y5EMmelx* zHA~!eemUNcjqTTXrZ_ymc2-jgUG#M6z6DCab+VvmA8T5ZDx+-DPIW(404y@Fkfk<- ze@>b5VPhFKVsbw>!P15^=9*(#CE(hvcdX(#N}zJ9KQ9BT=A}k`P_b8a8%Tq592a)! zU*wdZHvx?oOhT{-aUZHPy_5e$4?vM-=2Mza!W}CYe@_AC)8b~+We--Zx>YPd5JX9@j*#T_l~LrvMz(JPQJ2j8GJNb z@j@~21Ty`>212tIT^CZ9-oN)_>u7f}(vI#P;IVU+l_VBw4KS~7r-6tXGxrZZ_wH6d z2nWy$tRjJMv$AfJRjQutg{qVOTAS(KqrFUJ2o7)Ylq~reY4O-R@=0SzR;N$1tqFpp zvJ8WOd@_9{>jAJ%7kx86$l8Ae%JBXoIxV66%i^5^_0T0&EP#N?MDnk0%m`h-4s-G> zvh|nGf%W)5PHjMBF)3jf5*P8)9&mgAMVmH)IOWNug#!2&Kv1tVkWExmFAbAnRMs4Z zEjlq-kvCnYD&r_cTVyRgsDY*>Q%#|ayeF-|*3X~BuPc)9-S%rha0@>AcJ?{LRxbED zE#hHvC3;8{7?&?@J3V>UX96IoToaU&s#p<8wba89$986@C=W^cL0BF%9IWwErsnIW z>>xmt-;{b*HxLu9!LM0J9g{9?iaiv#Rlzq%siM2|995t$ulpw-H@qSg>95qe4kKLi zyPBlJ9a>p?9eJ{Z+JN}c+b*A>MaX4U&EM(oX1M85^((8>k7SeOjXZE#mF>>&yWrD# ziC>MRIi&P|)++si?78&*J1y|@|1IzQ|7_9xpOVyLW-k4M^pGC+VjNrTd^>kJ&SiUp z`5pfuH9p{9J7!0>xTd>vXu%mVv!L>9er#H30rf50*+|d$n9D~;20i1EfpemJXD*g4F)%fCUfjQ|6bDVwc*+30 zD-qkIK>V-j&20VR#CefQvXf}}k?TZ@!GJ!UUMX!PESBKviBeP!NYFt3K%h9b89#$? zHgQmj^%Mi^1Q#B6#A&!@{zi+e@M6e9qf={6SlA}*j;<>qwd_vYvEZjJPCV2gP>ZLZ ztv+J4`{S-&fD(XU!Wr`=C68(``GS46N~i{@A2UWn>_<`Mg}PqwTyu%q%>GGJpLY5t zI>F+iVD>^dc#B90ot%PrmybEL5R?UBd*=Fa{-maei@jex8S$r7d@fNH`y< zIvp<{R@&+s>)_BdJRcR=b9M#f!c%H|)Ip?RFB0Wz+ts;?VpXhfzd*}eBZgBW!`bL7 zVFB(rZbW z2b|@&IP<%VY()Z;@={-p7Xl)=7zJF@1?5)|R5HI=Bs~wp)CczyyPk6>q9>L5nK!kh0MTr< z&58ZU1dz#9J{sz#E0B0!t}dILj|J7Lu;HRZO5yv!O(Edww@1!zV%oV=6|&$1bq5*x z0@J6r->$cNIohJK)(d3H@)yvNG&>#52_1Kp)LnPdMATFwD3lc{pwwvN552p!3D4{m zEW^v~kyFa>`B3OM-ZOD`c8zRKfe!p~5;^c}K6;)!>J0xygn(Tlcb| zqcC+?yOnlR@qrr^RHNPnXCj=i2dbC1EVGnX`W5PrT|%0>UNO8pJ%&>o=O;N>ULn58$^(I5VF8CC1nSbTa+ za^2G5WE9VoedvMvNV8Vq7i0%h|*H@^VVHBc@J(wfy7U=#ivi5c~Cgf3FE@V%zYeEHP+ z!r@KDc?G9;t%tm()nf9%>AIPFj3T2&(ouDUNdTTt=|XA)>US`yhU zDVC^DGcjASEyXN)E6er(^SCV7`+f(Qo*AHt6b83d_u3b1v<7OOz*n7&W{5U)Gyu4) zS*giFMSq4%JRGGXL5~mZN@r!<-oLzOgG>}ws5*z<9z0`@_EZ-8nm!l#lYqZoPbUJ= zsu;Pc3SI_O+M=3Y$z&hJ)vqN;Oz@58m2*ahE=h9Iw3mhQ z{wP0k0=-r6{4ISrz24it6QTLCt0e{2Ady!Hp8>ib1Dfl z*@{p*Q+q5M9#`=IqqIR@U|aFSw+wj@)K`4cWGI z6Lv369%WIv&+v|mODMDn934;o!498UME#V3G_1Q7Pw{>DJJZX|BsvewKD&BODv39;I=y)m4^h9iCc?&& zR_*^fsMETC)cLIQ;d-w-iL=>W=$~lKiN#5T2`1O zm;o+fuVt}PZ=sEt1?d;9L&GQVV*h*pNbO~l5gV=k8|Bu~$|Ez(f~-?-B|Uq>Pg^{nGW?0W$uGL==xJdUgG{T^RRLfQvX_X-Or0)c7>1qokF(&t3(q-7npAr_>Q%~%4 z6gV$KEE;R85I^c}8*bTJ7E=ctoOiQaB!dWFCUw}VT|&%&QKy4cLw+bhJhv%k?Qy_P zJ8@g*?!GCv90&$R9IDcJVoGMD7n4r}&X)vCCMBX>6j2>l(>3YlaXI>gm-)*8C7OTnZ3{G~+39HZ-uI!hv)jZeu8=H}+JU9(yC~VC zJ|zObHceX273$VsOt7V3ZR2p1XY;*cn`>RHNeLu1%m2Mm0qZes&LtC%?g!c*=D6Hx zl=6c(()s)#8%;^zmB&Y_r z>&8BbR3P`Dw5=H0`Iv4_!5g{WTgjf{DgPPB&N(k6w<9|Lc}cOkg0 z_kcUMN~hx&o|7`tgu{&Ne1}Bh@GF{>&GAbcwo5yOQCKO#9mA6hvNd0SNd3#SDX%ft zM8bw3lVO|jv{}bR&zPF656oJw_^p1m-O!6IlZ=X-Hgjq8T0ih(EoxG|`EFq;CO^_3 z(819_Z_XE4LZBrgS7a6Hag;)Bgj2Zb&|GT#^_=uH?hVc zN%q$ULdBbka^P+dA+gqfWi*g_7IpcA)!zbJIsTlGBUXYZ=ihSnk}%QP>1AdKnwNcX zl{psfa|Njyqe|SBQI+50deIeh6?aOvUD5|Nx684~2c-{2m9%KA>CH)kt1`qTW;4T7 z&_9Pz*WDBi2dH(Bz3E_C%+eM7IYmv zH1QG)&{nXF1p<>PA{Kn1-5wXs1|eB`Igs5Xn7Vx(%$H)0 z-oenWDoJQ8zPP>cfj@+usY#J(AGXm znZh4-7{AxS8fl7Oy{7Vi^4jEV#eUF;fog`BY7j|exOh9F~}3rJOfR&2h3&d}P$CuYHT zrjZ(#Os|QC!~(TZ#`^T+QMXF#hB_P<3?2qexLt*jOm$hO)(KKP>l8dTiK~^LM)yk0 z8N$%AsEQuwYw)ARt0263>Oy7M7$Lze0=sXRIRMzM@JtIk9qaiCv}e|&L=N$m@Qgw- zT~upBtaWlZ_~PGNl^-KBlvx{XT$SnK+xTCqMmn$A%aii98jx8VV1CWhL;l*3n9+1N zYeqrxMHNEwRaa?F=Y`YO)~1j9Slx6`D;dLqC(J2pR$-aA)dm?9=hylrWce~1;iPoQ9!!$=p1{Npt$U5Oe2U7!#<@&KdN zLQ%7YaDGorJ+_o?HXz=RLm%apbY(g6xUNWk#j9hWy#l{{790r14cty@nlz(yBXJKB zi(=T%L8EDHAU9n%IbZ$VsiJFd;s5na;B2Mpci}%sJqkX`PtpL6W`h+&dWwBLU8~G} z;D1TBKuC!BuD62eFgpi-nT%`AZ!92QC80wrb`U$=2r(Uht<&Kn*mpfD>KE zjo^$WbHsZg`JQI?`uu;?n*)N9Qes+WdNk&mDYZprT<#$on!l!qY>Iigd+EK{yFztx z(d4w0V=gBO^Iyfm$DyH1v!%Bw*}D`ol|hFlW~5~r(~D9WV*zd|JMBD+5((^ZOMLU=xZNDAUjv;~SoKp%Vw44nyp)#=XU zH_jUm*YBHG72jYo?FrWIw5^U!I=Yl^w``!oJ>DApcqT0%S5MkgFMI+e+a(-pHk(?= zx3`Wsx_E`K4`Nwmi|T@%V_rbBxkAF6*kIUcmXLtlR9;$UZMdO|{e+2p*6 zfqMZGRRyjVVKiSGsr3V!cE}{Dd#vXR-%q{!8}3j)FdTdsI_wQ?R6uQW>!$AC(Z_`F zXn+rhDA9M_?W!=K!@l9jm^si!U|xyRN#tv^-`g{}(AwkOn&=YU*3$k!blw(*q|=Qn zIUM)uH_~Goh8L!*d!JjxLI5MS6dyjzo=n?%VS#uvlBlfErFs4vX=fP~Rol0HLIFWS z=|&Nhlx~!e?g0iETDlovNC5%qlJ4#pdWazu5Re#h7?AE5x)Fuzo$Fca`E);@-uu&D zd#`f)w7Q=M!iaZhNu9&DajT7%g}QrwtB<*x!gYt+g7V4bz1;BK6m1ROK5sn(72L()pOIXwq6s#yoEGjPT_dZd>Jeiu7oAI_PVu&KrYAUXb-DlR8QgawSBC|jSeRImb{;@GkvfKCt(F%Tn?u$ z8x8G$X6IQxv2YCf8Zqv4cl?&;g(cNFh48RkQw~8DQi)%v%T%t-U4=I5#yX+(s)$ii z&t*1~cikN&{7d`FuT_bfjHvVUpM>hE?C3w46MFu@X5qKfB$mlVKCa-%NgPLVZPjS0r=6Q_+dMkgatuo*hUmS{7GH-Z zTX-7sI$dha_zlUx=M}NI1PA#6CL}J!BxY%!G^U2n;0nJa{ezU*%*)9%w=r(GZ*A0d z+gy)e>;U@_nt7lwn$aWxB`(^#DPfhWQy0LIX4}2B?dB1@FYbR~w7JQ2h0~l+FTMXW zv#W8{BD;la#%(0*K=jDM?Q>k0V=?Ja+{As1!gQ<4 zgwQ%VfpZ-Q6`iU9q}d)LEh9;kSJae81b_}<16GesSZ?y4pj}W#DwbvJqrkz7sx$|KV)pwQ?G4TKO zrX2n&3T>;HOdY0yyqJ77N(+CHyTBU$BSS9c0Q&NcX+D&8s9Wmz==E9Y4Lj-U*yILJEh8Fd%C%)Q;NtV zPP(?UQz4}zO5d`CXesLV}^dnY0UN1NvIW z_Li7sN4$3Hqq(@-CE@2KRo1dL^f?v(Qm0MEV;fZ}%QP91N41&Zd6Fa6V)BCtxWd)6 z(JD;*GQl&NiO)A7AA+YDbW zm@D$pER*X)<=$ukE{TIc;XfhJtsrJytzk zvpn7LFc5*2Nd5^~Dm0oE6urTprWm?h9&wp$b|`bw%!y)y62Af)HWDc=PxHKFlA812 z(od&kK^%<*H5HJt_!(rpzMe6?X%ZSF(hd@CysPmf=^N}NoG?@?Xe+hfY0@9eW5WIz6j_g)8HU@DbpSp0w zpMAsMIMW5qxAV7D!(%}#cwj^6(UKp?_pSO7)UK~N^D|P9=;JP3vNY;ee3WmjP4+Uk z8k?p(yCtY>t`_bBpk>c@-@h^ytZ0|-979DnwZ zQgkRuT@srWO<Hap8On zw4a7nkF?|(uB{`x5GU)DHvSgh7c_~nND8|UH|vyQ)}3CT+OKGSWs0ZSfc&|5$6o5I zr6tH(dD*@0Hhdd0MV*;bE#)SXAj9-&t`WQ@goAUQ!+Q;zWi@@^n#F!~rYq8*eUlsxb6EJ%0QIpCXDj6BD$-2Rry-` z%XXdWqbgI`)an#uN)~5@xDi=l5~2T(>K~BeJq93MzLlSfQ6!+(c0Ri_ zSkrJMFqeHn$=6x2jC`4+Ml_tfURswY?bZSE+5-m2+HfW~Ooj+F>C~8wH1cFa2*SEv zvmLydu@S**EEKZGe>}9nu1g^waiY?NZ(<9#${jgSsZb(fp>wnJ^fim+_?1VzB9pGJ&EBFn&A5hNhTa(fxwE~GI4@f-(GFdcdwEng!@us1 zq0T!!FSCeg6}90Aw245jYfk(pxpfp$bpHE|8}?%>Q3LMQ8X%0*ndkZBoceX`ji%6E zG6%eZ7=`X|!Khe0W>hXKBmA(J#CI}>tx8=1U3HVpo*Km|E!?lNB)A{nQySmkManpY z3UFw^T#xnvdwCkrP$o}2iL`@7eTdq|f^|$Bc14y!i?)8MflDbu8N zvPK2zBwTjlgi9n28QDKGx#$^vb_8_L$2KamEd7EIR{22j453=}#(`v`Q8JM-C40~x zRfv(y@{f*wWId^H%6#Ep;a6v7{%qu+a^z_Gd~?>S+yi)IxNqMS6~3GqMMR!%7}r-t zTR7cZzu|L?=VPA9^=p2q6~=-8?u8$HjiphC-=XdEDoMLMlAAFwoBx7ux;6!k4`oSSyRFC zc%!p+G)tjL2uBU_Z;%Ro(rKM?!uN=1S&_FdW=polYc9)-BlRlOGcuRln96?VPyU8{ zM$T|u3KMpsfc3iyk$+yOF*L&iUt3tO%~tF#-=pf4yN1Gs+$_?x{@w&bYGx|`>vJLL zR=2Ct+uVU8`ZI%MKJ|{I6_0t96bC5ymvl)L0+Vk#za0e@;}aVMmoUB;ZWThyecq~} zt2MBGh9CuLnoQYP>s1nJmdSjM36E&&Z52<;b3$FvFX+cvpEzIU$S!n_O*-wHFcvWT z!+abvxdvwMC$uz!(!H;$2y4Z;hz%H9zA6bDq5*{|!y=D$O({3^pCJpY;^*}R>JbJp zja;%}VGtb;4*(ukTIB)W=$O)U;gvmKy3w?P`8K@j# z^GLIUMbpXbd?ye3@-9LU2d|3#hq;+y>n5SK9tD}Kc!H%QA^|6__9xK!7}HLw1)Y$biQHqStXRwNvRQl4;adcQ zc-rb{==OV>LQaV+t1(Hh3@oAFFs%I=i%( z)MjT~sQJW05}d6+$Zc%;2<6i&rZUcHUTB(lnDUPpFEG(dVp@&3mywM=_zW4Wb}o6U z%M;*7`k@j<-gq?=$Zu6Mlo9^b2E_|4xqZqcWR_O&cB)H8?Uu~72HkI;n9{?l{w8bX z`aaI$s&&&T=KxsIzY@Y`Gm}I?p;MLjBZqrtpC&cCP%AamZRwwd0U=c0xcaPYg#AME z#1!_W=l}kV#7=jUsRSxLr4z+O0heRgo0$oH8yj;b82R96*7NdiNb8IjpA>Y$2ReTmvZcL z#^<}=h)aJjduCVj4U#5k6?uh5ZNWyG`@}b&mg8yq=^jIP*+zq5ShM1~UmTnIqG%(T zrdu5VHX{9xP5?(A$1_fWs2=!y{IEv3Otlz#A4rKVF4g74Ko6N7zj zK;5eAhk^WBM3qw)L-W*N8!%?zQRx3O#rU6PzgNRm9=;q=ql4q#4!6Lhwu72ZtCcQU z?K_VDeUd7;Nn5w7C}9q71+mFa(HBd;YiKr|)e)CV=@nzHveB8R^aKbH5_}O#DMnRG zMPzLNhqoH^M{)vGKa5D`Nc~%u?e)O~Owl1&JoL0zb+dwOzVL7GZbPjZ+UytRp*41Y z)4t#sP;O+-0hjwqxaB;crs_o$hjg8RT7vZoJ5zyO}OyJLL({M+tFT zJCiy4jn>^=EgOLb`1$Zw2kOML{m;0K8|jRX#hUSwUK=ljIwBP7a;W;PyaSThWg2NE{ z09xNPt3NMH+fJ||eio=Z^BET}J85Zg~;7mqDNOa@nHm-%gsk+qBH-3P+9 z((v6T_|MVU&;!EnxD}|zReU;;MJPKbUnU(F(P&s%yzU=a<3U&7U+qDYDs9TyWAFAs z?YN!W>cj%3&xqs)T?_AbPD&|aW1Gv$&FiQ<(%aY<_gcC>p6+83M?z!J;XhdYq~(oe z8_UlIw5l8k=bD19orB={$v5ZTfkM+@m+!fg;P7%sbH+D-J9|zurzt=IN`t}J6IJpC z6mYXD{2^$%D)7w9Rl5Mi`7_tpb?T$E6K+?4RHaW^RP54F*G-zWu(4ng!mrkxD?z;O zzP4{7d^AN z7VYaP6!Z(Hbt%b(V|~d=&yt^#)7_4@F}FRaZsH6IW}`N*zYPoDYpM(K8rbJ^Ns0te zzf>5=Lce_(sP=fE``q-rG28gHy<*I44YFA57%l}n{oXR zqdL|50%K=Ty%ZG8-7yeT@ygqqydY{;x9(z8uN~Px-nY85(leacbRt~?Gg>vY-!#ZeX0T;({}y_#N|CfDmozxVqTVlKEfj2ZisQ&HMp z8x@@JI&eSF_wlR~F8YRp;B4{*cmox+O>(mYBEh)fz%9%9s@9Ga#vEnmvHu>>i0O&c zOyqiElF{EWfg?SvE)}v`d(fN5i7KXS_3w15Hh>qW6hnuVXR7Z7wcbt<+4t3d?5yP@ za+K#+DfsY)f+OVA`R;{X)K=1fsIGb-QIJ|dDxr)$zQ+juqlEEUQ4M}q68R2eFRmZC zsUeSQ;0|#xE2vJYL&p^Z-Bgv)$OX+TLN!C5gZyc^6%Q%HY@Y{Qv3KaBl6=Mim+__s zM0+8Q;umeFza@7A5LwdgzKhR9EJekjOGt&hQ)S0gdAmGKgB9SCo#|H&b7kLD77>}L z9krwWyn#w&zn*tUN*ZlX6kE9yuV>JL3^B%oZk)ouBE(wUhd)~0wTKJ~>xz|rmsDMV z4eU!t4&rTA@Jy=as8dB1&zPA#xV(B?6Jt5nYNw{ePVnft%A9`vlxudP%un}o^>FX- zvG1HMzhW%=151-vSX9w1vSudbb$NDQz7r=~K*~fL2kCZFep1#)MK{%w{^ZKHZ(8Zg z^JfvLBF>2SoPD(f8I%k_kZ)tt?UZ&vu{yrv4tkih>IgS-_6I;padw7s#d%_C@s87| zu_uq2StCH)OAxPvIM)+VPhT_*HW4a6*91+`Ns%H=IAA|aauGiM+kbX z@bHKJ!SLU7ig~>5{PvWde#M6&onwR9GR_q?9OC( z>w1G#77wgJo&-?CZUCQs<+Zc#6U&tZ%QwrMVUN ziqsr{a5_x+If2w#qSMCq9gsil>0F&6tO_2#wE=k_QZm?;jz8VzJSo%2xW1=x@?4Wh zFE4h0g9L}ISWTLZmZ)AojxW!Yne{t#`1VP#O@Hs_obdM{5bpf`X69C>mm3;ZRNLyGxQK{fF`ycYG4VL|SSppmR%-=wf8DhejV*2T;%tXaXB34K@j8n2 z-L@*;#<#FBe&kt5gaL%^!}2W4b*Rclx9;@zpiPF$vQNf?nHu_R8$8rg{>SKK{qUKk zu#uZRr-^}u6%A2!S43EPSLjUt+1T4>wGM_GB5jmPKPt4zm)g|@ntn+t6<_hEs|C!d zP^T?)*H(nBtY2SWIiq`^KTAC3kmIo)=TZ1PzV#|{=#`Dt!8ZnFz*Pax#fTe06sG(_I4_$ofb@%0(K~5$Y0Did_3n>% zzwSWyci+nA&+%_(jpz=%+juQe= zQSF`op z90Z1YZwYEoWq=y6Fg2TL8C#F58oXWr9X3F4P9eRe_GQBuXKEU^zEv>bX8`Io7?j}6 z_r9T4!6wK`IC??uC=8LEfUuH|WsT@cXGOx52*Z-J%RV>)my%G0B%HliA=L!pg%kSr zhX5>0D6eX1_?W+%P*JDX0oBjri1b7QNWh36DcP&I*)o^xm)TZM@7V_TM)Z62T-`|vsa&U7{ zTX5LvV|$n@?GzxiKkF5D{`%|+KOk4@WfeI57FK3}bocz>`eUo@&Ziw-^=q}Sn#B2T zu7qg(@F3`Ku<<+CKGrZ8{jh5yC42%hbk&nTO3RyeKJiJhEH=PkbWFW3J&eE|UuU6p-XmEMG>aB*OFtrsXvb7L zL_Z0$EWL|0V-nq>Wde+X#`ElOPWRDXJYO+#zsLFdRW!`bL&qn>%b{Z2kRuL*gs zRgc7ABNsVx1fhQQ8npG|Eg$JKgcpl~btmSAE)AHLh##(6TlQ?UuhFe@tzGx;@jj3I zxWx)j)9Kf9sdCcR8JOSrv@_`ROWQqwP8OeSqkdnkMbB2t*3$cwK?UXz(H=79!DY|| zK1=DKt6cL0W;w?p6^+6pQfVm}X1{+4SD<8-1{#jCVZGr|*@$J<|KZwLHZ)0{4#O|B zj(VlKx0z9dIHMzZe9T(L`gyBm{zZcaD4)v5s6^NmrVZ_912%z@d1>o&snHWSv%~We zf@e;%ZgoMh--^*UsGtV(%D;GeB=e4;pBCX^$Z1$CVm6Q}tSwXJw}Q2y%hMS!GlwnU zxB7nwp}Um6>>}G~*vS?WDwLjeQXG(d1hKv~uL^+dT<_wx54!*H&-7dvQygiicQvti zF6?}o+nG@_WtYJC$z!zTA1wH{g|42qr_Fmd3DPJ3V0G`_BzP|#u8_)Gzb$Z!T%4+M z`p}cI-wgSlV5d9Bm55n^@!W7fK_A`M1k=D5;(Q*#`xl!ZUIWSm7GREZ4kSA?;`!Z_ zXG=uS;HOSD;ghXzzm<=?K(>7joyqqkx`d0bu~K*l}i;oXY*?JZV?C=2_ao|_qVTFB`X1`^}5KioLccuUcNb7 zZF{(?T-7C^y@Ev?rI>bIV>ShP+=ZGmvACgsYiPMB8R+PM2M=G3zSOXOmgP0Z1e-by z-8DS~j`uX@nuA~+o+0CEg3=weiwee$B8fQgMq3>2>>ZNS**XUFSJ`EYqYdETv_*T` z!?5!`w7VvL7N$x9RqrTl5N`18yIe;O5zTB{H*@`iwdj9zd|@{;DvsRb$)NoQYtH!O zuyx59^~|BsH!{{xyY!D^z$IF^$B-p%6ec)m@ZRw)FR!h`c3)l^e@bHrPm{wk61wD7w5pFmuyD z^KXWuw^wXF-AiKhye{4EDrUAv#ixg0gT8k+XAgI79~Y^=m|09Twl=rH0*on~nhG*B z`sF3kcK))=)jQcW&kNr>-UvBKo(ySQuGXPsJ_}DI?=OE0Fp4tDq5t$`K5$zW{%2^; zO-U;!hZY)-8Sh{05+tm#^m5#!u?pLttqr32YoYbzg;|837d-RRr|q0?rs#w5ovYQq z`x3WSv-`WJd`;*;;f`-~M?I^XZfq?#h6*brw4rNa@%b-YcX}3TxYb0JC7ugT1wN0D zuj6+JH~;AETm?~ytL?k~>d^IB)3l3llflWcZohS5(eAJ6-dAQ%u!%&9_*Xo;MsI%O zG2p@pafMZ6({Y;J@v{Ev@?L~d$Vwm)Aw1W*$VZ0s^%_m+sqf%NS5(@UFSy;Dk>5f^%SwLVya={f}+BCDKgL z>p=S&qdI0Y@s7tpqTZb>7y)~lItt&I%oMU6vMON@$sQQDfb&Wp$34Uldi4^IoPC}8 zg`{?4g#X~-q5J!?w{7n6dU;NDjD_fXPOXw||8ulmB2Yt91U$z94er8t{~n)h&h+!9 zb#|4l+%BKo*Pa~J+f7_oP;?ERx#ZgSyK+N`FZ=~PL>=|KqF;2;;WNRm$g9lM2ztS4 zOWygyEp>$pNIGLD2bmL*RP=^#+JV7aBV^y0gs;=(L`AUZD*9*-?l)SXEB#P&b+i!> z_~?Tfb^Cv?t(c7a8vns+5S!qQ`!|xR57GI3X5R3LtKbhdhNG$XzKeRZdAG+mZ8`|K zAB4_4Pi0ii|D;DU8*^nvmXupGtXP;_;=sw8ojHtGMv2vj>fq~L0RH@$drt&vbs?uq z1D|ito?g*QygRR$@6>RPyH|^C&ibVrDum>{cnt}%13pyWYo^|lS$uA)Zbsy$ZL;;v zsXTugPtg}KEUo$v)?fBH)j`z`t|V;j+;i>eia6`W_iRZ6AA>#x5|#6c^L+y}bk=g$ ziTC|b#e`2ev{Tv%FwZK(akWyvb6M>G?b5B*ZCPZl9!~8t=__(V8QJ2ba^+VXxI*}X zQhKK{#2^~jR9iXjYrk{st+wG2YNm&gjqd)XX(GJj<1%ncAVORZG?KPc(=R)gER68k zGXv?Aqxg@A>99I_wwGw~#;;fj+wVzB;oCJ=LI>JiC8pb{`3!rRCS96k80W$Ml?6M* zM3swWt1$FfLh1OpmzJ^v;-GopQ(Ev^nJaZO-cd2HoI|ZBW(d4CL@w=A5Vb;|LDkG@ zmBBRGnin>^!gqZ7_Om{ zX(OiT=g;x8M*75sK1Oyt#=ED&CMg<<+B5VZel}lG;%qy$lruEHp3%v_;5Xdrmj8S^qLnAgw9Pxyrdcd0 zOBxXJnGxqJ{Ri=}i4;!@kfH@B z{=rgp@w_O-co{Q?Ag|qa{LM~2ppM%LgjruyUqm|W?RIJwNz2ME0PWu(1(Cs_pPt@l z{QHu!Y}hl-FE*8FyLm0V1?=M;TmGWKj}5G5pF|ifF)g@05dQ568e7$$x$#+DprSrQ zxZnTkWT%f@a`V_*{!1mgk+I#xhdvccr=0c@^cY26E@yxdAH7K9+IMcA`SM!+ z?PkOHIL4Gd!eB$$f*8f6xy)wD9s5e;E?z>1wo@;T9tatMJ)u{5g$x+A-~KRK^asU0 z-3vcUvj*A~93>rul7?Q`&1N@NMSl$feWxfFqSLK5;x)^9+D1OFCs8w=K}!BzQ{@!x z>EEm0t?F-k^_Fe=y}YOHB&B>bYNHNhT|iPVS}z=_EvpaDqfUG)o&u`UxDZEGR`k7N zoxePqdquh6@#rmmm+ZSg07-z!)0nh?nRRZo^w&Cs_3Jp%5a)V2wI1U?$l*lkd-Nx& z9=7WM_9Z@B28!F6mp(ZwUCwZ+-J9xTr)`MU z3E*Dr}~FY*{lN^#GIGu+JngedS`y4dp3XcZD|C$=B)D`Ay{ zpO$B;0`OJ(C@uuP%ks+myZRW6%yv{QWrl|OvQeeXD zYpelK5RYT47mVHA45)`lr5lt^c0M5u zo6!Qd^z<7DK#0JYqj-E_(o43qXy>yGpo*4~JH1Q%3qG*`{z6jLtdU0cYP!-A(2suH zA@R2}GoaIrH~R%F%6`(d?Uox$Ge)tDJmTG0`SFhR())mXc{GsPM^P(o_R;Q($%dgf z+IU6sU*b0IF8n`vY^Cq{8)(7w=X^B5EAaN$S=A>Sjo)=T>+Hd?bhCL-|D~R1s{`8a zN{4HJ!6qd#bbDVsK5SBW=4++i6fAHijCj6=nH(fnF`!CB6j;E|DT!pWaH!-Ls=a{X zTSHjnWM5>X2>njA#h~Ja1ZjjTEmO1rNxgg(@ydK79ySU}>F75jSg9M9VrSvc>g->$ zadte1;*dQ$(<}~)`T7}8m9vqjA|- z<0=^&NKIDgafOJ(EqAt_*;J8z*pueOGRRkcbX5Z2#D8S4JogG) zqwOWuFr6?kgoCWOQc;NwSHVLPiA5l<4z6>=H}Lpr-1~t?6%j-7<7ilA!~#d#+t;2huwzw+F~+nLw#v@;!RI?~QmU$vjxZC?UqM4TKX-==UW1Ucx zMlm9j^XzLlFb;VN(%|gbzZUNz^xed5<}Tfk<~4s31g~$pPskv4*%8$ke0NL zx#2Lc>*6utbHY3R{e(pZVC~p32j>*to&Qpm z+rb&e#lu!%2)tzVIQ&ApT^);^;YKN##E+@*nY_-H4X0q(;=tu0d;F5+T$a2KU$4}L zg-aCrApw7~w1~V3t2wfZx6*Z{#a(Xnf-1faOr;u1)bG9NZuCtxzz|2HoJdkF?4p}0fyhP9C zb33L}cqRCEc5p=RcD|&dD(tp=x0B&pNgiu*m3K|Kh*tiai$5=ve{q`Alh-U!rUx{y z{u*65(SN0SC}@2I+7G<4BblUhbWX#0QW2%kSV*xgJw39$rS~kg_C``TdQk|z(CpOk zG~!F0MQ0#qH|4e{z<1|`qt9vlgdDM@Jc0XHYo-^5Z(fpwYev(O4}Au(PKM&eU=Uu) z8U$-8wN=_1Sg*b_*vK-5>zp_VyMt=0z`^E){rlAUylavM9z)h4^tX94(Z8SmB-N~f zNTqy>WLX9{j}EGAdT9+gUg@2h(8XE}(A{qAbFuXEW&XuUFfXp)1|@ezb+<9cI~Fh& z2Gh)&wJja82V<8k!pWDGxWpPtE^%^;5ktvm2cGZlX7TR6d}0YdP-F~`=dK(=hcoT2 zXNB1)?S0vfIeDE`<|q5$qImthmE-G&mK$DJU_qbLn6{AVc~z!KYhP$uumP8o{u z8pN_LC1BSZ^8YHRQz~RzPSGN>ma=C=$(pGjCBZdjU#%rGi;m z8&Hy$K+cjs4DfbE6PT7*i1A`Lsxme<{>(8$>p?~(56IotsOmTz;$9&i;*xw}WBjh< zFJ(AlczUqDl=4`@mYAch!=Mb)j@{GLonJ9KA)hv978$GntNbvL${{RJ2yjg$AwHIM z-zi|nFA~?Xx(evxQHzCR(Z|w_xjhG2TDSgq15D&{zuI5v9(AiG5ui%jVUGBSl~bcA zynB|~73rUndN+`}`FUn5v{qOOxxCgUX3Pje6?Hb!b~J7`c(NW4F^a~-ky@tb{wVP{ z%B3MtG_SAVwUfrUhg3;ZQ1P(66(1f)q)DIb~+4N+1K#&xm^RwUl#~# z@2zJ?+GQ4~;%LG>0Wj+45QOnma>OpDZ1i<)OP-jr3ZtX!RxybQ;YcY{=@q+Yb=Ba>)pg5$ zMV9LQXt3Yb>Q%Bx*h$^~uNldr2Ysba>G7(UJvXW;Zx$N_!ujE-1U1iQM85H%QPUhr zvHiS`3;$U`O|D;ZLiLT~Mip6^2A`W`mW&pKOsMXAxsc*CIZqW%ioU0*2h!OLX>V&W zHX?X=2>$6$2Jy0JZ6UxDJnNB(*p~A%1K@0f(@JO~Z}H*$gQW}ZODkTFZeC&AC0(K_ z^~6An70UxN$*0xkD#)cz)6g-;bT{mWex;#eY2ByZ$(4xb6aGx;Gy6li2N5gNUfK$&IW;&^y0bXoSXV z(e5OG!DCfcCO5|o;>QxgP~O**R7xNd;qY--hm&F*gc?hlul?k})cV?j&M}*7s`T!P zR&zPAM(4M1%YupNJWi>twVjkcfsACb@Fqbhs~&C)LN(m6w)RfQQO}0z1nCJaw{^HX}Ha?cU3NcfZZ%hdc=yN*rY5WpE?k!8!m%-~@v6r`Uyh(E`m6$GRLg?h@A@c2sr8y1fiK_Az?dLmpm=1q4f zy?D+Dr71s7p5lfzNn17A_s+idRK6@!<|GAhM}*6!B*#sv7dK5-qum~t6K;P*5w`^= zfJD7ls$yCOQ_-Xb8n-IwHIc-kj0Ktwcj+w=&{kQ?=wc@)0TkM5GrKf2Txl~T2 z=DAf4qY66Z_De0C!qoN?^W`cB+5((MiK;Q!!>pfm8Gn8dO^&H2aio$h2XTIlD&5YH zsbKSs9_y<@QO4EKg2Ur?U)GNUCGs8gW7j*Iy>9GHO~r`OX%g)D8g9P}0DI_`Q#m|h zdG(vXJMuZ6`n>&1(unv`P|`|(Ct&Rp1*FsynQOSZR7u7 z(G40o4wfEnIuAYtFKJwdt{ERsLrl*RC!$}JciPvF;znhW(PsUHH;;Mx;sz>Q<->@3Q+6D^SG`bRhv z-@+`Ci7_g>=qwxkX$VdyRGza!lS;~-eZ@{@|lhef*5#=Ix)uigk9ITb#(0(04& z&=tmIuj2?6$St9LHV{LtD-y3L2(9$V8EZxP5@9F2bO>`&mg8Nir11T7t$3 zc=gtQ4U3rW@fsN4%SQzERNfIM@X=d;Wj-ax!C=M4yKd^RV!Q>*jx*nfUL#)bPNudW zuA=;$bv6y@URJyTB%oeLpbZ$A|%xQ z6_Q61JK=lYm3P)=n#Xzl@xVdEj-t=;sYL6WA@Paw??*!sJMx-FVMJk(Ya&<9ZjI`W zchK%Ut_p~4 zvV$5%Z-B|DzwWrv_^yc8nbhWGBf+kGM1oNkNBxcbo;Fd)z5Y>|8s#y@oj+9fgX3#d zzOfCXU9Nj(C$4U-%iWX$UL*%&nojkBPMUcu<4dbXM)RAA-|W;>=Myu)xmR1B2B-E2EO4+$9EfYdbX1&JDRqH_uLQOyoMheq-D%%tgQk7gKrB zUl~d*Fhktya@y%M=1JC0=^6r&bds6g5u(Y^Vk+BTjWRahTr>tOl$a_l^+ea_<{PIb z_*Gk?+PHsp36ziI3a6QC`JZ=x?A6md;Kjq5K<1*ytdj3jT5P8b4dD;%%|Bca#*Ss5 zr6j{lNX!OCfBnTNXKf+r=goB)AinU_DI`}HWUVvGGz)V>>xtZwypX$&p9OIXA^hE# z^tEMI5&(qD3zCb*pKvy5o6^m!E~{pE68Q`L+-oOzg5f4syTaijbCqwTCyE*58IDYT z{Vb3}{jk3sCl8eQ>&VO6Vk;dh%8yn}Sc0{KCjovB!)8&NX1XMPRrdW-RGUhCE$;5d zmYTM#F{^|&+xz>svEeM0v?MlKpwVg@gD)fbY)VKBv^*-GbC9)4u~PiDce&vcqcTx* zb38Gu93QVvgm?LXGc4VyqUkDJ4QQ9Ea zm<~i<-Ndj7W`Lb(pS*W4F3p+BN5lZ=Hm0MOj#@un1{VctcSVZXGm&Wfr_;w5!eE2f zK@VxNW@+?PlkG0jMlT7DXeq&FBP-o%ozNP1cQaNtFttD@&CC~{c7$R@x5aF>LUZm( zzqc{TkGH42K7qh8RfUAgord)GP!oI>7Va?Oe%?mu^v)vd5s}Q4SSJuQHQzG{2ruwO zu$#H{>8Ro?J34;AuKNouG58hjMspi|kz2TPZ`s?9{u=2khaWcGg%b9#+LUGzVoS&S zo(e0lY#R4pTj;y!UoD>*ahqA%eZybKJ)mRhpH}D}*>B-SnT>=$jQu)d?o{vUuGhKJ zP+Yw2@={o6&*#Tja_~#E9D}(=E`8t9-iEXT>p#(j$cWsZ>&5Cc3j6=a@%AmL?% zB}7S(2J55nsPA#-G>EE16Q0%>rN8gyl)lG^bxm-W4sR@#RJcsUnpj$leJ0p7g5d>U zrCoRq1pI@AeH`D>=c}O_e^S2P<>rGaAm8go(iZ*;aBNL)WqKL*%@FewcIfl{FP$QM znF%%DPv(_8<5yT+Av$Nv`uZ??chTpY7qg)CxAVRzNWLj5*l`w~koV-S1|0f?rLSrt z!YZaGjGrM*v&_SPO9-&am7oeQs50t!PG$PCKe_p%FD0->$V2Djy5V!*>Kak?k@#1T zGzRs(usAOFDOI?h<420Hqz|ruuhnFp*m_%b`ks4wJ{VCTTjc;ikj=_H{VT*M%J3%= zswA=Wozu-oulN&MpTtz@{RW(9+<56W{IvS_9w+fgo=IYnzbxKM0x4j=YURO{e=aFQ zgBXtqwf!4lU{1AHOZDW%erNN&qd}%1AJ`fsD zDY7A-#qPu&58r4;&)*p;DH&AQthcZ7cXoC@8#iDgrR2#2+G+YhJ$#JfCSAwoEte^E z%~t-w8q7UxGg*;`x&ap8dactpbS`;Hi%TstLTcaL9qh>^w353jX{)p%W6tX}>=M?6 zILzkt`#AM`50EY(FSvb;%6IJDvni)d-(~0^xjbQ?v#Fh>X1(S*pkDc=N8r`zth;U{ zSSwPrrQ;d+Dg|2NLgnxWN z7j?TS^%&A($@hTh%NhYoTohBt|b%gbivt%CJt@-rzA|E9_vUAvCcm{K zNp@nNs31`}trlfJbY@%hU83_4euFsNQ?9FLd=ueLHD?FD!||=xei|2JRK3nS3CTq0 zO#oUr^Yok?^C-M){Ix5cUtoywj~{7T5;yLPbM7Oo!^x6t7LpJO2ummDyDYc8Uc@li zEFLNdT%TOV+R$R5CfV63TMkOvgg}Sm3WS0w%e!hct)zi6mA}N#fc85vH7#5Vw{$gA zE-0e+X-WYEW*on95&nsfArjKCUV`;Nb)QTFW?oY_(s?n5l{WA_>;Gf#ouVTP-)`U7 zwmY_MyW^x{+qOFB*tS`*opfy5wv&!K>E897n{)Qw=i=Mrf4lE$scMY1*8A34^O?{5 zT_f7qn23amJkK>St+d1aCp`q@=c;auOE4PXr|2P;M9Jy#wM&byM-g0@SHs0c7f zp}+DZSdq+c3^^pHn-+s-Cb)uVVnG2^Ic_Jav0EvpZ)xopo6tfY&I=zwoH?>9`3AI7 zz0`xQhSp{BZygldZ)fQa_jc;>B~Z4oHF?S<8M8jkg4X8pesC~cxDAN&O`YHXJ8oVY zec%^GXra@*ilpf@6u3X?_3g8SD3c50 zlc}YINtOk(mH++Lx3Ew+rq)2-8o={x_apjHA4&X`p*sTSGY{5v!of^F6_44=2pae^ z?}~@PpG|wSuS`pS2ji?;gn?a|y-PxW8E(In$?)R9dc5idnA@Z}OD0BJXbEV6hLToi zfc8b|DA)cRLn+G?cM~g%IK=g4c!lF~koyh4)SUc`7szGdOP*&iSwLPc<($9TBZh&n zR2#nNEs(EV`<>cQuJhn_i~s&KyB<<$^)~7?XEK&piOgbWSSe6M?;@=r;!F4Bi{u(9 z)r$E0Ac1!T;m3B*W2yQtimwChZ)ZJ9^hihBiV`w#EUmW!1i}zPQ z^hB1t9@JxBc>?k;=I7-|!Dn1qUP4Cae2OcSHT>m$Uh{BsJn=pv_Uh<0h@xmVHT~@Q z;}~DfpDTz0TRoh@m>pTzvQrFcw>ZbkcZ38dcS{so)(HlX5oW9*z;wWllCuoDp6=&2 zAZraeX(8Ezh~62sO0XlCG=46d2TP|^!Gi$_en1n@HtPS($0#KEiy+;rzuX^2pwb=^ z0iWi&eN2=lcPqJ+@gt1=&`37?*Jgvxp?5l#1bwJxIR{Ba*use0i4hD?7qokmM=Wv zt=xA7MI?OU&oRkp+T?>S1({slq*O0kqM2Wccg4`ef`C*6>S)i4Iz7t5y6h~l;N8Nl zi&~DXq!T2_Af;XZLTTG+@oYR+>+t!K)uuo4@-Wxa<4%0{KzX>;ZU+~{4i!DFFg4MJ zB>Bjr@{O<7I^n(8n6R=_xX6Y9WrKP~((VSaPcv{)2!^B|^QYon=EmF2dvnxZT`b-4P;A`R4w6(9ENx=Oew*pDucTRk!elqsQsA&(=#<6Y!6-T^YsJ64>akls=%qivP0T z7G|;geSz8dvBdm+< zn*#@ng)%*cLcjS^7{r@~f>uik7n@R9A}{%vrY=x*G>?VK&BuUOWeMer4R@)-JA7J< zQ<7)8bE!d2Wf^r?DP8RnJpz)vMOQ4R+)uKHMQ3bzPq23K;k(my=$uJU3v}yj^Jp|c z_i~+-3TEzW)rc4bmn?#*vRdpT0G&wV94ifWh6*24aM&Te!{8Im0ucLBJ{M*}s&7{h zXTb}X!v6e7R6t=x^G%Z|mxSgc#e(sv%pKnqOU}WNi!UW`CAOtJ=TxeLFLGv28Iawt zVuu%$mgl0Ml*yG$L;eRQ1wO}V%WjcxD}aSkMh#_MW=kD_FqAyjn>CBQsi_+q$Ep$M z0f248Zi-z6ktNeFU{?!msvs|=PxMKM)O={+$t)I`D=4Z;lwOMrT^ShAAgaaNB9%F9 zRG?^glF0PJJ1L)wHpJNhj8Qt^_C¨ImXMM;$ZA*W4@M#SdyCuS5^JlMu=eDRfo< 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 QksL0-kk-EXx%mQhW)Qbc`<#w1N z*+`<)*aS7|R7gHDJr4>1g~Eb+2s^6@VbK(?`W9V1GP=1e8aTA*qzNC8l9-qLg6WwK zk|MiWAAW+TYZ(x)ek1MypaDR=tGTMg$U}>}uE@H?E|e>Z2l+6XY#iror!G!T)r{53 zK8MBl#ZJaO!p|u3Fj{0~jl0TOFGZK%3!Wv%eLhnbb@YU;2XB~H_hx`q!7ZtjXZV`a z=%;xV1Hh-q3p+gN%8px}Q>mq`q(l$;>0>*o<5g3b@tsvb{e!q3^cjwkYppt%F75Uv ztsPT1S>Abmt9Dj$-mr&hvmUau9(qZ$C*=!)(tM1W4$3ca@O)0~v{(8^ngXl-!iBHm zyQoKmH{TO1S=3!#I2@D%h8Ux_TiZ)YihO8H&wO@O?xf91{q5JzEEXqQ*%P#)Hs`VA z?B!2Qv|6mS7^`3|Kv_aZj+JoC<8=mpp*@BOW{Z9F`V|WT9(D@5(N8dvmbe+n!HFxr z(%bAWC3I`8Va7LBX&Q5^TGb>KLt}AP`gOZhg)JvZ2D#kzvZujk7(&%u(>zdb z&#{3`tqg+Hc{?2~E?mSqaU@ziU=<@--n4vhbGE}i^%c2p&c`j>UZB%!Lc4s1C7rSR^LeXn! zyC$)-M%AJJ2WGbOORfc1>5yqMAo1oOSgYnOKmShOV)Iu*0@h3XzJIrWhVow^#SOrk zm-j)lLLsrODhp7S`&?)HIdLGAN3v&@1p+21SF&(!=6zpzGc>XK$!P7&g?IbH<$an( zl%a3Ab+Xa0*~n3qq$Q{OxeN)z$Mm2CShNeaqoK1_=X0S?BgU%CgE!XxkmXBmF5BYe zv(DMZ>8Q+kRR7*K&Qa{dWcqdmzj(HptvEU%IH_!2>zI-4-k5q>9ydDf9wzYaQLCzf zjDXPDKZ(82v6*tNcz~!?J^`&maGb5!7TPuFB!gYCWKn0cC^x5)&AoNOl>$dE7D|#< zX?xO7|J39SEZcGm^w`f?Kpz8CEV|MyPEcaI=jNC!)L4cMD)}%8r*kT$lJKQ2OmwWp zz758`O@%C9ph5^CAS+C#E=?e6vQ@c< z7Wi5pZ(VR)srT`nt+tHFWeUkFDpQunE7qknDu3T?B~%Yqu{{AQGEQ{zFwR#OqNkP;c^SWrsO)Rwh=;P-|Pr77?H)5+qEV8^e{LRXvA0Xul z89bwd-HGA#GM|RIP9efZ8B=hBo;{vko;j!&5;l~ zmvMuTi~V0?(cu5o`hfmFqrLsx@xA_NKK+>c@fy7hHEh}5sHsHfEBgs@qxNVv;xmI{ zQD!tI_;S;wBoN?3O531n{2op8{Ag)O&oy`eru%q++I|;NaspsC1#4R*xJEl;qFu{C zm=Az)RwF1xLN4ES#!@HE(q_GaMIPaHG!mSK%9>u=OGV2)9?^DTV{pxHfZnDHDJ1mx zADFpR5m!TXW04s!W!=JA5OKF{$=06eRl*imRYdKBC!7H?%HBb~*1m7yu%bk~54X8} zwz1D{-DKL&mNVYC_B~3dpx%*gcyLIp!pCf|9>kK8sy!hm+N^=47>nL(v(D7kI;}@; z`Cx&|jO24#EdB>}jk@1M=*GuV{*|b~FVtP3E~Yz~b<6xs?Y#u1C*&?7)SNzPC3~ui zf~~4L7?vz~ezQ}=Z=U8jtWw{24Et9k3}P}kj*J@+#7&d_d zJ-d^yy8keqc17ld@2?N;+vE}t~DtpKYw7Bwj2##>h69G z_xPHqa6@(7NYRh8HiWU;~t)5iojWd_AHi~Oh(`_a;Ai%l%2c%5fP zsk(Q{53KZVFBuQ>ycGMK-)#TD27``r73jgUfj~gIS^+}EB7jk&|$@eq;4#N3+7NgzRc(UyI zT4*lZ(%y)7>MDnc58`8$Dwm1!*;Gw7bM{YPHmSLP6JLXx0F!SfCZGef>%X&esEQ5e zX_934l$&Co3l;WHNG-Xe(vbHmhYa){U|Q*6zCMen765%NIYT!xurEI`bUWTuHYQ*h zvTn_yrHvZttwH0}dPS=6Kd7*QB=>I|!*hS6Uq4>|fqB=Gdl(RjXY#C7Uq zBV+Y~AK~*y(4oh@zkJ+I_rbLL7~4c(?s{H%>!u)GTIDh^D~TR&NbT4a>}=n-pZK*h zOgAKrN&vg>P{oxIRrw$V%c8pb^It}4cOSDcxa??c(EE9Jyp6u!oTgF3Ry#^+IXxddXK61DC!T419(z-enNX|&Pl;LJ}yIzuT+zsTqP9zic#c61)H^^PWh85WuP?Km(VX&2uLlq80e-gs|aN0II(sxlq#Zu z)?}7ocQ(nOxlw=Kl!-!^b~Fen_aj|#_nU6=peVkK5f&B`XuyM6Wd-jxg%1Of^VH4Y zk1*jK2QLp{zS9!KrmxhJ{pv;IJuV+rwp-pK~Y+N7l~Kf54XFXtns{P1Pi?p=N?-=j(yXM6?q z$7&CCE7(ofQrH^jUD%2xRPdXZYVymf9^Rirt1f?+%gUEO*VYta;JlFIuhIL-6Qw=j z2EJ<#HNVLfZ@oE-vSQb|A0_%m#p$rwHe4VNrGTup=nu8~b{8gylI0j)-3=7-52&Y< zfqqtQte(1W4Ldni>2UuCwnTBIF4umY{a=63_Zt5x8*{Reus!xWnmGqUb|}Y(lug&o zzQsZS)oELJ>;0yJzIx%}9APz7O6DFzzU?8+1J;+FTLn>_$5oz>b{0(JQ)R%H;`#;c zT$vB?wd7y=3>Q_rs80it;#_jKdQGPS*gfDYz4zAmo3Fvtl)HD-fkNP9Ls8_|@CU+u z1Wz&7xBA$n4+aWHL`mfB6+ZJ!A#yFW`A{%4!NM_SLTvG*8Oo@ z7a>;f)izvA`1!;4_urGfxgmhED@(^}?QT7uYu#P!BE`YC-BJVfcjY^V@NI(oE8TkE z@oj?hD_!7MnYZMLL9oa7r|!x8{FK;tgA-R6co+O-;8S$7GynV4WdM0D8=pYxEs&$2 z*4}#uVL4B!1Tymg zB*WbGt&m^v9{c5Br&)MOXoT(`P{TSzEf0IO*ZKi;-8A;^+U9!$5BqO^K@H1g)wO>) zerRQ0svTW73n|^1HE;QZI&hWLGzLuRW!LU_yF3#4g!b38>*3H10e96rC~`Ql-3uG<;LYHe4>t=& z1DD$r=rm%zV&lfZ+EmM~{qjgb-Z5*haNO5>UR|s#@;_llw7mj$jos((`qlRl#2R^fS`V_qSMz;V|+VX=8jcM=*h9gnyh)Pslwx zkpKpJ)`S^E(KufeD&@OFFz_cnOj40-)FA-TAfu0`6O7&DM#wpoT4%OMG;;j1F}y=| z4}BR87IhTvTFja6VL`zvRel(<7_sFLqV7iS_m?b(7}RVu7@FIy_UEs3nnq%(QYW-q zYj$bfK}n?6<3@?udXmH%ep&W?Wf1IZq#vOWq!U25@(MN1VmXQ!+y@Yp51$}NcqizJ zLBOX>y8xJ+opKfK5$ts-B2y0=(*ljMMVDs6-syqd6Urd zL%;+i_F6?YKoG!^-y*8MD57|tD#mWRQyE3NEX_W#x}mv;F%`N;c~M>HSq>@W?X0>9 z`eFAd26x7dI>TzwO&_#F%!YCAsyzgAwuk@K<#r3}jat`UvCwUkWNmpb^%=?(T$9yl zgZbk{$j5o9(KX8>v6UYjtyCV5O1;HacMU%Lpz3AzOUX;C&LYPvo2dUX7k|QDbqKgx ziFeRw0qdN7>3Q!PMPIHD|iBa*6qnNV9W` z0sL*!NX|2!-wV1-Bv~M3gf5OiAS2&%>)-~)cHu+J>~G$|VZcYiB0{#W5q8Buu-?eU zXVP|0PTM~))Nk=6Pw5;7h^UYP(G)L#ozz*Q0Yi(Aw5Af3Jh9gAO`t?t2-YVNu9%zR*Y;-_%Hm$bbvjo z0NJJQ;8*wf|A7?)wt3fQCS<(yOmpLL5<_ zs47Mje=L^-8NP{!9?(^=Ztj+X4h0E;L}+S|$#3uX$tbCp1+pssl$dPN^^5R~ue@vP zVQlz`!L)+k7vcq4 zMS`_R&~Bg4MZbz`_TVy_)2O}D_{^TEal8`p4c7NeR^kM<EwUD`sm{G8083OTNU)7xxWq60*L z9aeM5RV;8a?pVJdVs_Dm{HNgUCUZaEmHtQ3eJng*?#K`gn5cvGW;8A`h-JKXSW`!& zW6P$@c;a(2!Qb$W3GP-TsdjojqL7{XoyF#1mX>Qcr!Wnn_z)-tl?%k5X)!^pu3_Le zkmQ)gA^;Q#h2^K%cl8wneodHTw`&!0Fv7mlsBy?Df?|!QnVp55NrVo5c6@qAykv;R zs)2!>aXW6&&<%uZEq9j%SrbT!<=P|UcbaZV9%OtmzRxr$7=<)8^yGS_CDyf*isZ7^ z&3#wk9QPoL`R({L^_^NM;1|`-B($YMl9~trS5k5?1kN$blOg)a|7@woEc~*$jwv7B z&XMpBMsrt}$9`8RlC?8=Lq2$!K#D@@Mdt60(_ZS)pie0f z6{KM(0ngB&b!+jCtu?-piH}99v4x=_5IC&8!%PVb4WJ_=4=2NX;WGc9- zS*^L$<``0^2soVT7fHE{f2=#|e51t$C#)~DA40GLYx{89brGvG&-e`^*KTAO#OQH^ z`JG9(v@K%YBhnZ^0yjlOM>|#bE~s>&59Kn7^zW zA5U);b!WZJk58KJKB3q{qS?0|C-rYRk;9nsWtU<_7N?r?$`-)ha*}L`Rtz8RDj78l zDeNpNDI+H4OJ90dtNGSNz+es@zChHqyu(@9UPy2t>+TL?aksJ)W>F-a#wrWayakx< z_^vRgLbn#4f5H@SCFaer-s}=gzHu-tRzQcit@y8|1ZTx& ztUKy%)sXkXYV0{<_&`5QUUNEDH76N#;X5^FXmVg8UjHyX&#NEVBXI~KekT0H1tl55 z;BNJeNIRM3h^ZfMsXF;>2bNuodbtM1RsTQJv(&xe8cSx zCYC#DgBzX`CK24i^MzWu*5+#$!>;ujTKT#gEiDJ}X02-ZhIG9Hv$4bMTMch=;GrgG zluZaIM{OR+c77jd%O~me1|a9a47%&+G^B=?EEixfSDz8nO;=ttT^T7^4yo8Iai!&; zI$DkE^vcRig{fJh*!rr^1n6|5I&xayYB>&X2IoM%Fg(CcLd&41eqe{mxO%yMoG`_; zISnH+c#5wEBJ(9Aw%+Z-KQYE}QB1pgvNW`t*UB9Beiz`@Tm}(zC*4XDVo_3#d7lTH z^)xyJN4G){#{&DlV3D>-Cp=%Jx!(b0=ABBm4Q z4Cw6O!h55BWsDoN@!tv{1APUIiPjy>Zse6tPOwo@4!e=PBlh>xt?lN;!Ha@Oft0jw z_)SC1H5dBJH9M;~;54~)N|aLaMY9)>p%NB#XlC<$d#&CEY)x-5Im+DXdrL{s{vv4T zD*dcoCfz4Yx63;)CUbWh=WkqhcRG6Iu7xKP?u%@lrEtvto>d4sqJDEWI--|Pm6!OW zV;$hRb7flY5UzX=^tX{A7GiuPvhXqT55+GWoQ z&*%jcbq-vpdQ3V&9n+6KpZ<5w(fl-&iNC5S)xyRzMLtir)3)FWiN5qM93z)$`G{_> zRX%7758awaRgy4JawWi7MFbu?P!LGV_x3Hk}r$GJ1_AF%n zUj6V}PC&N1*rSb$Yjh*~7nf@!ntc`ltmaUlnbXWg}SReFT_#TGIQzF3bR zAa~zz4$tySEQOXwY_p1=m&=)+KL$@nHU#Exoe}rul@a!6wFUU7_y=^WVe~tq`so; zNyu7OpnL%5Je_qSy02y@XZ5{+{mMR@gZ9A{R2Y;=~5k?qobo8>Ga)4 z#lgeB1II*Kc`-Gv;%Dn0zdbTmAfW~ ze#>9Ip8f+PM_rQr#s0Ob`7K+^=oimB=515M=VI5_`>*lPr$v_OUmj@@r)g_1+w^Zu zBJs{;*RWo<7}n_WBzu=AML$H)WZ-$JH9PMu7#8ZbCnq^B4Db#)v2ODK4cfq*4HH$& zb3@#bua&5G-L;iMm-El!zb_&%5n(+k9;aYB@lT;HXg$EaRnH?h5Mh=$Q63?8C^mm# zJ7Fe7cLxyqQ15HSav#Q!Jpy`UKhxHCh_Hjui>IuwU_GrLSYq)xW@`g1u~i?M5L`Fy~AO~^Turbbk0Fm(L9NK zk21c#t7+=xW}R9}E7jq#9d0YgH<|pNL%r3>l`(jyelW#3mXzP)M(h{gE-># z=ON;xN@{QBQq-6D-Rdx0I3NM|S5H~xg%?R&s+zGK{idY+hinOA`oQlZ1BodUkQ!v@x% zH3a9$ANaFxJ26%m;2BVw&fW#oDVm++y7W;ZIEe%-6bq`XV~&4z$SG&*uEj-73Vcf* zmFiSW`n@mc&*>7P3%~h;{dsnPREia2rtsPmx=lS%j*>})^wrN1mcmv!SVY?ktdllB zUq%tQ#p-=5^-=a3k(82v?&Zxm-y{=beTgn9t8sN8EAaymc;&y$Q{ApS>vLYqo2U2a z6;R>_SlOLRS=vMwqA}L6m!nKOD+`s#0`=Vj(t#~~73w3IcV*FAFh{igyV!P}y@LzpZ|27inIDC%iFWyTV zvX=JYcdb=Hh!~}jAcF3ETcNfGLbYL5ad=?*A|5tTqSMKU4jRd1WKcT<5^fhix=F^4;ptLwB2u z)uDQu2HUfFXUHW)ssF8*4M#dK@jtEnA?djFcdF~j7emE^}lrw2&e4uH|AM34qWHOCjgH1qkV@B+#%I@}mk5uLJF6(7u%st!eGAfpgSE7^H3Ya}s{1`yz;V(H?{ShMoP!Dd~rRl!a!=*5VvdZEr>AmE55 zTdaL(7u}|5nP*|D1>hcA`G9<}(IFgj!g4}Qb^T~owMyA?2o;HNs2rDyIr{KmiKTF7 zaMU8Q7YgmnNQ^TKPP$V$SuL|RLRXWP}mB}WJZ&Vx-7AR zd=J1fm$-Z(eg5WQLrUb8$GFa>xH9v_BdE@ekRWdnKI-CDtP3Q4N8icK?a3#YqCDF6eUGtm@zyUgRxa( zNeseRW`?ZU8pC5(^v-!cJnz%{?fvpU=l=5l_B-b~_qnd?9zpL(kg4qZxl|OA!!WVJ zBsGF)AM34fOw{ZwHz4F)bU&ngDN6l)xa(7M0uPxd#LH@>Z9g~+W?>F=r?0q;ii$RF zLU{rqZmsnCU9{oMRo9JNP|ey#>6a{_ z*2p58%earLZahBCYE;Iyvn0~GWPT{_u+{j>4@ytlLpbI$<>N|zO{Pbz9jS`M!x`s~XxDMk0ILD;c(&BW=nvc0KjN2J}}^dAnjYB?YMI+QH(i z@L&c#d;3~YS#Q4bw-u6o&r!c?()d(w`yq1wUL5K-&X+^~OZG#y53mbAW&I-y$Bc!R zvbBdlcnE!0@ITEQ&of7Ii$FXfqWc#M9`Mt28god-iydOW&H`OI{5{r5)l)EMA*Wf; zrmLQ-!Mg3ycgio8qfzFGtk~_}xDMO#;1R+P-Wxq5tuosz*O=k<>d>ZjloBv{IdM)y z=mv@KTI7jC^Bb72t$$;NsWjZh^236iHPv5W`vff3H^I`y6&hvOP!WJ1A7=LTbS*H> zs`IFv2?2h=tryg*DbzDMGKj4GMbH4HNb5(Z#@8#n?)%LMjfw&BTN^R=oVNIo=F?k8cGWb0K29BQA3eWdG)zxnJ8Dj+_)pQF%FOIx|x*(lP{m zA%y_0;hpYR{+X`Se7l}LStm?!6w_UxNyio+SwQ#AQC+L_T9wTtrDKi`SsL`Zy9lk0r5^b!?>@K*Guew&QL~<9*)eUc5Dckv~_t3Ar zU*yE7qT~@p6+I%9ff~?gy+QD%$+KxH%AT$3hiSBe3HgRl62tILaWHxf8|iU_d$c)* ztV1I{nWIjX&2-_Xb7=}zbK_yLsxjpFcQ<{0!Yq**JnGE^+u*ABtsHK#jGzaJ^+FMG zdsAD?t*{YRJFmfBoNjUH%_Lf$otfop|*CqD6FM&Wi967yGtxyI}u@;u-aKhqZpyj>{W z5nk26G-1t;>HT9S_Lsc}#0irj~(s0r_Gm31aN%{oD^Wj--jtm%}e^0^LCC3@eam zRJm9QB%xO7v2@OOrJB{U@-YDKN#!ewCsbFGxK-bwADPHV@@oUawmhyUPzyxCP}a)F z&ulOb(R5!oEd`UD3*z|*VY#s+`Gbchs>k?{nH~}n>`NweD>cC9K@~R0u`{74Pu@E; zQ=dL`$BQ1;miNa)?SjvO?qh_#PjTIRwYdtszsmVK)^3t>?azY0KzU^o;x8PZ|LvYlRNX@OyH6+?4v(`h_iV(Ubi7Qj0Ds;+JBS$V78DLNpb#`8 zV>}n3cH1YWvr*S}67z!}65sk{l0}Yn-YK!b)**-Rql}T&N#zFn$>e)N-q3sSxWOE( zMW@^Jk9Y+JOu1B7-2lCKQ!|U%?q>^)!0xrag;vBUsL|B!PTtJ;%;IHPZ=7%&OM&62 z&@+i8>=%k)3R$hnyXH&faaYG<1M9(>-y3&7%tdySP#+6Ff3YbVos(QUBr1O_jOKIh z%Gy+!$r`lpdrj0H=#uo1L*zzX`vU_`2saH#BOQ#}0kt99$M( z{o`r^QYT0y)sLaGI3H`Ibz^c3K03CSbyf;j)*m1cdx|PhYLFqH(V>)4*Za-k44)`6 zgpV`m{!VHeM^Neza|sQM_YZjGs%xSR3c35wr+;USfr{`KJFS^YaI*w1-stMMffF}g zB)7`Yjr%8N8~CY>S0f1;*<;W455x}ybZ`^R;8eVbupc$0zym#cm0NpOFq>i)y6Y1H zeZH4QL^mE!!5KPyDb=5E^7)@IL1H9FXV7(jw<(z~x@lo;Rk_flyN2x-3-1C?chEdf(d5!o zm9}MRU?;=uaQ!ENERs4U$Tr;G%I8cTad3}}*FD;n;%!n@FP=h_EtfZB(h|UCo6FX7 zdEdCfktJ6uN2)O3*OtDHFX52%DQo`HD~-`wl_i)|$#$ayMamPS?D~_wxkkB;)mn-f zp^{Qpv;^W#ATVkQYKGZ-!V7(SyXD8V|vEDuF8FVq5*RY4LkVo&z2FT#@GbibCo=MFRka2z>T%Pq+ ziV1?nl=VW`34{!sZSW0{^Xhd(!pMXs+f=pdy3f7^iSL#s`2zdn66Bw{*2l$5q}O$e zYXnZOKXQJ>QK!F0zeQH?HHd`L9)nzqir14A&W#`y>I zKZh5oU-cVkYy39#9+4L=?IleY}dzR^FHN2xc!R-F84Y$s|ya!JsQILk50Lc5cQX^ zz8VjNF{K3{$F}nThs$8C6(s91M4)-{?pMwcCqs|xsR4slmuhcGZauJ^yi3^J>Rz<` WH{KwZ-9LUu@oyggk4Nm+#D4&vd^uX(S{>8U%z5($Xc;EwJhC?rtebLAsHS&8EA%yBp~S32E@R&iUSZ z&w2lQ9WcgXx#AN~%xBJLg(=EQyhI~H1A#ywC1cJjc zQI|56lLLW)Qz#%rI1mT{ID-4@LO8hpJ4V?Dj#)u}-9!ugN`JKgz4+@I;MX4R)&E@s z9RL0Aqph){orN)lvLfq8CN@?UZdNuX7FJFs2_7yMi1KF$mz1g`J1~wIgukDM2i#N; z`~C0Z7cA^7pctILkCB1%O|dBdd(Yp`W@BMv<7H*#W#yq@;o@aw;bmt7y=VEr%fbQ- z`u{WVe+GN>?@9dil>dJNlpZxI04|1eQj!n>m5q@c0DmAjiAbrSpr9;oDEtJ0C_qx8 zA64Abk25^Hl}+0Iw2w7u=WXLd^ZIh}8ej>&0{ z%S|-nWGw|}CI#+e58_ujJZ)_3MfCSpuhD80&8LGoZKi0BJbeAqx3{Tz7Ly3v*O>KU z)A@P!cq|;pZZ5sK@@{*{D6mmpz<&{@!1f05*>r&X;Sl;d_>G^tL7?OUI2L^(mcC@9 z5&i-k8*mw4{6c;eX5F*da)L{>N5_JViWsG;DZje-NA)oJfbYK?o%p$Ug^!UCl6z^WI4~F@-|^ zTPUN#VlLm-ZvHav7w5;gCjsQYhlcW^%jV_V_tu-8U?Y%pjs{!Jz z6)BE$+bUE9GMFI*B~rUW4ZV2vy#UVS(g5KY@uC2gxCI4{=@WJ z&0s7lmH$i}CEMQ!(u@Zt1Ql;i8F?+|zFfUF@ON9-h-Vl8V|5fjKr9zZPzqtf zP*qeM(W3vZSpZtUmBAMraHx-e;}jx7k>RwF7hldx0nmbPLQGd>C;% z8c06}5`c*V{=d~m3HrIAZ?K$M8Ag-dKLCbc7i~@%0{8wF7@@UQA=uin_Yvi)cDN|9 z-}$1|9-gcE@w65#3=UoJpO?e;Wk5#tCou-D7h-MfJl=^Dzzp}{#uS_D-xg96tiKyt ztVV`y5+a1G>_KA)D=0n%q5ZYbz^o~`DaPljt4Ds)mibF35-dZ%aXLF;xPARpaowJ= zWKX#HTXxk7zbCHTa8GUHRwvmT{}loOf2bnmf94$o-xt}}v9$jaEZ2MZuG1gK@*AY* z+C`k$^ES8LJp(*&O8)gLQ{i5gszW4Pbp+0*kw$FTD~x|0@PfGKVS!$*w?qN^fwzlL z(W#WJuKw-P#IV)ZW~Y){(|Y6|kfv43zh3+AyYLn6!1Bz?Iqjvogn8kRzTd^Uz}V7y zPlJ_%-}1DuY$AlhITb?uZz1qsQSkp`IsxUsJbBZ(Jj0*iZMR<|2}ddi)1wr`(r@1L z=0>)TA#b~tEFk&^>p>TMklK3u4M3tb;q3pc@}vJc+irB1W9W00*W@b%Q=hkW$ybCd z@CmYS=I7s-9B&*iZ>l&DgZd`Hx|uSeHQ{Qk`l06dy8oUm)}-EC$NQl7Sl^8b(3<7& zp^-;Nk&a_(4j7>7`im1XccV^ZC}y$^qx+#2ma83wW-rb^*7-5ONwrJ7p{RASEunSU!x)&iJF&T9#+7f1RfX%ACj_pZ8LT~9;j6iHtn~Zi zz&7FknL=k^e{5Yuz-D9(^B)rkeR`><7Ko6&O{yg3D4AD(ATf7S7izz!?=bByh%8ha zzWyO1Om!phe>*6m=rEvCiPgNx4LKGCDX0qY1-##mP>fTtm<78^Txml6-3Yvam2W0w znbPZp`{%us-JOwj$#Vm=G9;u-=^z$i%t5gKcQNSIxjBB?4+p)9g=j*SQ^D^~f<9B= z%tK(*UBUl*YruL#Mc^to#2XFtDO4G@V7dEthFW;a&h~B-ZoO{hU|G z|Lzf?Xs8ZsR26Wm@FC(g#P`n_9798>qfNFcABfc&heD3A_C%oW$vih0+*l&y2;w#2 z`2UO+uFDL0Sq7)sz#2pdQm8_+FTr=J4e!=nwZQKWys*MQ8z19AVx;rM&w;Fn{Nu~^ z+LriSaQaNKkkYpen!RNx$u{pEHG@}^ykLfJBn&%{=>9S0fB+ztj1GuDcAprds>%5G zelx2<6Oq>x+bDv#hx<3qfvJ(KfBfs=HQa9|FkPEgO$A{ArGK_&!E_Wb_%*FF$|8h5 zG@2YpI>rC&3|m^8Xd+a~+im}B42Lq5eMEQXg&vgR6$0nPzb<0bR_|D&hT0=*p%FN_ z?Mp)!TyZekrG+f;U6Dnh_W!z4T$>vD3!l+78>0UEOY*mvYhV0=*Li<5d!bH0fj}6b z3YPTKwL6Kg5R!z8xo+uRbuV=w^PJjo-9``1}-&pnQbgn*OsN2_~!RJ8!@#>&}jvBOG zOe8*jU;^ z2~jB`D03rV!db{+aBu%vN8Z~JJu{~_i%+-}dc92sAoGNlL8Ev4*Vr_8dB$eD@^noV ze?sjv5j#nt{~ixsl4dU}C=!Z>l&E@s%8^kcy%t}IOP(f!`eFnf=as|rOyyp?&~_1| zhN%Wk8TnX#7W|K4h(x{Cq#0n{k@Q^+mi+X;PKbdsotMw342`;b`KoYKRQvD|eV#}{s z;4g3KTPFOPg>%YRD$^^v+l1AI1x^`Dp^gxQ=WK^>r+zZYK0pk!MS%Uw{zrhJG7)`5 zqCpyIqBLgJ_fYPa^Y#`jm%e*mm7~qA+>nKMZd4Sh(^ukp-O@rX%@ozoN3LPOOAc7D<4Er%F_AKQSM41+Wr0x&yBUU zXtT@`H2=xAE9dUn5E7XE5d)qHgbt6Q54#XVxl2!hh7HQW&H>;RT@bb+9w?Y@7$l1- zZ<@FgDR1bEE`gwdPUAHPu2UXJ<6X;_)_BNXv_|UihXX+^kDB;+7vTmqQa~U=1W;d% z3$UkfTa$8T@j6ldqy82hgwq`QMCL?BL@Y?MMjgV_{;d8c==vD`tbK`v9sJ!Rx^NZ0 zg?9B!aZUGr!gDbPWB=n`Pr-b!uI~&TRiQHz&8aq>HDeDAVde%RM7; z;^dd&uCk&vq7-`5cPmvZVZBri#>&4Ii;0^pgQDURgIRsJ2 zQ%NU9Ak&Cjx%9nF;^pc164ie{6j;eyg%`h3I**Og>Zyu^h?1X3U;{3kXUz;wR0IOo@irwE&8GkQB5|0UbEB%hrzv^UN zeKw$XmbK{s1H{o=z)JqI;QbgihQB}jQY1ZGj>Qi;;hG(cFI~cKMd7Mfo7f|oJ{==} zTTt%v$Kkdl_Od6mrr!KaxzdP2kB3hw8zYV(^^Hu3+V@(rx7&@rA4{rX5%#C@+7#M1 zA(Vgn_oN$gQAf(V9O8p!${njWLfV?Sj6})YQfXVCmlmZzWvv<9f3BQ*$n?|v&evn$ zb(!B(b)v`4jwc~8s(t4?^~3pkcKdjwrPyfP&u_rS4}UDL<1o2V=kYHKJ>{kg%6S`H z?C{+K?OU+ORngNm| z!TsR0<5(tbfGs92xwTc60lfe)-yx!hl?6Uf#$`^NWC#;V{*=t7proaGs~cM$^KB@S zG!ZP9D3)rmGHImfa;;-=BH&&8GW6 zD))f>qHPFyoh{p`i_28PaG4=-#i3$5gKs+th#~scNHSuKR)V|}$#odQHH)thkQNeS zzp>Uak0bgQK3#>C=HR%RmCWl2sjWJEqQR4(bNoteh9x3T0P4G4c*j?QNrwDl6R;=d zUqyI{mk;0KZT_U*IXG$iyYHoBbPl~Nh z8W&-Otn!gzBhryXu_SSf5sEGc?E>qLw@S^bW@z^CRB#`tc|0|Jm7Md8hID==kKD?B znlFYPcI-)^U|ojeUG{O8K`Y~Dq3f%9udf1!db+X{hR4(-pS&K1qQ@;u^;lBWZ*Sg7 zoMS>&E!LOy3Mut^zl6&&wlK&Da%$D6JL#`ElFfnBZ>NgHiH8HuA)Wkat4dV3*B_pdyscfDi91y<4i@NxjX=Nc`Oqs*(~^ z*!58@%i(4*@dk6I){QuTL(i8gXl83`>fIi7k9cGA#BF~RFy`_4<8oVcExH7Mkqf%d z^3o&8A1ia&48P_}Z{>((2=p<)Rv{&)GNY>}t4P_Pc*nts?d0siNef2@5ohD_PUng` zAFIWv%c#_j-`SG>;mE`59*)M&#zmHD`;oiM@=#Sjk4aI(86^HYw1c|6zDDxP$KC3O zlH~yR3I1T`?hC3E_3e6vvxkzo*MdC#1W@hIsjY^Zb(buWA9L9SYumc!(e))!i)#;& z*(w$3lN#0ydcqryl80+Zy^r(Nz5hL-K$WLK=OYyjsHF+!Xci0( z_3}0J?gM7614}7sa@NbR(DmC-z3~n74!$~|50pla?V%!Luh+7>Z!57`?S#762%O&F zQs(Jqv0IOsi{(v>WoL6uEe{c|-(KV-U7`jp<|+w%TlA@0>~9TGg)R&|AQeCy->rSv zm_!c#{+(?6D`(2En~&FZ8UhH&PMM7tDS4gWz`e#ShhCmJI}R&RdpD#!7Q?Wwd>^6M z*{|q;_!wZgQ}amO_hsxSR52wn>+0d|?qVP1rkmFjqudsHf4(Uvw0DR~89c{G_Td8; ztLOtVh&{^h=`PrAtUl-z8v`D#S3&|qAueh(F?uYLG@THi@`r8F!`S*ny2XCe+9bmd zMe!D6bxT>>5{~!sjL~7(pYcQ{R`Qp9>O3UGrfaX;exQ^z&`s)*lk;$DoqCvqoUaId zo6enGra@Jhs4elvgIr9^uFQmUr{!AB%*pZzHseuSI)Y{`_DYp%i45~gabdw;egccL z#8Ajmu$BBRp9V4Dtx(gK(9afsDhlV?#hy4CjkhjxI2!XxD9+Qq&tZQZ~JVo%JBgLkeR}Rz^QRIQ7$IGK|W{$-uAAehV)c zl_+0-g-LK4E}YwB*OwLj!leGdaZoE7j{qzDlKVo_>x{UWiL7zu)M2|yDuqG1TA<9> z<@cLE_p3YaO`>f3O8uJ5yJFnc%6;`_n=ZDT$o6n4vT?xJy6tF4OUGHNpD~HqOwPMm zQBT__1rEoyvivmkd@+-ydl>wNa+R*`5svCP=Cm`1eisn04l$7{j6bdFy4)9x7NBK>_EmO{4Vc0k37nZhdUDcM2 z=^9B}Z*Q;kh~#sy>&9Z^zUh=AZOlGhb}c!8R*#m*lak^Q!wE}fb2KirD+;TLqS04M zcC;#nzL@#N@dgK6|AJB);utK;=#0OuoIBOl+U&Z;-n(X=fInTOk)1P{0yxzuaqdsj zl=2uL(1H*;7IuDBE?%??@k|MQx=dJXjQj!w)iwis!KK+`uItnQ58)r*v z^V|bh8$W~F0kw?DR4ij-prQc;4HQp6o!={E`(n3~ZZNjJv7#eEbn;O41K7r>aI8}S zNXp=?9uM#J6aX#&KRytfavLbgPdH!J^m1oKQ6i9WkBp#u(}0KFNNd-In*bf<;h#*x zN?-#|yVIYyGD{PtzjEv0rpt8oNsE?`58|Q~MMvxGt+!U9bOfnR&X| zj%5B8?(~S`QtvjG!RustbAyyY#t04`Ps*7mSO2qE>jVLrpLvnM zle;)<)T#-m2|tg0hP-1!xd#7USd}YJG^0S|K?=^!V%ppz>QGb6u zF6nl{yf-iX1#=SRYFv3to1ht?T7J6i{)+C})u++XYuiuZj2D?LJ&3&)Z>LN~px>zu zfAe@GL}^Ad=?h85h_g%$$WFf}3Z&wU9ewH|M7~(i?|ZM)G!jG?dH%Dfs3VF{EmTa! zAk|vj;9`N%qe&YB1@gfHYql=ScAq2VykaJqCs#RzimeRJHkpa~C+Eg{+#z7RkRJW)sK|d5@X_zaS;PM80 zPmvLX2lel&=Q>K_ejkF^)4n#!i500@B*7SN#G!eEG(e~*RbAAW+?Fn4L4IkxR4Q#? zPkwPqbBAV8QG>=;PlL;zZ@6K#T*BW*Bgb_25chVqF!=Fl@bj^MfxM1U;UBOVEx}*L z=F6%8o_Rj3tK$7V=vgb#FDaGiZC&T>`#qMJ83f8ll%mmyn?G&8nEdP;aaSiwE&S)^ zR zqA%?7;P;O8%0;^Zr|;Etv!k*RNPjXY5-VDJ>!rmraEp!R(^m=ax^gAMx5~zwbb7YJ zTd;tVd41c-ea$8khPx&T7FZXz!ipt6NQMMa0(!fm*IP87b-%eB$JZ`3JT5gh79(i{ z`cYpEJvsc{S0Z!V0|V1^-|=IW{<&IO1Q&QF4eFzOQ_Y5>`#B4~eu5ySt2X`)8k$XO z^?O|Uiq9AVq}5?st+~n>fe?jn4;~(?mwLF!@5JwJbagY+Z1;XW-7fr|)mzMw)Z(}Y z;;7aTkslw|**l~6sajwHK_Q<3KOZ7*L=Wg0?~d63Hv9NV}6KE6Ra?`jd$9+nlBkJ#7NVnyMk8~?~Z1(G8)e7+;C8We5v&) zeT)pgl+zy@Rqw2*cUmS~|F(f-N7SF|LPwaDszmZ>jZgWI6W~FZvxrmMvCT;R`GYjt zSoRvNO`liY4lUo!3st!4=}0A}3zX|yBvg5Rfbyplx3#qnjhf_g2pvQPBUak(%pC?J z9+T@p*#+7c|1^{Xc;Zaqo3r}u{Glum0gp=+J+jQYLbq!l4lnShdgIs{n^b6V+St4n z7D{iwoN1yG2(^0If0?@eB&f3de9_Kqud@RL!YJwHJN53f*LeIKOBWh6!&H8*H$U6G zy;9t=#uG3%#Ere}_m{HTE8kS9*VqltU1%nr^M6Q?z#31iu#4v!M`=F`^ zUx66%CEu3KH6f`hCNazF#2O!zi=u6r(8e@+=Of`g4Mu4`L`3zEk%RvHGL3#QhYNnL zbkC8i_VsC-y_2AO_2W;&yQ8ws3)@zUqvAet%iBv~He3?F7#$y=PG5p#H0>xOKk!03 z!#>A3y;>-gU;;udTGG1D=ePvI(Y3zQK^c{vFh~ZkUi7{|E7E1iCpCpxC;)_gZdin> zRcm;suP+K*kdKzVBC#SR&mWQe!myQ;9XH8|lRhWYMug*WxL)~qWxM#fK*K^RH5{fd z;=WQ#3{#6x2B#k(zzciT`_5a;ma&)A+4?AohWm?T(}|7DQS=d}@;>-hw_5gJZoU2V z;~u563oBt0BiA(`_V)%FbFDP01fjWe0Z~FCm+*jHL!|;Ep8}MVw6^qOj5JrBjXv(? ztqF7VEcir1f|&5*j<@c|NwC$;EMSYJ8)N49YQ71OYNyu<1I~T|>Yr0bE!kmXHP$+f z>rL@5WsHEdd3IWUX_TLyubJ=TVzsm6;{xEEM#uab3MqPKUmLAi|B?)BDzf*Li}AIi ztIXbx@@Ct`JtiDm>(=F9m7xWdhlAk377-c+O43YPqpW9juQ;eu1D|&7ZxQi;AX0C& zM1C61sZR9oRxVpL7Qe?D6}-l3AANnlP>X;-9^r&$*%wo#+NPhU%yU}R=o^b!eT(qS zfZ{Jza0`eiYcH{EFp|+>B1Wn3>$PZgy@;CPAb1Dok&%R9onkx?U4t7Hh~&w-kQg@Q z`^jZzTLaXQ>Ctj;Z77jhp6e)b_pA0-;Rb`b0hPKr?!JmXoBLxgO!`;AKrL9~s-nUPy!E>-eqO_T&%}xg=aR#*bDZ)y{ectGzdHv_?0v`!6 z<+MKR25B5rI*)is`q%HI1m>T9q2{KPSo9NXu4ci{im)M0K6BI%YLZ!xX!r%wxheMi3$R)ftI4aI~`P$T-R1_ zFx0$WZnnCC)I*>(b|-BEwX2u-Q?ux3@Ujpy(;Z!?JML+3$NOvo?S!iKrjuD%r-LU@ zF9A<#%xyUUFx+uc5Wepd6e4{YN1!lLYBAT=%uGF7`EHMvde}PYDoUd493Z-L-<%09 zw>XC6!+Dr`tGFuFIMrOQcE4&wT0{Qo&WP*!l^9d!Vb~~;O$> z=ql5#P>GPF7Hz>I;rd8!9rjeAHl2~4fTrf&|KDDKH*wf%YQAf=syLttPFTQ7um9p6 z6ax?D2-r-19NXf~N#JX{3su~#bgN5iQMBSWf7yC)pJMLRX}Rs{=WMiWv{zo_R&_P;e79@iJ+|2j2#w1d%B=LjBuYe z=K%o2+y_f-~P_(W*$){ z-`u63-c`?8FEL4@YgoBQvX@}1Ry=?9P*zU<%{3#CVTb1u%02A~y*4XfO@{1 zD&On{%6h&Cak!2JYaV#_;iL;BU8SO$M!_puPdgLn!+9b1HG)V?+^a1{6}K(((Mm@7 zckdt}q>)HEFa<0ihFiL8nYlObFU&0^ef<-M{mkG5mk$Qd31f5Zd@^h2Sy;}O8XHP~ z&Qb{PF$|hWP~Ib{m42%R)tA8_e3|IvLW`1a z08=*H~bJ%#boNr|DbM{r=Sb@a~eT({Vjor;jdETU0)$zG!}NH zB#W2Ikl#vN0>L}h$t$zt|G z5b@XPwX7NJk%UHXRCXEhko%ftAv4EJM$QU^6rn^EL`67So9c6DoEqRT1$Ony?hHR>1%6=|D;GpY^e=C#}%D%2^8S18XYZgMR^0|9ET6~@Bk zxGP*heCfw&zqaJTnXDFbI1slbe$Omee^@R1jm-udAk$hTEbA5VfAGL2?$Mk4S!HrO zr!2=jI%Gh?%+>tzkKmwQ34bVm=ktk%ob)6wT6eWl@d(B0}cY%hc4erZuV zCdQ)7qNkn0y*FRGqhH%4>Oq8*Vz0X*v&V{Y0C=Kj*J%GJjlAq?4^;OuSlirsN(ezB zbb^{!aSjL3QF74{uWHSm)4p+dJBWYaraTOO^9cy8?s0WrSm*X-*E8*SRJ_>f7B9b3 zS$0j_P88!EeSU!((x(-SW;^St!5A$3E75lb%pfFqb6isjl&unCxNqO{m&8BK+JIQz z3k}YKI5{oMf~9E*-lxQCA34u)ZgzjFAc=PJAs?yOy=N#BkY@WJj(F_Key@Qp;nQQj!;oPQ6^T5&~@@rP6=zlI7cP_UUJtIg>DI*Ei-n!X4T(#WMixjJM8nEzieQ4O$pO;zx=F04 z&ny|!vK-G_TuJbD_9U+NfJV5-s~@SFa(+ou1_|E@SE=*C0tV|3m%UvotC|n;SEP0> zh6E@gmuA%t*)XZZ=6z?ESTIBtWNzND+%Cv{`J2nD&$R#MP_B85<7;PdM%=6JR(Bnn zOGcH32o4~<+Z$fx6OgymXuAs#kEPKCp(Rx5Fh{OCZ{GtD%hr|H^J+KhD>1mt<>_&) zbdU!%61P#p?*3-5z>lQ#tSV7>P)$0kmFsBjG4ID-JUU%GQxaop46Bz)3AKoQ_UFsz zFZWJdO$D#1g+6%1+>aOe79+-ckQ+?7~)eK`bB_;ATPjI`L&mZg^A%2hAHG(sEj#b-m{#==`KqWtFc(0R;QB^I4K{lAzNRi6zv_9Pte#J`Ctm}e zKDm4{jLgW&o{o6MfhmWeZ2a999luPXccapYNg_}2*T~FA^zejnU+01nDXW6>#v>iz zcsF}89DvPUzjw22`A3m{ila8av-TMI;R|6anF9%CGc4r>pB5c)zdwR&p1i5x zfc^RSv=p&dx>$YRMDI0dX42;NBC}|m!$@HTN7q=D_)dCu4W!I=6pe!XTvVCX+b3>omDu0zR@~HKGC~-*@#62no zYV}j2j^xf#RgDjPZU;?{dhhxex{VDt*0V@@-@A`00bZXOBkrP?tC>_DBTXZcqOPtP zb8O%FCha}*AlTPyTe>K#F6S!0a=kHFg|1EA`K`l>O4l0Z6b%Gf<9ux z*+9h@L2J6k#s9|W_Fj9q@SSa_*bF**i2Sg^Rq=Ynq%6RA@vAJ8Q3=(r8Lzo$*4{%S zP&y0y%m3_Vw^V94hRr`!upkA7wN1@co31C2TiT-0t8g^zWDWP-X1fN60R=L1bkt9R zX_8D@;!N6RKhdFxtc>=xj|9pd_FJEMG|FAS33}RSLE1!?^umr=4LA4{zHKsXTRGEy zZ78Uq#6?#d9sBLu!Zmzn$4JKr6?)}f-w((lTNj4WlggM+kd||(eXX=qB0pV}g9qPT zda2r3k@=F|>~4kMT&Ay;n+>2?)l0IrOAaQ+iJ+*C5+x>qeQcWdkdoZkZgy!B9H&g{ zk}j9YcIJ7Me(O@Nz4>DPop|UA6+_vc zke%MwL?1|3Lqsil0Jhl4Z-)4w{iL-EgDmZRmerF^`KsFdSQs)o8arAXXeq{5#Z1XrL^3&8v4*QfBR1+>a4C(%k@7y58}QeO&c*r5QOkdY=#jNKe1}cH z_oT}E&MEK7NN(0*C&NgLcKzD7?8rTS6r7B&Ya33fQ3b1<|7ZZ}B_p;i^@J+GBT5N; z4&Y?A;&EL_vzjG`eiM7dhb}vX8OUhFL~p)WM|@2Q5+=|HD9w#=;eSA@l75YbJ#7~S zACz3^PbZw11T-xN_q_*bCPoF+22LLc$V)iyCUS^A%~6VAgX7 z%tA!~6iDO?J6`{I!{DwGUQnyEZ0od$D%M3GK|tqNRRIH${N0Qb^`B-OR(+zsnsNT_ zk$GA31_3D*_-}Jl41McGtSvWq3_>joN%3^`XQO8mPF980WWKidI9L-|o{H*<*674Q zREX$jBQ@y5S`X-6=ZqPnZjrd5?Ir{DP<5W|?g;TvZnX;v%ulR+#Rg(@8@H3Wwu&eU z9$>yAG1O7X0^r}zIP@sl0(+@$Dn(OUG%~a%-(-_eeXiMmTtGA4m3xNbqXtP*x{O!k zp>uJJ$Q1!XvUKBb*6xvM zWh9{b4%x7%DlEjHV$~mOxEDC#hZ&9_0veg+97~F5a$!v7<1mg~*7pO%Q}1XjVz#hf z8DhD*tEz+Vt%!ZwhgSUY5t$=sjjef?uq96-EfA&HDzWZ6-?a|`)%c!9?&=C2%5^4? zF&k44b8}y|feoU@u1=qu0OfYg!;$*vh(S?$51)SJwIC)=bwK_H@0=eITd8UMEwFH)6%UcEnDxm5)@7L=d&(Mck$9)47k2UDgq=zPvB~4}VUq z4)26z)gpeS*gn;ZS>glX)QgZ%?8Pfx!vdT37phqe2V9%K)P=JFvNs|Dw=RBFu`lfG zO(GqhBH?nI$J%kfSI*lP%3o;&x!J@RUme4&S6vD;-n`RgqjwT*lBNF9lFt6nFmC>Q zDk7sMNoDe0lIlhDH@Ty^G){7xi9HakuiRj#@enLbqhrYwQGgU8FcK|W)vI^# zaA?>az>1UWtQFN;R!vDF!p*GUC|FaWyH2M~+Rm3osI*Pcy%KZiNKkbkd0_MfVqri0QYLMLg>>Jg3&uSm6&VEBLJ<&m}s-pj080;vp7(xcWq|;>*W1 z9<_cZs?&egR&>75^9$fWkZ=J_<5P-`7)lZ9r%gamaU=66&VLv!XUeo+wnYSe(>>+( zYfs(h-tlwLq=|kdASjrtNFVi!hB??rdwInN9Dj-jl(U@*XJq`;^!Mdn%zz9;OO$5r zz3VwIlcneGush*(8JELN&mgNLZ6kB@=eVTUdPaQ@LyGk~RuWxSDnH!}Bzm>`Bz~LD@BuD6ME|dh-FJpE@k(qy9{|ZjsZ_VZ%bjBD=(iD zhfm+0kl@2{%`t#&I1z;&?eiV|Oq@Kr0d9N!tmK^S+txDrd(f}lE_g1FNK%22Sv?)+ zb-XEq#|@ds-Y*M%^nj1f9XD_8V78h`Gbvzg25?w#7T#%Pbsk%Kc2a;~n_{FaJqtI9 zZ|~OY*JNOuAMpHW#>n4+5lS%^ zPUuw%cHUK!nhD?dXzDA%vq3{Y>fGSm@4m@f8`- z7QzRc>|yzhSM+(O#F_lmJoiz6fwiyYb4?O{a!NX_=Yt;ET{ES|;4t8@CNaXsoR6jZ zwe)n1A97IW@*;7|(*=#Mi)L746R^>=b<(*QnU~a7Iqf22`9PEl6)om}@gk<46%&WD zGV=-TclH}Ctl?^=Si{Pa8kfA*F9i5{4fY85C|kI#@NE-&htr4P?9R%5FaO>E8WYYM zN6kF+9M_crhJMvKZv*{dg*wvUq^+s;V~R$M{&W1=b*D>HJnH78#q&v=qfGG9=d~Ij4VMuqdGW9oIE1J4`8_sq?nf#2P+6AvR5FJY z%O8r(7NeW6s3#x!SGH0FZm9v`?miRqB?!=D;6YW}L1l?)iGa2Z*Tq$0xm>m;IabF= zj{a73ktTP{+XsZbc@ACS1%Owf;s(=YlHN&a1Hr}4rPenJ*HA2ghU{!OzHRVh`p;${jos*Mc?Ey^_6KEB|(zC>p{wiUItw{HdW;Z$-ug&j=?@gnr=@%Hlh|hOI z0Vvs?!p4$I{RjO3I(ib4u81>1#wgD%7Z}y0-yW}PG)eT_ZE6`ME8^`krKOMI@K4+2+z-MZ_ z9dgZ74bEkbC8a$6hha1JJToF6x8C&=v`C8hpK5gV6&NH%7h zAs@}Ey%%W4&=ZP@OC!1rKRV5kni{xC`nHS2JGXu;;92~nBvY?y79RBqA8exRh#PD2 z9Ym3bjXV9El{VHe=;aV7OXayCXtfpZG`ix8!4|fEYJeK9&Kj(!RsZ}e-*xTYh%6;G zZGV)=P}v-U_UX134HqHgu}EWN7A)S{Y0Ls2u+5kR4&F%ddv;hI*WI+l{}`l$q+=KY z-{Hs&kRkqIaLq4+r6+$hG*@jd6l!U6d9=)K?54axJabYBxL6=oGRCPEF93?0Y?+gH zhciai+c&%KJlC0f?;K2W3(7uV(ED&=2h6CS1FQl7`~Pg|w-$_tvJ#G70Uc}%oLM?N zJ_GZ6TCQ0(rpPjHgX5fVeYu$1{kmHlyq(&5TNUqiy=4|?ozORa$=MywwEmv$DOagy2IE`1)rHQRlKx|3cOI=jeh*kbjP zKTU7(&-DU*QsGn9s%0ajxkXk-cS#Xt*M8nLF%Wtr_NV9P`y0O^H$q%e`rF?KjnOL! zed%Kh)^~@9h|IP;XZ=BXHJtJmXPl2a#4-mJLCK-7&&ECU-KFye5_v3g&a;=&{yd!Q zFbJ+OeWms~l_+IT1^C!K2X&VH*RV}9KYVd$jdtVp>e9=5G95?Pf(PjyjPb|I=rrA1 zyFhtle~DE$JCP=xH?ItggHD76E$}(~EeWvjWavT}GvWsm`&)qma&HCnA$#PSN$ty# zv?3#>-==U-I5hAsqkOa9$Sx*a45s9I9s8NnGo6}t+Q$-XSskdZIQUK$}_sH(tjr_H2RfwuL zLA7zBh%)7B?bpzpbiv_R3srF1uX~~d0;7q2Svwz>a{w!LaetHm$`p<1JRN{v@U3K% zV>-}#hsAsu9$%JojclEJm1MT#`uh#3wCPE?t77ZK#mcmt$nj_1j@fP-dOw}Z^`|{!mNz%WrF%_?%ES%=Eg${_ zNcxwhy;pO`P^;-fI0`u?55GZkGZ)IdiB=D(?rCE{=lo_va`3WQ9!dgc#8QZJc&+U$ zehFxRE`1fN!4ERfTUF%9N${du)Z_D0^i^x5v_@B2(#7f$7TNP^c_VSsyarm)TJOT{q>H)2$M7>+L)hni8g`MAP~bk$a5+3Fiy0yH z@~Az%LRB;k*sgcFL{619a6hlUd`;xx>7rvk({h_4WaZ^X^Z;F6i0wILkQgP+HLiMn zt+D<}o@8mjmUpS6#|P;9!|GVs@i4+0mml7>DeffJ<`Q;yGRO|pba%0$(ee(P1XCX3 zQtbqJ%@)-FiHup@$#8ly1aMxUQ|1O@1Mr9$&xPIENs^_7u1wkq@cIX}Kp*9o2R9E< zT7oiN^$G`%^Ubg~Wql1dMOUx6W_l!u4jc{snYvpDPLrtuppceyCRORRUBuc}l+ z`I0u?gKxbRU&Z@@*rLkwBOFu-oW_ww(%uHJnHm|XDc-RhvGgSyPoGnHU4UMX#y>pC zyjdCM)`v59ymuWxAAHs4_;4PQ+uPB^H1Z>wpTQ`=R~*84A}Dllz;_(G5c2!KNTkZW zKhODRCr&#ulQngI4>x`;C7N8N?!6oNE%aM#AwZOQVHC+s%3wyuCX|q)aq~^*mp{M) z{=8PphBE>lD%+30KmH7^PgC@;yr7tSVSUEw-L;oOO5wbiLbMDFP7T zNyPv}1iC$HBP7=2`jweYDC}Ev&nDf5pC3o_(W8h0Q#g|k(4$g?{G1Mevyxh#cKQ!$ zrF5gN>r9HYI81e}*`^O7AyMAJGo3vvpC_*lITdWs0;O}AT}Pbq7yJF3#@F=ZmKs`; zpU!TNZc0-#hP@IlE%wHav6O0|v*_pzQ6E0=PFK0?Xv3;8OROA#1> zG+OQ|@c**a{slCmK~L(sdbTo#Uhd`fV8~VC%NXbStyVll+KdcbEl^wJ-CW*{doe~S z-(&37->8>~RZHZ58?Af%D8%FY^u5-^&fDW0AToyMlG@K9FE5KR(XyDbB*`s%u=%Ko#^7PX4$@;uYZ5@LDqPgQ7 zcubpLdroOy|2wjOgsB{{fYnmyl+>eU{$TK5pT0Et0g2RU2U#SR!*LfyD=m9Rp%b6O>EBdMdQHwlvQA#W8q?>-2 z<&5jmL*b(k(Bs))>3aIhd9jJSyv~i7nyRz)PKsF|hTT3^N&CDr+lqQ<7|T*cllB$8 z9FxXzuk@el8&ki}*-hD}d>Z9tpDntNhwSBltZQUXU8k&hFVxpU+KVlw0-{H0rng@) zTLsT@AjT8v=1%!Kmr~N5rt;^@0|g!pAM4vC+r1S~l_@I&TgmA}R5(IpVG)ym zIQ4XH)m#^yMb>`a5jq1jQNamYe5_h$pk)tPmaPIP{GDt&jGw6>!;Y3B4U$q`{UukI z?#4rdIB62o`;*k)k^Jm~0_>3j3S$I@VRsI4~%?>j9B9dH>gT(Y_Cc=Fx}b z_Ht{lyY+-WjRzyjst(7l*Vx=lNK)M<>wejQl$< zFS{xkDdkms^VFhM%hDX5eWV9mFw#5mm+}~6Q7h&-%(XE@od|fG=UWleCGh$2tVDT+ z*@4iY+U#0h+%&z{(+c#*k$O8=%~p%0r+_+^;udiZ2T06xm)L{2zA(t+Qe~0T8198**U^mk!Q9_cz1qUJ-o#$N!JLw|fd&NQxp|14DOr_fSeGLy0uf4MTT>ARyh{9Rovmy$Ah1|HJ!S*K=L` zGMsbv-e<41*Iw&h_u8i(;AY(Vc=z_}5>vsYW%bd`G-l3jR%m9-sr3>W#T=zNds&^s zjPN=?J^;zHN$51gZGqBJy?5Wdqi4i(nUmupa1GVbpSKbuf{=_O2FU|$3 zPkPCd-U$e*(7l8dna)@i`xk)QL~(sSyHd3Us#L*$2cvwv>Bodo0w# zEYeVXNtim3l`#>6mq3b)_Fo_GRp1Z${!^o#V1y&y9^FD9Q+O?Vy3nL-?(^L1$Zy{E z3kvJfl~-Cv06oA#*Vy*B!J4vm%!Ar<;CZ9{N=JVZ{{xXcWt;g1bviO!K_Is}%Av=4 zIet|D9lyJd7W28-`@=9(&2Uwu_yuF=*GUS=<>jM?zvkoxUlN*LDX&0klfJNsrkeF1 zbCl=sBci0~=*7h8at_3%_;eUG|p?y>#8? znPidkr*B=Fj1EIDc%Kd!kML0GyB+_Yox9GCtWNvH_D)uGU2%P1)oK->6hb2*h55y! zg#_E7&1Rtq&omCRs^=YpK+Nu?;(V#G(LmjP)276UpF#a7>I7QSkOQUh?jS}N0 ze1N3PR_#=LyG=d9_Jf_>-BAC5rejQH{Hbc?FHw;1C+8GLzG?2-)jnTo`o}ASt^lVEm^*XfTSGgUZ7&G9a=?5WJG@Z@(}`cUPHb&;dAq2cusRL;R6aoasoHkoIf#RUW3TB7B?4i@ z)-fXl1=mvgC$vZT@C5TVp9@D4u`I45uu0YTH_6y47ZkdF;AcH`snwTjeynx8=*0@{ z?igUfGi%@pp4&jwpdLR}2|};JfBr?KR@NVLq$t|!GSAX+fe>(m4=z8n5tE$(grS(S z4!!g5#s>>=Hf9AxfYDIn1bk6{?1G@p^BF}fh8FL?3_E;;t zi6;Boo?C2>TECsO%gfq`_))alNT##8^37IF>w!YC0?pa~F!oOCIf1^nyE(b-6ow#Evhe_7KUO;<^6 z=)9y71sn@C$JVQHID&|v#0Lq)4652^oH&m)l7hzk^;I&l5hfd~$=`#%w^Od&kTv3L zVzM7w+8Q&#uwFtoRnImA%F|l=&WTL0^(~bRdX<=qvZQr0wkh`dDGQIMS;gDIgJBPTu^JhUX|vqHGquX5yERgaM8YQ?_yW zlgKvX_@D=dBnkl`mtqKZYa=aa)M0ewiG}Sn0-Y$^A%RyTpzwue#;{QHl;iCOJ9o=7 zv2|q5Sp2xdHb1ak0m<&2Vh5Q&KtW@2Qp{Szob7s;BD?N6P)uc2H4DWb5WyHcgV-0A z7s&P9#?w6yy+h*D+`+^v%QbMH4)&A>_L0VS+wi$$`AtZk92_8Rg{>~eg2lcx3%prA zA%}jobno_&Ws|s^Yw(O$a{yTLaoI=NHCO-1 zdfZ$zRuvV9IhusH+XXU3KeRH6^U-Km!d4rs?B0ESj}mh{ZY8O@npr*AIbqdB>v(7i zz^VX1Sw@{{rZ78h+PTX&p{0^zgM9N}$43I3u%A4fJYptHGMO|d4t(x_Z3POxbv}Q*F*-Se;?NiYA zc-#{pC2*hKZ{l`z>&{GjnYR3WYWW!!5$h{nn^}>QEW3kDD09LuF`GtP4n1GSRo%X2 znv|U#Ew zo46wmGe)JB+#j<#^QO-BC|1g538j;PFUfS^;9|L%?Jmd>p! z?n7da6O&V>QkMg>3?=hcJ&wDim8FKg1T)X9%8l}siN_c~S$XRxrCeADP@?L{5P+#P z&*pShO>PFN;-#5Qu#<*s9~;>Nxsbm!xF!MY^(Gl+Pec9pxHJn!FZ3tr_F8~Qm^5kV zmtluk2Gwa55B5f|&NqM?-^4$4QE$)zh#;?(BrA0aQO}G@hn+;fPU( zJ3J0{_#^Ij^vlrs@OgF4_#G7mMr>3CeAoUv()VIVHE;69%hIcD@-fbz5lAi9?(XQT zJ5SX)#$d9l&G$s$HMNUhp_-rq)6Y8<-J@CIt081=MH55h&@c~dJ>^ltQq)u zk6xd$Jj-M*1m|aMGf?rF8q04;=d+N4a~9mw>ebl`&`rJ0LyRkv?^j^)_8DOi;H8w& zK2Sp@dhL&+f}c;X0~u?e2-xye`?DRMTsS7^RgtyNrQhMiIyPA($%efhH1gEPWh~K= zEIVy1-n(w;xEMuwX(vgl`J{u;1OKM$00}U*+iN$1m_kfEN3G|QCaP2$n~f@{2;gwS{Jmy9+o+uS*3d~HZ_+3w8;}EBrrT!h^1s< z9>swzr*Q#w+A)Pp z6E){FER3eT7f{TOK zM-?7sx%)`^1gI@cx$ew^YBI@>BThWO{Q9^8a3Pwn($^2pdVoszCrLxs9kE12H!Gt= zInZqiZ^^+S!%3jl@%I(|-SG+S9u&^2WwGVG?RQAYHt+OC04QuOnDiX?nvK00HWkAA zt$h*D<2L*KmuRquJ&Nm!o8_3>p931EFY#?Zv$dtk~s=c`&i@()0I_Z2|C zOvgT+JC~iEML2RHq{9CRQPBZ7pM`TaP?D*hR9D3E_R=418n|OgdKV{Dl00hBbV1z~ zLt7yphD~?r^kHJYTSYAKtvcycHV?6=)?v@bm2J9RAo&WgZKxkCH?q7dp4l&4oow8; z`&L(#d?I|g^Ns!(i=RoE>5Hk&Wm3(KP`0Ia>5snSIj0K!u1uNmq?hW=@C9_|@F@I) ztg(1NSj8&lKoK^H&pUx)i7op;K*#{nn?wjUXU?|Ben&K(0GCs)TvNkXXx5#?LLEnjVNmPDAwI2uX{AH7`Jp z(pbz;kDl$(5W%*avQmqxpEQ@O3`A?NU+w}r)7a14Gv7mbpV;N9=I$i$^ z$Yv21Nq;ZhLD(Es>VE&J{n%Le0j{rZJHRErJp;(^7*xIQ@C(U0dy}a`LY(4mvkY^d z+f24j>Gh?fV-wHajArny1iza9!ZCh!{P27j>xIB5^AnMAo$pqV5FGFO!$Bw(ZlfNx zvY_?L!QH(*PFEBCo4sA##RIz2H02loqS;V=&~xRapkoa~~7=zOLUKX~VbEvUBQsXLRhbhQafjjVC9N_!7$r76rb@*I-Y{x+guknjN z!a#X%(*x2;k|T)Sn}(gv_<>ZuzDR$&C+a&$vbLE$$u06Q7(EC$!%0N(+X0Q@!$%kl zm^*^fF*j-r@_)8H43d-!D1$m9#QZUrTs}#pU9@+1c4pljEsg=DJ~9jtqIKL0*YSjgNKXMxh*ujU+n$48<_X%>{3j+xE0RHe-}z; zk*U~^_xKT}ugDu>ToNm^DvmcgetjP5#k=hXtY;{ly=i2<@c2{olF|vw79Fxgj3>r<`rKpB^huBwDzCI!W5#+lWffpm*O5 z*FpLa6HgG3On&58q-Ty)?(4Me37hy@scyLa4)$aApluBet5ZuLC(CxG+~xSclzF$B zg558Tyys=z{`C%@=_r(npz5%>t2IB1mHu$?EE7o+?zi ziv+xl#*>{fa_2|Weztq&Y{-0F5h3YpZZEr`N&9w{Pe(F$laoL4PXZT%Rn=S7YXpqd086hK#48gLg{Y9FWhQ#qXx*Gq| z&iWYAJ>#QJTPXR~s~-%f&gAq}Hy#{Ne1JK#Fn-j1y7E=N!+{>_Ve~ta z{&suC!<}BpqXIM&%nwpo)kn}LH^4jT3qCd6oj;{2X`y}+I*V(NFeRLf4g!I550So% z5XH-q=W$Vo`=^3kYQ3Z;H8yJOFS;82k8E%Mgk%M4%O_;lt`8B~3YT_k_%cO{iALCs zY({*xW7n42K6*AbW!|_*i(k8&cH)-V;lzrips@N zZ;xS=xjGmRE})TxF$xmC^|#JqqFTGX8U%CD9pYgt#kW9n5p&w=Nsp5iGBM+dDmXXCc zO`rY~)&54ac(0IB6l$}pzYebr+9yae$KA&he!aF!52+;Ju$)qt7Iu(D$uYBbYT^hT z9ih*Jzv>YfDt2xeUdo)D^#Fr`=6rK7C!im*i+%`+1vy81kyTg7#H%d~TZJlOJ!-9N zBWM>SpNodP)TzAQK^8;MKBwD$%xrR*O(cPh+ejV%-WlLWf~($V6}=&pbU=cqs{2$v zb>$&&mG7JOyo`l9w2H@ZBtu+(g{p7pJrvSBBLi7kdtpU&B+ zfeB1#9{z4gpQjJM!^X>5_SXf_urbzu^Xl#6XzMkcNU5jy0~UD@osXELvpIHYf~O(* zRhscb{KaKnA>##K2$rf+dN|#Tuw@D*!j{U~DQkKO`TTK9QJWp6I^MTUU+3M<*~n7d z+Xqh~l<2?~m;TOup`ReaHD0m&2&dI9FlXht9pe%7Bg&KTuRImhrpl$>B^}cs;<9UP z+v?G)cQ7W#pOej-Wd$2CS8XK84%{qP!zQey1i7|C_vi=ylupI!hsd9YXe>RQx<+DGuyC#cUOFu?q0V-Ht1Q(x&xG!;1W7T-!4gEq657 z-A+#?R^`eTj{38qXSZMyc??E>i4;|d3zW32jQU&K>sj@@HVe}2>_k4FtL;h@(7G3! z1QdhDs}|U=;p|xuD>ey6nKl9`@SLLJ{gK#G92nc+Je&}tvYY*(m8<6!lziFrKTeA) z&u?O7wb(nI@#+`mOSb9HkX=UWmQQEUrUp43dVBN6f6eWZU%hEy$|PuIu0&_Pv7e`4 zUvhh2SJc{nd@sPD%kNN+QrpI;e2L;2ghXB@<+1aE$JKtpD2HfF z^jz94jrA1Qt{id2vR0Kz^+W~zN+`LZ6?fU|Gx{N*-tII8?X^L#qt9(i!q0x+`thq2R|;vlog8u%YZN_xxH0FH6b*H0Y`l$L5Hc{5VihD$ z($w{m#!&nZ@z$dy#7c!j3i*Hw`(IPMensdqbofuN^ul)q^#mz|Y>vP5u*s0;StJM| ztUPX^Oo)c7VGF^CKTd&!J>aXxGO4G6dZHNm#05Zf4FVm@x=%ca6eY=ZZh^@2$`kXt zoN`-cTBGCaX_d2{yqzAJ@=Eu*ZkWoO+awet5e807I5;)DI>n+2M@>zP3=tNQpI)<3 zaw{!;G*Lw_7t2U=Zh3VzE`61Xx%ZfHavu-qV)N^-D5ycwTuzctSTyaIi2dvhU7iys z+SSSVn}G7}D%FY2I;vNGyW%R6y4J}B)c;m_voaW=R(;{s2Nq1yUfJk)r!aQTL|I<2;JX}Fz88Jr+lJs=ez5`d1CfR+2k@0+)AbP@jU zNdLPw%oj9tp*VqUg+Hq>sD5^Y)vZ$6H4QLw9$u5U0+*frv+PqNoopyY(F^a z2LIEcyY8P*E3x}_!ZJF6_47%F)RvsnVmgx%Yh!|YjO}8P(3vK%z9_YRcU9NN!Dr*3 zYKMq&zu<>Za6Nj+-?3nS`xOB_Edt8Gj19b`%XvB^ymsSAls@p_O-$C$$Q3nQHHYs^ zZ#4Cm84P@ z=#=>M-r=>&gCyi|JgQq~$)~ zCGJ8b%Q!w!rd`bQ#cF30h7*_Q;3{qo9KsI*e3z|I@nOoz6mBKTgmE8h90)q`r^`}v zj1hJ&9Dnn;Y$|M;6ULFj0CS8Fys{sN>)4&|e8=ZGMgELuqmrTF zrx+m+9St?(bj~$=0R+uQs31pQgdrFsj;?!R)|I5?#!k-__KM&6jM4TCYu*(sYj z!o4-hp>scvB}shSkQ}8JQHU_wegnazTAmwnlb3g?s48BC(sai{{b>+yn-dX5oEN`~ zB9{VJcx0=V6-ob!jN#`O_4c7BCc^VWXmo(Fuv$6T*6FDg*pLihu|B3kNX#H;|J|5# ztu8jX@)f2dzMY0B`XTrspbS3NN4tabDt1F4@9Mpz`dW=3LV`+0QtW>04E5>iV()N} zjyP(kR(bTjpS!?os0Wd!fR6e8Rj?@CUj;wB64?+@gJ>p=7K`QZeK>u8k7M%aZT^pP zxM34!p)Sylh;bBW^}M$l8>}UBcWn)5W$!_`@&9%@MznaSz&3bo0Njcv;lMiJ4mtDF zF(zz&I$ZjHxB&mQ#P>J7;C7D|@DC`acJfgs3O&p8e@&?8DC5MP5l+i(dn*{IC>|z~ z-gi26OpTbN$b7C4b!?c2k@u$;jf#+wFpYt_vb|o}KOHkq0+1OVBszX>;TaTWF`iZU zY=vt>GDV>LT?uX;%WAoLJ4K?FpdP1>76;eN)X#WXRNwL4Qz{vyxI9xCDt~j*d--Gh zbq#p1jZ_ppBB4>Ad%%1v@?7OOmkH2+m!h%NR3a|6!4O5qGB~H5dX^p^ZIa?;-2X10 zMAZU2mCPGN?oB_KGp7g=M#296?>fuRHxSf=gGbV6qoJ2?bj4N&z|{1J<686(_`S=g z;2gd6AQH}nICi&b-0uco9Md8O|C-kG4;QeO?nG$8c=0SniH<2@$4Q>vB0IjQ@cn8Ozm)j2%GdDu<^8RJKuT1{QtzWNPp7>9$&dWf|jXgX~Eu4 z!&s%CIFlfufLf~epHXXx z?Os58lj=;kq=w!b0rk*U#rta~TAHQ0z$$RuM!+ROJF= z;wrrFH^e3tcEsCdDP34g!7$v>C%Va)aAR8c@ny3=LmV_W7q|l?6f2CtKvYm)&ZDhY z+BOb17Z^OISJkGiM(^#Y5Kc|Mx6$XiLj}Wo&MggqKyaN2_tF{4%f*N5^tMahoNcQoLLb0dQR@Kg=ry+Rkm*KhX>uU zZ%6xQzbl?FBM4@(hLfO|70=`N5tHaUxq07qnC|Bf8?vU0-m9*v2up%y9(RLJhvDMT zfBP1;10nJOawegDYC|cdgixW3s$KAZTN<`ET9rxZS<}fD1$(#`5>S#U=MK)a-%SK@ zG(|?m|4c#Ri|%FW06BV4MMF@r*;IH6x1&IuVFF5-3Lmu&V*vJriA9k z6iXb9^E%G<>o5OG#SWg|`c4lX4V9sVs>XlkD_rJi6e3fNvXYV{S1fgX3JhK(3z~z@ zd=g>+&bt8Pm*rH-7rXu@)c+}2T(V6BT(`?d$l$~oE?io9a1ie1#m7^yPeeuc7DQWV zrJY~_HxP@02hn0YI4eJUfh!pD6$sLDvlD=+uY((;=-Wb7cmA1>7F_o4f_lIVz3pL) zFG!Eew{C(n6}h2g8O9I z`5T4ZTL$(h7@Bp z4yS8{viJ~b*i_7aF8{L$?7yQ-`wTSsXnAC52^9$#$w!dSpqhMF@Lo?sF^qVdC*@yX zYBU4A`KFn*l))=ngShG>@)%n26w8!Uu%Vjn)Awx}*9G);(@W7+F#OY73DU^|YNO-= zgOtv6Ofl)TmrBnH1a{$Gq4*FMBhERA7(x1fTAcp`jL2NinkStX)~g8k|x6DPhlglh*X%aEV;Bstm9*m5NE z7_+^~`k&2e85|$r3AR=j!`O;|Mk$lU6(*+Va&mReE1)rL=!{KscU6{S{u{#Klh+6% z&E~|J_a<+YBRI=R||qoPXi;hBKo9$H}=J=foL;;Y1{ z-d@FGcw3OZDpx!pBP$sYX{9Aeq?T!s`#ERBr=-&T-+l^8#02sbH3m1ljYTDfjO;PyQuHm)ng^~tg28LxbV5(<@jo^}60qJ7?x3ZF%fVHrU~jXR!^yFLN) zgm_b#4@ML}$0JVVv-)GaIlVmExhoEJsqe-5>ywnG!}l%RAMOxLb4;$Aw5V3#ivpRr z*^F5-Vz^Ymanw|@`U#LY(KwU!wqA1?#@8~0I-MFjayI7}c zJY3moK5*_9-*9U*H}b4j)ENP-?#e9lVgQ&udq z7sH6KzI?%XL-kkmBJVHC;1WERwPo;lo$kp~k#3n=yWfQIg;^L8Pg%_WsxqkE&4f^& z@Drzc`*K_vwNlq_nxbzq4S4ZSO8!MizAtLZ;U(3dyPO7MRLSB>HeQ-)l|rOWzd3#W zXK_=x!wRV3^6Ge1UEnP>YX3hS(W4yM@r;FPy8pX@2-Ap=YSvn>*1o+r@pn~FreKBI z-`xS^L8GgJr(>-rT0=jTQ6gcn9+l1%+~Pumm>FQC@S zBGm8Gz(e)3hW}m`ApG~LDZnWISfk;`d$W!3MbrM&)T00M`rk7M!2831Y2g)_u#Y&Y zYH)Vq-BWom1gFX%S+`n^)GX)cvmEs_w<_@q@uHTjy{y=berDea5U1x z+%w5xT+JBbH;nruf!gE8^2hMnoH@5Fs4yvc9GfDEbZ1_9AX7$Qm;M9BtWCLZZF3!` z_`vbR9x}zJi$GuOn{K9rODJR+p_)H}mU*K@i7NLa_kk;xpQ`LgHaEC7MV8cHSO4br zB&f5B?#kshh7=&?e-5U%9QjGm&UCmHIO)`@R?2k|TzOzd*(^b;C8!O%ld(Q9s}x#I z(yGT_pKj~GpNYh=k@_zbGyFNwrC&UkzuEvMRl^G0jz~@GiI+mHL&E7=xnCry0JRhx zsK?0|1O6;cw{Ky6 zno1obKV+l(B5^M9Oj|1N>7T5XQQ%K=0AqHg2MgGneT(@%d^@q)&TBxg4<{1+M(tW8 zvzabe@gD{`b|W(UD_XgSB>(+9HfPiqe+RKROwHJ;_GHCQQ?OF3NF^Y z#t04yk3O7fk+LR0cId{L?)JV6HpYG>I~>&k-pyB3fG*`vqHzC8l8>k3hdJ0p|LCp0 zVi$=h2G#Enx;0@|jA)0|9~|2^s^T8bj<)x2e#AuG_HeAZJ=|t)eU0`1N#oW0 z-e>R8Ny-4$>BSn_TG85)V<+Nzmf7@Se!OX(8T7g z!K>f|jyWsL9`(NN^STC-ofStkCfAn0e6J?^>}1|L6$AtH0C zbCW-B)lGdibwM&=dZ(4uorJWsM;_hYQ0#Cn@D)&oCe%@BSge}ULYy5nOz z9vJBCegk~s4TSxGg2|7NbJMSTDA)Zg;oR@%i=wqE)}-{Clq1oVZ2`{TwJW1Br0z8{ zSJrhm1&dRLf?$k5#@l_HW&YxJZ8m{Mv5W4hv?B*hqI?2fK6!+`dA+9aB} zbyuBm;V3S}Te$i3ME_H{eK-?u@6(3qeBq|KPNszW>Acf&j{Z_>j9cyfl>pbx*hfFuViM~;|o_R)_Q6$2k4*E;Jovys9R6(|+F_$>T!L148s0uF9B?Jw}A zCj(wzj`4AQ>l0Un+O?p~U;PbyRz3DBX|nTTzUpm_Y}YZ5KQHMhDS0>Z9RybfjBnp8 z478s*yX^=ZrcF_l=FHOZFc5k0cvW`xvK8zcyfW<$qBx>daie6n&4i>zU<2)M@)s9y ze)H?5oR@tm!N?eHeI!Se5$L{Ag*0_vg`dV_i;CEx#;cUWcy_;k2*x-H@-q;#!0j*@wUe-}o5eM4K7y#I$QxHC7) zmhoN_k2_yK2ab{=Ir~HWpctw1X1>01D`=Q5f^vsjkbaYmLTMzO~EUbyDmd-hLo&yv)WkzOad*2aF_-vm?-PzO4XqKo|93pz92jcO%V zV*q#AQRNy1G{Ukk5!q!>#J7o4#yToFx5wcR)1QW~wEaU9qD2(CFcV+kw+l`@{kGL8 z%_#aUZX)Vs=v^bwKq__3fxy^*4euJhG_t*PNB#b>BX&g$To`nf$sUl}6zy{tHmIvX zhW@Cc>@xK+7289>eo(aI%i=wwnxa68X}6d6^c<}M548BwjFe zLiEKOPaW_?dx?vpnndkC9_eT-y0OvM0e6GEJ|IObAb zfL@;zx;&0j&$Q1w*B^lee%wwv4o|K{*TjS=N$Zv)1@Q$u9%e`$>`?r5C%~Umf1FH? zXKo}k5Xp_dJjs5=ks(>@@rj52uAyRJh4a(L)f}Qn((V^)BisW*r99{-VQ>FJAGwdd zNR1EWUK|%0p^m7ap2%y354o9y-t;^S!u8bGDSKE83XSi2eTt>s=!!I7KBD6xxFEB| z=)f}qjdT=eb?qq}TJDS6e>SJ7)z<(kjHddPew^t&^m+y+ z%G-yKQ<<7FDL9nUqM<%SNw=}^xEE8W2T|(0NFG`}Xof!%56yA$NW=%4WI+D{Z_73W zcE3j3&W%uIipHk(5v+&F{8as~iaf7c_XT4EJ14RhAhLLO4mz7LkH@;e!tPA-N&99a z?+Vr3&+8I!dXG0{>h;nu_fL3w8nTDTvd_0tH8Mzm*8Rw@a%*mo!KJk{gai4l-@Y}h z%nok6L|+gvd$q|uZIBIK%hh-2urpq_qjf!Uh2o_oQl6i9?0qUI({TM=W9fXI5)o?vEuy`^mVNC`wnhMSru_VUd!e9-_rX@Ot~P!b zFJl%f!$3+drlO~Zmul;VW&;;f344jE?3;VzR-s z`$-lXyj;_7Q(W0oJ$|*hGl8kP%W>o=f6`FboPfOW);AvL(P8q9wn08!scJq}X0imH z(fdQ4>juk$HZMhNYJR$FjEgsI}t1j0~I?Sq7^1I(% z{yxava}m?3<*IcsJxm~(MmKr#GE`;z%e?APBmpvP(`PE;I^`Ku4S0DFsN@f$tE(~$ z+b=Nt8{nF3$x2CwzIyo`0*~Y<7o^kR57{_-o~=C-8>VE+d+)N5%1SW;9-Z0ftamHm z(d`{-jNV&<+<#~YXhEM-@V?oFf2hhn`QL@~|9<}Ut^co{jUgeS$~JcF5pE#qC1~dr z2idj1x2SK${$PtK0$4Jo%}kZ-gtPX^3`N!V&JQsIey2dv)*&A*9`56jLM^ z>+<-dM9>bW&dVsgl-xccfZkumj+#yV;i2aPQ6!L6oE=f#X~&0!=Q>Sno8i%*9 z@~>;|7kOfq!$un| zkKHCgZk_b)UtpGU*p7+(Y?%PhW`OGxtFW|hUzIJxnd1L-aIAtFb%m+eD-wuB_U~@& zBJnnUev((YAF)DRdRJ@x3DZf?L;TJAf27K2aX}&Bz|lfsoaO(OrY7ExMQtp1Dv2WL)`&Du*;YVHsh?1sU1xf<_-Y#E}EF5j4*mso>oN6#d~I#^>Fon+pm1ma81^h0 z#9k7Dtv#W-!>PKXsKb}KsjTD+SIAO(*U{jV?!9I70Scwfm|l5km(M6@oEZ$(*4D0N z1Np)w*YLF`bS-%H)aiLCHzue>oO>y3=HDy`*d{7Nd7{J?`cUxF(H_~@N$S0XZ-ak z>A_5)MWy(o*Smovm$5`oWk>#iLHX4D;#vDU?jT~jJl!w=mAXFrbg`%so$}t-N1z63 z8Mc{{U`iaAmY=Ve5B7yeLM*f{>C)GGVU5iH^3HyUmYGFxLxwP)<41$#e zaf>z&MB2@h%lEJrHwb)hOR8dJqm@wF#TW*di_&LBs@?*_?AU$<5A{Tj-`Fsm=13{V zD54QdLCTe!v~?Z-c<$mVDS=WvcE8uHf6qhKdC{wYHp}Nbo(1eYNHr+XCU@56#a_vq zyS{$lxtlk~S?ODI(x&wp}?8HfP7O|_!aK`9Xls&`TGAsE`DFi(pNtN zf&H|xK+0i+iZUZR-$-Efn^zA#t!-nc@wf_XH39MlI4JdDYC4c!XdAM?c`Wkux%lG| zWsq`!%I*UY@r&M9f=_KceBY;JERiX%>eaaa6(uHhsDD9KxQ&9Z63SC5L~(^$xg`z=&DN4rU7{dq_x#9+NvyWI19RzUn# zd+DpQ%kdDDFW<3pU=jYHg|WYv9s9$?i4iABc;^JU)b*}(=op1YUQt~3%}wiKBA!_O zVEs%eY(ehY#4w#RgVaf=p22M;u_aDJeUVt{8xQ*NUL&4QR&>oW)>-nz8z1G@#Ml-I z+4=eD44fI$AJFXJ89)vtz+c&ZBVY-UZJ9M2C2OH@dviT_MVF_mPG}h(UyH8wPON^T ztmG!%k#h6h^aPGC9yPHjECcXc6QD%yac~|JF zscq-o5s!ED6VL}DM`h4!Hd#F3W@-m#bH;Xu1EbyMA`J0!F@=uNPisvGDJjO6vUmUn z=zSxYb{L8YT6DbrfC+N<+A3IdUx7|UqVxAn;B3}UhXM`^D+4fpjvaaUNOIRDEOCUc zkNl?Pz;EzdwY$spi?jo0R8-koP3dK-cge_(TtZu$gM(k0Q{ps%%g5HA>yO`1@K8*D zWFiM)ivfza|Av~{Hi4)_*f4H+zIw&A5ifkLH~D<@OAFwu@qFI#I<4eF!?Bhs;(I$v zuK_?#{H6soJ3vJ21LHW&VL=6;2R>fC6XHFO;G5!A#5@RS{{^5|>CC{!^#KP68y0u# zrXIldaYY46gzPsE6pUgR2fCK{3vP@yDVFKr)@aATY^I!g9~zfV$NP&z(d>I}tfyc5 z!Y;ewG~DN`=0Aam;lLtTwEh&iLT@yTd)A_SK=!-Yb!k+pg4i zhR|0N<%fG-Rn{Q9%b0Vno`cv4?h}dgq~r+4AVb9?JJ*P{+WEJs17z`yY?Rte$S<6! z@UfIvF?+OZ3sE<~p&xJ7`6y}9gOH}^K=@?(Of^v4$XcYs>Bvat)%F`5>#>x{WUUQs z373UhhU;JPQKtuwUD%KifYhtfVXUVt+44xA-72xTcw*=rV_ zEM2F#I@3yN=M@NT=1Nt%tdm=GFWESbaCj}{TD^@|*4=cq*h@;)c?0EljGES>LHa?Y zhVZz~61i0EsDCr!ta2r|g-FS+DCqPXn zIe-c`>^j|Y3Kawmus!!)$r8nKFPx3nsvWtxI$Vkn>hP^gZP*yzuWctyQ5MtUm*#I2 zt38M?12U?_F|I5)@-}v}v9Zo%v4Zq{c~zl;Kx7Hn9zn&DE2OC{y+1?Q@C0r={t@9CM*Fr`*6*cH zH7p(;-mzk7^D^!K3=I-)`nhS1udJkYd*uGBnZU$!_9PE&zPp+xXh#>9QZK z;x&d^jhu<3wTU^L5_^Aj8j+2=;3a5-Lxp4W0-!QnuMY43r@6b?!S~>bV`5-@N0GiL zxY?_0BNT0GbugM8FlC+=ribAZq#^2*un=T+b6J)P^uy6|GuP+lM8h35C zLlm93K_Yn9sgHac07&fOfMP%_r8PnAjm}L@R+_2so1I@cA8q&qaY+Ujt{)NFr;b$I zUYkpEy54qG;dkgJhC;c%65Zw9ZhPO{G>6aMn0U4+(j*XQKRuc=q-6;mGyNGxlHwsy zcjDivYL3~%lx@Dy#D3jPA2?VQ*FQ@TlT%IL{`GE!&=o+3t=?MHRE3eK=7ek_S7|}S z)IhdfgbL_>oE~;-;=NcE@GFKioWCa(9224#8=`pUt-rs-(nZ-!a+X*Fx)nXx+9}?1{fY=W>E{26 zwN`gE?jC+UrZOkQC639FtrAnFKnB8A2lC#jHCN-btd}V$%A%k>zW6gbXSa{@Wv@$? z0~5l5&t)Zz@+ThcLB$AIcB0-^nzV>TE(0ADU230w`1!*6B61jTH-Myt;K5QtyUvX9 zwBJ`;1NnNz*KY)xRds!Sm)st2Ha6|gIzOh?pzL}5)nWcL`vrs+gl&A^^?$&O!HPS9 zLnyBg&8OFtDjhrXl9A8Dzx}b*#!cW7y=bPrZf*LAza5R!I|!H)I$m%e9*K&v1pbAM z10iEi!=hdDjuqGKM0u%g13|NQmCKNk^^n;ZmwKO#inqJ*IT>3!r4!1Rud(aksawJRwrX>00z`*BPtNgIPIpvGJ$m0$nXr}$;FG^>?G#$j~1ACc^M#e;mGJsY+? zr>GYId<#r0N;B3BqYLPWNNyO|{{8wfrDR2JkuXtm`;n$CII<9B8mkRtDZK6X+j96~ zR=06fKVyLgDFH`nGdPnf8CXyTFb6e}d2Tklkp{pK?d(J4ynJ+5r>UF7C06f5B%|Ey zYCq|0IWNB}G-FaCXd+Z1bkK778?Z-8SPv)qhIeL0A3^OqYtuGPH?@PDK)LoVW0fZ~ zxiST+s73*;?nAUJu0M<*c00f&8e{_mLT}qnIU99v(1YnreR3_}HO}u-2i_a2lpp%7 zEop4nURJ;21w5WT3*L9j)aG%b-)Id-rR0JbQyS?*i<@y_W=hLI`pP_XYM;GI1sM2u z+YZkZbNG3eF)GR-x5v}Dx#^_FKE1Od2K(wXpuKwN5h&`OpYx;z$c9uA3i@0~^eNBC zo~j#OHC>$xvpkzpl5%amUhlCV5QNBurv4~9$UVT3Ke^tTCcUDg@997Q(Cbaj%*7M# z)5_W7DY0KuePMlSDBalea8-ladU@}w)+VpVAQ2xtWl&37(jJyJJL468nV<OcBXCfE@hLCnCW{^2XrKNmv@A1SL6i|fRTi%G1J-(Y~dfFn;hHFYy* z*b$g2pRr?8Lwp3E&WSO^J6^Q8(0LM{qyrOC4uOU#}n zJokplBBD;mY?+GDKaKRTo3Q~3WSlz1gcyqAi{F>*xAUJS60|RBOp+&=q-W%adpcmI zaat=#f~#>}@pKa~cc3yy+tl&N#x4cS0|;w^z3yM9zLVS-7Yaw35Z?94p}ZU|O?6eK zNO^h>+V~QhbqGi<)+_gyC0=y@LF1AIA}P|;{(3M z{@KK*0%6{M$-8HA77AKSXq0{B)gfLc!l2Yv&l|Q^AmtulYY^<$EnD#TRAL7v#*64l zdL~Bi(d(BK#=of6pX}$XQ{9?v$NRQ#KVQsW`5^D{uZJJD%l#emKa~{odtW=puE;89 zo?n(Jt~OhQWVX`SJJrR^8%(Gp9T4FV7EqGc=skpr86%2}#-+Z!ACJ7WDII;+bu*+60XpxnY| zP7C`z!U&e7P3!mKG%Z#IW5qBRj?dyPeSQqJ83k!;vf|iE+6Zjd#IzfZ-nsj%hA7Uj z0EyYFelgUu8C6toc2XQG#lkvE=7NuD#y z&C5=0devW?gx_F3pH~iWtFYho0&IQTyITj(A>uKeZek^-Jq?Q6>lZ71ewY1kj*NP- z&C~g)lpqy;nmMerd9vg+>mnKSWwXfIiwju5oG87BH| z!A53sW;+ zySuwJ(49bl;O_43E)93{d*54ir>4F;HUCV_H}mpGDyQw7v(MUVJ?mM|+WXMg{0+!t zrro+9o9ne%tyJVE7~|0X+B<`!$=_vP#k9J!H+FrY3{PattfrHs%@uQS5()I49<;Ff z+lx*+9syTW>;-e5SiB6o9-lrg-MKZlAjeVs`3&Jibt5AwcsfS^s+j(jR^vA&9`aD! z#ABV|A?`>j{Tz3xVsVVlxs-5v%|`pb?|AbXZO7}Dz@D&(vGU1^0zYQaeB;&pLRGG% zRRj-dAeZaD^l{vr6Qje}VVQf=cVG;y`iChyt?rkOI*vcvQX8W=9FvUtVn7&TNKtAW z2vnnm$TD7=J%$`kIt`z%XAa<+WvHFIf4jZ&voK@|E@g`UjdXh;%gM=n*1OEbweV(qbU8P5dtzX;!TwQ*U7{x8z4};TmF)J;oqL21Nvfi z#o%t?(JX&#U5~N&r;$45M@B*IHI#eq+$FBFRor{u5tpC0K@8+|wrpR5owsuP6Os5& z;5Vq>1bJzQ<>0w?at;q!w9aO>ym8Q9?DU193H<>% zIn;#(b}5jKK9T$ZaVv8D21}H8?DJJ>us;LejBQ@m6?Ej~A}H;&lLT9GF5vGMEnGJ| zf#7`F!h^g#1J%g=qar;9rf)7wr%zbXK$c~I$>7&5M#n0Gtx!TwH}?95rt{!) zki@Bwez1(o>>oA&w}d4%%>c;sc8gtYln(9WC<1F~|s{5`1Aj0I*+; zQL+&;|9rOh%K9sv&8*W7zs?c;>aoP&GmyX@LswDhQwyY^@`Rt5auTVQ^o$eB5kJco zoSR8Y{coM5u0i?mQRHyEROe3@P%-+e~V8L>XpPC8+6-2=9Z@ud%SwZcJKq3`%%v$Itgm-O$g)?P*xB2_Xr>_zZe1XbjyV)KB#?Z3zPEZ zG`r0V3qt_=zv7>MVgPFU|K%j#|6L|Bjq68&+720@L7_^3rI)=YOZ?`ONVP8{jRUT9 zPZ90oBY|vjYVT()_w_U>k;-w65e&zOl4d{hRyn9;v z6jI;?`0Ik#C*117a+XPMfQP&{zth%1g(I8}c-%X(wLnBJiWB1?RE9?xaJN=h=YRBV z2^XUjAd1-h-yn)nCxvRla*9eyN++-bi`d#QB?xJK#$#|t!=Sl?D)1HRCBHpFBtSzrfQK&qtBEU2uFws@Ibn0@j9HuhqTe@e)^3d^<0Oh;pB=#Z;)0Tsy1nwWd z!MCNTaU-65>wE*g`bve9Qh12vuI?d5ygwVWYfCs40jp;wG$1p^>JUD;84frP^N3BUWp9-UegD#6m zM8)10BkAy^u-u5%<`w<3$KwhCO?eSh$VZSBAa#|MtG8AB42o_F<4i#%Td)!$pKuov zfeY0+|AGQD0y7j)3Rk*&*ktv>(bEr#(jv@Iz-6x(o#?8owW^2oF&92lfheNiS<-|; z0FH20RENRf?4_ZRA~Xx|#;nHgaU{2~y*rK}1)yY=W|L)0i{dIrX(Z2iz z)!)2#@e|i_kHgikB$prJ4CPENJ(9LAIiV~1qZj%vLW<;`B7nx=qJR+bPxNq)tXYqq zs{~mgC`VC-P1h}&osnll@_4{0X+SA4yk5y>L|%+qpx)UC=Zg79)crJxJA)LQRHm(g zW`kdRh?6$GE%(#!{x6lgH#)S{%Sjpn=pZz|n9CKNKSO-j?taRa^;^9>=-Ekg)0F$8 zy;js_1^M+o?fx&k!x?<*mWPVybCwV{P>%SeQ>O&#Yo8uxpOXQ%1Cdn&69@dk|J9;5 z&;9@OVWyHRkQNnO{8{oJ!^AJ4B5h*hFt01>bOIH8*?;;c=eh5+-b#@l{%93OhVJ!a zIR;*aX|hRstP}}IN>%$lg6!V|sb89zrB1YJJ?)IE1CJRWtVh%K!|C7Z->}zB#*h!g z1Aqa}3&9YTqRm!S=WZ=!-&7*Ng8Vb2-!`3&!nm`u8r|!fAKZhSV}ry-mRKU?l%Be~ z6Z0WtUKEUpfPE70D0e{;Z;WRm1akL6^k--kX>ukkC5ii!$1%$p*iD_xPYFoKm5vzJ z%xn`^mbimjw2ZXG=!tTtnRK3nEBxzwIO1d_soC26fhPAMR+;~3>c8#%t7>|V`HzV8 z|8#gK%}?{&{duvieUz=N-({_@le->}nDY#SOpWxV0?|r_TxZ2WXHX8$Rrdo(Kh@pk zX^UpA&OkS?pscXxIa>;%u%0(FdajA}HnC*dFV;d7_$mc>b7K=bQ;`CVbgO(v-0Z&N z5+LIOP}r%#)9a>*Jz}OK0@I^@#3_5E&i?ypDB~B1>R_dQ^;2w;m4DFNs1oA8=DZemw&d8p7dbt+ZGy zNJ5=W{XUnqvjd}oPc=*PaHzT?d1p7C3Mke7k%jw?O1JwC5v_=><#kczXZjeX@(?hm z&RXy^jyUan6U`DQTuiBraMXVG?nvw&B$w%~3md8{<>u^vId1H-k1LqMXp|AB|x(@|=F^pX04>A_f!BBJq6CdXXlONN@~ z;4a-o!PVBW`YbarV0FLJ9vsw4P0E!vKjs*$q(z5(d;ZTz+`>L5Dyaj4>7BeL`;fj@ zTTlC4AICqxZxyG=z>qlD;7Qy|v}b({#{}2-4Gz2*-ztJqGq4~D2W6{+!hc1n4_YPMTUa4IaoE74S66C z)qnK>?GxWwN`W~3V#!EHyW_fVgRndBBUA_*<+SXa$(H+&bI6^SVy!KeD4LGm<>e+} zC7m%U;ly`cp8TQ}Hp>jb-!wtqhbXp#1tFs4-xnt@juD*{1ffFaY5(zNjn03Q<>hDj zG#9=DdFGuxLTGDHOv0|*WvX#S>vGDG)&-X@p<$lxb54!iCJqR@3s;DN5_$< z$t9ZlPm_5hsKhqVKYjP}&MAI~CxOgAlS*LcpV*4hb2f`T$YekHPW&A5@L!=@j_1T#z7`p|B7)}HcV=%)wG=-d0gCkUN|!`F%f^1Y@2NRivQHYVwz<e0uG9-^Wn%)$fDk#8t$HV1? zvJ4BXEj+iPsc-m057Y)qC@LKb4 zW|*7$U5sHN0ropT$~EG2A@6yc^fPA{W|%jUYab;lQvCD*2jrQfE!@Xk>vV&sMX zuo#%#zC&ZNgIUr590-$>*CgNNq{ zu0ZbIv)VA^MSDs+#=s9_GZY9Jct7<3B0%f{tN;RW!sG>JYV<QfT3JE=ZxDVHM`IKFi<+J%GOH_#SF7_v*ie8%aLFVm5HvlSg z{`zjzo;q9lV|`=IfMpCw>74HR?fQ9?@n8xP#jL_q&Vmq#_8snF!D1G1jwQQXwtNiv z6?hlYSFN?z*5y_jdo}-!DVaB>ChJVgRxVel*?i8epRTOs6-3%dmT+_7D8tLLlrCca4nTF8_rl|Ep(Q33`wh^Uybi zFD@(ZS62(|(8UIP8znE6500T8Y^b(&Kt1|VVuaYn-?{^pcO8!cpIenKCp53TEDFf; zv~IV)Wb>&~b7OARH$)eO9W}(&VpWPz*5_S2m!e>f)ulSm6z9MHw}Z`aHS|I*ucdd& ze!|jLPm96HBgHsEx@8H^J%!Al|AVBI$m)%Ct!_x7hjmQD@kV_dNabX-mf4>GNV(MV z#Ra%WC9yd!=8Y(M<6g^?u@Q$M%jb}JmVY4SwcE!JwI3uTI;5E|tJqv>nACIrY|vj^ zP4<_(*$oGnlEQoN&cS}HUuuUJ2PdLvM7pRFs}J8EngplRin^Cc6_1lr4*rbdi6wF| zNVf zT0QINum}hm|9uEyAUKoBebWJ$uGv=~05A!GA`W8mT#m_~901IJ-UcDt_Rj4>AUyvj zgZ_IQ1_`|GpPstAZV2XG7z3T7ufRBfzrKGfx&L$cpV9c=8N>Y6mlcnZ=|sri8hI`C z;zU>4Z>3Lw3C#~X)QQY7QXMC6{BF!-c{b2ZqD25(PM%Mi`D2v!1pm80T7B)kZ)3#y z1EhPhsW^GXl(0Gp)UV=41QvtYQ1hjvkkxTZqq(n{^|jc!`PWSDTR~qu;&H>dMO7Vx z_gT+y7mk%Qv)dc7%cAkg9fQj}ItL!VB87i~EIR2&BG)Av$k*#sw6KS9K6Y>y;4SBi zDoeEE9`-8b?=UBr6AdKYRFEGJx-{&zS8^wm>g@7!GH9t%&n4i#E8;m_iV-{!-MIC5 z?qV#7RF>MX;A32%uow}q$rjSNNLfl*%1D&wt~M#@G1X)6H07`2Q9RQh`>cNxOx;t* zJ2;Qo$6p|YtsxZ1(=@59H_h5?mQwr>j{BHKU4#?cm}6pz$B|{i9CFIUvH(Kb3%kg~(-#hqN5t#d zS&|7(#V<7w={Km6@I=shU7k+-hD99))33f+s>@5~#Mt|CW1q2?d-REnlKgONB;8W2 zZ3OwQ5|z;3ma88>`XlnJdUJ(AaD=RVZzoLA_xQI&vc|hoiz;s8P8r{;9L%!Du{O!S zkvil4Sue3c@a0gNTQ=S6(nDTlr&kN_V!^7^W0kvn1Wz>*vt1>xYBP(hXPWGx=PH4M ziSW%&1Y!Eu78wjJeR6(AY$XjRg-6SwT_IXTySFUkxz)Ep4uC^sJYR)~Yba#Vdr<9P z6FN%xSCwjdT#2uvGJE-&OE)pXrzB6%%%}Itw0x|^8IHIGixN>aR8CoatJxLku*1Jw zaKtA?+*A(07cvD5B&@-s-iv$T!p1&}?fJZCHrvQEI%CNFuvYvAH|wQSi=&U~3)ffN zlqg>>P9pS)-$NpVL!X8v$($D4vNNd0fA-p`yniyY@%#4kLG5SWXhM1D*9xtT&C^OZ z$I!C(#uWMGhOK*+px8lyzJ z{KuPK(T8f^C#}Z^{?5r~>}kAm@i@$9iE+H(Yv=ui){wx@Pu1zoHWI-&lYm$WFtFe+ zx^0}cen&*U1k+GCW^6DJ7wgCoysQpBEqN32=Ay6b6Q2EU1KMgdJwTApsj;su@2dcGc#ksUuzD5JWrXc-9wc z%4r_;bsll0e($>#Djo7AU6PqBE@yfvsp$z7l7tH39HgaxvjlTH--ERjI5V7gmX z<6EPb!St^=b3Z3OF>xrhEMt%5nA{!1D7)e6AdQz7S|-x!W-tBR1BzfCM$x_!*F?$$ z!zCG;C2BoY)ExItqq`Q%&dJF6`MO{n4 z=Unw~Rc3;QCcs-}6*B^9tMNq=SqKJ4>l#Dt<*+;&>B2B-~s^mzRQ}i%Z3}t!NFv5K~>vQ8rgakRjLlm77tQW4R z{=-N3!R!+kcaKRVy>T@=l^wgNBP)^CVbw<1o3BCJc3)3x@=%sJv~zgyx4v69mUno} zGmB2{C73q4Me7hlg{%5f0|5q4hdn9EC~48$5rfty=}hbU zg5gp()4sXPQza9Gspe4M^$z>=Tv}&ZO1)&yWOhw#fuK^vF7sq<*nn2|)}@AfWhCEY z8ZQ@JcuGUpta1UCQrEz@-hBcsCPP)%qe1Oeb{GXr5{y)R!$|IawdT*D?)(dY=XcCOg zT&_4P?wgf(#1V97T0H@n_|=RAtu@AdTDSOBoEz_O1Jk6v+-N>+i%1q zx&qAwJ$vlkx-gYC1eIJ`J)BLOT=W|EuE%?h3&MC3%@Hs%#T6bJGrXh;57oZO?24hF ztKRC8omAOdeM8xpJ%!uK*NTqgDuJ^qyR%KHyGm!CgwuEqnOSY4zUBtz{>V<0t1H1` zNmr`LnS9~d89n|3Z}+^;0~*77P4z--vExvS8gqpIOy~{q&1wxJo&R0;!a5} z94)VyKSo-mqiGzvVRT~@RjT4;Jn(jUft(2zSf9N-ey?^Rte0V^TNaf9aQ_s`fe%6? z581hhp5P{Z-qgKpE|HLng)+Pwn@c5_cBhcOg36^dxuqgKUtBM}_$vnJvD8@K8>FFN zG|KJGpmcSRt4K;vMhVWot5j(+M&=S?S?`-cEO>_^FWMK7|w+?rZ@ zxV4%XP*9}~a8y-^7%x-rTwOsH_^QmBPv?E>5Z_|T%c&u+&`?J^F3R=%KsPd_+xlFV zxPrq_E(gi87;(fj%xlva?Z?81ktv_ErF_z(1)l6ZH_`P}E4r;5pm+4>_cO|0lTg=i3kqk^c-Uq=k2q~iq+-VFddTWfx?dPM2yOO({)Wugh{ z%LemiV(qPI={Cu&mK3mr^OYJ)(>I|5i+hWO=w@SfEy(8$4gr6Qja6$?24tVVD;Q?? zc=@j2>pa;>f#Bhg^KWDNfC-BTEXnL;eFa0_WWJl zj$Y|Rog9FYJl(r9B&Z9%rZDojcAZQObhful{hpFIsm(O`hbtIn|0MZp^-@7` zO45E<$T(h4B#2mE-J_agJl~r?Kjaa%cr^v<0(~mwMM$lic5a*7c8q;;rZUI} zaZY~d_UA_d`SY9dBJMno@^?m=^&y2}3^79T62+Zi(+wZMQ>FA(IXm38cXA`+q- zXa=o^o2u_87hY>IWxC1Vszces8b@_Sg1cdN^4~7?jEl?e43;;ZBGl zv+t{SL%@?a8D8r?#CZ)D9LY$+%b6`sTx~<(UW_b;(LT59VzR_H!8A3`iHp$5;h!#P zj%6v2zBUqH&&;PLW_s@8Up~_<&f6nR7i6X}N;(YXG)|FI*Pb&O8&MgaLE)3n>~kMs zBwS7|%$PHk{_`NUeh*=kgRgSN+P7g~bg}X!`h7>O@t(Z(6e^XDmTdmhj+vtw>XjcQ zt4i+0C2I1xVLiUX8i_mmM#qVXJK#iUu(!2CySKyP>ux#IT*C=mzcwd2pM^JOUe4)E zmO_i>lvrzcs+v8nI$w;uh}OunX&EhM$Eb(tJjV+eG(#feKdPh;K;a9C_zb3^)op5= zoM}>nG5~l+Xs?d%DoZCsDR)J-~HB z4sO_1B&c_ogP@pIy(Y#6*#Iq<0&+iA zWH+F&zeV);9#3g(@AobUDqW^{r;pK}HP~3|dh-x7qAjMe0Ss4^QjD(A)uwlHqg>6N z@r=IUtY)$#Dk9Qynxmg^;P>DCj_(rj4P7af4L9ft1QA!bzGlAJBc_wY+EmP~>;0cL zpLUGmn$msR!3%r+gvD4bwaRdHy zwY=Q`_d1bVL+5?}C)RA_GgJT_1@CElYB=g))jOBjpIm*9DD%lQ*KL1W3zMxEIX|{E zY;^KRn5(9rf;&4w9SJq^O>hL#$&EHT!5)9!VoNn2!@mn=GlzvwuRM#fyw3^<$N}zd zFqK8ZiKlw5d!KE!+X^mR9eGzf$bU3E!#-=Y!U{d{4aM6V7(Bo2JzL2l=qoCLE*I0u zH-xNJkBK4CTy^h1r(qdwiq3*iAc}Rc@EA^Z0hsj>t!m-lOIvLyH>Fz#og{J?b>zZ zd1#$>DuChh*HssN4R66NUc;4osi>{KRyU7fVa~%fO3HaV2tqGu%EtLl(Ttg=a1xcL zT_ZnF_V8vHSuMJCFPp27O7heaIrr#I>B990S2VoS+irkdZl{xdjsNfrHhJgqoIt(1g{QwEYx8?Mb*)vUPP98?rkX_I%8#%$6(REOjqs{7q|wZ+jd6 z2)t&1QAaF6CM7xPIj4Bb`ECv^S%b8cR9%af3kTLPaSzvTb}KW$Mjm)aUBLz^m<@M0 zipGfTc#isd57ZdpQTzm!-a1Scl%!vSUogCF%`35%;xDLr6|&A`_9-yw%`3oT=*>KK ztj3e6Xm7uoY|qQlh$w9ij0Jv_ljkz|(1D<>&N9TYT+j14_995blZfOuZ<-vXB!+zr z&oRazD@cE(zZ8b2^e2N{qC-2omG1sBs>iv8=@-3f=_2-QFH9ZTUc2cnj+%;8m|vj> zi&0m@2PO`#^o(;q`piAPm0g_<8)RsESY2`f$D;VKzwOHyQ(7MV-qyk1!@Ml|g}zT! z>K_imtvdPNhE2t)GkSBxo8u|LzMHpJZPGZ}QE?0GyRWd3_H=@~++zm_2jT(qr^N2> zOW;EdB0{80h6Id#`t~`Tb2IkHVrfPr5%_?!?ZVN6kcdfu@92q>rz#OY0Hgyt2o@rh z9;GXEeY0Sl0Ac} z`#_-(tCJB7Y2TLJwhm(ZQnbWQWS3DZ7$t{1eOX`KF_^=uvXn;?I*{i+fjZN)S(a7ls~}5V*SKpquXvqz!(v?4@bzh!jI6W>^QGw0<^wkKzL+{{dW%R*1ht7}UN-5te zb6rvFi*`!t_<<|mh-ccFaVhJouU-^#3zHieW3q5K4$m^(rND;ev)TocW?AHE=6bw* zv&J^c+iG1koT5ur`$X;<>`Z~Hv8H3_e=**xnZzINb!D8n)c2}jyw}v&+74Mw$vkOz z%k#e8$eCo2tvA2)o_WAD)e=8FTK1paLx=DIQ9YB+ ztbbelJbe1059u%$q2Fzs7$6+lm3_$9T6muX(5#FSd|xcXA)7M(D;ax9q+QRTIZTkm zjFkE?Cg=21Oy=;={(2=rL-M$V_LC%9!ZMq;m>2Z-2v+?0LzHmx(Ak;+W!r$lKhE$? zf<3p9LZxng{>AGMN6wJ&6|m!^uz_H?G*2yQKA(ds+X7~2)B^elE5L5LxwFMm^UHx> zGosmrWv!*&;yS)9kHJ1c$sUm-eK#nSX%doJC>&uweKsr;<|E22Bz+ZAClC=yZyt`y zhlVt;EK`&33@3Eo>J~Vs=u)Ew!9v_0hAARXq8;8(h=+kT7aNXDq8j#{8et`U$Y&0V z8vHP3lNx{1hM36g-2=Yxn3viyk!BrpZ!ex}5;p3BWD!szZNi@gV_$lX z>!|oj&n_S+bdWaTnW=xFo!(kK;mO^*biwFzW33D^QysI)w+cgyzxsC{qA z8NZd1>SrK2oaHPfX>6<*c`QVkSG1u`I|Tjdh{4PG+jGJ{{`r?RY-Ha_h)7Q>Zx4U) zf$;2o{)WtnDvQOih=x_)X5$w%=+16GZW~d2nW$Dg`Kxoa5~m6M=&6m6xmKUnhB1xJ zFJ_EGq6XQgoE#z$qJNg{X))JxE@d@SorcX|59{Gx_cUmJz=R`sQ9Kj|-9y~9aZ7Us z?BSi#g||=@JPF}H@pRT|z3hXz)r?E9w&STg<565eAITpu=6LYz(Z@$(fA=w0OWvHE z?Z)g3Nl+_sOE zH2e#sBWlz(Q`?t~PG$0Qx8m!ik%T(yLo_2C`y<08RK=o(7kt$WMY!~>5eS)(if6Jz zoz|Y#3ETNXSy?bf+K-00;!5Kley;FN+mzDDtT9r_;^ag-o}rVP9;>~)hkf1jAbP&3 z|72gNxOe9LK>H&qMOYYGl6fd_mXsF<=9rxixZKF@TTAn@R246Aju8jhGK|_+)_hkB zYHVRufdA&^)?z8yNRbU$QBlax#T7D@#xZyRI`XgK zndw`5$&AcjIRKpv_An8lM-6_0m9Hp`<0)TtSK7uSiU25DSXiKId`T%qb_Z>TT8v&ukTOKBpxl8eT}c2s!tGYS9qNV@;pt+5VxwPgPq~O2MyuOgvpQB zxb-)4U6)GPb!PL-aK|*;!q1wwSQccjs1R160T;8fTc?#Fg$Q@ETm6gWu{AZVq!;gy zruAC=<15tMzQG%%=&;yz&X1a;5?kXZF}4n@YK+>5uPv-p=MbGp9~x0>{IxQ+g47CXxz$|&br0Kv+rs@*B7L&p&^8XmdTAT`lk~0YZPLa z+fCQ1KeNgwLtRWi9=H88N5(9%)aMf1z-nUV-alatQ*b01z(c%9ig&9ViI&vE@K)Cv zH^5ko9h>SawSLtGN;ICln|1OMPVV|Xb515j{EaVjdD1-V^TG`^N(i8isZss|&#z@A z3hk|jT8+BG(2~0laMmQTYj3m_5U6Mh z2hjuO`|_qJjJA+v2h*{G!S;GQcSG6a9{lvK;^ATCv!OnHNxHQ?=dlQ%A5m9NgP&N> z=N)l5j!o=h7xCk-nqaTu763*`gdTBz!*=quWT}}yU$p!3MQQy2!G6IfFstWp{GRWR zcmr@`-6pExgYGbz+IXEE@YTkGdZ4z)a`=#vv8wAs4%b#1AAj0z5)lvKPTOWP&(#zu zYGC1U6PlOp8Aa?nO>+geGO3*alR$>KTo0yNQ??)dbMr;XAXczF$F5IZ1b)H})xRBIrCHZQ~Wlyv6znrl1 zu(o(-Y1Ncbio@soQAun!0WWAf6x{61W;aP>3zL8}%-UY3{Vh^Ixq(4i=qn|b8=?B{ zHcGu=p8l5v!@tq)T1e*2^61@j!m<@(w8g!Vsoq2HInjP{#~v)Y?!XF}&ij{ZXkH+v zvqig0bTtJ+x<6j-DS;dUNT(xU!niO>|Eax{pR`)TDd}K)TqGS$7n%&wt4prOi zSZ&a@Jb4teOWpachF%vsJe_%fb0_zq(4nk%5_faNs9oKu32go}@Po&`!_!OQDsjz$ zX)1?E)aBh@DCKb`jtDNvI)K0xUWg!Jy&Ni>Wg@2EDk7kh=6|!WOeWIHv>xnl@k>WaM-FEiSH=PZ7~ai(IZ7eBg71qF}2O0>CLYXnZPn z@o2XH8^+yRk@9p4UV^^Kz4{P5T816NQ!~SJI(<)XZRIqhZAJTo?Z5|{-}`=e5@>jm zTQn1sl$15g@p3dipnfEFANaRs5U(?rt`VBs>&HN#Wy-y%2}7x7Bq7CH*)sCGHY|c} zqJH1U-QRt4IS^eVcD#AND-4J*?ac=KdZ26|_q@9PwuHGm@XZ5=t|S`G4#n6pDzr7% zOkU!uY#1x2?&q7?4hH8k9L_N@(}Vvq{vluur*&)-HQJG=f zlJQdIKO~y5$woYUvv{0TLWy=ucx&oso}1&}Fj`#%t@USTLVd3Q1Ml36*-d#-@ZD?> z)Ivv@U#%_Y%q-YzavNVC&`~~2vV4cUAHkd*da+I6xn*#<+wRD&le`EeSdy7E#)oRf zPjZ*9eg*k^%6jVX(aWpVn!XP=&i)9)#*?zEsu0A!hC{-^{Q9}0D)_iKbF-IbALmu;dVI-mR`6d?L`gMmuvX9?7#8YyQDTE`!`wc zik3;^`EQuP0`3{N-41djJg~rv=GL3;Kch8!Nz_oyg+1I%u@j%~qZTcTp0NmK3XiVY zXU>=8o(2f1_d85MD)dKKLF@hIfG^w%ESn%4a$|yX^U?@Bmo8t$oPVSbi?4+4&$0Xs zX!s>us@xX&;<``fRFr-kuf#Uz`poP$w6{v0sIfO>!wBwZ-}$GF-eRB;RMuu;o&1gN z-NB?|GcJY!{NbBBv{wnCK}W`aEEj^dP2djoo>qxD&}T^#z1Q;zQ9$&7!EOjM=wyC@ z#L}KO|Koz0%)ByFC@*3ka&h0dhIzJW(o>wF{Xqnss41>vszp6+{q2~`)zLWnQYNe} zR;^aWg6`-vDTsZSc_lUW62Z%{`czwI^#EB2y6^gX>= z7f>e~tA~c1)JlckD#lRDNFDQkm>jcu08Dowk zw3(QmT%xPF@iL_rts#y;isvEvc|ztfnn}=Te%pggcYcE1#G09#>u#YPj55aSS=br;?1X;kI`ZhdskI1*)|_x3o=XclGLNDExb(7hvfjtsy0k!?=I1Y zdC!?dzHQ--!#iVYcVHII64qmPj~sbBb3Stc=k7i1nX&MMsQ^wuvM`$|t5QCQ&6KIA ziL<1^Sq|&SX*6ZG|C2Vn8__7>UN@udD2t~o(Lc(0_Yr4jok9ofHb$);es5$)I!zNy zHh6u0_Z1z>^o-jNk_GlcN0Q?)Nj8uHR zg4CQTltHOgDPn<{tLm;qo&TU{@_r+r!)gZ4)BirJHx08FCbj*Tl2SVb_H!aFh^PS7 zYNDA610mF-0Qjm}`QF>%jTl27<^e>pV&9}816@BV4bUINk#m}goGG`Bm#nrn6+i4! zfW9)3+SY~Fj%b&O?$M3;7TRyIWSYlV%Q@`8QjXcf#+Jtq6KpJBK}@PD zzVWT$v=eObD_p;Mf$7R2^}e$bnrd5Q)XijY6P%wr8b+7Ix2y5;+UlxYcBUbkaq04f z?bXBc%M75kr|@^ZvNrvGMTVhbJ%7wn(xAi+1CIDprV$s4bd~!Gle@9I;nI%r1xNC| z4$!o~K~NLD3H5mS-oJ@FrFcb0hpUqtWf|W;RJGM~rCs+#anI7f-i@q3NL!WYse7~n z5Z#t=94MGR(BXHpfFxP1+;d-RoS!7OKWhKYDlCU0gBs1Vul8g1KSIo);itjQOA&suJt)^8)e!*J|V@b^*&eKnx_KM6HT zu0F`tz8(yIP>jkjuZhBf^6}9xe;oP48G_$Rs1b4AY&}%Bu;IM}&Z7QpzUh)(4Z9)+ z${DIsop2lS)hv_<`?Kr$BCYmbCxG5+OOC1dN{PQ&RXuyH#?%4=q)ih1O_rahsfmEE)8Wn;;< zFE}{sxap1WX%POE9}Kk3RH4O&YTpx5bKyLBhanPb0#|e$($RbqtDM9^U03QDR0OXh zaGmW8*HgE?Vmq4z?M>cv|NdsAPfKtll2#|-*u|8B7}sgwqWC6q*S;a`45%+r6`$Fr zgx?SoBdpTL#Kqw{p%oRXGuRw=t5yCQ`;MEg>u1z%{g{R9>2J^_f?9>S@aUDVz>B+% zm;cCY|065@kF5CrAS<4?v(A&)<0t|GVu+en-lu|k_WS#H4NLP?AM|tYgu|8f>8rEP zl6F5ycrdZsfeNcdHc%3i!B=NNLrce5k5Py8o$$x)`0(p zDQ;uTnFhO{ti);uHgdM;WtZeFJQLBtp~8(mS2}%Ct$N<->aLouUpHFV9PhKWGUZh zxE{gbT%iI=Eu&CYp1jUEY>AxX>M|;&7@jh4y~42L8#4yhBWor@a`ni{I|;9}>1 z%D7XHR3nRg+t_UJExttF)c1NAtd#dPLpyCFk$4U(uh4{k^HRPJ2#fH(FcXJQTFK%> zNjl3Ck<(p^tbN`{vjO3AwtNDWnB_uIl{Oh_ay`ONg}Yk|pt}UF;9jS-g3D%v4z*0b z96FSBiuLpR8CCMQbJm8}G1SE%+xqPBR)ZkjkYsyTo8V<_>ccIMYvdyj80x~Kv!JTe zS8|n(wAj>G>r+Okd@wf3u1Gmj6A`d1fVOz_O~Jm4sB6(sYz2E+YyH6==tE3OikHBq$LAdl|c$DLFqBY1_#x;g4h^Dq%MaW4nGFmrE~624L*)SjceRZp;ER+VgsN__Z-ki#V`aa=?e8dm&PFqIJuhICg2`PFIY-YGZ8F@yMFAKE+Sf8A}(+j zS&vq@ap>B^94X#t*fu|{6$@wO zP!Pz9g&h*(e3B+YBv+|TKc=``AN8N+#9gptEyo4|0SizuM!}V1KWFl!#qJFOEjiZM zFk-YzXEOGLtOCQP#SBwUo|ylWs9Xmw3&D3=~e^r@2Mq9R9&O-RtEygiAFf?b*3G zMlP0=#;;r{Mgp;Ve6?hKjEmDhf!to}MO%Hc!6xLWE%d&93oI(e*mh^_ExWC(^M$0+ z#mFlaEvA)CxLxkAz};7tBPcl76Y?2&%hWz{_w3J^AQcB;9=4U4mmXF`OFgt1cS`se z!$!7NPZ93+TNmR>_ovZf(IXs_$y!W_=7Ls-cgi6mqZ0{_#TmyM4me@#DN~DlC!-cq zFsjH^i)ZCK9ULXLH3>;Hu8gWlYG^zgH#h6RG z#0Yf^5AVR-ukDr?YOG*umaZQXvokiG?;VNl*j_8t4P2j$lzY2D^G@apuaDsIHhp3` zTf@sgB*de&%lqU`fJkxxD>l$2Zoyy0R4rmIuD&&)vx<20ugdpnrsV)W&Fy(Dm7n%! z#dK!Njc&ij2B{T_?kBy@9&s6^Z&zBlyr*1S#IaNFG0_Itv-1@LarjNgeq3lN`lk1V z%MFQZ7nysWI;bXa_xu%)#3t@}GShR^z)}UIY*H{xf{Nu;MeOqE?#W`Koho+X!B!>p zz~!tC;FD>u)L*#N8T(=A=yb0f^zF3smm+-6W=E(6Cke@!jB8=$+Q`O|cbd$n_<1;kwCElU?AX_nH7Rou7=NyhWV#}E(2AByO)0rf%};B2s!TL zS=6>tisw5!rHuHEcgB*MqMAx%{+07chjk%z?%YeUD=gUexNA!=l~fiaLD72G4pC5v zsx^lEL7;6HzA#(U)zZusrr?%>)v_?G>uCaDO}O_A$gqG-^Nhn9YdJHP ztb1@83uJwBCzbQt%D^6{*ZMHEg=Bo%)50wj3gREte|gb<3^{VaBbFKx`=k%4PNa=| z-Shi)zSeY!S+b9-<8I55T2_LwLoKZ8W0^Gk>vy_3d=J3Z7o9v?SOq|%lt7;Bs7Q?A z=eL|C?u%}#h-WL0Wh+)SJEJ*$aX2PYYH|CbzjbdXEwawRUaA#UuLS<4psC!^~9TrQA!*LxS# zNdPk6C?GuYEz%t8WLNyXSoJ~J&6mWcuc5XZtw5R)0YL5a-JT zAFLT?YK;7g%&ddjuOxfPiX2P-~+pf7T23RIzMP% z#G+zgtJUl9?yH%!>$ckhhR%J(Y?R(!o9bx8Uwn=aTD3@n{AHY8-#{GPg~X{qe4?An zP0@J+)GG{FZI@dwO32gZrV2b3YJ6xhTvlP=dyg~0%4PlCo(czZLMN;>r&>%jPNpJxVXX86GE<27z>`LiRj$tN`htKPFXhF-xvbhBS77XU^+SGi-x z_{x&^O)txE*IB-Aj4xX(hlB7=I((@N=-v%;3HXUEXL!cV&i!eATr$vZ*Rpf3DwfWq z1|E(45BAr^j*PFdm-e;O$p6a=1R z!fdoy%&~+$jHKE-C&M%igoanvlFk90*ab`9(yOKNKmUo$c26B903g3r6Yr}2mhwVh zcUM;;jplqLX*C@ZtEpA$l>KawD|&{FqdW=Fqsd}SS=uu)XhCvyM!rP=FU-wSTlAaB zT}sh-&L%M6J^tuP;Ki%`Q50Kw(*6iZC+)hi0W7fPRc))Dzy-;Ji>wJfh@-Qh=Ek!) z|8J0YTd5Z#au+!}&vUeJDcy@K7vqWZ4~S1nK2EcE8*jXdYZ+oXzfzNuzsW6;za^qw zN9*UQacs4zv;$13?=(^LxT34ue*Y(y9pADNOI>!acRw|(T~m<*MR*xr_yfh?{d~^3 zKyDH7_WPeGHR!{Vx%H5K^L@g{r4Rc|bV9^upg`(P5A{4g*9hAb4&VAp($J0&SobmyNd#DB)j-LxGvLomDCG zP?dMX|29W}14GMMHLSb#T5hS*`#o@m8v;;G)mCbj%}sYL>m#7$!Qa4&Zs@ox(Dt3R zaM-Qshu)O_Qf==D#k(X8J3!Z2xSzrBf(5-faX#JFdl!YT6o%z(V ztoq+k_S&cfR#};Lrxcw#|3Q*fSv`QWh<^Bf*tb9dpc>lJCn?D+LI%A7*i6@Tt!d#? zDOw`+^-FA7Z>&u}=?8P5KL7`w1ee?MYlrdJR8B05o*B8LtR6%$Of9TdWmyq|yZm&M zwGeqJX6Ga0`X~X?FdG<|qM^Y7sd$vo!FL|cdsE(SxfuyWX(#Ki!zEA2uD~tm_ll)8 zg|Dty4lS#Io9t5uu)^^h*bJsIgd&hwNEA+A@ugKo_U$@4=tqe$?)Ymq|>oQ!c;@Wh7c=ug-+}lCA#X z!787{N{i2edCLLQHHCpm`#hg^8z>jDoHn|vR(T(k_4iW{*>7!=B;+3vRU9JNNBhH* zU6MWyE!-QDu+*`Fi`D%^e;4^^*}D3Yt4NJ|GP+>g4t^$!M!a`B@Ba(beKtQBS z52&QdN3iKO?QUF5xi!UsOsQOLo!m6kp#EXcOUF!}k6xqm+EEL@D%AWQ!@10K2hp%+ zGV?2xi|F+E37Z_#q`PZ?gN1isOR&&>`VFyhmp#iZ(r9$5xvX-EPpSV#_1RY+a1CuX z=fb?b+P1CnpWO$J?JD}`(E0yF{c9W>VS z{HwXeY3yJA&TT2|Z~h)cV^Pi-00AqB%Xy^G+%<@Yk+e|iBp(A#Rh(%bOyX!kNB-vD zb3!CNSGmN^jRG2=SpUvCWy4^JlY(}b1(H)cm0wMK?(7HEgI09!wLb0mR_iIk2KN}h z()8o+M~k$>)mtVjDKR9heZ)J<;Lgjt0;Kf;BK^RHjM?X0q*&Hwo3^p_*f2#gbU+b3E`xF1gCsI;Uy*zHiO#y+qeL~jAU6#K-;+GvE zeS>Md)>aj`IzP@Ho}W!3_STGoQ;#Z*o|l03E5K$J*(bXsn6QS9f#;!<3)3lDANv#% z1xTifj>mm16hTq>Qy!#v<<7FQojW^ig2j6sOP79_^`+$v`mn|6l-$ItP>%{rCyj_j zm3xBHy{B}`vy!ur1tJjyOSYaR((_BE^P&IUd&XzNzr(pYGDEd+a z+6@fTzv(_=)Yw+;E+znql4rh?`S{?=!t7AT6!0l5&$)aYVYnImwo%8~ditpJ#rY$A z{q3To+dk*S17uq1f4^qJt$N8plYUsLn!2RNPv74w3Rohyo@t->t+P1uw@S1P={`Jc zNAb5PiA-+YHt_qVPj7HfS2Hb9YhE`n-;&bOi#d@pz0s|r~s`rrAOUtB%Zj7P08&!~RGs|~V2#CO(u@Ak;2eGk~6?9eYQeOa*1 z?30$s*1Gm=p8?gW@8xNjyb@r5rImDp#QQG26_U?~MV2&h&ucEasT04^ z=*H9{jD+M_k9LIQX1SEE?8=v#2*ycVP?V^Hk_Z9RnBAJ6Kj2O9tWc#xAr9sBLf}X z(NlcE$G!b8vnJMZnD1t4OM9lWTSxni(GBp5pIs2iS(Mh!yPvHdzrQO#UX%QH&|}_N z#`})F6E$6-o{1ye&&uZuT@kfXbMtTPZUt?*yeDD7-Bo&KI8uf~Vv|}K+%A3iRmy#! zM1B;}ZA?PcUW7jmacALh zc4~k2!ZyZE$vU&hJLSn!-KKzMhk_+P|3ER$b36%VS1ddDDG_IZges5gME>@?hdQ7sKjJeS=lU~B#c#74R5)ck)rYiQ$_if7-YAX z@3ARHAkjQe{{kHdMvv?1wX?D5sa+i2yR0&Zve7zcCXGz&9<3%wB8A1EY>pB2uHN`|#x(_E3UQh1n(|tOv^VmMJKpW9h}63Yn`G;|$=iu=UF<@9J9yshM&)Ml z^^3?^h>KUdH^S%Px{z;OR>7kgm4o%Da)+#+E26{Xf+MoitSa5CE}m8~jREb}d*|W! z8q3U=P7^-1)*hu7TvOb?_m8Ad3|)(MNBx8qrJs|FPTLPks~7OQ-5${mZ67bwt(4H{ z`{r;P7aujz(E6-Y8!|eLS0i2l-=eQRC(?kmoE4)pC7cAhfI>dFs*c^Ufni;DHYxTf}= z(#V&Yq2E^d_e?g^BH?CrFsm zo5Ht^p{G$|e{E-%JN!@NFLsBR?Dn}4FW<0tupzCL%#BS)UO^eMmbn==)JUYp@Mq&huHp$!)vjTz2k`AuZ!u@c!txz^6f#+$MGk8 zPMv!Zi zcuA3onq13ZaEyB2$p>QN%UCP_vfke)`8fS+)Yoe5mW}(4tm>p30;zjW-(==@sTX!t zmPeFcss?zL#mw{6wTdQi4cUzGI?OJIdLVhhZ*Vc?>%w=`JXRbZuzmBCD)oI;W;($a z4Q+PHF^=Sq+Cq;#)yj10GiN|?9L)(_F53)>w9LCus(5`!5bY9Ler5V+Qu5>PQcm8@ z`)p5tObe(Oq#+*XBy_GO4(76#B*}IXw6Vqus#8fmg&ihV@~w-qGql%7)JS_50ES== zhixz28(0_b^T!e({m0kTVD?{n&-SX;9Z@e+nNiUjFR*f9u=CeY^@e6J^WqIvxl1>_ zr9F4G^?c@MYNjM3q7ARS$5o@UPpNy|>1%54u6{?1EBG*GgUlDU7rhGiQ|lm zAAhk%0NV;GcGuseoLS7W*>6u-iVluYlGSpzGpCZh_jv4Lp*&@`F0i?GYLLigxp{AP zlhYu;H_g${`v$$CrGG##mpU_A?D^w3UwGNPgWycAtuBs>Z)Eq$V04wIC>0?DTv=2& zT=--edA5)=&Zw!nSNfoTtXf0%FZ3qD)YxrkD}m#Cf4V}ZqDyS4`?zwdq~=o-q2Dzx zI7UyxN0XpWPcSVq6f%f#q)e6Mym@%-Am{H{;&POfZc}APol!H? ze_7@-)hE{CtCpvpo~O7rGhC<%MINch>BuA<+N06TUd+q%AIxxjVfvoGJRMUXPj+ce z0E%VX!E@6~gFfH*rhwgN2rDgExt0*F|Bp(C5l4051%?8}=T`#F7m@Pq_D&zMhv+Zp z-#j*yd*`J1__4y_pMx+7{Sgsi*W2nmFLmp8IhC9x5c2}PE~5D-d(yLu5lfD0UuGfY zpZ)){5>fV7H5&Mp-5vK=1R#rM%Tbi2+O5BAuu2z@J7M;`M1EwgEtj#|}cm|;clFWz`h{G#NKR%$9Ib5q0c z>4qFsP~B-6sj+688oy(VVmJD_hOZAWH*DUo5qfM`AiEc{C*6Vewl|*7n$=}7Fr8m$ zp_O#89GnYmZtH9B^hSf!eux&VzltjDp_!E4XZ51Cwp+Z+3P{5-z4R0+f7ivrt=jrz zIp4oRlcI^LsmB{#N5weFo%IlQ9w2B^dj?E&DSzQArDxX1X z{;}3njqRCrjqyE~zm0mng6lWm#3E$3sP?MX9(1t{hXn^-PNpALe#8V0j}`D98igMt zPj1os4=>-f4WnF|cHTNxtw5YRo9wbJJPr*O6V2ETs2x!iykYd%fe!TV^|T?VR>mOQ zV5|W7B{3@nzGq{#NV%QvtzjFr-{#c4r7z%cFu_#O)CVWmec;@Z!Re~Y>0_Gp6pX8| zyt^CfYqaQ*`m{E-sc*su5$A?~%*Q3iD3X>nAc_uWH*@#qSHN!?_=_lx{F$N`k3CZ) zVqojo2IB5EeS`hrzwZnhx+pnc!*qzGU6mAhJN5TKH*%u6S;40gjQ|<^`u8-lt1}uE7@t<6$uY_!60{*|xmf_(rM}nZv=oLPEOtT64nWfqXzN5VUxQIH+%aH%MDF=EpTl z=BfaV^_I&yXGtLW+egwTSho)KHro?AO_LlN2 z*RaUUh#!BbmFAm9-MhDjx5kBh_*qSk21}ZK)ss+F1&V0lMfZx31gZH=W0=-grtl4T zHabV5VPOu_0=@Zk87V_g420;(d$ep4Vit?7FO29Mtp2o%A+b)O(a=c{aR>1{DJmp< zwF>tgtTg&V$YI5hz{XJveXMkvFE&JOfGW~(x++jB~8)h=sXwvJV?tZO5D zS37jU_Pl9pIlHFW`~_$>a!zh@cwq=DKiPHtz(nXhja&Ne*O$@Iu6FbZ&0P7<3z5B6 zm(Sh%-YA|M=|JR-|E#v1Zr;73xm&dIQ`Lv>s1FdkXx{jww7O z*ce(7FGRsX;yk(oBxN1RW}qq`FarHEP1i+v9~Qe);lFxM7STV+R3lA+n_^i5gLo}s z3r}<-Zi~P|eKE5f)7ge#?8rCWV>QoRup$>G;b}$e<2`+HWBn2}OsU6*2-?Z1NxV#)qy>8q8E^Ls$osmxc$+eZ=7mU8}*NjZ( zV{u>EIuEjk&1xAcPVI6a(>v6SRcc(g4jR-@*DZaVkmjyzeRB@6PbM0$pL+sJb+D*dpAUO!5gBOz^Q!8HH%>S~>eA&K_l^gOz@YcZ zHQEdhQ5p>2OJyo%NuOPvWYjbk`xt0xj;1wGyz~#o;$%iR(`J!F7#!J6-BvnRD z3p|VM)0Nmz|Jq8@gKlgM+@>LR@_Ko*sLGz(I)he7ToWu);feeHy7CZszeS(h4KK+v zbzUGaIL15NPx@681GAqunr83J(3Wbb1)6rHuQG>xpV8gH&^>ejw*P!mJ;^B1Oe((q zSeD=&{Q}Xi)N|_rUCxKhnq?(AIS&tWQg7YakhvyPi7GC>U38*&0`fd^##>uARJGn@ z?M$4A`5b9bxJ5Wq2)fJwrc*kxP!e4XKNvDphaU(R^#&S0p-ekQ$MsGbr&HPJjyPVK zWSYmQ*0uuQsnH6Z(VdR?QlnCso9}1u`hu?sd;|{0?#J4lzJ$_*Q)Q!YIT_2Lc_nf= zMMA`Wl@Z_Lrk@|q4P0jxusnZAo5?6Pr@vQev%3Tm``G5~wVcYrqb@^@)W6s{26Eq{ zqdIwJxwb9Z{1_2=7DW7T6S{W8in59=;?mLY&u#^gDi{&eoM*CZEx@DZYispFU<)Ht zNmX*~=$AC~15kVHgdl3vX&WG)Tbb2B%}dr^+F|TKu!PvaU#;Azq-3@>3B?>Y*`H3G zMz@P|Iq5QNV+ylPNgj62-g`Ya;fP?h8=6;6IOKKN@5Zx-|D?gNk1REUknNkUCT3j0#6?(EU!_beh_FuvZWEWBRH+cdX1pi1}hl>2l3 zo7>O{I8Fca*}h65od({E-+)8$%G+hMCajZDMCHo0`~X^oU5s0hynpalh7pa|Iqj0y zvGovB{leU}n(aZ+cY!c?S#pnod3}e=m~!)R{@+^i&8uyrFR$xA_hQ#7zXN_689EvsQNfmo8AJ7H^>AsD@?>bX0$2!H;&A@%g~B)mZ@0U zykvZhu#EUDG~4JnTj0m>-N-tP+zd&8Zx^3k_TR>Xkll>iAL<03Y0zp~sHRhKT%*|;^jxU0n7^hnJCEhH*X$=k6+i3m2X&HmOLTP>Idv6! zKp(1V>SU|lI7#l3MA2fXr|svIgx8(j33<`JJ=Ca&NRv4;4zv?}8F`PLRyg?#m!axb zDTwdA+F0n5mt1J=YwIgjXzrDgc=~+q^RvZ)F9Q#!o%VmC=;}$eBFs&b9ec~QxZfJa z?f(Ex%R~2HYifz{tbxp9Ohgo+v=v&o0E;V2#iUk@9_Ka`51vR(oo~HgS2n5|&{@ts zEUJ=iY zi}j7h{&uXZl%j>{&}v%Zl!b&$jAu+F)H#J@DO~!uklP8YIhj`Wf_ZI-31iP+oT84Y zTEt8;s%4a4^VK#vxfJ$d-xfumEDi(@kWTMo>UHU=Np&N~?UL!f&Xnc_rew}5S4)?ZT^h$ z-O-|N@Jh^_{1zm}4&N=HYF4uzVh23}E<)fR(F$PrG^}$nFw{wTc)}ILE@R zArjQBIPKt7py<8Mg&kP#xI47-tfx9wXs+C%-*Kh#gUdyv!SI839x9nrg&ZRu(uQvfQ<2wD9#RG+(I&V8?*8rcFEAtBb<5j6 z<$S8YO804%JAC zh5-E=zqZaikoDtSTmxjuMTR&pf;Q9G`$1v8Kp=^*^gw^^5FUs=-|ld;+;G>|VXRLo zK{eSj!l45m~XQ!7`K+!>wsOfDTTCf4@H5}j|J zeNOY=6u)Dn_w#n{QWQG~GzoqPU5ZdNW-?KNfz5c6Lx~YR-{UBz$>LK``nJiRE^re&)tYNU9PgBEPdJob}M5HuE^h z&(7!PkuD9@5ZZAOSJg-Iwzh&%dwcGv9Wl_>{6s#dNX(h;j4A?X)sU;cM{VBhZ2Big z#Vws_eXgyCElYO#v(2xEmO9>+`E@7G#14c+GT2LDU$icJ(VdOnHf6qL z`z)f&e!ct~xwiIf>PL{-9E$Ae_bNmTv&FraC$1J1nMfsY8s;QO57;iljc_1fbfj7i z25T5xI6EuO8Rc=N(LRxi*{Q%Up2=A;)+gLn{SVO0`lDP<>@;$QL-XP{)u4n7JK_rV zH-zr6+f?qGruAn{GN7Hd^L=%xQ63rSitw#(zb!}zezAri87_l%9(@3Sa)5XJzl?7A ze;@4fzkdbx?Eh)%&HrxB|Iapu66Oy)A-BXOEZS-&j6oLrV$5-&NzAfVAJ?t>C9_t6 zK(7j9>GQt+g!=};Xs5+%ayyJU0f9_In-tzYvS~Mnc7vZ#WnOUbbScdzn)c~se)p4( zY^clC`We+{H#j%w#;?Ah$4?0yrplyze>?hW|Cog+Cr`cBjC?2UsY>QA+|ONXJK?hf z;x)KzjmxqLyz@e;%Jntb;H{= zotri1adJJ2eRPkm{zzrba;G{div8{;E@q53Se^NlJMYGySKSf!gX%jqmapQ6fY-v4 z#qnoHp0m+7q^O{{vuRE}%JBljVydP%RzR5z1+v}Juo8Y*)52*DGuo0zQV|SUA6OmK z)C=KQ^xtzvqUw^u&Nc!4oZSYKOe*{QQW^s4FyOo$DyixuT@awyQ^?e?(@tNOrw?K8 z=q@L8C}lMT%&KX? zeTQ$MN5QGLgB`Y{?gYsJomOmk_wa9a1&a3Ub*Z~G&>=X@ zYleWcsu>Bxhdc9D-P$R%S}BOz7vTzWGQiZNh|3e6HZc`c{RT=&MNP3!g+iBfQhwD= z$hP`#V|v>}fH}faxB}-;xShr|xF5S5P4lbt%ZLbpL&u!RuF#wjD-*l+6%c;pwPv6G zpeKcfrx;#)DwEdOAJj0dXXwghtn4ezDS}37<%^!Dp{z8XJuxsTUzp$Xi5%H0!&^qF zBko%|$7Lo}f;4i`JQ7ALl#+gyiT-mRe$*xJP!dpwJBbrGyzhNN>Srb#I3W&X0&gEB zXoNh<1HHep$~=f=sBj5`6>eu`9YkH8_j5y%6CKlPmDSj|Dj_N+yGhK~qB9Xj?18ER zn4+bMfm7$g*{?P#!~~h|fL{8uK?3#q^7HHi`?NIvY+5kiVV=Wzc7dy`&L@63Z_x=+ zmP9ORT^B}ST>e!5!vb*q$Y$Mnf}JTnk`YVa_-m zXk6)Gt*4n8DgN*Z5MN3|C=cybFtguVY1igzz6?uTU->RUXq7H2sdFWqjgPq!Q1!DC z`p+xy+$<`bEyEtVK;Q>NWY_$R&W-}G5{;I|VV}ST|38iQZ4M6uW=BRMU9TCG{C@TX zIHlIL>OIwsv{Uj>e(a4|odMO_w$v3FL|U*`*~9}%;YIXI#7~VRR0+AXRdEzunyVkF zgO5{-k~EH=wTwJ_lD4?kz4+Y>s|vX`5?@qa#2{H%E(f|Of?%#d`PhuG2@--oCVoW0a^dV^uj<@iZfv2={xH6-1M@5=`=Z1u)0#>W?RQZn_lb@qr%O9!GUyzOJ1g`2@Shy5h+hcL>+|0Q7^`Q_qY91M zE!N4%PN|sqeE$IEy(Ca^ul~KI>Ay{fYe9{gv z;;MDeu`-M_;o>uy`Ti%_pc-Wiq73jWOK$gr7Ga#ObyXVf z2^N9gfDo`e`2KQEw0`_@px**j;nz5Fbt1ApzYzN;;7vgAA}P8~xLDp1$ym9_XPROGfTP(QjYMqQ%Rk3t!rm2ugtVy_k>yX44?-wcL3)ZOA^8SFn zbo3g2`un_oEA)|s;S;gK%xQ}WbBrlApR`>~S;;xp+lI%O=RnWrSB0ynBb-5Q70DHZ zcT5u+!N&l=O1$d*kHRED|0eUDW?2WHI8yQSo#_(!`-}#dB||Y#CGPxq{<_rc49O#uGqlZRzo=mAUBD zVzE~8Ie9jas8Kz!%6Aj1?#+XK6wcQ5B@1~8^2AKmDQeEwOkZwvVMT0}aK1{PNc$5O zX)H76w2SUqB(sXoT3-h=ZHemA?^aRl*RdSiRQxX4K*F=JG2%Y$Uw4l$g?9j|$afPh zDK0dWD|$1C|KGUF{eC+m39Igs_(=jB2VWMHhv&;-scm;!@l@R{mbGZ7huRITG{*aS zua4#oz(|4?z-G)+IGbf81Myi~KN!6}EyV)LwAgA9ht6{iULOJTjT3Wrj=3z!0QaJR zfe1M1b)Q(Bp?t(eYC6pLse?vq0Oo~*R|TMlOQ)2O1bWXWn_@54D$Hpz8LxdLU-WQS zzpII_caF!m;M$S8lIGe!T9$Lgip0r&UDeDO)+{AQ?^t;jQkmItVPcwpb=7nX|Ghld zfu?=wM~GnJaj4rYpeQF&sC>H@q!J=H6^AR{>wx3p2lFaOPyvIqSsNB{$@Vl(i`n$?U}(1oOI&aG_`&yNPr!;z}*= z8sP#h19cUJevfum_SCtyO`*+?S&FI1d~9en3&>x}Qs|eOWS6u#{mcwDC=K)SGkD8l zb~RVvhdKXU;pyj}uUp6DQ=eLQ?Qb4I=Uru4+y}h_r(288v+}-8N=MOlKK+!}>cJ?n zFmnbs5H2m&2<{G+Y!RMK*1m5b(YPPP9}Glm0oHK&Tj_R=c(7p$8Ls#^W&x6z!3i8a z_^l(j&c5MXIe{ete5!aSzx|68H3??d_AjR^(mHE&?{F@u*JhMfm$*$e3jyb(q zI}2~8TQ6%Woe%%~z9^rqGH;EI*QY*BmxQ|&O%#W3sR{fdfFD|1GC~YG+gP^Am`A}~ zgO==()dTPKW-=yP8rewd>Q2ESAZDfM;ase9As4|b39U77a7m5L zrn*Spo{$vodH;|$UW2&tfM-5|%|5z_W5+K~6-C`6&I@Gqf~@@nAT8~b)4eZ0c~|c- z1n>@1F4_~@66B`6%>(XmlA*fz5Hxvg`^~2d%)6Tr3MQ)FTY0`k?iG2)paQuyzSSRM zYbnZ8FDoCrGsc*>yc_>W3t93I}Pmm zVm?`;VzY8l2woM;K*}XBf+^zrq)SC$0|El408}5EzPU|mrmQbzQsBGY&6{is`AIPU zaq8Tn+u?ikR2*%R0_X7{%>6Y;FIl_Fyuw#qlFh*jtbIm3W8dgzEDifUhG1%a*+8q^ zFf5RD(*(`aSwnGaR>17~lq~S-@2w8~!e6yr=;(G1q2!1E8Do|Epwa3pG`9KVr@?od zk6pE0U_&F`tME0u;qFB$?~1TLhI1?ErA$~w7TE*|cY9@FK$cwN#bhe&PbD)hGLuA` zaO}yRzi3>i@p>!o*k7%~I~D`Ody>hiNERC~JK)b_#e>Xnt+7;uR2~DW44rXBzMgm4 zIvW-}9d^GbGUp)PQd%Q2Lav++QyEy=TAJNz!4;^J{OzSRl{WYtf^-F%)4bb3&^tC% zdpd_B67O)jonS8U+WBL9ssJnjie+JKFN-OKzLsJ?c0q#+rV|L-v3owUncrjAb>2T| z40lVAj%B)P=J8=SA>xL}f5{zZ9m1|q$g=4WE*9$uSc1KLxKK?2<{9|0R{IBgVuuHi}Q+&_OgxB(kgkiipxkKpgX&G zz)(B5su#HV=vQeehu_2v!L>T#UXc;^wJ1R2OBaw*%I9l}3!iGCPsQ!~WuWtR5HW0GY|3o0(8HW5QHGj}bg~!gi7RUSg z{D6fNYy5na$5S5AEI9v4YqbrmrJ?4N_0rUt5Wzncb* zu$H@j0CkIXY60oml>!NYfPkMmJ?1jo#~A*aG%`7Kduk}9*czW9jr|hm@ac0uk%XYM zN%e?p1&g;$lTcu)SWP8TO!~RN+KC2sR_Exw>@q@l zZ%Utu3{27(4h8pQoU#Hip`rX{plfGX|4+C_fESRg$T`6vcd16#ey?mN;!l8-c-B@c zhqikELh$l}=rbj5oA0&!Nv}I*>ug^|XUW9_`@Y36>|EVN$P*a1=;VAW0BG-w!5a*{ClbGSXNdN<; ziRTWTcF3%xoE2G5U34?rtt5CwKPz}d8pAsr@tT%7L=YP7Irjn26*u!Sg=5{mX2U*O zNWkhpwrBlupU`Xh1uyu)F-65@ef4OZiRg>6chW|@AAHY=Q8QPc;_;HMveVQn^$FeQ zW=`4_OuiT z!gR&N8+n2cxioL;9>)u5?!>8gXXPiN%a`XJXWe*X_^X7ww&e4%1LsWQn-*b_j`Wr! zy{dk^Bk+jsM5#+}*FWi>`-U5LGC2XE;O*N;X^-?7c?95bhJT-*xY&Kz3F3UZW#iG} zxNs|gR~0u|)_QGT^OFZTMEHwhb{5AGq-hxSA4}3MeT;o9EM5|1G-i?`!2XsgPk+nh zzkNHQgT1$a>alCTl16-E>oY&^7Bq!?8M1N{5{J|@Cwc4sA%Rql#3)&YiyF-sJ;1Sw)g2uLE8*spPG)lGtE1Vb#;AWNjfuZLx3JAWS}nvMucDk}Jci!; z+o?GK-OYb<`d)J*3JhwAd-u|oo9WI`cWhbi-_4nj9Y(9;o-Zysm`F_TW1m``jIHla zF3ji)tl4h`TmTTQK=?VnmoT&Xe{{>**1O^^$%-Nf=t+BMdBYuoT53S1`PIjjMi{qt z7c_vlsLkrPA_z)+0$2yC0TQ6+R~KPkbz{%=>l%_8mj|bdj31E_yl?p_2mIN!(!SPs z&aSO>N?h+pYhc*p7`<;l*MH&@nJR9xWsR?f(ES@e2{wzpPmno?q^oZ`(GfhJvQb2l zxF~!EX6x*xGl1VzH5d&o+O}1pdC&--OV@IjtbN_^n*{%{KLpb_=FJ25TYhTia8R+} zCh2ned3*@ovzuGc6R27x9@fdT-2PSx6Rk@<3EW83ARvIn12M7S8Ahb&3difVpeiyv zs^|zm&Ebt@zu;XVCip`P{31bZ;LLz{>H&6WhSDzM)Jywl&#>JT)-d;R=5_D}Zq!|F zhLE6D5*S%YK=4Q8IQ!qfe`)_~K;t5yF8=R-|93b3Gp+M~Z-)QdXCc3i6lm52@{KP= zH5la3YKX+mTJp7Pu5DsQKoHWy(j8QX% zjP4w@r`MlOY^*Eoz}Qf^5wA-%fFL*e<-xMg4gjE5_E5D5JO3sS^ahN^(=Na?A?4(S z4s|vdfhsZ5s;Te%_$%hjGUuVISA~5Jp!EO{?p%BsMm`zV`6rW~ zs{12QGVJ3JjqT9e5*LJ@z+XTY$+r61@8jArw(Tn@UMThO6Mf)Z~@-VWjtZSB9D z*w8s_(3KKJbPH<~21xvf+?`8k!KQ#}_`o1E{2=L%L#vBRnt zSlCJN-Ia1F#eT8qC&fu*aiNnOM?(UYBkFM+jCIx2Ho`egfs zNKx-MI}ZSduI=HhaIHHxUbG|at#9>*FMPQ>2k6muZjn2zeoh5+X@IYxUwW9=>flg& zPwIPpqqWOvFxpf5iFq(lOC37EsR0m{kg7%!di2S~g|}CSd9XP{$Z@=f08p6GcG>G^ zM{Tl4pnAtIh0w+lfM;*!G-^auL}r9hHN=nK+`H3U*eSuU2k6S+=K|MlBZF!F$IYG` zuH~`yu*tcW0DTGZa5Xl*lyrnxDdAU(OUpv`J(7N)OohbaPMh-2V7Jvl@!9+weKlAG zVkS=vz=edN83dWPzH1TWCgVNR^r+F$0^AEKD+x5Y?n#j$^8{ zFYkGyNbr~A%l#l^ZLtx@!p?R;t7}kzew!D)il&cUc9VvaV*_~hL&u;yq)tAJJM$f& zPyuX#XLHpt{13p{9f)n?%|_5maHHX^vZofZR4fTnM*FIgN+T}ePJy;X>< zpapmf;Pv?gB5K0>A*T&m@j&;n2K&R=4UhPlNApH`&vvUNW}PVL8kEXHIW0ZQdY!mf zjz>8+vp&sEbBVt*K^viVFNOqHwm-ukndzpb*9;j~qlDd!p2O6s2xn@7|6xt&Kdc{j(FDfX=;dh>ZO%6!W*$Qm-X+Ql(4{cU$tCDykLTh; z-3I}S;&|_ zW>V^MWwlrSNwNoyILEslIe~XnQ5=jh^jW1Sy=9Y(a=-yY49N8A;A>W)sd8=CfbEF$ zoB>uH4g~@~yPTIbnq9p{KyC$ubp|bp=iOB&Kk>t=z8(p)nvSXAA&*{)Xs;H6tsxUd z{6494teyIxS}OlqVjr-6X)GL?99ogf!+G*ld@Sn=@Oyw`k}eG!a18L|=M7THagY1S zL888rL3s}e41h-Y@4@F@ZBSPJ`V6E{UNZewIj6yUGSi-%3N|g^BDfB;^h`<*D37>W zFial&oc2}rZ(aYklI1TXaF3dVgG!DLTNus)^ziksc?Kyegb7v>&>bzxRQyxmA?^E_UE`0L$$}-|e znkH_N_E+}d>jopY=_?EmI2mDUtWl^~)>*HyGc}|G5Q{9JlDp*6rHa4TU%jQOFeQndh%3@L6H}9^lrH{+N z6ne%Fo~!WBL6iX#bXS=*ot#wdRUv^5Fo1#p2DFL52yWX&G0l+hy>n4F!MvA6JALs< z3OfZV;zSl896^!f^Ppf{tU@ugRd|s*n z;e2-;p#CB)^bw$)&B#kMWFWb*4a+vV5bWhh^1g6x4wRtu(9G*~MSQhov5jTUK3O-2oOl9)LR z%Z2PE>c?GGW#&y7vaj0VzRFO4B^}wATSZ-BDddo%5@oh?A|RYtmM8AWR)FyOfF*=7 zp4|x2>F#+Hq@zh)<(%hF=JDxz%MIEq7P(ezO(P&!M3Ob9;%8nGuphpJsz=t109M!a zf(1zAwIr8ofbZGh@q4bG=3L?n8%TB`WIJX~r~tn^*}= zT$O3;Wp%3v^tjf`ItE|;(s29Di3*MtSMjyb$mQE;Aq;x-<*<{0^=;P4|F8fC>fXIm z&&KPDSW$)sFyp!HZSm{wNBFRa&j*dE?NW&C5s{mLYl>=a! z7Etw#>Ae5|aZIVyFtT4N1T~;7vpz%5$x%1ND*M&^$ZCOj{cPV$cNwprSw!1PRJT7p zbDiiivA#7|T#I~67&M@8aYp&Z~SPixa)Fych#8B zrCDgh5XR<8YvJ==b&u-kmqt3<4gL?SFVtX`d%A3@pIKRDuI*860qT>-LT_CsaAi8# z?@%%IDP=&JrO3s7K)|Y`xJ6@>N=1(q0>sltUZ?2A;>MWcF6WgHk zST)%Pv_Apw8=xEV{Q;!24)-1OI3?M1jY9&LjGXZ=lJ$dp1`m)kbebo|63&z>6aHcR zcgi#KZra^7sJ}O-@>97>6UFB$7Ae2~@Zf4b2k=yjIVB=#KN)oWntrgzIHhhDWL@w& z&L??M?00P!@lLrlQg4s#q4)zvgB9cPQ}+GPN51_nYR$%>lLWc9YwI`#30M;19`jcB zgQ@52Nahx{gfV2v*I4D#$a2|r>7Mza~lYH_kR+DS$l%2+R)l zLH>jD`wZhG`=!x*yKZ0pPkYz>*5tCSqo}x5iW{&{k4FIkF>2^t5VHXRDS~v%mM%z# z1c=z!fPfyFf&oE7i+~8BlZZ3{AqYYup-BlP6oG_5LXtape!BNhxDVfxACm9+GMQOx z&06oQnRms*;NzYcUYT*{vi8m<3&=v07F4rrN?q=i3^s(^pm=svM|6^i_jP1jOV`bb z56r>(qOMTwEWF!Pthqdsq5kzSe2YEwLb~Fe*V*N*vA#M{b2Mw_EsdBnv?iq{b-U}w=V<;z|-ZAe%ZVmJ1 zC;^e_*>IXViCk0&(~;=k zxV|5zzGg6DA3;ENXZ)S6?4tb_@0ZWz*>_~q?eG9{N(AIBt}15bE=0bfV$?au&`gNj zdG6HBfWD1IN))27zI~|AqKxf~_KeynF(e5*3pL%`EcL&YggsfGd($EDrpv8b!Xfb> z`%YTw`ATb=)rtCMU)iDB!_6*^eQJ0%A}ko46Vi5(Nc?Gf!+HiWMJJjH+m?Ys0}IZl z)m_H4hg5688ZUezC8b6Y_D~ITKk_D@hJ%Yb8E0}Er;zO|6()xV$K7^HRLBhqgAxNi z=@D{e=f?G5ACn1Oxf6e+kSjLW?&FYHx~sb(G7MUGZgNYR`r)QDxcAvDq2t>*a?9)|*$| z%I?$^m8+Fz&|*LWu4Ym&7jhjd5Gli_5hw5^J==M;AK~*eJKW(O$Q*LduUw5enbhS1 zV|x}S=}m&ozSfetu%aj7BRz?0)n~O4n&A@di}7mrbkf5sUVc|uiJWO! z{jj!ZY||}rRAN34U-qh=`HHpP70%>s2qN22pDD>hQ0x^oa!vYGLafKorq7w%fp{9( zUTiq~8$l#h7+MyDt~op^uckQrwZ<(Orb9^^W50B8ZrgVOQu_XPhwC`olBef9?Ho+E zC!*G$hFD$Q<16dx>_3Y8f(z7n8@G}e+~d+|k&+=+EAEYQx!d&Tx6jqS0poD$C1&tD ziD%Ud=a(4)gAh{CNcfde+y!TmZ@s*ZXZxBh4_?eqp}yuYz8q4zwDEQHwti)S!sD(~ zS4R}{s*+`y8t-HObIIz8v~X`+1T*geIIj3}=~vlDL{)B3f4;|;Il!KrPG1KnB)Rkm z8@+~h?WRhqf<^%G4lJ;+J2oRLYeeEK{1cqktC=>e>*HAs4oG zSQ}YQxaGYR+dOwrdosLU?_W+>wZU|2RiqhRL`)Wjd%u#X;)iz2_{vPhf+PQ^`!7PN zUXIs~H*~iF@Gzd%b+&C0U=<>-N@Vj7 zJC^9!ti8z>29!9O>RJfcBSO1`V(u3AS6ed%WaDyN?$xI8ljUZ7G8hA{VYbTJ));B0 zlk2j*7AXWt$|wH~K+5SBd~!&M7QOx}aDBwj@zVZQ$Xm@S^vd55d8k5b)7?aw>|zNM zl$@7!WLW+x<&TRsIPIFO4LaT6>V;x8JJONWuC^HIxFH#K&l72o43Zrq6Jbq?CF}J* z_Och<<^Z0S%aI6cnP&msl*w|w^!K*MQ;8x->KQ1ZX?xrR@mW+$15U*>L{}2>7^GC5 zyYsEc>k-T3;RiQ_d%7pTrhb!wa@ zi5S4*;nk^ZK8F2S^|~W;z?GmgQS3Q=+jFwMndOtguj?~FiN_w8v$TNe^w1pZMZxh( z8F874&IlD|G7Ntb8J8s225_54fkeQDr0)k%)_~`H?9GcJO}$H&Y$B$a1!@}omo)}U zFg*pd&yBXab+e3iVo3I4Kv~`Xkk!`jpO)UyQ)`JxYdn`|wwEvEASU1q$%Tzt{*nB9 z9l3>Vhdi|5w;@0_|GEs{syP{x$U`BS5>6zS@qle-idRBZ?k7J<4=-A6zD43z<-BH%eVIl{ zzZv0ePX|FoJLD4%Ync+5&+=A2_iGFG zQCfL8ezNp<>iN14!Ar*XSL&*wZj&@QFmwJ5fMg1D;*KhO~L+NYd?(tUPD9wfDGl?cj;9d9+p_$*qaq!=>HlQ#q9F^#^vMKhFXIU0jgkHd^!BC@7iAO* zcdD3$5}8i&ke?&0{e5JMh>)qU&`v1+L%ucSi@YsFoE#R7*!Gv!RO=3%U5zX5X(>OH zmUfsk&Hr`}`Q6^WqU=cb1^=+dU^-^Fgn zSdURiq2r7~hVTW*D<{MKZ%=V1)ooA}^W@w(SU7}aJkzf~zBWAW!3SCBM0Y_1=JV9k zxvNd<2urq03wzv}Rj6;H08u$&zcY~5iedul&KgiIuO|WK>KI`JU;T+$LNVY==ylse z5CNkih)Ux^MKPS~;Y}eXuSB^o*u&%BLCw+QR*roRjZ4ayn1o?FCa$TIT>$Cxd;)ed zggd0gzydC5XUA*u;O^U9IqVw2?qt~Y1iKz_HyrGS#a&FWi;Z@H;VvrPMa8?Qco!A# zqT*dtyo-we7b>w=_PU!I1m`I3LN$Z-4a9V^NL-(xndL?s-Dayu=fKZelk zcvGiSuHRmE3H@=8Mk*&vJUVOWE{%Of|7)8)ZeMn`>8Qme;QzZNb zE>NVVri{~gWimkob7zOQ`Z}=-|mf~!g3sHAN=gJ)Yj5E zkKdeBcB)os{n;0(nASC`$E>@7wL^!EMKE+$((GO9BDdBGvk?nhvpMCn5xJOc3yi37 zz*xjAgHGR`gX?Fu6u*_T`jQX+1J8a}O4=g3p(X$a}DA3q{ku|}}@r6nnG@simk*MYR|8RT-E z$9z8~NP|xW^I8#eHr^ZO$cvar)nOcdn0Geb6cd=4c1cYw^w&i5V}7CRZ{|y*qoaq9 zojaS+ZI*scbLRMX2+0MEWOic&>0j~_nHNudFG-Kw*vfgRrZ;-79M7hQ7zF0lmb&NMoOG9Jx6Q9tV1SJU(5fLH1%?WUk z$v1nTwKM5XKv53*&?><+Ln9GINa-?qCDNlO3vXfDHP(bA&i{bJ;rfhX%R%3?z`927 z!IB_EsOKHUr&mFW-Eov(f3rE028^nl7`hP`7nhrxn@NA0M#JV3`K+$A!`+QujTf6TPvstqYgEm$5rWk;8T`D3w z&w0CldY7!{$TNx0Bi9AZ(%Y2E8$WVW3{E@N1!7EdUx&+xJxsR?dfdh3uxa`xR-&+_ zc;L?%gwK45Gb~!UTaDl7wek{C@s~e$k7*I)mm)k#@^wok=|~zLk7rr#6}XJ) zYX#$23HoF`?&qOt?%>WN!N6)OZM!x%YfW>ve&3jynsVc= zWq2TP4GnCOoXsn`voTsgD-eNOw4u_dA8XlD0E z+i%tf&x0vhSe~4in3$9_bpME_pyN~OzjkJak&v!!5a*o?$1_TrH%Or%fd?6k^a4IB zYc`;_X6ii&yKOkjkk=bW>fy#r{oukU)Db2ir+c$3D6bxmDum5Zf@ z?|}3~$2Z&6y~{GXXDm^yfv}N)jykfFTd}R)Mn&={a-~UC2{^ZM6o)ppaMV?()X<3b zina&x3Q4KH?^G8!^XZd8k3Ii^ooi!>Qgg36y$Q+0_nMz>`hD5EMKP`wYTphI-~0(8 zfUf*rFoo(ve5^!)v0%3rfU&59coi_!&Jx^TXj}xj4m>!I!-U@aaI5n_vaqPjK&>bg zFD{w6LM}bs(Nby@ClpbMZ|`<%)fb0f-FD=@iTCKumV*%8$xfx=^efOiK&F z91U9`SKPJegH#E&ONSCkFFF2S!x)L1*@90+l zx3n&Te%NjEb0twv+ddYxn&76xY02G^)DHD!Z!CdV!}eOY2SS?UU|(uSSW7F{`Sppf zBS{KNJejMS`24w~R4&AKHGsef3)a~?O%NZ1HiLq8Ydi+(s*!dpuil+ zLm*f~rNXDYX@i>OpM5WuLsQq$+3o`-#oe6BzH%gF07w%sE{Hk$C}Os*gu35*J8Y2d z(eJ?WG@hDbKKlOnSVQ0}?F28SZy>U5ROWDeK}bs0-FRib4*7ltJO=|%19*k$!ksY6 zp~0_SwQyBFDI;Sq2YDlyyB7j!UHuN-O@#fQMA){>9k-n61p&T@9VV2CvBi}#!&{I3 E2Mm9Wj{pDw literal 0 HcmV?d00001 diff --git a/example/README.md b/example/README.md index 80716b9..be615e6 100644 --- a/example/README.md +++ b/example/README.md @@ -2,16 +2,23 @@ This is a sample app created from a fresh flutter project it is useful as a playground for experimenting with/testing the c2bluetooth library as it is being built as well as providing an example for how this could be used in an app -This app simply connects to the first erg that it sees. +Currently this app just connects to the first erg that it sees. An update is planned to make this a little more user-friendly for testing in environments with many ergs. + + ## Sample App capabilities ### Get workout summary information -1. build and run app. -2. long press app on android(samsung) home screen. click the info button, go to permissions and enable location permissions -3. confirm bluetooth is on -4. turn on PM and go to the screen where you would connect something like the ergdata app (usually this is a connect button on the main menu) -5. open/run the app. it should do some discovery and show you a stroke rate: 0 message -6. hit back on the erg and set up a piece. Recommended to set a 20 sec (minimum allowed) single time piece. -7. start the piece and take some strokes. after the piece is over you should see some data for the piece you completed appear on screen. feel free to modify the app to show other data points. +1. build and install the example app for your platform. +2. confirm bluetooth is on. +3. Accept any permission prompts you are given +4. turn on PM and go to the screen where you would connect something like the ergdata app (on newer firmware there will be a connect button on the main menu) +5. open/run the app. you should see a screen with a "Start scan" button. ![A demo screenshot showing the start scan button](../docs/images/demo/pre-scan.png) +6. Press this "start scan" button when you are ready to start scanning for ergs. You will see a few messages on the screen while it scans. Wait until the app says "setting up streams". +7. Use the back button on the erg to go back and set up a piece. A 20 sec (minimum allowed) single time piece is the shortest thing you can do that still works (just row pieces must be longer than 1 minute in order to be visible to the app and be saved in the PM's memory). +8. start the piece. after the piece is over you should see some data for the piece you completed appear on screen. ![A demo screenshot showing the results of a piece](../docs/images/demo/completed.png) +9. you are now ready to start making changes to the sample app to play around with the API and explore the other data points that are made available. + From e5554a6fc8ea13ff357a44653ebb22b87f0a4547 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 07:09:12 -0500 Subject: [PATCH 096/220] update scanning to work more asynchronously --- example/lib/main.dart | 63 ++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 086f197..94de161 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -55,39 +55,42 @@ class _SimpleErgViewState extends State { } startScan() async { - bool goForIt = false; - - if (Platform.isAndroid) { - PermissionStatus locationPermission = await Permission.location.request(); - PermissionStatus finePermission = - await Permission.locationWhenInUse.request(); - // TODO user feedback on no location - if (locationPermission == PermissionStatus.granted && - finePermission == PermissionStatus.granted) { - goForIt = true; + await Future.wait([ + Permission.location.request(), + Permission.locationWhenInUse.request() + ]).then((results) { + PermissionStatus locationPermission = results[0]; + PermissionStatus finePermission = results[1]; + if (Platform.isAndroid) { + if (locationPermission == PermissionStatus.granted && + finePermission == PermissionStatus.granted) { + return true; + } + } else if (Platform.isIOS) { + return true; } - } else if (Platform.isIOS) { - goForIt = true; - } - if (!goForIt) { - print( - 'Your device is experiencing a permission issue. Make sure you allow location services.'); - setState(() { - displayText = "Permission Issue Stopped Scanning"; - }); - return; - } - setState(() { - displayText = "Start Scanning"; - }); + return false; + }).then((result) { + if (result) { + setState(() { + displayText = "Start Scanning"; + }); - scanSub = bleManager.startErgScan().listen((erg) { - //Scan one peripheral and stop scanning - print("Scanned Peripheral ${erg.name}"); + scanSub = bleManager.startErgScan().listen((erg) { + //Scan one peripheral and stop scanning + print("Scanned Peripheral ${erg.name}"); - stopScan(); - targetDevice = erg; - connectToDevice(); + stopScan(); + targetDevice = erg; + connectToDevice(); + }); + } else { + print( + 'Your device is experiencing a permission issue. Make sure you allow location services.'); + setState(() { + displayText = "Permission Issue Stopped Scanning"; + }); + } }); } From 8bd7250d5e3a5a7de142cbe1ca020d472e052f9c Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 13:54:11 -0500 Subject: [PATCH 097/220] updates to standalone docs --- docs/API.md | 25 ++++++++++++++----------- docs/DesignDecisions.md | 5 ++++- docs/internals.md | 4 ---- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/docs/API.md b/docs/API.md index cc54f1e..adad656 100644 --- a/docs/API.md +++ b/docs/API.md @@ -4,10 +4,14 @@ This document is the starting point for learning more about the c2bluetooth API - The broadest overview comes from using the API as documented in the README - sections like [Overall API Design](#overall-api-design) explain some of the core concepts or goals that we wanted to achieve with the API. -- For people looking to get into the internals of c2bluetooth, the [Core API Concepts](#core-api-concepts) section below is a good mid-level overview of the various groups or categories of classes that are used in the API and what their purpose is. +- For people looking to get into the internals of c2bluetooth, the [Core API Concepts](#core-api-concepts) section below is a good mid-level overview of the various groups or categories of classes that are used in the API and what their purpose is. - For summaries of how c2bluetooth works internally and all the things it "takes care of" for end users, see the [internals](internals.md) document - Obviously the most detailed explaination of how the code works comes from reading the code and inline comments themselves. It is helpful to understand the general goals first +## Terms used + +"implementor" generally refers to users of this library. This is intended to be an audience of primarily other flutter developers looking to use this library in their apps. + ## Overall API design @@ -15,20 +19,19 @@ This document is the starting point for learning more about the c2bluetooth API ### Inspiration In order for this library to be a good fit within the community and provide a good user experience for developers, the goal is to design the interface for this library after other existing libraries interfacing with Concept2 rowing machines. The libraries looked at were [Py3Row](https://github.com/droogmic/Py3Row) (Python, BSD-2), [BoutFitness/Concept2-SDK](https://github.com/BoutFitness/Concept2-SDK) (Swift, MIT), [ErgometerJS](https://github.com/tijmenvangulik/ErgometerJS) (Javascript, Apache 2). -There are likely more libraries like these available, but these were just the first few that were looked at based on a GitHub search. +There are likely more libraries like these available, but these were just the first few that were looked at based on a GitHub search at the time of writing. ### Object Oriented -These three examples all seem to use some kind of Class-based approach where a particular instance of an object represents a particular rowing machine and contains functions to make interaction with the machine easier, like getting data. +These three examples all seem to use some kind of object-oriented approach where a particular instance of an object represents a particular rowing machine and contains functions to make interaction with the machine easier, like getting data. -Designing the library in an object oriented way seemed to make the most sense given what other projects in the space seem to ave done. This should also should keep things relatively straightforward to program and maintain. +Designing the library in an object oriented way seemed to make the most sense given what other projects in the space seem to have done. This should also should keep things relatively straightforward to program and maintain. ### Subscription-based data access -Both BoutFitness/Concept2-SDK and ErgometerJS also seemed to have a way to asynchronously "subscribe" to get a callback when particular values change so the screen can be updated. Since the FlutterBleLib bluetooth library also exposes [Flutter streams](https://apgapg.medium.com/using-streams-in-flutter-62fed41662e4) for reading values in this way, it seems like a good choice to follow this model when exposing data about a PM5. +Both BoutFitness/Concept2-SDK and ErgometerJS also seemed to have a way to asynchronously "subscribe" to get a callback when particular values change so values being displayed on the screen in the implementors flutter app can be updated. Since many Flutter bluetooth libraries also expose notification data from bluetooth devices as [Flutter streams](https://apgapg.medium.com/using-streams-in-flutter-62fed41662e4), this seems like a good, clean way to expose data about a PM5. #### Single Values For getting single values from an erg, such as serial number, software and hardware version info, and other things that likely wont change that often, Streams may be unnecessary and it might be easier to have a simple synchronous interface for grabbing a value either from the erg or from somewhere in the memory allocated to the particular Erg object being used. -Whether or not this is actually a good solution is still TBD @@ -43,14 +46,14 @@ These concepts are roughly divided up into "external" (i.e. those that are part ### External Concepts #### Data Objects -Data objects, like the WorkoutSummary class, are essentially wrappers around data provided by the PM and allow the data to be accessed as an object by an application. +Data objects, such as the WorkoutSummary class, are essentially wrappers around data exposed by the PM (Performance Monitor)'s bluetooth interface. This makes it easier for applications to access this data by providing a more object-oriented interface. -Data objects are primarily one-way communication from a PM to your application. +Data objects are primarily a form of one-way communication from a PM to your application. -Data objects are located in the `data` directory and represent a large chunk of the public API for c2bluetooth +Data objects are located in the `data` directory and represent the parts of c2bluetooth's public API that are most likely to be useful to an application. #### Model Objects -This is a gairly general group of classes that represent various indoor rowing conceptsas objects for ease of use by applications looking to interact with ergs. Some examples of classses in this category are the `Ergometer` and `Workout` classes. Unlike Data Objects, they are intended to be able to enable bidirectional data flow. For example, an `Ergometer` object may have properties for getting data (like Data Objects) but also may contain methods like `sendWorkout()` that allow you to provide a `Workout` object to set up on the erg. `Workout` objects could also be returned by other methods as a way to represent a workout if needed. +This is a gairly general group of classes that represent various indoor rowing concepts (in the form of objects). Some examples of classses in this category are the `Ergometer` and `Workout` classes. Unlike Data Objects, they are intended to be able to enable bidirectional data flow. For example, an `Ergometer` object may have properties for getting data (such as Data Objects) but also may contain methods like `sendWorkout()` that allow you to provide a `Workout` object to set up on the erg. `Workout` objects could also be returned by other methods as a way to represent a workout. -Model objects are located in the `models` directory and represent a large chunk of the public API for c2bluetooth \ No newline at end of file +Model objects are located in the `models` directory. \ No newline at end of file diff --git a/docs/DesignDecisions.md b/docs/DesignDecisions.md index c9d198f..0b52632 100644 --- a/docs/DesignDecisions.md +++ b/docs/DesignDecisions.md @@ -1,7 +1,10 @@ # Design Decisions ## Bluetooth Library -This library ultimately depends on some bluetooth library to function. Originally the plan was to use [flutter_blue](https://github.com/pauldemarco/flutter_blue) because thats the first [tutorial](https://lupyuen.github.io/pinetime-rust-mynewt/articles/flutter#bluetooth-le-services) I came across. However, after seeing how many open issues and PR's they still have, the decline evident in their contributor graph, [comments online](https://www.reddit.com/r/FlutterDev/comments/hm63uk/why_bluetooth_in_flutter_is_so_problematic/), and [an analysis on cauldron.io](https://cauldron.io/project/5134), I've decided to use [FlutterBleLib](https://github.com/dotintent/FlutterBleLib) instead since, even though it seems similarly unmaintained, it has less open issues and seems to have reached a later stage of maturity based on its version number being in the 2.X range, rather than the 0.X range. +This library ultimately depends on some bluetooth library to function. Originally the plan was to use [flutter_blue](https://github.com/pauldemarco/flutter_blue) because thats the first [tutorial](https://lupyuen.github.io/pinetime-rust-mynewt/articles/flutter#bluetooth-le-services) I came across at the time development was started on c2bluetooth. However, after seeing how many open issues and PR's they still have, the decline evident in their contributor graph, [comments online](https://www.reddit.com/r/FlutterDev/comments/hm63uk/why_bluetooth_in_flutter_is_so_problematic/), and [an analysis on cauldron.io](https://cauldron.io/project/5134), [FlutterBleLib](https://github.com/dotintent/FlutterBleLib) was briefly used instead, before the project ultimately switched to using [flutter_reactive_ble](https://github.com/PhilipsHue/flutter_reactive_ble) mainteined by Philips Hue because it seems to be the most likely to continue to be maintained into the future. + + +During the transition from FlutterBleLib to flutter_reactive_ble creating an interface to represent any bluetooth library was considered because it would give implementors the ability to use a bluetooth library that may already exist in their app. This would halp maintainers reduce app dependencies, app size, and conflicting libraries, but was ultimately never implemented because it would make the process of debugging implementor-reported issues reported against the library more difficult. ## CSAFE API Usage diff --git a/docs/internals.md b/docs/internals.md index 72cb15e..399e8b4 100644 --- a/docs/internals.md +++ b/docs/internals.md @@ -3,10 +3,6 @@ This document is meant to be similar to the [API](API.md) document, but specific Only people interested in contributing to c2bluetooth should need to understand things at this level. -## Internal API Design - -TODO - ## Internal API Concepts #### Commands The command classes are based on the similarly named classes in the csafe-fitness library. There is a command superclass that is responsible for implementing general-purpose command structures from the relevant CSAFE/Concept2 specifications. These general command classes can then be subclassed to make clearly-named human readable shortcuts that pre-fill details like the identifier and command type while also performing validation of the command data. From 11c4d1708ea5d41be01a3bfc4464ec8db5d4a029 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 14:36:23 -0500 Subject: [PATCH 098/220] add a deprecation notice to monitorForWorkoutSummary --- lib/models/ergometer.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index 4d258ae..5b0e4fe 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -54,6 +54,7 @@ class Ergometer { } /// Returns a stream of [WorkoutSummary] objects upon completion of any workout that would normally be saved to the Erg's memory. This includes any pre-programmed piece and any "just row" pieces longer than 1 minute. + @Deprecated("This API is being deprecated in an upcoming version") Stream monitorForWorkoutSummary() { var workoutSummaryCharacteristic1 = QualifiedCharacteristic(serviceId: Uuid.parse(Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID), characteristicId: Uuid.parse(Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC_UUID), deviceId: _peripheral.id); From da9232198631c76b00af8dfd9118ba0b3c09a10d Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 14:37:05 -0500 Subject: [PATCH 099/220] swap bluetooth backend in dataplex class --- lib/src/dataplex.dart | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index e75d2df..82d3c16 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:c2bluetooth/models/c2datastreamcontroller.dart'; -import 'package:flutter_ble_lib_ios_15/flutter_ble_lib.dart'; +import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import '../constants.dart' as Identifiers; import './packets/statusdata.dart'; @@ -18,7 +18,9 @@ import 'packets/base.dart'; class Dataplex { // data access speed - Peripheral device; + final _flutterReactiveBle = FlutterReactiveBle(); + + DiscoveredDevice device; List outgoingStreams = []; @@ -65,15 +67,23 @@ class Dataplex { /// set up a new subscription to data from an erg. void _addSubscription( String serviceUuid, String characteristicUuid, int? dataIdentifier) { - StreamSubscription sub = device - .monitorCharacteristic(serviceUuid, characteristicUuid) - .listen((data) => data.read().then((bytes) { - // manually insert an identification byte if this characteristic doesnt have one already - if (dataIdentifier != null) { - bytes.insert(0, dataIdentifier); - } - _readPacket(bytes); - })); + var characteristic = QualifiedCharacteristic( + serviceId: Uuid.parse(serviceUuid), + characteristicId: Uuid.parse(characteristicUuid), + deviceId: device.id); + + // this stream should get cancelled in [dispose] + // ignore: cancel_subscriptions + StreamSubscription sub = _flutterReactiveBle + .subscribeToCharacteristic(characteristic) + .asyncMap((datapoint) => Uint8List.fromList(datapoint)) + .listen((bytes) { + // manually insert an identification byte if this characteristic doesnt have one already + if (dataIdentifier != null) { + bytes.insert(0, dataIdentifier); + } + _readPacket(bytes); + }); currentSubscriptions.addEntries({characteristicUuid: sub}.entries); } From d199551f837abbdb02f2ee086851f14f5af17318 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 14:37:38 -0500 Subject: [PATCH 100/220] make dataplex device object private --- lib/src/dataplex.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 82d3c16..7de8fa4 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -20,7 +20,7 @@ class Dataplex { final _flutterReactiveBle = FlutterReactiveBle(); - DiscoveredDevice device; + DiscoveredDevice _device; List outgoingStreams = []; @@ -35,7 +35,7 @@ class Dataplex { WorkoutSummaryPacket2.datapointIdentifiers, }; - Dataplex(this.device); + Dataplex(this._device); ///Keeps track of how many characteristics we are currently receiving notifications for int _currentSubscriptionCount = 0; @@ -70,7 +70,7 @@ class Dataplex { var characteristic = QualifiedCharacteristic( serviceId: Uuid.parse(serviceUuid), characteristicId: Uuid.parse(characteristicUuid), - deviceId: device.id); + deviceId: _device.id); // this stream should get cancelled in [dispose] // ignore: cancel_subscriptions From d1a0d9d3ca6d61c1d4cbd874ff53b1b188fa8042 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 14:38:31 -0500 Subject: [PATCH 101/220] remove monitorForWorkoutSummary method --- lib/c2bluetooth.dart | 1 - lib/models/ergometer.dart | 20 -------------------- 2 files changed, 21 deletions(-) diff --git a/lib/c2bluetooth.dart b/lib/c2bluetooth.dart index 5fb67a9..855baff 100644 --- a/lib/c2bluetooth.dart +++ b/lib/c2bluetooth.dart @@ -6,4 +6,3 @@ library c2bluetooth; export 'models/ergblemanager.dart'; export 'models/ergometer.dart'; export 'enums.dart'; -export 'data/workoutsummary.dart'; diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index 832ccaa..ee470d4 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -63,26 +63,6 @@ class Ergometer { return _dataplex.createStream(datapointIdentifiers); } - /// Returns a stream of [WorkoutSummary] objects upon completion of any workout that would normally be saved to the Erg's memory. This includes any pre-programmed piece and any "just row" pieces longer than 1 minute. - @Deprecated("This API is being deprecated soon") - Stream monitorForWorkoutSummary() { - - var workoutSummaryCharacteristic1 = QualifiedCharacteristic(serviceId: Uuid.parse(Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID), characteristicId: Uuid.parse(Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC_UUID), deviceId: _peripheral.id); - - var workoutSummaryCharacteristic2 = QualifiedCharacteristic(serviceId: Uuid.parse(Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID), characteristicId: Uuid.parse(Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC2_UUID), deviceId: _peripheral.id); - - Stream ws1 = _flutterReactiveBle.subscribeToCharacteristic(workoutSummaryCharacteristic1).asyncMap((datapoint) => Uint8List.fromList(datapoint)); - - - Stream ws2 = _flutterReactiveBle.subscribeToCharacteristic(workoutSummaryCharacteristic2).asyncMap((datapoint) => Uint8List.fromList(datapoint)); - - return Rx.zip2(ws1, ws2, (Uint8List ws1Result, Uint8List ws2Result) { - List combinedList = ws1Result.toList(); - combinedList.addAll(ws2Result.toList()); - return WorkoutSummary.fromBytes(Uint8List.fromList(combinedList)); - }); - } - /// An internal read function for accessing the PM's CSAFE API over bluetooth. /// /// Intended for passing to the csafe_fitness library to allow it to read response data from the erg From bc8287707be3b7dff82e02d65869341a744a7881 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 14:40:11 -0500 Subject: [PATCH 102/220] remove docs on data objects (they are being replaced with the dataplex) --- docs/API.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docs/API.md b/docs/API.md index adad656..4eef549 100644 --- a/docs/API.md +++ b/docs/API.md @@ -45,13 +45,6 @@ This library is built from a few core concepts, some of which are shared with th These concepts are roughly divided up into "external" (i.e. those that are part of the libraries public API) and "internal". If you are just using the library in your app, the external concepts should be all you need. Anyone looking to contribute to this library might find the "internal" concepts helpful ### External Concepts -#### Data Objects -Data objects, such as the WorkoutSummary class, are essentially wrappers around data exposed by the PM (Performance Monitor)'s bluetooth interface. This makes it easier for applications to access this data by providing a more object-oriented interface. - -Data objects are primarily a form of one-way communication from a PM to your application. - -Data objects are located in the `data` directory and represent the parts of c2bluetooth's public API that are most likely to be useful to an application. - #### Model Objects This is a gairly general group of classes that represent various indoor rowing concepts (in the form of objects). Some examples of classses in this category are the `Ergometer` and `Workout` classes. Unlike Data Objects, they are intended to be able to enable bidirectional data flow. For example, an `Ergometer` object may have properties for getting data (such as Data Objects) but also may contain methods like `sendWorkout()` that allow you to provide a `Workout` object to set up on the erg. `Workout` objects could also be returned by other methods as a way to represent a workout. From 27b8738e13c1352f0e234df16fddf70c442ece3f Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 15:11:56 -0500 Subject: [PATCH 103/220] remove README documentation relating to how monitorForWorkoutSummary works --- README.md | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/README.md b/README.md index f61067d..84a5dd3 100644 --- a/README.md +++ b/README.md @@ -114,40 +114,7 @@ To Be Implemented/Documented To Be Implemented/Documented #### Workout Summary data -Workout summary data can be `monitorForWorkoutSummary()`. This is a stream that returns a `WorkoutSummary` object that allows you to access the data from a completed workout (this includes programmed pieces as well as "Just row" pieces that are longer than 1 minute) - -```dart -myErg.monitorForWorkoutSummary().listen((workoutSummary) { - //do whatever here -}); -``` - -Each workout summary is a flutter object that contains the following fields: -- `Future timestamp` -- `Future workTime` -- `Future workDistance` -- `Future avgSPM` -- `Future endHeartRate` -- `Future avgHeartRate` -- `Future minHeartRate` -- `Future maxHeartRate` -- `Future avgDragFactor` -- `Future recoveryHeartRate` -- `Future workoutType` -- `Future avgPace` -- `Future intervalType` -- `Future intervalSize` -- `Future intervalCount` -- `Future totalCalories` -- `Future watts` -- `Future totalRestDistance` -- `Future intervalRestTime` -- `Future avgCalories` - -Futures are handy here since the erg can send back different data at different times. The primary reason for this is the `recoveryHeartRate` field which the erg sends after the user has been resting for 1 minute. If the workout is cancelled or the erg is turned off before the end of this minute, the data may never arrive. See #10. - -Overall this method of accessing workout summary data is not the most ideal, and is likely to change later if a better solution is found. See #11. - +To be implemented. From 94d079458823c90ba587bdbd4adcf0190e8ab0d8 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 15:20:01 -0500 Subject: [PATCH 104/220] Add Core Values section to API docs --- docs/API.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/API.md b/docs/API.md index 4eef549..fd60cb8 100644 --- a/docs/API.md +++ b/docs/API.md @@ -13,8 +13,17 @@ This document is the starting point for learning more about the c2bluetooth API "implementor" generally refers to users of this library. This is intended to be an audience of primarily other flutter developers looking to use this library in their apps. +## Core values -## Overall API design +These are some of the core values that were considered as part of the development of this library and forms the ethos/soul of the project. These should be used as general guidance when questions of scope or direction of the library are considered. + +### The Silent Protector + +This principle shares its name with the [popular meme template](https://knowyourmeme.com/memes/the-silent-protector) depicting a soldier kneeling over and protecting a sleeping child. + +![A remix of the "silent protector" meme depicting c2bluetooth protecting the apps that use it from low-level details of bluetooth communications with a concept2 erg](../docs/images/silent-protector.jpg) + +This is essentially a graphical analogy to represent the idea that this library aims to "take on" as much responsibility for abstracting low-level details and hiding away various "gotchas" and complexities of the Concept2 Bluetooth interface specification as possible ### Inspiration In order for this library to be a good fit within the community and provide a good user experience for developers, the goal is to design the interface for this library after other existing libraries interfacing with Concept2 rowing machines. The libraries looked at were [Py3Row](https://github.com/droogmic/Py3Row) (Python, BSD-2), [BoutFitness/Concept2-SDK](https://github.com/BoutFitness/Concept2-SDK) (Swift, MIT), [ErgometerJS](https://github.com/tijmenvangulik/ErgometerJS) (Javascript, Apache 2). From 166d56c09e953d56b06ca0f303fe792de7b2e069 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 15:33:19 -0500 Subject: [PATCH 105/220] rename core api concepts heading --- docs/API.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/API.md b/docs/API.md index fd60cb8..1c76758 100644 --- a/docs/API.md +++ b/docs/API.md @@ -47,7 +47,7 @@ Since a lot of the architecture is already provided by FlutterBleLib and will li -## Core API Concepts +## Basic API details This library is built from a few core concepts, some of which are shared with the `csafe-fitness` library. These core concepts represent general groupings of classes that serve a particular purpose or abstract certain aspects of communicating with an erg. From 9fcdc15523096069f6bac1cf5b4b4f941fe284e2 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 15:33:29 -0500 Subject: [PATCH 106/220] tweak the "table of contents" for the new sections --- docs/API.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/API.md b/docs/API.md index 1c76758..6498c90 100644 --- a/docs/API.md +++ b/docs/API.md @@ -3,9 +3,9 @@ This document is the starting point for learning more about the c2bluetooth API and inner workings at varying levels of detail: - The broadest overview comes from using the API as documented in the README -- sections like [Overall API Design](#overall-api-design) explain some of the core concepts or goals that we wanted to achieve with the API. -- For people looking to get into the internals of c2bluetooth, the [Core API Concepts](#core-api-concepts) section below is a good mid-level overview of the various groups or categories of classes that are used in the API and what their purpose is. -- For summaries of how c2bluetooth works internally and all the things it "takes care of" for end users, see the [internals](internals.md) document +- sections like [Core Values](#core-values) help explain more of the "why" behind some of the design choices made in the API. +- The [Basic api details](#basic-api-details) section is a detailed, mid-level overview of as man aspects of the public API as posible and what their purpose is. +- For people looking to get into the internals of c2bluetooth or make contributions, see the [internals](internals.md) document. - Obviously the most detailed explaination of how the code works comes from reading the code and inline comments themselves. It is helpful to understand the general goals first ## Terms used From 7def01f7872def21e518c8e0905bc069c773cf21 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 15:34:26 -0500 Subject: [PATCH 107/220] more silent protector stuff --- docs/API.md | 4 +++- docs/internals.md | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/API.md b/docs/API.md index 6498c90..242b123 100644 --- a/docs/API.md +++ b/docs/API.md @@ -23,7 +23,9 @@ This principle shares its name with the [popular meme template](https://knowyour ![A remix of the "silent protector" meme depicting c2bluetooth protecting the apps that use it from low-level details of bluetooth communications with a concept2 erg](../docs/images/silent-protector.jpg) -This is essentially a graphical analogy to represent the idea that this library aims to "take on" as much responsibility for abstracting low-level details and hiding away various "gotchas" and complexities of the Concept2 Bluetooth interface specification as possible +This is essentially a graphical analogy to represent the idea that this library aims to "take on" as much responsibility for abstracting low-level details and hiding away various "gotchas" and complexities of the Concept2 Bluetooth interface specification as possible. + +To my knowledge this is not currently a software design principle found in the broader software industry. However I think it is an awesome way to explain the concept. ### Inspiration In order for this library to be a good fit within the community and provide a good user experience for developers, the goal is to design the interface for this library after other existing libraries interfacing with Concept2 rowing machines. The libraries looked at were [Py3Row](https://github.com/droogmic/Py3Row) (Python, BSD-2), [BoutFitness/Concept2-SDK](https://github.com/BoutFitness/Concept2-SDK) (Swift, MIT), [ErgometerJS](https://github.com/tijmenvangulik/ErgometerJS) (Javascript, Apache 2). diff --git a/docs/internals.md b/docs/internals.md index 9cbb2da..b840e29 100644 --- a/docs/internals.md +++ b/docs/internals.md @@ -1,7 +1,9 @@ # Internal API and Design Concepts This document is meant to be similar to the [API](API.md) document, but specifically for providing an overview of the internal API organization. -Only people interested in contributing to c2bluetooth should need to understand things at this level. +Only people interested in modifying c2bluetooth should need to understand things at this level. + +This also can be thought of as an outline of many of the (often low-level) things that c2bluetooth "takes care of" for impleenting applications in keeping with the [Silent Protector principle](API.md#the-silent-protector). ## Internal API Concepts #### Commands From e2148e55a84b3ce8269b97774d47d3f1293ddff1 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 15:42:09 -0500 Subject: [PATCH 108/220] rename segment distance to elapsedDistance --- lib/src/packets/segmentdata.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/packets/segmentdata.dart b/lib/src/packets/segmentdata.dart index 09d7825..65d402d 100644 --- a/lib/src/packets/segmentdata.dart +++ b/lib/src/packets/segmentdata.dart @@ -17,14 +17,14 @@ class SegmentData extends ElapsedtimeStampedData { /// Represents the first kind of [SegmentData] packet containing part of the full set of data about a segment of a workout class SegmentData1 extends SegmentData { - double distance; + double elapsedDistance; // double segmentTime; int segmentDistance; int segmentRestTime; int segmentRestDistance; SegmentData1.fromBytes(Uint8List data) - : distance = CsafeIntExtension.fromBytes(data.sublist(3, 6), + : elapsedDistance = CsafeIntExtension.fromBytes(data.sublist(3, 6), endian: Endian.little) / 10, // segmentTime = 6,9, From a410a72a9abb497da0cb21a620a428e6d7602d22 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 16:09:21 -0500 Subject: [PATCH 109/220] fix byte index of the segment count --- lib/src/packets/segmentdata.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/packets/segmentdata.dart b/lib/src/packets/segmentdata.dart index 65d402d..45efbee 100644 --- a/lib/src/packets/segmentdata.dart +++ b/lib/src/packets/segmentdata.dart @@ -11,7 +11,7 @@ import './base.dart'; class SegmentData extends ElapsedtimeStampedData { int segmentNumber; SegmentData.fromBytes(Uint8List data) - : segmentNumber = data.elementAt(18), + : segmentNumber = data.elementAt(17), super.fromBytes(data); } From 666bdd046151def9d3ccc3c0e2d02b6202a5381d Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 16:09:37 -0500 Subject: [PATCH 110/220] rename SegmentData to SharedSegmentData --- lib/src/packets/segmentdata.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/packets/segmentdata.dart b/lib/src/packets/segmentdata.dart index 45efbee..7ba1819 100644 --- a/lib/src/packets/segmentdata.dart +++ b/lib/src/packets/segmentdata.dart @@ -8,15 +8,15 @@ import './base.dart'; /// Segment refers to the concept of "split or interval" from Concept2's specification since the two are mutually exclusive. /// /// Both segment data packets seem to start with the elapsed time have the [segmentNumber] stored at byte 18, so this class abstracts those two fields -class SegmentData extends ElapsedtimeStampedData { +class SharedSegmentData extends ElapsedtimeStampedData { int segmentNumber; - SegmentData.fromBytes(Uint8List data) + SharedSegmentData.fromBytes(Uint8List data) : segmentNumber = data.elementAt(17), super.fromBytes(data); } /// Represents the first kind of [SegmentData] packet containing part of the full set of data about a segment of a workout -class SegmentData1 extends SegmentData { +class SegmentData1 extends SharedSegmentData { double elapsedDistance; // double segmentTime; int segmentDistance; From 84f94adab833f2598a2ea8f8dde7646b6d115557 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 16:10:14 -0500 Subject: [PATCH 111/220] finish parsing out the bytes for the SegmentData packets --- lib/src/packets/segmentdata.dart | 52 +++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/lib/src/packets/segmentdata.dart b/lib/src/packets/segmentdata.dart index 7ba1819..72ac6a4 100644 --- a/lib/src/packets/segmentdata.dart +++ b/lib/src/packets/segmentdata.dart @@ -1,4 +1,6 @@ import 'dart:typed_data'; +import 'package:c2bluetooth/enums.dart'; +import 'package:c2bluetooth/extensions.dart'; import 'package:csafe_fitness/csafe_fitness.dart'; import './base.dart'; @@ -18,26 +20,60 @@ class SharedSegmentData extends ElapsedtimeStampedData { /// Represents the first kind of [SegmentData] packet containing part of the full set of data about a segment of a workout class SegmentData1 extends SharedSegmentData { double elapsedDistance; - // double segmentTime; + double segmentTime; int segmentDistance; - int segmentRestTime; - int segmentRestDistance; + int intervalRestTime; + int intervalRestDistance; + IntervalType segmentType; SegmentData1.fromBytes(Uint8List data) : elapsedDistance = CsafeIntExtension.fromBytes(data.sublist(3, 6), endian: Endian.little) / 10, - // segmentTime = 6,9, + segmentTime = CsafeIntExtension.fromBytes(data.sublist(6, 9), + endian: Endian.little) / + 10, segmentDistance = CsafeIntExtension.fromBytes(data.sublist(9, 12), endian: Endian.little), - segmentRestDistance = CsafeIntExtension.fromBytes(data.sublist(12, 14), + intervalRestTime = CsafeIntExtension.fromBytes(data.sublist(12, 14), endian: Endian.little), - segmentRestTime = CsafeIntExtension.fromBytes(data.sublist(14, 16), + intervalRestDistance = CsafeIntExtension.fromBytes(data.sublist(14, 16), endian: Endian.little), + segmentType = IntervalTypeExtension.fromInt(data.elementAt(16)), super.fromBytes(data); } /// Represents the second kind of [SegmentData] packet containing the remaining part of the full set of data about a segment of a workout -class SegmentData2 extends SegmentData { - SegmentData2.fromBytes(Uint8List data) : super.fromBytes(data); +class SegmentData2 extends SharedSegmentData { + int segmentAvgStrokeRate; + int segmentWorkHeartRate; + int segmentRestHeartRate; + double segmentAveragePace; + int segmentTotalCalories; + int segmentAverageCalories; + double segmentSpeed; + int segmentPower; + int splitAverageDragFactor; + MachineType machineType; + + SegmentData2.fromBytes(Uint8List data) + : segmentAvgStrokeRate = data.elementAt(3), + segmentWorkHeartRate = data.elementAt(4), + segmentRestHeartRate = data.elementAt(5), + segmentAveragePace = CsafeIntExtension.fromBytes(data.sublist(6, 8), + endian: Endian.little) / + 10, + segmentTotalCalories = CsafeIntExtension.fromBytes(data.sublist(8, 10), + endian: Endian.little), + segmentAverageCalories = CsafeIntExtension.fromBytes( + data.sublist(10, 12), + endian: Endian.little), + segmentSpeed = CsafeIntExtension.fromBytes(data.sublist(12, 14), + endian: Endian.little) / + 1000, + segmentPower = CsafeIntExtension.fromBytes(data.sublist(14, 16), + endian: Endian.little), + splitAverageDragFactor = data.elementAt(16), + machineType = MachineTypeExtension.fromInt(data.elementAt(18)), + super.fromBytes(data); } From d3f6e4f6a4572c608d8304a04f4350f2b5c0c837 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 16:10:33 -0500 Subject: [PATCH 112/220] commit silent protector image for the docs --- docs/images/silent-protector.jpg | Bin 0 -> 75586 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/images/silent-protector.jpg diff --git a/docs/images/silent-protector.jpg b/docs/images/silent-protector.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fca1eb2ea4d0c75c15b58e1d89aef459bbdb0d70 GIT binary patch literal 75586 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 z z(Rn!sP9(puU1j*(Byvjml?kSf16I-4_aRV`M;qDW@}xt%a&vZ>aqMwr$d-E2jCpYd zqwfn38^yi ztaXC?na|F94vpE+un&aER{^Faba@<{M*e8|*Em^Sk!eZ*mrg0R3YI9^KuVfH+~^jk zgOvsS@7mvO)-VbkoC?LiMYetgL*K7hKf8=VB`ino$3A&LssQR3g|F$Yd_R2-nVi@? z#^RD5C6|}ScD(wS*qmSTF%&FwYjru{?neK(WSrD${EN6pgdI~yYSs~MA}w}|BJ!Oj z%Q!Ww_zw~T>#AL$qAPt3K85+Eo%djn{8_IAZFwSVs9pW>>xQ<>(zPo3o;XJf#W+Ar z2SkXjEx&|WLRURh30U8A~4AvtSL6r!urs3;o7oh3BNPlr)eFPd6pW| zoMKjmaH(8p*%6PG#F;_RpuB^I=!P+rteRGuE2=-;vhlD*JQDB8yHq69v}E^Qd$;R> zTpd$v@>mE`CTuW0giA1)+1uoXVZ&6wty5QHBYQG#c?pn`rp=P|M9ux^c{1eL>!e&p zx+=QMO<&te>;=3%=^ex4l$#YmTX(RKnf-Wf;kOA^;mL&PomtjNwqsA8)RIO)^Ceez zO$?6b2Se#;BI5rKV{aMMX4w7fQlwac7HiSsE`{O*C{Vn(6QH;U2oRiNMT<*tclY2> z+}#Q8?p7#t=Y9Ws_SrLM=FItaf6epEJXveq>vvtUBuX#f^f<1;q9{a2plq3=_U_!Q zu@vDK!Tlyd9{yyt`YEoU30dV8N&h||z*$SDc_;E8l1#y2gZ!!Vljl<51UqbSA>}>U z=)%gEra>irjPc9g^!nar`EDMiBIQ)akx9Uc)UdJd+~?Dx&;rT0f{Nc zzxWY~$(r>+r@Sc_P3i_8uzQNI+~G4Lv(|mp>1S#+@$TsmrMIt+1|sCh-QT!fRo31r z4e|Q;^W!LTAn@ZYY&kn4YxDwY5|?cSZ>1lo0zMB;ncCTNk`_3=P=1`2`}PCzl4}x5bjOc6wV^^s8Ox`ohphHmAFw-z zBnn@zgkK|mzFHA+Iu$av^qKST^aWG(GcKLs}+i6OsPYT}!H2R$I&~1H#wLAZF6J7Y9(?ntW{TR`q)P>P#>;Kb#|4*~+ z{rrE`t(?AA&Z7J7^CV&Z<@D7hN|JcA-9S6h!e)wTM;!Cw`KAz&!o2S%ikR=yl(Z0& zIboxxW5&i1!UdBN*Ff+3-sa`Z!yGw>0_)Ms0UeQ_l&D%f`m06i)^o(jX;N4PDCET_ z-@;Ek>~apyA_SIO2DaDr528A)4z`pa3pti~(OjcMc{Pn*vd^AJ)9lP@T8Y{0*dLex zp(kbUBrl`TGl+tqfr>X)blF}po+0KI*?H32&S4;MG_G3?XxE;8*K7IxEb$L!5d+PR z?3|3tz|ncZH=kKP*A&#Qgd%nu=k-Yx!VvD)Oc4lhg+brd1UAPs+;SjQjPv(=sDbH< zx+@vOJu~JN zgs2kC&4G$7)5{(>Ei-vw#U^gz_}|%4<1IgtF7}m*(`5{%@fwkB!@U$mJEF)NHMb=l z5fZN!Pq-M-cx4MTMy)pPlguZp--ucI7X;OV+6fM-c+O@&F)9l2T8^6~7Bl4i;^%|SH5OkP@eWcaSnvI}GVl3eo==m&Xy6uo4@ zr3$(|j-lWted{wuDgT|eXOrO_ZSk{q+)l|m0v2vVw-i~KSDLP®*bJWykIw};Ew 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 literal 0 HcmV?d00001 From 676388a655b322d19a75433414ade9954bd560d5 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 16:11:37 -0500 Subject: [PATCH 113/220] document the use of the term "segment" from SegmentData packet name --- docs/internals.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/internals.md b/docs/internals.md index b840e29..9c7a693 100644 --- a/docs/internals.md +++ b/docs/internals.md @@ -5,6 +5,12 @@ Only people interested in modifying c2bluetooth should need to understand things This also can be thought of as an outline of many of the (often low-level) things that c2bluetooth "takes care of" for impleenting applications in keeping with the [Silent Protector principle](API.md#the-silent-protector). + +## Terms used + +### Segment +One key difference you may notice between this library and the source documentation that this is based on (such as the Concept2 Bluetooth API specifications) is the appearance of the term "segment". This is useful because splits and intervals are fundamentally similar enough that concept2 uses the same API to convey both split and interval data (the two are mutually exclusive anyway). Concept2's documentation, however, refers to it as "Split/interval", so the term segment was introduced to make this a little easier to think about and help differentiate data points that are unique to either splits or intervals. + ## Internal API Concepts #### Commands The command classes are based on the similarly named classes in the csafe-fitness library. There is a command superclass that is responsible for implementing general-purpose command structures from the relevant CSAFE/Concept2 specifications. These general command classes can then be subclassed to make clearly-named human readable shortcuts that pre-fill details like the identifier and command type while also performing validation of the command data. From 40d0fec99afbc5a67966c98d44f91812cdf73c62 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 19 Nov 2022 16:18:23 -0500 Subject: [PATCH 114/220] update example app to use the new dataplex api --- example/lib/main.dart | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 94de161..83d41ef 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -146,23 +146,17 @@ class _SimpleErgViewState extends State { displayText = "Setting up streams"; }); - targetDevice!.monitorForWorkoutSummary().listen((summary) { - print(summary); - //TODO: update this for futures - summary.workDistance.then((dist) { - setState(() { - displayText = "distance: $dist"; - }); - }); - summary.timestamp.then((time) { - setState(() { - displayText2 = "datetime: $time"; - }); - }); - summary.avgSPM.then((spm) { - setState(() { - displayText3 = "sr: $spm"; - }); + targetDevice!.monitorForData({ + "workout.distance.total", + "workout.timestamp", + "stroke_rate.average" + }).listen((data) { + print(data); + + setState(() { + displayText = "distance: ${data["workout.distance.total"]}"; + displayText2 = "datetime: ${data["workout.timestamp"]}"; + displayText3 = "sr: ${data["stroke_rate.average"]}"; }); }); } From 6e051640a66e1972bae8f624219759e59bb3484b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 22 Nov 2022 13:25:07 -0500 Subject: [PATCH 115/220] formatting --- lib/models/ergometer.dart | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index ee470d4..ed9843c 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -41,7 +41,9 @@ class Ergometer { //this may cause problems if the device goes out of range between scenning and trying to connect. maybe use connectToAdvertisingDevice instead to mitigate this and prevent a hang on android //if no services are specified in the `servicesWithCharacteristicsToDiscover` parameter, then full service discovery will be performed - return _flutterReactiveBle.connectToDevice(id: _peripheral.id).asyncMap((connectionStateUpdate) { + return _flutterReactiveBle + .connectToDevice(id: _peripheral.id) + .asyncMap((connectionStateUpdate) { switch (connectionStateUpdate.connectionState) { case DeviceConnectionState.connecting: return ErgometerConnectionState.connecting; @@ -55,7 +57,6 @@ class Ergometer { return ErgometerConnectionState.disconnected; } }); - } Stream> monitorForData( @@ -67,9 +68,16 @@ class Ergometer { /// /// Intended for passing to the csafe_fitness library to allow it to read response data from the erg Stream _readCsafe() { - var csafeRxCharacteristic = QualifiedCharacteristic(serviceId: Uuid.parse(Identifiers.C2_ROWING_CONTROL_SERVICE_UUID), characteristicId: Uuid.parse(Identifiers.C2_ROWING_PM_TRANSMIT_CHARACTERISTIC_UUID), deviceId: _peripheral.id); - - return _flutterReactiveBle.subscribeToCharacteristic(csafeRxCharacteristic).asyncMap((datapoint) => Uint8List.fromList(datapoint)).asyncMap((datapoint) { + var csafeRxCharacteristic = QualifiedCharacteristic( + serviceId: Uuid.parse(Identifiers.C2_ROWING_CONTROL_SERVICE_UUID), + characteristicId: + Uuid.parse(Identifiers.C2_ROWING_PM_TRANSMIT_CHARACTERISTIC_UUID), + deviceId: _peripheral.id); + + return _flutterReactiveBle + .subscribeToCharacteristic(csafeRxCharacteristic) + .asyncMap((datapoint) => Uint8List.fromList(datapoint)) + .asyncMap((datapoint) { print("reading data: $datapoint"); return datapoint; }); @@ -79,7 +87,11 @@ class Ergometer { /// /// Intended for passing to the csafe_fitness library to allow it to write commands to the erg void _writeCsafe(Uint8List value) { - var csafeTxCharacteristic = QualifiedCharacteristic(serviceId: Uuid.parse(Identifiers.C2_ROWING_CONTROL_SERVICE_UUID), characteristicId: Uuid.parse(Identifiers.C2_ROWING_PM_RECEIVE_CHARACTERISTIC_UUID), deviceId: _peripheral.id); + var csafeTxCharacteristic = QualifiedCharacteristic( + serviceId: Uuid.parse(Identifiers.C2_ROWING_CONTROL_SERVICE_UUID), + characteristicId: + Uuid.parse(Identifiers.C2_ROWING_PM_RECEIVE_CHARACTERISTIC_UUID), + deviceId: _peripheral.id); // return _peripheral.writeCharacteristic( // Identifiers.C2_ROWING_CONTROL_SERVICE_UUID, @@ -88,10 +100,12 @@ class Ergometer { // true); // //.asyncMap((datapoint) => datapoint.read()); - _flutterReactiveBle.writeCharacteristicWithResponse(csafeTxCharacteristic, value: value); + _flutterReactiveBle.writeCharacteristicWithResponse(csafeTxCharacteristic, + value: value); } - @Deprecated("This is a temporary function for development/experimentation and will be gone very soon") + @Deprecated( + "This is a temporary function for development/experimentation and will be gone very soon") void configure2kWorkout() async { //Workout workout await _csafeClient!.sendCommands([ From 1b41f85b3a8770b59f69c0b95f17a008edbf1a03 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 20 Dec 2022 17:35:42 -0800 Subject: [PATCH 116/220] add keys for SegmentData --- lib/src/packets/keys.dart | 16 +++++++++++++++ lib/src/packets/segmentdata.dart | 35 +++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/lib/src/packets/keys.dart b/lib/src/packets/keys.dart index 60310a3..b2f517f 100644 --- a/lib/src/packets/keys.dart +++ b/lib/src/packets/keys.dart @@ -18,3 +18,19 @@ const WORKOUT_WATTS_KEY = "workout.watts"; const WORKOUT_REST_DISTANCE_KEY = "workout.rest_distance"; const WORKOUT_REST_TIME_KEY = "workout.rest_time"; const WORKOUT_AVG_CALORIES_KEY = "workout.calories.average"; + +const SEGMENT_TIME_KEY = "segment.time"; +const SEGMENT_DISTANCE_KEY = "segment.distance"; +const SEGMENT_REST_TIME_KEY = "segment.interval.rest_time"; +const SEGMENT_REST_DISTANCE_KEY = "segment.interval.rest_distance"; +const SEGMENT_TYPE_KEY = "segment.type"; +const SEGMENT_NUMBER_KEY = "segment.number"; +const SEGMENT_AVG_SPM_KEY = "segment.stroke_rate.average"; +const SEGMENT_WORK_HR_KEY = "segment.work_heart_rate"; +const SEGMENT_REST_HR_KEY = "segment.rest_heart_rate"; +const SEGMENT_AVG_PACE_KEY = "segment.pace.average"; +const SEGMENT_CALORIES_KEY = "segment.calories"; +const SEGMENT_AVG_CALORIES_KEY = "segment.calories.average"; +const SEGMENT_SPEED_KEY = "segment.speed"; +const SEGMENT_POWER_KEY = "segment.power"; +const SEGMENT_AVG_DRAGFACTOR_KEY = "segment.drag_factor.average"; diff --git a/lib/src/packets/segmentdata.dart b/lib/src/packets/segmentdata.dart index 72ac6a4..8f6ffa2 100644 --- a/lib/src/packets/segmentdata.dart +++ b/lib/src/packets/segmentdata.dart @@ -2,7 +2,7 @@ import 'dart:typed_data'; import 'package:c2bluetooth/enums.dart'; import 'package:c2bluetooth/extensions.dart'; import 'package:csafe_fitness/csafe_fitness.dart'; - +import 'keys.dart' as Keys; import './base.dart'; /// Represents a packet containing data for a "Segment" of a workout. @@ -15,6 +15,12 @@ class SharedSegmentData extends ElapsedtimeStampedData { SharedSegmentData.fromBytes(Uint8List data) : segmentNumber = data.elementAt(17), super.fromBytes(data); + + Map asMap() { + Map map = super.asMap(); + map.addAll({Keys.SEGMENT_NUMBER_KEY: segmentNumber}); + return map; + } } /// Represents the first kind of [SegmentData] packet containing part of the full set of data about a segment of a workout @@ -41,6 +47,17 @@ class SegmentData1 extends SharedSegmentData { endian: Endian.little), segmentType = IntervalTypeExtension.fromInt(data.elementAt(16)), super.fromBytes(data); + + Map asMap() { + Map map = super.asMap(); + map.addAll({ + Keys.SEGMENT_TIME_KEY: segmentTime, + Keys.SEGMENT_DISTANCE_KEY: elapsedDistance, + Keys.SEGMENT_TYPE_KEY: segmentType, + Keys.SEGMENT_REST_TIME_KEY: intervalRestTime + }); + return map; + } } /// Represents the second kind of [SegmentData] packet containing the remaining part of the full set of data about a segment of a workout @@ -76,4 +93,20 @@ class SegmentData2 extends SharedSegmentData { splitAverageDragFactor = data.elementAt(16), machineType = MachineTypeExtension.fromInt(data.elementAt(18)), super.fromBytes(data); + + Map asMap() { + Map map = super.asMap(); + map.addAll({ + Keys.SEGMENT_AVG_SPM_KEY: segmentAvgStrokeRate, + Keys.SEGMENT_WORK_HR_KEY: segmentWorkHeartRate, + Keys.SEGMENT_REST_HR_KEY: segmentRestHeartRate, + Keys.SEGMENT_AVG_PACE_KEY: segmentAveragePace, + Keys.SEGMENT_CALORIES_KEY: segmentTotalCalories, + Keys.SEGMENT_AVG_CALORIES_KEY: segmentAverageCalories, + Keys.SEGMENT_SPEED_KEY: segmentSpeed, + Keys.SEGMENT_POWER_KEY: segmentPower, + Keys.SEGMENT_AVG_DRAGFACTOR_KEY: splitAverageDragFactor + }); + return map; + } } From bdecbb8b5a132cd432b32ef4eba2140f0ac326d2 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 20 Dec 2022 17:36:08 -0800 Subject: [PATCH 117/220] add a list of all data keys to the dataplex --- lib/src/dataplex.dart | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 7de8fa4..718d243 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -24,9 +24,22 @@ class Dataplex { List outgoingStreams = []; - /// Map of characteristic UUID's to the sunscription instance for that characteristic + /// Map of characteristic UUID's to the active subscription instance for that characteristic Map currentSubscriptions = Map(); + Set allDatapointIdentifiers ={ + ...StatusData.datapointIdentifiers, + ...StatusData1.datapointIdentifiers, + ...StatusData2.datapointIdentifiers, + ...StrokeData.datapointIdentifiers, + ...StrokeData2.datapointIdentifiers, + ...SegmentData1.datapointIdentifiers, + ...SegmentData2.datapointIdentifiers, + ...WorkoutSummaryPacket.datapointIdentifiers, + ...WorkoutSummaryPacket2.datapointIdentifiers, + ...ForceCurveData.datapointIdentifiers,} + + /// A map of incoming UUID's to the data keys they support. Map> characteristicToDataKeyMap = { Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC_UUID: From 20eace4d798707f148ffdd5e582888ce4a4c330b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 20 Dec 2022 17:39:14 -0800 Subject: [PATCH 118/220] add definitions for segmentData.zero() functions --- lib/src/packets/segmentdata.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/packets/segmentdata.dart b/lib/src/packets/segmentdata.dart index 8f6ffa2..393e79f 100644 --- a/lib/src/packets/segmentdata.dart +++ b/lib/src/packets/segmentdata.dart @@ -32,6 +32,8 @@ class SegmentData1 extends SharedSegmentData { int intervalRestDistance; IntervalType segmentType; + SegmentData1.zero() : this.fromBytes(Uint8List(20)); + SegmentData1.fromBytes(Uint8List data) : elapsedDistance = CsafeIntExtension.fromBytes(data.sublist(3, 6), endian: Endian.little) / @@ -73,6 +75,8 @@ class SegmentData2 extends SharedSegmentData { int splitAverageDragFactor; MachineType machineType; + SegmentData2.zero() : this.fromBytes(Uint8List(20)); + SegmentData2.fromBytes(Uint8List data) : segmentAvgStrokeRate = data.elementAt(3), segmentWorkHeartRate = data.elementAt(4), From 08e7f1b8ef006476e089d7111a261ea25b0051cf Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 24 Dec 2022 11:46:06 -0800 Subject: [PATCH 119/220] add more zero() and datapointIdentifiers functions --- lib/src/packets/base.dart | 10 ++++++++++ lib/src/packets/forcecurvepacket.dart | 5 +++++ lib/src/packets/segmentdata.dart | 6 ++++++ lib/src/packets/statusdata.dart | 15 +++++++++++++++ lib/src/packets/strokedata.dart | 13 +++++++++++++ 5 files changed, 49 insertions(+) diff --git a/lib/src/packets/base.dart b/lib/src/packets/base.dart index 05f9a0e..ca8cc19 100644 --- a/lib/src/packets/base.dart +++ b/lib/src/packets/base.dart @@ -14,6 +14,11 @@ class Concept2CharacteristicData { class TimestampedData extends Concept2CharacteristicData { DateTime timestamp; + static Set get datapointIdentifiers => + TimestampedData.zero().asMap().keys.toSet(); + + TimestampedData.zero() : this.fromBytes(Uint8List(20)); + TimestampedData.fromBytes(Uint8List bytes) : timestamp = Concept2DateExtension.fromBytes(bytes.sublist(0, 4)); @@ -28,6 +33,11 @@ class TimestampedData extends Concept2CharacteristicData { class ElapsedtimeStampedData extends Concept2CharacteristicData { Duration elapsedTime; + static Set get datapointIdentifiers => + ElapsedtimeStampedData.zero().asMap().keys.toSet(); + + ElapsedtimeStampedData.zero() : this.fromBytes(Uint8List(20)); + ElapsedtimeStampedData.fromBytes(Uint8List data) : elapsedTime = Concept2DurationExtension.fromBytes(data.sublist(0, 3)); diff --git a/lib/src/packets/forcecurvepacket.dart b/lib/src/packets/forcecurvepacket.dart index cb7c447..78d90f4 100644 --- a/lib/src/packets/forcecurvepacket.dart +++ b/lib/src/packets/forcecurvepacket.dart @@ -5,6 +5,11 @@ import './base.dart'; class ForceCurveData extends Concept2CharacteristicData { List data; + static Set get datapointIdentifiers => + ForceCurveData.zero().asMap().keys.toSet(); + + ForceCurveData.zero() : this.fromBytes(Uint8List(20)); + /// Construct a set of ForceCurveData from the bytes returned from the erg ForceCurveData.fromBytes(Uint8List data) : this.data = data.toList(); } diff --git a/lib/src/packets/segmentdata.dart b/lib/src/packets/segmentdata.dart index 393e79f..680863b 100644 --- a/lib/src/packets/segmentdata.dart +++ b/lib/src/packets/segmentdata.dart @@ -32,6 +32,9 @@ class SegmentData1 extends SharedSegmentData { int intervalRestDistance; IntervalType segmentType; + static Set get datapointIdentifiers => + SegmentData1.zero().asMap().keys.toSet(); + SegmentData1.zero() : this.fromBytes(Uint8List(20)); SegmentData1.fromBytes(Uint8List data) @@ -75,6 +78,9 @@ class SegmentData2 extends SharedSegmentData { int splitAverageDragFactor; MachineType machineType; + static Set get datapointIdentifiers => + SegmentData2.zero().asMap().keys.toSet(); + SegmentData2.zero() : this.fromBytes(Uint8List(20)); SegmentData2.fromBytes(Uint8List data) diff --git a/lib/src/packets/statusdata.dart b/lib/src/packets/statusdata.dart index 86984db..02f4f71 100644 --- a/lib/src/packets/statusdata.dart +++ b/lib/src/packets/statusdata.dart @@ -7,6 +7,11 @@ import './base.dart'; class StatusData extends ElapsedtimeStampedData { double distance; + static Set get datapointIdentifiers => + StatusData.zero().asMap().keys.toSet(); + + StatusData.zero() : this.fromBytes(Uint8List(20)); + StatusData.fromBytes(Uint8List data) : distance = CsafeIntExtension.fromBytes(data.sublist(3, 6), endian: Endian.little) / @@ -19,6 +24,11 @@ class StatusData extends ElapsedtimeStampedData { class StatusData1 extends ElapsedtimeStampedData { double speed; + static Set get datapointIdentifiers => + StatusData1.zero().asMap().keys.toSet(); + + StatusData1.zero() : this.fromBytes(Uint8List(20)); + StatusData1.fromBytes(Uint8List data) : speed = CsafeIntExtension.fromBytes(data.sublist(3, 5), endian: Endian.little) / @@ -30,6 +40,11 @@ class StatusData1 extends ElapsedtimeStampedData { class StatusData2 extends ElapsedtimeStampedData { int intervalCount; + static Set get datapointIdentifiers => + StatusData2.zero().asMap().keys.toSet(); + + StatusData2.zero() : this.fromBytes(Uint8List(20)); + StatusData2.fromBytes(Uint8List data) : intervalCount = data.elementAt(3), super.fromBytes(data); diff --git a/lib/src/packets/strokedata.dart b/lib/src/packets/strokedata.dart index 7023c83..cf5cb77 100644 --- a/lib/src/packets/strokedata.dart +++ b/lib/src/packets/strokedata.dart @@ -3,6 +3,12 @@ import 'dart:typed_data'; import './base.dart'; class StrokeData extends ElapsedtimeStampedData { + + static Set get datapointIdentifiers => + StrokeData.zero().asMap().keys.toSet(); + + StrokeData.zero() : this.fromBytes(Uint8List(20)); + StrokeData.fromBytes(Uint8List data) : super.fromBytes(data) { // _workTime.completeIfNotAlready( // CsafeIntExtension.fromBytes(data.sublist(4, 7), endian: Endian.little) / @@ -33,5 +39,12 @@ class StrokeData extends ElapsedtimeStampedData { } class StrokeData2 extends ElapsedtimeStampedData { + + static Set get datapointIdentifiers => + StrokeData2.zero().asMap().keys.toSet(); + + StrokeData2.zero() : this.fromBytes(Uint8List(20)); + + StrokeData2.fromBytes(Uint8List data) : super.fromBytes(data); } From decae2d4065db996847e22f68f4739420b7e7315 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 24 Dec 2022 11:46:45 -0800 Subject: [PATCH 120/220] update elapsed time key --- lib/src/packets/keys.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/packets/keys.dart b/lib/src/packets/keys.dart index b2f517f..fdb5ba7 100644 --- a/lib/src/packets/keys.dart +++ b/lib/src/packets/keys.dart @@ -1,4 +1,4 @@ -const ELAPSED_TIME_KEY = "workout.timestamp"; +const ELAPSED_TIME_KEY = "general.elapsed_time"; const WORKOUT_TIMESTAMP_KEY = "workout.timestamp"; const WORKOUT_AVG_SPM_KEY = "workout.stroke_rate.average"; From 1fd5c18ed9bf81199755d7c8e02091641677ba0c Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 24 Dec 2022 11:46:59 -0800 Subject: [PATCH 121/220] add elapsed distance key --- lib/src/packets/keys.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/packets/keys.dart b/lib/src/packets/keys.dart index fdb5ba7..bb718d9 100644 --- a/lib/src/packets/keys.dart +++ b/lib/src/packets/keys.dart @@ -1,4 +1,5 @@ const ELAPSED_TIME_KEY = "general.elapsed_time"; +const ELAPSED_DISTANCE_KEY = "general.distance"; const WORKOUT_TIMESTAMP_KEY = "workout.timestamp"; const WORKOUT_AVG_SPM_KEY = "workout.stroke_rate.average"; From c9e8bcbaa6d9e8ef929b14200e549bd292f8c639 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 24 Dec 2022 11:47:31 -0800 Subject: [PATCH 122/220] formatting for allDatapoints set --- lib/src/dataplex.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 718d243..8eea7c7 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -27,7 +27,7 @@ class Dataplex { /// Map of characteristic UUID's to the active subscription instance for that characteristic Map currentSubscriptions = Map(); - Set allDatapointIdentifiers ={ + Set allDatapointIdentifiers = { ...StatusData.datapointIdentifiers, ...StatusData1.datapointIdentifiers, ...StatusData2.datapointIdentifiers, @@ -37,8 +37,8 @@ class Dataplex { ...SegmentData2.datapointIdentifiers, ...WorkoutSummaryPacket.datapointIdentifiers, ...WorkoutSummaryPacket2.datapointIdentifiers, - ...ForceCurveData.datapointIdentifiers,} - + ...ForceCurveData.datapointIdentifiers + }; /// A map of incoming UUID's to the data keys they support. Map> characteristicToDataKeyMap = { From dbc032fd17bbf0907c2763cf8335580fbc871252 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 24 Dec 2022 11:48:15 -0800 Subject: [PATCH 123/220] include elapsed time and distance in the map for workout summaries --- lib/src/packets/workoutsummary.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index 507c11b..2654658 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -64,8 +64,8 @@ class WorkoutSummaryPacket extends TimestampedData { // workout.calories.average Map map = super.asMap(); map.addAll({ - // "workout.time": workTime, - // workDistance + Keys.ELAPSED_TIME_KEY: elapsedTime, + Keys.ELAPSED_DISTANCE_KEY: workDistance, Keys.WORKOUT_AVG_SPM_KEY: avgSPM, Keys.WORKOUT_LAST_HR_KEY: endHeartRate, Keys.WORKOUT_AVG_HR_KEY: avgHeartRate, From bbc16bfa79c02d7534b5e6ea740827742cb7cc72 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 24 Dec 2022 11:49:36 -0800 Subject: [PATCH 124/220] use keys for monitoring for workout summary --- example/lib/main.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 83d41ef..fc65f5e 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -147,16 +147,16 @@ class _SimpleErgViewState extends State { }); targetDevice!.monitorForData({ - "workout.distance.total", - "workout.timestamp", - "stroke_rate.average" + Keys.ELAPSED_DISTANCE_KEY, + Keys.WORKOUT_TIMESTAMP_KEY, + Keys.WORKOUT_AVG_SPM_KEY }).listen((data) { print(data); setState(() { - displayText = "distance: ${data["workout.distance.total"]}"; - displayText2 = "datetime: ${data["workout.timestamp"]}"; - displayText3 = "sr: ${data["stroke_rate.average"]}"; + displayText = "distance: ${data[Keys.ELAPSED_DISTANCE_KEY]}"; + displayText2 = "datetime: ${data[Keys.WORKOUT_TIMESTAMP_KEY]}"; + displayText3 = "sr: ${data[Keys.WORKOUT_AVG_SPM_KEY]}"; }); }); } From 5cca58b9e99288e22edce2143a4ac11a6c67013e Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 24 Dec 2022 14:20:16 -0800 Subject: [PATCH 125/220] encapsulate Keys in a Keys class so they can be exported for end users (and the example app) --- lib/c2bluetooth.dart | 1 + lib/src/packets/base.dart | 2 +- lib/src/packets/keys.dart | 70 +++++++++++++++-------------- lib/src/packets/segmentdata.dart | 2 +- lib/src/packets/workoutsummary.dart | 2 +- 5 files changed, 40 insertions(+), 37 deletions(-) diff --git a/lib/c2bluetooth.dart b/lib/c2bluetooth.dart index 855baff..5fddd60 100644 --- a/lib/c2bluetooth.dart +++ b/lib/c2bluetooth.dart @@ -6,3 +6,4 @@ library c2bluetooth; export 'models/ergblemanager.dart'; export 'models/ergometer.dart'; export 'enums.dart'; +export 'src/packets/keys.dart'; diff --git a/lib/src/packets/base.dart b/lib/src/packets/base.dart index ca8cc19..8182cbd 100644 --- a/lib/src/packets/base.dart +++ b/lib/src/packets/base.dart @@ -1,7 +1,7 @@ import 'dart:typed_data'; import 'package:c2bluetooth/extensions.dart'; -import 'keys.dart' as Keys; +import 'keys.dart'; /// An empty superclass to represent all types of data formats that come from Concept2 bluetooth characteristics class Concept2CharacteristicData { diff --git a/lib/src/packets/keys.dart b/lib/src/packets/keys.dart index bb718d9..d309ff2 100644 --- a/lib/src/packets/keys.dart +++ b/lib/src/packets/keys.dart @@ -1,37 +1,39 @@ -const ELAPSED_TIME_KEY = "general.elapsed_time"; -const ELAPSED_DISTANCE_KEY = "general.distance"; +class Keys { + static const ELAPSED_TIME_KEY = "general.elapsed_time"; + static const ELAPSED_DISTANCE_KEY = "general.distance"; -const WORKOUT_TIMESTAMP_KEY = "workout.timestamp"; -const WORKOUT_AVG_SPM_KEY = "workout.stroke_rate.average"; -const WORKOUT_LAST_HR_KEY = "workout.heart_rate.last"; -const WORKOUT_AVG_HR_KEY = "workout.heart_rate.average"; -const WORKOUT_MIN_HR_KEY = "workout.heart_rate.min"; -const WORKOUT_MAX_HR_KEY = "workout.heart_rate.max"; -const WORKOUT_AVG_PACE_KEY = "workout.pace.average"; -const WORKOUT_AVG_DRAGFACTOR_KEY = "workout.drag_factor.average"; -const WORKOUT_RECOVERY_HR_KEY = "workout.heart_rate.recovery"; + static const WORKOUT_TIMESTAMP_KEY = "workout.timestamp"; + static const WORKOUT_AVG_SPM_KEY = "workout.stroke_rate.average"; + static const WORKOUT_LAST_HR_KEY = "workout.heart_rate.last"; + static const WORKOUT_AVG_HR_KEY = "workout.heart_rate.average"; + static const WORKOUT_MIN_HR_KEY = "workout.heart_rate.min"; + static const WORKOUT_MAX_HR_KEY = "workout.heart_rate.max"; + static const WORKOUT_AVG_PACE_KEY = "workout.pace.average"; + static const WORKOUT_AVG_DRAGFACTOR_KEY = "workout.drag_factor.average"; + static const WORKOUT_RECOVERY_HR_KEY = "workout.heart_rate.recovery"; -const WORKOUT_SEGMENT_COUNT_KEY = "workout.segment_count"; -const WORKOUT_SEGMENT_SIZE_KEY = "workout.segment_size"; -const WORKOUT_CALORIES_KEY = "workout.calories"; -const WORKOUT_WATTS_KEY = "workout.watts"; -// rests are only applicable for intervals workouts -const WORKOUT_REST_DISTANCE_KEY = "workout.rest_distance"; -const WORKOUT_REST_TIME_KEY = "workout.rest_time"; -const WORKOUT_AVG_CALORIES_KEY = "workout.calories.average"; + static const WORKOUT_SEGMENT_COUNT_KEY = "workout.segment_count"; + static const WORKOUT_SEGMENT_SIZE_KEY = "workout.segment_size"; + static const WORKOUT_CALORIES_KEY = "workout.calories"; + static const WORKOUT_WATTS_KEY = "workout.watts"; + // rests are only applicable for intervals workouts + static const WORKOUT_REST_DISTANCE_KEY = "workout.rest_distance"; + static const WORKOUT_REST_TIME_KEY = "workout.rest_time"; + static const WORKOUT_AVG_CALORIES_KEY = "workout.calories.average"; -const SEGMENT_TIME_KEY = "segment.time"; -const SEGMENT_DISTANCE_KEY = "segment.distance"; -const SEGMENT_REST_TIME_KEY = "segment.interval.rest_time"; -const SEGMENT_REST_DISTANCE_KEY = "segment.interval.rest_distance"; -const SEGMENT_TYPE_KEY = "segment.type"; -const SEGMENT_NUMBER_KEY = "segment.number"; -const SEGMENT_AVG_SPM_KEY = "segment.stroke_rate.average"; -const SEGMENT_WORK_HR_KEY = "segment.work_heart_rate"; -const SEGMENT_REST_HR_KEY = "segment.rest_heart_rate"; -const SEGMENT_AVG_PACE_KEY = "segment.pace.average"; -const SEGMENT_CALORIES_KEY = "segment.calories"; -const SEGMENT_AVG_CALORIES_KEY = "segment.calories.average"; -const SEGMENT_SPEED_KEY = "segment.speed"; -const SEGMENT_POWER_KEY = "segment.power"; -const SEGMENT_AVG_DRAGFACTOR_KEY = "segment.drag_factor.average"; + static const SEGMENT_TIME_KEY = "segment.time"; + static const SEGMENT_DISTANCE_KEY = "segment.distance"; + static const SEGMENT_REST_TIME_KEY = "segment.interval.rest_time"; + static const SEGMENT_REST_DISTANCE_KEY = "segment.interval.rest_distance"; + static const SEGMENT_TYPE_KEY = "segment.type"; + static const SEGMENT_NUMBER_KEY = "segment.number"; + static const SEGMENT_AVG_SPM_KEY = "segment.stroke_rate.average"; + static const SEGMENT_WORK_HR_KEY = "segment.work_heart_rate"; + static const SEGMENT_REST_HR_KEY = "segment.rest_heart_rate"; + static const SEGMENT_AVG_PACE_KEY = "segment.pace.average"; + static const SEGMENT_CALORIES_KEY = "segment.calories"; + static const SEGMENT_AVG_CALORIES_KEY = "segment.calories.average"; + static const SEGMENT_SPEED_KEY = "segment.speed"; + static const SEGMENT_POWER_KEY = "segment.power"; + static const SEGMENT_AVG_DRAGFACTOR_KEY = "segment.drag_factor.average"; +} diff --git a/lib/src/packets/segmentdata.dart b/lib/src/packets/segmentdata.dart index 680863b..964e7bd 100644 --- a/lib/src/packets/segmentdata.dart +++ b/lib/src/packets/segmentdata.dart @@ -2,7 +2,7 @@ import 'dart:typed_data'; import 'package:c2bluetooth/enums.dart'; import 'package:c2bluetooth/extensions.dart'; import 'package:csafe_fitness/csafe_fitness.dart'; -import 'keys.dart' as Keys; +import 'keys.dart'; import './base.dart'; /// Represents a packet containing data for a "Segment" of a workout. diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index 2654658..a5efde0 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -7,7 +7,7 @@ import 'package:csafe_fitness/csafe_fitness.dart'; import 'package:c2bluetooth/helpers.dart'; import 'package:c2bluetooth/enums.dart'; import './base.dart'; -import 'keys.dart' as Keys; +import 'keys.dart'; /// Represents a summary of a completed workout /// From 111afa4164884ceaac181419eb45d17c4eeb8816 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 24 Dec 2022 14:21:12 -0800 Subject: [PATCH 126/220] monitor for interval summaries --- example/lib/main.dart | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/example/lib/main.dart b/example/lib/main.dart index fc65f5e..2e67b06 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -159,6 +159,20 @@ class _SimpleErgViewState extends State { displayText3 = "sr: ${data[Keys.WORKOUT_AVG_SPM_KEY]}"; }); }); + + targetDevice!.monitorForData({ + Keys.SEGMENT_NUMBER_KEY, + Keys.SEGMENT_DISTANCE_KEY, + Keys.SEGMENT_AVG_SPM_KEY + }).listen((data) { + print(data); + + setState(() { + displayText = "interval #: ${data[Keys.SEGMENT_NUMBER_KEY]}"; + displayText2 = "distance: ${data[Keys.SEGMENT_DISTANCE_KEY]}"; + displayText3 = "sr avg: ${data[Keys.SEGMENT_AVG_SPM_KEY]}"; + }); + }); } @override From 1bd9dd761e8cd3c874641b7f1d11c53974ed2807 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 24 Dec 2022 15:24:46 -0800 Subject: [PATCH 127/220] actually subscribe to receiving the data --- lib/src/dataplex.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 8eea7c7..f9d583c 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -48,7 +48,12 @@ class Dataplex { WorkoutSummaryPacket2.datapointIdentifiers, }; - Dataplex(this._device); + Dataplex(this._device) { + _addSubscription( + Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID, + Identifiers.C2_ROWING_MULTIPLEXED_INFORMATION_CHARACTERISTIC_UUID, + null); + } ///Keeps track of how many characteristics we are currently receiving notifications for int _currentSubscriptionCount = 0; From 2c156cf75f991bfc7ac9f7568fa7098b4f7361d1 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 24 Dec 2022 15:25:16 -0800 Subject: [PATCH 128/220] correct the SegmentData keys for distance --- lib/src/packets/segmentdata.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/packets/segmentdata.dart b/lib/src/packets/segmentdata.dart index 964e7bd..803a624 100644 --- a/lib/src/packets/segmentdata.dart +++ b/lib/src/packets/segmentdata.dart @@ -56,8 +56,9 @@ class SegmentData1 extends SharedSegmentData { Map asMap() { Map map = super.asMap(); map.addAll({ + Keys.ELAPSED_DISTANCE_KEY: elapsedDistance, Keys.SEGMENT_TIME_KEY: segmentTime, - Keys.SEGMENT_DISTANCE_KEY: elapsedDistance, + Keys.SEGMENT_DISTANCE_KEY: segmentDistance, Keys.SEGMENT_TYPE_KEY: segmentType, Keys.SEGMENT_REST_TIME_KEY: intervalRestTime }); From 26cbcc737428c07309e7774a3296b55b82df6685 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 24 Dec 2022 15:25:37 -0800 Subject: [PATCH 129/220] correct the values for erg machine type (0 is actually allowed) --- lib/enums.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/enums.dart b/lib/enums.dart index 21269b3..1d0392d 100644 --- a/lib/enums.dart +++ b/lib/enums.dart @@ -34,10 +34,10 @@ enum MachineType { extension MachineTypeExtension on MachineType { static Map _machineTypeValues = { - MachineType.STATIC_D: 1, - MachineType.STATIC_C: 2, - MachineType.STATIC_A: 3, - MachineType.STATIC_B: 4, + MachineType.STATIC_D: 0, + MachineType.STATIC_C: 1, + MachineType.STATIC_A: 2, + MachineType.STATIC_B: 3, MachineType.STATIC_E: 5, MachineType.STATIC_SIMULATOR: 7, MachineType.STATIC_DYNAMIC: 8, From 9fac002568daa34d0de3b35dd0768cf10b395395 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 24 Dec 2022 15:25:57 -0800 Subject: [PATCH 130/220] add multiplexed characteristic ID to constants --- lib/constants.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/constants.dart b/lib/constants.dart index f8b2eba..3053759 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -37,6 +37,9 @@ const String C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC_UUID = const String C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC2_UUID = "CE06003A-43E5-11E4-916C-0800200C9A66"; +const String C2_ROWING_MULTIPLEXED_INFORMATION_CHARACTERISTIC_UUID = + "CE060080-43E5-11E4-916C-0800200C9A66"; + // CE060010-43E5-11E4-916C-0800200C9A66 //C2 device info service uuid // CE060012-43E5-11E4-916C-0800200C9A66 //C2 serial number string characteristic // CE060013-43E5-11E4-916C-0800200C9A66 //C2 hardware revision string characteristic From 7e1eb4c39c63c24b59a17b4053671a91cc66dbc9 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 24 Dec 2022 15:26:21 -0800 Subject: [PATCH 131/220] display both general and segment distance in the UI --- example/lib/main.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 2e67b06..f1fe2d8 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -163,13 +163,15 @@ class _SimpleErgViewState extends State { targetDevice!.monitorForData({ Keys.SEGMENT_NUMBER_KEY, Keys.SEGMENT_DISTANCE_KEY, - Keys.SEGMENT_AVG_SPM_KEY + Keys.SEGMENT_AVG_SPM_KEY, + Keys.ELAPSED_DISTANCE_KEY }).listen((data) { print(data); setState(() { displayText = "interval #: ${data[Keys.SEGMENT_NUMBER_KEY]}"; - displayText2 = "distance: ${data[Keys.SEGMENT_DISTANCE_KEY]}"; + displayText2 = + "sd: ${data[Keys.SEGMENT_DISTANCE_KEY]}, gd: ${data[Keys.ELAPSED_DISTANCE_KEY]}"; displayText3 = "sr avg: ${data[Keys.SEGMENT_AVG_SPM_KEY]}"; }); }); From f489af31d2f14b4ebf3ca269b6be787fd2dcde74 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 24 Dec 2022 15:43:10 -0800 Subject: [PATCH 132/220] remove extra parameter to sublist call when parsing workout summaries --- lib/src/packets/workoutsummary.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index a5efde0..2c41338 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -42,7 +42,7 @@ class WorkoutSummaryPacket extends TimestampedData { avgDragFactor = data.elementAt(15), recoveryHeartRate = data.elementAt(16), workoutType = WorkoutTypeExtension.fromInt(data.elementAt(17)), - avgPace = CsafeIntExtension.fromBytes(data.sublist(18, 20), + avgPace = CsafeIntExtension.fromBytes(data.sublist(18), endian: Endian.little) / 10, super.fromBytes(data); From b18c976d4de3c5a1e4789f088bc885518d1f34a7 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sun, 6 Apr 2025 15:39:18 +0000 Subject: [PATCH 133/220] Migration to a flutter 3 android compatible config. graddle bump from version 6.7 to 8.5 kotlin bump from version 1.6.21 to 1.9.10 permission_handler upgrade from 10.2.0 to 11.1.0 --- example/android/app/build.gradle | 58 ++++++++----------- example/android/build.gradle | 19 +----- .../gradle/wrapper/gradle-wrapper.properties | 5 +- example/android/settings.gradle | 31 +++++++--- example/pubspec.yaml | 4 +- pubspec.yaml | 2 +- 6 files changed, 55 insertions(+), 64 deletions(-) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 8b1b141..58afde7 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -1,33 +1,23 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' +plugins { + id "com.android.application" + id "kotlin-android" + id "dev.flutter.flutter-gradle-plugin" } -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { - compileSdkVersion 33 - + namespace "com.example.fresh_example" + // Any value starting with "flutter." get its value from + // the Flutter Gradle plugin. + compileSdk flutter.compileSdkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = '17' + } sourceSets { main.java.srcDirs += 'src/main/kotlin' } @@ -35,10 +25,12 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.fresh_example" - minSdkVersion 21 - targetSdkVersion 30 - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName + // You can update the following value to match your application needs. + minSdk flutter.minSdkVersion + targetSdk flutter.targetSdkVersion + // You can set these values in the property declaration or use a variable + versionCode flutter.versionCode.toInteger() + versionName flutter.versionName } buildTypes { @@ -53,7 +45,3 @@ android { flutter { source '../..' } - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} diff --git a/example/android/build.gradle b/example/android/build.gradle index 1881064..1627dad 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,20 +1,7 @@ -buildscript { - ext.kotlin_version = '1.6.21' - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - allprojects { repositories { google() - jcenter() + mavenCentral() } } @@ -24,6 +11,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { - delete rootProject.buildDir +tasks.register("clean", Delete) { + delete rootProject.layout.buildDirectory } diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index bc6a58a..1af9e09 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ -#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/example/android/settings.gradle b/example/android/settings.gradle index 44e62bc..8623888 100644 --- a/example/android/settings.gradle +++ b/example/android/settings.gradle @@ -1,11 +1,26 @@ -include ':app' -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "8.2.1" apply false + id "org.jetbrains.kotlin.android" version "1.9.10" apply false +} + +include ":app" \ No newline at end of file diff --git a/example/pubspec.yaml b/example/pubspec.yaml index c669235..5edaba1 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.12.0 <3.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: @@ -31,7 +31,7 @@ dependencies: c2bluetooth: path: ../ - permission_handler: ^10.2.0 + permission_handler: ^11.1.0 dev_dependencies: flutter_test: diff --git a/pubspec.yaml b/pubspec.yaml index dab0f9c..b1f4ab4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ version: 0.1.6 repository: https://github.com/CrewLAB/c2bluetooth environment: - sdk: ">=2.12.0 <3.0.0" + sdk: '>=3.2.0 <4.0.0' flutter: ">=1.17.0" dependencies: From 0337d811b261bd57355a84c4d330bae7f6a9db61 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sun, 6 Apr 2025 15:42:11 +0000 Subject: [PATCH 134/220] updating gitignore from up-to-date template https://github.com/flutter/flutter/blob/master/.gitignore --- .gitignore | 137 +++++++++++++++++++++++++++++++++++++++--- example/.gitignore | 145 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 259 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index c20e093..6ce9b51 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,9 @@ +# Do not remove or rename entries in this file, only add new ones +# See https://github.com/flutter/flutter/issues/128635 for more context. + # Miscellaneous *.class +*.lock *.log *.pyc *.swp @@ -15,26 +19,143 @@ *.iws .idea/ -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ +# Visual Studio Code related +.classpath +.project +.settings/ +.vscode/* +.ccls-cache + +# This file, on the master branch, should never exist or be checked-in. +# +# On a *final* release branch, that is, what will ship to stable or beta, the +# file can be force added (git add --force) and checked-in in order to effectively +# "pin" the engine artifact version so the flutter tool does not need to use git +# to determine the engine artifacts. +# +# See https://github.com/flutter/flutter/blob/main/docs/tool/Engine-artifacts.md. +/bin/internal/engine.version + +# Flutter repo-specific +/bin/cache/ +/bin/internal/bootstrap.bat +/bin/internal/bootstrap.sh +/bin/internal/engine.realm +/bin/mingit/ +/dev/benchmarks/mega_gallery/ +/dev/bots/.recipe_deps +/dev/bots/android_tools/ +/dev/devicelab/ABresults*.json +/dev/docs/doc/ +/dev/docs/api_docs.zip +/dev/docs/flutter.docs.zip +/dev/docs/lib/ +/dev/docs/pubspec.yaml +/dev/integration_tests/**/xcuserdata +/dev/integration_tests/**/Pods +/packages/flutter/coverage/ +version +analysis_benchmark.json + +# packages file containing multi-root paths +.packages.generated # Flutter/Dart/Pub related **/doc/api/ .dart_tool/ .flutter-plugins .flutter-plugins-dependencies +**/generated_plugin_registrant.dart .packages +.pub-preload-cache/ .pub-cache/ .pub/ build/ -# If you're building an application, you may want to check-in your pubspec.lock -pubspec.lock +flutter_*.png +linked_*.ds +unlinked.ds +unlinked_spec.ds + +# Android related +**/android/**/gradle-wrapper.jar +.gradle/ +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/**/GeneratedPluginRegistrant.java +**/android/key.properties +*.jks +local.properties +**/.cxx/ + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/.last_build_id +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/ephemeral +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# macOS +**/Flutter/ephemeral/ +**/Pods/ +**/macos/Flutter/GeneratedPluginRegistrant.swift +**/macos/Flutter/ephemeral +**/xcuserdata/ + +# Windows +**/windows/flutter/ephemeral/ +**/windows/flutter/generated_plugin_registrant.cc +**/windows/flutter/generated_plugin_registrant.h +**/windows/flutter/generated_plugins.cmake +# Linux +**/linux/flutter/ephemeral/ +**/linux/flutter/generated_plugin_registrant.cc +**/linux/flutter/generated_plugin_registrant.h +**/linux/flutter/generated_plugins.cmake +# Coverage +coverage/ +# Symbols +app.*.symbols -## Custom stuff +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +!/dev/ci/**/Gemfile.lock +!.vscode/settings.json -coverage/ \ No newline at end of file +# Monorepo +.cipd +.gclient +.gclient_entries +.python-version +.gclient_previous_custom_vars +.gclient_previous_sync_commits \ No newline at end of file diff --git a/example/.gitignore b/example/.gitignore index 0fa6b67..6ce9b51 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -1,5 +1,9 @@ +# Do not remove or rename entries in this file, only add new ones +# See https://github.com/flutter/flutter/issues/128635 for more context. + # Miscellaneous *.class +*.lock *.log *.pyc *.swp @@ -15,32 +19,143 @@ *.iws .idea/ -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ +# Visual Studio Code related +.classpath +.project +.settings/ +.vscode/* +.ccls-cache + +# This file, on the master branch, should never exist or be checked-in. +# +# On a *final* release branch, that is, what will ship to stable or beta, the +# file can be force added (git add --force) and checked-in in order to effectively +# "pin" the engine artifact version so the flutter tool does not need to use git +# to determine the engine artifacts. +# +# See https://github.com/flutter/flutter/blob/main/docs/tool/Engine-artifacts.md. +/bin/internal/engine.version + +# Flutter repo-specific +/bin/cache/ +/bin/internal/bootstrap.bat +/bin/internal/bootstrap.sh +/bin/internal/engine.realm +/bin/mingit/ +/dev/benchmarks/mega_gallery/ +/dev/bots/.recipe_deps +/dev/bots/android_tools/ +/dev/devicelab/ABresults*.json +/dev/docs/doc/ +/dev/docs/api_docs.zip +/dev/docs/flutter.docs.zip +/dev/docs/lib/ +/dev/docs/pubspec.yaml +/dev/integration_tests/**/xcuserdata +/dev/integration_tests/**/Pods +/packages/flutter/coverage/ +version +analysis_benchmark.json + +# packages file containing multi-root paths +.packages.generated # Flutter/Dart/Pub related **/doc/api/ -**/ios/Flutter/.last_build_id .dart_tool/ .flutter-plugins .flutter-plugins-dependencies +**/generated_plugin_registrant.dart .packages +.pub-preload-cache/ .pub-cache/ .pub/ -/build/ +build/ +flutter_*.png +linked_*.ds +unlinked.ds +unlinked_spec.ds + +# Android related +**/android/**/gradle-wrapper.jar +.gradle/ +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/**/GeneratedPluginRegistrant.java +**/android/key.properties +*.jks +local.properties +**/.cxx/ + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/.last_build_id +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/ephemeral +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# macOS +**/Flutter/ephemeral/ +**/Pods/ +**/macos/Flutter/GeneratedPluginRegistrant.swift +**/macos/Flutter/ephemeral +**/xcuserdata/ + +# Windows +**/windows/flutter/ephemeral/ +**/windows/flutter/generated_plugin_registrant.cc +**/windows/flutter/generated_plugin_registrant.h +**/windows/flutter/generated_plugins.cmake + +# Linux +**/linux/flutter/ephemeral/ +**/linux/flutter/generated_plugin_registrant.cc +**/linux/flutter/generated_plugin_registrant.h +**/linux/flutter/generated_plugins.cmake -# Web related -lib/generated_plugin_registrant.dart +# Coverage +coverage/ -# Symbolication related +# Symbols app.*.symbols -# Obfuscation related -app.*.map.json +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +!/dev/ci/**/Gemfile.lock +!.vscode/settings.json -# Android Studio will place build artifacts here -/android/app/debug -/android/app/profile -/android/app/release +# Monorepo +.cipd +.gclient +.gclient_entries +.python-version +.gclient_previous_custom_vars +.gclient_previous_sync_commits \ No newline at end of file From ebab62e5d4641b41817f61a744a0589c6be3b26b Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sun, 6 Apr 2025 15:43:27 +0000 Subject: [PATCH 135/220] Updating Manifest according to current state of flutter_reactive_ble --- .../android/app/src/main/AndroidManifest.xml | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 88b2d57..dab5e37 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,18 +1,10 @@ - - - - - - - - - + + + + + android:windowSoftInputMode="adjustResize" + android:exported="true"> - - - - - - - - - + + + + + android:windowSoftInputMode="adjustResize" + android:exported="true"> diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index dab5e37..d2bf230 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.example.c2bluetooth_example"> @@ -7,7 +7,7 @@ + package="com.example.c2bluetooth_example"> diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index 672d7e3..e820de9 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -11,7 +11,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - fresh_example + c2bluetooth_example CFBundlePackageType APPL CFBundleShortVersionString diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 5edaba1..d1aa0dc 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,5 +1,5 @@ -name: fresh_example -description: A new Flutter project. +name: c2bluetooth_example +description: Example app for c2bluetooth package. # The following line prevents the package from being accidentally published to # pub.dev using `pub publish`. This is preferred for private packages. From a4518b3dd45cb356f9a805fb23f52501938b5bb1 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Fri, 2 May 2025 21:41:03 +0000 Subject: [PATCH 176/220] Complete overhaul of the example app to be very simple and clean --- example/assets/images/logo.png | Bin 0 -> 17468 bytes example/assets/images/logo.svg | 16 ++ example/lib/main.dart | 417 ++++++++++----------------------- example/pubspec.yaml | 10 +- 4 files changed, 141 insertions(+), 302 deletions(-) create mode 100644 example/assets/images/logo.png create mode 100644 example/assets/images/logo.svg diff --git a/example/assets/images/logo.png b/example/assets/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b1c63db0293982e5c20752b0ac0e68d4e43fac54 GIT binary patch literal 17468 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 F{{Tl4nMMEr literal 0 HcmV?d00001 diff --git a/example/assets/images/logo.svg b/example/assets/images/logo.svg new file mode 100644 index 0000000..ba74749 --- /dev/null +++ b/example/assets/images/logo.svg @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/example/lib/main.dart b/example/lib/main.dart index 5308873..91f5b26 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,337 +1,160 @@ import 'dart:async'; import 'dart:io'; -import 'package:c2bluetooth/c2bluetooth.dart'; -import 'package:c2bluetooth/models/workout.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:permission_handler/permission_handler.dart'; +import 'package:c2bluetooth/c2bluetooth.dart'; -void main() { - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primarySwatch: Colors.blue, - ), - home: SimpleErgView(), - ); - } -} +void main() => runApp(const MaterialApp(home: QuickstartPage())); -class SimpleErgView extends StatefulWidget { +class QuickstartPage extends StatefulWidget { + const QuickstartPage({super.key}); @override - _SimpleErgViewState createState() => _SimpleErgViewState(); + State createState() => _QuickstartPageState(); } -class _SimpleErgViewState extends State { - String displayText = "_"; - String displayText2 = "_"; - String displayText3 = "_"; - - ErgBleManager bleManager = ErgBleManager(); - - Ergometer? targetDevice; - StreamSubscription? scanSub; +class _QuickstartPageState extends State { + final ErgBleManager _bleManager = ErgBleManager(); + AppState _state = AppState.idle; + StreamSubscription? _connection; + double? _distance; - /// Storing the connection [StreamSubscription]. - /// Call cancel() to disconnect the device - StreamSubscription? _ergConnection; - - /// Using [ValueNotifier] to handle app states - ValueNotifier ergStateNotifier = - ValueNotifier(ErgometerConnectionState.disconnected); - ValueNotifier messageNotifier = ValueNotifier("Welcome"); @override void initState() { super.initState(); - handlePermissions(); + _initBle(); } - Future> handlePermissions() { - return [ - if (Platform.isAndroid) Permission.bluetoothConnect, + /// Ask once for permissions before init + Future _initBle() async { + final perms = [ + Permission.location, // Android: BLE scan needs location if (Platform.isAndroid) Permission.bluetoothScan, - if (Platform.isIOS) Permission.bluetooth, - Permission.location, - ].request().then((result) { - if (result.containsValue(PermissionStatus.denied)) { - print('Your device is experiencing a permission issue. $result'); - messageNotifier.value = "Insufficient permissions: Stopped"; - } - return result; - }); + if (Platform.isAndroid) Permission.bluetoothConnect, + if (Platform.isIOS) Permission.bluetooth, // iOS + ]; + final statuses = await perms.request(); + if (!statuses.values.every((s) => s.isGranted)) { + setState(() => _state = AppState.permissionDenied); + return; + } } - startScan() async { - messageNotifier.value = "Scanning..."; - - scanSub = bleManager.startErgScan().handleError((error) { - print('Your device is experiencing a bluetooth issue. ${error.message}'); - messageNotifier.value = "Scanning Issue: Stopped"; - }).listen((erg) { - //Scan one peripheral and stop scanning - print("Scanned Peripheral ${erg.name}"); - stopScan(); - setState(() { - targetDevice = erg; - }); - messageNotifier.value = "Found ${erg.name}"; - }); - } + Future _startBleFlow() async { + setState(() => _state = AppState.scanning); - stopScan() { - scanSub?.cancel(); - scanSub = null; - } + // Scan, take first ergometer + final erg = await _bleManager.startErgScan().first; - connectToDevice() async { - if (targetDevice == null) { - messageNotifier.value = "No Device Selected"; - ergStateNotifier.value = ErgometerConnectionState.disconnected; - return; - } - ergStateNotifier.value = ErgometerConnectionState.connecting; - messageNotifier.value = "Device Connecting"; - - _ergConnection = - targetDevice!.connectAndDiscover().listen((connectionStatus) { - switch (connectionStatus) { + // Connect & discover + _connection = erg.connectAndDiscover().listen((state) { + switch (state) { case ErgometerConnectionState.connected: - messageNotifier.value = "device: ${targetDevice!.name}"; - subscribeToStreams(); + setState(() => _state = AppState.connected); + break; + case ErgometerConnectionState.connecting: + setState(() => _state = AppState.connecting); + break; case ErgometerConnectionState.disconnected: - targetDevice = null; - messageNotifier.value = "Disconnected"; + _distance = null; + setState(() => _state = AppState.idle); break; - default: } - ergStateNotifier.value = connectionStatus; }); - } - - setup2kH() async { - if (targetDevice == null) return; + // Wait for workout summary + final summary = await erg.monitorForWorkoutSummary().first; + _distance = await summary.workDistance; - // ignore: deprecated_member_use - targetDevice?.configure2kWorkout(); + setState(() => _state = AppState.done); } - setup10kH() async { - if (targetDevice == null) return; - - // ignore: deprecated_member_use - targetDevice?.configure10kWorkout(); - } - - setup2k() async { - if (targetDevice == null) return; - - targetDevice?.configureWorkout(Workout.single(WorkoutGoal.meters(2000))); - } - - setup10k() async { - if (targetDevice == null) return; - - targetDevice?.configureWorkout(Workout.single(WorkoutGoal.meters(10000))); - } - - subscribeToStreams() async { - if (targetDevice == null) return; - - // ignore: deprecated_member_use - targetDevice!.monitorForWorkoutSummary().listen((summary) { - print(summary); - //TODO: update this for futures - summary.workDistance.then((dist) { - setState(() { - displayText = "distance: $dist"; - }); - }); - summary.timestamp.then((time) { - setState(() { - displayText2 = "datetime: $time"; - }); - }); - summary.avgSPM.then((spm) { - setState(() { - displayText3 = "sr: $spm"; - }); - }); + void _disconnectBle() { + _connection?.cancel(); + setState(() { + _state = AppState.idle; + _distance = null; }); } @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Center(child: Text("c2bluetooth example")), - ), - body: Column(children: [ - Expanded( - flex: 2, - child: workoutSummary(), - ), - Expanded( - flex: 2, - child: configureWorkout(), - ), - Expanded( - flex: 1, - child: manageDevice(), - ), - ]), - ); - } - - Row manageDevice() { - return Row( - children: [ - Expanded( - child: Container( - child: Column( - children: [ - Spacer(), - ValueListenableBuilder( - valueListenable: ergStateNotifier, - builder: (context, state, child) { - switch (state) { - case ErgometerConnectionState.connected: - return ElevatedButton( - onPressed: () { - // Cancel StreamSubscription to disconnect targetDevice - _ergConnection?.cancel().then((_) { - targetDevice = null; // reset targetDevice - ergStateNotifier.value = ErgometerConnectionState - .disconnected; // change state to disconnected - messageNotifier.value = 'Disconnected'; - }); - }, - child: Text("Disconnect"), - ); - case ErgometerConnectionState.connecting: - return ElevatedButton( - onPressed: () {}, - child: Text("Connecting..."), - ); + String message; + String hint; + VoidCallback? action; + IconData icon; + + switch (_state) { + case AppState.idle: + message = 'Disconnected'; + action = _startBleFlow; + icon = Icons.bluetooth_searching; + hint = 'Tap button to start scanning'; + break; + case AppState.permissionDenied: + message = 'Permissions denied'; + action = null; + icon = Icons.block; + hint = 'Restart app and grant them'; + break; + case AppState.scanning: + message = 'Scanning…'; + action = null; + icon = Icons.wifi_tethering; + hint = 'Scanning for the first erg around'; + break; + case AppState.connecting: + message = 'Connecting…'; + action = null; + icon = Icons.bluetooth_connected; + hint = 'Wait a second'; + break; + case AppState.connected: + message = 'Connected'; + action = _disconnectBle; + icon = Icons.link_off; + hint = 'You can try a rowing session or disconnect at any time'; + break; + case AppState.done: + message = '🏁 Done! Distance: ${_distance?.toStringAsFixed(0)} m'; + action = null; + icon = Icons.flag; + hint = 'This data was recovered from the ergometer subscription'; + break; + } - default: - return ElevatedButton( - onPressed: () { - targetDevice == null - ? startScan() - : connectToDevice(); - }, - child: targetDevice == null - ? Text("Start Scan") - : Text('Start Pairing'), - ); - } - }), - Spacer(), - Center( - child: ValueListenableBuilder( - valueListenable: messageNotifier, - builder: (context, message, child) { - return Text( - message, - style: - TextStyle(fontSize: 18, color: Colors.blueGrey), - ); - }), - ), - Spacer(), - ], + return Scaffold( + appBar: AppBar(title: Center(child: const Text('c2bluetooth example'))), + body: Column( + children: [ + Expanded( + flex: 1, + child: SvgPicture.asset( + 'assets/images/logo.svg', + width: 150.0, + height: 150.0, ), ), - ), - ], - ); - } - - Row configureWorkout() { - return Row( - children: [ - Expanded( - child: Column( - children: [ - Center( - child: TextButton( - onPressed: setup2kH, - child: Text("Configure a 2k (hardcoded)")), - ), - Center( - child: TextButton( - onPressed: setup10kH, - child: Text("Configure a 10k (hardcoded)")), - ), - Center( - child: TextButton( - onPressed: setup2k, child: Text("Configure a 2k")), - ), - Center( - child: TextButton( - onPressed: setup10k, child: Text("Configure a 10k")), - ), - ], - ), - ), - ], - ); - } - - Row workoutSummary() { - return Row( - children: [ - Expanded( - child: Column( - children: [ - Center( - child: Text( - displayText, - style: TextStyle(fontSize: 24, color: Colors.blue), - ), - ), - Center( - child: Text( - displayText2, - style: TextStyle(fontSize: 24, color: Colors.blue), - ), - ), - Center( - child: Text( - displayText3, - style: TextStyle(fontSize: 24, color: Colors.blue), - ), - ), - ], - ), - ), - ], + Expanded( + flex: 3, + child: Container( + child: Column( + children: [ + Center( + child: Text(message, + style: TextStyle(fontSize: 50), + textAlign: TextAlign.center)), + Center(child: Text(hint, textAlign: TextAlign.center)), + ], + ))), + ], + ), + floatingActionButton: FloatingActionButton( + onPressed: action, + child: Icon(icon), + ), ); } - - @override - void dispose() { - // disable subscription on scan and ergometer ble connection - stopScan(); - _ergConnection?.cancel().then((_) => _ergConnection = null); - bleManager - .destroy(); //remember to release native resources when you're done! - super.dispose(); - } } + +enum AppState { idle, permissionDenied, scanning, connecting, connected, done } diff --git a/example/pubspec.yaml b/example/pubspec.yaml index d1aa0dc..92bbe2b 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -28,10 +28,13 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + flutter_svg: any c2bluetooth: path: ../ + # ask user whether to grant or not bluetooth permissions permission_handler: ^11.1.0 + dev_dependencies: flutter_test: @@ -47,11 +50,8 @@ flutter: # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg + assets: + - assets/images/ # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. From e7bfe01b768bdd9944e0bb94ac11c0796efec059 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Fri, 2 May 2025 22:12:15 +0000 Subject: [PATCH 177/220] updating example's readme --- docs/images/demo/completed.png | Bin 99941 -> 0 bytes docs/images/demo/connected.png | Bin 0 -> 84684 bytes docs/images/demo/pre-scan.png | Bin 85203 -> 80974 bytes docs/images/demo/premission-denied.png | Bin 0 -> 88835 bytes docs/images/demo/scanning.png | Bin 0 -> 80424 bytes example/README.md | 14 +++++++------- 6 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 docs/images/demo/completed.png create mode 100644 docs/images/demo/connected.png create mode 100644 docs/images/demo/premission-denied.png create mode 100644 docs/images/demo/scanning.png diff --git a/docs/images/demo/completed.png b/docs/images/demo/completed.png deleted file mode 100644 index deacd080b8a939df4ad989f63a2f618ed6660dc3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 99941 zcmeFZXE&dU&ny$|NO{0y?1lAeb1n!&L_*w&&Mmu$Is2nC(NxNCc>+u zrJ*CDsQX#~wBzfI|6K1OI4LhS=0Dr`!hE85U+?{An-IL;7)$g&@AIE)^Yilai}Ue` z^NKR?35p8}i}Q-%aq$X?^YVg5|34c3zZ#4B-yh=YD*x{q_!=X?2oApHuBjl0S2{qm z0d{V<%PDFT5fRNUsV(B+G2kh_l-2f5+nV?B*FJ8>?YmnkTE+G;#YMi6yH5Pxngsvm zQTF039ohO?oj*0(CG}(WM&ypWWzGLaW>h*(YMnYtYQO6zG=4NBkI|V3=KA=Y|0A9O zOD|JZ8iJmcCZxOjee4?+);(Y8GjBn$fj0wpy8F=37R2Bh=M1dc5VQvmk87CZg!pRX zIYZ#pAmjBvDY$wWqWQnO|A%{n@6HMFbEB6Uyi~`o!vwNqhBHznv6)7aJ!=A zBa0=o-Z>lr?MzmAuZU?z~y z`VC*U{M((Ip1qwtzL@%hn?pvrReWCh#TsQM28$Qt}|@YQoj8j?|tC45vM$%=L%w+PEwG?NX@U;^QFIj4 zJr)yn^{|r(CmbV7P5}1D5oZ@kTr0%y$KVMa?p@b#3W1(}#;1wD_n7$xM4i0-{{$4w zqGmnoho@KfJygPnGUVXMVN8dt6EAaDZP(IUEnUh^dc${hP2NUf4EK@A82CzO+&i&i>kdt_sA#MWP!QiKBqS>gE|yp|Dg)2(^R&Ib z-|+^Y*sH=dOIE*1qf4w_*w&T^&ax26L7=lKm5oW0v=d{!Q#sw!wK0l(v~-BPpyQ>> zp$6Ct+o>0|My_ru zEKHBq9d0Bnvdfd<<2W0hM~8T-Q#lFXP9!Y4?$i-9s8q{(8MtnKX!Y8V~>Vcjg{OtjZihS_cik8JWZ0c?LAJWBzP5L*WIPW&*7qMv5W*Oj z^Ykh=euq_Q898tb8^eigTLWjupFWoJOHcUPV#zFMk{>b>$;HcxNDD~6m9?zzznFqi zs6CD$TM<6-9z|PyX>xe8$%vafL}DK_`(6Z);$iD;evfH{8AmHnLnbpblkFl~&d0Z* z-umyzNS40G#@#r+4012~j^y)5MqMUH?FkAO@ctOBXtmEEyKjjmv_|OCw3wmUp+I z8z+ic?-M!%+~dEGtQ-`x7o|!Jm-_a~!8`2ukKC_KjbP*tl}2vLev7s6+YE6{lEzrl z)2+0L`5fRum7=ygW|f?L0+jVDd*<%LCAn(-jmN=NNiL(%g9C6|-^2?Da6=3QY`{2! z4dmIWh*udeQ`^}3Yo)|n3*evsdHD3u4r~(W{gPD7nvczR$Dw|no~#!uUB(3M-)Rih z-5EK(E`xha+^|`RoJPzJV=OVCuNoIjit$ZIn8)RK29ZyFepz65=Zl zUyn-6(g0fxo$Z@^Q@utS@c@4*HhXLqXR+drlb)*UA|&WgC*jZ_m|wmfeyPsDzaO=H&1-M=cHmbt z0U1bp{i5X)wRv8X23eJ$qQMZT6dR+cyJMVZnEILPjAxu#dqh-+Ldb%@<~s2$+n zu^w~z=m&OC=;k$NO}KrUvr{SN-P-Vje%kr@qCpQkO2~0G8&M#WN6V*f+~jP;(SlaO zeNBCyUDnQ5muIsU2}sUt1Sa$nrEPx{&E4CKKF$)9cNz)ZTqzCbwhudggD`EwCIF^OrFh6LTPiZa}23T}^=xJJ+d%4_9J{!TSj`VLzbb#5|BhxsF zY(OQnl$~=_8)Y<_z5VqGmfu?iW?msz)DY^;%GV|b75S`rx8*dZMMLO zWHE70pZ1+Dg*BV#6vY2zB9;T*YOlL?I~21Q*!YA>+dSuZG9d#SC+(4aJfK(m6KmYi zJQBp|Y02F2rF;F25XROu?iGuNW4hT`giJk~-@$7mcer&&-lke_Gx%(>H1V z?8m}Dk-wi(CnUE$!8vtSsuj2Q%N|9zX`Z0^@E?3kYg3+&>xp661AFQjqtT{Vrg6b) zs$=n-Cu3_*Zw1Qc7ZuodD@Pn+@D*~DAKui`_U3S`jO|l&y;1*<^TQ@TVj-5P4S90L z)ct-8ZC%Lqp^LQ!4rVa-%%kB2^YtLs6WimH9GpbiYZGnVchRWF+5zGcY9`OtPEO_2*nMnWp|9DEEm=}hXXXf_ z>rQZ4E+@@Z5O-{}`I4UsC~WX>zYf?z5aNy$ky`ZhryaA%?!@)v zo9t#{Yc@dx1-oem*j{VG=&`y_b#(2^$J@nDGyVkvZ6Q;SScx*3#)TWPwM%~wanjZK zwGH#MAr#56OrpjaC83Y8r;5l~gsA>{uB*H9)}{$f%$3uC562U1>;)h8u zNduPpi=ezkyvW>HmU%vbuE%mUI`nV9CdJ!D>b5{PdS4W>%deg&?K&3ewDc=|=~mpR zb+@V~z*BlyX0L1d3eq?2(}a@ik+8Drh3SISt4j}^y=wOjVLzf~Ml31HNzzS~aOkFL zx-C6Dvai;vc3X#jx3tK4qrAh@D%EVC17=9M!pv@}K<$x4k?$n-a5IY8>vUVSJiiu` zX+)b8tw^%p638$o#>x65?=UiFe%a5ZqqJ?tq1TQdd$AcP1J%TIPAc5--M`QX^D^b< zID&(`FF;hF%UrlvM%@%KqLF6SymZkww$~iP?l~!%d5&&#R(TCSkJZ?>vcRDCZW0k7k5Rz2n0Kq5-g2pN-G$zxu7b#&)p0Pi`p8s&E@9`0t zmE2(K4QwlG?}TnJXD+atu7%m0 zXX9GTT?5zs(mKX4RN6Z(;>H;%+~gzKO*7-|*AG+zmI*Z;x`lS=jMWq@@V~u*hx9VqTuu3Q zaGRdDS%zP1HE)A)r40COJ7-7tbs52D9Tt^~w;5fzsbgh3aE?%%#<2_*uSR8CNj*%< z9`D~t+J4vk67lhwmsz9baP@$idfg-%AZaTL9;KdQtDMUI&kRH`gv-idb2G~7(W`8> zA04S!#N2Ob1oWHGSxc{byPs|$@ct-NG#EDAVbLLL)a%b95%~jIUJ!O*R{$g#o$X{y z2+aD2UBc%!_c15*_Ay%F{kS{9FrTp_cDxO%T`|uEAol@6VLt>(s#$Ymmg%XBUPvZ0BYN~wh+7&OtU%UGiMFa3tzq_L78R=TNi3n=OE(E& z8(&d3m^`>ls#P6S@dY`In+Au+_^~6vxQ@HS6wdW^N)P3Szdy*iBhI{E>*rroJElEW zBk7@oEf||(gBBEVGb`G-`_<9e>7VV;;h3AU*PxWA{GsDQSYM)E$ule2K(;Gx7i6d zdC&eZ%GmAQEOQIh%6P)=CF&gDtEju&^u$ zFAh^@$nwjbn_Yq{_qBivb@tob8Xo_I$-iyYGUxU5%X!SF->ix%ju|Ik^P}aSw9mJ-}qshH%2@j#0myr;ezJDAYIZjKLIm-z(47fJv|1)6Aon#KcbVjzrE4jCrxe8%ua&@* zl~rS*Vle-p2z_SS9#=OGH}5N#-3a+Yc3fW%AlTcQ4h<93vwmIM>k^*{IE#Q?V|daH zXS6s2S#@_4ig+3)tWG(rjdn8A&-YT{No7TkKNn$@b+=-f6qAS6U+DUHIszcUgs2!a zKvtknbSL5Xvidc-dG<;hhqcil+L$_LR%c}gOwWXWs6UuUOmPc!x6^aM-vAulG zIUt%-TLnMXHlx9FkkrQkoOn~VJcR^2W6Qxfl@7Ov%3v(dq*CnnEfh$No7P4K#^*uA zxisI?b;pyv)BSzKh;oGmW9npTn$>bXvgW6DWH$i;6dKz4eXpr<>|W~K6LePfSnK=} zJOJtSpz@!)ra3a>8h`+`baq=#pX_0RH9i3codXL_>9Zn$&S_gY0uyEz_ae6=HLkp)*8FCM%V*@KrFHV!Lehq;YgY|BYrpbvbXAqsPu&zKM!3R8Ltl{cxM)R=_=D_FrW9W-sI~D}~67XAfR!{?bLc>F)E$ ze=Y|&K&s_&&$LtVR@M&}6U8%DOGxv!#|UjvH?J5#tN#j7#ww0ZOYx0AvJ#>KV7>{~ZZF@^&OR6nEI?-xeruZ|V)~sB6>w(+e^%MWYDcyd zK`eYw?gbp17?W^eba`*Mnx4_PV11*J-J{NHzbO6Gwj^erIn$soBPzXgMcC&z2k8^M z+sEEuP$fDfJ*|^4Q|TEx=ll3s1Jl@*^K)O!!;eH_tbsi>0jVY++IVcwO^Vzd=+=`? zl%9iZUD7J}of83oAAh}af^?S^2~l*_kZBTK`}h03U()m}Umxv;Dl%@x53k4{!f-R0^!d*Yp=_nnqbKEd|_LSG7#{QAlqIWmLWS7H`AdRe*}o zUNq39!xu3!ky%e)&&=x^ARx!XFF3s@XSjlN{?b|VOG4Ydaknul+-koX^FCLk+yP^B z`|>2~?Eq|L<{wFd=?QG2@t2d&My;Y$X~wN7Q|5Rda$GS;p{r8vTq3exLRd3F)CV5c z01oF~+)waI1pvXwrtYnld8S@$>6@U4?7d%G7lDGkFPu-B+K>%f{{rI;0xShUW~$L_ zFhz)WmBZ|o(c6!qVwbZ`njA+4HuK{8X}c2(_^5O-H%jNX&)XFUSE$vxD~#PYcYUW* z!aq)xk`P5y$rQZ#8{RtQj5+90*>t9Ah5+8-Q~u*m=?)v-{>K@Mb$ZBFYvfX#quv+V zld7VFglrsMj-~}nT*BE(V-pIS)u3#-2Sa?$em92tayCle5X)5U=`FAEc?5MQpi9bx zy-B(E0`SFUGO*LJ;jrkIsx?%299`zv$c}MKsh#6=1x}>SX5{aw&5N~z!U@m8O>O!mq_DZpKMq)N-29%?;^wct{EzPSf*52Uzu7_y6Oun0BE zx$L1w()~eks$#M2m)GRkt#Sg)b$`be9Wb{3;}jUaNZtKHyIhxH_9g`KCgd0(zn$}0 z(s5)w5kC`jReN}I?*92)*v3_+#p57zvary)AkEI7Kbg?9zMho;zd(@?Fc?w)ISaX-K4mI@$3z>yis4I=As+-1mQHj>|*Dh(_O^!gA1eE;)b+G z46p8#t_DN#_7r{Q<92u9yWw+e&D=BJQ$1F>Z*MyxM!e8$21ogNo=#~8kdE%w(6{lo zUoIHXX=mSQ3@zhOfAx_ts;22c=aCgth(XTo0c!TVFC{!D5~@fl7Lc0!=M{?HNS$V0 zrIoY;kPNUEpMP9~&UAB9f?s^+kA@ZFs?=KV)>ivv7#mSJ4w;I1POY1z5B9Fb0ifms z&&Lj5#;4O%ISiln6H)_L92LjqBuf@G1`nwBM;*=mKm_;|vn#>Amm(J?YxU@ybyfu{ z@AtP}?$pb{nQ0!dN&&_(wm3MSG77emen3KgtmMZRt#-ERvaE({Ic(`w7-V~$sLTP4 z^_ZKkFxNVcFr~T0rUVKDCYteQqnz#*<1-T^)gR)sAH|tn_Iq`jptnN)X2zaCL~<(a zieAuh>#KwiTCExNhg^qSE<3k4*tz%meLUaQxo@UhwFKaFQt=#8CNa`qw;}KS^MHxp zKa+bWb&jo#*ZQ&_7X74zO85$uxpnoWHRS8UZ`zX4G!m|^VDjUWz(KVT=eXX(t(ow; zI`NDavo!umy?Cc&BlEk=+rh?wA9maK(XGn**)IT_o(wX2oH*?Gr$j;GCV7qD^KOCPyh>X0^5-vNe|q&Uzl+%=Z!&of*S! z%_zCY?=-SgEek9og8=$wwd^8%T7W;6`EmmSI6SPyzRw`kb8ovOYJ#-v?RyziH;>f{ zE3EwR+sG!D824tUtwBVdWq0%Apslj|omJ%WPo&z8R_eN1_Aps`6FOp-O1dCRlQGpf z*&g|_YZ^~WT~g-g0NY%?fld8H9Qb`Qti5;`(aLt-IP!%zLucIyU^F|Wn8@z(1>Ys2 zi4Tx*<2wN-V;(&>5SwqM0ciy=XCh$?NV1wdX1}Wx{#_};Vi|`4AcU!wDD{B`ak{5c1wFk`0+X1|N(mc9|fJ)Ts58>CZ%njSp}sPh*W zi3)3!?DOMkjzI#c6*h)>2dq^#hO5sVlJ7U-8uA$aHX$a-Sz-I0K40f22yO7nop9Zt z;K$PWiagh-*y@Evk+q&m9ITuwna2I_W;%6#)7khE9oqXQ!Q?cJw$rzihIa=WALs2& zX*E)ekGc{pLfIj1T-zDgCJoQ@6-Nhm+)mKtwZn24W@~ZFwLO5ZPQ4*Mz*b{Z{$_Vi z;$tX9qSBYo`!WXOP>rqqyi8+bUYJ`a7+90}Apm=z5k^!Fpdj;c{$ML|`O@gur^-pC z^}zhpZ)}&K9zm0E{~Uf7Jt^EMnV;u1Bi>Y2DpT27ip;Y$XvM96s5}QW%YkO&aQnXi zH~CUKE{FGT`8@TbMHmV^$S=@YLrx7=zc+k>K511g%=}~X66Ffwv&j33J_qG4K-W*1 z^Rp$49)$n-n-+wteUznD`*dT!jnVX?Bt_?>29y5GP)~$r~M*t z+@Wc3*Ua?d-%v|V^HitM^S4J-Bz9`G9?t@NW^3Ccjh!2O&o$iRv9L9WXECL`+0t0C zG$FZSuHPQnqRjHWml}qeToj{12K)M=@W=TL8u z{R>$_+*$K7lbb(*I0FzusdM|0iz}e{r0OukH#^)}XXw-7OyAY9wWB^0`$3d`1x1(- zrsuSm+Ur)F9ow}c%G`f}0?YQ{n8F9pr4pvod1sk{yFWEoUAS?T9Pjww#s&jkF!2+z z@Ape={+EkZtLV~*sI|3v@>lX! zkARrU=Z7|0=V}X6REaWwGfk3<1RdveMvokDC)P&@*$Gy~)(h)~&D3}YWL`=U>r_Gq z3J|qF^s@{K?kvtdSv82TjLYbNAHF^w}H z-+^`+a`&kDtQTI8)#+2&fU3w7fhE1kNX$0jxeTXFX;a9xmm06bB23g%0(x&U66CVo zyqugrWpB4K5#%aD?R!_bF8uJ2B}?O0)Ayv=6v$;`{!Syw&wo~(*;iRZj@>1j-&P*2 zBfJ~&p*VXi&`2fZixy`O;NV`qgP|LkJsU&|;nWWSdC$dWA}EDgN`P-j&!tngh%!+= z+knWut>)wGe*4Wy4U}{(qb~- zM~iH{tSD``jDWJ9>H6Fbo;MK1dz?&j2ylvyu&ONpt$WewvJ+t;JHMNL6saY|f%H8Z z?FT7_DbImONxvgWadE;ati!phHB2xMyaDdf4=Y*#2^8Q_LK%i99K^r(S4n|-LZS(P zn#ajwJ{SZmu?}ndUXK?xeg~zf-Ab4I9^1>sOj5G*XNnC+`s<0bYP~9)Q{y40B(LBJ$3_=`o=-K4-hUkOk<-Z+%~8>+}%wr^>wu%Dmdr3rAJROnQrBYysa%J zxst~-iW?EuNH$kwO4vzwV`6K;wjDj@+Ak>RYq8^TG1ElU#3y?1^oIgs{tzN6tjb4q43NBDZIgaQh3{b- zUF{=O!V6Ykx}nzA<@LcbZuQbK%DhnbPo*ZTDPODwyB*P|P14^5u z>b*R-Qg@vZT?>bdxA5m5AORr>;D=7VT&Fo&3^zW=?3}yr_Z4}JB+X|cR^cAB*xm8* zT{S?sh_j||NWWx#oMho@;twx9->m7#k=@Mn$*EORo8+3>V%1VD zo@yhLCg=#)pd;P);t>dSKgjRLDHM|1*~0_J--EgmX7|Jf)Pj;tt5;(N17(WG-+S+$ zD7xJa4it=Fo*_$qU(}Xs3UZKXbq!pS5lfUPq-|$)!@$|0fVAbK8a@G@mYajSn$W19 zmC7ec>Nqn2ob7P1#?OjtBEsu`B5rGTzSrLcLWxROCSEo{blWI>#qb%>rigIl9;&Iv z1|wkgt?=eVU(`bHD|X2BP}OSeYS85+>`f-(+@6imqE1iTBU@#|BGHOuc3d}|ZDv^o zAqA^<`-41bZfMA>9TwscI{Q+nZBN9yI!Q&sW4swLXUJi+()Pf(o!!woQxy-J60~(WW-k8?r zWp^VDfcOKW+u>@R7XvsYz;l9HThLVRlg|wgwiQ%sn=4BTQROBO*YsDC;;s4*U*hEA z!2mS_NsCwusf}*MDHoc5202EtCsYJ=QQXQy)Sgb1tHq4q8}P4n0OTzbg~Qoktt zZgT|Zc+i=ByIJ+wo4Pr-Ldz@$BH&R5(R4BsV;Kn#AGlofLRnAf9m8Dw{#Ehh{so?d zhigYIf~Bb@cQv)JlM2)Q*kFfzv88oeeO}4Z8ZrvlaW~S?(D-59Y|1-;0iTDjB{;6aT zvYMSp9Op6s;QU!ND3k)$3nVFOYP?bvzGVzVx^YV>_x&1j#2BWC0{4!7?;Fo5qG272 zHxNBZbvwzi7PHGXx?Bmvi(kUGMh}(=)v7rtMF6QXB~WAG6ZPj52|NVF6TWX#)JN4N07_Srj1O>{6gMZaP0mq^} z1_6B(qIh@OIO)p)B5VWL?V;QK7fricuK8W*k&aHd?;}J1bQ|+S>x+M{Nn9otJGcjM z6MfSN`!#vv+<)MG)QBl8VD)&-`qe?`Ne@WxC#B#^6Soxry8AY_Z13!NcrFpepL9PQ z(6%OF@n!;uN52!W65Inmei6&Bp|hYn+(HF@JL`1pPtuA5iMvNrY4nhMAfj#G7Bgo zlLX9fe2D4ht9v`;Q?pOr8mVQK*%-WO;{lA+x>_Czy^P`P%2T0BW+3`qoUI*ri(nY9 z)-Lh~uEoC^SK7V1D|!}D*Xwso1e{N3S&wPOX%iBW>VF*kYw+))-t+UVz3x$GbfNQm zV+>Euc$sl~Iciu$HZMv$ z?w>410B|@h043pK0FncsO^ly)^f;wCkM3e0eX?-eQwz8sGnf$IzAwt)cZW)opp4N! zO00rlL4-x!-~A6t4^qYST1c4_(Wdy)vBg#v<__@}tyAk?^Z3&OXlX6RSl&Dp#`Au6 zvJt73h&fLCOFJ>Gi!Hijm5}^cVZFUG@DE!`{_HtZI*9;>h}vM|_V1XUI@2u)SDcLJ z$%!o8w{#hpn|0VyaPg_dz)ATQDb*Zck2uwgNB+JM3>|Ug71%$THEw8QvAJR2pQ(>Y2bsDIq|^f5t(p-(u9f`Ggy^#%M9 zLd}xYS|!MyK|BML7tCyH;d#ZS@K^euJbSf7zMy7xd2^?QaS+Rxt=mAE>m57*EOH2{_gW6;QR)s|4Bk<>vr4~4Zmt}@!yVU8gda$=!m z&2=ThU!p^*I=|lKxH<`aFx+!KCZZFGZfR-0Ym^s%HvWm)<6p`tkrBQ1<4?i^#Y_9pj!*Q3ccxnKuEe7H;Ow|ERQr$s&WhqxXEi&^n1dy zZ#!XPTc%>l*`7CAuTXN~-#(^RS7_mQ^JL1Vxx1juy%yd)(zaaUn_lmxb-d;mje?k~ zDmlD~#|E4F{o7iZA}w>)gTyhVSL9KMPX3+E1F(z;hqc_6Ra4-$PF7JFz0FoXUj+Nr^% zLry+tA^Sbn)0H(bMh=IIX_7vh%fR~rOK;GNQ=ODPgiHoy@$jPZKaUrrIY>dtdAOv1 z5N#s_a$0nd?!4Ep!0~BLuQ=iBUB|LZbcVpm=dsL9^Fs0WZVhS*DMMW{&!UfKT6zKaTd>zlStbK($fE_+sS%eb*d{zBLVP>z7=eEiLp z+bq^i*y9+28ZW_VuZvq}sWXzOlg#yN~UCkzn zWcZm(={7r{Fm_Y6puj$csSSln3z*iP{=Q|%tSC20jFgs$u-A5(@OvK+Gt#AqK^ns0 zs^55s0@aNX6E($R?N$LteaCt+dNxuIU{*UGacZE362MlOKES%%b3uzf#?y`N~o{Ji(p~Ri`hwqcr?3T;0COey&erY zrc$3Vh<|C;QXFm*!us z0#-I~*Ye&g5W#B({b|o8!a@066I%i#YCIcOJcrkSRxtj}qotP|e(zKlBDJbsR=7)Z z97%A*#ogG>G466oS)f|GBfbyBWDD4Ti41kEYa^p1-b{-6v;A^y*J$y;OehsQCanUj z#3aO$Yuls&UA@V#jEpUsWE~eiDbk}Gq7TBcPl*^Pt|CljRBiG7i+^5bOxB|978rkp ztBjvV2?NSq%sAr;!@KD)HeqX)*X#1{=o#XhNLx+CArb>X&-{uX_~fG)J;0+|o9eK= zN3i8Mr{6@&&g$|u$Ot`#cfld4DYUh)P=1v%(xYRYFG2YprE72KTwlEAJ+9WzB0`* zX@YsS!0HCeNYl2QV(kD&gEp2H-vq7}c7FDHlA1M2#WKoFFN%nrCk>MBNX*b+v}j+FcNqdEn_V?} z$ZDH@OOhg)KG;26^05}llN2Qu<8A{aNb?zW^E7ShR`NfUNVCfHYksu~d+*b@1*{J( zngVhv$`!<<9sl2&H-QX5E+3OQs$bJlQBeu#&g!+kOzf|;rV)o(;7yr1)du(e)(GlW znSom0g>?&Quky^AP(aMw-hLPi=xS>fdw!berit6W{2dC9a+DfVA6+~+`%&#Z3WRY$ zKy_inE?CVUsa^nL6=CO#K_Av-sWz{Y6`i%8PSAZwPm;I|0-T1x^_-ze_Tfi?0hNyPO75FSHD7U{}GV>BVZ3}RlM=~51iR+ z^YianXU!h~R|eF*?)V|+03yd=sX-zxRWy)2K^OplS3yWiz>cCfcGW3d3?>p@e zeJpA6^B0|$hHUuTdbjGI>B2{k-oD^3NP|kVm%%|u2CBBdbk&UcU92F1T*Z}eP=C-` z&yuQeYs%_hK2cKg`!`zW47nW$A_qV_Zjw#gVJM?{9A+yd%wV4-$K+A@<1?`01Au@R z6`n)wTTLf6u#A@&Lt7#0m6LnaJFVX5Kg#PQ;?%H}tgVmY*&`MutfZ^m(5BA2O@=(y z389ENsdZYZ#Nw&kYJBxqYdw@#iZF)RrlwLmU5!lvds3p9``uLJvSck&e*Y#Yg=K(_ z<4#TsEA}80Ir~CCkI&@>UY(v{oy^p$+jpBA&Ox3v_25l5Tbc|9kW*Q2z2Elm z!CLDWWGcfxmNOLCbTnSFuJN3oftZ~XO_lhNl6=q9*l8C$1njKZ?E}RwfwS5cY;HTj zQ%8h-JM1$0cHq#~!NtM$fwq0MKkwFd7?Ap9+Il}WjKz;u<1c`yQ>|yB+|D_oi$s#z zr`x858QM`G^Q`<3Fiz2R!`=5Y;k~~cSKO~wIFO}c8u~Yg^B8VimVyNO0HVVKGe9Ds zy>`NLqEhzL?;NU{^NM$XqWQe;Sd z3tBj3EisLS@}pJ0bG91Y98hdlo54lMftwOgH36ZyGVHQrF7}9SP(6yRs8)0Zb$RWD zBZ|TCJ3EnFa=XvrVQQvs~2m5rbWsI~eIS8G`Wlpfefx`>N zY&)fmyOzk*MasXa7qLE=pC>K$o|EjCtlYm4UXsqEAY{-^Z9xKH>;@uPz4fcCTs6w?7|59TEpJgv*&bjFoFWV7Sp!Fv??Mwx6@2~t>hyqs=9Dnpt~$T5Wg7|6!KP{- zP4}V-wY{QARA}quBrU#%shlzc@sDdC8d~Xkp@Xn z0OT^&)3K=o;UB0{L9PTAgsvl&XfPr-pHELzB zMI+2jTUX<*vx68QT{U_W@^N8Q>Pm}saGT9Kp*;VgEEy2oo^Mch8uWKsPwKMa=7284 z9{7gs?F5Z201tsGcg6OXj*;C;5Kus@$W(*WuqR&iMUmg^Qs-}vh}q>?4_=2<#`8G8 z;1Dz)qX6D|VRmUQoCFc5Uz=yHR9k{8!3gV4+&#N^BB)%AvpIg3dE+Tp&v&^0n@!DD z&(M2}{}ICMbIt}%Qj*%fYAzLJbc2WWM(jU5SsvodW_y-yD(RKoEOQrBPnSW2JF9BR z9dgnjNHOLzGFp;R^0rz!11$6zFvd=y7qJsbEhYOMHVo& z{_xysWSGCmb(=X*S7(<03ALYJ_3#1N&a8Ep6s=YHd!lM{V z6It4rH_-opSypshOO@3APsQ+qkLsIzYM~1 zO|Q&KFchqk1}~8{Z8Jp79j(3_Tlg4is^b@3_i0VxW#`x(Xh61;e(@vwhk%8G-0m`j z5^i37KHD4wbp!4EHGNOJk6@`)DZ53e=WF_Re%Y0M;@K#lq+O5Js=?8^F15&el#xOv z{3E^QC42>%oe)XW-ZVunAoPN#E)pQ>ZpM)vz5q z?s%mffA-fTZ<5$T)5AhDyOfhx65et7Dj80x#_*K8UwF>wvCh}AcBR%wIif-@WQ1Pe znu$AQ><+@NZbZXZZLhtPe*bvPGLM111M%hAC2I1UW8S-%c2l$1oe~V6%(qA6lDVh7 z)thv1wzG}iHw67nr3C4F>tEJoOq@3Pz(UcVDKC?Z6o}J^zOmAi;r! zPexH>Zp4wmNZ;Y2fM37=yo@_aHBv*3ojba`VZvy1%ii^Nw-sOe(Fri$$B637Z)oq-m1E+ceCB4A+`Wa^@JPjBDM_g_Yn&5(xxkhC zzfOYr?$)H@>*?M_ZMpNo(3fYeHniczk`6!frRSU94ObwB6zWBaVKfn>q5+J|UngYkAlB7ScMJe-0L) zooDzKqZ;E1twA^6c)Vjn06L+nm(1jhnMe*pj2P!MG@ZHk4XoKb{XXJ8yII@mnIM=w zNlY23u4a?Swjc5oID%LP$uphv%gk!8NRioSjFW%<_WUJB&}ka}d_oQZ>n*H{x%L;s zm_Dp8;zDG$F%KXVUHZK~rUxnU_VL^8FJk(4}N1FGLH9=az|MHQ(=U>8Vk+n~y82Q>+xNgm-#w zcu|W7;ux$$kItMD)CI*H$xN1vI;nJe5vB_p+!Dj>(or>BBLb=8rq$G4cjVTAx&3Oe z1)NtTX@b1cHO~o*_?S~}qtN-MWZ&_W#Aptw8ZIg42bc+yx;o`spCj%M>J@oYsZ$m} z&g^WGu=Tm2^~~pf$$qBIN*T!xlc6oScR&+|=s^>M3x2*}wsb9luC*Ethrx%}n^Qhw7PH?}$t)Jg!isyYh7m7Cy?_W*vYeXFR$zzjmj`iNWw=U_kn+56)xn{#X zqU`<>H@~=#SKj@@Ylea}D@o2<9XjXu)qZ|Sz~F53IBog%&aXcG{BF^w*0rc)FMRXz zeaxonvka4G^jBYLau#KNHace_i$EURpl`vZ9*vwZ&i}NHT3=s4Y9veYtp}glR8%xm z9&!{GHEGk+fK!Mh0()$^oPMI#{jJl{YDVYe+E2IYXH2*Q8CF;}<#yE_gbV5@M5lY@ zD8bR+o%PQkDVv^=Vs@#lcGGRIj-P21*DAm9V#(dmu{VwqCB6zupM#$W-=bG1C*iQK zc3^Rx*~`+l#6co`m;4nCc{1d^)O@-sOtv0heXYk4l`OKFt7bE2k2?IzJ?S`Xf!zVE zw(?sofuk(+RwJ*LrOLZhh12Tr|Jf}k1JcoUY75DXByqk1v@!Oh#t9PNI%G`gG<+U+ zTkW6hYh=w`_Gl1{L(Eg{n+He}13<4c+y}i*>l`O7y}scqX~-if&L}P|{)4oY@gD@1 z?09zEk+*wiL9#DGVy-X@HL>4$Z(r&nqDvt{hC^piplr(njhh3l{h&^!J+Qa68bw<3 zB)}nim=LHX5Vla`)%%W?UQPo^f1pv&Ldx;YX^T59aVIH#XU`!%o&<;_}~ z2@|QATJ_ZYywKee-#IVWMDl^AefaoXUF^j)F=F$^X8S%Ldn1hda|5(V1H$^J>E(Q! zfC{W>PH=7n6Z_cX_h7yPLOj5wvM00Fv$|0y(UzQLL$^OVIW@nMe>?lxW#LUe%7TR9 zbEYL+h<3CUXz?A$R?hu(O4Dk}{B><>^4R`=v9`lrDp50@!^9zg{=I%-uS|9(|ql*4ZXtp`6d)` zo@77dMQeLVB+@#0QaA5pn#n(zud}e*GVl54XC>!ta4X*L`e)-M?J6x8=UOfrizdgn zgT_$u0a9D}hBZADp<{<0UbLG2fx$Ve&VrwE&aGHED1}h}e`Dt_yXtDXXi;?G9^4_g zySoGk?oMzI?(XjH9w4|waCetLaCdhNdS;$?@6+yYxc9ckht-%?vuf6;K6>vpW{H}e zJKCar2Y@@^5J0AU?x>%8YhJ%Njfze?#2G3%F^WD3p(E5Yyp-Bp5zXD_Tc=uOZ>HOk zNXZ2vp~fNJ!2vE+(J{T!$#ma7s_P$*&6=x@CMy&?;C>(wJj;vLp+R1Myx|NSFb@iC z+Wz3MEC7n%%pXRMCWLwU&2D7mBHh&zvm;;x`i%y0f~X?{$H@rnl0N-;=_-F{D&^q# z*N>#p|7HyU6{(B=6&w2hCnEpLEdReK4+{<9kFn&Ar?GK74ByPwzc_1oIwc1@oAQDEN@ zERB(1S2dA0@@TI74|fT-I3v;CV86q-@aB9eL7-Q;&f~w1V+p#Z|95q^+5j8PD7k^& z;E%;qs4uYLq&GgL|0TUBuIoh@A9hIZTq)gGdB!9~|4xT(_y4h@-$lCFv*lOl??rps zMe4Wl@4%Fiu7=+z8?CfD3-yN_jda2#Wz7qkd`jiNgTgIOHHRlFC7KvtgJxIg3Dv%!MYtRW zfBY#L`8#lUJKC)NIsCsvKl0k5FvqaLOlhHWGiAxiI)V zPSb(`{rQF8>BZy2cVIo`caoZae!(Q!d=vENXtr<~mLLaCASuw9H?CLIf2Q~dBZj&I zg_aTy7ZFvtzz}p8w7ic--32)c0?pHfQY|0R$A5Km!BA)<$4Zw6n}X-LsKeQ zJpH$V5*LVMsG`2^jN!7;f;}SFM^&SC^KZd z;r@f;i`~(-Jm|Ua6upVy)<>6&@OwNhK81PM%t?ZGqQOE`Dm6`i0X`~IGUA+^6uJ$i zV2BzJFS_`5R(*BKzhhYDbeT2JTwoU58)Ylii$(EV8!6Q@lc;eqhBPx9TtQ7^2l({h z;p4Y!Uw`dpGAPy7*wubbpxWBdU}&Zkn=lborpyNKR-o!y+g z+P!XzJGe+PbOa@{Q)gWWFAC?a6>u3U&8be7Mxnpk*P6w!m(k0Hs%fmWRpL%r(--6s z{&7uVJ?V|S|HJGk<>xqPz%mi~h8yfX>Jsko{8PFeH>IiDN*m71+X7Jo8Pts4kW*e7Akgsj?Ht3#CXUJ{sQ}vD3i;(E zyvaVBosH1W6!x!w7|GDbL+P&}x;E;;LCm-Sc#(D3ZKgLz^iqOS;vsXeo(*_bUNFCP z)Ejj@q;|V1WzAs_B=bjMTQh;}tCo*@rSpCKrw!|3WzFP59}h{oN~;(JSnikKR9%Rw zO?f}N^=sxE?Jw+XQ@DCXPa9>Rdy>#8P%q74T^JVswnf)P4&d9^aMc)jQ;L+f69+F& zKiLT)nL`F_@}aH^ppxt@G$q}=yOisKm9Y535MbynRnPNm#VS>&I%L)trN5hIeVf56 zXtBY!YihDOqt1V@MU`Lu=H`lq^_X*&KoHdImLhJWlkc4;=SXZ3y#1$aFYNJNOH z0o@K3N+q3?Y1~_!JksZLn=ggTH%VCQK@PpO7bl>+Uoa%qo%?t1jpe#fyCKW8yx~8? zlEOhKu<*zY;F+vdx<`M5vN>hLo=TJK%fUWtR&Z3v zZ}JKRk_X2h5r0?8FUNJHwP^6o+VHC!Gru(X-Ok1WMJgh=^$b1x(4CEo8LT+no1+BA z6)=Vw^pnWxxHr6z3-b*}HTPRR;~Q8ZMbspGP+;XBB| z;Me;H?U}Wy;M?5~bVBRI^pTj9j9K zkoTZU1bZ@CvC*!hx`~Gv{0MvBDKT$w~r^rvXO z%dabToB!}g@~ljC+8zO4;}m)BMir?QvfXv*0w_5p4VzpoIWX_$Duu^HKdC@ zUG#tB%aWJrm%d}1M3ZB67MbUIsO5Kd=nq;FHn6;tH_M+TxBnr;b6{sSx`MIZyDii5m zmd+i_W8P5nJe^QkhIb#D3>9wfcek766H|JdMfxJpAW@@{H0-~|$py+wnm<4MNdvM% zGqNOrXFGYF#_^cew)s1;qlgerS+{IwRT9FI1kYp`>*G>Irl(r&KXOS1BI>1`aV<5r3Y!2=m?TKpRH+(bNn|R~g3)AELrtdM zunYxVW005h@qtmMZm;~G21h>jGTA~D>IB7%qF{tK($OVILuJ?HoG4M%Hu+3kbQE<`7qNRvcl!LkTa@Fk!DonGYj&hYV^@pYLdaIek9`dGh@fZ=q zNsZA%%4otMd5$bJgq?yO(T#P4qIxqoz1S zsrk3wniMgb^kr<7FmMGcRe$_h?CBC!_-I0m;M2xAI?0}SQ_fGj^99#rd*3PrY)r{& zJo*hzk?(Rr4Q1gQZ6e*5uHuKDr5wFXVFU;c)E7nag}|_05qBxiDD&CON;guKIKF9`_ZDk_v$f z8J&te>p}$St@f+N-u6oVP7?aZqa0zmiQR?zBDV76zLo*{cAxJ~PT{~Wdpj>(yda`j zOMMe77}_|b@)%T& zujEsow*@CJ95jC_Eh$QJVa$%w^dYG1KN-~E&Ae{nG)RSDH&^KI+e7!o5a4;ciM{;g z_HoGElN+|OV(~Gn@a$NabMOr5tLF!56*>GRzD72WT2t~v)<3LTUy*oGQwY=smD-vS zT`qR<$Py8dG2)yYTNElit=g4eH+0s?bb9|lv2DDb5_3I5;5>pM0)ad|IAfa5aBNrz zmfFRo-U*7RF{1k+BS;3mC4+-}JUGl9D`=pBcgF9aM7^;Jxj&n|#6&Jk=ERgct5!RC z@#@TUy&3|5MBpWcijs8J7-f@v;qwgd;8Mt!o^yIsu9s4pE%0_)SM>wRh-<}~mO#I3CU6^c#1Pio(m zb96MP4?ecs-Qr4s$3Vk)xmI{iTMqV99jMloQ_3S`sgCT}ct6tp?YN{EZ8&R_LE=gp z0XbfSHscUl6ji6Asr*Dr@0XZZf^XMm#dnQiNr?J|p-4W|G^eX|3osV6k2zWVyDw)1 zoBk-=&jK$Lt0oOqgMHL$I(&3a=Yv&2P-(FE`qRCBV>IN%%ym_oqvDTee{Q-AA?f-1WWz?n*K zO>C${N~5-CnSx(cJA>AnL}+&3M4I6m64Hs|VO2RrZ4k_79HK_$%OBxSmUJsHj7P)O z>p?!GQX;T$C_P{De{qVaHJ+3EcqiR7A3Gj4rqY!}uD>=Yul5Pu6oC4@;2e5q z=+e2_OTP#9@n#;9$Jf%G1-OhMr>zu#S4F?4a@J?1(V2$6ql1MbgkFJ+G&I%N*m?49 z^AU5GDyuvCC_Oo82Z2J3dRp3Bcfa70f4Ff+AdrB8vzN!~%P4SOebh^Zw5yjzF($uA zc-$=`tJPpejXO?cmDhJ>(g zxcIh`TRtWuq~s^cXi&{lvr2aRzy!M=QGKPwHviG&O^4*hz2@#-q6F+;lz$&?SxGbZ z`ezhu*=j=4iBq}?B zGH9{-RW$?oQYGFeVl zbAkk(qHfj)IgJBEavb^Eol=6b@G9&e0rZr+sW4-6J5ptsXKn?Ak=VZqt#_>uT6r|xr-8#NVl89gZaJM?L62^DM9?tzRfwaMDz(gO9QSjw9TP5d{S;H zGi!M2a}y^7!nlw!}!S%n8caE-K7xu6|zE6PFQhDiTC0- zv1TdcABwU!HQZezF-TASzMFy-mqg6XZ9ORMsA&JOq4Ghgq!$wRW4j9mZMEg^^j*KM zxAn5Nnt(D^haVPgPJsGtttn}4r43%I@|POqAtK79UD`u(!I;=U3T%eqZk#rxYwogd z;IPfjvSh!ceIG|27n^o)k9wg!o&nPG7Hc>DnZBd@$i;}0n?dh@PEH<{xGFBqg&bzy zd=t0L6;?(SFt$zm0A2IV;|HXIY;ty|h%}DJ7X9^2K;N4cPt<;_Dp26X^3kl#<1qw( z9?>HGZpFM~|G@5TcR8E#zGB+(?q@ZMY^O8BC=IjL?m({1v*ATZc+W;*r-)h@_HSyp!V{@8ux8?uTXD>%jOH-)9MpUMcFn=gF)UqmsE7>PLn17r!FQ$_m{UGTW1{7a~0)=c@mq-orCTc(`4 z%ZFN9P%`M-W)3)~q~OT(^-Qud$2=b6922Dl9tNRq%n!%4YZ^LPMO|MQULvKpuP0Bq!tSY*Yatcn zZm3&~KoaHm`U6`y;Gn;aXE#KIk2Pxi%gSGIUmZo-UnPctPpEo%y6|e_>s`T-@{a+J z>M?t9D3b0VAiMTGOhdmb%@+a#-NHn=McL23xora>~Z-^Q>Cw<-cvQKSf0H_kMJ@lj<;hC>%FSy)JVtD|tA?1*R_Av6ksfoY}5 zW;z-th+7a2g^6!K3$BaE#`N(GWYyFaW_q2vZZvF*2Js82J=Dq?DhaUJ+Ts$(bqPr` zy=^$mn4G|l82|_>l8CVS@wW@?plTmq1^Yn>6-dOK6;T!ChA)qB@9sodWR#5(yQqV? zQ3kt?pv-9KUIVvNvVK@g>??TlEh&pG((zP7(4tDWVR~!+DxG^fRIECimDVqC3U{lf z5+!&Ld1y~EhCIX?CBl1n8u7)>dtZkjr7tBZ_{eQX!$pZs32J|VXts1_nc-engKT!E zlPAJ%(%pHbwGm@I_!DMGUoX7tGf=OotuEd-wMw8(DW|J+KX-nNr9YA>pl27o==Rz3 z84B~NiMfie7t2<$a(@fjzhCWag+jW>jpqGTEKN)lmc;4RlZ8>l{Kpuj+1eF6$j$tO zi=`dYj4TZi#g}{Kt52h)p4n&HPH^nv5_m}AMMLi8nXdxjq7r%=UCgK#xyR&D6G&L2#vgH+%SGG0!izyR&F2%FnV{r1wqa)ED zeoY5>{mNA1U@_izhc;N7`UIMCWpB0LW&Yj5WTn>STAd+0t`T{<{7U4W0hx`^oPb>{ zeVCrXu}{hC*0eyUN%=-fLh4_NL3>8u9qYjMv$5-Jy<&cvDcJ-6530xr-M^TqzksE< z+aYEIt64GPs;6H!4xVDLaUQHKvKm4RSB*=HH+T6RvF!)`-HPn8VfvFK2QC#z*gM?5 z{)^wzDFI^7oyjgN{3K`}s;ivxo z9esP}eWwT_cp}*KHXKM^S@XJ*imnTDSf4K;Rwn!3+VK!XO7Z*tL8iXR1r9phUkh@N zM(t%55ginITBen~y*gC-vmTBG(-$&Q`35AZKuJovuZsq@1Fu5-G_m>U_!EC&hbG}l zR>$~G5AN!gE(wxGES&R6h{62T{$@XR{vfg|Y2d2|nNvlaD*VdIqiGN|MUP^c*n7$n zPuq;0sv;YJ8J5J7M_i;q0vR}WT+KR1WaaSu5og4wo;oGt@0NQ>ZQebaTwn2c8+bC9 zs}g}F!EWo#<`ywerteo|2c>`8+NPt)C!eiN>8q}#YAQ8f*|EE5-d8JfV*~dH$ZaUk z1oePi(@yZI(9$!F>ijmTzz-gpry#S#2ZN z?|O5%%{nl&k7m;PI>hbOBhb59+NV{USG4NhaY4bUZuq1ns04uU5frsfjRx2k$ z9&h286|4{r4geAyHVmfmLQL2F>xfyEpU}I7$~o|d)SB}Ouo+x|ycFnXc{vJ0GxfmysZ@>02&2k#c@~Q1&?Gn;VGPu& zP|USuf5)^er&lpC(AvD9-Iu7bOjYjX9>)p`7N%hc5XM3SekvW4e3F3d>%O)6d3o>7 zdIlvg1mqU*=1q2lZ8SOJA#dJmg|h`ff06vxD2kZuM%*{jHy{2MxjfjLm%7>8Zbx;0 zMQH8F<5VMB1ZG}6ZayWPEMeB&kPEaRjPKUQ_6JR#}MBw z&ZX@y2DlmKywhiXMIaQ_wgi^uHqZ5QYwd*1zXTdrfbui@&jya}JWP)m|&O z-)@rk)3??91d57tHEF!{l;J^qmG)*{oEJLV0IR zVe4zT;hsFi%ypw1h*}*F=bmzE;3JvLoZ!Q6b(2AM(CBsOCkc+X`!`bEr^Q0K*S%LO z^d9pmO{Z)FuyG9K2{hPi9Z=@+mrPkf_7X{qo{>diKP$&1W|wLo3#7s z&P`oREvLfmt*i+GApXsc3*w1naS{v@?r`GHENmWS!*TLPzQwvVB%MGnTWIYNT00{_ z1lEO7=Q$*vD8a*&aGmkTjXAKA*1^s8Ib5AewH5o@G8U|jEr`?I9#<>xuk*}aEin=* zj8+&nSI;n2S+J3Z0y)4CWqelx08t&(Lv8^Rp0pl~=m+^VbmHW~Q7ve=hC!QIbxG%^ zP%psiY<}?0>m&k*; zejXM)e{my$XXe=#>hCdiU2=%LpfB>0v5@C*s+;L3h*)pYdAsxGDb&DrA!dh0u2gAJ z8jEJXzW6PIEg`2%CcNdnF*K!+irEu&>&x}6ZPU~a9}K`0EW&@Vz4;a8wb?bS9$Mhg zI;1#zVu((7wkD@`xssil@^~TYv7KRU-L(we?yHJ!6CDVv zn%=)I0u^@yf5u*33`2|lFw|^J#Gv<(vC|5 z?@X*pHsj4#h-{nmOCIGu$G9`rs z)kbOFHF-V&{(3#-KlLbXVTm~HP$S!c+y$Gi{(%Sedv={-xK<^V^DrUdNJq5=-zvg43u$gVrU)iRt4d5Xdg|WsrtJ$2U4V3F5N>k;MTiK~h9&R+2}6Dv+4S^+ zeQ>Jp+*8t@ejikqyFMP+x(qt_aP7=z)Q99=Jeh23R&}ipQJ415-)xYM%*Ho!jazsd z870=%DSq4o?Dy2ERnc6Aww%yP%?C8P=%{MHzPt0g{fmw9NS;nYWT zW!QgM7p2;CYU#2~BkMs@9X3KGS?k(FrJx=Sp3D&8qT1YjyoYA;5Z8s&yKAXztm>)7 z&w1ZH6(*iV%qlTGQvKo}Nt}oJ=+H?%SlM)8*;KjcD$U1{3L|o#cuS&4F)tLW9m+zf zjKDi>V<^^|a_=fn#*ee-4X(`(@6ltj3e^whcA)9^`7$%-oC&OC1YwwmW43f>l5w}9E{TB zaA0y0N0Q@WrKBwPYAOs>T_TZv0Wp(xO33Yy{4oafpLjpG#H~QzY=qmG_424hG99Xu zbcghgr06Y794&2wqIRw22@mFl^>V}jH#U`wh+g#z!FPRyOg?|at?NlfH};pJCxdhY zoH})yj`ra@uBD%jeY*x3(NbI9qGg6AiTNYEppFhvK2w*xJAmTFPoqi6Q6yT&-*ra^ zAM&6=_Q{>}*cmW+6gsNwHHkI631)ToZm>LYS7WcML3Uz{xurkHxt>`Q%+}mFr*|4= zE{U{ZSZL-~3@oE*xj-QC3;r*eE$_|V+RyL{KL1ZPJ&s z62?i+xON+|>F{Sdg)`XFu7sc3WOt0(N|dzBktC3H-eIR?*}34rAaVHGi$T z62E&)Ce}mGH`CuFCHnDc$KUx@_b?1A4QGSE`0Kyid&6y>wzKb|#zVGbU_&+X@+qY! z4E^0)FS>h3DL<@>9NL=CS<(N%pGaFV>{Z^^M(*=(!)mGszM##|`DWz^=xY3_PM?Gt z)HpcKJz63K+5*@NSOny*nAy{oFg(=ctcPhb z)uiRBlFo=myIBOgwDybfIX#`y9`Ko3H}7%(jk8b)FwXBs5fO=XJ-DD(m-gr3dt32L zC#xkjAsVbyTd(6T+0iA1GN)SnG`gs`mQ9Wy%KxZDSF93r*FoaAS>K-_PPX4a)=n+F znTaD24<=U$N(~kn9Wc0={6|2kgoW7NB`vvvmS=5$8KORCQICd-YF-*>yzM>FEKVM) zu1^3o?O&M7({_vWBVLb{xg_!n_lHpV2h4$VXfZSLvo9D~+ zb$}0{;;Psca?@#7ZFMbUy=EIW&Qg^q8B9Ws+s_{Qgmm$(3Yav7AvtuhbEm1aE};tK za91-p=w%M??DFtj1oqHZOO*GQeC*h2S$LQaduI2Y0@-#R_Usu#Gd^zJN`}bQDwMt# znzgd6o)N4UD#KB$a;j2oAM~Rw8RbfbiwtV6xQUS2v8?X%qvxh(nLWC#ktjDXJG*g0 z7pI)W!FQzKu*S7-7>6*g_Lwj4r3;lJs>Bh9bX+Q?wND)qczd!C^`KSrs+v_U1Z zWgBFnvJ5%oaQ%ehNMR@UEi0W^`P9GD^qJENaRF;4FHT9x|45i*BEJ0I1cH8Y?(?^j zcgMiFc}e(?v=W(m7~{rP4*Ck!j|&fuGfkvZLXrVURPY~)+)981__zI|5FE~}wB^qy z{lo9eDTqMoLJF25(n?rAw$vQf2=wG8!NS?aPP}2~$dZ^w*xNb14>vY-!m2x6p-zQG zz%-&4j#1!9qv%?PY7H?!XWjpN$0^59Kb-T~rziFQ8GLM&n9A8_zI;NoVC99VF90$b zh)**cnOg8^gm3(E30uE|b2zg2s|Q)a!j>Znkvt;*x!DZVE_2lG^=p{3Y%mnllQf{& ze0+j;ARYuha`9*f+8pvdK%Sm zB+8QJ!j0b4y;&iBMw@t~SDESlGl39Zs}kI+zdozIgy8gK2CUJvRs=s+^933rhYX zhmgE_EY<(5h7)ot$Z3DH<848lPv*!)CMOgj5d=nRp=;?lNPOK&^GasFDqWPsilQT+ z>Frrx(Jy${kEQz)4Oh5H|MDOmAHX`Tn@8PU0l!T~y&stdLB8GcT0>E|-=L&txB>^D z(X&9VnDCZb3AYml4!u|RgJ2OPpE+Lgyynx~S~90#6Qn+<(Xb&o;W9BwtwYx=53J8o zz}y`Zonvm7D%&#Tp8E{5hf(0HTZRtWh$BqlL$rO>TPosK24F-zgHdRMgnuZ76!5CA zZCO^#|5Dvv=c#wd?XALYD*NEwy7ONZlSCweBLUK4Q&;ts5rwG56M)ce6kV721L$@9 z{TXneFKDl>KK_#p@f}hj<9^OKY-G(5pGc3l$!S4nw8s?L{rQ;b4ni8w2*o4F$5rrx^wJxaKNB2*ATM%dXjV z#4iH%Y}3kz>Vsx*Of>2(a?ndhz&rRP+Pq?(D@d+Y@u!(kK&H0S0Kq)lvJqGD%G+QpELqvXK&yndGq*uOQU!Z*uMH?SL@b(&#&Aj~7&ViQT_;zqnE`2D>-yS%$HLa23m z(K`4=yNu#nZ3lMId0tGSb?%G`f<{WPm!7}TN+N@HlY(oQnjFvv4^)*J;EH`j(6%O* zZy5Ro)^R2|ShSuljI=G&TNhg_TAnrtcxY!Th)F2JJGeAl35!7fQS;xMrd|yZ6Gp?F z_PtnnRs&=cAX}(Zy#1=Jt4zp2DE^1Vl8+{iu0HM?p(T`3k0zcg;Ml`DoVPTIqNCW@ zD>`=Gj;GbXXUTT$E3ruY!v3KW2HJRUhkTn}MR@^1Y)_~Jw}TP4m{brkZ)wBIfo!d; zUIs}wuZsMYJG-vAcxKCMr2p+?+Slo5Z2mIUNu6SNdBgxarUa%FyNmT8@)jnQSNGgC zx^ToeiXl$+irVGB+->@(u>7p@&+fU_`Aj&t!nx_xKI{syt{TswR+i;gxBEA*UN+IEne!wXUIMkAEYfa&*0Y_NrP|Y%mQ-!^F8qERRiJha}dOUQ*hVRTiS@1Ngmu`4O79J%56QQ!${lj8(dc{-`ug+aR|dDk35T5>SUr(qhjMX`gCRJQE_DJ zu&K&^BBMa6Tr>3yRj=#a`v{F4zbpSBAWvBC47q)d_yix~^0~+*74n}ZWm@d* z6N*FXb$3t?>P53=Cm()!(>%6L<3Z+?mPKjxj_0QM`dyu*JGON?3WgXZJ(rSSK+5yU znr0&?=k&8Q0+j|bYCptC9iE1UTo!8GUc&W_F*-#9pNELa&dkWv!^;J14_lIHb4X$| zIau*eShl%AteE{p7VOcn74ne2bF#s1xwKW=I9L*)u&iUiIR)s{W4kNW$|F?;YLk^( z5LvL>oRUb`p<+o=G<|c8(iPgq79iR?+5ac*HC(dl&$dx85 z%kqF)9LfzkAW;OP0AzXa>!(=8|Mw>#os<0c@Bfsw|9+2L0;$!1X9Dum|HoDTKYwcM zpJlsv?SALDaL8w|_$gog|MjQh<5z-D5{I2_;)X{O3~ex?HYSTmO;cVf|L3qLlrWG>A&|FeM`jgL=SQ%$x-@_hs`5Lp;;{Yfq|0FvE?{-;FwcReIJ8xz-*B{fP^ zz{w^C0&KHg2_`zExM|do<2m)UbJevBgVqvo0y=|{r&=xufRzo4ctTvnR1$#-w=)>E zj+sX5S47VBdzTQnpdILjVeB6d>=1cgWAN4GR|j0Cs`#=WW55$i;_s;Fa7;>yq|zRF z9x$AqeCeh#MLx~mn^R2>^d-z&dryk0_Xw~gDL2qJBtYKJ+V{4;TJoI2>yc%ct9g%;V}o{}3$gY*MjO zmCb{|zC-_P^bqSqxPaugjJ0Pkqrclhaod1FV$ z8n@Hlx7(byx#4B8tX;a4iwO-=QZJKHPO1)v4j>)*)Oli6wT=s$@jlCJWRVR+YVpYU z_(FPb_)qQ57`TAFZI?C`gCX#m>upI^1@>U4Ck2Z&;@E_^K+xppe3oh~5-URSSO zeROPZrnQsk|1<4%Tb`Cl&2os!S~Ky`5_TKU-WyM-4o7o`=LP>w4&gAm#{QlDlepG9_bNM52w-Fb0c&12&ca#~Tw_8P z>I_{t(+_HDq^LijYU+eg3y za4q^Ug9fBV0~xDQMT3yO-u3%@Q>Q7>E>wK#_cR^#)-D~6@ZT7leMocS6(|6uAz>UM zqlgbT^Zmu?d3OZdhBj(~92aKGzL7wt_R@{|8S3zVF9>7#+dxfF*IR7WHSxAH8xE<~ z+KT1v5zIFkFwwTSmU1(w&DfyQmz)2y5*;YE8*<5*qI+2%7bLE!v(QN-{)Ev34`^*q!AJ6f>zXH(}gjLnBd_R|ZFu^4S zBJS}*#cfqG?_YUrd?@&`8`*<)5MY41)*&dfq$x?HSCji$wb_$TrrpGUYt#%gj|eP} z>xbwWZGKeTEatF9P!T&w;0M^o55)I+U5+Mgv@Ia>NeTL^Zv^;%OtPKN6(8E?BONC9 zn5cdsg#?CqeH}YH%Mo~GK7K|7+(z%z^WmD?DH(ksZ^uN76)vIudb6+}BePhs!;CN@ zBLru*q>q3`2pDe$(^gU^nmbvvhp3Byux)gShXoHVEY5UuKUm+ucynBhOWGx%o$Brf zD0`FrjJteVXE}@oyDJ$#q z$;j?f4GOBFvEP&^bE~Cj&A#|!j6U$5dme$e5XJAvY5wQolwf72I`80?Z0i=SV23rWO)Ck#B!-_z-Aj$#OQ^{VZ5un5ioOA6FYpjk)WZqa8J%Prf6j-ad3G$YI*z zAOH52yo9}Z#hB9Ptf*y2cAF;)p17Xl;}9vOQ-a?7eBd1CE2JKcz}Z~+x`3)|iE~I} z1;2)T#5h^#Dykqr7CJ%n-Dq-FO_Y27^C^LK%J}Qo|9$D$C{XFi^c~!C8;&_P+uTHz z;5Qx+YrN{?(c5A_AdzqT?98FXlcHW67&9(oTjJ1Nvv-nHFreHm6C|zXr6X&-u0d$opRPZHi#S;A9lqzVoSE zDr8gMVJLB0ifcXG=>>MEh)G+46?>iif75{NfB1VpZ52!3vfZ@hc*7O>yT2BGBzH;g z*EhKj<;Pg!pu&5irh*95TV;;y*meOkqr_uq6G~X6fM;lS+RB#CqL{()aPQoYF(@ZS zVIG}Ha0gygReC93h-JN*TtioQHR>9L& zZZ;JJfyff44f(^5d|9bLsDdt26W&gjR0P%`13{HGb14(Ntt$O_Tq{iYyNGt_90oF(|$so%d=;;ac-aabeE|VV;Q*R#}iR&?2NtwZwddNiggT20WC( z-FXT-ANOP&MuHLWRw)Z=PWp$67ds|hL({%a(%lIWNK&gIVaW1W*V9z zu&qD3-KW1NWX+Ar3|n%a3PAH6&v}tD;*=u^d^Z0Ir|nQNZaSoG-5<_fUnusmmCMRY z9=a)W`xo`f1A zLE%kz4W9`|JZd)#w^M*n!KeU{0{By(&~1%4f*Unop%P`FVVmPn3fJ#zseCW4 zm~VFh8(>M(kry3+;!dIQA1{S?e!Q7xyQZP`5STcLmI`bg?Sn%nWiJPCvVb^a0=AyNmD}zc!r(|C=E+03OvZfoC^$>u5Vm zHbmHe5xQ?Mj zqnHKVCa_TqkWrjykK3J0E>~-e&jcjF-5caX@#R8bT0F;oTTa38vkw{hIcYM13Hw1i zZWg5c59*TiS)0h)>3>4|+X1$*#n_H#*?{ zT1HoM*u!4<*PsHgf7;ZOd(|BB{(tKVaUR_kh57}y=`~vTrycqaI(uKZUpt}o9Fr4L zu)ER>b~gjJVynOgL|cdyO3VxW3TtZiG&=G8t1)>SKc1IWXFKB*VBdykRNH{%&Hd}Q zCWDNd5{Fr&4HsEHF++iFvs!JWPY-A6F4`P);^h{1970bUa_FmeYnfhVomJxHSM$6gFUPhSw&t3s*P-cQQ@m%G zUiXIaA>b>pd>t^R-N5IVDqf_x{L|0gAUVr$c?Vi_I8#`sc93)6HdoWgJ&Nn4hc~>x5y@ z&DG3=MZdIkg)j9F=L3&cuv~Xp2OX1Vr3YAJ@$#Ju4xx^2g@?jV+nJ|?!ib-sv3vY8}2 zfBG$3lQ@LB&$^UXxu>4+o)~sueKk~aA6I(|%)6xFT?ym^`sku$!LLabU-pG;6kStW z+617&0bVZ9q}0MpZSn`+yKCV*F$@Tg;H-FGy6JYFT`%gvjHV9Ux&3Z` zNRYOiwtUm6+RaQA0jGHLaaTcQXviAJe#EpR|89GE(LoL(*+Ym%sP!&K;G103 zdju`u1}&3eYQS~7S?Bo%obVyloNMyI`=fhW96BDm#Nndhc)MCqvNdPDbxdhkyK0py zkbVSZ`jYA>_55I=cDkXl#*uyU3h6ajrlfcl;pLc*fJq@O8se(va)+RQ`4~uL?iAA6 zyu*xZh#lt*9OQ`%4OH8+IYaKP_Z`klbjBtZq;c1}#c3LwUzot{_4Ky^bJ||AYng8( z{?d?08+)AN?l~5c;7W}E-|`%k!N-Vlt5PI&PZ7kxUx?s_6=aR(@3lMJK7MhQYn_%F z+mGGULOPaCIq65S39~*{_cZQ_qTAkjlNKM_Gg}h<0n&&8Qlr&^3~oGL;cfwu^oa|< z;7cmpYNzxl?9O5DenJylogjAWfVL(vf@83gxmqULF)hge;3Bl&#OFtV$KR~x)4w|( z5k|YL5n4yCT(YuPQJSx3+WULF&xyMq<+%?_lc;dj$y0=Z(C;PnTN5V`NDov#q z8|dThy?xx-aLuV;(?@ZY*o>ZmAh zVSABdPx8BYsyV|7_UprFtgpb%_{t}Zohk9)8tb5jmt&wzsRJB#7S?7}VNut@F9LsN z|IOaa5~T$!T|F6C&Q#^dxm1gQMyenmpOH%DQQfw2rI)6&U&!^R%Q;Ou+S`!2(0bTSK&nSF3Z%KV|5MXYeX06d)8MuVp}jE;D<6$-RFWom<8TPS zufWJk`u6v_#rbw13#UBSO3zcExjQS>2yH2igCB(&A`)kDuUeoFd4Ep$a!WJ)Zxw)S zFMkMrpm76TxgZ6FwKG=uxP=}Y><(C$Rrz>Trk0HD7N^YfYTcL6i+!9kZ@7!XUd^X* z=X@MI&M#sto^pd8lFaI318McPB6dfisxIrl0knmqN@?Z-&1yc@^#}I@Kn2BMCbqF> z>y~1}3w?VAA|St@8fB;`4t3 zQFV~N>Bqw2K5felaC%!IKbg~E&C8832Y~p8d_(NZRNwhH122Tzh9{c#%kGix5!}o@ zJ&l&RWC=IDAM8V9S9v5|bqs&aJboi{qpGAz6%!nrJx6J8W)|Mcy|5u>B=hvnFivPQ&) zKR-rSk|(i6t%M^xQk!cD5^36ToDU3uauc_k!lb9d_a*OOr2h8Wq#kzA1fXwhxZt%9 zPDBu-h(qaTQW8|}H8_X{HRS(<2pW1~`Y*YqE$M`C#^pO|7r)0XJ;0Q;#70%Cstnb0 zY1Vc5%=(L83WfY8-IOc<5YPj%H5+R`S=!Y3#W$XInJ1iLRva{c8M?&H@rX_au;s2+ zfN65_sb$*GtyWPL@nyM>JD3EY+%tnimE!N7yJZK?ru?h!?JQF0q9m;cUK!H+3kgyUx1T?I~~<|43~A!b2o;c z#t{SBZM$ssR--yW4Fq7ED7Wg3p}k(iw5|r)wLXL-hR+C;h8)i36I<9F3lys}{v$+v zp#y34j86KRxieM9(+zUez0By$pMkU4@1Iop z|BGe6dd89>2ykh%IemJO(3t7wcsFqxWf6{QIds0)A?+ILamhlK1sT=YS+)&5)=rqz-E$H2~Em#O+A z8XA#`yfvuCu219JFN~a-=afPL@rq8v73WqK$OY0t)=J;fct%EOr+I&d{|#+MK5s&% zM=0uv<%_D@Wb~90AVU*Ll50gEuUuES>wUz|FU|})fZ!|e(|@mnc}To z1A$M_5z6Qy`ja>H*YS=`bJdg0+aXMxxKyTk(@a|@HOX^x8{<0w+X;vEw;1Z0?_0|{ z>%Mq6PJF zplE@5a3e+*2^Vx(5>!RESHqe$&35yH^8A-pX={A=%FJ>De^;>$Tg|1; z*K*DzSoaVpAj5Qvr)H8%a!3WB8+@OvScAU1T;U1#aAvCdpz3M|A?(UDjLhbxf|h}e zk}Hs{rmSpgDSbYN!m1Q1KR1VRC!Y^mBax5mz|4KbjsX7TB#8i(^U+2pLaoTIHd z0#L15Hc((1q+6+{>EEG38Tt5;L0~b4JMfT*=+-DCcUTb?4pir%NIn^Va?4L#`sD_q z7TJRZCl)hjCXM5igOC@#6JNSzy}AFFeEb;yD-Yp^JS5-IWk$9qAkuEn-f=371Zovi zwpb?7;nUU>ex?~UyG0h${mxOoee%2tma#qaWjzT+KfqaBaY?zn+5>?^e25B75+9CLh0XhjD|d_&~6%%guV{Rke0;zdVChl`iS&5+Id-w#uliT zgWDa<-MsSCo$1b43KP@@K<~vBX~LG64blsbZ@gi8hJKpmy47L}dIt)JO?>Nnu|^Tn zK)L#Sx&?NV8NcCN8Us;&Rp?5KZqX-`bA9-HF}K6vo$21PJj!e(&O6<)Nn*up07k@wF+5FhHecCdz6pz> z!^=5ecw+VxXITnpYaqg92W>HoZY#Y@1ZBVu%jeZo z)RfH7K#?<6Y{0V;1w$HF^YLpbVe`z!4wwnNW>Z~=;v33C8|XD#2!}G`W%9a*n|sdP z!S6CK+g{tHf6o20ANxBxgm1b?GE0XI1TGE%QL|APS)L=;9|M@uT|; zw;oh1UpecanNuWF8zQ(5Altu7b1OlX)kyLbT0W_D>lj+UJV2knkIVcuF0ayg<0_c-agh{`W zJ}b?H{Fymkc}K=?F^o)5o5dA8aIEq}?xPLY$RLqz){SRiT}8jo=;$^vS}yj@N_)rY zGLfF2lC;~mh`&IXc`~2cI}{HP+>7k&&`QBSe^9)yUf`g$Ig817VaO;nu7{`|1^u9B z)pvKUqj&AxIrddb(+A3SdWl*bAj7B&L4<7xAASrk@$JaYkwE!bgAP13DluLD+_i>_ ztY2BT^3Tf=Lj(24wk$y^amQq$280p5UA-bZlPHScrEKzZ*PBmPak%e1A75mELgxC% z()ZOC$Wb2wapD^u^9v5BpJ~I~i)$pzJ_FuvKUJPBJ&QwKAGY9c)!zP482-HJvf($# z{v-payO9nqsT9`WH;keYLCD(-(3-~c><8ISyqk=I1ZKW49|3;9r_n%{`{xBg!)=IJ zY2ZE$7xueP+M$?SxS#`8`b$cDoj{AGMuXyrd9zWWP*EA{qA`LH~0!~;R~AOOZXbDjWQ zS{k80QaC@aKjcnp%U}BujYs&iSpK14?(Pi#5HPBk);!6*FH&O&6(sWKxmG$nd2}Xx zX-1bSe_QYU`<^?LGApBBu5R>0xuaH-tYg~P{W>=4rYuE(V1nCc8PFTlL{+DCK@?Ce zPECqvUef`!XY@WInxcOL>+UY7?ukKT4zY+ zpo+0i^mFl%h`M3A0FJ&D*)1rFon4J>hZQIs&~Qs>xN2#Zq+^ZG05sVHE#KafuMtD} zS%A*7L%zP4pN?+kQlAQb^~+3N7$L$GK?RDwZnD1;I+4GjU5CtgT9;gFl+Vt3PA?Wi zX0;*O5DkdBczki8qPWo350w)-^s*lTKT>s5k4A?t9-n`|S@3YJ)~Ld|Z83PtEnQeS z9UVOp$n;=z%_vpbPQD7FT1V?hF|s>`H5Ajhvd*SDX|a?3ZhD~N&-h%!v3JPwP~6k* zCQX~MLeTmRgbqD`oAYa&!Jo4Jv=qHv{}-GSzdrgC*#EBVNTyi4RheRQI&@FLI-)Bv z%7#v5d?+=-fN9PrvJAnYJE|tARgJ7rK0zrxfo6rmU@%qs?l?T+cXb%e-rea)!OM+` z(m~E4?%oT+moKT8YDXdC?k%i+<&r?%VMEqK;z2kXjN_+^;_hhNJt}qI)as!Y-)#L8 zt3Pbx+{cCJhtjt(vunYU==>GB2F42yEuzR?ha%?vsXw6QOjtjdTK55A2SxVa^H>pIME zqMy^wXiW#Lik=&8(j{ocztIG9A12}#nP9v9creDtWXJNPTj&a-uHi~n%{Z-jh|v*6 z{m{iF$0KjtrR2Nd?UQb!hQriz^?F^2PD*5>Tk7TVjahifgp6Ne8{JNGC9}h)pgg+C z+3Jq{)%<&sxtcU?n2BcIkrKfRLK^`lZxx!C`P26mH?9CvzuRckw%Z$cAK!RF!Za>Q z%=tc~U=|;V!GlyjckY+9kBI?1-h{?+>}Rp9$({~;=}1#O z6JA6tC9^kAmN~9tm;*6kYs;W1@ts3aIJcEKueS#yL5dLS{+;;gy z$t)EVDf5&Kewv=G%PH~uC-T~hrpis$?@^87`uXn@i@pSvF}33t*)nd=UUXnzo~G|? zi0;Vw*Cw|nM7W>2_PHq82@aVb{u%OLC4bLJye)V)d2zQrI;(lM z9|`H@t!f=(-B@U^OMO`+u9RZ$VoA^my5*bMAUcY1Cc0s~YNN1m^7O8){0nN|qzBv7 zZ78NZ6}%JQY2o)Sitcc4$2*2M+5TNf@~sdT#BnzM-d3)%&r|Do%DXMQ`=Z+LpoTbX z&U=*T-9}t1a82wQ5?NDmJ5QmCkT54@(35Y=^^iS<56jDfF(dD=-?Tycg3f^4nJ-%s zqdEx&$xd=x8P)Y+{|SCnH7e-)=EdAY8vQnv=nSU`)_DqYO7&1$^^od2>G1sb3GDc) z$2c+g4w=b9FK%`BX*Q}&q>JwH_Q+ss7&2M}cc@A!?!h{zQ+#B3zcrIbpE!&XjE6O$ zD)R!aCW?C-Zu!&fWkF>hSO3RtZ;u~-9zUqKH0@}ILdXjwB6-v}CfckrQ^B8dB>Su; zwW9Sg36Ij~O^-27yVOoF(HQ4KsaHE(E`rZ&==_dq>Z<>66-bxMI_o|Jn)tF}B(RN7 z9Yz$)Dam6VPJE-}4n-=S+aG6E(mi!nS6z!bvfs6=xqn+ zt+P#1@?G0dPk>tXS!V$EQkC(vM0$>3-aUTJH@?p@K6Q|%mql20mNe|}=@`skQqNN2 z2B@_TBuNiozRGP;RIWuj^HCFYsHrj$Ygslc=L1sbwmo%%hX|B6z_1T~q;JW-g74h$XF;7@1OSMuLUe)i&SY26p#k=O|)AOxgH1}<(?vRmXu0_W=VGD2hwIog-n_KG)1(qM?ehZn|Tg6z+ob%wk zLOc-5#Tf6UpF>t$oBy~!&wVnz^%b8iVz1IM#f65p zhybo=Hp{8A$T$)DL;h_X@z~C=>+*U2iFs&9ClAK@hPw}Mm7l@Z=g2FM;l`|1feZ_C z@e=5FIw)}7-Yx2?RI?B72^K5}*Os!kVZ}XG{-zYJGjy9_V2EQ4nlnYP) z%4$_JvIiB&7I0nfz(jrF^!Ia*Fmv)8yZJJ7@Dbxy+dF+@ehHVmsh&*~7W8}2z&RL$ zpSNdXgXcq=>~UF(OIvQ->93zJ1-^#G#wj*wcBEBU`zy&&hp@%77%U$Ph`uo-&(K6Y zd20%l^Z!Wbwj<7I<5)51VnerdJgUWu`mKV9A$ME`kgG?ZauTLvBiuPojrxWwL_3F9 z2jQxlz-a~ z7^n1zmrf&ySNjy|Tvt`I)fOlHdTt5TB0|OMO|7E-! ztL&gaeo#q&(ZsiHY*(>x(?~UCLZ#6>z;y#t-b!|_hdF0yY?ARHzpZLP*F7t+z)UQz zspuwB5iT$NQJ**yas)X)Y0>u%dGS=ug5l%siAgnTshdGIr#i<{HeOJPt63UTUt6^E z1(Rl}!LbFJU8?%Jy6#y&=XF;!Rue^+bF|Ix+W$x)6@LHp?&n1_or;su&MB+lyscgR za7EIfluXo|e&8{fQAm%^ZEK!-G%44@_^nvMPHXLk?ipiwv8KbtOj%S$EGn3WWpPOar^ zsgQ8P+5Bt#^8${quPSHg-Q8oeQCmTn1}6qCc5Y>j=0S4jsI*4eUO`aBOxdU7ClfXPfnSk)XZPZY@=-Ce@Csf6ySy^O z{UE(l!h{A`L71nQp@Xe^ipkmX0x=2c`7@d*D}~eN1Ih+}Tq@$D zEDha-rw)(g=S-ldW6hW9UX>XZmwzxU;Pjtz>+!Zuo>%HXvJ!6%w&L%^#xAIwem^K> z_I7H%pPr-48eIuJ%V$A-lrui$c-wo8S!ojoOnm+mJ6G8W8GN^<(A!NoE8X5{7snC* z7feako`O65_&3$mA#6f3N7RIhmY-*Q+{IK^17=DIM5_E9>9xBE@MjB}BYr*S9`xJw zzpilq_s9Ro8Z{QUpz-fcNt*iooJpZiecdrU`nw-Fi#etjx~k-UAVj3(*2?j3qO2B9kI&v`W7Gi`Q)j6m0#Eun z{wcZ-D+Z1QhJk4-^N2kO_ndch@&uo_a_w>K=FGsaMDk!Fs<|clewxB7u!gEfHxqOGV-C6wAO#-U92Dy?rrBI-<-69B7ku@oxdMn}z*5uuONEmd_r8Z3>VNOI#c zyg1gIxSASlFG5*4A@kZI!b|EWxI33rHhks81O6$EoI0b^=vcAH&u!F``)UJtNof2- zuj1}LuaUq94{>7qaTFxf?!IIQq9qKD?a20x%UC*AYFT@o!Jw;@2=v5*@vuZnuL@;8H zdNKElcXC7INK@$5@zF7a;oikfaRxq4weEy^|Imcp^9_eDqFq@Xn2E~!ewGmHSA76m-o@SDCW$t*!jtFCUn(94%P za(0frbEVgB5|c(3Hr2?#b&qcR3o5s>nsT+%GS(5$(P8D{Z|St~->N8zUu#xn0@%{& z7|$l_%0E;TmwUgfFg3La+3{3o#G2`R%6o_2pA3&xZcCHmKW0=kw^m6o9A(ffHpz**t5C{3rv z?3c~M7eg;_c(TFD0n^_ny&Vvc?aNCLf4qY1B(e-x1D7-B6A;7_cY{h_&CqVoQJ*9ertz*Rr`*$ny zJZ8Hy7fewCQ%d*eWzi0{_Q%_Q-VcA?c#za#X$kd0ky%d9;-7BgbMyCe***J_ZGFj| z_~Dse0+LtI%q%!Uy?eOR_H1b{)?YGesZe6cJ1#}u&J8Cz&j0EV&o&No zu{?W{e(8QasXFp9IY5VaSKgK|JRs#z(W3#!qxSZn{Y(bDRA-6*+%U371+pb`RUPnm znp%29oD7#8&7CkgI|)aZetIm3|2wj<%>Ydc$ufit4v(~VsEh5FK3&58_GSXgUeH2Sf-4#rWn)t29tkJ`J#tB|E? zCEC=iSiH63u?3v4gKi{(R&uevkf={ZHz5F~5k!x;!Xx&yhgkq|Reo_V&trB!2GyDe zlSU0Z<+6>Or_2)m$wxWP`szSGKL#O+_Me>J_VK@Uf42B)Qr@K59O91m%FODlIbl8#ulCS$eB5| z-b5ni_Vrq|<1tt&NXB$nipRK-so|~gaW#D4}z-l?uvs!-WX3Q=ZI-i&2&u%ozD0O(CL0(IORWs9|GKP4%ec?ozU>vahBetl{h*!_b zk~cM0q`anD2e~uDXSZ`Kl((e-y2J=59(cFAG-p_jqbTPS5LB>X?4 z^rss6C?^vsBVr`z)a8%KT3kh?OZeMq7W!2z(L2X<6y+!lkL?QHFB3g`j)bE*9)7up zleCUWmv|XP9hl{GL(x#t_Iul>aB-&>el=p+GLiMs-&H*fu5D&*akUfu<&pN(NloG{ zZ=gFYYV69yOIgaR%_b#@f8rRO`HOOSntQ))B;)utF%pl|ZXWe$Roa4u-VHicKwlTn z``x+j=4&Qyqo*F zRq)_lXdEo7Rsd}@?*|h8Q@v>)_FUQY zm0=;1n<7l2_@?>1!HaocKdG^M%&jp;6=i3r4=@k&z_kvuyutdPPXa5(aG+Mv&+#^9 z8QVEFs1p`qdOz8)bNxn`>=ns(-AXxTKlGI?6Nb=P#!eR1m`6^!bgRvG2Ui@}Hm92c!3twylA6&A9s7D#t&+Eh+0?)Y zg0!Uw>_Rd5_UkUwvG6b&<+PQ5Yv5imMBTL;TO^wcWLE5_b zP?n@Zuu3|kk!s=*_DWpBv!#uQhN%tifE^}-bd;gSjRxeQUUyz);B3WFmE5|cFL+`+ zB1TW9-Y(84^G&DHX3X+WbbZ#9Y!DH5I8mr#aj=dwYqCKq<{dn zh!br#P1yC0k56JVZRhyOaDh2+BCs`{>S?sgGBy&?IbdQ2H+OJnVDFj%m^#d0!;fDM z1wM&QTL91wHu`8T;9WuvHbkn@1QfXqX1+(2QI~)7g>mieSOr&yNQg>Cj^2qaIjfqR zo<*lUM28|KeU3EsQP#3xAn~6fr$Z?hCI?WW=HU9lycoVAmS!=wLM$vXdmDEBWneAs ziKBI%FyQ>@?3Sva;1qE{*zM>{4Set76Zy=eRR_%WuPPk!97b!4Vna4IWA*_b6shmk zGEjeh;FJe&=BP9+CwIWaY=N_1UBrU24wZI0k@y`WbpS(KNoqG!`$T<05gJT&IT`t& zoMB^CzS-NGL9;1qdK_|3BkysbEz6?yf*|i|2PTorln8$Spce<-T3CO`i)=5RLPy@{I9EvL@Ks|SQ{DRzaZ(~!0MTC655}BTKV|YCg*A{$k?vk z(l+CT`ZV)2lXXx1U0LA;@^lY80l(uQ&+z3hewW$WF#1qz50RW6G$UZmITD-Y zj_Khp92JGBJ!epi@^bZ`pbPxvV!fvII$=SJ7&>qXEDMAQo3LOb+$-fEQ)=#kQc+|T zJT(sG3_a3+u3cGHKhf(s?d6V5gIrC2OhQhq25dNo zrp&Zg>v#Uh*7<)0V|Xi<)u=Dp@0 z70tf0P^8-t<=D~fDwJ}Ra(~+k7Vp~8CtN+xXP_y?VzNCazGR04vp~G)>~vLTraQfl zH6wjJqFgt>+^M?*nYId6ZMYZRD=~5iNod-$Cm0F#Pu_a%2MR)G(Xqefa;tkyz48bt z&-_}^m9aYSLn-3FH2jUpA=1{{$@#BrS9RING!{B| zOvMFSt#9?%6EXM&^i|&bROnQB?|U^5hjK&SP3{~s&k>)YinJ5w*Ii%#on29q-;4ch zZ?H8Sg0|=A6gxk(Ydyy>-m0#~!R^!1*HQw;QGe}c2;xeBc&W-O;-L(wn!%+h%e%Wr zB&O0fP8E~s6Hid~$OHU?`K*UzF2H1!__&;k{gAB7hQ^@eUP#4-PEn2`NG#G_)lmLR z<%L4;^KU?GvwWZvesHVZ``hpvsf>r^sN+3d1)oMN?(h>-;`4K7GkBJH!z37_!FP zyNi8u8vL}dV0E)qXR+k~w2Uf8C}J&8AtXp*;O4K3muOJPw_Wr@ywGw5w#!q)rNXBp zYdfs}T;Ay(?j2c^Do2>5hG_sn6uaG7H~wit+r68KAQAp{sE}2m{dr(3MW3y;N5I<* zQI4!JfJiUKuDr74Ho;KH%w*wcDUi`GLc&?fK zn{t!Ga=$4i+0XrftP^NLe1tsU<0i?oF16%G%zA0gY=S46B4MK}#6?(DO_#PYVE#l+ znidS$?`u{%Mtds&Awv(z2f`M>j}{ncb?@$a)!W&<&qF<#cHI=uGyZblKZ^;k7>ydc zsm`#p{E;xUih3I%S5(w<&3%nv_cbH@9Pak;6M{{;Z&Kh+^7Q?`U2OmlL-oCqcG}i8 zemg-l^k{zg8f3E7?kJ`IgttI0m7}uC9Lc;JgZ$wAp^tGoRVTmFfc(HFy9dcA>9hw0 zr)$U=-h2*_O2?+h5_HjIgy7S=&0%{G|4X08JxAli18A6C=ADe=K9I2_+?Nv!lV7cJ z;>?6suSE%AdYZMK4SSvzF^Sb2C;t4oW1OgLB4;R=S^}LTiu`Vty}1Wl^%Ubz1oZ{k zif&aE&1F^ez)32m@!FeCi~^-J3H|19^*|*)j2Z1wy#1oUe_@DPItD+jSl*x+e8uNd z+?sOj;h1BZh3hIz3eMSvE~`o@Ds?f}I&t;yTNL!R@U2HINn5?hYt6P2tzSQBabkk; zvf-wU?SQkOdiH%e{|NsVy^Y3aDbrb(_emJxWyZo{>|lz<#1eKX8@KA%jx^TU~hdcd&+`Tr9$sio5h zi}To$_OL+ZwjRz+G;^CGE~*oIDi+le)<-$gSMk$E^f!&kg5#)d;m@GZra$YKXF_ZM zga7md|KM}#FR?!r#Bn+MZ!G=g{0IB}yzX1~1+M(+nGk(EZGa1_>Hlu4ZpUFQ)>gAp z*zf(CMAxXGwau~`(tKeI&F23p=wm7qXG?=rd6fPxmKXKB`B58~A(DOzzP~=$yH)GC z_I*o#^ij%sT^TG;IMQV^<79d1QdX)ORRj1gd`e1t7D_}-Tx&){%vn9feqmJa{b;eI z^zq&oSlD$nEVnyrJ1g;jd!z01y>(QiTxH`5} zuanpTre%B7QO^Z=wPY_{Y9ua)=h%?nmw4BuaUrUyh@(=M2xGO#5&hE)+RFS08D5=7 z9c5B2iZAYFz{?mneYVo^?)P@F8Lu{MW5AwmeU>n(`@8rG5P23<)o`gVJj$)1@6)g&vf@yy5ykhVNrdi=(8mvHKiu4TOeY8a3s`Hmhv!7rU}qnuKN% z{+1sLlQe19-!4veb%pf0MLs$n#toK|4+3{9rrrzR$UI4CnWS0K`Rw_+!$(+n*X7|c zK)TzbZ{E+!3UU_&Zv2CaYG6}2W~p{R%_uJx-2DO7BV{8gQ=qZUamA^R)bbC3FDfP-Ygv8QebGRO4+bDAl&8JBT~z*_8)9K{EH5 zF<9X=8@h_$6!5XWZbJ61stL(fNxl~!bm7AphF@T~pNyeUSK0sKsSvJ*XV8ln2ea`X zsOR%vLeMlSivi>7Q!tD$l6b+~Y}*+?xlMu{oF}&)1{NSn^7qv|DQ?bPdQ5 z-f~Bx^+V*~*4VjWhNT{bkd+#SpKZxjuG2ASzZm7e;ZOJR z9}J=2o)m~Z*IzafXd1L|#Og|a2gnvYeQUSI7>|l-8q|;OF$IoA$A(|r?e5D34vojA z8&7H_MRdgqkGFqSq{7MI+cwkn)EeyZGB^h+)HeMzX#ef3S{K;=HkWAjaZ`Nva-P6NQtBa!U8Zi| zKQwE*zx_}BAU7oQFOG+4T7~_$UG^)J_*_mnoV4f5YEltKpOgYo^EY_5s%jR&Or2&i zSM?Bui^e5%tXk6TyXKFu>>bqO3+$O2>pGB2NBvV8PsD8rv74o__f%+bUD~EhF zd!+4I1t~@g_x#@haQslZMd#OMRl=W+ay)hx871(bN}a&@Vi=2G@w7+XfH zw4W~GEOfzxO%$}VECE^Df!-q+6Esn#RFx`TaI*44NF(i~oCd2l2UVokx9*bbOYQ#_ z%MkjVv;J!vwD~38;R5;#i4)?o6?Q(BI6MH8=EXgn)mou4=~lThq2vximVd{nq^dAm zbU{@ZvD)x^V#Cuwp^SNTg{BeO>lk!(v#EV{Zgo3^m01j!?JBw5gT~Ua)EPLYOcS8V zElCB_RafE``jU9G(=3!$D0)ZEG?`>dA`%S_WzoLi_~r_0`0gxF9m4UJ851663@aP= zn<{GgQy1grMi1|CvASE{>($U2d@7Q!wy@KWKTEVLsNx59g6fZ7~BujCPd~`#e`_PD*H8n6?AV%D_2B=C)-XF%*t`u}aY4Dp4Ohe$9&}`Vt%v z0@D>^O%}2Ak=S}QTAUG43rlH1TI>iiyAQe8w7Eq2RBtCO<6Zv-Bl&XrmI{nYIte7Cd zuO~B?kPm#cFt^+;QC}t#MYHG3xke9hW|MhnBt4viaNIdj|4o+JaeP zfzrKYcd(npTL8W6ikCp?moX9Z(|xMf6a0n5;Gp4GyH)zf6N3n8L6ToSpO)}$dujZ6 zXhN(07@pyyjKFW~JIBtOC-K_j6S|Cu#bYP{;*DiavQiGSCEQPBaZ=UN5`0Lm_E%hy z&&(@lThMa%`nR~blRo6r0A1bvkly`YfP^yd$?{Z`Mw_~*m%N}und8rn-7lhy8u)RS z+Al3@#WxYZzds)fHm{Ni?eF4_3M?QJ*q72SofY^vl{r{cMY9r5voc-$QAu&?TzN=J z-qlp_s;6kQXeA*_`v5g?gI(K@o8*L~2*yjm0#Rvi@*b!Cnws(8$!ojnMj>dS{y)KHHxUTNO}M+zJd<~bTyNk zMLL)Sv7@~}S(SN>x}QesyT2WF&ZBl0ijj(VSEq%`zIFIJ=pV^gxO_B*>k~tX-nC?@ zPkR;4lFJG^;>$#4rzEA! z{ofyeJ^mLXNQS!tQM<#hpU*J`S?V<-&iUOHU{0>LcSHX}nqDt3o#qO#BeYk5K!(DA z7#Nf`5ykP>A_=%3COj>0tpuH$cry_H{18@z0)3rAH~#i)+E@}PkqZS9QhepY*V))O zc*paUXXlFp0l*>T(+nB_boA#D=GS~UU%`E_?ryU>4Q{ploF(XB3Q@!afdbH8hi$Q+ ze79~edek)2v&9Z?MhkD6W}G--P~tQT@Hr>Lu?h*o%RThJ{j4C+U#Nc2POg9XS(C8b7 zqQ=CPULO6H0IT)!_3+2K*82L?lO66rj1^4p zj_pL-eO9bbCrF^*IIs34Gn){8ewdL+Fnud*AS*9}bUXP*ptkvZo=cJ|T+TyQSj;Z& z#NZc`z!v}M2DF)FKx!I5hHKLKI_5f>8c=fgMnSGUqkpFEKH*b=RlH!@M~oVW9`em! z2WQ?N;&lxLT14`nDo@(aOHbBu5 zP_rZ9&yf^(uD$p>ZN)6TuenYKHuyYT-O%G$3*m!0;HWWyfbGy3a=53`Ti0|!nLAb|-%rf9JEKR!g z+5tX#{WaSFVD9gqtTqYOpvd_%z%ph7^2&HKo_mUs)YZtGJfp^wKt%fD9LmbczBeHW zXDuddJJiv6-_S@StJ41?L6CGL%0FvoH+43@$qo;Ha7-)N^gAMksTS~uHiG2r~ukqWbRU<*=6oUDmte}yyf(`$2$n^ek zC~cNmo1scTTbmFdlED%A!1?sZwAOiB?@!yM{vqzWN9Vo>xYw#qNA;)Kr1!fVr^?ls zdpQ}|VsQTp8xYBLHD8Pfmip4gx)4Bk^>`vp==&K8qz%_*00rti@3tC{y^L_b?{nE* zmp>2k1td>rXN!P<4saw%f|i%V3|eNvHDoIMNddAv8ujV_py%vz@?v?P znktgcx7>N3h3L7vAwxxaf{G}R@UBJH+)pfA{B?u3MuPU^+e8Nc3%n1h8D<0hPL2SS zRTgsqFQpHm`@_jN-D(%1wC}$#Dh!~HMTk~CGnxB+%d03G0I>%Il~2nPO?+nvtt#_t z1>7Q@u`d2&CLO)2V++d(~+PeO0M~HYa*#pMMPh4_}Syl$h|rCwWvCR zG$49&Ddnifg$;lLiD9;>L4ibWAU0NmrK?t?G=U*aRMk{epLrNvRYP)`6xEk`=tS@S zZYTnr9ne_>h~WB1!)#Rs7s;3DfG83WhmHSZ^E_1>;Cb@VmB4Yg+no0*)(lt|P#{v| z*U6r}q{9%3#ri#&i5U`1md?}8ew+V|x3@BB6s^)eThD!pg;!i{?^j25bj(Fm*O1rs9$v531}^r9bT>=ki1v8 zEjz&VT>JjiTBlZJ(P1mv^uxjH$Ihs$z$fX{_*{x-d!sQRpzWkfV<=l=XVbge!`zL&A3~bf?bX1B z6{G|j7N>NbcLO6r=N2kO;$BJz)5kl{-!%iULXhbpL%j@5!rey_{ zcWhTD12z*g7&@H4v1=d^xHD6ws~yKRcMqo#Xs$9J^JM|CWac+{;QK4GBw;|LF8gOk zu>!F}2aI}rt)oBr<}T(?dQS%H_VlC#d~hG`Z{$}kv}6x=I;@}#Dh4eyf3fiP$BT%e zMNi~~*Fk7EwlVaSkwNRo0k7-btGdCAYVbv+Q3ha8S}s+_^3aw6<+R{}HO^e_89reW zW2qhvki;T-l@hM2?xSr|RP)OT)6rYUzeWb1l8Hg2^a!Ze<>6`dk8>)zrx*579ODId zk5k_AVtSaC07+#O#ZyVg8+pSQ8XtY`4vuqcYBu|dZycT`BIY8W$U+@?TyvQUq1n;6 ztd&auc2#uG*VSx>KY65ep1astXsuB4z|vRX1#tSGH+=O>lej0lJY_8pUz|L>f^Q1T zfnp63i*k~38Pjhj8mY*4Z$Vs<3y00bpse)45TLrog^zUs<2ErIwqQH(F=^eoO|x#XfCD=NQ|(Jfm=;DneV4?k}J(2zU#`BBVx)18RwSSQpFKeHFu` zzf6;wy8+4K{>5b=+<5)uaOzS^v&#Dkh+(-jq2nuD9ehJz=g{fx3Hs{rB?=KFL{Wq| zas(MZg2Z!-Yru_|271dBnM}}@I3>MK;YIQTl3q(;CIK*yw(Ii+=)W%U+Tvz!R@gLKEi0^?76I`i;dZKYPo0y}!rmz@(5%=j zmoX##I|J8Vq;2eTz7FhC8Si#O{Cggo#>xS7vAS?Iz_>8qf!8`zeutk}ggo?USZJ%C zpy}DKTaigp7(35J~!Zza9C~H9uKzula{<^KQWZub)PWFFxDJhT2~6 zfI#x(*R4D-AcsYOsJx_*6o$0r4>#+z6^9t`t|PaSzVxbhE%G})38{ta%H!SHE7)EL zlmKM~hpZxL_^K-ugY-z=+-lO*3oL_x1(04XK&{&}uk>eyLoUkji5GT`L+$+vm*&cO zq?_V`wbtJQWTgW#YkTDue{qhwZHlSUFtd6a#&;jayw|J-lEnaxtr-x71i-wy2sR~( zOP9#$m4#P9#f$zv@^yBvYYdx(^~wjF|A)P^`f4lc+C5cTDAtxzpg@ZjclY8J+^x8~ zJ1ttYxVr`k?poX}cnB2N5ZvYLzTf!H)%gR?#ha@zMzRN4Ywb1XeCF@jYj*kGDJ@4k z^&W_7u|}i|2PD4>56a9rFbZeMPH1}lYZWq0#A3)*F%OJaepmwk+S7J%AX3B-Q#Dmp zf}U5Kge6UDeE1_QhX6)!1h!73tRl`S;i)ZI+srSEf@T${_ZBX!ij)K$4eeIAh>a(@Vd7IbnYEs1ooTH|9+;qQq%_RS;A;AyUSI>#_tVGpM!=+Ppi}9 zvj^M3oJJS(4Ln?+0Ug)u+2Lawm#Ign6Rn|`;qH*P!JyniOGL_}hVj3XHec(%|S z5KPU3h~3qwT_(}16Awi-(JWQ}uTmLj^Lpwf(8;4EY|HZ0D0FlcFZ~pjHE=TC_3Um_ z?uRK*J2-65HOpLV3*v`SX9Iaw7bi7PkleT$L%qI+)7^i`LarBJ+~^l_v8-#m2i{o% zny5UGyl#iy zUJ{t3TIyZnj}ySbyq;1JN7vxBnYB4?8@{3K?KI$jD=fQQYsaztxuWK1eD4s+%!xFX zWO^|QGkQA-^ehfJ*M>x12+QC2K$0wAMP`bsI zMcnGd^bQkxsFNyj)H!_ZK$pNy=>APUh@P=07Cbs{x$WlsAXm}$-rI+fNn zTE$(6OB}*~YE5oZRBWJ&nR$mGDKayIs zU0$p6bx~$U!ZPY{!?q>o8%wxt27up=^)_cUkdb9JQ_&7G8{3!I|H}2O24x5eo1FE% zz%09b0T88)d(VJ4bJ{}dm%8Kb9yDII#z9>njs1e{*hqoE>)N}VJ_G{+eme`qsKRXB z1Vg2?=LxD}OQ}jqhV!^S+HJjlw)H1dD*d`L&JEE8zlL>Gw$RLnVup5hr6j3QP;df} z%D{fByC~t|6AUn>OC0yf3`4xEWJg@W$2CFWHRZmf%kz{{uhlQ@3=$>tWk-N;x;h~J zYF{`u{Qy7#!<~*xfk9)wl74{_>JKoMj0|o%>7{|Q)u3MnfI!sd6hk(+FdJ8i>Z0`4 zM4q4m08r|`nwkY^c=falcY&uO0~QbQEM@UbR&mE@O@yEpAKgzH?LCRqI`}$ zDhDo)4@7OoIHD}Qt=86P0>Y!l#U+)C33Hp{nJC)Zx>W-0qEP5gJ5Fp-yIJ5Y$GaPS z7-`C9mYSp~Q>amtjB~XhXad+~J?@3rI~#Wtc3N$R000ee@#((RZV>`{#F&)OXDFhX zu>3lStLC@9e?J0_xc;SS^H=bEQ7Rcng%FLsw4t#fgt+(-XLn3)F9iFD)QmsB`Nl~X1X4Ado1{AUCH z6~Mr&-f2sZ=|4yS3hWz@O8$Gn{^gYaee>Tz`2S%g_(T8Pyd_4wMfuvH1#tA{>QC%b zg@CE?zd$5wFJ0F;bbq_IrzZ%-Hu2N6(_xZ-yumhP6?*>9hkyW_zK51ehJSn?beVyE zC=EeSf4)X!L9e1M8epSd>JjeB)m}%@yLcLxzY;Vx|WRp!P!lfeZSPhY~{!Rc?KC(L{UlC13!r1UO zQTqvC)zk^k73P%LZ)t zqqdwFmMo%8GS&#eNa zqe0gfUhpRXrJW#gv0i#|^g z%lS9sjeb}ZbO(q$&-33`h5%pRc6(f1-#j>L=4TtKgnU&dLT38Nkv zb{&a+erd`RYqY2=vKIg^RBvuxw?-_lmMrqcHp*$a1yYH5OmGFR1;Dr7l|JK7crgih zI}XS^` z$=%7PK`fgH>32@KD~>_m5xkTSwe<_&kx)uEWwT4Q>bQZwwJl1m9m9MY&;!{AD1nhB zr$jF65cqFhxoOjWNEbk6$puV4f9^FHYQ~A7rnh+3?TA@n#|}BHFzz7(J$nu`06r`5 z6y0_lgQ%g+w9%2!DSAOctFUXk#H{o!8PQ?P(+bQJbkF)Uj{BS~ZKaXD$ojt)n~eK% zFG<$sZgp4HUM;3vK(%A3lf0)wkYLF)-( zio~{$V`FjQCPjVK!#AJ51rSm2ENuG7`xb6(rp#9nf7SqI<;m*LW!M6p>DgW?T@6ISrVSl`U?QmBHFW&bjRF1lL>kHLoR)3E&(mzASE`26}LR)F`oR zzl^odxqFlVaNAz%Pg1g~Dz~Acsm2#Mpaj9s)*?9?t4NDH<(^T^%J4oCrGmMyV?nn` z^le%@_BV73ot5=74o|~-H)`|!8JFx1A#ZURgd+-ir?NrTYIZJ`Zej*!UE-(H1qGRc z;|_`yaUoVK%qVn=3;)XkFrNyJUTA7x8x>U;tSE1LhV997fB|AwSMbO+=x&mfaR;ZZEeFEbwcdTme8WBUW;0STEpgLlgoJpXmcAe2#(^ zmbQ@C_c_#`B=&YsefqXo7PU=gJ(FSB;3_)$sIf7HvHik`{gObw4GTAuno8#CQ>@Yk zsq_8$1B*QueZTpiSgvUuj}Xm8Wa@xGb5G0%yq@8CogsN5MeY{23Fd-gkau;GpVvI! zl+ZbG%%^Tg<@qbfLI1O9p{?a%&9Un z+Wb|O%V(KoP6X_GK#Bc=e`dtrEuGF~@~*9~x;wW~4~Vhx8nf&%a)>dYw0h}c`)Qkb zH?7-y@QagKP_cPFrE-3cg6UI2sAkHtGCsjP%bysYzxO=Vz_y(E=+f)w^Lxd^wUY7G z--zJsr`W$$M?+f3c^5q3S`UAKEEsSMMoP#pyE%dHES=jVTC01#-OOq%o{6eV2~l8p zJK_78u*w}4KA6@nmWl`o#+~z!(XJ%#?gFEAv1ZJf0%dq@Ebp4A={T1cdn|bTEqafJ zg4;zZd(2|xA%Jwe_Vgj?{9vqRChcViyIpSWkB3HaeI5I~npdPWPQO_25D+$CnOz_T zfWsjOV{oNIzL^-+__>0P)XUU|c|qu#{93NbUgb=Q1jEa%OpQPpq))_m{Su%{nO3S+ z!q7d9N{=r`M+Hp&p#zF#v^fp+r`v_*Mn0TSLJUunn(ISQUe&dxgLij|Pk)a(st2Gx ze~GxnQFoJ7f9jL~u`LTWaiD>t zm=ZpuW9Zd%-N)esun9*W%Zpa*CSMWTlM*DAAAoOG17VufX#3CAil4pu^b-x(o&*JI5C1T1{Nw_JZO#8S)r(Z_3E$E)WK<`G5x#5fo;^lxtV#^-3j>4t}NH5;~mr0!(f_U4zIKX ztCr(cT;kj<%d5&G1Oe%Au{hs_;%+-Ul1CnWyL*|&;r`owg>tG3&x@TPaOxlVb|k0+ zTvA!TV6dC`=?rQ^yWMdmF6dILStkCNJp0W{(Q+^+uIQ{%_JhiZuW`_^RQtHRs7qX< zPmF+By@=;z+q77N@9u&+yemx!PEM?4U|oS7{bHhPS@Fv<%w(3+FHiGS{cPpgo%*md zGNJ3Sf8z`oI8_IsXVP+@jvKW{+6z?tOj0?jYwl*m zj{HeDOIW?EZmFX?R$AAs+1gN^2Farf4FjP~%eGPedq;+-^Dy>#;+Kb5p%fXN)25=4 z&24#*CCkpX%vn<5jkQQRVB@r-vAKS-vSbRFC3iDUx`9)-CHo)!G9)x)c#h5fKtS3W zREKxXoA=EB%KEUePno%%$1&DdS75|nK)AX82KT!?2n<4XkA+?ZtZ2$A-IfHgO@h&= z6PrYICIW`f$6iNe^Lz;XDqfK6-{P(Ip2KS}k2mDxFl!M#hvjBJKHG{icg@pb@72gE zzOYJlWx-1xoZWQa)AHk$($;Y#;EdAS;r`wf-x+GiCe;7~6tD*Jt;Ya)(F!dN6^dNt zl|fgXPF}E zKy;AzyaG{}74P`%R6rx^u4qDe#E&a$kFTw|TA7 zc~z4YH+;oh&bq}0IBozDuClI@WL1` ztZq!twr}fxWn2${auBstzD(pighj9$>Kad)3?qCTldQPM#XO(p3R`tmtFt9j#PDw9 z%)5jXDi)XhStoJU<`Db!uaMXd{XG^8HqSft`qw{V>(zN9$f&$1gYQUbifEgUCc)C* z$Z^#tZ$6E(g)x?jKG=WLvAvsJUdTyN8tNIlyLcG#Cxqu#nO7Wip@ zFe-{OsXeN!7brSJrCB=bq?wztLfpL23oqTsnr)J!Hj(5NsNt2j8cqLsfj7j6WqvcZ z+9iEGL2yZ>4ldM5R|na-s|X)t44AsA^YpXGO|?H|MrL!ZGGmXGHleaBOG||sa-J!@ zq+$(;bfh)kRJ7@>YNnM9N+Z_YhNL8_(YEros?}ytG~_P+Fy=iiAn%%I^#2Sr(4VU* z**pkN8fY~+EGQo5IlTWfZF|?GXo(ov%0cX=5)YXPTFF1|K-!G5$`cu_9ou*qI>kj7 zcIq7JtH3VNE>!uGaz63+r|DwN!Fd)2{gtpxDp^+V=DzAnhyw5KOUvx<9(HNwh~sz##nQI+ud7Tc95&}ze(>Y?WDEOMNi zx9<1Pp{ln|x{ccsr8n1W7Uc_%EhCB8gUd^La|5sx#;C*r&o_B!l5uCX4u*sA46P#0 zl^uHJlW^Llg}xUardTRxsu6RS|akon{ z&_lzyFN{7((w~t_Axs)F!^#)*Lu$Emb-pO+qR^kWmZbK1yC7J>B)5Kwg{^-4sB9eLMI(C0ip>U?da0HT99ZmV$| zzWk2@y<5;PqM^e)C%AJktH+THi_04$%!CxmuUVM3fwGc`B)B98ENpP%#-0z}e{#(@ zo7M44zhNLd11#Kbau{Vl;SGM%g%xEzsd*0zDy1@7$qS}a`-N&Jq& zf=@tOM@84pq(QJBj~1!h2L6qPtWVJ;)`ftHw1Gf{QC&MbfarRCMfj+QxBt1aH?V>j zNZNdKYn0+$zes10P+E!Z26ivS1BF@)5#zbc3 zjE2R<+d8`xu;>?Yn(swf=_gysZtoy||GQU`qLyf%%CL@|p;uXN1yfu(=9m8rS@88& zJ~2_$u!7yWinBJuh({N%KsJ&!M&W9g1DUU5Hzg_QW;eP|+=QdADi7!_^TU|{DfDHkGq?0`S zC9a?=e*cj*7qzX%j?;{Y^0DD#UBt6iBtGD!ZR$`k&PXT#(KtypjN8$q%Vn)^Z}9ig z*kl+j$QW4**N^!!#1{q;{o2V=pU-Q%#0nA;6lbQHALSlbcSG|~F>}2sCvwSEVHlmd zct6nHTV0$wlu^AnH;#G(dU*}eavk6zEJ_%fTHi|%bCNCqKdsK9K*t3=Hcxp~B<*@` znyoGpB-O6>kIx_od^A{8Jq}@%odx63MAuv4$E<{K*A?C6LMwQRwB`P1w0+D=V*(nT z$z&0mCk#x0B=VzIJo!=H!v}ABmbQ%Lj-7tOcn9JT+>yvrAmc7Y#Qu$jbJ|@N>b2N_ zR{0>S^PCrE4(B~LrO^@-O%awAEOr>fzcS-1=V8!WUb`p@fjvK=-KnP-dkPQxErogW zJ#5c!Q-Hq$H$88LX_{wBBD5IWP9K8=;!!Cn(6P|AYOF!5jD3Cos?c}fFZxIK6FyIv zyY?t`HtG6#iBtBzYLZ4)hn^u{KQG63(=5-Gw7wN~JYH7bj>yVNreO4Zfoc%Fo0&Ure^WVK$_)QunhEe)X z<9_%HZXa-F#F=xU$86YB^OT9ar`Q^X)7KQ3mPEX?Wxr49=g$BBsSTQyl>bs{+m#3? ziR{q5#VQoba5UZH!-vLb3!n(EmyS=N#JRd?rE|f|9pTZ28rZgv!ry} z8jq^>5O~^=PlRQcHc!9vpla*GZV)s{yFM**4>G|V)c2ieZ=p$VlzQ1i9tOx7PcN;L)F)vjt-pt@E)22W1$NQ(!4oYrG$n0gp zZTKjH-dMWN07=9BTi>J|H7&_dw!4jEA#~eMyk=Kcwfq|=Wpa#@^E9LMNvY(54ZBPr z1?tx;GQAQ6;(i%lZOR^MuR{V0t#(|)jVdCQeN@XZ$)wH(w2~}z$BHBtpQ;6)1B%<) zNA^BYP14+EFDvfJFC^SAOXKl}Kot(%WzrNxZZ@xaH=e725Zz3D2QH=e;VD|h^V47N z>XS%wb4vi%7%quaLi0WLk!ONUs~&~;43UgOpPZ#+(=rFd!=GH9;>yymhRN~niu%R(gp;p@r z!M%>gV_NO@@7Ho1y&$HU$7^tVP|h=!au`e7{93`XAe}cImsA*`Nl8!>)d&n zALavWv%a+Xc#`_=MlTpo(?e&3U*qu)&rQih0fdt0pVgCmaom;LrcqX;G+89%Yr*! zTWBiBCPUNQW9c?5as$ zCphf-FFBq{zwn$PDCaWO8O_s0e?>#hJW{(c(A9lzSL8Xia$aUW{gHvSZ<+-3T+gn( zOfOGUwl0D{D`*aFUFCMpmt{QcT32urB8;(Tmo>BQE#PsWRFGHYKUI@f8+Wdo2_$tO zzo6k(QF$_EA8Lp8er*UBLH!?h_<9PMa(;>~iz@2TzXu(OlXt{IaVTEe*RXxxN6R`f#8x9~1|aO7kfoX#_Z_>`Gx^$z5lJ!RER5nLwxi$>NK zd4L8i;do`st5?*_U+y_N#V`Ol|0@TmgF}FD*+;y+wReT-`dz_Eq)o84Zol~y<8CtX z_zeN?C%t>A(*)nGgXyzK#~|nooL=xKJT$bAFa*n|X~m4!#Ruf?s<;2@gTdVdA;{BC zHhI?0B3mk>>A{CxD!Rh$b`Y#d;dr7BDahf}mTT&nQz=Gx7+7KZ)oOd0g{(4VW{!~% zE@#K*lB@uUiBq2Hy+S%m(cSu@Cnk(VwUvLCJZSRgol;n-vGA2)P1la&`bhGPR^ zXWS7*C~{6vno@L3D-YadzY{_uza-z@1hB40{$b-+m!Sq$Ak887oOHL5wHbZ69~JgQ zif=HPVR`BBzF_I+?2BePSq?~G%TXm0h9TSa{>w{bQj?q}MJtfB7fm0{*{*8my!iVQ zz|67BV7E@twb{p|g8OT)Q;dqf;J7u;@bvA7%cfgK=JD@sKG`{9$thG1t;?HDcWbR8 zYvr=tk$#4$ezx;)r_T=q99f?-^c+MOpcx@hiWbH`wH5RzF zt*+maEb`3Lt#cKZH?6fNK%AC|%OHcZwt5>h#qn4b4&{8rTDeT+a?Fpvx%MVMtT;s-WacCAZAG-ZAxn2}AGLe%tl$$v zVt7 zUb0gr{()aP$l#Syk4q+p;bf$86Uu^(ocJxmwg|K25gqKb$|YkxKlSHPqZ+6Zln4iT;#!C*<8)Xur{%BDJ@v+iBhp+Ln_F ztRoDneOs?n%wHqk+b;YbNKs<20*KnjOO%!Wv$c(xAHlMJ0cxt+3Wv3l8HA+4wNV4~ z*vFm6J1)6}nKn|Mjdbcs{nX9ps4wmU)NU?*^kwmLBTmcn+F$VZHs_tE1A^heVV%}_(T`kx+ zR(yE;W!ll*JsENPE_mX+&(+2`Y>KR>tN&SCau@i5YaxLV0t~>LD=QPtskW(w^OVG(nM?k1S>1%+s2Wy3iNVT3=M|MrssMJw7NV zQ42gKXNBThjzkD`ba{nUGI9hDy3OMUAD-=?x3Vc}MbmPS)lN0xs$Fcz-S;GLMLtXV zT3RFaz-Y8;IeVv>N>NyJT01KnSKA@!>mtNT&nL+AD=kwEdlGp|tAB`hBf*VCOmU>Y zg+dc*XH|AhL&7#WQJ301ea~WvoG(9by69fI1j#J7b+OX~$?tZx^suNJ6b*0o#TiN^ z7Dt*1ZiW^4I=3-3AATd~BZ4HU+kWIvj){nWiv1L5m17%|pC5iZ3vJ=xOshi!@zL& zBY+<-bXzAmFhzAyT(z$AHYpts$WapmEU194065^6mvoDOz*7LLF`QDMYNQ=a;jxwJrF7on^nT6+Y-`mTH2FxkvtRRKGpKK#`^w@ z6yN_iJbs+imzalW?@W_8df=W#kKBAh%$+IBnuc#SZ@;+4-PrDNnBR$fUD7?@l8D`# zNn+Dt)wKGw@w#^Yz{^qBo7~H!Y_x__)bPERaq>wIRxrlA_UFqF)7wyZoB>Sxa|f&I zcgQ%7uXvm|Y{BLpV{YT<@JOpLgSFm3=JgXDYo;^w&uq#q#|@Mv4moG=Xt_-ic~$M( zs{}w~GxQXl`hM=NrpT9Ati;O`Y@y63}2YwNU1=qpLJB#I>nh`mDe zxvu^oyD zT9JoMIuCcFj6`il8@Djg#OyFu^v=MxtXf`xHmqHQ&4)uy?wDEf{6=r+;Kz^gP3@bP zwhOGez`_j6I zNCJ?idY22}w1ki45YbN53Q+oxuZb+m~i_VZf3KDu$?yq2=6 z-uGN)Kn@TYWIlaq|D$_?(f=ki{JVT)B|OdG_M)<$U7eWb?F-c@uwvl1azy-x;oAn2 zJZ1NzQqKmZh3;&^(Ij;xL`mi0FLR@~b0EZzZ$C{jo(Q=SY(*kn-GC zs2!G-7urS&+TcekLa~6@`7`H&LIV|>be%QYCf$rN372ZWYI&HwwCTS(d_mgeS4@1& z2$kDvo-!9s9ok`zUGdwz`M9KoLt0eW${1)@Yh%-M1!yh zufKS1%xxC))7#jG#<6n*o!1e10TuWBglnrS*Jwis`#4xX^2@gzDux>PyhMtd0?b}% zLruY=E+Xdqp9m(4DUlsswkf*ou7;LSEMe!vJ2bj#6Kap=Ue)shkEOMs5-JiD^aUzp{w_>Ktm$H|cTzfkW>ul#C3rcngWI|PI$eMBH)S&`g5Ar2c0Ualvinlo z_@iTi2vN+PO+X$iZjg-YwL;)*^J_gy`IhJW=XtzP4I9^&eNF*b>dvcqN@FV>CG4Iz z{Y;GYuO@_m)tYoWF6dz(>PKW@HPFiLAO2yh7)2*wygXc+IeT|>2ko1pE2x!|4 zgXb~3c}mWW!RcOS{^@Mo5Ao&z=e@-KFQD^bEv>1)d!8ThlnNgz2m{Bx?T3`oZ9$b$eI?bHT z+f%$O<$cQb5n#YlyA!p9Z;LhGL z`km#3L!kQ_5{8rZQmQ!`|AN}H#gk#)>OTMj zkP0M>1P4f19cM$!FLM_T)n;lmH$iiO6(YP|)#}DDi2jbJPr8i?S|-6W_x^N{nUmc! z6t?KmqTZ~z7ANU@{;BY)8od7bzJfIYGz=HS)9pi67gQKOe*I&+s6}dnuT#s#C1RUb z>AkrAc;%&(v1q*h7skhF`*%9N8EsAnLHMJBi+TJFUKuOD zoTD=5te!~-A2FC7r)=wx@p2fxMt<8oyC6S50X6nLb^l=|jiT51qI?i%->GMrbegw13glEbT^1uKIEokC+{oV=_5(h0 zSTLUek#IEN8jGK*=+)n=Of6XA=Trilb;f|W^BT1I*t`W-J}f9i%tpG3_Uy*Jj&P6ac{6M+xv=jga= z+}V(|fH^zNey^FQIGFfExm(Em1=y~194!~TV5b>JheQo~4dbmDGfX?vOn28fZJ-<$ zwf!=z>zpeK;bYKS>LUJFc2}R(Rqot+KpXG(u&jDJ*Ab;M$^T02XhLDr{g;NXEVg2b z@|fPCj(a43U#ucYHa-wPrm0Kff!=`G7OHJu0{3Qm#$qhlTDg?vc;E+DD+hGXHPj^2 z2x>(Rg4s;B2m=oBO$HuC8m#w&H8a)9Z>(|*-dLLdoXx;K#kAaa6s=Pm2h>qnzS_Rc z$2nS^lcv!__=~k(<`S_jc8j0H`bfuz>IDEoFm;uXep2f0TWd3izrE{7nyYMbHuV8f zK{iSAjH#3QiT&~*iwErO+_BS_>F?Z%lzue>=f^5_ZsB`Q8gcZF!x)d-C!o6m=K3qi z?jr2ii}#^?(U}zH)WCA~2&tve%&n{zP6z`2LRD+2{o8Etfe1$m^OA(Iu4mL_40Jgj zv@PgW9YBmfE2?aW@^e*T0ZKNr06hNU%BM*`Z81`Rkyw);JBs3v0%a5enHQ*{gm$&d(XdCm94W`sU1UFmv2tHC$^ao5rFoC+~GtTnRWJbfkAU+DPeu({KkhoUQ1Db##H(Lif& zwMntw%5&OPuF?Qup(gL!{ml$f%kX8lTo!?l8vUdqut-MZ3wD@cPBqQX<9$)K)BdJ_ zvKV{v2WbmcWpMw|u|nzdD^f6|}E3J?NoQg11?iY;t;uU=9YkReZFGD#5z>M|s|v#f%K5#bo64@;CdFXW z6qyN5RIL%mIR>L=Q&Fg+co5g}9k=`ViVC%k+q(OlochMliJ#Jn1xwyTOndu4_n(Ae z9oi^xj0PY_d&=5$I_>CpTqHrHpsK_jV6-^zS_nB&yz zEi0_cy@EO2g4^r}#YJhOe%*GImhKbSn8AGa?T*gsb*jF~SaZ{lsVF39Q;I5S(Pb^A z$jfg}y4LT;U%_LW)ms3qX!=$6`F6E@`VIFAW3;LdI|GUKcBWUcZ2*hAlU&R0q)$_#^V(?H=qFM!xEq{GrT_LhvAKT~d}EJDrzBVBHiGR$@_PiH0p z%XThX>ksTCUtp$Byz+;Xfc9OU(t97OzAfn5V&<2S?^0(ImUC-#-PGJ12_5W;7`t(F za~ad!JV*6W6RrW27UvFCe}7*%2oSN}=6w^u#{2-xeQ&TbX@$;v)tLDAc*5{^ zSD{gW!fRX7wi^Ds78v!z#(|M{FA`LADDn_=Ut&F{Kkb3P&`H)+D2xf_13kEtVel0F zyS!pAzN{(LrV>JRk?|afv7rLZMJ%dKu#%#VTnt)xbUyL1wKYN3bP6i>Hj_>oTN|OD z1NzL^b8Sx*V{$UBXV}2jZOuoK(U*Dg89f;j`TZ453wj{sfRp>L-)Eao5Ro>i;1ea^ zpplB~d$Gl$+ghN(SR`X343X8@G8C=dtaaa$xQwX@p5s#$FB8SqknXUvMJT`~M8f56O27>)`9 zB)1)=UZ+6SBU7w5<8}AnV^(<)1pRmUL3(|QZiQe4VW19z#VY~o#av%dqSBb!Fn!U! zp0Q}iM0-WI*(S+c^TqpV8^1crVVNC`UmTaeIqGQrY-R~siUq#w>Je)Pbq~ zH&nf02B#>ySAA4wBUoiH4-45UmpURpuI#3uq?&A$cAzg@Agkl6}se6%=78 ztVT<)oM|)8erIfuAj=}q=wf-cQmR|ZcX&w|623_^taE8R|8N`IX#+(|0-(c(#@Wr2 z`;s*Ia4+@dM^^UQE#3PK^?|f@m(BPa>x3=U2{^5ea9?HL(Y3Egk|G8)lNu81R$-4k zY6*)3nATXa*Xo`Di{!=bb%`S_2w8GISxUlVHD<^=Bb+WxrH0tK(-A77Jpc>IS$D8%jWV`jMO}mL-^X*nmDvI?i<8W=8Ol|IJI`8@0jAiCkBeC74U zLzQ(861zPgQC}wB*z9`V95!C9L%s-ZUrX8f?l~!q+hCl@51?II z)#~BkAFpKPkaz`qiNxDrvQ?soo=_8lIAAZ{bt(a@2wuz6b-B`-{z{~$7caDJ(!IvQ z#;nHkL@@mHQKLPkuHjA3WDzw%U^6e^sRe`kD2@mR}YXSiod{Yu!zJNUuAK3Sdj zbYHJnh7O%cU@(oL>L8W4b*rj3$MAaQNsNt-@$PzCsznsE$?|$cTm;I;90pIz(U}Zt z_+^-yt!vhk24lac5vLk99|Iv`49>Z4EwTQ#I(izVHSxoFV@3}k&QT_*`93cUmxUd2 z>5c%7WM{ID0XorN1s(!2&3ucZcud{a1p*R_V7L5n9&^3f?H$>s1-0l#S zt6JfrWik&^KqmqHUj%qn~N_d#pn_o)K9-tGEn^C{767cWB`;?6uj-nO`IXz!%H zo`}F!`D>`YR%X$diAPjeSARmYV`G#snECpkZScYvUVJvFdllK%t4q67C$CB|sVvy6 zUhw>5m7M4$hT6k#gHoHah%e0r6^<~aBwzD~AEcTp)bGA!i4x{ZbGCKB?7Lm(cL0Td zm}eF~SFzKD#3x5;t(Fk^!s%2%bC*hmF6;d7l0{5zIC?JlfR6R5^2othR#U6(K>rb@ zvk2qnCjH^1b6%{#LJ^#wsrKA#iUnu{&5hgRq1 za@cV2k6slpcaY4Tl9Vp741I9NBchGDEOXu$iRsz}z~~!#{M`@n<@;-;688aVH(!A? ztCSz5uW*XqXSbdLA`2HeBf4JGsk1Imds)vVvqShNhU3OMRSP&AdliuVSF*b704+41 zHoyMJUO|`wSR9Md@;hbuJxoE93nk4BzT-w}GXP`hcdZKVHPE5S;{W|{*Jic4ih{NK zSl7>lhy;{Ht(lPDiqy_VcE0^ANe{<8u$05akk9Oyi+^WHxF=mN4$0HnU;UX^xzQE$ zxOALb?rP4uwQq2>k?&>uaEOFqWXTzvO?^})!2t%<3@hG^&gsPgQi3E&2#ayO)urb5zKj<5s9W2g^<`H zaRMdj$eynkhxyoB2^_&#Ma7Ru7H#p9YjYf%3ffW=t-5SCQZLu|q#wIj7&W`J>_Dlz zCZr#y7bGLTprN(jEU34Chl%V&B@CBFys;J1B8$P`_5OK%o-6Iq&!S%C5V4?~w9xkw zSU~|70$uX{E@eflsW>-r(3nYhX^!o%&O&fS^3o-WI z#C`(qnkSh|faxL2Cs^Lih@|%v$6v&RF`9Yg*P{30M9POgITiy^qP+c!zFn3QYi3;J z69Sx{Xgbq;A%I2l;<}-4wi{SGnE*3g{NC1bX`KJ#ck9alk=A~&u+);lT~cm|5aA+9 z;Vvh9ec{X*nH29CFOHE1I58$JmO0BBrG5Rnj;Mhf^K>zzHx$C2xXMD$w3a1eLJMiw zf4oY?nCaKxrES=xBiF(LMILGyWUf2g1tV_s&XJ-+^qj3)j-?Y(ZT;RV+RgbyoN^R2 z#cX%ynQzh_ZtwRckrmL2at|+1(hIKNdiYi{j_!{|BYXx!?f?|LOjOF0n!JUK>L6QT z;)}S35Y2HXMzZNu14*J!phw@sV1%*2pZ;4)?)mcjH;=VDm4#R-rBQ^Cz;YGWZ4@Nq z=Kh|Rl~2?}v__3XGh_EH^Xz~4=w&g%P3nlW4R9Mnv1IO+E(>laDWK(aAqO-qQY*N- z?FNmMzbuaMb@$-P`);-LixE6{GEAtzgXc}kM3@S~JK~cjy>YF55iK(<*R|70UtNl= zWlP2p2R0Gdk<;2HTEYc;KYdGXdaxk6eat@qaf|p>?nMSkq5U#V&lummvJJm@Ja$yv za812SC+fCuaAyi;7l-1A{I8lX0&AX;SrO-0UgS)IV#|~+TS@g5x9`A&e;eq>E2SQi z7Sm^-Ol*~1a=b3;32lAyoYi?9=RtRKY_RX%WlUxKm#1evD(2dLp}`Jud?`1l0qJL0 z_6FUba2ty~qO$N-8`+bC_j@EfE9z9Ok{xtJgVHeH%RuAKKZBQ;HVcV+!9SfLT3du9 z7y4^%Us`*L`xayU@7Pr33cLW6BvDKN&l}7#HvhHk>^$H{#@7Uynp*xBC-zlzC54Vf zWfwEyuB-K`?ei75`06$I$vx+%u6zA#zqnaKrC5YnGIT&IL|L}NKwcr3j*S{-3<7_3 zszOUTbFr}iIDZ1;nTE(m3(<#UaklFYV_lf?adYZ6nC1VlcV1CVc2S=Pc@-5Y7DTBp zDk307=`|`U0s<;cYD9Voy_dv7Q4vt8bdlbBCy9de-U$#Qy%PvEq|NbL^Uc-F#gv;_ z>tp4D#RBp?C+F<5_y7Of=keI}&%<>;sCci?DiM@085t-qM1keYcRYSC(wG zJH+M_QL|Zf78(7L*uC?62&i+&Y`_YdaSNDl05O(R?E$^5<_m;lN zT!=Aw9^1P;W-EMSR3uL-v2t{YHY`xHxIb{&|2FB{)xDH2cXKb@T_}IY7{0KZjOEe} z6*w>3a4Z|}{%HSNRBAd~r&7XG<~Sk3BTSN~PUA_6W7NTnSg+i*!t$D5de}Nk?23CQZNnqSh{ zyOaUy%L|33OTSDC&sS_lGz=+GN5@~hK^1k5UFMrj(~VJmJ^3X2t%b-Xfl)%q;?^IN zpTD-ztlghkvG40gj$R9Yw%}a8d_#BgTIa{TiT9rLRJna1hYL5(ud z^IYC+<|8YtU)Mx3Y?I6q_!sDPjJq{2;jLCj-YU_sBJ1*h=O^ zq@P|K8i^l&#LNc&dvWXIp?J|eM+DE#OS$O;u>UeyO7}xp4Ck(0Ip6yD3jFT3j5cer zmhHp3)8IIPGso;V9AfL6$${l(zU7ooPnh^QJj^s@msZ!I+SzsFwpRiSC5_!lc3ETn zpE$XB;}~kfb6Mr+sEE9Njc_ocI_suy zhjQhbW2#l;|NR@Rx?YCf&6+WO!^D0<(RAaKAXncz@>!yX#WPuwG{$|4zxbg4U5jy# zctoL0+bkCI*595Wl4UQSAk%ByFMDN&_jy;9r%(7R&JPIT52KCiw!=ahP_dShfyS7o ztV@M=U>P*yPWkLmwD+EwWPw584HKnq_%fYpxKoSz4qka5zxGM;v7IhNXFk#Kc6R_w z2k@m4$uByttEY*T(!!)u2h$`!yqlG;T=Z3cGcIpKe)|wB=m49}ieX;ak`c(e2msp4 zY;9Tut0exbeD?e64EHYHd-gUQTdLqb?12jjd+%^#HGKWz^Zwulzn=`B7axWTXVV@x z<$t%$5?yGB*DCe;$I;gG*1wYdI3)VtXA!qUu6n;q|H$n(TR3Si42w+^lT&HZ)6_iZyBo_tKLE1;6nin0aDY@$J&-@ahW zwK@JfqX~{l6rrqoYs?a9Px*JG(kDH%as zA2>HZ*0y;1tZ*Qe93|Lt`KB1&>ge=xiu?WV-;B*m1^05^<-$V`isc;Q+@K5PT^1q9 zGRG6dXh1H8nl0B~sqb7&_0?i_jvEH#4}~s6SXQ}WY!M;N4^?QrGIMD4-3!<9BTpl# zM&_4Vt{p`sR{YpT`FyHaF4i^>_3IQ`GuHg|hRKZKzm(f@M_mT6W{$o|$ni{;W;Anh z)yk7Mn(3&c`>_$HRxg{b;o7!e;L^9vTBkBy%Rbsa$MR`^cmu|1rfo0;1iDp{-!<4s z4N;?k;ia0U9W%XD1@1udvr@k6FrwI<k(-FBpM?f zhlR>-PPvvQf1SD8c2j5V^+X>s#63UivA2XsLLx7p^Uh9(krLyTRH8*#EXH>C7Xv?Q7~4f72bGGnJmCVfn0 zAMU3)MjawKwoTGT64!GB?V^FLaxkp?P5+u8Vv*4F9gNpg({}_Z!VvgVEJb_T{lt$5VSg(;nJ>SJA z^v>$cxt4`>kTmbU9)Iq_uwJPFD0k(NP9LxF3O#W3J9xp+dxxgK&;SwA3*nJCI4`LEPL|#b$MGq z$vbCCQV&t377%12C((au3he!f&3t-hh=e0kSpo)4PEUvNiTN9$EAV zz#|n0tTT$=_uegeRxfP``a!+=raFE~Vn6*LDAYW4>G zyJ<40{QeSUxEIXON!b!3Wn!84ZJBrMdV@*xuV*d5<2BorrC-2~l6Eha{I z^_IIQG{HVPx^t)qKT`jY^+R|vQ5={UO)Nhot|oUaZ4{9TZ#4L1uTQ3FJiZWB-Yv;q zm3vQ2;o6!kp(_g1)g9VoMzdQA2G?@?y|lrhBwC9+Ka8qx>ckIrWlkn>KX3eJDy*@Z zcL&H5zYc=5R(hb5uU}r79jq?d^y~U9#mm)6=xRN_=uYK-KD)DO+KarqFrk+X<$~$l z$J#ViJ(^0=93K8FH+T)j56{H}h2kGAE*){43mIgx9C2KdcWfWBdk0#O%_Vfbf?qN? zxn7ux51^uTV!J9w?~aVJnwW++ELDZD!jPn7kDl z)QZNJ2G&DUhErev&p=*3I1~R!U3EHa>;CiPA%Ve6M>EaJSb)cd87z$0`Mf=vvvq5J z>GAsDo~rEW>;CS+o1g}t%tU4xQ*FxE3rYe_lcG1iduUIl38EFgCxQ+FGf1mcOz?*- zzM|>!qOEDqGYu};j;5UHU)nBazI0>X?BHNxv1h-pBwGhjC2oDoL3fn?FF0)L!~ely zhi~0iy&|jbVu*6%G*R5krTZ)Lk9>%Dg@;<8gA(}*?cSjvvy1g8b4SGhpNh3=rEcU^ z&<>mhe@eqR5UFCD6f+g*Ch)u5@?54T=*mdH{hM#8lnTyuG6cZ7uxOsdWA0 zdP0V)!yeEMhl3&-$Ie{$w=UY8B!;p`mbT5>U+8+DPP7`dQky)W3AiIJ>PXL4|EFpv*Zv`cz-JXN-OWx z9HpK2vk}0&MV{o3x>G3vI*O)5!_AKI{#rFPZHGQV)`oCRsD~*U^bQEB5*xSfMBKFd zWig9^=sG^TfUx?O;6eoMaDlTaj&kdx0S`x^lER%68XsP}d^U73b2#!0iF5DM?j8SE z_FB?pgwGxCFi`sJ)vSGr_IRABYdjP|_kHKjQ#!d)!09?ADSvzMs2cRD_vaP{T|m;# z+Dh3*1Ae&77PIlTYre%~qLSh9Uf&Iq(tE`(!n!7F3AF1EAJP;jFK=V&Ba%flWKB)~ zAq6%ho!{$b(U|+oBZnM)qlu#{n3<)}DUzJY4t58N(%=6$)n&Dp%eEJO{l$|kyZ@Xj zQAdp_a^`y_8H7&9A98$Z;+%|JX9{%Lxe_^X1&Hb6ZNl`8s-zothuz}^yEz;DfRY7F z6!O0B&9gdy<3MP$98B;gbU``iDQb8=rvN*YEZBfP#73e+EaZ>5qj`W(oAZWwo7nxDeT8YyY47x!KRLjeW5;89h>d#lm%oYTS&rT${gaSorNnukBHta(y9_1Ea;Z-gn& zw7m~m%g6xKAq;imvFSenentLJS9*850MsAO(M#X7jHfW*24~W;j`MZo0={qJbVpGt zY4al=qO77=Ymq)7=)oZGkfo;vE~|w{Nv3JM?J8*nk!MQ8{qLEmAaW=g3ueaOs-xo{aK4av>-xti z&H3w!iR13}M#gGo;CO`Ey*Lk62jJ6^-3!L7USINxS_WX}@DO`kjP4cQPo&9!psBLO zakU;u7T|-nL6*+|1g^$Htx(xc6(=UsoP`=cl)>OZ`og5=h3T(3eO0 zKq$_1y4|OZoGOEQ{V~klUAf0U7Iiu#t**!0lFxePKCDIktI7TB(YrG5ymVe&96It+ zjyoN4<9S8PGn#Gdb5Z3zAwG+7#jin=>F0C1@I}I*XLZz<#dJQEjw8_XWl}`byufC&kufxG=)k#wg?#&hge)CaQO>?>jDkkYx9JM ziAp8{^Vf`WK_wa2yOuE$s~P#MLq{HK4Bj0a{G#$3j&W{^gp!r z6qHe}yJ+z;fZF?%w4^)NIR84JL{3+|Reva>BKXPL`TjN^gSOm?SLT8bGSK9%gLU(+ zamK2M+=tHc`t|)#i;|6kr<-m1+M{p>->U+T%LTco*#G@)Y&;sEcje;Z1GV(>U($3zy_)0rha$ARE%ly zt@(t8_W3!6h;=b+Rm91#>Q`On^is%HBd?H=OWKu;HJ`nz=#oxNo~0Z3mtD+n{y_o_ zfHf1vs~iJ*a%Ph#fhe!{@vk1(&dev=1w!8p=KNUo1N!FsPg=gpUpL#4Za?#9?k|4I zOh~|E6Nz&N)?37|Cfm4DRy)2cI}O%R|PAlXHE z*By~9jCAcA{AwA0I!J(%?$_{uq47vw<7H&A>n>T#IrsE6jHf6o33&FzFlma$-G^55 zd%foZetv4Bv)HL+-lCB!UTT&8b1*u3@Nf4kI;k2<0rxf~+eLB10mJru-Nw0{J8$T3 zI?>;wu}CT^oAif`xL?9^0SzSBMR@bYizEngNCyisqRhsBlof=pwG##;z zet3U>qMg2eulkvnBCFs=j&kN&=iuZ~AaR;UAHoZl~GK0kr$?R~h$zee+*~ z@Lx0G|9%x5(KfI?DW;pm+{vGj;co96m_!>K8_i~D8dJyC z{_)~rlAPPd_=H=#_Y)_^&#S{EK5eeA0nB|Y$XR&aDIrliKUbvN)xt#ELw zXX9=F%A*UMejfSv%<3Q4!J{VLteghR_+Nzw;K@k;n?KgBN8{<}lzn}Tyyu%X2H7#q z5f+w?X*Vr=E${mIx_3-0#C}}uB;8Quil(BX=*r#;6c-m$g81lGrsuSXxm!guwKvw6 zWSH%J$7dJOiZxZ;TkJb_`5`Tc=^^TMh`;h*=U9sRs_$xdU0z`?e_ zAWie$mM`uV<6m5Vb}SqrhdmC&HzkYE_&IRyqtQWHa)DM{6De80V&KbxE7$9q5&`sV z$VSN{%&sG0v^OI=NjAQD<=5=b=c{f3f*jhSQMgPr{@Oi+MCOTeO044Ds6fR2$2e?6 zpQgQ>t%g7G3^Rk2VZ3Zec&WWvb++M20@kBT@@De$tG>cUM}0+;I%!2-F`3ynn%w+X z3G<=B=zVX$TqD zprIb)`n%3^GSA9YUdphAkh4urnvB-s4|bh+8FzQP$gWGgF`qE9#%o*^9|l!1Y4maP zUOXAWP}M+R6Y-4x)aQ8PqhyGli^+gTw$rE{Gas^gNKXiQH|SsH#c`QsS@g?^gbIAw z!Y2>ToQRSD9c0rhRXAxd-+FE{iOGMrC8E8d#Ll8*_~fh2}#;W%*1M+)Wj1o>T;SsCbwk zOx0IAG^QWQJMQ8k29!U8a5n~V4s-mQx3k9_6^_f7gsn&ZETn4-qYr*IkZ-|C7NGU$ zgKqEc76+rFkpAHv2naeuziE`5&p0$MC+_T*r?JVll-5&RLBtcN? zDbC~JY`d?uF4a>fz?jaP>%qw@ba2JonufYc^01%}>XJiYx6Z97@vZ42Yw?;tYCnvh z3Qt||mh`zT9QYpR{-j~~dmrK(&i_fiGu5ikIO9Z<>C5Aj=jb4ahJh=?YJ#Q7lP#p% z%=UG5#>9ZAn%)+rIw{A31v9hX%H1tNniVEXwv_-A8==v#-X) zC^sOFN%Cl?RCEUHAHUsXF2SfL4^Fe*?kz#^2e{hT{19@=U%JjHIQ&>Z@@B4!N}W{R zH$I)>E^(^X@^UM#ULu+LzUI1}I0Qv5Y0=~l-WMhAKtw=usknoZlT*T>$FETGq&$X) z$+24|%&V8!@vCztAXxHd+>C^1s@&~PRk@8YQIo?qZn?Yl)abSY8u@yy9_XoUrD+Xo zLVfj@(GN=!Q-cVRU1N~QtI^ZD2hF(+3zK7jgQTrAh3ekS5lJG5q!&>v;5AkrGhc4H z$lao}$0!iV#nrCs?>6E&9KqEZ!p`(o2QGY!M%2jj_d?CtOE8ekX9IIS& z&1B{hnELO#I#+&K3~et|sjt?P5^g%JS8Ewag*2>fE!nM>t45crHh;>gi7Ilz#6L5_ zMWgq9_5%(faMM*~wJWFSb_i!r{&wDvCnwIiCyet>6zU%fYCS<6+D-9^82JWT!{<~| z$-|_0D=4b;cq6IV&}b^96vpB)z9`$%{g_!>#aC|?78b98GzqRQm%cp{i#XU?<6&aL zrU; z7GGNHS#z}B7-c}CWbhh<6vO(^t}gqLAs9rO(UyaD4$?@Z08j5W(D2&wcM@v8Xf>=)Sj zA8BLjB?3JC78Pw1qLRx*S#y&@qOb<5Zi>3nOc38DZ`#m?Er--WwLZ($7$t&X$mEJm zMM-=Jduy2=z)}tgY$|Rhiy77-YMux1)P4i{hpp?E*c#OgFSWgVuaS{}Pr%FHswcb) z-E!G2Rx7~4vuXnj!K^~=wypJx+ub^pIz=TbkMcU7Z=PHtiyZ2scGe)+mS2mme>xz_ zC6Ni^6UT=9!Go&DGI|s;a@1May0Af{c0&UfR27q3=uBAS!xxz=HyYydnTv@5E(N9m zZkEvYJ^o-FEXFUp$@6Qkf=*En#NTo8lZXG&)xwyY*f{mnfOspD$slaTqU%B(>f}TM zzHsJQ;6t?t9rT^dUxOC+$iZjX8XK6ZbhzX9+$s7|yrxNJcM2sAL7=|hjMIyL3 z$7&Z?MY|Cc)0z@&$s40?Fd_7iu!< zE}iY?)E~I%bS!V>Q-5GbMrjn6Fx`J5xf4*%4hnw0FFKng3oCIw zeV3g-+l3!!YNk#`WtGBF28KeJVK-dl>pb_4tnB1(JD!#8FYFDxGu7Z(oX;tS&OC;c zu202y_s<<)FJrwL6S%!X5c-ewLUeSy{Sn3xUs{7GaW?ycEtgOX8tO~>e7tipL@j8B zKAZP?Ju+R%h_o6L(qBeP>-6atQcR=2!uEGK_C-S=Ecm&=EZBBpK*6Su^*P6-?+d=cAPw z1&XT&^oYY0=Yj<&677m(;fW#tk!H4>?7eN~de49A-NyS`JqH9!1o$i%<89gxt?4I9 z(+eS$vjyYT#T%S2SZwhLyppI{FGIu0_FWg7aqky-(^BG%0d6L8anaj-Eu?2xWP7_& z{s;?ByV8tK)_%t;_48EL6BGH|I_G{ntM1$?f=!^N^QSmQ*0lX8YpWp|ew}q0V3=Tb z2!E&eadba6ADk~Vu+wz~;qf$o>%C6N^hc(W%dj52$%`YhONv2WY(nhtcD*i%7*wdk z4L#nHUmO<9zRoD1e)_$J#mFCs@^iFr!x;R9qpN)2a!T7Bo-uUqw-nU;K(idGbam8} zN%!#$6B?h^Nb=SF zDW+mx6odW{-C^y7mDpj|k)wsa5LlF5Z@kJ39#v-zAES1Pp#Ee zPU1J$l~x+teA+Qv!I;@I zLW^30Segwo!7Bxrzp`eyn9Cf+R#U6D?(K9JKLBH2URZblD|@!m#-VGxglQ6nIk45 zZWEd3hc+2*GQ(}ftCV#4+jvp8xI_w%^BGbPXG5g>_ADQrppJmpPkp!M&~^mdx;PS5QIZWuP79H4 z>Z)b8a5igl#ce_3p?4hBde+&oa^i)J+AE(sv&EYn7|BV_1))0A<`n$6^hO>N8~q07 zgOeYyvjN%sRm_Ga4i?nVCRvVL+(Z&$b*5SFP>V5FElNlAbmk|;NfU>R=#WrnA9|;P zOH?^`SB~27&a$?F5$Bc0`k{R-OX()x^M?lst<$q8cSLni_BofQRM_MCO2;fK!;Ka3 zpu@S1i?xQ6Iy7!&70OcLB2V1qsFIG7Z~ByhLHH^IgL)R12z||(FDzz?V{dH&BWSQ> z*k4jjD_!i*JcukjST4m|d|GIoV{SXgONZBv5}xTKu9G(RW??clzE3d~y^2dxA(2VK zL{ae2jec~>kbU-sFL(zPPmgR${5Si|7<{TOZ&k4)iUlX)w=K>Y#R;w3HB>SVa2S2_ zjq#tOiy0?=JCk`coT&>99RAh3E2!)c3nL->#uIJ7E!08FMMYENeR6@QA1M{=uGbq> z@`QPZAG2>+kuJK_-mjN)F4>G;lg~S1lQAUZ8f?ajlYbX9Q9{&CCA9dF@SmVxJ;oLj zdW&k(kCNnWleeXruh+~U?}$@&OH<9A5gPZUnbPZ!6(R{k^iF~qC(hBi$Y)7BhQGFk zo9M&{kKQ)j4YX*b&CU-UyhmHMah!UGPM^XGHhFu`c70Usn(cTQbqvFI%mu6+igu29 zBDKgnX(eSUKYV$jM$KG2(#MDQ^zd4IsT=w!dPIz_^5^PZwj|*o6hq;saTxd57f=7r zKDK5i#jQb6%%vH>pxNd~%g`GT6?A!WH+F9Y(nr=^c*^@VaHFo-xU_zqP>My*`;3Ed z!0?Ad^k;HTZp)|41w>O}gRid7d~4}6w7AjgC^?tId}roaQ^jwJW~Jg~Zgg$uy}HK<^!oEpEa!4(*$Y1fo1u$R-&az&nVDj~Lb4xRBWbERzqx)b6$470ML+ZDBHs)TY&CbM#XO=>)@ zW@Z@k#nD56w#QfKg>Tfk`qfmfdi$!)Q*Bmmqbuj(a|dfhEKEPgoI1smjbM=TUxT+x zS{U0FcR>u#)e@c_ElkU&9DO`)%Cni}+gkC<48qjO& zET`XTKB{WkbF2?4YuyXX}!&10UwrIV&Xl7XFe}nPiN#u(XCBv4N&dPVn#819JXGnoi8|1fyVWEfwni#%tEz=X#4vx zHPK?1P8{59v6?ZfH0=c^M9RsIIqG&lV&AlQD|H_vJN9cG^kw%K1;9qX+V`mXfTRvq zzSmMX<|JbdiG?Y-uyeYaC|y~oDYH+`kHjeQ41RO6g9XTdn#b!P$*FC@lg!(hv?SpY zM4iHnW+(e>t6qUfnR;8TCT~`NTZYP1x=&{9HBp8shfg^*I){3R$neT_Xh)4$raw?` z5*tOJ%E*lHeq;QXJDpjxA&&l30%nrXOH5`J)8dXVg7w*o_QS#T4y%nPh42UY;YzD7 zizOQc`FqVSucd}1gvs7SV(_Tt?`8Py8R|dU6W0UReh=ktIgy~R{dA9du%j+b4YmE} z?jg<#|9rDkY8#7_tu(G(rzDONB?}v;s=fqohv;^hTF;d?JPG`7WrMV+=@-dq_3%F(eI zp5_|m8H64&Uw=Q>9aJWbmEoiQ{J|Cxoltaz3oak6SVA5&VUpDJxxL|j|5ZS;2=R+M z-{d}yuRx`)h&pV3r_jH($egn4ai~e#EmE;+1843!!|$MB_ormH8aOH>54*+Weioel z*TFpN4ZY>>?+b#^?~#I-nwpq}LtIiv zw~-!Qq2$A zH;sm2)>ZR56up%_yRSQpGn+1hB`d3Vn-VK?;~S5~SjEDk_zaKxFwB|Zwk9si_5F=M z%~fM`(oK(Yid;G&nD7X7I*Q%DqOa(DJFmuQf&f5qd+t5eyzwy(^CQAS)iEu&OilGJ zJj(S?TIU&3*78K5ABfw;C@P%GXO?{s$Egz)@*%*U1(LmllIxne1sCogK1iV6#v zBRNz4-m4;q4LVgf!1EExK{IU;WYrS(zW&Eq3(fB}=0k6aBzuqjq!bCQ77EJFRLV7a zJU`g3aC)SRDiMf{miTdpTS8dbInaIfe)bF=w=!bFB9^Kwfb`b(-VMjhMPQPaz#UcK zx3>$_vuk;xQJ${b>KCKe&Fum{Bfh00=LaVG4eS2A@my-!Yx9F?_H7xZQ1&_}p~!0o z0W3{U|3lnGKrru)u2CT4L>Y+` zrYH=`g2u|ht(V`F(K%lv1@SA)J9Gnr2YGZGOC|m}-n|k)ls05(*Am+s{=vELmdUW21aG50<_1S)?pOLJt2v9T8$~ELRdxJoFwv!nr zw%yB{gr<)kY@!4(9*z}2aE=a9?&|zKJ6l%1dNpR)P)9@421EZL^gl%Sd939Bq5l5= zM8yBEfAW88gZzIuf{RoX1D!aONp=aHXa;0DYIB2AkY?VJMU?wpi&x^ z>oU|4I5oNzK6OV&M+A=XO+spp2DOxR3@ps}MY9=@RvevKjpLBoXePC8tsb1LJ_MOC zt-}M)I|B7N^*x~{k8aSY?he{{D}Cwem{i!9@fE$Z*BQeo2T!B86Vjvwl$|zyrrEx% z6hL(2g?D8=vA6hx*$8aWZz=ck4SSo5nJNm?ORO>aM-NU7>dOTo@+%2*%X?n6n6 zaLbEPe(z*k9`b&UY0Y#OM-VWRa z5A{qdfC)YQ6fA8*0Izm~V3G8KR0)2{bp9gcV2^=eLj}BPI51{Nb3vm^4*j)(o{tV9 zakhA+roEl{uGM>7-zfc+)r<+&UVKWg`WHU9b$+<7?kEaUndOph@TyeeRQXEK|COn^~^w2e)$vE+FRvv> zsbzlh_Ri#*DA7=d@0E!h^$^qC!mW3frjR+CLRn)>a7^B9W(k-g6f754J1Z6?euj-P6{$i3M+9>_GJL2#}^9;sRRj7sas8>TvJ-E!%An_Kgh7XeO2? z=$&Vqz(&DtfLUy7kg(x=!kghTI~`?1^H4uo7}j!lBUl_+FpG~YE{$b-Aan-d_Hvc0 zRIF&hfUdPlj99Maevw3cJ$1!d*OB^jXhWamEzcI{tOW0Wo;dkRE5+Zv$6o^E>}kbT8UuoZlkW2td*uYavcOwM+hJp4`DMmO@}H9HhNgV zFiT}60(@g%o?;~B?bG)*!@S+)iIyc!*pbQ3v^CLD2@0dA2~Ez@eYFuWW47H;Xp-(y zo4iPv@5U=Mb=%qmX;Q(2=;5d&u2+usTG+{h?VTH~<3BsH*WqS=dUg|Csx-2dR~~?y zk@J5tl}aWKSNG$FWkjT{AKu;VjYx%OWGA;=HLR|pb$BI6Y4czX@`2#FuclL_Y=&2? zAP-tCxZyG>m}G{Mnlaeh|6e%y?1vwhC#D3&ZPM`KJfQ+UFC`9&@^|shEFjdzgdP$LA=Sc&cDzaQWbZQ;;SfGl&aVuXduTS{ zdx(YrH;Y@|gx}z4ZJFdq@b6@@GKRL&`;61j4mfS+dRI$o9I3!->Z@vptYLF=1Q8ov z31)rJI)64RkJ%(>R)6fpWxNZd@Ce32v~P}q@6k^_0BR#nxva!y%{e% ztt`YxmG+=Kp)dnCJCuzkczvs^IVfCqV2pgK;@4c$qgf^E=ywnjP^eQMf+238%p}a*(9RrU=NB$NQcM-9w)jzJ~_k1zlDmacO-~qADeHocEg;2K-Ii3qgh* zh**~jIjs5Aw@6{5Izs+r@optwDo(=sVSh33n0*f;LNFf{dPlc+ri8C^a@BY|!D`|V zMaQMA-nD(pYs-$BGK-sGWsO5gOJoYTYa_Fx%Qtw^mK<$tX`Y7Jlbe_KfIb5Dw?INL z0g8Oh#p*{IyjWd|g>IHlP$eJ%zDDc%r7m*cq2g(E4w~k*-`!r+LefD7YA98${9e2S zKb2rI9*riob#>)55APnfCqOIF8uZ7&z(4M_6j>9$a|gM8_<21rJGVP`8Y$Q4WRpGA zIG=DC)`dH6>?##=`X*Ntrs%q;t6WO$S3TO}6RAa64~%7NfDb^XI+U$>+G~G)fnlmR zIZ2|(@X))EYsnf5;<~>ddt@rG(G`e8ULtiRaMVG*V!&1y+k?NVg&~ikRQ;bfDp6@P zJaN(xk6#!Fxu5;4^8uE14yYSg*(&qh&^GhF%FT0*N$ZfiRa3Z$mQUfU=Eg%~n!s(v z^sF__{nM9Sddp0~m4$lBTl2xm71_d?5yZlquZlLNbv5#|1)k9c4S8?;9y4P$Q2C3E ze7(J>-OCP}31dYw(TI(jHF5K)f#e9b_uaGa7&LO9K2>93SvP4$YX05*tJB$l*)**H zQ6%*zQxU{ti1jFl6Rfx)Z^HN&_d05HpO537ovJ1^Bw$T#hIEc8;i(AET^UgU3t&Ts z`e9nkbf|j?Rai+STNt%I;B4Fr?G`Q;VUXQN@^TxSVCKL@0PadC}cGFH-5E{K65<=C+fw4UHOAaSKFK;-`l!Zn{3H zJ+yvSE|laS2j>s|61F`!CF~Wx)i(v9EPQ-?`W|HW?mv6U)jTrVpC|6Syh7~GPJWuZ z7LSlC543L-P|baM4nh1hl#4Ggm289s%7BH`ZR_ZwoE7Ht6`1pX6)*Va*vVAHJ^zE) zJ)|sqXuOZOGgDmZ?6S`Ini#?l{M6AlHcX}pTMi_#J+LgntcCF5lwh8O62o|%q;HWt z7as7ARgqAL9h3u!={k$cQ+S{`F)pB5*~L~%9q0XonlN51M%!Jh27bPNzZIWC1FOpc z*jdKlC;$9$uUqqiiBL4`-sORD$nPwHl5=F?cov2|t88zV+kPA&897tcEp?h#TQt;IAVCY!$%e>gFZ}a|uOBwGGYYL(!gvE(%mX&Al zGeeb%XY+PK#EHX#j>@R>l;K^j!}YR&*(!B=Y{pZa(wUE>@m)45zP|a7`&!-tSE=)r zNef?M&T4k*q^7b$fQJA6qX-V3*hoH34fR{u7VCazbV|DLLTNeMt%mHvivpz0L~^%K zNE{sPU*fV_T_T@;_ZsFH7ow}lb9h~V-_-lzY?##}T{|?Z1ILtfE+2X2<79uj7`gwh zmlYwkvYVyv)azG|!TcVb>wClFb+oZBZncTi=AHcFxxW=4bS8lh>c5VkZ0p(`TaFUz zUt7!WQ!(4PArF7xKK`QyQsO-MQMGq@d?8$hU4<4FB_`{Ar+s_ox`vlaB3=WknA!at zFWt`(+5zZ}W$$t?64-zaa*ajT=XV*CuL`#*=8zmuziVw`Ip@+qqn2Y66soNLqgYJC#KlP$v= zZ_40%_6;fxE^RFggf8?5naz~nR}`kNRc}{ME8Y@;=QhZ{5-V_jgzG_Th?i zuG)js?Hj3mK-(On&WkiQ@?|pm5DmSiwgdeBOw`yTL_64;K@LV=Yml2C-EU^%dkLhp z-pkEm>0}PsOH_x}8ts?*m9FDIHlo5Smd6&DWNng#)pZ3*A@HsKGsQm`6vk@wK$ze%bv%V2XZ9Z>`U3vo1ZWj~d{8*gs!|%HAH)+G=Hg zb=>;Pj5W|u)+d_YOY#wRWq7AiJl|$ES7!`G^DXxMq?&an+8I|{MM^#74?fAY#^;;P z@`7RF{G`YWC|f;MaB#IF@0L-AxP(*5 zB&tMJ3%iy{BeKTUW5-3&TRSQZ8iSbswT4T7^@{Fy^ZNM#7jw+)m+a;7rS=VMA%f(> zI%ZHkmF>C_ybv+0!5-Jy2IR0H*6 zUhpN1{^751a0zWJ>TBBHkRBGL@o9P$+nIs|z#4*4TxQ#9(8XLodhunK(S7fjLjVJG zm(Ki(8oL^iNtUGvJV%M=@ld$zW|5lP{zh~EsKBr$Uh(dl#u@(4oGBy45vD_%K7MXH z(c(x<&EA-*h7Yp1oMPBX*go{pTT5d6jz0GW*Z$LaW8q_nVFo}ZkeCPCKZlC88nC6@ zQ!*3&trN}5fmOK_Ol3TW^Y*85WjKZEv;D1EVsBO752onN5gU#^TeGaYKQochnfEJ5 z?uvi1wV!X3FWYp8E@K-WMNzw)mM&=MMI-|&Z`?_U93=_UW6f~ixu1=Y&sK7_Bdo?S zIf{T330miKs2q3o%Cl2#;nHP|{-lhM@Jlj=Ek58NKLPk@{$QG4j%zZ&Mw)|bER3+t zaf+9hl10qg`hl$}zkU`GFr>opC!~BUIu_)9Q;lh#9adNWEH|w86v0*rH;Rl8xf)2< z&V=BNPtPXw+bGKn$uwcmIrXTy2IE&Xj%SMxwQo~z&CKj$dVR!%r}uYMTTseo%)8;a z6nlbxGE*@()rRLY5bdLYi*NCwQzs90M(E^)Nw zyGQ95k zmah&Eq6Fi(rkD#I{QmNih+`|kN;)InlE8w4ohc^8cCMlAUzuke4FP^2mSlV-kMd_{ zQlIDXMD^{!rKnNTr|t-`phsx)R;2ih6mt7Yx=|{ET%(~G=0-(8u&PHPY%E;KW5v|t zV}|NTj0ctpbI6DLngO7@)vCD=0~E<_e=15(QG3eD?`S4-6gajMq=)a&aL0~2W zo#2PoEa0xXSTd`Cu)0>~a^w;zgl+hDN+GLT^{+(&R1kBBbn4w}`HQm{X<}(wVXqLX z68^hxPn7Wx7Cas` z-Ue2vjNvW_YlaY zfT&TfDjJAg=KBJQ$K`1iM~%P5=cGI=eGNzgg=y+D{vB_KkP{P>)9l}A$mI_NLNCa^ zIA(sC&0K=-c(USG%>$o-_~%Jbknw*)h#T(4H|D$2H{=k)X8e4Rhq*BO42rkM) zi?zOcUl!7JX4-HY=_>VsxahG(Ef^nhk}?WVN~HX~bFXZ#$f0B2Vht}e=jw>ju;tnA zrO=q68-aiF2npJFLWMU-%4zG?^9p2z859U09J*cbheiT_7B%ze%Ih{d z2-O_2X?M$)$FnaUsw09d=5gG^E#HU>A6H#w2A=u+c%JIcIRm#_O_G%w+tlK_1(xg{ z;I_S5){8aN0dk&Qnld(fZ8?>=k-vyu^AFcf3YOIp528)G%Z_tT+ax>{ryT!i8xG)% zY6w#5LAU?0EA@UuHC8+z{{2#0V_^A^cMKona?-R=i^ zO0naa>f7hU1T8~@fjJ3ZpM54^W2C)mI2BxGOY+eAk`16tmx{YVm7~lV?WWq&d2v`)TZBhS*srPO zy!m^DfK73MSzW<+oD$M=RPwJvsVNg8Itr*+EAoKr(Cu(Yq21% z&=hL_1_V*@F#ws0&%_oxvWzNi$lppVQ&Bo={rbLnCg6tP(l&u-s5F8$f@{12z+jo~iv<-y6TF|<80-G;`07pm#J ze z^hWp$k+z;~gFNa0$T)D!ZMC&;Mm*sfD)aP!FE?+{()s~VB)lk1 z%Ec*F8iu{0zel?uOvf z)3n}IVTE!1dRp?i9i6`2IzBzyn@e=+(7#%Zw|w386tT7L5%OkP(6PYze|j7Z{WUxE zvfrlcyscRg2RUWL@1BS@t!ex|Wrj0J?vqN{FGNcLO|K(Hre5VO^6o9Zj$fV`;yG$U z8&^Gb!m5SpOEnH^K0s;`s7atEf!Z@bY7(ePpe6x$$@lkJ7&?Ju=%NWhHOhhCR4*F; zKBoO|m(W}62@sTbi0XIZ`Dw49Ai?x-gLJmjC)cVynne#PKY~K_<#a(&Hb|`ti?g${ zPq1tTn~gtvb~2PSVqLv#>*|_5P@8pbv{6WJT2ok;1d<)$o9+-6M#wzV`uyhxD;zg% zVRC>*qwR7s#sox0j$T=Bl%KJ(D3M6y>;_hhV1u#461nlEs$=_UHAfw$dHTK zgY`Lba?WvN7WjF$*%L4ARn%z0KBo~BOS1dU_?5-c0^bA&W@&CH;f$!GY&fyvsY&(H zIK9|2r;*3geYu1AxVN`A$91U$oP#&giYc4xz{a1^vsL(%@Q+Kma>*r_Yl>*>fyXsd z!q=kk`WyCj1AGFU@{znP{Z*W>vhLc}trgPEr~@_*4h!|$GL~nW5FQep*kNUWHw}$> zosxjZ&!Z5Ewi;TPm1N1|lFRbs8+OQ57h}v}6soDWiYQ-NGJHmEZ0p<0l3t{$bl`bt$S^4{e}cp5f-@(ob%#wsWiTS z9siG!(%XJCG`&5$VC|OLkZNdm0Gy%~_;F}xh++}M2(C!<#6_0}(!s!4<~CRaK6xd+ zi=XJ6T9HdphY$a_Jd>Hq^EapZjZF@`(Q4Av*@=dBuZO{!{LNVy@z94`k&X8%Ql`EL zaZ+w{ducm82rqhK2A!c5QB9TZ&`{O=WXDF+>b-P<*ErwfB z2uo0hgP;UrvKkv3gK#94#D|56O-V@s4bBhp-tl<66@{EkCYza=iMS^l{NFHIOywaJuhl14E2!~?D zl%P-=hfAE7oU)26xO2zAz<@^VE3(AC)ZGIyO)1D2kV{PWqb1?-O`%GFn{>Y7w$jeV zCZWG3vr9Cb*j1K2aD=9d0Z}wjIFySFEtJJqD_-_{-7t3an}7H*c(X<_czjj$7!1k1 zs+93I+Su6GMYB71?l`7S4^7BCO;aECdljaFY`>|pCGYK@9c!&a`N1iT_Z;^Ur>>gi z?@r$obttCe$uV=Les!@1pF18}m^ju#{bFWL@je%#=TAdtBi?9!8m<`4@8OcC;6skxS_%@Y`j+GCM&*Mj3CPWf zf;0jjpP=T__VEK0TYGz|Uz8Wv2yA7iMAO}>Xr+JQmlvi| zF+YPDkICv#Z6B6*A+SgYb`ZNTQWy|r0m>GhiPGyP12p{y2M1ql1#{tq%9v)j${7Bm zh=>S77mZ0=3!JH`>Q6MQ`|G!=GMIc-w<{|v4PVJys6LU_9g1wjqad4;su)NS)^jqM z9^!*#vU^=nTbL;(Ys)Us|cZ<-U9OF2Z`l z=^7Uq1g#18I`|WM-8x-_7Yz-jazWK`di#hrynjm>(gz?RrpJ{$39YJJ@EYmHCnYh# zh!~vF!{n@zquhU+vGEf$Tnp9G)wNiwW6cXiWUQq9=a$(W|SM@WW3Cb(9i2m;!5!^C-5k+Oyipi9mN4r>ycW8W%nHtP9-KL&Jikt zO$`hx`bGnm88%Md>{9f*t4%M(601cTfzsT%o|XYcOro{TdwTumk>F6SpY zff`GvAN&r02kCJ^I)NdMGc+=CCd_^n{<7w_Hx+n`TyLtlhbkEp54DuC>l+ ziZy5Qssmoe_UyB_PhOfGJ4L>z1+cvhXf-Dhaw41Z84N}bcM(Ah2R^a)h#$TE3Yn}h zbouN)!~Xcl_wHrwJHf>oZZtI9_weC$FqohUn{YBNFdMt+jmv(e41UwAgdbK7^d>ea z`@nK-mW~d>7{hz}_HE;RXViVC_M1Z0un0nlzSJ6$Z4f=UiojYp8TQ>udvkO1SA(dS z&6_tjxymOVcqrwTZ$*OgjOD5N45b2Jyg@m13$-QPfte4a_uhfj#H6IzXZ5CcMd`uw z!DWH+FW0Q+#69@Ich^syzdUCL9Jy?~9VmYvhSnavEp0LrK{!3W5pEX@yc|&STubcv z#p&TUWEjfV*S>jxUkg~pNu3!;gR@JI4#MUBKjM}w}+N-Fjz4zW* zzPo+e=X>9O-iY7t64!m-*F3M|JkIk-$cyLC?%aHE69fX?k(ZN(gFrZfAP|8O{y)Gc zbM8d`AkeiZ=34R=N=hII@DV-;_ZkRv9VlJmn-P7Zzj%!ueGP z_%**q@?RPF69kg9Gjp`JGJ6Dl!6nJg&Bw{h$;ZygDZmcp0)cR&uK&IX8Bi}LCi-_7 zhhK;Xl=bL$nGyKBHj4On84oDW#Nhw$n{#t=^9geTZ|+CjJildIXY}mQ-_3*_d?mrfPr7v6HCJ z`_E$#|7W)lGRA0#8q!={H-7k)c8u=E2U6w;8q@@%$Mb40`IK%(H>6kRBAmS>_DfrR z{%C386k~o=#!qSZ2KmOLkW!KDNZfdZs0^*A_*uS&OV^DkYRjZ>}S_V;Z6g zBcR*D6M(X`6GH`I1nnv?q5Q9TPWN&t*fn-V`_b;lvCD6lg(BuX(w5yLmT!Daqcwjk z-SAjN9AfBRpH}xpSO3>i0KM5YeaC;F?(xNJJ1>E})WfWfM?E&13@VV2Jfx6YP#{^%++p(+iPp!;3z=~F7ZI$WAL+c9hgR&4$#D63#Dgck8ac!p&x-EQHZ8_bku zM?A8Qyk|WD9at6;ee{O!#UcsR?R%7D&5JB`awCd@CB;QkwT|yl4 zUu{T8ndqgzRH83$to}A+LNDRxLzPmt8#a83{W&C0V?J$QQSMcKdU(bGoWf%I1;q@L`q%AGgX$1#ciHsg!3oBqEHCrDA_QeYJE0-Bhij9gCBe~^&z zQ$A1ARZ@eXr@;Tu6!j}@mEBjFy5jNB^>}=EL8#66=)cSFN=+$x@#Pa0NAK<3cT}Sb z{m%KQ@(~(GL*vg{leY>G7@c~jRR_JUKGDU1#)1F$AJY@rxVPIdTb8bKZ|)gEv$(H) z5d2@38pNr6$0taMKs^FU>pm1wz^z^Sx4BF$y!p2;F&~p%&En*v)rr)8RW~A0ov`%U zUX{3^EyMnL&y4&}ug&VVKE>S{p3b$x)kb0WVjrXbjMu_)AKAODF+6JSqyp|oL=#B` z8IfT>0s;hW`Byi`+5W3GKbbp6Bixp%UI#n!(iqUCAKGfP?-OvXSXeyPE*u=MQva_r zt2b!AWA1=WrKOY-{Gn5(aqh&z{HnV8S6O8cz}|Nn8Fwq0gG1#Z*!>tHH= z7S&L6PLL{^fG%1{s29m0BrKeDsVe@r8(9LlrJ++Mi6y39YxURRU5Cozs|ERkNs89* z-m2yusHk9Aaf_x5RwwgP{|+c5;fHoBry30GIp53bcd4svnkg;}Vc~|OhVrDKH8$3@ zHrDv2gIubDe;-1|CBJ-)N9)Obk;f(51LbI8YZb1>V;EkRZFHWwFSe#3TCiGo8&q!uxf z7^5xYvM=>(!a+=gF!26C7~BrV!Ga1PmQB>un8jyyq-S;vV4$a)cv+M?Sw7sbELBnz z|2lv)L{1R;jV{7;tCjk`dBBSdv19X3Zo6tcncoN(oLg7%^^> zsxB0KE18RdSFA-}K5e_KlAAs>EO|^D_m7eP2IbMZg+YiM!@b@0d28+{+ za@!mgv^RXbbtlf%b!6C0O+(1b6U>-mKub-5-0gT5pK=Pknf-P$k77um9SAGUrUJuX z-QcZzvm$_8@-B^fbYx|Y+1)~?7l z2~D^pn&Q&~orByt4oD)cJB-f-E@%@*zDZfv4F;<}6VJfb< zj@@Tnu|t)1(fI=iq%4Ql%%Kfz6XM9h@6z|rVRP&Cnw(BTQ4SZ&d7-JH>Rzd>tL%-srB(W87jf#} z4{rhOox$YV=h|CauWbN7YilbTD{E_|hd*z7z8iSS8%QYyg@)0!{rvf}Be+9Xf9TrH zqI*3_Lfx9ExcK;!{M^~oOv0aEx3TtPcu%mW6!>&-jS@3Us*H>b3ii*#0x#kq+%}a= zkEIJoy72^3Bn%JwYAerf7@%*-2dAH|d_^=T{OBm#ppZ!C_WAm+p}oj2sN2{$E%Wd| zj*pGYI(nN)FBE8(A)n~Pq##6_)N89Jz1)y`th>f9c5^_~#WC26TZ&|{Bh!VL^*bsm zH$KR8^epf_D0W=yO96Wv``8%M6%SC7l34i6-Ws@dt_m~Mr79lal>AN^Zg$h0-1+h! zdv+u`Cnu+WYWcMwPHS*c^t^{b=D92Z8}py67WUjq?g6`>b}R%5MahcEGt zo;{PXpZGlRid*?54UVMy@}*m7=*@QRK47{&;p`7YkU-K->lh0II zprdQauG5%rE;dS?osKQR8wUfK5ncIdrtKnVw7O0q7o9O?-Y{7E%M0F9_sq#iMsFQefxqM3mc%_9eN{PDGnT!?gdQFno*W(@Uw5o-dl3Oc-2`3)cL@jy ztE6@2Oy+Ojc-Ll_#mfY zuOeY3Ap{-Ry?ECB!LQnV)&D@CnG$9cR;^c5Fgj{@xu-d7UD0oY58})dO6^;Uw?Gd= zf?IqB+MMbRI1mzzyFw0Y-?qePE8NNnPwk}LrM2AMwO%HSzOu8ox3{&itkNG8))MiT7Vit}kkb?Xo zU^T1dsS(c-=YjLI%gX8+lBl`Sygx>k^*f963axBy7uD-V%_2U0=JDDKa!wtSXEgY$(zRMI`^TKH>+5YnEbUB%| zYx$Y<(zn(iCdS^Q=ioa?>;=?DB|0;+1rdXA><`RCs52c4l(u+ZL3=+5h}AcI66cU8 z&aTX^C{#zm-zQ0tl9E{VC)tLShn1ORLPjmhh6R2^=6fq-wZ7zyD2suGl~f*8en7IP ziTPC)6=7DL&$6^CbZ96j8ecYLR68vNCQ12-TTOPjxVTjC3P_ai&j#-V=db10oYkBK zo}o2w3D*iQYGf|OFU`fw5!`{0z*d`aKeS=I4b}Bs&U(OxBlsXA$jbV9cYT7_?qF+Q z(Q_4Q>o_sOhlP=BRxXq_CmSu* zBvEaNAw^|4*0bOhf;m^l+Ap(~dh1wOeR~H^7qpxa@H^sddqDHQUET7jO z_9e4!>s6di^)@v%ndS~t!iwy3vBSk!CpFE}wOHlebP>PX!?n>7eG#fT$~5ARx#-#t zL{P9guqWa|Gfhu1hGrSvi;lvn&vW+A4nsB2!**31x}`n#eu;NA^i?+kb6}^UGOO%+G|wTiyRe~M#+-ljumJ}CW+=5>tZ9I~r1fK-9KOBe zEIjRlO$}WqR~Eern8;_cjO#1v!(Q&wvO`riTmn(7@!BF$HuH8!&PKM)ab!h_Ulg7Tk_9mS;#kzFwM}mi4ll(MLeGXDYX1SZ=lSF zva4Axa~NH~i-_bBr)N&SzJ^}4KbRKc)P;*RWqVSGJT7aN!{p=DnQUI%pIzQo!0w=$ z3TtR+X#BjdA`J{*vCs&4p6HBL*!x`SX4+OHe2HO3u!Nc~np^gzZLMv=(ZjRGv(eG< zGcz;5IxBHu2PUSzzJ79Y5k!qn9@@87H`vk`Ef9Mj!zd&9DRTF{#70c>c{NsjnT&TwZx5!?Bw{%e; z&_5{^!(&qe?4cPth5RdbbP8QNS~gs33)_KF)gAw33P~TRO<`9qmG62#v6l^a_NvZp zXs}hG{RKh;tzTs^S;M#fJVm&~a@)>|%-7yM7XezgnW2-G%uxornz;3Md1gq2N%Q;aAf!4AS;JH5`GgE zz*XNwL_s=kTQ)pA+@*~wYS=myF!b9~P#%n)9Hka>Eyyf;2aiyO>3rJ{VMnTxeJI3S zELp(h)ZH|VZPqt-cCJV%*Ix@h=i?=U2^v(`ZPhI*`^Y51af05d=CQQr-3b&)J73+! zp3ei*U0gsyLObFuv_0lUtF_cuQdKo-Z4GQfR)z*pohL!a7Jr9>9B_mrie zPvUd$tPAw?rmd6jP@1~d>JtStWh%Ymr|RF=0nh})inB0>LBq-J+sO4bYpUc2zb=r}w)B6B-wJR0uVUMfP*Kz~g8llDIGYEaXGK?MZDo}ZWZaCXThoqML4}8dI4A_c;XqpC0u{8Z zv(Bmg-Dp`EiYghf{*g!C&Z~PetCN@M8@dgzJlwVXpn_gkuZ#!Oq4mUq5R?FDaw2?1}vDlo0_>Kgb4<6ww>^OpBQU3K2EZADMA$o=JO$p}gF@^p#CC(4$6snOzo0Ynu#m*4w>DA=?f zUltCGj-HNw>IaNa$idcdvp*}YW@%aJqEl^6je+mx;svWmKonbYrJYuzZey#SPLvrqGks@sCTpf=@cuTJb7+jVII0zx52r( zR4SDvw3@=n)YK$4Hm1HbT&K{W+-P998GYx@VFrt#O6vm1x40aTQf~c32qd-lW>r+dl`AGs_0)4ktJ+6e?wqOMX2B~Cg@8M_y%!er+w z3&$x<(|ui^j;X%T`gj}SB{9W{B7=53^AcBtDZ-!A12f;tw6DaxCFryjmI601F|l{< z7vo3NjI*JHXmKPdMJt2g)>Y$#G~x+F=|-HCSzWKGN5;p!R(6^;$6ar0mp;NDbSBPV zfpK_iZAP!JZCTsfe2Dze$f$`2dP4xr-|M*_A#K@hpTB<|X4Q-=i~`Cn&j_n3D`d4Z z;yLuU&>sg!MwlDZV#VBE!;Hi9>%4crb&|F+%CzuqCIE;Y4G7aWTh^uBIZ>5Qpzk_r!BYU`MSSbH+6 z2UNi(Z@Tj1&`5UecsE844hj2Nf0=h9n%ZBC1}yO;V$a_2@$sodOga0I*G@hMFA9>} zdyqf0rsw~`9ius*X~2w-n^&jKc$ybTG-zCvZkL-AuxEWp;pXFmnRM%v8GZ18{c^Rx z@cnxq+f5(at@{fL1>D=K#WdJP3BUx)YqxS++MQLNv+XZ+<|x+`aG&~j{S@~r1xAEp z-}@>s3=e?lG4lZ<)u<6zTryt;A7HH0VuD6SMyj51O`ZU!injM6vn!|@*x$Sbk2|vb;Re-I{_yFbe8U~N-E1MD{A!E zt$fLSzO%i2P8Yz-&wn%H4L~7swjLZD{lE-keyANE9RRPelBl#a;2>zrmPK|C4~euv zZ+N*cw*W0#Tr>}e+OJ;b9^^rMNY?{@*_%xxM5EDmIuS#wJ>88dNIxMiF01A1A~`6f z*lA(Mjo=hGTy^N-)amD9h;kqd>{eK>P<#RRjO#=GM56 z5c*}s*n6Q{6iZL29oggxWf=%RYv%o+u0Pd@Y9q>YcC)L{(Pu|`cV|tOSL|*Vzks4j z4m~SmYcQQ>!a)GRPr{pYTc+v}Qz)=|FwGeam9Ah4UPFhfJJ|(>)8i9ryPekzGL6Gt zbkQ&OBsTaYn_r0*cPSSAnvR?I*O!%<{H_8;HAla$4YxqV*&8Y=Wv9xu>Xsiobn0vo z@!fNGQYbqRW-x6_d9uB&)+S#(@=RKq@*vPo*G<7`A250Gavw%4J7!=15cqL?aHQtR z)D*?Y$T%YKW8GP}xYDZaXPiH4uaZ(gRMbpVaBy(bbuXs7riw%pvB@JpFbTb%AaPx@ zujQNqOyz_@U(FVrg==jm2agS#0!tM8JXBq4>&G!{p&5Yh$&V9xnk)%hEh^qT8*LP0 zcG2*=>}_ms`<9K$4#_xKTQ5!%bulT&)lgTzS{uPuTO5wjjJv*ob$4}7d7s}|Eqvj$ z0$jT{D`6{@O=d{GB|zQY8N1@HQt1X>HlgXPIXn!%vqxs663+r#RT?RbjQpUv3qj7% zQwybg*^Le^LNe$Bf-@22d^knWoGU0IZUcm1WoY{8AL_zIu3OzjcP;!0uB3sEVvr;$ro< z-}m_3zTwj1tw})7OB&Gw4+Vwp2t3z|S>;Bgg)zpuVtV3`jrQ)f)CXX5cL0X(*%aTU zXt5;Mjoh5SPD`pB+XXlsD5|a5ve4022Bl`JA+gN(#F1%&W0(PPHoo4i*9(iwadF69 zd3mV$Vjat^_JK-+^UfOKyzs?{pMtR(-IU#aSGdq%gt}s9CjnZ61X@=bT3Dj;T9{^Y zGk~ajLdXEzIy?e6@cY?6$`fR6y`yIU_xE2ORrO={rfn?wHz=&M2b=uRU1F&id6QsVN&p?lu=lkwm~6|(+R2~Aa1 zwosGLbnX^QJs}2iDntQ*d*6ME+%I0Js;D?RI`W*Ht8yy`-pDw85uYWs7cXACe5r-m zC=k+iA|WNQFQ1B#z+LsPd^MFnY#m800@v5)WA?IxIl{C(Mu(gKF)VB(0CA223aL>h2DrfSGORSB+_F?vV>MX)RmDrZHPP` z_GobHOHAisFb(v^>}W4;Rk&#aFLg~~`X$58?(W7XpXoRm#3^Y`nMHRbY}hf0dz^sP36Gsc)aL+}r!JgaKmt6ee^y(O9{#Oce`bX>VoM z&)`dTnKd4I_*3I#usb5+E>!NTMI4w?&F<_}HAdVIF3n!dGJU+;aCRoVT9|Tr3z04n zqJdUYlBbd9lhxgeTBBN9oPNK2>a|_%_SiD~Eer)yQ0neWayskD!&G7vJdgk+Mcr4E zR@vCtc*4O!b!FF(kx^G$t83uf08kw8DaJe@MiH;)Fvn2BmNy9bh*Uug26K;?xWsHA zCMqh5p*><@DQ$aY6G&Wo2c3{mn$494E(n1$rf=X!QDzL{&C6wojivxjm_6 z0CRQrugc^Mu^D_xfG2s;35bgu&j*GBKu@e*%s?UOAJEqYZXTzlrEp#Gv3)waZ<>ap zor|xgzL;AqDW)UjZ=euCuHtoTed-Mm(Wm(SJ8k3k9kJ~ey?qZw#}a{PX!V2>N5cg@ z-8Y~0O%D+p4NME6_!BlN$o4}fH08k=^VMufq^qCv?w$-(8j9aetnxVEbvKetyYwZ2 z@y12Eui@yZJj=lDMe1&d!TV`mG!Zmo>G$k-8o`84hnAD}_XtdB$VXTSsqwozz9;q8 zX;2B-+s%(U-LdR*FCq!nHqXZ`=w}!Bn+p&}?0aRl?AY&7NWq$ZvLY23v5bC@j;M3< z^UEoAvDtng+BO-Kk(se<(a*-tZVga}FLNavH##D0MFb<9s`UWRJ(0)m>e$HMzPNi4 zaPBi$9tyc;efpF}L}Gn6HJ0z0kj=u0eqZCo9xI1DnwJFHmoAY5&#SSW%-m#brL?iJ zKfjoW2=67 z%BgyJVVl*5k%7yO><2!I<-94SbCk2KAqqm@=PVS@L%5`i|SU(>wd30~Ur zePhJ!FPT(K=m1K8+OgB`G~L@QU^XjT8x$fbtgRej1<*_EO~b&W;6z!w5I3gBN##1x zT;RcuzC+ImkxTJv8zjTtr z(bGtTOPZ^tHyS_b&^~ExZxCGI)tKkak5Par^ev~w8c^L1tUzPV>ckCVVq=g`3~I2k zK4M~Gt&FXVC`KM`i>-hW${aCgC7w@r9R^kvyFWZov&{;9E$tR)(tIAR9{M# zbw26UE)acrB5t(nunU+g|3~;4GfO1WDx%IOQA4Y9u`zH@FYcCR0=g7A>E=7>>aPy( z*rG=IiRSJ+~%NX;G5QKvA;ij4P@lM;#_0dcz&6V-81yzmbr;K7~S^8%BtQB z$JoZe#U&0-@o4Kg?5BK2&Y~}pfWbJn9fjQC%Ku`ZqG7;3>1o(kt2h09r?=RT=Lfa$ zSONFX(_6pTyk)`s;kE6vLCw?5ARy=AZRt7<4LJ>stxvru%A$~e_+{we`eMPLhR&F_ z`mly8oAp#(7|nRxJX{+2K{XGbZqW0n)xLg6Uvqh7BjI!%#W6Sx2z}mv zs%^f86IbGM1#H+Vy9VV4@^FXxj0v8bSjQ<;VBnd(&;0n_%Fe(8%T5Y*{Vz+}m8~RJ z)uy8~rs%epjNh1_7}nI))O4*nYiMewiut*AW-xBjYy#k7X|YbBB}EY6PTq+;o`Iya>q;f{{* zQfdxh;QZE81-eMrFrI+_3*ZT;zZ9m(zzg*VD{BjYHqXtq3c4mb00}It#tu?`0-`>^ zkT#q(JiA9lMfLFE?0#BR(l>cDGy76$YI zM`dMe>ngW)9K!9vCfCNo7@(ptHicpSvLz2|IBE(CE6J^P8myAwe1tkUdWh|GQu6Q! zN3s*Qannx7;}dkt37{VDTl4KscpOz!@EO)jXu#(-*5~mFLPHe2X5OBtyQQ7(Dqpu| z>j3FUoAk6{Ph%OG86_^`a@eA`;-~@K2DTJ_7^xEHeX+1BtGu0!K>Rp$TAp6%2q7Y+ zDRb_G7izGEnn?LvHnre+q(w%AHq5v2V5UpFWt`P``}YAB$okbwA{j0@igNb>lj(?0 zNNIo!p7`tljZM}-*Soc};kW91zM{Ki{0Y!!z=1O^GM1y9?7JKqrVMi^NTZ^(yMd^0=r_ufesye678~?4!|^ji?$yUvDiNt}IdbJj* zb=qorS>7W6rTYWJ%O`MJXQpjwnX|_c!A4be;*q8o2a8LH`towt1S$u_T$)k0?u6d~ zLKlZ!!%Xu;nMy#IY%LBAI7~iLm+uuQ0LTy!_5KzGBh%yO-vV#~qCA|IeC8AFpMR(Q z07H!(9td1e-zA^}g3b#%@>{JF0D=UFitFh#9knqdm?{1xndobv>@*r-KC067{P8;kb4xwz=F zK^6pI;Hp^#L+zL{PGLd8KFU%iF0jZTy*~Z)7(EFTT==sQI~H{5^BTy|fzHjN8cg6e zGN}E#!qt&m4t5hcB7X5*N3Dl)NH=59?Ny{VOa^68tm?sO+2oer(vRt#I)S_$opzHO)VnK0um)b$#v-EN$B+0kF$;slD(YYam4~;5yd$;+4(KMGtW%;p~EDf%=CCz)AkaqCUb0W&)@n&XEp8@-BBH zefQq^oi;qeXOQ@?d`gR5VHUTtXjFoC0bx+UJvaAo+Rb1Ts8=A9DFLz^da8MVVAGWA z^mTwoIud?rkZw@&jzlIhJNoz1 z-mc2+(-#G3M(WPc;2s;h>;PxM4Ka4jU>&6!eb+5u@*#!}c%%V)m$V8(UlE9Jd6SK$ z;$4HTg$4C>DMW6T+&*e*XMHpT=yTQ36=wr4?7OsVi>}Vb=E9BZ{2}kUq`j{mhxSju zNnCZ^o@Dz)wnk?LS(^1E2w0{m!{YgP`B|9R$DOycbqDu@=Dz^h0V0|O-q@Dojk{h} zR-FKil*q&Fw6vTe>H`-Ne@sWmW$7Csn+g7+^LkS!Z_=1KU;;pXdaovC$d+}jE5_`q z&KtCb3$2=nWK^ufVvI~oKyR9E-;fHWGly~zlaRy^$8dc@J_?`=Z?hNO@14HrFMj6R zC6IQSt-OT2oq~Yt!8cl3>VU`XEovIZ2vD%;UAzx!d_A;X`avNSd+yd4Z9psT_;SEs zMyk>$Rm4xj*EYminFxSAjz<%THs&KNC}2|qbc{MAj!ci{F5a^|IXNI1K?6;WBUx*O zMyMY=;6rWgLhh=3{E^CDxAY{NI)^V2HjVwtZEx4p{Jx2cYtXo8YO3LgKTrJ~JU=ot zX?LdY+b|k03voQfadAEkp8dz{;pff=YD`=E?UW*3McDnEl#i7)**YF(s;Yi?pB>_# zj34icpB@4W|J1vyAbM#15J1_FnRE0S4F)h%N2j0qhjMbLq{5Q7CJ!zQub$9WTD4?H z%@9cv-F+zj6EoFDsUR<(3eZKewlHzBhYwXWHP`n|80as>7=Z-xuy7sJU4pw@$vt$k znL33Jby>@G3h#0~*mU)hdmSv%h)#;;GCi-P*{(Z2lDi88D1wwdwQ!yTC-4Rku=j^J zt@VHx_2+;Df`?uUCDG2PG;!M+#zFeS9s5_--lrAFboUE_#qy^aEWUfI%t-d*{&&J` zwl$(Zd>6D)4J8iK?dMrfOI`LcpTED5bS_4k@IC-P6Ot_`)M#Sdfus@9o5yVpl0ZXv zD-DVA`JDIm%MJpwddK5 z1K(x^*}F(8Oin}B)*#4kMkV#SSDmF{tM^B>o%Z%PNTEw+{i*T%N+>vugomDR*z&2! z_7|Qm625_6z#R!Y2n)f707*MO2222k!THcy>fAY4RK#9yKzskbP^A?K0|NuV{7(%H zk&=*@lxTSybQ%}vmK9}{OP?{jPy!FZfZM)AXg@_ELWWFiJ%C*EI4>X!aHV`i=+u>@ zZsY&%9RVFA&U!za?H61cyz2HqUR^d``2gq7Ae*6+!hRl44v>6AK!+e{lXKP3fH~e& zQM|<;Q$R2L?O4KddexZ(wq)L)D&W>oD&VE}in<^D3k*FzZazgR#LJ%#AKNvY&|;Z- zuirzB;MtT1cogG;g=spECo&1{Vv>5t-jaS%i9n0Gf5-fk!zYM{=<{A_0+#h6f?hBc zwcX%$7^ewlq+b+_me-a+6J{g6Oh}Q~Nopi|OSVd+OUPq3UajskSG!%-16dcin#Dv= z{>fVHYOQlY1tx%f{o*xk=i$_H=EaJ1vN ziVjD*fJFQCZ5>)NvLBO^J{#Y-^2Xtqjg21&HLPNGo%8PCEeb~fad>NGkD3{jz6>F} zg#&sMLVBM#ZzJuIa?a?;xUPYUZzl1hIQ2N6`b%35gZC$+Jj!DGnb>nF;M|eL10rb> z`#*T*8@~e%6h7TMtRHq`UpYv^{Iqnj>9Lk)z0s9FkauL-9tlf6JaqB%o3Ehj4~+=* zJZXBipt}}r85e8$Jl=p6g$Tq6dNo<6-n#GTbd&DeD{c<`x`l6fqybT;%#jr?|h?P6#?fe{&&>ZKTnnPTUhFA96a(cBGM9h}%Xqfq->UPNO8gyrSHK;MUCSyFtV^z+eJ7kN{PAbzhT|f~v}D ze#vdx>sKmW>_09#liA_PJ{1A?K%kTR{riY{d^#ZIfLS@UqyDw;@5}~XGlb&=PVaLe zNdM)DCHBDY%ArFAsZ)4VO^bbXf&AhF?>bR|(N0_$y?7Dj*t25jQlrCer@ zwNVunF2`w;2qM|l%VXPHckY;Gtf-#=4i=D!p*f;P3@svCSYBL~Cw;Bb1@OW=DSfwN zLpa+)%wB6$12`W5mJV)DB9jCnU-S(OkLv5{y6n8z%p1yhw8Fr^#P8%2e8{i{j!IrxA=nYiu>&J?IL?9 zMRrE7c{l;P)|Yagi^RG@n2XC{wpj*<>#dd@r;52T@iDppZqN@hH)Oj%8h5!bJ+AFL zhu&uvF1i8xq18RnMt~el8cPD!TIjng23od=`S>T=HSV(}63#l;fptwp{Lq*`k?O%( z>T^r4XXiV3PSh0Eck35Zfiz6fe(cUD?d5`{#8Faj4E(Ic(vSD5`Xm}ItAK*rj@Q^8 z^^Bg2kLGOLWeCBK)N*J~MQ`ab9@0j)ge+uhGm45{Ebb?ZG4vg$&Zb)nA+*w}+w zG^U?Y4g~~cP1e$ROzN1!z`o0=tQ_@P`k!6^X#RA-{?gPf zocEt*KkdcJTM#pVi^U=o!Ix*Mh7#TfJ2~mJ!9X5mLfPwbWSSu0c`Dpv0|SKLD;vZ&D)nfer{Nx^9o#+E#G40TjcpL;{zReX0tb`u(@511bZx$G*Jo4g0?iS6zNv z{Sxo@637A|$~u&z)TpvW^F&m1qMvmQu;%OlqYBUiK%{tdSm=U6i@H5AEcLvdw=Nak0P?fXDRMkWuwZ{hrCv%ZAWRKJU&84|%XQ+g`L$ul6v zhF2x=1=x^-HYgzP2mv<@=3-;)C3;1K^Y*ysx@%^^+}di10XS;yn{@OGsF1jIU&_Jx zHdP8dIOi1F1+kX;3}&U^lBJC=`>^j5?1y+*T zpvikVU_e^uAhN85%2tDbAE$OimD+izh>VtkmXwAe*gshz>eYoIU0Kw2jiDHRo|*S^&Cet@}#6lo%mNK|(A=Fdvg6cp~O$l`D+{_sMRq3d2c zeFGNcolydt47?cyP<-Ps2Wn$!6s5*%+x{tkO#_$4?M}#=k*$FsNnBZfxHW&`ND+_`Y2BYDHUuOEk6|G7=C`@n4eHDQqdquyQ1vTQ^2j! zV5i`7%wUP|dwLg8O=fRj&L3axYeaqSl-CIktPFn^td4}La*(fER`%2fiZ|LU?0hB(;Z1)Ky6$`Cs?(r(ySkXQyxAK#TDlibX+2(DWbuH=%=M@QT$S=7%w z8fuH;xt2O{rAbL%rSXd`Q`P#TjJj7*|LFQRD z;j-Nq9(R*B&)zD(o1YIOAmE|(kQQp!oNrZlU#tL@`A9vSpt#$Ol(8^>Z{GL)ePGSm z2Go#a@yl92;qXJDiJ|Xu_=&l$Y2`Xo3W25ZEQ#|mp z_fyUHtLLk5m{o)0djfwLdia@4ug@AfFkvN1aJ#xrzrJ29T*;#mD`n|%ic^8!k+@n; zS6so$1I-43s;G(^cK5Omn(O65G;43FUl2iaEn)1Zyr+Vv15PZ9*{BbPE?Kn-4o4tc zMpWH%OPKsD-vf0ZekvV+F@vwaTe$v!L$B_vjjC7kX7Hn2e}6@Ar-I+f<>#>5g##?K zEz&C159WrgmE`0O=2|gzqF%LLA?hU!X`HgACU|PS` zi7sDQ{_s2p^9u9+Jp}#uC(WJZenXE%avK#cQXB*H9VG?bi^=W4Z|$A!f;BZj?CQ|6 zzY-a5t;94i`(pJl1!kTm4s7Pu(P1{4rIx?4E>5~%cfLn{%*%^^7cU1+;Nw%2mbO%P zamHi0XXxFjp~=yE`yL5x+-ppZhAXA^5JZ<`i zfayB%Z-E_%=>^DwTvJ(D*MaMknps#dJ)L6y9a=JkeK#XB z^BoaA7P4u+cxSmUd1w%y&e|u+>a4tI9qtZ5((_lRK?z0z zG{tid)48HVT{r;BGcC`@BMoVBzUX1#>8kwC6Xn|lgLY$Gt!*AKmFJftQMDupqI-OP z20aKaW4-+qtV73mwNd$nBmViG75 z<686Fn`U43b=y?KAMt$-ex3u%;mJXfKzqR8rV_3S=H~#DE>c@N4lAzERC6{c&iW=c z@xFr`u4j4M=^n!$E1_;=LEe@Chy;CGX#$8Mmi2vn_<|xi+we^zwzi6rbWBbB>4cMR z_dt9K3sd9Nw>(dH|40WxC%VA3&oq(ZT_%chj}Y8Uju3Sl6=J%8U=uS}jURO$!m%Na z)O6ocVw!P2Eq0MN*=b%t8hZX{ML|_hf3HnK;~r7lBql*E8}7V!{?4C1rN+fMbjK@A zm$m{I<_!-<_i7et72m6ji}%#W1pU?I&0z4q77S{u{}S8u$}Ouwe9W?h*x2kwOLI^6 z!wGilF!irt`*Eys=`>HK8~r-E&me!>J;8k~L0zYaY)3~)4(bofnFmtGv~rmq2dGx( z+=_?8Mz1crc$n$`s}8&Bfb4|xMao9>>b`L7-sgcAzt zfrN2AFSJ11^zj)43EBnz%>@{~MEudNfgU}@nfd7n#V5sCa`b?$b2vcH-~7En)Yl%! zb?bTLU;9X;6{U`U&-=H^AOC5`->H4O!ru?cr!x5U#S9>j9T=A9_>j{>)l(A82x#u= zN^d?Bj3yO|W}qe}n3Z*s0pyQ^qDBD>zkWLMfz~jz1 zQD#!k&Y&! z2Lzo1B6k2L>i7NL_R(s;CoK5eb4~(9cMTQXzj|p<0`*0-`aju(l>h3pzh-gGYBL(O z{ar+gOjYv#8BjC3p#N@js(AWe8LYJVUs+pe_P=t7((r%f>Qe^v&edPRH7IrpP#iZF z>qh>o`Q{`)VL+dh{MQOHpcSo=^MB;QpzH{6?0;oM-d`OyC_4!p_21_oJJbFvXLly6 z`Kl;i9TF^u3- z07)Dc8}@r3zhYTXgF2xGz_N#djRRC<@$T9z{}lnxv3QwT3D{Qrq2Xtx=}97p9D?U5 z84xv==X-k8|DO0WuEZa;-$O9UyH9@$^Fd$2aZEIf(B;k0=o;JO77qyIOE{a&5VP`_!%s6qW%5~o>6IfaE)C+GkNfp3`rlrLQ3|hyS6Mu zr8kWgoejf?=__(Mq4=N3{ydxCg|)2f={weU|Bm_V^P6u9=Bn?il;;xt!Cn(n7pdwv zO(o}2pNir+qpNFuI_Fh6W&drI=taD`sB(r+KOVd`blJo}{ZAJ_STl0TDY}~(Ge0li z&TL(mov;O`q2ZzbJ_QsI719IQbMjLp##JFZ7x$c=1kNk9N^h5cHO-*c$sY^o#SZM{ zw?pVjTc-%8fv-HMgWvpf6oF77fDtRBR+U!i0@ItC^y6*USli$?bshYklh>x=eUR(d zL%C7GX((FT?Z(agJi5JwZ+~WzGa<6{W~`TohjGtj3VrC{YflW|#`YyypN9Ue5#V4! zzFki5X~4~7Nq)TBqyKza#J=ONwFU+9Zxu9?iPfDMe!fbe4^`AT9MHEo*DVGFmw(pR z|6}jHqoUfHIMK!|s3?LcD9A-Jf+9I9f|8+0l0|ZsoN3HRmZ)UOIp@@(l0lHzNY0ri z=ccFH@6LOFyfw4ltTlgr=dSC$%RXnHy=zzeRnj)#xKp3YbIJ)k)529ExEQe zvl)4h|Fgk969IR#n@6fXbKjP{p+77%lB{wtq~hzrUAw)l@h=mOGd9Mm)kyerCAp@C zzmm<&INBTfdk6>|ZNUQNa{rG8V*VOWf6n;rebzbh@BF*6g15g`Tn%DMx%ZtJ3R3^2 zXGP^FBMM0cIyv{3whqJJu7$t4(lC_2}0uZI10cG$9;G(vj1LG29tw@1u3EIKI8 z|3^{~d+qn^-Z7K4-D`UK??!xUdLPWzYH0Iz(=PBYArR+)urePM>3@j-J2$yRy0aO> zAZ*{P-`-bOR{lDCm6jHQ6HnLk4==N_u|;^0UA?NtdZcy|LDXbX>g?#)979J(_vzE8 z@&Zvr`J3aPT+5#Nt8ea$-2b+c42AxN&T00YpE^mIm>Blg$e<@}P{1L=<5#@!E#r?H z6AaI}px3O2t0%(4^LX&&_1rPs`YwK7A05i)B7)n-dd*c6#uab&IYa5$asJ+UjJtal zln5>@RaI3V9vqZV1=8{J^D;6*nc(w#!;60ie6{z}XM!CB;8oj#BaN`98TQ!gtf)xW z(2&p`B3HfIxg$C^rYuLRQYO7;9}T7!fw&40%Wd&EVW*9B{DF?L-TJ*I%*u|};VyOv zjRN43R`l=dbrnNi$9!bqPZoS%B*|0=HMNt=uVRu4x7Q) zLm2hkGc#qPbL`Mye00c}fL|hcGv?>(+Z=nJ{wbxZwuVdYa`cGJuHbkSejjTQc+kRB zw;UBcy1KZy6qWZZZCJ%Kb!}(Cr`&r=r1duLcnJF|fe(MJ9}YW8qd7(4^KGM1+txjm z{7wDZmWuvR!Et;^FSi>~?86Vc$?1>i+N17I$xp)1;+N;}(E!Da#u9DX{GGkv{K4tV z;uaPb-p6eymDQG~im2TVm%8=#Jjh0blT=%9NB3o`VYdhsIx`1J0V30

e&8{*vfFBO66vAVX_8EzQXgngcmZ> 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

hIjS?$Vob$hD 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�}B64=wR`Lc4w{KnU_~s|%b64YxiRQVI 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 literal 0 HcmV?d00001 diff --git a/docs/images/demo/pre-scan.png b/docs/images/demo/pre-scan.png index bb7f2a91228c367f3723def915c5f1ed3ed29c42..15323055871665ff69358c9025315b8ed14eed15 100644 GIT binary patch literal 80974 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 literal 85203 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 E2Mm9Wj{pDw diff --git a/docs/images/demo/premission-denied.png b/docs/images/demo/premission-denied.png new file mode 100644 index 0000000000000000000000000000000000000000..884835769ce8e7301c06f823c7bd6ec28523b66f GIT binary patch literal 88835 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 -1k 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 literal 0 HcmV?d00001 diff --git a/example/README.md b/example/README.md index e3acb6e..dff8d41 100644 --- a/example/README.md +++ b/example/README.md @@ -4,9 +4,9 @@ This is a sample app created from a fresh flutter project it is useful as a play Currently this app just connects to the first erg that it sees. An update is planned to make this a little more user-friendly for testing in environments with many ergs. - +![The example app](docs/images/demo/pre-scan.png) +![The example app when connected](docs/images/demo/connected.png) +![The example app when denied](docs/images/demo/permission-denied.png) ## Sample App capabilities ### Get workout summary information @@ -16,9 +16,9 @@ This is a relatively old screenshot of the included example app using an older v 2. confirm bluetooth is on. 3. Accept any permission prompts you are given 4. turn on PM and go to the screen where you would connect something like the ergdata app (on newer firmware there will be a connect button on the main menu) -5. open/run the app. you should see a screen with a "Start scan" button. ![A demo screenshot showing the start scan button](../docs/images/demo/pre-scan.png) -6. Press this "start scan" button when you are ready to start scanning for ergs. You will see a few messages on the screen while it scans. Wait until the app says "setting up streams". -7. Use the back button on the erg to go back and set up a piece. A 20 sec (minimum allowed) single time piece is the shortest thing you can do that still works (just row pieces must be longer than 1 minute in order to be visible to the app and be saved in the PM's memory). -8. start the piece. after the piece is over you should see some data for the piece you completed appear on screen. ![A demo screenshot showing the results of a piece](../docs/images/demo/completed.png) +5. open/run the app. you should see a screen with a "Bluetooth Scan" button. +6. Press this "Bluetooth Scan" button when you are ready to start scanning for ergs. You will see a few messages on the screen while it scans. Wait until the app says "Connected". +7. You can use the erg to set up a piece. Example: A 20 sec (minimum allowed) single time piece is the shortest thing you can do that still works (just row pieces must be longer than 1 minute in order to be visible to the app and be saved in the PM's memory). +8. start the piece. after the piece is over you should see some data for the piece you completed appear on screen. 9. you are now ready to start making changes to the sample app to play around with the API and explore the other data points that are made available. From fec8565d4ee1287e805e9de48c929082a4160dfa Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Fri, 2 May 2025 22:25:12 +0000 Subject: [PATCH 178/220] fixing some readme issues --- ...{premission-denied.png => permission-denied.png} | Bin example/README.md | 4 +--- 2 files changed, 1 insertion(+), 3 deletions(-) rename docs/images/demo/{premission-denied.png => permission-denied.png} (100%) diff --git a/docs/images/demo/premission-denied.png b/docs/images/demo/permission-denied.png similarity index 100% rename from docs/images/demo/premission-denied.png rename to docs/images/demo/permission-denied.png diff --git a/example/README.md b/example/README.md index dff8d41..371934b 100644 --- a/example/README.md +++ b/example/README.md @@ -4,9 +4,7 @@ This is a sample app created from a fresh flutter project it is useful as a play Currently this app just connects to the first erg that it sees. An update is planned to make this a little more user-friendly for testing in environments with many ergs. -![The example app](docs/images/demo/pre-scan.png) -![The example app when connected](docs/images/demo/connected.png) -![The example app when denied](docs/images/demo/permission-denied.png) +![The example app](/docs/images/demo/connected.png) ## Sample App capabilities ### Get workout summary information From 6b754ff398cbbdb00aebce6e970a294db175a03d Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Tue, 6 May 2025 18:55:56 +0000 Subject: [PATCH 179/220] using a map rather than a switch for readability --- lib/src/helpers.dart | 47 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/lib/src/helpers.dart b/lib/src/helpers.dart index bd856d7..e623a16 100644 --- a/lib/src/helpers.dart +++ b/lib/src/helpers.dart @@ -8,29 +8,28 @@ import './packets/forcecurvepacket.dart'; import './packets/base.dart'; +typedef PacketParser = Concept2CharacteristicData Function(Uint8List data); + +/// Mapping of the first byte of the multiplexed packet to its parser function. +final Map _packetParsers = { + 0x31: (data) => StatusData.fromBytes(data), + 0x32: (data) => StatusData1.fromBytes(data), + 0x33: (data) => StatusData2.fromBytes(data), + 0x35: (data) => StrokeData.fromBytes(data), + 0x36: (data) => StrokeData2.fromBytes(data), + 0x37: (data) => SegmentData1.fromBytes(data), + 0x38: (data) => SegmentData2.fromBytes(data), + 0x39: (data) => WorkoutSummaryPacket.fromBytes(data), + 0x3A: (data) => WorkoutSummaryPacket2.fromBytes(data), + 0x3C: (data) => ForceCurveData.fromBytes(data), +}; + +/// Attempts to parse a multiplexed Concept2 data packet. +/// Returns `null` if the packet ID is unknown or the data is empty. Concept2CharacteristicData? parsePacket(Uint8List data) { - switch (data[0]) { - case 0x31: - return StatusData.fromBytes(data.sublist(1)); - case 0x32: - return StatusData1.fromBytes(data.sublist(1)); - case 0x33: - return StatusData2.fromBytes(data.sublist(1)); - case 0x35: - return StrokeData.fromBytes(data.sublist(1)); - case 0x36: - return StrokeData2.fromBytes(data.sublist(1)); - case 0x37: - return SegmentData1.fromBytes(data.sublist(1)); - case 0x38: - return SegmentData2.fromBytes(data.sublist(1)); - case 0x39: - return WorkoutSummaryPacket.fromBytes(data.sublist(1)); - case 0x3A: - return WorkoutSummaryPacket2.fromBytes(data.sublist(1)); - case 0x3C: - return ForceCurveData.fromBytes(data.sublist(1)); - default: - return null; - } + if (data.isEmpty) return null; + + final id = data[0]; + final parser = _packetParsers[id]; + return parser?.call(data.sublist(1)); } From 2a1c57fec42bd1f65fb6299a417e91c351f95bee Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sat, 10 May 2025 12:07:16 +0000 Subject: [PATCH 180/220] renaming characteristic to resemble the documentation --- lib/constants.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/constants.dart b/lib/constants.dart index 3053759..bf632fc 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -22,7 +22,7 @@ const String C2_ROWING_PRIMARY_SERVICE_UUID = const String C2_ROWING_GENERAL_STATUS_CHARACTERISTIC_UUID = "CE060031-43E5-11E4-916C-0800200C9A66"; -const String C2_ROWING_GENERAL_STATUS_CHARACTERISTIC2_UUID = +const String C2_ROWING_ADDITIONAL_STATUS1_UUID = "CE060032-43E5-11E4-916C-0800200C9A66"; const String C2_ROWING_SPLIT_INTERVAL_DATA_CHARACTERISTIC_UUID = From 90087dfb6182f7f8a00681630e9405e67c66df89 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sat, 10 May 2025 12:08:26 +0000 Subject: [PATCH 181/220] adding remaining characteristics constants --- lib/constants.dart | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/constants.dart b/lib/constants.dart index bf632fc..a301aa9 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -25,6 +25,18 @@ const String C2_ROWING_GENERAL_STATUS_CHARACTERISTIC_UUID = const String C2_ROWING_ADDITIONAL_STATUS1_UUID = "CE060032-43E5-11E4-916C-0800200C9A66"; +const String C2_ROWING_ADDITIONAL_STATUS2_UUID = + "CE060033-43E5-11E4-916C-0800200C9A66"; + +const String C2_ROWING_SAMPLE_RATE_UUID = + "CE060034-43E5-11E4-916C-0800200C9A66"; // sample rate read/write + +const String C2_ROWING_STROKE_DATA_UUID = + "CE060035-43E5-11E4-916C-0800200C9A66"; + +const String C2_ROWING_ADDITIONAL_STROKE_UUID = + "CE060036-43E5-11E4-916C-0800200C9A66"; + const String C2_ROWING_SPLIT_INTERVAL_DATA_CHARACTERISTIC_UUID = "CE060037-43E5-11E4-916C-0800200C9A66"; @@ -37,6 +49,9 @@ const String C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC_UUID = const String C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC2_UUID = "CE06003A-43E5-11E4-916C-0800200C9A66"; +const String C2_ROWING_FORCE_CURVE_UUID = + "CE060040-43E5-11E4-916C-0800200C9A66"; + const String C2_ROWING_MULTIPLEXED_INFORMATION_CHARACTERISTIC_UUID = "CE060080-43E5-11E4-916C-0800200C9A66"; From 427f36e093bc482fec6fb607c7a71df63653d521 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sun, 11 May 2025 07:03:48 +0000 Subject: [PATCH 182/220] use streamcontrollers to be more flexible during testing --- test/ergometer_test.dart | 215 +++++++++++++++++++++++++++------------ 1 file changed, 149 insertions(+), 66 deletions(-) diff --git a/test/ergometer_test.dart b/test/ergometer_test.dart index 610c0f7..d5b194e 100644 --- a/test/ergometer_test.dart +++ b/test/ergometer_test.dart @@ -1,4 +1,6 @@ -import 'package:c2bluetooth/models/ergometer.dart'; +import 'dart:async'; + +import 'package:c2bluetooth/c2bluetooth.dart'; import 'package:c2bluetooth/src/dataplex.dart'; import 'package:flutter/services.dart'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; @@ -12,41 +14,51 @@ class FakeQualifiedCharacteristic extends Fake class FakeDataplex extends Fake implements Dataplex {} +late MockFlutterReactiveBle mockBle; +late StreamController> characteristicController; +late StreamController deviceConnectionController; +late DiscoveredDevice device = DiscoveredDevice( + id: 'deviceId', + name: 'deviceName', + serviceData: {}, + manufacturerData: Uint8List.fromList([1, 1, 1, 1]), + rssi: 90, + serviceUuids: []); void main() { group('Bluetooth tests', () { - setUp(() { - registerFallbackValue(Stream.value(ConnectionStateUpdate( - deviceId: 'fallback', - connectionState: DeviceConnectionState.disconnected, - failure: null, - ))); - registerFallbackValue(DiscoveredDevice( - id: 'deviceId', - name: 'deviceName', - serviceData: {}, - manufacturerData: Uint8List.fromList([1, 1, 1, 1]), - rssi: 90, - serviceUuids: [])); - registerFallbackValue(FakeQualifiedCharacteristic()); - registerFallbackValue(Stream>.fromIterable([ - [1, 1, 1], - [2, 2, 2] - ])); + setUpAll(() { + // Fallback values registerFallbackValue(QualifiedCharacteristic( characteristicId: Uuid.parse('c5cc5bf5-2bd1-4d1a-939a-5e15fb9b81a1'), serviceId: Uuid.parse('c5cc5bf5-2bd1-4d1a-939a-5e15fb9b81a2'), - deviceId: 'deviceId')); + deviceId: device.id)); + }); + setUp(() { + mockBle = MockFlutterReactiveBle(); + // Mock ReactiveBle methods using streamcontrollers + characteristicController = + StreamController>.broadcast(sync: true); + deviceConnectionController = + StreamController.broadcast(sync: true); + when( + () => mockBle.connectToDevice( + id: any(named: 'id'), + connectionTimeout: any(named: 'connectionTimeout'), + ), + ).thenAnswer((_) => deviceConnectionController.stream); + when(() => mockBle.connectedDeviceStream) + .thenAnswer((_) => deviceConnectionController.stream); + when(() => + mockBle.subscribeToCharacteristic(any())) + .thenAnswer((_) => characteristicController.stream); + }); + tearDownAll(() { + deviceConnectionController.close(); + characteristicController.close(); }); test('Ensure DeviceConnectionState to ErgometerConnectionState translation', () { - DiscoveredDevice device = DiscoveredDevice( - id: 'deviceId', - name: 'deviceName', - serviceData: {}, - manufacturerData: Uint8List.fromList([1, 1, 1, 1]), - rssi: 90, - serviceUuids: []); final fakeConnectionUpdates = Stream.fromIterable([ ConnectionStateUpdate( deviceId: 'deviceId', @@ -67,10 +79,10 @@ void main() { connectionState: DeviceConnectionState.disconnected, failure: null) ]); - final mockBle = MockFlutterReactiveBle(); final erg = Ergometer(device, bleClient: mockBle); - when(() => mockBle.connectedDeviceStream) - .thenAnswer((_) => fakeConnectionUpdates); + fakeConnectionUpdates.forEach(deviceConnectionController.add); + StreamSubscription _connection = + erg.connectAndDiscover().listen((_) {}); expect( erg.getMonitorConnectionState, emitsInOrder([ @@ -79,23 +91,14 @@ void main() { ErgometerConnectionState.disconnected, ErgometerConnectionState.disconnected ])); - verifyNever(() => mockBle.connectToDevice( - id: 'deviceId', - connectionTimeout: any(named: 'connectionTimeout'), - )); + _connection.cancel(); }); test('Retrieve ErgometerConnectionState status during connection', () { - // dummy discovered device - DiscoveredDevice device = DiscoveredDevice( - id: 'deviceId', - name: 'deviceName', - serviceData: {}, - manufacturerData: Uint8List.fromList([1, 1, 1, 1]), - rssi: 90, - serviceUuids: []); final fakeSubscriptionChar = Stream>.fromIterable([ - [1, 1, 1], - [2, 2, 2] + // Each StatusData1 is 18 bytes + [0x31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // 0 m + [0x31, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // 1 m + [0x31, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // 2 m ]); final fakeConnectionUpdates = Stream.fromIterable([ ConnectionStateUpdate( @@ -109,38 +112,118 @@ void main() { failure: null, ) ]); - final mockBle = MockFlutterReactiveBle(); final erg = Ergometer(device, bleClient: mockBle); - when(() => mockBle.connectedDeviceStream) - .thenAnswer((_) => fakeConnectionUpdates); - when( - () => mockBle.connectToDevice( - id: any(named: 'id'), - connectionTimeout: any(named: 'connectionTimeout'), - ), - ).thenAnswer((_) => fakeConnectionUpdates); - when(() => mockBle.subscribeToCharacteristic(any())) - .thenAnswer((_) => fakeSubscriptionChar); + fakeConnectionUpdates.forEach(deviceConnectionController.add); + fakeSubscriptionChar.forEach(characteristicController.add); expect( erg.connectAndDiscover(), emitsInOrder([ ErgometerConnectionState.connecting, ErgometerConnectionState.connected ])); + // Connection should happen once verify(() => mockBle.connectToDevice( - id: 'deviceId', + id: device.id, connectionTimeout: any(named: 'connectionTimeout'), )).called(1); + // Subscribed to the two defaut subscriptions: + // - Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID, + // - Identifiers.C2_ROWING_MULTIPLEXED_INFORMATION_CHARACTERISTIC_UUID, + verify(() => + mockBle.subscribeToCharacteristic(any())) + .called(2); + }); + test('Monitor for distance data', () async { + final fakeData = Stream>.fromIterable([ + // Each StatusData1 is 18 bytes + [ + 0x31, + 0, + 0, + 0, + 30, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], // 3 m + [ + 0x31, + 0, + 0, + 0, + 40, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], // 4 m + [ + 0x31, + 0, + 0, + 0, + 50, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], // 5 m + ]); + final erg = Ergometer(device, bleClient: mockBle); + final StreamSubscription connection = + erg.connectAndDiscover().listen((_) {}); + Stream.value(ConnectionStateUpdate( + deviceId: device.id, + connectionState: DeviceConnectionState.connected, + failure: null)) + .forEach(deviceConnectionController.add); + characteristicController.addStream(fakeData); + final result = expectLater( + erg.monitorForData({Keys.ELAPSED_DISTANCE_KEY}), + emitsInOrder([ + Map.from({Keys.ELAPSED_DISTANCE_KEY: 3}), + Map.from({Keys.ELAPSED_DISTANCE_KEY: 4}), + Map.from({Keys.ELAPSED_DISTANCE_KEY: 5}), + ])); + await result; + await connection.cancel(); }); - }); - test('instantiate from a peripheral', () { - // final bytes = Uint8List.fromList([0, 0, 0, 128]); - // expect(CsafeIntExtension.fromBytes(bytes), 128); - // expect(CsafeIntExtension.fromBytes(bytes, Endian.little), 2147483648); - }); - test('can provide WorkoutSummary data', () { - // final bytes = Uint8List.fromList([0, 0, 0, 128]); - // expect(CsafeIntExtension.fromBytes(bytes), 128); - // expect(CsafeIntExtension.fromBytes(bytes, Endian.little), 2147483648); }); } From 76ab2470695717e0f2655a2223d1073c92e4e3f6 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sun, 11 May 2025 07:07:41 +0000 Subject: [PATCH 183/220] test packet parser --- test/src/helpers_test.dart | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 test/src/helpers_test.dart diff --git a/test/src/helpers_test.dart b/test/src/helpers_test.dart new file mode 100644 index 0000000..20d16bd --- /dev/null +++ b/test/src/helpers_test.dart @@ -0,0 +1,34 @@ +import 'dart:typed_data'; + +import 'package:c2bluetooth/enums.dart'; +import 'package:c2bluetooth/src/helpers.dart'; +import 'package:c2bluetooth/src/packets/keys.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('Handle mutliplexed data', () { + test('parsePacket handles 0x37 SegmentData1', () { + // Construct a byte array representing a packet. + final data = Uint8List.fromList([ + 0x37, // packet ID + 0xE8, 0x03, 0x00, // elapsedTime: 1000 (0x0003E8) => 10 seconds + 0xE8, 0x03, 0x00, // elapsedDistance: 1000 (0x0003E8) => 100 meters + 0x88, 0x13, 0x00, // segment time: + 0x88, 0x13, 0x00, // segment distance: + 0x88, 0x13, // interval rest time: + 0x88, 0x13, // interval rest distance: + 0x05, // segment type: rest undefined + 0x03, // segment number: + ]); + expect(data.lengthInBytes, equals(19)); + final status = parsePacket(data); + final map = status!.asMap(); + expect(map[Keys.ELAPSED_TIME_KEY], equals(Duration(seconds: 10))); + expect(map[Keys.ELAPSED_DISTANCE_KEY], equals(100.0)); + expect(map[Keys.SEGMENT_TIME_KEY], equals(500)); + expect(map[Keys.SEGMENT_DISTANCE_KEY], equals(5000)); + expect(map[Keys.SEGMENT_TYPE_KEY], equals(IntervalType.RESTUNDEFINED)); + expect(map[Keys.SEGMENT_NUMBER_KEY], equals(3)); + }); + }); +} From 76ee32ba610ea55ee491d4787ad5b9cab5b7fb22 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sun, 11 May 2025 07:13:08 +0000 Subject: [PATCH 184/220] test dataplex --- test/src/dataplex_test.dart | 81 +++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 test/src/dataplex_test.dart diff --git a/test/src/dataplex_test.dart b/test/src/dataplex_test.dart new file mode 100644 index 0000000..4a0e4ca --- /dev/null +++ b/test/src/dataplex_test.dart @@ -0,0 +1,81 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:c2bluetooth/src/dataplex.dart'; +import 'package:c2bluetooth/src/packets/base.dart'; +import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; + +class MockBle extends Mock implements FlutterReactiveBle {} + +class FakeDevice extends Fake implements DiscoveredDevice { + @override + String get id => '01:23:45:67:89:AB'; +} + +class MockParse extends Mock { + Concept2CharacteristicData? call(Uint8List bytes); +} + +void main() { + setUpAll(() { + registerFallbackValue(QualifiedCharacteristic( + serviceId: Uuid.parse('00000000-0000-0000-0000-000000000000'), + characteristicId: Uuid.parse('ce060030-43e5-11e4-916c-0800200c9a66'), + deviceId: 'fallback', + )); + registerFallbackValue(Uint8List(0)); + }); + + group('Dataplex', () { + late MockBle ble; + late DiscoveredDevice device; + + setUp(() { + ble = MockBle(); + device = FakeDevice(); + + when(() => ble.subscribeToCharacteristic(any())) + .thenAnswer((_) => const Stream.empty()); + }); + + test('creates multiplex subscription on construction', () { + Dataplex(device, ble); + + verifyNever(() => ble.subscribeToCharacteristic( + any( + that: isA().having( + (c) => c.deviceId, + 'device ID', + equals(device.id), + )), + )); + }); + test('dispose cancels BLE subscriptions and closes outgoing streams', + () async { + final bleStream = StreamController(); + when(() => ble.subscribeToCharacteristic(any())) + .thenAnswer((_) => bleStream.stream); + + final dataplex = Dataplex(device, ble); + + final s1 = dataplex.createStream({'a'}.toSet()).listen((_) {}); + final s2 = dataplex.createStream({'b'}.toSet()).listen((_) {}); + verify(() => ble.subscribeToCharacteristic( + any( + that: isA().having( + (c) => c.deviceId, + 'device ID', + equals(device.id), + )), + )).called(1); + dataplex.dispose(); + + await expectLater(s1.asFuture(), completes); + await expectLater(s2.asFuture(), completes); + + expect(() => bleStream.add(Uint8List.fromList([0x00])), returnsNormally); + }); + }); +} From 79e7040250036257d87339a0901114fe3389b507 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sun, 11 May 2025 08:41:27 +0000 Subject: [PATCH 185/220] adding stroke data --- lib/src/packets/keys.dart | 20 ++++- lib/src/packets/strokedata.dart | 116 +++++++++++++++++++++------- lib/src/packets/workoutsummary.dart | 2 +- test/src/helpers_test.dart | 27 +++++++ 4 files changed, 134 insertions(+), 31 deletions(-) diff --git a/lib/src/packets/keys.dart b/lib/src/packets/keys.dart index d309ff2..f59c117 100644 --- a/lib/src/packets/keys.dart +++ b/lib/src/packets/keys.dart @@ -3,19 +3,36 @@ class Keys { static const ELAPSED_DISTANCE_KEY = "general.distance"; static const WORKOUT_TIMESTAMP_KEY = "workout.timestamp"; + static const WORKOUT_SPM_KEY = "workout.stroke_rate"; static const WORKOUT_AVG_SPM_KEY = "workout.stroke_rate.average"; + static const WORKOUT_HR_KEY = "workout.heart_rate"; static const WORKOUT_LAST_HR_KEY = "workout.heart_rate.last"; static const WORKOUT_AVG_HR_KEY = "workout.heart_rate.average"; static const WORKOUT_MIN_HR_KEY = "workout.heart_rate.min"; static const WORKOUT_MAX_HR_KEY = "workout.heart_rate.max"; + static const WORKOUT_AVG_POWER_KEY = "workout.power.average"; static const WORKOUT_AVG_PACE_KEY = "workout.pace.average"; static const WORKOUT_AVG_DRAGFACTOR_KEY = "workout.drag_factor.average"; static const WORKOUT_RECOVERY_HR_KEY = "workout.heart_rate.recovery"; + static const WORKOUT_PROJECTED_TIME_KEY = 'workout.projected_work.time'; + static const WORKOUT_PROJECTED_DISTANCE_KEY = + 'workout.projected_work.distance'; static const WORKOUT_SEGMENT_COUNT_KEY = "workout.segment_count"; static const WORKOUT_SEGMENT_SIZE_KEY = "workout.segment_size"; static const WORKOUT_CALORIES_KEY = "workout.calories"; - static const WORKOUT_WATTS_KEY = "workout.watts"; + static const WORKOUT_SPEED_KEY = "workout.speed"; + static const WORKOUT_PACE_KEY = "workout.pace"; + static const WORKOUT_POWER_KEY = "workout.watts"; + static const WORKOUT_WORK_KEY = "workout.joules"; + + static const STROKE_DRIVE_LENGTH_KEY = 'stroke.drive_length'; + static const STROKE_DRIVE_TIME_KEY = 'stroke.drive_time'; + static const STROKE_RECOVERY_TIME_KEY = 'stroke.recovery_time'; + static const STROKE_DISTANCE_KEY = 'stroke.stroke_distance'; + static const STROKE_PEAK_FORCE_KEY = 'stroke.force.peak'; + static const STROKE_AVG_FORCE_KEY = 'stroke.force.average'; + static const STROKE_COUNT_KEY = 'stroke.count'; // rests are only applicable for intervals workouts static const WORKOUT_REST_DISTANCE_KEY = "workout.rest_distance"; static const WORKOUT_REST_TIME_KEY = "workout.rest_time"; @@ -35,5 +52,6 @@ class Keys { static const SEGMENT_AVG_CALORIES_KEY = "segment.calories.average"; static const SEGMENT_SPEED_KEY = "segment.speed"; static const SEGMENT_POWER_KEY = "segment.power"; + static const SEGMENT_AVG_POWER_KEY = "segment.power.average"; static const SEGMENT_AVG_DRAGFACTOR_KEY = "segment.drag_factor.average"; } diff --git a/lib/src/packets/strokedata.dart b/lib/src/packets/strokedata.dart index cf5cb77..1904f25 100644 --- a/lib/src/packets/strokedata.dart +++ b/lib/src/packets/strokedata.dart @@ -1,50 +1,108 @@ import 'dart:typed_data'; +import 'package:c2bluetooth/c2bluetooth.dart'; +import 'package:csafe_fitness/csafe_fitness.dart'; + import './base.dart'; class StrokeData extends ElapsedtimeStampedData { - static Set get datapointIdentifiers => StrokeData.zero().asMap().keys.toSet(); + final double distance; // 0x01 = 0.1 meters + final double driveLength; // 0x01 = 0.01 meters, max = 2.55m + final Duration driveTime; // 0x01 = 0.01 sec, max = 2.55 sec + final Duration recoveryTime; // 0x01 = 0.01 sec, max = 655.35 sec + final double strokeDistance; // 0x01 = 0.01 m, max=655.35m + final double peakForce; // 0x01 = 0.1 lbs of force, max=655.35 lbs + final double averageForce; // 0x01 = 0.1 lbs of force, max=655.35 lbs + final int strokeCount; StrokeData.zero() : this.fromBytes(Uint8List(20)); - StrokeData.fromBytes(Uint8List data) : super.fromBytes(data) { - // _workTime.completeIfNotAlready( - // CsafeIntExtension.fromBytes(data.sublist(4, 7), endian: Endian.little) / - // 100); //divide by 100 to convert to seconds - // _workDistance.completeIfNotAlready(CsafeIntExtension.fromBytes( - // data.sublist(7, 10), - // endian: Endian.little) / - // 10); //divide by 10 to convert to meters - // _avgSPM.completeIfNotAlready(data.elementAt(10)); - // _endHeartRate.completeIfNotAlready(data.elementAt(11)); - // _avgHeartRate.completeIfNotAlready(data.elementAt(12)); - // _minHeartRate.completeIfNotAlready(data.elementAt(13)); - // _maxHeartRate.completeIfNotAlready(data.elementAt(14)); - // _avgDragFactor.completeIfNotAlready(data.elementAt(15)); - // //recovery heart rate here - // int recHRVal = data.elementAt(16); - // // 0 is not a valid value here according to the spec - // if (recHRVal > 0) { - // _recoveryHeartRate.completeIfNotAlready(recHRVal); - // } - // _workoutType - // .completeIfNotAlready(WorkoutTypeExtension.fromInt(data.elementAt(17))); - // _avgPace.completeIfNotAlready(CsafeIntExtension.fromBytes( - // data.sublist(18, 20), - // endian: Endian.little) / - // 10); //{ + StrokeData.fromBytes(Uint8List data) + : distance = CsafeIntExtension.fromBytes(data.sublist(3, 6), + endian: Endian.little) / + 10.0, + driveLength = data[6] / 100.0, + driveTime = Duration( + seconds: data[7] ~/ 100, milliseconds: data[7].remainder(100)), + recoveryTime = Duration( + milliseconds: CsafeIntExtension.fromBytes(data.sublist(8, 10), + endian: Endian.little) * + 10), + strokeDistance = CsafeIntExtension.fromBytes(data.sublist(10, 12), + endian: Endian.little) / + 10.0, + peakForce = CsafeIntExtension.fromBytes(data.sublist(12, 14), + endian: Endian.little) / + 10.0, + averageForce = CsafeIntExtension.fromBytes(data.sublist(14, 16), + endian: Endian.little) / + 10.0, + strokeCount = CsafeIntExtension.fromBytes(data.sublist(16, 18), + endian: Endian.little), + super.fromBytes(data); + + @override + Map asMap() { + Map map = super.asMap(); + map.addAll({ + Keys.ELAPSED_DISTANCE_KEY: distance, + Keys.STROKE_DRIVE_LENGTH_KEY: driveLength, + Keys.STROKE_DRIVE_TIME_KEY: driveTime, + Keys.STROKE_RECOVERY_TIME_KEY: recoveryTime, + Keys.STROKE_DISTANCE_KEY: strokeDistance, + Keys.STROKE_PEAK_FORCE_KEY: peakForce, + Keys.STROKE_AVG_FORCE_KEY: averageForce, + Keys.STROKE_COUNT_KEY: strokeCount, + }); + + return map; } } +/// Additional stroke data from characteristic 0x0036 class StrokeData2 extends ElapsedtimeStampedData { - static Set get datapointIdentifiers => StrokeData2.zero().asMap().keys.toSet(); + final int strokePower; // watts + final int strokeCalories; // cals/hr + final int strokeCount; + final Duration projectedWorkTime; // secs + final int projectedWorkDistance; // meters + final double workPerStroke; // 0x01 = 0.1 Joules, max=6553.5 Joules StrokeData2.zero() : this.fromBytes(Uint8List(20)); + StrokeData2.fromBytes(Uint8List data) + : strokePower = CsafeIntExtension.fromBytes(data.sublist(3, 6), + endian: Endian.little), + strokeCalories = CsafeIntExtension.fromBytes(data.sublist(6, 9), + endian: Endian.little), + strokeCount = CsafeIntExtension.fromBytes(data.sublist(9, 12), + endian: Endian.little), + projectedWorkTime = Duration( + seconds: CsafeIntExtension.fromBytes(data.sublist(12, 14), + endian: Endian.little)), + projectedWorkDistance = CsafeIntExtension.fromBytes( + data.sublist(14, 17), + endian: Endian.little), + workPerStroke = CsafeIntExtension.fromBytes(data.sublist(17, 19), + endian: Endian.little) / + 10.0, + super.fromBytes(data); - StrokeData2.fromBytes(Uint8List data) : super.fromBytes(data); + @override + Map asMap() { + Map map = super.asMap(); + map.addAll({ + Keys.WORKOUT_POWER_KEY: strokePower, + Keys.WORKOUT_CALORIES_KEY: strokeCalories, + Keys.STROKE_COUNT_KEY: strokeCount, + Keys.WORKOUT_PROJECTED_TIME_KEY: projectedWorkTime, + Keys.WORKOUT_PROJECTED_DISTANCE_KEY: projectedWorkDistance, + Keys.WORKOUT_WORK_KEY: workPerStroke, + }); + return map; + } } diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index a835346..23179a5 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -119,7 +119,7 @@ class WorkoutSummaryPacket2 extends TimestampedData { Keys.WORKOUT_SEGMENT_COUNT_KEY: intervalSize, Keys.WORKOUT_SEGMENT_SIZE_KEY: intervalCount, Keys.WORKOUT_CALORIES_KEY: totalCalories, - Keys.WORKOUT_WATTS_KEY: watts, + Keys.WORKOUT_POWER_KEY: watts, Keys.WORKOUT_REST_DISTANCE_KEY: totalRestDistance, // "workout.interval_rest_distance": , Keys.WORKOUT_REST_TIME_KEY: intervalRestTime, diff --git a/test/src/helpers_test.dart b/test/src/helpers_test.dart index 20d16bd..82090cb 100644 --- a/test/src/helpers_test.dart +++ b/test/src/helpers_test.dart @@ -7,6 +7,33 @@ import 'package:flutter_test/flutter_test.dart'; void main() { group('Handle mutliplexed data', () { + test('parsePacket handles 0x35 StrokeData', () { + // Construct a byte array representing a packet. + final data = Uint8List.fromList([ + 0x35, // packet ID + 0xE8, 0x03, 0x00, // elapsedTime: 1000 (0x0003E8) => 10 seconds + 0xE8, 0x03, 0x00, // distance: 1000 (0x0003E8) => 100 meters + 0xC8, // drive length: 200 (0x00C8) => 2 meters + 0x64, // drive time: 100 (0x64) => 1 second + 0xE8, 0x03, // recovery time: 1000 (0x03E8) => 10 seconds + 0xE8, 0x03, // stroke distance: 1000 (0x03E8) => 100 meters + 0xA0, 0x0F, // peak force: 4000 (0x0FA0) => 400 lbs + 0xE8, 0x03, // avg force: 1000 (0x3E8) => 100 lbs + 0xE8, 0x03, // stroke count: 1000 (0x3E8) + ]); + expect(data.lengthInBytes, equals(19)); + final status = parsePacket(data); + final map = status!.asMap(); + expect(map[Keys.ELAPSED_TIME_KEY], equals(Duration(seconds: 10))); + expect(map[Keys.ELAPSED_DISTANCE_KEY], equals(100.0)); + expect(map[Keys.STROKE_DRIVE_LENGTH_KEY], equals(2.0)); + expect(map[Keys.STROKE_DRIVE_TIME_KEY], equals(Duration(seconds: 1))); + expect(map[Keys.STROKE_RECOVERY_TIME_KEY], equals(Duration(seconds: 10))); + expect(map[Keys.STROKE_DISTANCE_KEY], equals(100.0)); + expect(map[Keys.STROKE_PEAK_FORCE_KEY], equals(400)); + expect(map[Keys.STROKE_AVG_FORCE_KEY], equals(100)); + expect(map[Keys.STROKE_COUNT_KEY], equals(1000)); + }); test('parsePacket handles 0x37 SegmentData1', () { // Construct a byte array representing a packet. final data = Uint8List.fromList([ From 247b8e265f5f5f83997ae40effb41e951c10bfd2 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Mon, 12 May 2025 11:55:24 +0000 Subject: [PATCH 186/220] fixing index error --- lib/src/packets/strokedata.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/src/packets/strokedata.dart b/lib/src/packets/strokedata.dart index 1904f25..f3b7e43 100644 --- a/lib/src/packets/strokedata.dart +++ b/lib/src/packets/strokedata.dart @@ -75,19 +75,19 @@ class StrokeData2 extends ElapsedtimeStampedData { StrokeData2.zero() : this.fromBytes(Uint8List(20)); StrokeData2.fromBytes(Uint8List data) - : strokePower = CsafeIntExtension.fromBytes(data.sublist(3, 6), + : strokePower = CsafeIntExtension.fromBytes(data.sublist(3, 5), endian: Endian.little), - strokeCalories = CsafeIntExtension.fromBytes(data.sublist(6, 9), + strokeCalories = CsafeIntExtension.fromBytes(data.sublist(5, 7), endian: Endian.little), - strokeCount = CsafeIntExtension.fromBytes(data.sublist(9, 12), + strokeCount = CsafeIntExtension.fromBytes(data.sublist(7, 9), endian: Endian.little), projectedWorkTime = Duration( - seconds: CsafeIntExtension.fromBytes(data.sublist(12, 14), + seconds: CsafeIntExtension.fromBytes(data.sublist(9, 12), endian: Endian.little)), projectedWorkDistance = CsafeIntExtension.fromBytes( - data.sublist(14, 17), + data.sublist(12, 15), endian: Endian.little), - workPerStroke = CsafeIntExtension.fromBytes(data.sublist(17, 19), + workPerStroke = CsafeIntExtension.fromBytes(data.sublist(15, 17), endian: Endian.little) / 10.0, super.fromBytes(data); From 07a4967598c71227c600e19d58c2711f262fbb46 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Mon, 12 May 2025 11:55:55 +0000 Subject: [PATCH 187/220] testing strokeData2 --- test/src/helpers_test.dart | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/src/helpers_test.dart b/test/src/helpers_test.dart index 82090cb..588d596 100644 --- a/test/src/helpers_test.dart +++ b/test/src/helpers_test.dart @@ -34,6 +34,30 @@ void main() { expect(map[Keys.STROKE_AVG_FORCE_KEY], equals(100)); expect(map[Keys.STROKE_COUNT_KEY], equals(1000)); }); + test('parsePacket handles 0x36 StrokeData2', () { + // Construct a byte array representing a packet. + final data = Uint8List.fromList([ + 0x36, // packet ID + 0xE8, 0x03, 0x00, // elapsedTime: 1000 (0x0003E8) => 10 seconds + 0x54, 0x01, // stroke power: 340 watts + 0x02, 0x00, // stroke calories: 2 cal/hr + 0xE8, 0x03, // stroke count: 1000 strokes + 0x64, 0x00, 0x00, // projected work time: 100 seconds + 0xE8, 0x03, 0x00, // projected work distance: 1000 meters + 0xE8, 0x03, // work per stroke: 1000 (0x03E8) => 100 Joules + ]); + expect(data.lengthInBytes, equals(18)); + final status = parsePacket(data); + final map = status!.asMap(); + expect(map[Keys.ELAPSED_TIME_KEY], equals(Duration(seconds: 10))); + expect(map[Keys.WORKOUT_POWER_KEY], equals(340)); + expect(map[Keys.WORKOUT_CALORIES_KEY], equals(2.0)); + expect(map[Keys.STROKE_COUNT_KEY], equals(1000)); + expect( + map[Keys.WORKOUT_PROJECTED_TIME_KEY], equals(Duration(seconds: 100))); + expect(map[Keys.WORKOUT_PROJECTED_DISTANCE_KEY], equals(1000)); + expect(map[Keys.WORKOUT_WORK_KEY], equals(100.0)); + }); test('parsePacket handles 0x37 SegmentData1', () { // Construct a byte array representing a packet. final data = Uint8List.fromList([ From ca40ed33d09c3349fe2706dbe0a95495a7c7d038 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Tue, 13 May 2025 20:15:16 +0000 Subject: [PATCH 188/220] WORK -> ENERGY --- lib/src/packets/strokedata.dart | 2 +- test/src/helpers_test.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/packets/strokedata.dart b/lib/src/packets/strokedata.dart index f3b7e43..c6ef70e 100644 --- a/lib/src/packets/strokedata.dart +++ b/lib/src/packets/strokedata.dart @@ -101,7 +101,7 @@ class StrokeData2 extends ElapsedtimeStampedData { Keys.STROKE_COUNT_KEY: strokeCount, Keys.WORKOUT_PROJECTED_TIME_KEY: projectedWorkTime, Keys.WORKOUT_PROJECTED_DISTANCE_KEY: projectedWorkDistance, - Keys.WORKOUT_WORK_KEY: workPerStroke, + Keys.STROKE_ENERGY_KEY: workPerStroke, }); return map; } diff --git a/test/src/helpers_test.dart b/test/src/helpers_test.dart index 588d596..f8eee6d 100644 --- a/test/src/helpers_test.dart +++ b/test/src/helpers_test.dart @@ -56,7 +56,7 @@ void main() { expect( map[Keys.WORKOUT_PROJECTED_TIME_KEY], equals(Duration(seconds: 100))); expect(map[Keys.WORKOUT_PROJECTED_DISTANCE_KEY], equals(1000)); - expect(map[Keys.WORKOUT_WORK_KEY], equals(100.0)); + expect(map[Keys.STROKE_ENERGY_KEY], equals(100.0)); }); test('parsePacket handles 0x37 SegmentData1', () { // Construct a byte array representing a packet. From 1d21d99b2b83d2c74fa0fd624ab7b76d0764c81b Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Tue, 13 May 2025 20:36:38 +0000 Subject: [PATCH 189/220] fix concurrent modification occuring in dataplex dispose --- lib/src/dataplex.dart | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 41a5423..2d2b58b 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -160,18 +160,16 @@ class Dataplex { /// closes down this instance by cancelling all streams void dispose() { - // clear current subscriptions - for (var entry in currentSubscriptions.entries) { - var key = entry.key; - var subscription = entry.value; - - subscription.cancel(); - currentSubscriptions.remove(key); + for (var sub in currentSubscriptions.values) { + // clear current subscriptions + sub.cancel(); } - // end all current output streams - // it is assumed that this also triggers their close handlers and removes them. + currentSubscriptions.clear(); + for (var stream in outgoingStreams) { + // end all current output streams stream.close(); } + outgoingStreams.clear(); } } From d514d1d6e0930baf9f6ab2f523ad07e6a2d36a10 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Tue, 13 May 2025 20:41:32 +0000 Subject: [PATCH 190/220] allow mock test for parsePacket --- lib/src/dataplex.dart | 12 +++++++++--- lib/src/helpers.dart | 4 ++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index 2d2b58b..fff3cfb 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:c2bluetooth/models/c2datastreamcontroller.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import '../constants.dart' as Identifiers; @@ -21,7 +22,7 @@ class Dataplex { final FlutterReactiveBle _flutterReactiveBle; DiscoveredDevice _device; - + final ParsePacketFn _parsePacket; List outgoingStreams = []; /// Map of characteristic UUID's to the active subscription instance for that characteristic @@ -48,7 +49,12 @@ class Dataplex { WorkoutSummaryPacket2.datapointIdentifiers, }; - Dataplex(this._device, bleClient) : _flutterReactiveBle = bleClient { + Dataplex( + this._device, + bleClient, { + @visibleForTesting ParsePacketFn? parsePacketFn, + }) : _flutterReactiveBle = bleClient, + _parsePacket = parsePacketFn ?? parsePacket { _addSubscription( Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID, Identifiers.C2_ROWING_MULTIPLEXED_INFORMATION_CHARACTERISTIC_UUID, @@ -107,7 +113,7 @@ class Dataplex { /// Read a packet from an incoming stream (from the erg) and redistribute it to all outgoing streams void _readPacket(Uint8List data) { - Concept2CharacteristicData? packet = parsePacket(data); + Concept2CharacteristicData? packet = _parsePacket(data); if (packet != null) { //send the data to the outgoing streams diff --git a/lib/src/helpers.dart b/lib/src/helpers.dart index e623a16..6e34071 100644 --- a/lib/src/helpers.dart +++ b/lib/src/helpers.dart @@ -8,6 +8,10 @@ import './packets/forcecurvepacket.dart'; import './packets/base.dart'; +/// Simplify mocking on [Dataplex] +typedef ParsePacketFn = Concept2CharacteristicData? Function(Uint8List); + +// Allow mapping functions typedef PacketParser = Concept2CharacteristicData Function(Uint8List data); /// Mapping of the first byte of the multiplexed packet to its parser function. From 9e493bff8ea95d9bba8c04b1cf9d4a21b24c422e Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Tue, 13 May 2025 20:44:33 +0000 Subject: [PATCH 191/220] test dataplex outgoing stream --- test/src/dataplex_test.dart | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/src/dataplex_test.dart b/test/src/dataplex_test.dart index 4a0e4ca..c326db5 100644 --- a/test/src/dataplex_test.dart +++ b/test/src/dataplex_test.dart @@ -18,6 +18,11 @@ class MockParse extends Mock { Concept2CharacteristicData? call(Uint8List bytes); } +class FakePacket extends Fake implements Concept2CharacteristicData { + @override + Map asMap() => {'foo': 42}; +} + void main() { setUpAll(() { registerFallbackValue(QualifiedCharacteristic( @@ -29,6 +34,7 @@ void main() { }); group('Dataplex', () { + // FIXME: Remove Dataplex subscription at declaration when _validateStreams is ready late MockBle ble; late DiscoveredDevice device; @@ -52,6 +58,36 @@ void main() { )), )); }); + + test('forwards packet maps to outgoing streams', () async { + final mockParse = MockParse(); + final fakePacket = FakePacket(); + when(() => mockParse(any())).thenReturn(fakePacket); + + final bleStream = StreamController>(); + when(() => ble.subscribeToCharacteristic(any())) + .thenAnswer((_) => bleStream.stream); + + final dataplex = Dataplex( + device, + ble, + parsePacketFn: mockParse, // inject mock parser + ); + + final out = dataplex.createStream({'foo'}.toSet()); + + // Add fake bytes to simulate notification + bleStream.add([0x00]); + + // Wait for output and verify + final result = await out.first; + expect(result, equals(fakePacket.asMap())); + + verify(() => mockParse(any())).called(1); + + await bleStream.close(); + }); + test('dispose cancels BLE subscriptions and closes outgoing streams', () async { final bleStream = StreamController(); From 49270126b257122c8431bc32d59f1af603918dad Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Tue, 13 May 2025 20:59:40 +0000 Subject: [PATCH 192/220] addSubscription just in time for stream creation and the ergometer is supposed to be connected --- lib/src/dataplex.dart | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index fff3cfb..e0c8b59 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -54,12 +54,7 @@ class Dataplex { bleClient, { @visibleForTesting ParsePacketFn? parsePacketFn, }) : _flutterReactiveBle = bleClient, - _parsePacket = parsePacketFn ?? parsePacket { - _addSubscription( - Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID, - Identifiers.C2_ROWING_MULTIPLEXED_INFORMATION_CHARACTERISTIC_UUID, - null); - } + _parsePacket = parsePacketFn ?? parsePacket {} ///Keeps track of how many characteristics we are currently receiving notifications for int _currentSubscriptionCount = 0; @@ -74,6 +69,15 @@ class Dataplex { outgoingStreams.add(controller); + // Multiplexed characteristic during initial stream creation + // TODO: This section will be removed later when _validateStreams is mature + if (currentSubscriptions.isEmpty) { + _addSubscription( + Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID, + Identifiers.C2_ROWING_MULTIPLEXED_INFORMATION_CHARACTERISTIC_UUID, + null); + } + return controller.stream; } From 220d925ed71721ca07ab150d5466209a7d26620f Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Tue, 13 May 2025 21:10:18 +0000 Subject: [PATCH 193/220] improving test information --- test/src/dataplex_test.dart | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/src/dataplex_test.dart b/test/src/dataplex_test.dart index c326db5..0244685 100644 --- a/test/src/dataplex_test.dart +++ b/test/src/dataplex_test.dart @@ -46,9 +46,12 @@ void main() { .thenAnswer((_) => const Stream.empty()); }); - test('creates multiplex subscription on construction', () { + test('dataplex construction sanity check', () { + // Dataplex construction follows Ergometer one + // We are not connected to the machine at this stage + // No ble action should be triggered Dataplex(device, ble); - + verifyNever(() => ble.connectToDevice(id: any(named: 'id'))); verifyNever(() => ble.subscribeToCharacteristic( any( that: isA().having( @@ -60,6 +63,8 @@ void main() { }); test('forwards packet maps to outgoing streams', () async { + // Ensure subscribed characteristic is parsed and channeled + // into outgoing streams final mockParse = MockParse(); final fakePacket = FakePacket(); when(() => mockParse(any())).thenReturn(fakePacket); From 3fb292d861906127160bdfc8a8f3a128eadb36af Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Tue, 13 May 2025 21:12:17 +0000 Subject: [PATCH 194/220] typo --- test/src/helpers_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/helpers_test.dart b/test/src/helpers_test.dart index f8eee6d..c5aca5e 100644 --- a/test/src/helpers_test.dart +++ b/test/src/helpers_test.dart @@ -6,7 +6,7 @@ import 'package:c2bluetooth/src/packets/keys.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { - group('Handle mutliplexed data', () { + group('Handle multiplexed data', () { test('parsePacket handles 0x35 StrokeData', () { // Construct a byte array representing a packet. final data = Uint8List.fromList([ From 1f36cdbcb67d578b89f415cc3ef81065c6424891 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Thu, 15 May 2025 10:22:01 +0000 Subject: [PATCH 195/220] fixing some definitions --- lib/src/packets/keys.dart | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/src/packets/keys.dart b/lib/src/packets/keys.dart index f59c117..d92284a 100644 --- a/lib/src/packets/keys.dart +++ b/lib/src/packets/keys.dart @@ -24,15 +24,14 @@ class Keys { static const WORKOUT_SPEED_KEY = "workout.speed"; static const WORKOUT_PACE_KEY = "workout.pace"; static const WORKOUT_POWER_KEY = "workout.watts"; - static const WORKOUT_WORK_KEY = "workout.joules"; - static const STROKE_DRIVE_LENGTH_KEY = 'stroke.drive_length'; static const STROKE_DRIVE_TIME_KEY = 'stroke.drive_time'; static const STROKE_RECOVERY_TIME_KEY = 'stroke.recovery_time'; static const STROKE_DISTANCE_KEY = 'stroke.stroke_distance'; - static const STROKE_PEAK_FORCE_KEY = 'stroke.force.peak'; - static const STROKE_AVG_FORCE_KEY = 'stroke.force.average'; + static const STROKE_PEAK_FORCE_KEY = 'stroke.drive_force.peak'; + static const STROKE_AVG_FORCE_KEY = 'stroke.drive_force.average'; static const STROKE_COUNT_KEY = 'stroke.count'; + static const STROKE_ENERGY_KEY = 'stroke.energy'; // rests are only applicable for intervals workouts static const WORKOUT_REST_DISTANCE_KEY = "workout.rest_distance"; static const WORKOUT_REST_TIME_KEY = "workout.rest_time"; From 5ef8f250be35d01407c0349ec9f59ae0bbca955b Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Thu, 15 May 2025 10:23:08 +0000 Subject: [PATCH 196/220] fixing value on DurationType enum --- lib/enums.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/enums.dart b/lib/enums.dart index af15985..6e68397 100644 --- a/lib/enums.dart +++ b/lib/enums.dart @@ -105,8 +105,8 @@ enum DurationType { extension DurationTypeExtension on DurationType { static Map _durationTypes = { DurationType.TIME: 0x00, - DurationType.DISTANCE: 0x40, - DurationType.CALORIES: 0x80, + DurationType.CALORIES: 0x40, + DurationType.DISTANCE: 0x80, DurationType.WATTMIN: 0xC0, }; From 60734c3f46bf1b1494c2546f9697cebaf684faa4 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Thu, 15 May 2025 10:23:51 +0000 Subject: [PATCH 197/220] adding StatusData definitions --- lib/src/packets/keys.dart | 13 +++ lib/src/packets/statusdata.dart | 147 +++++++++++++++++++++++++++++--- test/src/helpers_test.dart | 89 +++++++++++++++++++ 3 files changed, 237 insertions(+), 12 deletions(-) diff --git a/lib/src/packets/keys.dart b/lib/src/packets/keys.dart index d92284a..25e152c 100644 --- a/lib/src/packets/keys.dart +++ b/lib/src/packets/keys.dart @@ -2,6 +2,17 @@ class Keys { static const ELAPSED_TIME_KEY = "general.elapsed_time"; static const ELAPSED_DISTANCE_KEY = "general.distance"; + static const STATE_SEGMENT_TYPE_KEY = "state.interval.type"; + static const STATE_WORKOUT_KEY = "state.workout"; + static const STATE_WORKOUT_TYPE_KEY = "state.workout_type"; + static const STATE_ROWING_KEY = "state.rowing_activity"; + static const STATE_ROWING_STROKE_KEY = "state.rowing_stroke"; + static const WORKOUT_DURATION_UNIT_KEY = "workout_duration.type"; + static const WORKOUT_DURATION_KEY = "workout_duration"; + + static const WORKOUT_MACHINE_TYPE_KEY = "workout.machine_type"; + static const WORKOUT_DRAG_FACTOR_KEY = "workout.drag_factor"; + static const WORKOUT_TOTAL_DISTANCE_KEY = "workout.distance.total"; static const WORKOUT_TIMESTAMP_KEY = "workout.timestamp"; static const WORKOUT_SPM_KEY = "workout.stroke_rate"; static const WORKOUT_AVG_SPM_KEY = "workout.stroke_rate.average"; @@ -39,6 +50,8 @@ class Keys { static const SEGMENT_TIME_KEY = "segment.time"; static const SEGMENT_DISTANCE_KEY = "segment.distance"; + static const SEGMENT_LAST_TIME_KEY = "segment.time.last"; + static const SEGMENT_LAST_DISTANCE_KEY = "segment.distance.last"; static const SEGMENT_REST_TIME_KEY = "segment.interval.rest_time"; static const SEGMENT_REST_DISTANCE_KEY = "segment.interval.rest_distance"; static const SEGMENT_TYPE_KEY = "segment.type"; diff --git a/lib/src/packets/statusdata.dart b/lib/src/packets/statusdata.dart index 02f4f71..ee9fe7b 100644 --- a/lib/src/packets/statusdata.dart +++ b/lib/src/packets/statusdata.dart @@ -1,44 +1,136 @@ import 'dart:typed_data'; - +import 'package:c2bluetooth/c2bluetooth.dart'; import 'package:csafe_fitness/csafe_fitness.dart'; import './base.dart'; class StatusData extends ElapsedtimeStampedData { - double distance; + final double distance; // 0x01 = 0.1 meters + final WorkoutType workoutType; + final IntervalType intervalType; + final WorkoutState workoutState; + final RowingState rowingState; + final StrokeState strokeState; + final int totalWorkDistance; // meters + final double workoutDuration; // FIXME: Can also be Duration + final DurationType durationType; + final int dragFactor; static Set get datapointIdentifiers => StatusData.zero().asMap().keys.toSet(); - StatusData.zero() : this.fromBytes(Uint8List(20)); + StatusData.zero() : this.fromBytes(Uint8List(19)); StatusData.fromBytes(Uint8List data) : distance = CsafeIntExtension.fromBytes(data.sublist(3, 6), endian: Endian.little) / - 10, + 10.0, + workoutType = WorkoutTypeExtension.fromInt(data[6]), + intervalType = IntervalTypeExtension.fromInt(data[7]), + workoutState = WorkoutStateExtension.fromInt(data[8]), + rowingState = RowingStateExtension.fromInt(data[9]), + strokeState = StrokeStateExtension.fromInt(data[10]), + totalWorkDistance = CsafeIntExtension.fromBytes(data.sublist(11, 14), + endian: Endian.little), + durationType = DurationTypeExtension.fromInt(data[17]), + + workoutDuration = CsafeIntExtension.fromBytes(data.sublist(14, 17), + endian: Endian.little) / + (DurationTypeExtension.fromInt(data[17]) == DurationType.TIME + ? 100.0 + : 1), + dragFactor = data[18], super.fromBytes(data); - //TODO: add more data fields here + @override + Map asMap() { + Map map = super.asMap(); + map.addAll({ + Keys.ELAPSED_DISTANCE_KEY: distance, + Keys.STATE_WORKOUT_TYPE_KEY: workoutType, + Keys.STATE_SEGMENT_TYPE_KEY: intervalType, + Keys.STATE_WORKOUT_KEY: workoutState, + Keys.STATE_ROWING_KEY: rowingState, + Keys.STATE_ROWING_STROKE_KEY: strokeState, + Keys.WORKOUT_TOTAL_DISTANCE_KEY: totalWorkDistance, + Keys.WORKOUT_DURATION_KEY: workoutDuration, + Keys.WORKOUT_DURATION_UNIT_KEY: durationType, + Keys.WORKOUT_DRAG_FACTOR_KEY: dragFactor, + }); + return map; + } } class StatusData1 extends ElapsedtimeStampedData { - double speed; + final double speed; // 0x01 = 0.001 m/s + final int strokeRate; // strokes/min + final int heartRate; // bpm, 255=invalid + final Duration currentPace; // 0x01 = 0.01 sec per 500m + final Duration averagePace; // 0x01 = 0.01 sec per 500m + final int restDistance; // meters + final Duration restTime; // 0x01 = 0.01 seconds + final int averagePower; // watts + final MachineType ergMachineType; static Set get datapointIdentifiers => StatusData1.zero().asMap().keys.toSet(); - StatusData1.zero() : this.fromBytes(Uint8List(20)); + StatusData1.zero() : this.fromBytes(Uint8List(19)); StatusData1.fromBytes(Uint8List data) : speed = CsafeIntExtension.fromBytes(data.sublist(3, 5), endian: Endian.little) / - 1000, + 1000.0, + strokeRate = data[5], + heartRate = data[6], + currentPace = Duration( + milliseconds: CsafeIntExtension.fromBytes(data.sublist(7, 9), + endian: Endian.little) * + 10), + averagePace = Duration( + milliseconds: CsafeIntExtension.fromBytes(data.sublist(9, 11), + endian: Endian.little) * + 10), + restDistance = CsafeIntExtension.fromBytes(data.sublist(11, 13), + endian: Endian.little), + restTime = Duration( + milliseconds: CsafeIntExtension.fromBytes(data.sublist(13, 16), + endian: Endian.little) * + 10), + averagePower = CsafeIntExtension.fromBytes(data.sublist(16, 18), + endian: Endian.little), + ergMachineType = MachineTypeExtension.fromInt(data[18]), super.fromBytes(data); - //TODO: add more data fields here + + factory StatusData1.fromMultiplexed(Uint8List raw) => + StatusData1.fromBytes(raw.sublist(1)); + + @override + Map asMap() { + Map map = super.asMap(); + map.addAll({ + Keys.WORKOUT_SPEED_KEY: speed, + Keys.WORKOUT_SPM_KEY: strokeRate, + Keys.WORKOUT_HR_KEY: heartRate, + Keys.WORKOUT_PACE_KEY: currentPace, + Keys.WORKOUT_AVG_PACE_KEY: averagePace, + Keys.WORKOUT_REST_DISTANCE_KEY: restDistance, + Keys.WORKOUT_REST_TIME_KEY: restTime, + Keys.WORKOUT_AVG_POWER_KEY: averagePower, + Keys.WORKOUT_MACHINE_TYPE_KEY: ergMachineType, + }); + return map; + } } class StatusData2 extends ElapsedtimeStampedData { - int intervalCount; + final int intervalCount; + final int totalCalories; // cals + final Duration splitAvgPace; // 0x01 = 0.01 sec per 500m + final int splitAvgPower; // watts + final int splitAvgCalories; // cals + final Duration lastSplitTime; // 0x01 = 0.1 seconds + final int lastSplitDistance; // meters static Set get datapointIdentifiers => StatusData2.zero().asMap().keys.toSet(); @@ -46,8 +138,39 @@ class StatusData2 extends ElapsedtimeStampedData { StatusData2.zero() : this.fromBytes(Uint8List(20)); StatusData2.fromBytes(Uint8List data) - : intervalCount = data.elementAt(3), + : intervalCount = data[3], + totalCalories = CsafeIntExtension.fromBytes(data.sublist(4, 6), + endian: Endian.little), + splitAvgPace = Duration( + milliseconds: CsafeIntExtension.fromBytes(data.sublist(6, 8), + endian: Endian.little) * + 10), + splitAvgPower = CsafeIntExtension.fromBytes(data.sublist(8, 10), + endian: Endian.little), + splitAvgCalories = CsafeIntExtension.fromBytes(data.sublist(10, 12), + endian: Endian.little), + lastSplitTime = Duration( + milliseconds: CsafeIntExtension.fromBytes(data.sublist(12, 15), + endian: Endian.little) * + 100), + lastSplitDistance = CsafeIntExtension.fromBytes(data.sublist(15, 17), + endian: Endian.little), super.fromBytes(data); - //TODO: add more data fields here + factory StatusData2.fromMultiplexed(Uint8List raw) => + StatusData2.fromBytes(raw.sublist(1)); + + Map asMap() { + Map map = super.asMap(); + map.addAll({ + Keys.SEGMENT_NUMBER_KEY: intervalCount, + Keys.WORKOUT_CALORIES_KEY: totalCalories, + Keys.SEGMENT_AVG_PACE_KEY: splitAvgPace, + Keys.SEGMENT_AVG_POWER_KEY: splitAvgPower, + Keys.SEGMENT_AVG_CALORIES_KEY: splitAvgCalories, + Keys.SEGMENT_LAST_TIME_KEY: lastSplitTime, + Keys.SEGMENT_LAST_DISTANCE_KEY: lastSplitDistance, + }); + return map; + } } diff --git a/test/src/helpers_test.dart b/test/src/helpers_test.dart index c5aca5e..a0e43fe 100644 --- a/test/src/helpers_test.dart +++ b/test/src/helpers_test.dart @@ -7,6 +7,95 @@ import 'package:flutter_test/flutter_test.dart'; void main() { group('Handle multiplexed data', () { + test('parsePacket handles 0x31 StatusData', () { + // Construct a byte array representing a packet. + final data = Uint8List.fromList([ + 0x31, // packet ID + 0xE8, 0x03, 0x00, // elapsedTime: 1000 (0x0003E8) => 10 seconds + 0xE8, 0x03, 0x00, // distance: 1000 (0x0003E8) => 100 meters + 0x08, // workout type: 0x08 => VARIABLE_INTERVAL + 0x00, // interval type: 0x00 => TIME + 0x03, // workout state: 0x03 => INTERVALREST + 0x00, // rowing state: 0x00 => INACTIVE + 0x00, // stroke state: 0x00 => WAITING_FOR_WHEEL_TO_REACH_MIN_SPEED_STATE + 0xE8, 0x03, 0x00, // distance: 1000 meters + 0x02, 0x03, 0x00, // workout duration: 770 cals + 0x40, // duration type: 0x40 => calories + 0xFF, // drag factor: 0x55 => 255 + ]); + expect(data.lengthInBytes, equals(20)); + final status = parsePacket(data); + final map = status!.asMap(); + expect(map[Keys.ELAPSED_TIME_KEY], equals(Duration(seconds: 10))); + expect(map[Keys.ELAPSED_DISTANCE_KEY], equals(100.0)); + expect(map[Keys.STATE_WORKOUT_TYPE_KEY], + equals(WorkoutType.VARIABLE_INTERVAL)); + expect(map[Keys.STATE_SEGMENT_TYPE_KEY], equals(IntervalType.TIME)); + expect(map[Keys.STATE_WORKOUT_KEY], equals(WorkoutState.INTERVALREST)); + expect(map[Keys.STATE_ROWING_KEY], equals(RowingState.INACTIVE)); + expect(map[Keys.WORKOUT_DURATION_KEY], equals(770.0)); + expect( + map[Keys.WORKOUT_DURATION_UNIT_KEY], equals(DurationType.CALORIES)); + expect(map[Keys.STATE_ROWING_STROKE_KEY], + equals(StrokeState.WAITING_FOR_WHEEL_TO_REACH_MIN_SPEED_STATE)); + expect(map[Keys.WORKOUT_TOTAL_DISTANCE_KEY], equals(1000)); + expect(map[Keys.WORKOUT_DRAG_FACTOR_KEY], equals(255)); + }); + test('parsePacket handles 0x32 StatusData1', () { + // Construct a byte array representing a packet. + final data = Uint8List.fromList([ + 0x32, // packet ID + 0xE8, 0x03, 0x00, // elapsedTime: 1000 (0x0003E8) => 10 seconds + 0xE8, 0x03, // speed: 1000 (0x03E8) => 1 m/s + 0x2A, // stroke rate: (0x2A) => 42 strokes/min + 0xC4, // heart rate: (0xC4) => 196 bpm + 0xE0, 0x2E, // current pace: 12000 (0x2EE0) => 120 seconds + 0xE5, 0x2E, // average pace: 12005 (0x2EE5) => 120,05 seconds + 0xE5, 0x00, // rest distance: 229 (0x00E5) => 229 meters + 0xB8, 0x0B, 0x00, // rest time: 3000 (0x000BB8) => 30 seconds + 0xE6, 0x00, // average power: 230 (0x00E6) => 230 watts + 0x13, // erg machine type: 19 (0x13) => SLIDES_D + ]); + expect(data.lengthInBytes, equals(20)); + final status = parsePacket(data); + final map = status!.asMap(); + expect(map[Keys.ELAPSED_TIME_KEY], equals(Duration(seconds: 10))); + expect(map[Keys.WORKOUT_SPEED_KEY], equals(1.0)); + expect(map[Keys.WORKOUT_SPM_KEY], equals(42)); + expect(map[Keys.WORKOUT_HR_KEY], equals(196)); + expect(map[Keys.WORKOUT_PACE_KEY], equals(Duration(minutes: 2))); + expect(map[Keys.WORKOUT_AVG_PACE_KEY], + equals(Duration(minutes: 2, milliseconds: 50))); + expect(map[Keys.WORKOUT_REST_DISTANCE_KEY], equals(229)); + expect(map[Keys.WORKOUT_REST_TIME_KEY], equals(Duration(seconds: 30))); + expect(map[Keys.WORKOUT_AVG_POWER_KEY], equals(230)); + expect(map[Keys.WORKOUT_MACHINE_TYPE_KEY], equals(MachineType.SLIDES_D)); + }); + test('parsePacket handles 0x33 StatusData2', () { + // Construct a byte array representing a packet. + final data = Uint8List.fromList([ + 0x33, // packet ID + 0xE8, 0x03, 0x00, // elapsedTime: 1000 (0x0003E8) => 10 seconds + 0x10, // interval count: (0x10) => 16 interval + 0x2D, 0x00, // total calories: (0x002D) => 45 calories + 0x80, 0x3E, // segment avg pace: 16000 (0x03E80) => 160 seconds + 0x0E, 0x01, // segment avg power: (0x010E) => 270 watts + 0x10, 0x00, // segment avg calories: (0x10) => 16 calories + 0x4A, 0x06, 0x00, // last split time: 1610 (0x0000A1) => 161 seconds + 0xF4, 0x01, 0x00, // last split distance: 500 (0x0001F4) => 500 meters + ]); + expect(data.lengthInBytes, equals(19)); + final status = parsePacket(data); + final map = status!.asMap(); + expect(map[Keys.ELAPSED_TIME_KEY], equals(Duration(seconds: 10))); + expect(map[Keys.SEGMENT_NUMBER_KEY], equals(16)); + expect(map[Keys.WORKOUT_CALORIES_KEY], equals(45)); + expect(map[Keys.SEGMENT_AVG_PACE_KEY], equals(Duration(seconds: 160))); + expect(map[Keys.SEGMENT_AVG_POWER_KEY], equals(270)); + expect(map[Keys.SEGMENT_AVG_CALORIES_KEY], equals(16)); + expect(map[Keys.SEGMENT_LAST_TIME_KEY], equals(Duration(seconds: 161))); + expect(map[Keys.SEGMENT_LAST_DISTANCE_KEY], equals(500)); + }); test('parsePacket handles 0x35 StrokeData', () { // Construct a byte array representing a packet. final data = Uint8List.fromList([ From 8d28767fe5bfce2e73633bf6af00a8f0cd179445 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Thu, 15 May 2025 19:05:53 +0000 Subject: [PATCH 198/220] log unkown packet data as list of RadixString --- lib/src/dataplex.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index e0c8b59..ea435d6 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -126,7 +126,8 @@ class Dataplex { } } else { print("Couldnt parse packet from data"); - print("packet data: $data"); + print( + "packet data: ${data.map((e) => e.toRadixString(16).padLeft(2, '0')).join(',')}"); } } From 54739dff36eecc60dcb51c6da6b5ade03544c09f Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Fri, 16 May 2025 19:22:11 +0000 Subject: [PATCH 199/220] adding StatusData3 --- lib/enums.dart | 71 +++++++++++++++++++++++++++++++++ lib/src/helpers.dart | 1 + lib/src/packets/keys.dart | 9 +++++ lib/src/packets/statusdata.dart | 48 ++++++++++++++++++++++ test/src/helpers_test.dart | 29 ++++++++++++++ 5 files changed, 158 insertions(+) diff --git a/lib/enums.dart b/lib/enums.dart index 6e68397..b1fd795 100644 --- a/lib/enums.dart +++ b/lib/enums.dart @@ -430,3 +430,74 @@ extension WorkoutScreenValueExtension on WorkoutScreenValue { static WorkoutScreenValue fromInt(int i) => _racingScreenValues.map((key, value) => MapEntry(value, key))[i]; } + +enum OperationalState { + /// Reset state (0). + OPERATIONALSTATE_RESET, + + /// Ready state (1). + OPERATIONALSTATE_READY, + + /// Workout state (2). + OPERATIONALSTATE_WORKOUT, + + /// Warm-up state (3). + OPERATIONALSTATE_WARMUP, + + /// Race state (4). + OPERATIONALSTATE_RACE, + + /// Power-off state (5). + OPERATIONALSTATE_POWEROFF, + + /// Pause state (6). + OPERATIONALSTATE_PAUSE, + + /// Invoke boot loader state (7). + OPERATIONALSTATE_INVOKEBOOTLOADER, + + /// Power-off ship state (8). + OPERATIONALSTATE_POWEROFF_SHIP, + + /// Idle charge state (9). + OPERATIONALSTATE_IDLE_CHARGE, + + /// Idle state (10). + OPERATIONALSTATE_IDLE, + + /// Manufacturing test state (11). + OPERATIONALSTATE_MFGTEST, + + /// Firmware update state (12). + OPERATIONALSTATE_FWUPDATE, + + /// Drag factor state (13). + OPERATIONALSTATE_DRAGFACTOR, + + /// Drag factor calibration state (100). + OPERATIONALSTATE_DFCALIBRATION // = 100 +} + +extension OperationalStateExtension on OperationalState { + static Map _operationalStateValues = { + OperationalState.OPERATIONALSTATE_RESET: 0, + OperationalState.OPERATIONALSTATE_READY: 1, + OperationalState.OPERATIONALSTATE_WORKOUT: 2, + OperationalState.OPERATIONALSTATE_WARMUP: 3, + OperationalState.OPERATIONALSTATE_RACE: 4, + OperationalState.OPERATIONALSTATE_POWEROFF: 5, + OperationalState.OPERATIONALSTATE_PAUSE: 6, + OperationalState.OPERATIONALSTATE_INVOKEBOOTLOADER: 7, + OperationalState.OPERATIONALSTATE_POWEROFF_SHIP: 8, + OperationalState.OPERATIONALSTATE_IDLE_CHARGE: 9, + OperationalState.OPERATIONALSTATE_IDLE: 10, + OperationalState.OPERATIONALSTATE_MFGTEST: 11, + OperationalState.OPERATIONALSTATE_FWUPDATE: 12, + OperationalState.OPERATIONALSTATE_DRAGFACTOR: 13, + OperationalState.OPERATIONALSTATE_DFCALIBRATION: 100, + }; + int get value => _operationalStateValues[this]; + //TODO: error if values not found + static OperationalState fromInt(int i) => + _operationalStateValues.map((key, value) => MapEntry(value, key))[i]; +} diff --git a/lib/src/helpers.dart b/lib/src/helpers.dart index 6e34071..0546813 100644 --- a/lib/src/helpers.dart +++ b/lib/src/helpers.dart @@ -26,6 +26,7 @@ final Map _packetParsers = { 0x39: (data) => WorkoutSummaryPacket.fromBytes(data), 0x3A: (data) => WorkoutSummaryPacket2.fromBytes(data), 0x3C: (data) => ForceCurveData.fromBytes(data), + 0x3E: (data) => StatusData3.fromBytes(data), }; /// Attempts to parse a multiplexed Concept2 data packet. diff --git a/lib/src/packets/keys.dart b/lib/src/packets/keys.dart index 25e152c..99c65c2 100644 --- a/lib/src/packets/keys.dart +++ b/lib/src/packets/keys.dart @@ -7,6 +7,15 @@ class Keys { static const STATE_WORKOUT_TYPE_KEY = "state.workout_type"; static const STATE_ROWING_KEY = "state.rowing_activity"; static const STATE_ROWING_STROKE_KEY = "state.rowing_stroke"; + static const STATE_OPERATIONAL_STATE_KEY = "state.operational_state"; + static const STATE_WORKOUT_VERIFICATION_KEY = "state.workout_verification"; + static const STATE_SCREEN_TYPE_KEY = "state.screen"; + static const STATE_LAST_ERROR_KEY = "state.error.last"; + static const STATE_CALIBRATION_MODE_KEY = "state.calibration.mode"; + static const STATE_CALIBRATION_KEY = "state.calibration"; + static const STATE_CALIBRATION_STATUS_KEY = "state.calibration.status"; + static const STATE_GAME_ID_KEY = "state.game.id"; + static const STATE_GAME_SCORE_KEY = "state.game.score"; static const WORKOUT_DURATION_UNIT_KEY = "workout_duration.type"; static const WORKOUT_DURATION_KEY = "workout_duration"; diff --git a/lib/src/packets/statusdata.dart b/lib/src/packets/statusdata.dart index ee9fe7b..c5174be 100644 --- a/lib/src/packets/statusdata.dart +++ b/lib/src/packets/statusdata.dart @@ -174,3 +174,51 @@ class StatusData2 extends ElapsedtimeStampedData { return map; } } + +class StatusData3 extends Concept2CharacteristicData { + final OperationalState operationalState; + final int workoutVerificationState; + final WorkoutScreenValue screenNumber; + final int lastError; + final int calibrationMode; + final int calibrationState; + final int calibrationStatus; + final GameId gameID; + final int gameScore; + + static Set get datapointIdentifiers => + StatusData2.zero().asMap().keys.toSet(); + + StatusData3.zero() : this.fromBytes(Uint8List(20)); + + StatusData3.fromBytes(Uint8List data) + : operationalState = OperationalStateExtension.fromInt(data[0]), + workoutVerificationState = data[1], + screenNumber = WorkoutScreenValueExtension.fromInt( + CsafeIntExtension.fromBytes(data.sublist(2, 4), + endian: Endian.little)), + lastError = CsafeIntExtension.fromBytes(data.sublist(4, 6), + endian: Endian.little), + calibrationMode = data[6], + calibrationState = data[7], + calibrationStatus = data[8], + gameID = GameIdExtension.fromInt(data[9]), + gameScore = CsafeIntExtension.fromBytes(data.sublist(10, 12), + endian: Endian.little); + + Map asMap() { + Map map = super.asMap(); + map.addAll({ + Keys.STATE_OPERATIONAL_STATE_KEY: operationalState, + Keys.STATE_WORKOUT_VERIFICATION_KEY: workoutVerificationState, + Keys.STATE_SCREEN_TYPE_KEY: screenNumber, + Keys.STATE_LAST_ERROR_KEY: lastError, + Keys.STATE_CALIBRATION_MODE_KEY: calibrationMode, + Keys.STATE_CALIBRATION_KEY: calibrationState, + Keys.STATE_CALIBRATION_STATUS_KEY: calibrationStatus, + Keys.STATE_GAME_ID_KEY: gameID, + Keys.STATE_GAME_SCORE_KEY: gameScore, + }); + return map; + } +} diff --git a/test/src/helpers_test.dart b/test/src/helpers_test.dart index a0e43fe..3b2b91f 100644 --- a/test/src/helpers_test.dart +++ b/test/src/helpers_test.dart @@ -96,6 +96,35 @@ void main() { expect(map[Keys.SEGMENT_LAST_TIME_KEY], equals(Duration(seconds: 161))); expect(map[Keys.SEGMENT_LAST_DISTANCE_KEY], equals(500)); }); + test('parsePacket handles 0x3E StatusData3', () { + // Construct a byte array representing a packet. + final data = Uint8List.fromList([ + 0x3E, // packet ID + 0x0A, // operational state: 10 (0x0A) => Idle + 0x00, // workout verification: 0 => ? + 0x05, 0x00, // screen number: 5 => PREPARETORACESTART + 0x02, 0x00, // last error: 2 ? + 0x00, // calibration mode: 0 + 0x00, // calibration state: 0 + 0x00, // calibration status: 0 + 0x01, // game id: 1 => Fish + 0x02, 0x00, // game score: 2 + ]); + expect(data.lengthInBytes, equals(13)); + final status = parsePacket(data); + final map = status!.asMap(); + expect(map[Keys.STATE_OPERATIONAL_STATE_KEY], + equals(OperationalState.OPERATIONALSTATE_IDLE)); + expect(map[Keys.STATE_WORKOUT_VERIFICATION_KEY], equals(0)); + expect(map[Keys.STATE_SCREEN_TYPE_KEY], + equals(WorkoutScreenValue.PREPARETORACESTART)); + expect(map[Keys.STATE_LAST_ERROR_KEY], equals(2)); + expect(map[Keys.STATE_CALIBRATION_MODE_KEY], equals(0)); + expect(map[Keys.STATE_CALIBRATION_KEY], equals(0)); + expect(map[Keys.STATE_CALIBRATION_STATUS_KEY], equals(0)); + expect(map[Keys.STATE_GAME_ID_KEY], equals(GameId.FISH)); + expect(map[Keys.STATE_GAME_SCORE_KEY], equals(2)); + }); test('parsePacket handles 0x35 StrokeData', () { // Construct a byte array representing a packet. final data = Uint8List.fromList([ From d36f09bb2a6f12d4ee0045bdcdc7976c0d899919 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Fri, 16 May 2025 19:23:07 +0000 Subject: [PATCH 200/220] removing stuff that wasn't supposed to be pushed --- lib/src/packets/statusdata.dart | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/src/packets/statusdata.dart b/lib/src/packets/statusdata.dart index c5174be..1dec42b 100644 --- a/lib/src/packets/statusdata.dart +++ b/lib/src/packets/statusdata.dart @@ -33,7 +33,6 @@ class StatusData extends ElapsedtimeStampedData { totalWorkDistance = CsafeIntExtension.fromBytes(data.sublist(11, 14), endian: Endian.little), durationType = DurationTypeExtension.fromInt(data[17]), - workoutDuration = CsafeIntExtension.fromBytes(data.sublist(14, 17), endian: Endian.little) / (DurationTypeExtension.fromInt(data[17]) == DurationType.TIME @@ -102,9 +101,6 @@ class StatusData1 extends ElapsedtimeStampedData { ergMachineType = MachineTypeExtension.fromInt(data[18]), super.fromBytes(data); - factory StatusData1.fromMultiplexed(Uint8List raw) => - StatusData1.fromBytes(raw.sublist(1)); - @override Map asMap() { Map map = super.asMap(); @@ -157,9 +153,6 @@ class StatusData2 extends ElapsedtimeStampedData { endian: Endian.little), super.fromBytes(data); - factory StatusData2.fromMultiplexed(Uint8List raw) => - StatusData2.fromBytes(raw.sublist(1)); - Map asMap() { Map map = super.asMap(); map.addAll({ From a46a541c299c12b7f6126ad161557c5a7845fe50 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Fri, 16 May 2025 20:56:13 +0000 Subject: [PATCH 201/220] fix: screen number is an integer --- lib/src/packets/keys.dart | 2 +- lib/src/packets/statusdata.dart | 9 ++++----- test/src/helpers_test.dart | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/src/packets/keys.dart b/lib/src/packets/keys.dart index 99c65c2..cfd1220 100644 --- a/lib/src/packets/keys.dart +++ b/lib/src/packets/keys.dart @@ -9,7 +9,7 @@ class Keys { static const STATE_ROWING_STROKE_KEY = "state.rowing_stroke"; static const STATE_OPERATIONAL_STATE_KEY = "state.operational_state"; static const STATE_WORKOUT_VERIFICATION_KEY = "state.workout_verification"; - static const STATE_SCREEN_TYPE_KEY = "state.screen"; + static const STATE_SCREEN_NUMBER_KEY = "state.screen.number"; static const STATE_LAST_ERROR_KEY = "state.error.last"; static const STATE_CALIBRATION_MODE_KEY = "state.calibration.mode"; static const STATE_CALIBRATION_KEY = "state.calibration"; diff --git a/lib/src/packets/statusdata.dart b/lib/src/packets/statusdata.dart index 1dec42b..55675fe 100644 --- a/lib/src/packets/statusdata.dart +++ b/lib/src/packets/statusdata.dart @@ -171,7 +171,7 @@ class StatusData2 extends ElapsedtimeStampedData { class StatusData3 extends Concept2CharacteristicData { final OperationalState operationalState; final int workoutVerificationState; - final WorkoutScreenValue screenNumber; + final int screenNumber; final int lastError; final int calibrationMode; final int calibrationState; @@ -187,9 +187,8 @@ class StatusData3 extends Concept2CharacteristicData { StatusData3.fromBytes(Uint8List data) : operationalState = OperationalStateExtension.fromInt(data[0]), workoutVerificationState = data[1], - screenNumber = WorkoutScreenValueExtension.fromInt( - CsafeIntExtension.fromBytes(data.sublist(2, 4), - endian: Endian.little)), + screenNumber = CsafeIntExtension.fromBytes(data.sublist(2, 4), + endian: Endian.little), lastError = CsafeIntExtension.fromBytes(data.sublist(4, 6), endian: Endian.little), calibrationMode = data[6], @@ -204,7 +203,7 @@ class StatusData3 extends Concept2CharacteristicData { map.addAll({ Keys.STATE_OPERATIONAL_STATE_KEY: operationalState, Keys.STATE_WORKOUT_VERIFICATION_KEY: workoutVerificationState, - Keys.STATE_SCREEN_TYPE_KEY: screenNumber, + Keys.STATE_SCREEN_NUMBER_KEY: screenNumber, Keys.STATE_LAST_ERROR_KEY: lastError, Keys.STATE_CALIBRATION_MODE_KEY: calibrationMode, Keys.STATE_CALIBRATION_KEY: calibrationState, diff --git a/test/src/helpers_test.dart b/test/src/helpers_test.dart index 3b2b91f..55fe571 100644 --- a/test/src/helpers_test.dart +++ b/test/src/helpers_test.dart @@ -116,7 +116,7 @@ void main() { expect(map[Keys.STATE_OPERATIONAL_STATE_KEY], equals(OperationalState.OPERATIONALSTATE_IDLE)); expect(map[Keys.STATE_WORKOUT_VERIFICATION_KEY], equals(0)); - expect(map[Keys.STATE_SCREEN_TYPE_KEY], + expect(map[Keys.STATE_SCREEN_NUMBER_KEY], equals(WorkoutScreenValue.PREPARETORACESTART)); expect(map[Keys.STATE_LAST_ERROR_KEY], equals(2)); expect(map[Keys.STATE_CALIBRATION_MODE_KEY], equals(0)); From 5431a704752b4a20ebb2f69a66a6ff01ba01ca7d Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sat, 17 May 2025 11:56:40 +0000 Subject: [PATCH 202/220] deriving timestamp --- lib/src/packets/base.dart | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/src/packets/base.dart b/lib/src/packets/base.dart index 8182cbd..bf7b674 100644 --- a/lib/src/packets/base.dart +++ b/lib/src/packets/base.dart @@ -19,8 +19,15 @@ class TimestampedData extends Concept2CharacteristicData { TimestampedData.zero() : this.fromBytes(Uint8List(20)); + // DatetTime is a modified versions BCD scheme: + // https://github.com/MoralCode/c2-missing-spec/blob/main/concept2-the-missing-spec.md#date-and-time-formats TimestampedData.fromBytes(Uint8List bytes) - : timestamp = Concept2DateExtension.fromBytes(bytes.sublist(0, 4)); + : timestamp = DateTime( + 2000 + ((bytes[1] & 0xFE) >> 1), + bytes[0] & 0x0F, + ((bytes[1] & 0x01) << 4) + ((bytes[0] & 0xF0) >> 4), + bytes[3], + bytes[2]); Map asMap() { Map map = super.asMap(); From 481638844994c9cdd43fb66892951c0a24a8b52e Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sat, 17 May 2025 11:58:12 +0000 Subject: [PATCH 203/220] fixing mux mapping --- lib/src/helpers.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/src/helpers.dart b/lib/src/helpers.dart index 0546813..6453b52 100644 --- a/lib/src/helpers.dart +++ b/lib/src/helpers.dart @@ -24,8 +24,10 @@ final Map _packetParsers = { 0x37: (data) => SegmentData1.fromBytes(data), 0x38: (data) => SegmentData2.fromBytes(data), 0x39: (data) => WorkoutSummaryPacket.fromBytes(data), - 0x3A: (data) => WorkoutSummaryPacket2.fromBytes(data), - 0x3C: (data) => ForceCurveData.fromBytes(data), + 0x3A: (data) => WorkoutSummaryPacket1.fromBytes(data), + //0x3B: (data) => HeartRateBeltPacket.fromBytes(data), + 0x3C: (data) => WorkoutSummaryPacket2.fromBytes(data), + 0x3D: (data) => ForceCurveData.fromBytes(data), 0x3E: (data) => StatusData3.fromBytes(data), }; From 417e877e1d3c9f41dad5e7407d907112cf10a53d Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sat, 17 May 2025 15:19:31 +0000 Subject: [PATCH 204/220] adding belt packet --- lib/src/helpers.dart | 3 ++- lib/src/packets/belt.dart | 30 ++++++++++++++++++++++++++++++ lib/src/packets/keys.dart | 5 +++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 lib/src/packets/belt.dart diff --git a/lib/src/helpers.dart b/lib/src/helpers.dart index 6453b52..af6e62a 100644 --- a/lib/src/helpers.dart +++ b/lib/src/helpers.dart @@ -5,6 +5,7 @@ import './packets/strokedata.dart'; import './packets/segmentdata.dart'; import './packets/workoutsummary.dart'; import './packets/forcecurvepacket.dart'; +import './packets/belt.dart'; import './packets/base.dart'; @@ -25,7 +26,7 @@ final Map _packetParsers = { 0x38: (data) => SegmentData2.fromBytes(data), 0x39: (data) => WorkoutSummaryPacket.fromBytes(data), 0x3A: (data) => WorkoutSummaryPacket1.fromBytes(data), - //0x3B: (data) => HeartRateBeltPacket.fromBytes(data), + 0x3B: (data) => HeartRateBeltPacket.fromBytes(data), 0x3C: (data) => WorkoutSummaryPacket2.fromBytes(data), 0x3D: (data) => ForceCurveData.fromBytes(data), 0x3E: (data) => StatusData3.fromBytes(data), diff --git a/lib/src/packets/belt.dart b/lib/src/packets/belt.dart new file mode 100644 index 0000000..4ec923d --- /dev/null +++ b/lib/src/packets/belt.dart @@ -0,0 +1,30 @@ +import 'dart:typed_data'; + +import 'package:csafe_fitness/csafe_fitness.dart'; + +import './base.dart'; +import 'keys.dart'; + +/// Represents the heart rate belt packet +class HeartRateBeltPacket extends Concept2CharacteristicData { + int manufacturerID; + int deviceType; + int beltID; + + static Set get datapointIdentifiers => + HeartRateBeltPacket.zero().asMap().keys.toSet(); + + /// Construct a WorkoutSummary from the bytes returned from the erg + HeartRateBeltPacket.fromBytes(Uint8List data) + : manufacturerID = data[0], + deviceType = data[1], + beltID = CsafeIntExtension.fromBytes(data.sublist(2, 6)); + + HeartRateBeltPacket.zero() : this.fromBytes(Uint8List(19)); + + Map asMap() => { + Keys.BELT_MANUFACTURER_ID_KEY: manufacturerID, + Keys.BELT_DEVICE_TYPE_KEY: deviceType, + Keys.BELT_DEVICE_ID_KEY: beltID, + }; +} diff --git a/lib/src/packets/keys.dart b/lib/src/packets/keys.dart index cfd1220..8324e3d 100644 --- a/lib/src/packets/keys.dart +++ b/lib/src/packets/keys.dart @@ -16,6 +16,11 @@ class Keys { static const STATE_CALIBRATION_STATUS_KEY = "state.calibration.status"; static const STATE_GAME_ID_KEY = "state.game.id"; static const STATE_GAME_SCORE_KEY = "state.game.score"; + + static const BELT_MANUFACTURER_ID_KEY = "belt.manufacturer"; + static const BELT_DEVICE_TYPE_KEY = "belt.type"; + static const BELT_DEVICE_ID_KEY = "belt.id"; + static const WORKOUT_DURATION_UNIT_KEY = "workout_duration.type"; static const WORKOUT_DURATION_KEY = "workout_duration"; From 4e361db5bf8bf8ee507820f6c7dbe0f9f25ee63b Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sat, 17 May 2025 15:20:54 +0000 Subject: [PATCH 205/220] adding WorkoutSummaryPacke2 --- lib/src/packets/workoutsummary.dart | 62 +++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index 23179a5..64e3631 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -79,8 +79,7 @@ class WorkoutSummaryPacket extends TimestampedData { } } -class WorkoutSummaryPacket2 extends TimestampedData { - IntervalType intervalType; +class WorkoutSummaryPacket1 extends TimestampedData { int intervalSize; int intervalCount; int totalCalories; @@ -90,26 +89,25 @@ class WorkoutSummaryPacket2 extends TimestampedData { int avgCalories; static Set get datapointIdentifiers => - WorkoutSummaryPacket2.zero().asMap().keys.toSet(); + WorkoutSummaryPacket1.zero().asMap().keys.toSet(); - WorkoutSummaryPacket2.fromBytes(Uint8List data) - : intervalType = IntervalTypeExtension.fromInt(data.elementAt(4)), - intervalSize = CsafeIntExtension.fromBytes(data.sublist(5, 7), + WorkoutSummaryPacket1.fromBytes(Uint8List data) + : intervalSize = CsafeIntExtension.fromBytes(data.sublist(4, 6), endian: Endian.little), - intervalCount = data.elementAt(7), - totalCalories = CsafeIntExtension.fromBytes(data.sublist(8, 10), + intervalCount = data.elementAt(6), + totalCalories = CsafeIntExtension.fromBytes(data.sublist(7, 9), endian: Endian.little), - watts = CsafeIntExtension.fromBytes(data.sublist(10, 12), + watts = CsafeIntExtension.fromBytes(data.sublist(9, 11), endian: Endian.little), - totalRestDistance = CsafeIntExtension.fromBytes(data.sublist(12, 15), + totalRestDistance = CsafeIntExtension.fromBytes(data.sublist(11, 13), endian: Endian.little), - intervalRestTime = CsafeIntExtension.fromBytes(data.sublist(15, 17), + intervalRestTime = CsafeIntExtension.fromBytes(data.sublist(13, 16), endian: Endian.little), - avgCalories = CsafeIntExtension.fromBytes(data.sublist(17, 19), + avgCalories = CsafeIntExtension.fromBytes(data.sublist(16, 18), endian: Endian.little), super.fromBytes(data); - WorkoutSummaryPacket2.zero() : this.fromBytes(Uint8List(19)); + WorkoutSummaryPacket1.zero() : this.fromBytes(Uint8List(18)); Map asMap() { // workout.heart_rate @@ -128,3 +126,41 @@ class WorkoutSummaryPacket2 extends TimestampedData { return map; } } + +class WorkoutSummaryPacket2 extends TimestampedData { + int avgPace; + GameId gameID; + int verifier; + int gameScore; + MachineType machineType; + + static Set get datapointIdentifiers => + WorkoutSummaryPacket2.zero().asMap().keys.toSet(); + + WorkoutSummaryPacket2.zero() : this.fromBytes(Uint8List(10)); + + WorkoutSummaryPacket2.fromBytes(Uint8List data) + : avgPace = CsafeIntExtension.fromBytes(data.sublist(4, 6), + endian: Endian.little), + gameID = GameIdExtension.fromInt(data.elementAt(6) & 0x0F), + verifier = (data.elementAt(6) & 0xF0) >> 4, + gameScore = CsafeIntExtension.fromBytes(data.sublist(7, 9), + endian: Endian.little), + machineType = MachineTypeExtension.fromInt(data.elementAt(9)), + super.fromBytes(data); + + Map asMap() { + // workout.heart_rate + // workout.interval_rest_distance + Map map = super.asMap(); + map.addAll({ + Keys.SUMMARY_AVG_PACE_KEY: avgPace, + Keys.STATE_GAME_ID_KEY: gameID, + Keys.STATE_WORKOUT_VERIFICATION_KEY: verifier, + // "workout.interval_rest_distance": , + Keys.STATE_GAME_SCORE_KEY: gameScore, + Keys.WORKOUT_MACHINE_TYPE_KEY: machineType + }); + return map; + } +} From 499be44cf1da5592dd2be7b213d9c8db1b07e75c Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sat, 17 May 2025 15:22:16 +0000 Subject: [PATCH 206/220] fixing key to work distance --- lib/src/packets/workoutsummary.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index 64e3631..7f61417 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -63,7 +63,7 @@ class WorkoutSummaryPacket extends TimestampedData { Map map = super.asMap(); map.addAll({ Keys.ELAPSED_TIME_KEY: elapsedTime, - Keys.ELAPSED_DISTANCE_KEY: workDistance, + Keys.WORKOUT_DISTANCE_KEY: workDistance, Keys.WORKOUT_AVG_SPM_KEY: avgSPM, Keys.WORKOUT_LAST_HR_KEY: endHeartRate, Keys.WORKOUT_AVG_HR_KEY: avgHeartRate, From f0d1a06645e06f90ad096bff26d80b7e76fa11c3 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sat, 17 May 2025 15:22:42 +0000 Subject: [PATCH 207/220] adding workout distance --- lib/src/packets/keys.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/packets/keys.dart b/lib/src/packets/keys.dart index 8324e3d..1784d88 100644 --- a/lib/src/packets/keys.dart +++ b/lib/src/packets/keys.dart @@ -26,6 +26,7 @@ class Keys { static const WORKOUT_MACHINE_TYPE_KEY = "workout.machine_type"; static const WORKOUT_DRAG_FACTOR_KEY = "workout.drag_factor"; + static const WORKOUT_DISTANCE_KEY = "workout.distance"; static const WORKOUT_TOTAL_DISTANCE_KEY = "workout.distance.total"; static const WORKOUT_TIMESTAMP_KEY = "workout.timestamp"; static const WORKOUT_SPM_KEY = "workout.stroke_rate"; From c7cc3bd784797e4841ece35e14e0ed5b7f987610 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sat, 17 May 2025 15:24:36 +0000 Subject: [PATCH 208/220] adding raw packet data print in debug mode --- lib/src/packets/keys.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/packets/keys.dart b/lib/src/packets/keys.dart index 1784d88..7d8f0a2 100644 --- a/lib/src/packets/keys.dart +++ b/lib/src/packets/keys.dart @@ -16,6 +16,7 @@ class Keys { static const STATE_CALIBRATION_STATUS_KEY = "state.calibration.status"; static const STATE_GAME_ID_KEY = "state.game.id"; static const STATE_GAME_SCORE_KEY = "state.game.score"; + static const SUMMARY_AVG_PACE_KEY = "summary.pace.average"; static const BELT_MANUFACTURER_ID_KEY = "belt.manufacturer"; static const BELT_DEVICE_TYPE_KEY = "belt.type"; From c3917ef6f0e5e7bea8ccdd8b9d23fab89b623908 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Sat, 17 May 2025 15:25:07 +0000 Subject: [PATCH 209/220] adding raw packet print only on debug --- lib/src/helpers.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/src/helpers.dart b/lib/src/helpers.dart index af6e62a..f43ef35 100644 --- a/lib/src/helpers.dart +++ b/lib/src/helpers.dart @@ -1,4 +1,4 @@ -import 'dart:typed_data'; +import 'package:flutter/foundation.dart'; import './packets/statusdata.dart'; import './packets/strokedata.dart'; @@ -36,8 +36,9 @@ final Map _packetParsers = { /// Returns `null` if the packet ID is unknown or the data is empty. Concept2CharacteristicData? parsePacket(Uint8List data) { if (data.isEmpty) return null; - final id = data[0]; final parser = _packetParsers[id]; + debugPrint( + "packet data: ${data.map((e) => e.toRadixString(16).padLeft(2, '0')).join(',')}"); return parser?.call(data.sublist(1)); } From fdc377160d439a86e3b88bcf0c2674445804ca47 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Mon, 19 May 2025 11:52:54 +0000 Subject: [PATCH 210/220] bumping setup-dart and flutter-action versions --- .github/workflows/dart.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index e2b8fc2..7d9368e 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -23,12 +23,12 @@ jobs: # https://github.com/dart-lang/setup-dart/blob/main/README.md - uses: dart-lang/setup-dart@v1 with: - sdk: 3.1.3 + sdk: stable - - uses: subosito/flutter-action@v1 + - uses: subosito/flutter-action@v2 with: channel: 'stable' - flutter-version: 3.13.0 + flutter-version: 3.19.0 - name: Install dependencies run: flutter pub get From ec3c4f954b12621f2136faef1960471b3a46a9e1 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Mon, 19 May 2025 11:52:54 +0000 Subject: [PATCH 211/220] bumping setup-dart and flutter-action versions --- .github/workflows/dart.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index e2b8fc2..7d9368e 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -23,12 +23,12 @@ jobs: # https://github.com/dart-lang/setup-dart/blob/main/README.md - uses: dart-lang/setup-dart@v1 with: - sdk: 3.1.3 + sdk: stable - - uses: subosito/flutter-action@v1 + - uses: subosito/flutter-action@v2 with: channel: 'stable' - flutter-version: 3.13.0 + flutter-version: 3.19.0 - name: Install dependencies run: flutter pub get From b029373f202bc95419fb99a6264249504664d9a6 Mon Sep 17 00:00:00 2001 From: bertrand esperou Date: Tue, 20 May 2025 15:20:35 +0200 Subject: [PATCH 212/220] defer subscription until after device connection --- lib/models/ergometer.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/models/ergometer.dart b/lib/models/ergometer.dart index 680ac94..2c1b94f 100644 --- a/lib/models/ergometer.dart +++ b/lib/models/ergometer.dart @@ -36,9 +36,6 @@ class Ergometer { /// Connect to this erg and discover the services and characteristics that it offers /// this returns a stream of [ErgometerConnectionState] events to enable monitoring the erg's connection state and disconnecting. Stream connectAndDiscover() { - //having this first might cause problems - _csafeClient = Csafe(_readCsafe, _writeCsafe); - //this may cause problems if the device goes out of range between scenning and trying to connect. maybe use connectToAdvertisingDevice instead to mitigate this and prevent a hang on android //if no services are specified in the `servicesWithCharacteristicsToDiscover` parameter, then full service discovery will be performed @@ -47,6 +44,7 @@ class Ergometer { .handleError((error) => throw C2ConnectionException('Error while connecting', error)); _dataplex = new Dataplex(_peripheral, _flutterReactiveBle); + _csafeClient = Csafe(_readCsafe, _writeCsafe); return getMonitorConnectionState; } From c1161cfb82651b2f1c354e12c67c3d70c80b8a56 Mon Sep 17 00:00:00 2001 From: bertrand esperou Date: Tue, 20 May 2025 15:21:47 +0200 Subject: [PATCH 213/220] fix: there is no known enum to SCREENNUMBER --- test/src/helpers_test.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/src/helpers_test.dart b/test/src/helpers_test.dart index 55fe571..9b53c59 100644 --- a/test/src/helpers_test.dart +++ b/test/src/helpers_test.dart @@ -102,7 +102,7 @@ void main() { 0x3E, // packet ID 0x0A, // operational state: 10 (0x0A) => Idle 0x00, // workout verification: 0 => ? - 0x05, 0x00, // screen number: 5 => PREPARETORACESTART + 0x01, 0x00, // screen number: 1 => HOME SCREEN 0x02, 0x00, // last error: 2 ? 0x00, // calibration mode: 0 0x00, // calibration state: 0 @@ -116,8 +116,7 @@ void main() { expect(map[Keys.STATE_OPERATIONAL_STATE_KEY], equals(OperationalState.OPERATIONALSTATE_IDLE)); expect(map[Keys.STATE_WORKOUT_VERIFICATION_KEY], equals(0)); - expect(map[Keys.STATE_SCREEN_NUMBER_KEY], - equals(WorkoutScreenValue.PREPARETORACESTART)); + expect(map[Keys.STATE_SCREEN_NUMBER_KEY], equals(1)); expect(map[Keys.STATE_LAST_ERROR_KEY], equals(2)); expect(map[Keys.STATE_CALIBRATION_MODE_KEY], equals(0)); expect(map[Keys.STATE_CALIBRATION_KEY], equals(0)); From aefcd7ecec04889b5f49c6be0d15e6ff0d5d7d9c Mon Sep 17 00:00:00 2001 From: bertrand esperou Date: Tue, 20 May 2025 15:40:54 +0200 Subject: [PATCH 214/220] display debugging when calling these mocks --- test/ergometer_test.dart | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/test/ergometer_test.dart b/test/ergometer_test.dart index d5b194e..be30957 100644 --- a/test/ergometer_test.dart +++ b/test/ergometer_test.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:c2bluetooth/c2bluetooth.dart'; import 'package:c2bluetooth/src/dataplex.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -45,12 +46,18 @@ void main() { id: any(named: 'id'), connectionTimeout: any(named: 'connectionTimeout'), ), - ).thenAnswer((_) => deviceConnectionController.stream); + ).thenAnswer((c) { + debugPrint("connectToDevice(${c.namedArguments})"); + return deviceConnectionController.stream; + }); when(() => mockBle.connectedDeviceStream) - .thenAnswer((_) => deviceConnectionController.stream); + .thenAnswer((d) => deviceConnectionController.stream); when(() => mockBle.subscribeToCharacteristic(any())) - .thenAnswer((_) => characteristicController.stream); + .thenAnswer((q) { + debugPrint("subscribeToCharacteristic(${q.positionalArguments})"); + return characteristicController.stream; + }); }); tearDownAll(() { deviceConnectionController.close(); From 37bc3be8b66f862a882fa811aca37e77e2b56ece Mon Sep 17 00:00:00 2001 From: bertrand esperou Date: Tue, 20 May 2025 15:57:41 +0200 Subject: [PATCH 215/220] verify specific subscriptions call --- test/ergometer_test.dart | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/test/ergometer_test.dart b/test/ergometer_test.dart index be30957..2bf7053 100644 --- a/test/ergometer_test.dart +++ b/test/ergometer_test.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:c2bluetooth/c2bluetooth.dart'; +import 'package:c2bluetooth/constants.dart' as Identifiers; import 'package:c2bluetooth/src/dataplex.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; @@ -133,12 +134,15 @@ void main() { id: device.id, connectionTimeout: any(named: 'connectionTimeout'), )).called(1); - // Subscribed to the two defaut subscriptions: - // - Identifiers.C2_ROWING_PRIMARY_SERVICE_UUID, - // - Identifiers.C2_ROWING_MULTIPLEXED_INFORMATION_CHARACTERISTIC_UUID, - verify(() => - mockBle.subscribeToCharacteristic(any())) - .called(2); + // Subscribed only to the initial subscriptions: + // - Identifiers.C2_ROWING_CONTROL_SERVICE_UUID + verify(() => mockBle.subscribeToCharacteristic(any( + that: isA().having( + (e) => e.characteristicId, + 'characteristicId', + Uuid.parse( + Identifiers.C2_ROWING_PM_TRANSMIT_CHARACTERISTIC_UUID))))) + .called(1); }); test('Monitor for distance data', () async { final fakeData = Stream>.fromIterable([ @@ -231,6 +235,18 @@ void main() { ])); await result; await connection.cancel(); + // Subscribed only to the subscriptions: + // - (init) Identifiers.C2_ROWING_CONTROL_SERVICE_UUID + // - (createStream) Identifiers.C2_ROWING_MULTIPLEXED_INFORMATION_CHARACTERISTIC_UUID + final subscribedCharacteristics = + verify(() => mockBle.subscribeToCharacteristic(captureAny())) + .captured; + expect(subscribedCharacteristics[0].characteristicId, + Uuid.parse(Identifiers.C2_ROWING_PM_TRANSMIT_CHARACTERISTIC_UUID)); + expect( + subscribedCharacteristics[1].characteristicId, + Uuid.parse(Identifiers + .C2_ROWING_MULTIPLEXED_INFORMATION_CHARACTERISTIC_UUID)); }); }); } From eff7c05b55ffc4f188fe94604acde33e81102809 Mon Sep 17 00:00:00 2001 From: bertrand esperou Date: Tue, 20 May 2025 15:59:33 +0200 Subject: [PATCH 216/220] fixing documentation --- test/ergometer_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ergometer_test.dart b/test/ergometer_test.dart index 2bf7053..0d7077f 100644 --- a/test/ergometer_test.dart +++ b/test/ergometer_test.dart @@ -134,7 +134,7 @@ void main() { id: device.id, connectionTimeout: any(named: 'connectionTimeout'), )).called(1); - // Subscribed only to the initial subscriptions: + // Subscribed only to this subscription: // - Identifiers.C2_ROWING_CONTROL_SERVICE_UUID verify(() => mockBle.subscribeToCharacteristic(any( that: isA().having( @@ -236,7 +236,7 @@ void main() { await result; await connection.cancel(); // Subscribed only to the subscriptions: - // - (init) Identifiers.C2_ROWING_CONTROL_SERVICE_UUID + // - (connect) Identifiers.C2_ROWING_CONTROL_SERVICE_UUID // - (createStream) Identifiers.C2_ROWING_MULTIPLEXED_INFORMATION_CHARACTERISTIC_UUID final subscribedCharacteristics = verify(() => mockBle.subscribeToCharacteristic(captureAny())) From 8410de20b6a632e5142fb48ac3f6b21bda8ba966 Mon Sep 17 00:00:00 2001 From: Bertrand Esperou Date: Thu, 15 May 2025 10:23:08 +0000 Subject: [PATCH 217/220] fixing value on DurationType enum --- lib/enums.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/enums.dart b/lib/enums.dart index b0a8db1..275659d 100644 --- a/lib/enums.dart +++ b/lib/enums.dart @@ -105,8 +105,8 @@ enum DurationType { extension DurationTypeExtension on DurationType { static Map _durationTypes = { DurationType.TIME: 0x00, - DurationType.DISTANCE: 0x40, - DurationType.CALORIES: 0x80, + DurationType.CALORIES: 0x40, + DurationType.DISTANCE: 0x80, DurationType.WATTMIN: 0xC0, }; From cbaca2aeebc31723b16f195240e195c994401603 Mon Sep 17 00:00:00 2001 From: bertrand esperou Date: Thu, 22 May 2025 19:15:07 +0200 Subject: [PATCH 218/220] imrpoving readability for fake data --- test/ergometer_test.dart | 97 +++++++++++----------------------------- 1 file changed, 27 insertions(+), 70 deletions(-) diff --git a/test/ergometer_test.dart b/test/ergometer_test.dart index 0d7077f..8ca31f6 100644 --- a/test/ergometer_test.dart +++ b/test/ergometer_test.dart @@ -145,77 +145,34 @@ void main() { .called(1); }); test('Monitor for distance data', () async { + List Function(int) distance_packet_fn = (distance) => [ + 0x31, + 0, + 0, + 0, + distance * 10, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ]; final fakeData = Stream>.fromIterable([ - // Each StatusData1 is 18 bytes - [ - 0x31, - 0, - 0, - 0, - 30, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], // 3 m - [ - 0x31, - 0, - 0, - 0, - 40, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], // 4 m - [ - 0x31, - 0, - 0, - 0, - 50, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], // 5 m + // Each StatusData1 is 18 bytes, + distance_packet_fn(3), // 3 m + distance_packet_fn(4), // 4 m + distance_packet_fn(5), // 5 m ]); final erg = Ergometer(device, bleClient: mockBle); final StreamSubscription connection = From e25d9485bea05b3c03022cf18739c3f94a8a3bbc Mon Sep 17 00:00:00 2001 From: bertrand esperou Date: Thu, 22 May 2025 19:25:49 +0200 Subject: [PATCH 219/220] moving test to mimic library architecture --- test/{ => models}/ergblemanager_test.dart | 0 test/{ => models}/ergometer_test.dart | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test/{ => models}/ergblemanager_test.dart (100%) rename test/{ => models}/ergometer_test.dart (100%) diff --git a/test/ergblemanager_test.dart b/test/models/ergblemanager_test.dart similarity index 100% rename from test/ergblemanager_test.dart rename to test/models/ergblemanager_test.dart diff --git a/test/ergometer_test.dart b/test/models/ergometer_test.dart similarity index 100% rename from test/ergometer_test.dart rename to test/models/ergometer_test.dart From 04faa83e63faf7a50a434affce20535197b4a064 Mon Sep 17 00:00:00 2001 From: bertrand esperou Date: Sat, 24 May 2025 09:38:32 +0200 Subject: [PATCH 220/220] improving coherence --- lib/data/workoutsummary.dart | 111 ---------------------------- lib/src/dataplex.dart | 8 +- lib/src/helpers.dart | 8 +- lib/src/packets/belt.dart | 8 +- lib/src/packets/workoutsummary.dart | 24 +++--- test/workoutsummary_test.dart | 2 +- 6 files changed, 25 insertions(+), 136 deletions(-) delete mode 100644 lib/data/workoutsummary.dart diff --git a/lib/data/workoutsummary.dart b/lib/data/workoutsummary.dart deleted file mode 100644 index 370c62e..0000000 --- a/lib/data/workoutsummary.dart +++ /dev/null @@ -1,111 +0,0 @@ -import 'dart:typed_data'; -import 'dart:async'; - -import 'package:c2bluetooth/extensions.dart'; -import 'package:csafe_fitness/csafe_fitness.dart'; - -import 'package:c2bluetooth/enums.dart'; - -///Represents a data packet from Concept2 that is stamped with a date. -class TimestampedData { - DateTime timestamp; - - TimestampedData.fromBytes(Uint8List bytes) - : timestamp = Concept2DateExtension.fromBytes(bytes.sublist(0, 4)); -} - -///Represents a data packet from Concept2 that is stamped with a duration. - -class DurationstampedData { - Duration elapsedTime; - - DurationstampedData.fromBytes(Uint8List data) - : elapsedTime = Concept2DurationExtension.fromBytes(data.sublist(0, 3)); -} - -/// Represents a summary of a completed workout -/// -/// This takes care of processesing the raw byte data from workout summary characteristics into easily accessible fields. This class also takes care of things like byte endianness, combining multiple high and low bytes .etc, allowing applications to access things in terms of flutter native types. -class WorkoutSummary extends TimestampedData { - double workTime; - double workDistance; - int avgSPM; - int endHeartRate; - int avgHeartRate; - int minHeartRate; - int maxHeartRate; - int avgDragFactor; - late int recoveryHeartRate; - WorkoutType workoutType; - double avgPace; - - /// Construct a WorkoutSummary from the bytes returned from the erg - WorkoutSummary.fromBytes(Uint8List data) - : workTime = CsafeIntExtension.fromBytes(data.sublist(4, 7), - endian: Endian.little) / - 100, //divide by 100 to convert to seconds - workDistance = CsafeIntExtension.fromBytes(data.sublist(7, 10), - endian: Endian.little) / - 10, //divide by 10 to convert to meters - avgSPM = data.elementAt(10), - endHeartRate = data.elementAt(11), - avgHeartRate = data.elementAt(12), - minHeartRate = data.elementAt(13), - maxHeartRate = data.elementAt(14), - avgDragFactor = data.elementAt(15), - workoutType = WorkoutTypeExtension.fromInt(data.elementAt(17)), - avgPace = CsafeIntExtension.fromBytes(data.sublist(18, 20), - endian: Endian.little) / - 10, - super.fromBytes(data) { - //recovery heart rate here - int recHRVal = data.elementAt(16); - // 0 is not a valid value here according to the spec - if (recHRVal > 0) { - recoveryHeartRate = recHRVal; - } - } - - @override - String toString() => "WorkoutSummary (" - "Timestamp: $timestamp, " - "elapsedTime: $workTime, " - "distance: $workDistance, " - "avgSPM: $avgSPM)"; -} - -class WorkoutSummary2 extends TimestampedData { - IntervalType intervalType; - int intervalSize; - int intervalCount; - int totalCalories; - int watts; - int totalRestDistance; - int intervalRestTime; - int avgCalories; - - WorkoutSummary2.fromBytes(Uint8List data) - : - // if (data.length > 20) { - // var timestamp2 = Concept2DateExtension.fromBytes(data.sublist(20, 24)); - // if (timestamp != timestamp2) { - // throw ArgumentError( - // "Bytes passed to WorkoutSummary from multiple characteristics must have the same timestamp"); - // } - - intervalType = IntervalTypeExtension.fromInt(data.elementAt(4)), - intervalSize = CsafeIntExtension.fromBytes(data.sublist(5, 7), - endian: Endian.little), - intervalCount = data.elementAt(7), - totalCalories = CsafeIntExtension.fromBytes(data.sublist(8, 10), - endian: Endian.little), - watts = CsafeIntExtension.fromBytes(data.sublist(10, 12), - endian: Endian.little), - totalRestDistance = CsafeIntExtension.fromBytes(data.sublist(12, 15), - endian: Endian.little), - intervalRestTime = CsafeIntExtension.fromBytes(data.sublist(15, 17), - endian: Endian.little), - avgCalories = CsafeIntExtension.fromBytes(data.sublist(17, 19), - endian: Endian.little), - super.fromBytes(data); -} diff --git a/lib/src/dataplex.dart b/lib/src/dataplex.dart index ea435d6..cbffb13 100644 --- a/lib/src/dataplex.dart +++ b/lib/src/dataplex.dart @@ -36,17 +36,17 @@ class Dataplex { ...StrokeData2.datapointIdentifiers, ...SegmentData1.datapointIdentifiers, ...SegmentData2.datapointIdentifiers, - ...WorkoutSummaryPacket.datapointIdentifiers, - ...WorkoutSummaryPacket2.datapointIdentifiers, + ...WorkoutSummary.datapointIdentifiers, + ...WorkoutSummary2.datapointIdentifiers, ...ForceCurveData.datapointIdentifiers }; /// A map of incoming UUID's to the data keys they support. Map> characteristicToDataKeyMap = { Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC_UUID: - WorkoutSummaryPacket.datapointIdentifiers, + WorkoutSummary.datapointIdentifiers, Identifiers.C2_ROWING_END_OF_WORKOUT_SUMMARY_CHARACTERISTIC2_UUID: - WorkoutSummaryPacket2.datapointIdentifiers, + WorkoutSummary2.datapointIdentifiers, }; Dataplex( diff --git a/lib/src/helpers.dart b/lib/src/helpers.dart index f43ef35..ead0377 100644 --- a/lib/src/helpers.dart +++ b/lib/src/helpers.dart @@ -24,10 +24,10 @@ final Map _packetParsers = { 0x36: (data) => StrokeData2.fromBytes(data), 0x37: (data) => SegmentData1.fromBytes(data), 0x38: (data) => SegmentData2.fromBytes(data), - 0x39: (data) => WorkoutSummaryPacket.fromBytes(data), - 0x3A: (data) => WorkoutSummaryPacket1.fromBytes(data), - 0x3B: (data) => HeartRateBeltPacket.fromBytes(data), - 0x3C: (data) => WorkoutSummaryPacket2.fromBytes(data), + 0x39: (data) => WorkoutSummary.fromBytes(data), + 0x3A: (data) => WorkoutSummary1.fromBytes(data), + 0x3B: (data) => HeartRateBelt.fromBytes(data), + 0x3C: (data) => WorkoutSummary2.fromBytes(data), 0x3D: (data) => ForceCurveData.fromBytes(data), 0x3E: (data) => StatusData3.fromBytes(data), }; diff --git a/lib/src/packets/belt.dart b/lib/src/packets/belt.dart index 4ec923d..537edce 100644 --- a/lib/src/packets/belt.dart +++ b/lib/src/packets/belt.dart @@ -6,21 +6,21 @@ import './base.dart'; import 'keys.dart'; /// Represents the heart rate belt packet -class HeartRateBeltPacket extends Concept2CharacteristicData { +class HeartRateBelt extends Concept2CharacteristicData { int manufacturerID; int deviceType; int beltID; static Set get datapointIdentifiers => - HeartRateBeltPacket.zero().asMap().keys.toSet(); + HeartRateBelt.zero().asMap().keys.toSet(); /// Construct a WorkoutSummary from the bytes returned from the erg - HeartRateBeltPacket.fromBytes(Uint8List data) + HeartRateBelt.fromBytes(Uint8List data) : manufacturerID = data[0], deviceType = data[1], beltID = CsafeIntExtension.fromBytes(data.sublist(2, 6)); - HeartRateBeltPacket.zero() : this.fromBytes(Uint8List(19)); + HeartRateBelt.zero() : this.fromBytes(Uint8List(19)); Map asMap() => { Keys.BELT_MANUFACTURER_ID_KEY: manufacturerID, diff --git a/lib/src/packets/workoutsummary.dart b/lib/src/packets/workoutsummary.dart index 7f61417..ce75b97 100644 --- a/lib/src/packets/workoutsummary.dart +++ b/lib/src/packets/workoutsummary.dart @@ -10,7 +10,7 @@ import 'keys.dart'; /// Represents a summary of a completed workout /// /// This takes care of processesing the raw byte data from workout summary characteristics into easily accessible fields. This class also takes care of things like byte endianness, combining multiple high and low bytes .etc, allowing applications to access things in terms of flutter native types. -class WorkoutSummaryPacket extends TimestampedData { +class WorkoutSummary extends TimestampedData { Duration elapsedTime; double workDistance; int avgSPM; @@ -24,10 +24,10 @@ class WorkoutSummaryPacket extends TimestampedData { double avgPace; static Set get datapointIdentifiers => - WorkoutSummaryPacket.zero().asMap().keys.toSet(); + WorkoutSummary.zero().asMap().keys.toSet(); /// Construct a WorkoutSummary from the bytes returned from the erg - WorkoutSummaryPacket.fromBytes(Uint8List data) + WorkoutSummary.fromBytes(Uint8List data) : elapsedTime = Concept2DurationExtension.fromBytes(data.sublist(4, 7)), workDistance = CsafeIntExtension.fromBytes(data.sublist(7, 10), endian: Endian.little) / @@ -45,7 +45,7 @@ class WorkoutSummaryPacket extends TimestampedData { 10, super.fromBytes(data); - WorkoutSummaryPacket.zero() : this.fromBytes(Uint8List(20)); + WorkoutSummary.zero() : this.fromBytes(Uint8List(20)); Map asMap() { // workout.date @@ -79,7 +79,7 @@ class WorkoutSummaryPacket extends TimestampedData { } } -class WorkoutSummaryPacket1 extends TimestampedData { +class WorkoutSummary1 extends TimestampedData { int intervalSize; int intervalCount; int totalCalories; @@ -89,9 +89,9 @@ class WorkoutSummaryPacket1 extends TimestampedData { int avgCalories; static Set get datapointIdentifiers => - WorkoutSummaryPacket1.zero().asMap().keys.toSet(); + WorkoutSummary1.zero().asMap().keys.toSet(); - WorkoutSummaryPacket1.fromBytes(Uint8List data) + WorkoutSummary1.fromBytes(Uint8List data) : intervalSize = CsafeIntExtension.fromBytes(data.sublist(4, 6), endian: Endian.little), intervalCount = data.elementAt(6), @@ -107,7 +107,7 @@ class WorkoutSummaryPacket1 extends TimestampedData { endian: Endian.little), super.fromBytes(data); - WorkoutSummaryPacket1.zero() : this.fromBytes(Uint8List(18)); + WorkoutSummary1.zero() : this.fromBytes(Uint8List(18)); Map asMap() { // workout.heart_rate @@ -127,7 +127,7 @@ class WorkoutSummaryPacket1 extends TimestampedData { } } -class WorkoutSummaryPacket2 extends TimestampedData { +class WorkoutSummary2 extends TimestampedData { int avgPace; GameId gameID; int verifier; @@ -135,11 +135,11 @@ class WorkoutSummaryPacket2 extends TimestampedData { MachineType machineType; static Set get datapointIdentifiers => - WorkoutSummaryPacket2.zero().asMap().keys.toSet(); + WorkoutSummary2.zero().asMap().keys.toSet(); - WorkoutSummaryPacket2.zero() : this.fromBytes(Uint8List(10)); + WorkoutSummary2.zero() : this.fromBytes(Uint8List(10)); - WorkoutSummaryPacket2.fromBytes(Uint8List data) + WorkoutSummary2.fromBytes(Uint8List data) : avgPace = CsafeIntExtension.fromBytes(data.sublist(4, 6), endian: Endian.little), gameID = GameIdExtension.fromInt(data.elementAt(6) & 0x0F), diff --git a/test/workoutsummary_test.dart b/test/workoutsummary_test.dart index fb3dbac..e063fed 100644 --- a/test/workoutsummary_test.dart +++ b/test/workoutsummary_test.dart @@ -1,7 +1,7 @@ import 'dart:typed_data'; import 'package:c2bluetooth/c2bluetooth.dart'; -import 'package:c2bluetooth/data/workoutsummary.dart'; +import 'package:c2bluetooth/src/packets/workoutsummary.dart'; import 'package:flutter_test/flutter_test.dart'; void main() {