From ff050794867be6b33720fa29858cb3d5813c2554 Mon Sep 17 00:00:00 2001 From: Jon Froehlich Date: Fri, 22 May 2026 11:15:24 -0700 Subject: [PATCH 01/19] Add ESP32 BLE lesson (BLE.md) Add a comprehensive ESP32 Bluetooth Low Energy lesson (esp32/ble.md). The new document explains BLE concepts (peripheral/central, GATT, UUIDs), the ESP32 BLE Arduino API, and includes multiple full example sketches (Hello World, sensor notifications, NeoPixel control, Nordic UART Service) plus a Web Bluetooth demo page and exercises. The page also lists materials, troubleshooting notes (MTU/notifications), and TODOs for diagrams and media. Also add a bluetooth-serial.md file entry (new Bluetooth Classic reference). --- esp32/ble.md | 1146 +++++++++++++++++++++++++++++++++++++ esp32/bluetooth-serial.md | 549 ++++++++++++++++++ 2 files changed, 1695 insertions(+) create mode 100644 esp32/ble.md create mode 100644 esp32/bluetooth-serial.md diff --git a/esp32/ble.md b/esp32/ble.md new file mode 100644 index 0000000..445f89d --- /dev/null +++ b/esp32/ble.md @@ -0,0 +1,1146 @@ +--- +layout: default +title: L9: Bluetooth Low Energy +parent: ESP32 +has_toc: true # (on by default) +usemathjax: false +comments: true +usetocbot: true +nav_order: 9 +--- +# {{ page.title | replace_first:'L','Lesson ' }} +{: .no_toc } + +## Table of Contents +{: .no_toc .text-delta } + +1. TOC +{:toc} +--- + +{: .warning } +> This lesson is in draft form. There are missing circuit diagrams, images, videos, and other content. + + + + + +In the [last lesson](bluetooth-serial.md), we used Bluetooth Classic to create a wireless serial connection—simple, fast, and satisfying. But it came with real limitations: no iPhone support, no ESP32-S3 support, higher power consumption, and only one device at a time. In this lesson, we'll learn **Bluetooth Low Energy (BLE)**—the protocol that powers your Fitbit, your AirPods' pairing process, your smart thermostat, and billions of IoT devices worldwide. + +BLE is more complex than Bluetooth Classic. Instead of a simple serial byte stream, BLE organizes data into a structured model of **services** and **characteristics**. This takes some getting used to—but that structure is exactly what makes BLE so powerful and ubiquitous. And unlike Bluetooth Classic, BLE works on the ESP32-S3, works with iPhones, and—as we'll see—even works directly from a web browser. + +{: .note } +> **In this lesson, you will learn:** +> - What BLE is and how it fundamentally differs from Bluetooth Classic +> - The BLE communication model: **peripherals** and **centrals**, advertising and connecting +> - The GATT data model: **servers**, **services**, **characteristics**, and **UUIDs** +> - How to use the ESP32 BLE library to create a BLE peripheral that exposes sensor data +> - How to read, write, and subscribe to BLE characteristics from a phone app (nRF Connect) +> - How to stream real-time sensor data using BLE **notifications** +> - How to control the onboard NeoPixel by writing to a BLE characteristic from your phone +> - How to build a **Web Bluetooth** web page that communicates with the ESP32 from a browser—paralleling the [Web Serial](../communication/web-serial.md) approach but wireless +> - The Nordic UART Service (NUS) as a "serial-like" bridge for BLE + +{: .note } +> **Did you skip Lesson 8?** No problem. This lesson is self-contained—you don't need Bluetooth Classic experience to follow along. We'll briefly cover how BLE differs from Classic in the first section. If you want the full comparison, see [Lesson 8](bluetooth-serial.md). + +## What is BLE? + +**Bluetooth Low Energy** (BLE) is a wireless communication protocol introduced in Bluetooth 4.0 (2010). Despite sharing the "Bluetooth" name with Bluetooth Classic, BLE is a completely different protocol stack designed from the ground up for **low-power, intermittent data exchange**. Where Bluetooth Classic was built for continuous streaming (music, file transfers, serial bridges), BLE was built for devices that send small amounts of data infrequently—a heart rate monitor broadcasting a reading every second, a door sensor reporting open/closed, a fitness tracker uploading step counts. + +This design priority—**extreme power efficiency**—is what makes BLE transformative for physical computing. A BLE sensor can run for months or even years on a coin cell battery. That's not possible with Bluetooth Classic or WiFi. + +{: .note } +> **BLE is not "wireless serial."** This is the single most important conceptual shift in this lesson. If you've used `Serial.println()` over USB or `SerialBT.println()` over Bluetooth Classic, you're used to a continuous byte stream—data flows like water through a pipe. BLE doesn't work that way. Instead, BLE organizes data into discrete, named **characteristics** that can be read, written, or subscribed to. Think less "serial port" and more "structured data API." + +If you completed [Lesson 8](bluetooth-serial.md), here's a quick comparison: + +| Feature | Bluetooth Classic (L8) | BLE (this lesson) | +|---|---|---| +| Data model | Continuous byte stream | Structured characteristics | +| API feel | Like `Serial` | Like a REST API | +| Power | Higher | Very low | +| iOS support | ❌ (Apple blocks SPP) | ✅ | +| ESP32-S3 | ❌ | ✅ | +| Typical range | ~10m | ~10m | +| Max throughput | ~3 Mbps | ~1 Mbps (typically much less) | +| Complexity | Very simple | More setup, more concepts | + +**Table.** Key differences between Bluetooth Classic (Lesson 8) and BLE (this lesson). BLE trades simplicity for universality, power efficiency, and structured data. +{: .fs-1 } + +## How BLE works + +BLE communication involves two fundamental concepts: **roles** (who talks to whom) and the **GATT data model** (how data is organized). Let's take these one at a time. + +### Peripherals and centrals + +Every BLE interaction has two roles: + +- A **peripheral** advertises its presence and hosts data. In our lessons, this is always the ESP32. Think of it as a weather station mounted on a wall—it has data (temperature, humidity) and it waits for someone to come read it. + +- A **central** scans for peripherals, initiates connections, and reads or writes data. In our lessons, this is your phone or laptop. Think of it as a person walking up to the weather station to check the temperature. + +The peripheral **advertises** by periodically broadcasting short packets (called advertisement packets) that say, in essence, "I'm here, my name is X, and I offer these services." The central **scans** for these packets, finds the peripheral, and can then **connect** to it for richer data exchange. + +{: .note } +> These roles are about who *initiates* the connection, not who sends data. Once connected, data flows in both directions—the central can read from the peripheral *and* write to it. The terms "peripheral" and "central" replace the older "slave" and "master" terminology that you may encounter in older documentation. + + + +### The GATT data model + +Once a central connects to a peripheral, how does it know what data is available? This is where **GATT** (Generic Attribute Profile) comes in. GATT defines how data is organized on a BLE peripheral, and it's the conceptual heart of BLE. + +Think of GATT as a structured bulletin board. The peripheral (ESP32) maintains a bulletin board organized into sections (**services**), and each section contains individual data items (**characteristics**). A central (your phone) walks up to the board, browses the sections, and reads or modifies specific items. + +Here's the hierarchy: + +``` +BLE Peripheral (GATT Server) + └── Service (e.g., "Sensor Data") ← a category of related data + ├── Characteristic (e.g., "Potentiometer") ← a single data point + │ ├── Value: 2847 ← the actual data + │ └── Properties: Read, Notify ← what you can do with it + └── Characteristic (e.g., "LED Color") + ├── Value: [255, 0, 128] + └── Properties: Read, Write +``` + +**Services** group related data. A peripheral can have multiple services—for example, one for sensor data and another for device information. Each service is identified by a **UUID** (more on this below). + +**Characteristics** are the individual data points within a service. Each characteristic has: + +- A **UUID** (a unique identifier—like a name or address for this data point) +- A **value** (the actual data—up to 512 bytes, though typically much smaller) +- **Properties** that define how the characteristic can be accessed: + - **Read**: the central can request the current value (like polling) + - **Write**: the central can set the value (like sending a command) + - **Notify**: the peripheral pushes updates to the central automatically when the value changes—this is the most efficient way to stream data, because the central doesn't have to keep asking + - **Indicate**: like Notify but the central sends an acknowledgment (rarely needed for our use cases) + +{: .note } +> **Why so much structure?** If the GATT model feels over-engineered for reading a potentiometer, that's because it was designed for a much broader world of devices—from heart rate monitors to smart locks to industrial sensors. The structure lets *any* BLE central discover what a peripheral offers without prior knowledge. Your phone's Bluetooth settings can show that a nearby device has a "Battery Service" at level 73% without needing a custom app—because "Battery Service" and "Battery Level" are standard UUIDs that every BLE stack understands. This interoperability is BLE's superpower. + +### UUIDs: identifying services and characteristics + +Every service and characteristic needs a unique identifier. BLE uses **UUIDs** (Universally Unique Identifiers) for this. + +**16-bit UUIDs** are reserved by the [Bluetooth SIG](https://www.bluetooth.com/) for standard, well-known services and characteristics. For example: +- `0x180F` = Battery Service +- `0x181A` = Environmental Sensing Service +- `0x2A19` = Battery Level characteristic +- `0x2A6E` = Temperature characteristic + +You can browse the full list in the [Bluetooth SIG Assigned Numbers](https://www.bluetooth.com/specifications/assigned-numbers/) document. + +**128-bit UUIDs** are for custom services and characteristics—anything you define for your own project. They look like this: `4fafc201-1fb5-459e-8fcc-c5c9c331914b`. You can generate your own at [uuidgenerator.net](https://www.uuidgenerator.net/). In this lesson, we'll use custom 128-bit UUIDs since we're defining our own sensor and LED control services. + +{: .note } +> **Don't be intimidated by UUIDs.** A 128-bit UUID is just a unique label—think of it like a URL or a barcode. You generate one, paste it into your code, and use the same one in your phone app or web page so both sides agree on which characteristic is which. You don't need to memorize them or understand their internal structure. + +## The ESP32 BLE library + +The ESP32 Arduino core includes a built-in BLE library based on the [Bluedroid](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/index.html) Bluetooth stack. No installation is needed—just `#include` the headers and go. The key classes you'll use are: + +| Class | Purpose | +|---|---| +| `BLEDevice` | Initializes the BLE stack (call once in `setup()`) | +| `BLEServer` | Creates a GATT server on the ESP32 | +| `BLEService` | A service within the server (identified by UUID) | +| `BLECharacteristic` | A data point within a service (identified by UUID, has value + properties) | +| `BLE2902` | A descriptor that enables/disables notifications (required for Notify) | +| `BLEAdvertising` | Controls what the ESP32 broadcasts during advertising | +| `BLEServerCallbacks` | Event handler for connection/disconnection events | +| `BLECharacteristicCallbacks` | Event handler for read/write events on a characteristic | + +Don't worry about memorizing these—we'll introduce each one as we use it in the activities below. + +{: .note } +> **Alternative library: NimBLE-Arduino.** The default BLE library uses the Bluedroid stack, which consumes roughly 170KB of RAM and ~500KB of flash. An alternative called [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino) provides a lighter-weight BLE stack that uses approximately 60% less flash and 50% less RAM, with a similar (though not identical) API. For the ESP32-S3 with its 4MB flash and 2MB PSRAM, the memory savings are less critical—but if you're building a complex project that also uses WiFi, or targeting the ESP32-C3 with only 400KB SRAM, NimBLE is worth exploring. We use the default library in this lesson because it ships with the Arduino core, requires no installation, and is what most online tutorials reference. + +## Materials + +You'll need the following components. We use **[Adafruit's ESP32-S3 Feather](https://www.adafruit.com/product/5477)** but any ESP32 board with BLE support will work (including the Huzzah32). + +| Breadboard | ESP32 | LED | Resistor | Potentiometer | +| ---------- |:-----:|:-----:|:-----:|:-----:| +| ![Breadboard]({{ site.baseurl }}/assets/images/Breadboard_Half.png) | ![ESP32-S3 Feather](assets/images/Adafruit_ESP32-S3-5477-11-vertical-cropped.jpg) | ![Red LED]({{ site.baseurl }}/assets/images/RedLED_Fritzing.png) | ![Resistors]({{ site.baseurl }}/assets/images/Resistor220_Fritzing.png) | ![Potentiometer]({{ site.baseurl }}/assets/images/Potentiometer_100h.png) | +| Breadboard | [ESP32-S3 Feather](https://www.adafruit.com/product/5477) | Red LED | 220Ω Resistor | 10kΩ Potentiometer | + +You will also need: + +- A **smartphone** (Android or iOS!) with the free [nRF Connect](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-mobile) app by Nordic Semiconductor. Unlike Bluetooth Classic, **BLE works with iPhones** — so everyone can participate! 📱 + +{: .note } +> [nRF Connect](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-mobile) is a professional-grade BLE debugging tool made by Nordic Semiconductor (a major BLE chip manufacturer). It lets you scan for BLE devices, inspect their services and characteristics, read values, write data, and subscribe to notifications. It's free, available on [iOS](https://apps.apple.com/app/nrf-connect-for-mobile/id1054362403) and [Android](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp), and is the tool we'll use throughout this lesson. Alternatives include [LightBlue](https://punchthrough.com/lightblue/) (iOS/Android) and [BLE Scanner](https://play.google.com/store/apps/details?id=com.macdom.ble.blescanner) (Android). + +## Part 1: Advertising and discovery + +Let's start with the BLE equivalent of "Hello World": create a GATT server on the ESP32 with a single readable characteristic, advertise it, and see it on your phone. + +### The code + +```cpp +/** + * BLEHelloWorld: creates a BLE GATT server with one service and one + * readable characteristic. The characteristic contains a greeting + * string that you can read from any BLE central (like nRF Connect). + * + * Works on: ESP32-S3 Feather, Huzzah32, or any ESP32 with BLE. + * + * See: https://makeabilitylab.github.io/physcomp/esp32/ble + * + * By Jon E. Froehlich + * @jonfroehlich + * http://makeabilitylab.io + */ + +#include +#include +#include + +// Custom UUIDs for our service and characteristic. +// Generated at https://www.uuidgenerator.net/ +#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" +#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" + +bool _deviceConnected = false; + +// Callback class to handle connection events +class MyServerCallbacks : public BLEServerCallbacks { + void onConnect(BLEServer* pServer) { + _deviceConnected = true; + Serial.println("Central connected!"); + } + + void onDisconnect(BLEServer* pServer) { + _deviceConnected = false; + Serial.println("Central disconnected. Restarting advertising..."); + + // IMPORTANT: restart advertising so other devices can find us again. + // Without this, the ESP32 goes silent after the first disconnection. + pServer->getAdvertising()->start(); + } +}; + +void setup() { + Serial.begin(115200); + Serial.println("Starting BLE Hello World..."); + + // Step 1: Initialize the BLE stack with a device name. + // This name appears when centrals scan for devices. + BLEDevice::init("ESP32-BLE"); + + // Step 2: Create a GATT server. + BLEServer* pServer = BLEDevice::createServer(); + pServer->setCallbacks(new MyServerCallbacks()); + + // Step 3: Create a service on the server (identified by UUID). + BLEService* pService = pServer->createService(SERVICE_UUID); + + // Step 4: Create a characteristic within the service. + // This characteristic is readable (PROPERTY_READ) — a central + // can request its value. + BLECharacteristic* pCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID, + BLECharacteristic::PROPERTY_READ + ); + + // Step 5: Set the initial value of the characteristic. + pCharacteristic->setValue("Hello from ESP32!"); + + // Step 6: Start the service (makes it visible to connected centrals). + pService->start(); + + // Step 7: Start advertising so centrals can discover us. + BLEAdvertising* pAdvertising = BLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(SERVICE_UUID); // include our service UUID in ads + pAdvertising->setScanResponse(true); // allow a scan response packet + pAdvertising->start(); + + Serial.println("BLE server is advertising. Open nRF Connect and scan!"); +} + +void loop() { + // Nothing to do here yet — the BLE stack runs in the background. + // We'll add sensor reading and notifications in Part 2. + delay(1000); +} +``` + +Let's walk through the key steps: + +**Step 1: `BLEDevice::init("ESP32-BLE")`** initializes the Bluetooth stack and sets the device name that appears during scanning. This is analogous to `SerialBT.begin("ESP32-Bluetooth")` from [Lesson 8](bluetooth-serial.md), but the similarity ends here—BLE has no `println()` or `read()` on the device object. + +**Steps 2–4: Creating the GATT hierarchy.** We create a **server** (the ESP32 as a whole), a **service** within it (identified by `SERVICE_UUID`), and a **characteristic** within that service (identified by `CHARACTERISTIC_UUID`). The characteristic has `PROPERTY_READ`, meaning a central can request its value. This is the GATT structure we discussed earlier, built in code. + +**Step 5: Setting the value.** `pCharacteristic->setValue("Hello from ESP32!")` stores a string in the characteristic. When a central reads this characteristic, it receives this string. + +**Step 6–7: Starting the service and advertising.** `pService->start()` activates the service so connected centrals can see it. `pAdvertising->start()` begins broadcasting advertisement packets. We include our service UUID in the advertisement (`addServiceUUID`) so centrals filtering by service can find us. + +**The `onDisconnect` callback.** This is a critical gotcha: when a central disconnects, the ESP32 **stops advertising by default**. If you don't restart advertising in `onDisconnect()`, the ESP32 goes silent and no new centrals can find it. Always restart advertising after disconnection. + +### Discovering the ESP32 from your phone + +1. Upload the sketch and open Serial Monitor at 115200 baud. You should see `"BLE server is advertising."`. + +2. On your phone, open the **nRF Connect** app. Tap **Scan** (top right). You should see `"ESP32-BLE"` in the list of discovered devices. + + + +3. Tap **Connect** next to `"ESP32-BLE"`. The app will connect and display the GATT server structure. You should see your custom service (listed by its UUID) with one characteristic underneath. + + + +4. Tap the **read arrow** (↓) next to the characteristic. You should see `"Hello from ESP32!"` appear as the value. You just read data from a BLE peripheral! 🎉 + + + +{: .note } +> **What you're seeing in nRF Connect** is the GATT structure we built in code: one service containing one characteristic. nRF Connect shows the UUIDs for each. Since we used custom 128-bit UUIDs (not standard Bluetooth SIG UUIDs), nRF Connect displays them as "Unknown Service" and "Unknown Characteristic"—it doesn't know what our custom UUIDs mean. If we'd used a standard UUID like `0x181A` (Environmental Sensing), nRF Connect would display the name automatically. + +### Workbench demo + + + +## Part 2: Streaming sensor data with notifications + +Reading a static string is a good start, but the real power of BLE comes with **notifications**—the peripheral automatically pushes updates to the central whenever a value changes. Let's wire up a potentiometer and stream its value to your phone in real time. + +### The circuit + +Connect a 10kΩ potentiometer to the ESP32-S3 Feather on pin **A5** (GPIO 8), which is an ADC1 pin. This is the same potentiometer circuit from [Lesson 4: Analog Input](analog-input.md). + + + +
+Using the Huzzah32 instead? (click to expand) + +On the Huzzah32, use pin **A7** (GPIO 32), which is an ADC1 pin. ADC2 pins conflict with both WiFi and Bluetooth on the original ESP32, so always use ADC1 for analog input when using wireless features. + +
+ +### The code + +```cpp +/** + * BLENotifySensor: reads a potentiometer and streams its value to + * connected BLE centrals using notifications. Open nRF Connect, + * connect, and subscribe to notifications to see live sensor data. + * + * Circuit: + * - 10kΩ potentiometer on A5 (GPIO 8, ADC1) for ESP32-S3 Feather + * (use A7 / GPIO 32 for the Huzzah32) + * + * Works on: ESP32-S3 Feather, Huzzah32, or any ESP32 with BLE. + * + * See: https://makeabilitylab.github.io/physcomp/esp32/ble + * + * By Jon E. Froehlich + * @jonfroehlich + * http://makeabilitylab.io + */ + +#include +#include +#include +#include + +// Custom UUIDs — same service UUID as Part 1, new characteristic UUID for sensor data +#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" +#define SENSOR_CHAR_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" + +const int POT_INPUT_PIN = A5; // GPIO 8, ADC1 on ESP32-S3 Feather + +BLEServer* _pServer = NULL; +BLECharacteristic* _pSensorCharacteristic = NULL; +bool _deviceConnected = false; + +// Timing for non-blocking sensor reads +unsigned long _lastSensorReadMs = 0; +const unsigned long SENSOR_READ_INTERVAL_MS = 100; // read sensor ~10x/sec + +class MyServerCallbacks : public BLEServerCallbacks { + void onConnect(BLEServer* pServer) { + _deviceConnected = true; + Serial.println("Central connected!"); + } + + void onDisconnect(BLEServer* pServer) { + _deviceConnected = false; + Serial.println("Central disconnected. Restarting advertising..."); + pServer->getAdvertising()->start(); + } +}; + +void setup() { + Serial.begin(115200); + Serial.println("Starting BLE Sensor Notify..."); + + // Initialize BLE + BLEDevice::init("ESP32-BLE-Sensor"); + _pServer = BLEDevice::createServer(); + _pServer->setCallbacks(new MyServerCallbacks()); + + // Create service + BLEService* pService = _pServer->createService(SERVICE_UUID); + + // Create characteristic with READ and NOTIFY properties + _pSensorCharacteristic = pService->createCharacteristic( + SENSOR_CHAR_UUID, + BLECharacteristic::PROPERTY_READ | + BLECharacteristic::PROPERTY_NOTIFY + ); + + // Add the BLE2902 descriptor — this is required for notifications. + // It allows the central to enable/disable notifications on this characteristic. + _pSensorCharacteristic->addDescriptor(new BLE2902()); + + // Start the service and begin advertising + pService->start(); + BLEAdvertising* pAdvertising = BLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(SERVICE_UUID); + pAdvertising->setScanResponse(true); + pAdvertising->start(); + + Serial.println("BLE server advertising. Connect with nRF Connect!"); +} + +void loop() { + unsigned long now = millis(); + + if (now - _lastSensorReadMs >= SENSOR_READ_INTERVAL_MS) { + _lastSensorReadMs = now; + + int potVal = analogRead(POT_INPUT_PIN); + + // Always print to USB serial for debugging + Serial.print("Pot:"); + Serial.println(potVal); + + // If a BLE central is connected, update the characteristic and notify + if (_deviceConnected) { + // Convert the integer to a string and set it as the characteristic value. + // We could also send raw bytes for efficiency, but strings are easier + // to read in nRF Connect for learning purposes. + String valStr = String(potVal); + _pSensorCharacteristic->setValue(valStr.c_str()); + _pSensorCharacteristic->notify(); + } + } +} +``` + +There are two new elements here compared to Part 1: + +**`PROPERTY_NOTIFY`** tells the BLE stack that this characteristic supports notifications. When a central subscribes to notifications, it will receive an automatic update every time we call `notify()`. + +**`BLE2902` descriptor.** This is a BLE protocol requirement: the Client Characteristic Configuration Descriptor (CCCD), identified by UUID `0x2902`, is a small piece of metadata that the central uses to enable or disable notifications. Without it, the central cannot subscribe. The line `_pSensorCharacteristic->addDescriptor(new BLE2902())` adds this descriptor to our characteristic. + +**`_pSensorCharacteristic->notify()`** pushes the current value to all subscribed centrals. We call this after updating the value with `setValue()`. If no central is subscribed, `notify()` does nothing. + +### Try it out + +1. Upload the sketch and open Serial Monitor. You should see potentiometer values scrolling by. +2. Open nRF Connect, scan, and connect to `"ESP32-BLE-Sensor"`. +3. Expand the service and find the sensor characteristic. +4. Tap the **triple-down-arrow** icon (⇊) to **subscribe to notifications**. +5. Turn the potentiometer—you should see the value updating in real time on your phone! + + + +{: .note } +> **Comparing with serial:** In the [Communication module](../communication/serial-intro.md), you call `Serial.println(sensorValue)` and bytes flow continuously through the USB cable at 115,200 bps. With BLE, you update a characteristic value and call `notify()`—the BLE stack delivers it at the negotiated connection interval (typically 7.5ms–4 seconds). BLE trades raw throughput for structured data, power efficiency, and wireless convenience. + +### The 20-byte payload limit + +Try changing the `setValue()` call to send a long string—something like `"Potentiometer reading is: " + String(potVal)`. You'll notice the value gets **truncated** in nRF Connect. Welcome to the 20-byte MTU limit! + +By default, BLE's ATT (Attribute Protocol) layer has a Maximum Transmission Unit (MTU) of 23 bytes. After 3 bytes of protocol overhead, that leaves **20 bytes** for your actual data. Any value longer than 20 bytes gets silently truncated. + +You can negotiate a larger MTU (up to 512 bytes) if both sides support it, but 20 bytes is the safe baseline that works with all BLE devices. For sensor data, this is rarely a problem—an integer like `"2847"` is only 4 bytes as a string (or 2 bytes as a raw `uint16_t`). But if you try to send long formatted strings, you'll hit this limit. + +{: .warning } +> **Keep your BLE payloads compact.** Send numbers as short strings or raw bytes, not verbose text. If you need to send more than 20 bytes, either negotiate a larger MTU (call `BLEDevice::setMTU(185)` in `setup()`; both sides must agree), split the data across multiple characteristics, or send it in chunks. + +### Workbench demo + + + +## Part 3: Controlling the NeoPixel over BLE + +Now let's go the other direction: send data *from* your phone *to* the ESP32 to control hardware. We'll create a **writable** characteristic that accepts RGB color values and sets the onboard NeoPixel. + +The ESP32-S3 Feather has a built-in NeoPixel (WS2812B) RGB LED on `PIN_NEOPIXEL`, powered by `NEOPIXEL_POWER`. We used it in [Lesson 2: Blink](led-blink.md#part-4-blink-the-onboard-neopixel-), so the NeoPixel setup should be familiar. + +### The code + +We'll extend the Part 2 sketch to add a second characteristic for LED control—so the ESP32 simultaneously streams sensor data *and* accepts LED commands. This is the same bidirectional pattern from [Lesson 8](bluetooth-serial.md#part-3-controlling-an-led-from-your-phone), but over BLE with structured characteristics instead of a serial byte stream. + +```cpp +/** + * BLENeoPixelControl: bidirectional BLE communication. + * Streams potentiometer data via notifications (peripheral → central) + * AND accepts RGB color commands via a writable characteristic + * (central → peripheral) to control the onboard NeoPixel. + * + * Circuit: + * - 10kΩ potentiometer on A5 (GPIO 8, ADC1) + * - Onboard NeoPixel (no external wiring needed) + * + * Works on: ESP32-S3 Feather (for the onboard NeoPixel). + * On the Huzzah32, substitute an external NeoPixel or LED. + * + * See: https://makeabilitylab.github.io/physcomp/esp32/ble + * + * By Jon E. Froehlich + * @jonfroehlich + * http://makeabilitylab.io + */ + +#include +#include +#include +#include +#include + +// Custom UUIDs +#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" +#define SENSOR_CHAR_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" +#define LED_CHAR_UUID "a3c87500-8ed3-4bdf-8a39-a01bebede295" + +const int POT_INPUT_PIN = A5; + +// NeoPixel setup — one pixel on the onboard NeoPixel pin +Adafruit_NeoPixel _pixel(1, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800); + +BLEServer* _pServer = NULL; +BLECharacteristic* _pSensorCharacteristic = NULL; +BLECharacteristic* _pLedCharacteristic = NULL; +bool _deviceConnected = false; + +unsigned long _lastSensorReadMs = 0; +const unsigned long SENSOR_READ_INTERVAL_MS = 100; + +class MyServerCallbacks : public BLEServerCallbacks { + void onConnect(BLEServer* pServer) { + _deviceConnected = true; + Serial.println("Central connected!"); + } + + void onDisconnect(BLEServer* pServer) { + _deviceConnected = false; + Serial.println("Central disconnected. Restarting advertising..."); + pServer->getAdvertising()->start(); + } +}; + +// Callback for when the central writes to the LED characteristic +class LedCallbacks : public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic* pCharacteristic) { + String value = pCharacteristic->getValue(); + + if (value.length() >= 3) { + // Interpret the first 3 bytes as R, G, B + uint8_t r = (uint8_t)value[0]; + uint8_t g = (uint8_t)value[1]; + uint8_t b = (uint8_t)value[2]; + + Serial.print("Received RGB: "); + Serial.print(r); Serial.print(", "); + Serial.print(g); Serial.print(", "); + Serial.println(b); + + _pixel.setPixelColor(0, _pixel.Color(r, g, b)); + _pixel.show(); + } else { + Serial.print("Received write with "); + Serial.print(value.length()); + Serial.println(" bytes (expected 3 for RGB)."); + } + } +}; + +void setup() { + Serial.begin(115200); + Serial.println("Starting BLE NeoPixel Control..."); + + // Initialize NeoPixel + #if defined(NEOPIXEL_POWER) + pinMode(NEOPIXEL_POWER, OUTPUT); + digitalWrite(NEOPIXEL_POWER, HIGH); + #endif + _pixel.begin(); + _pixel.setBrightness(30); // keep it dim to avoid blinding you + _pixel.show(); // turn off (all zeros) + + // Initialize BLE + BLEDevice::init("ESP32-BLE-NeoPixel"); + _pServer = BLEDevice::createServer(); + _pServer->setCallbacks(new MyServerCallbacks()); + + BLEService* pService = _pServer->createService(SERVICE_UUID); + + // Sensor characteristic (Read + Notify) — streams potentiometer data + _pSensorCharacteristic = pService->createCharacteristic( + SENSOR_CHAR_UUID, + BLECharacteristic::PROPERTY_READ | + BLECharacteristic::PROPERTY_NOTIFY + ); + _pSensorCharacteristic->addDescriptor(new BLE2902()); + + // LED characteristic (Read + Write) — receives RGB color commands + _pLedCharacteristic = pService->createCharacteristic( + LED_CHAR_UUID, + BLECharacteristic::PROPERTY_READ | + BLECharacteristic::PROPERTY_WRITE + ); + _pLedCharacteristic->setCallbacks(new LedCallbacks()); + + // Start service and advertising + pService->start(); + BLEAdvertising* pAdvertising = BLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(SERVICE_UUID); + pAdvertising->setScanResponse(true); + pAdvertising->start(); + + Serial.println("BLE server advertising. Connect with nRF Connect!"); +} + +void loop() { + unsigned long now = millis(); + + if (now - _lastSensorReadMs >= SENSOR_READ_INTERVAL_MS) { + _lastSensorReadMs = now; + + int potVal = analogRead(POT_INPUT_PIN); + Serial.print("Pot:"); + Serial.println(potVal); + + if (_deviceConnected) { + String valStr = String(potVal); + _pSensorCharacteristic->setValue(valStr.c_str()); + _pSensorCharacteristic->notify(); + } + } +} +``` + +The key new element is the `LedCallbacks` class. When the central writes to the LED characteristic, `onWrite()` fires automatically. We interpret the first three bytes of the written value as R, G, B and set the NeoPixel color accordingly. + +Notice the pattern: we don't poll for incoming data in `loop()` (like we do with `Serial.available()`). Instead, BLE uses a **callback model**—the library calls our `onWrite()` function when data arrives. This is fundamentally different from the serial polling pattern you're used to. + +### Try it out + +1. Upload the sketch. The NeoPixel should be off initially. +2. Open nRF Connect, scan, and connect to `"ESP32-BLE-NeoPixel"`. +3. Expand the service. You should see **two** characteristics now. +4. Find the LED characteristic (the one with `a3c87500...` UUID). +5. Tap the **write arrow** (↑). In the write dialog, select **ByteArray** as the type, then enter `FF0000` (red), `00FF00` (green), or `0000FF` (blue). Tap **Send**. +6. Watch the NeoPixel change color! 🌈 + + + +{: .note } +> **nRF Connect write format:** When writing raw bytes in nRF Connect, select "ByteArray" (not "Text") and enter hex values without spaces or `0x` prefixes. `FF0000` = red, `00FF00` = green, `0000FF` = blue, `FF00FF` = magenta, `FFFFFF` = white. Each pair of hex digits is one byte (0–255). + +### Workbench demo + + + +## Part 4: Web Bluetooth + +So far we've used nRF Connect as our BLE central—it's great for debugging, but it doesn't give us a custom UI. What if you could control the NeoPixel from a **web page** with sliders and a color picker? What if you could plot sensor data in a live chart—all in the browser, all wireless? + +That's exactly what the [Web Bluetooth API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API) provides. If you completed the [Web Serial lessons](../communication/web-serial.md), this will feel familiar—it's the same idea (browser talks to hardware) with a different transport (BLE instead of USB serial). + +### Web Serial vs. Web Bluetooth + +| | Web Serial ([L2](../communication/web-serial.md)) | Web Bluetooth (this section) | +|---|---|---| +| Browser API | `navigator.serial` | `navigator.bluetooth` | +| Connect | `port.open({ baudRate })` | `device.gatt.connect()` | +| Send data | `writer.write(bytes)` | `characteristic.writeValue(bytes)` | +| Receive data | Read from stream | Subscribe to notifications | +| User gesture | Required to open port | Required to pair | +| Security | No HTTPS required | **Requires HTTPS** (or localhost) | +| Chrome/Edge | ✅ | ✅ | +| Firefox | ❌ | ⚠️ (behind flag) | +| Safari / iOS | ❌ | ❌ | +| Android Chrome | ✅ | ✅ | + +**Table.** Web Serial and Web Bluetooth have strikingly parallel structures. The main differences: Web Bluetooth requires HTTPS (or localhost), uses structured characteristics instead of raw byte streams, and is supported on Android but not iOS. +{: .fs-1 } + +{: .warning } +> **Web Bluetooth requires HTTPS or localhost.** It will not work from a `file://` URL. Use a local development server (VS Code's [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer) extension, or `python3 -m http.server`) or host your page on [GitHub Pages](https://pages.github.com/). Web Bluetooth works in **Chrome and Edge** on desktop and Android, but **not on iOS**—Apple's Safari (and iOS Chrome, which uses WebKit) does not support Web Bluetooth. For iOS users, nRF Connect provides similar functionality. + +### The web page + +We'll build a single HTML page (vanilla JavaScript, no frameworks—matching the style of the [Web Serial lesson](../communication/web-serial.md)) that: + +1. Connects to the ESP32's BLE service +2. Subscribes to potentiometer notifications and displays the live value +3. Has three sliders (R, G, B) that write to the LED characteristic to control the NeoPixel + +Make sure the Part 3 sketch is running on your ESP32 before testing this page. + +```html + + + + + + ESP32 BLE NeoPixel Controller + + + +

ESP32 BLE NeoPixel Controller

+ + +
Not connected
+ +
+

Sensor Data

+
+

Potentiometer reading (0–4095)

+ +

NeoPixel Color

+
+ + + 0 +
+
+ + + 0 +
+
+ + + 0 +
+
+
+ + + + +``` + +Let's walk through the JavaScript, step by step: + +**Step 1: `navigator.bluetooth.requestDevice()`** opens the browser's Bluetooth pairing dialog. We pass a `filters` array that limits the list to devices advertising our service UUID—so only our ESP32 appears. This is the BLE equivalent of `navigator.serial.requestPort()` from the [Web Serial lesson](../communication/web-serial.md). Like Web Serial, this call **requires a user gesture** (a button click)—you can't trigger it automatically on page load. + +**Step 2: `device.gatt.connect()`** establishes a GATT connection. This is analogous to `port.open()` in Web Serial—after this call, we can read and write data. + +**Steps 3–4: Getting the service and characteristic, subscribing to notifications.** We drill down through the GATT hierarchy: server → service → characteristic. Then `sensorChar.startNotifications()` tells the ESP32 we want to receive updates. We listen for `characteristicvaluechanged` events—each event delivers a `DataView` containing the raw bytes. Since our ESP32 sends the potentiometer value as a string, we decode it with `TextDecoder`. + +**Step 5: Getting the LED characteristic.** We store a reference to the LED characteristic so we can write to it later from the slider event handlers. + +**`sendColor()`** reads the three slider values, packs them into a `Uint8Array` of 3 bytes (R, G, B), and writes them to the LED characteristic with `ledCharacteristic.writeValue(data)`. This triggers the `onWrite()` callback on the ESP32, which sets the NeoPixel color. + +{: .note } +> **Spot the structural parallel.** In [Web Serial](../communication/web-serial.md), you write raw bytes to a `WritableStream`. In Web Bluetooth, you write raw bytes to a `BLECharacteristic`. The data format (a `Uint8Array`) is even the same! The key difference is that Web Bluetooth writes go to a *specific, named characteristic*—not a generic byte stream. This structure is what makes BLE self-describing and interoperable. + +### Try it out + +1. Make sure the Part 3 sketch is running on your ESP32. +2. Serve the HTML file from a local server (VS Code Live Server, or `python3 -m http.server`). Open it in Chrome. +3. Click **Connect to ESP32**. The browser shows a pairing dialog—select your ESP32 and click **Pair**. +4. The sensor value should appear and update in real time. +5. Drag the R, G, B sliders—the NeoPixel changes color as you move them! + + + +{: .note } +> **Throttling writes.** If you drag a slider quickly, `sendColor()` fires on every pixel of movement—potentially dozens of times per second. BLE can handle this, but rapid writes may occasionally fail with a "GATT operation already in progress" error. For a more robust implementation, you could debounce the slider input or use `requestAnimationFrame()` to batch writes. For this lesson, occasional errors are harmless. + +### Workbench demo + + + +## Part 5: Nordic UART Service (NUS) + +Throughout this lesson, we've worked directly with custom GATT services and characteristics—the fundamental BLE building blocks. But what if you just want to send text back and forth, like the serial bridge from [Lesson 8](bluetooth-serial.md)? This is where the **Nordic UART Service (NUS)** comes in. + +NUS is a widely adopted convention (created by Nordic Semiconductor) that uses two BLE characteristics to emulate serial communication: + +- **RX Characteristic** (`6E400002-B5A3-F393-E0A9-E50E24DCCA9E`): the central *writes* data here to send it to the peripheral (from the peripheral's perspective, this is "received" data—hence "RX"). +- **TX Characteristic** (`6E400003-B5A3-F393-E0A9-E50E24DCCA9E`): the peripheral *notifies* data here to send it to the central (from the peripheral's perspective, this is "transmitted" data—hence "TX"). + +The naming is from the **peripheral's perspective**: RX = data coming *in* to the ESP32, TX = data going *out* from the ESP32. + +{: .note } +> NUS is not an official Bluetooth SIG standard—it's a convention created by Nordic Semiconductor that has become a de facto standard because so many apps support it. Apps like nRF Connect, nRF Toolbox, and many Bluetooth terminal apps automatically recognize the NUS UUIDs and provide a serial terminal interface. + +Here's a simple NUS example: + +```cpp +/** + * BLEUartService: implements the Nordic UART Service (NUS) for + * serial-like text communication over BLE. Type text in nRF Connect's + * UART feature and it appears in Serial Monitor; type in Serial + * Monitor and it is sent over BLE. + * + * Works on: ESP32-S3 Feather, Huzzah32, or any ESP32 with BLE. + * + * See: https://makeabilitylab.github.io/physcomp/esp32/ble + * + * By Jon E. Froehlich + * @jonfroehlich + * http://makeabilitylab.io + */ + +#include +#include +#include +#include + +// Nordic UART Service UUIDs — these are a de facto standard +#define NUS_SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" +#define NUS_RX_CHAR_UUID "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" +#define NUS_TX_CHAR_UUID "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" + +BLEServer* _pServer = NULL; +BLECharacteristic* _pTxCharacteristic = NULL; +bool _deviceConnected = false; + +class MyServerCallbacks : public BLEServerCallbacks { + void onConnect(BLEServer* pServer) { + _deviceConnected = true; + Serial.println("Central connected!"); + } + void onDisconnect(BLEServer* pServer) { + _deviceConnected = false; + Serial.println("Disconnected. Restarting advertising..."); + pServer->getAdvertising()->start(); + } +}; + +// Called when the central writes to the RX characteristic (sending data to us) +class RxCallbacks : public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic* pCharacteristic) { + String rxValue = pCharacteristic->getValue(); + if (rxValue.length() > 0) { + Serial.print("Received via BLE: "); + Serial.println(rxValue.c_str()); + } + } +}; + +void setup() { + Serial.begin(115200); + Serial.println("Starting BLE UART Service..."); + + BLEDevice::init("ESP32-BLE-UART"); + _pServer = BLEDevice::createServer(); + _pServer->setCallbacks(new MyServerCallbacks()); + + BLEService* pService = _pServer->createService(NUS_SERVICE_UUID); + + // TX characteristic — we notify data OUT to the central + _pTxCharacteristic = pService->createCharacteristic( + NUS_TX_CHAR_UUID, + BLECharacteristic::PROPERTY_NOTIFY + ); + _pTxCharacteristic->addDescriptor(new BLE2902()); + + // RX characteristic — the central writes data IN to us + BLECharacteristic* pRxCharacteristic = pService->createCharacteristic( + NUS_RX_CHAR_UUID, + BLECharacteristic::PROPERTY_WRITE + ); + pRxCharacteristic->setCallbacks(new RxCallbacks()); + + pService->start(); + BLEAdvertising* pAdvertising = BLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(NUS_SERVICE_UUID); + pAdvertising->setScanResponse(true); + pAdvertising->start(); + + Serial.println("BLE UART ready. Connect with nRF Connect → UART."); +} + +void loop() { + // Forward USB Serial → BLE (via TX characteristic) + if (_deviceConnected && Serial.available()) { + String msg = Serial.readStringUntil('\n'); + _pTxCharacteristic->setValue(msg.c_str()); + _pTxCharacteristic->notify(); + Serial.print("Sent via BLE: "); + Serial.println(msg); + } +} +``` + +To test: connect with nRF Connect, navigate to the NUS service, subscribe to TX notifications, and write text to the RX characteristic. Or, in newer versions of nRF Connect, use the built-in **UART** mode which provides a chat-like interface that works with any device implementing NUS. + +{: .note } +> **NUS is "serial over BLE."** It gives you the familiar send/receive text experience of Bluetooth Classic's `SerialBT`, but running over BLE—so it works on the ESP32-S3, works with iPhones, and coexists with custom GATT services. Under the hood, it's still GATT: the NUS service has two characteristics, and data flows as writes and notifications. Understanding the GATT layer (Parts 1–4) will help you debug NUS when things go wrong. + +{: .note } +> **Library alternative:** If you want a `Serial`-like API over BLE without manually managing NUS characteristics, check out the [NuS-NimBLE-Serial](https://www.arduino.cc/reference/en/libraries/nus-nimble-serial/) library, which wraps NUS in familiar `.read()` and `.write()` methods. It requires the [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino) stack. + +## Exercises + +**Exercise 1: NeoPixel strip control.** Modify Part 3 to control the 5-LED NeoPixel stick from your kit instead of (or in addition to) the onboard NeoPixel. You could either send 15 bytes (5 × RGB) in a single write to set all LEDs at once, or add a fourth byte for the LED index (0–4) and set one LED per write. Build a Web Bluetooth page with five color pickers—one per LED. + +**Exercise 2: BLE range test.** With the notification sketch from Part 2 running, walk away from your ESP32 with nRF Connect open. At what distance do notifications stop arriving? How do walls and obstacles affect range? If you did the Bluetooth Classic range test in [Lesson 8, Exercise 4](bluetooth-serial.md#exercises), compare the two. Are they similar? + +**Exercise 3: Multiple sensor characteristics.** Create a service with *three* characteristics: potentiometer data (notify), photoresistor data (notify), and LED brightness control (write). This requires reading two analog sensors and exposing each on its own characteristic. Build a Web Bluetooth dashboard that displays both sensor streams and includes a brightness slider for the LED. + +**Exercise 4: BLE servo control.** Create a writable characteristic that accepts a single byte (0–180) representing a servo angle. When the central writes a value, the ESP32 moves a servo motor to that position (using the [Servo library](../advancedio/servo.md)). Build a Web Bluetooth page with a slider to control the servo wirelessly. + +**Exercise 5: Connection status NeoPixel.** Use the onboard NeoPixel to display BLE connection status: **blue** while advertising (waiting for a connection), **green** when a central is connected, and **red** briefly on disconnection before returning to blue. This is a common pattern in commercial BLE products. Implement it using the `onConnect()` and `onDisconnect()` callbacks. + +**Exercise 6: Power comparison (research).** The ESP32-S3 Feather has a LiPoly battery connector and a MAX17048 battery monitor chip. Connect the 350mAh LiPoly battery from your kit and run a BLE sketch. How long does the battery last? Compare with a WiFi sketch (from the [IoT lesson](iot.md)). Which protocol consumes more power? For bonus points, use `BLEDevice::setPower()` to experiment with different transmit power levels and measure the effect on both range and battery life. + +**Exercise 7: Web Bluetooth + p5.js.** Port the Web Bluetooth sensor display from Part 4 into [p5.js](https://p5js.org/). Use `createCanvas()` to draw a real-time visualization (bar chart, oscilloscope, *etc.*) of the incoming BLE sensor data. If you completed the [p5.js Serial lessons](../communication/p5js-serial.md), compare the code structure—how much carries over? (Hint: also check out [p5.ble.js](https://itpnyu.github.io/p5.ble.js/), a p5.js library specifically for Web Bluetooth.) + +## Summary + +In this lesson, you learned Bluetooth Low Energy—a fundamentally different approach to wireless communication than the serial-style Bluetooth Classic from [Lesson 8](bluetooth-serial.md). Here's what you covered: + +- **BLE is not wireless serial.** Instead of a continuous byte stream, BLE organizes data into structured **services** and **characteristics** with defined properties (read, write, notify). This structure enables interoperability across devices and applications. +- **BLE uses a peripheral/central model.** The ESP32 acts as a **peripheral** (advertising and hosting data), while your phone or laptop acts as a **central** (scanning, connecting, reading, and writing). Once connected, data flows in both directions. +- **GATT** (Generic Attribute Profile) is the data model at the heart of BLE. A GATT server contains **services** (categories of data), which contain **characteristics** (individual data points). Each service and characteristic is identified by a **UUID**. +- **Notifications** are the most efficient way to stream data. Instead of the central repeatedly polling, the peripheral pushes updates automatically when a value changes—dramatically reducing power consumption and latency. +- **The ESP32 BLE library** (`BLEDevice.h`) ships with the ESP32 Arduino core and requires no installation. It uses a callback model (not polling) for connection events and write operations—a different programming pattern than `Serial.available()`. +- **The `BLE2902` descriptor** must be added to any characteristic that supports notifications. Without it, centrals cannot subscribe. +- **The 20-byte MTU default** means BLE payloads should be kept compact. Send numbers as short strings or raw bytes, not verbose text. +- **After disconnection, the ESP32 stops advertising by default.** Always restart advertising in your `onDisconnect()` callback, or new centrals won't be able to find the device. +- **Web Bluetooth** lets you build browser-based interfaces for BLE devices using JavaScript—structurally parallel to the [Web Serial API](../communication/web-serial.md). It requires HTTPS (or localhost), works in Chrome/Edge on desktop and Android, but not on iOS Safari. +- **The Nordic UART Service (NUS)** provides serial-like text communication over BLE using standardized UUIDs. It's a practical bridge between the simplicity of serial and the universality of BLE—and is supported by most BLE terminal apps. +- **BLE works on the ESP32-S3, works with iPhones, and consumes dramatically less power than Bluetooth Classic or WiFi.** For most new wireless projects, BLE is the right default choice. + +## Resources + +- [ESP32 BLE Arduino library source and examples](https://github.com/espressif/arduino-esp32/tree/master/libraries/BLE) — the official library in the ESP32 Arduino core +- [ESP32 Arduino BLE API documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/api/ble.html) — Espressif's API reference +- [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino) — lighter-weight alternative BLE stack (~60% less flash, ~50% less RAM) +- [nRF Connect for Mobile](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-mobile) — our recommended BLE debugging app (free, iOS + Android) +- [Web Bluetooth API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API) — MDN Web Docs reference +- [Communicating with Bluetooth devices over JavaScript](https://developer.chrome.com/docs/capabilities/bluetooth) — Google's Web Bluetooth guide for Chrome +- [Bluetooth SIG Assigned Numbers](https://www.bluetooth.com/specifications/assigned-numbers/) — official list of standard service and characteristic UUIDs +- [Nordic UART Service specification](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/libraries/bluetooth_services/services/nus.html) — Nordic Semiconductor's NUS documentation +- [NuS-NimBLE-Serial Arduino library](https://www.arduino.cc/reference/en/libraries/nus-nimble-serial/) — a Serial-like API over BLE using NUS +- [p5.ble.js](https://itpnyu.github.io/p5.ble.js/) — a p5.js library for Web Bluetooth, from ITP/NYU +- [Create Apps for the ESP32 Using BLE Through P5](https://www.hackster.io/lemio/create-apps-for-the-esp32-using-ble-through-p5-55292d) — Hackster.io tutorial combining p5.js + ESP32 BLE +- [Getting Started with ESP32 BLE on Arduino IDE](https://randomnerdtutorials.com/esp32-bluetooth-low-energy-ble-arduino-ide/) — Random Nerd Tutorials +- [ESP32 Web Bluetooth (BLE) Getting Started Guide](https://randomnerdtutorials.com/esp32-web-bluetooth/) — Random Nerd Tutorials + +## Next Lesson + +With BLE under your belt, you've now covered all three major wireless communication technologies available on the ESP32: **WiFi** (cloud connectivity via [IoT](iot.md)), **Bluetooth Classic** (wireless serial via [Lesson 8](bluetooth-serial.md)), and **BLE** (structured low-power wireless in this lesson). From here, you might explore BLE HID (making your ESP32 act as a wireless keyboard, mouse, or game controller), deep sleep with BLE wake-up for battery-powered projects, or combining BLE with sensors like the ADXL343 accelerometer for motion-controlled wireless devices. The wireless world is yours! 🚀 + + diff --git a/esp32/bluetooth-serial.md b/esp32/bluetooth-serial.md new file mode 100644 index 0000000..ae6f539 --- /dev/null +++ b/esp32/bluetooth-serial.md @@ -0,0 +1,549 @@ +--- +layout: default +title: L8: Bluetooth Serial +parent: ESP32 +has_toc: true # (on by default) +usemathjax: false +comments: true +usetocbot: true +nav_order: 8 +--- +# {{ page.title | replace_first:'L','Lesson ' }} +{: .no_toc } + +## Table of Contents +{: .no_toc .text-delta } + +1. TOC +{:toc} +--- + +{: .warning } +> This lesson is in draft form. There are missing circuit diagrams, images, videos, and other content. + + + + + +In the [last lesson](iot.md), you sent sensor data halfway around the world—through WiFi, across the internet, and up to a cloud dashboard. But what if you just want to talk to the phone in your pocket? Or stream sensor data to a laptop sitting on the same desk? Sometimes you don't need the entire internet—you just need to cut the USB cable. + +In this lesson, we'll do exactly that using **Bluetooth**. And here's the fun part: the code is going to look *very* familiar. The ESP32's `BluetoothSerial` library provides an API that mirrors the `Serial` library you've been using since your [very first Arduino lesson](../arduino/serial-print.md)—`SerialBT.println()`, `SerialBT.available()`, `SerialBT.read()`—it's all the same, just wireless. By the end of this lesson, you'll have sensor data streaming to your phone over the air, and you'll be controlling an LED from a Bluetooth terminal app. ✨ + +{: .note } +> **In this lesson, you will learn:** +> - What Bluetooth is, its origin story, and why there are two very different flavors: Bluetooth Classic and Bluetooth Low Energy (BLE) +> - How the Serial Port Profile (SPP) turns a Bluetooth Classic connection into a wireless serial cable +> - How to use the `BluetoothSerial` library—and why it mirrors the `Serial` API you already know +> - How to pair with and exchange data with an Android phone using a free Bluetooth terminal app +> - How to stream real-time sensor data wirelessly and control an LED from your phone +> - Why Bluetooth Classic does **not** work on the ESP32-S3 and does **not** work with iPhones +> - When to use Bluetooth Classic *vs.* BLE—and why we'll learn BLE next + +{: .warning } +> **This lesson requires the original ESP32** (like the Adafruit Huzzah32), **not** the ESP32-S3. The ESP32-S3 does not have the hardware for Bluetooth Classic—the `BluetoothSerial` library will not compile on it. If you only have an ESP32-S3, you can borrow a Huzzah32 from the equipment cart, or skip ahead to [Lesson 9: Bluetooth Low Energy](ble.md), which works with both boards. We'll explain why this limitation exists in the [next section](#what-is-bluetooth). + +## What is Bluetooth? + +Bluetooth is a short-range wireless communication standard for exchanging data between devices over radio waves. It operates in the 2.4 GHz ISM band (the same frequency range as WiFi and your microwave oven) and is designed for low-power, close-range connections—typically within about 10 meters indoors. + +### A brief history + +Bluetooth was developed in the 1990s by [Ericsson](https://en.wikipedia.org/wiki/Ericsson) as a wireless replacement for RS-232 serial cables (the same serial communication we studied in [Lesson 1 of the Communication module](../communication/serial-intro.md)!). The name comes from [Harald Bluetooth](https://en.wikipedia.org/wiki/Harald_Bluetooth), a 10th-century Danish king who united warring Scandinavian tribes—a fitting metaphor for a technology designed to unite different devices. The Bluetooth logo is even a [bind rune](https://en.wikipedia.org/wiki/Bind_rune) merging Harald's initials in [Younger Futhark](https://en.wikipedia.org/wiki/Younger_Futhark): ᚼ (Hagall, "H") and ᛒ (Bjarkan, "B"). + + + +The technology was standardized by the [Bluetooth Special Interest Group (SIG)](https://www.bluetooth.com/) in 1998 and quickly became ubiquitous in wireless keyboards, mice, headphones, and phone accessories. + +### Two flavors: Classic and Low Energy + +Here's where things get interesting—and a bit confusing. When people say "Bluetooth," they might mean one of **two fundamentally different protocols** that happen to share a name: + +**Bluetooth Classic** (also called BR/EDR, for "Basic Rate / Enhanced Data Rate") is the original Bluetooth. It was designed for **continuous data streaming**—think wireless headphones playing music, file transfers between phones, or serial port emulation. It establishes a persistent connection and can push data at up to 3 Mbps. This is the flavor we'll use in this lesson. + +**Bluetooth Low Energy** (BLE, introduced in Bluetooth 4.0 in 2010) is a completely different protocol stack designed from the ground up for **low-power, intermittent data exchange**. Think fitness trackers that run for months on a coin cell battery, broadcasting a heart rate reading every few seconds. BLE trades throughput for extraordinary power efficiency. We'll cover BLE in [Lesson 9](ble.md). + +Despite sharing the "Bluetooth" name and the 2.4 GHz radio band, Classic and BLE are **not compatible with each other**. A BLE-only device cannot talk to a Bluetooth Classic device and vice versa. A device can support one, the other, or both—the original ESP32 supports **both**, which is why it's such a versatile chip. + +| Feature | Bluetooth Classic (BR/EDR) | Bluetooth Low Energy (BLE) | +|---|---|---| +| Introduced | Bluetooth 1.0 (1999) | Bluetooth 4.0 (2010) | +| Design goal | Continuous streaming | Intermittent, low-power data | +| Data throughput | Up to 3 Mbps | ~1 Mbps (typically much less) | +| Power consumption | Higher | Very low (coin cell battery for months) | +| Connection model | Persistent stream (like serial) | Structured reads/writes/notifications | +| Range | ~10–30m (Class 2) | ~10–30m (similar) | +| Audio streaming | Yes (A2DP, HFP profiles) | Not originally (LE Audio added in BT 5.2) | +| iOS app support | **No** (Apple blocks SPP for third-party apps) | **Yes** | +| ESP32 (original) | ✅ | ✅ | +| **ESP32-S3** | **❌** | **✅** | +| ESP32-S2 | ❌ (no Bluetooth at all) | ❌ (no Bluetooth at all) | +| ESP32-C3, C6 | ❌ | ✅ | +| Typical use cases | Audio, file transfer, serial bridges | Sensors, wearables, beacons, IoT | + +**Table.** Comparison of Bluetooth Classic and Bluetooth Low Energy. The original ESP32 supports both, but the ESP32-S3 only supports BLE. +{: .fs-1 } + +{: .warning } +> **Why doesn't the ESP32-S3 support Bluetooth Classic?** It's a hardware decision by Espressif. The ESP32-S3 chip was designed for IoT and edge AI workloads where BLE's low power consumption is more important than Classic's streaming capabilities. Dropping the Classic radio reduces die area, power consumption, and cost. If you try to compile a `BluetoothSerial` sketch on the ESP32-S3, you'll get the error: `Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.` This is a chip-level limitation, not a software bug. + +{: .warning } +> **iOS does not support Bluetooth Classic SPP for third-party apps.** Apple restricts Bluetooth Classic access to its own system-level protocols (audio via AirPods, keyboards, *etc.*). If you or your partner have an iPhone, you **cannot** pair with the ESP32 and send data using the approach in this lesson. The good news: BLE works great on iOS, and we'll cover that in [Lesson 9](ble.md). For this lesson, you'll need an **Android phone** or a **computer** (Windows, macOS, or Linux) with Bluetooth. + +## The Serial Port Profile (SPP) + +So how does Bluetooth Classic act like a serial cable? Through something called the **Serial Port Profile (SPP)**. A Bluetooth "profile" is a specification for how a particular type of communication should work over Bluetooth. There are profiles for audio (A2DP), file transfer (FTP), human input devices like keyboards (HID), and many more. SPP is the profile that emulates a wired RS-232 serial port—exactly the kind of serial communication we've been doing over USB. + +From your code's perspective, SPP makes the Bluetooth link look and behave like the USB serial connection you've used throughout this course. You call `SerialBT.println("Hello!")` and the string arrives at the other end, just as if you'd called `Serial.println("Hello!")` over a USB cable. The Bluetooth stack handles all the radio-layer complexity—frequency hopping, error correction, packet framing—invisibly. + + USB Cable --> Computer (Serial Monitor) + BT Serial: Arduino --> [radio waves] --> Phone (BT Terminal App) + Emphasize that the code on the Arduino side is nearly identical --> + +This is the key insight of this lesson: **SPP is a wireless serial cable.** Everything you learned about serial communication in the [Communication module](../communication/serial-intro.md)—baud rates, data framing, parsing comma-separated values, bidirectional communication—applies here. The only difference is the transport layer: radio waves instead of copper wire. + +## Materials + +You'll need the following components. This lesson uses the **original ESP32** ([Adafruit Huzzah32 ESP32 Feather](https://www.adafruit.com/product/3591)), not the ESP32-S3. + +| Breadboard | ESP32 | LED | Resistor | Potentiometer | +| ---------- |:-----:|:-----:|:-----:|:-----:| +| ![Breadboard]({{ site.baseurl }}/assets/images/Breadboard_Half.png) | ![Huzzah32 ESP32 Feather](assets/images/AdafruitHuzzah32_200h.png) | ![Red LED]({{ site.baseurl }}/assets/images/RedLED_Fritzing.png) | ![Resistors]({{ site.baseurl }}/assets/images/Resistor220_Fritzing.png) | ![Potentiometer]({{ site.baseurl }}/assets/images/Potentiometer_100h.png) | +| Breadboard | [Huzzah32 ESP32 Feather](https://www.adafruit.com/product/3591) | Red LED | 220Ω Resistor | 10kΩ Potentiometer | + +You will also need: + +- An **Android phone** with the free [Serial Bluetooth Terminal](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal) app by Kai Morich installed. Alternatively, you can use a **Windows, macOS, or Linux computer** with Bluetooth (we'll cover computer pairing briefly, but the phone experience is more fun and portable). + +{: .note } +> If you only have an ESP32-S3, you can borrow a Huzzah32 from the equipment cart for this lesson, or skip ahead to [Lesson 9: Bluetooth Low Energy](ble.md), which works with the ESP32-S3. + +## Part 1: Hello Bluetooth + +Let's get wireless! Our first sketch creates a **bridge** between the USB serial connection (to your computer) and a Bluetooth serial connection (to your phone). Anything you type in the Arduino Serial Monitor gets forwarded over Bluetooth to your phone, and anything you type on your phone gets forwarded back to Serial Monitor. It's the simplest possible demonstration of Bluetooth serial communication. + +### The code + +```cpp +/** + * HelloBluetooth: creates a bidirectional bridge between USB Serial + * and Bluetooth Serial (SPP). Type in Serial Monitor → appears on + * phone. Type on phone → appears in Serial Monitor. + * + * Requires: Original ESP32 (e.g., Huzzah32). Will NOT compile on ESP32-S3. + * + * See: https://makeabilitylab.github.io/physcomp/esp32/bluetooth-serial + * + * By Jon E. Froehlich + * @jonfroehlich + * http://makeabilitylab.io + */ + +#include "BluetoothSerial.h" + +// These compile-time checks ensure we're running on a chip that +// supports Bluetooth Classic. On the ESP32-S3 (or C3, S2, etc.), +// these #error lines will trigger and the sketch won't compile. +#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) +#error Bluetooth Classic is not enabled. This sketch requires the original ESP32. +#endif + +#if !defined(CONFIG_BT_SPP_ENABLED) +#error Serial Bluetooth (SPP) is not available. It is only supported on the original ESP32 chip. +#endif + +BluetoothSerial SerialBT; + +void setup() { + Serial.begin(115200); + + // Initialize Bluetooth with a device name. + // This is the name that appears when you scan for devices on your phone. + SerialBT.begin("ESP32-Bluetooth"); + Serial.println("Bluetooth device started! You can now pair with 'ESP32-Bluetooth'."); +} + +void loop() { + // Forward USB Serial → Bluetooth Serial + if (Serial.available()) { + SerialBT.write(Serial.read()); + } + + // Forward Bluetooth Serial → USB Serial + if (SerialBT.available()) { + Serial.write(SerialBT.read()); + } +} +``` + +That's it—under 20 lines of logic! Let's walk through it. + +**The `#include` and compile-time guards.** The `BluetoothSerial.h` header is part of the ESP32 Arduino core—no library installation needed. The `#if !defined(...)` blocks are compile-time checks that produce a clear error message if you accidentally try to build this sketch on an ESP32-S3 or other chip that lacks Bluetooth Classic hardware. You won't see these checks at runtime; they prevent the sketch from compiling at all. Try it on an S3 and you'll see the error in the Arduino IDE's output pane. + +**`BluetoothSerial SerialBT`** creates a Bluetooth serial object. Notice the naming: `SerialBT`. This is not arbitrary—the object supports the same methods as Arduino's built-in `Serial`: `.begin()`, `.available()`, `.read()`, `.write()`, `.print()`, `.println()`. The API was intentionally designed to mirror `Serial` so that converting a wired serial sketch to Bluetooth is trivially easy. + +**`SerialBT.begin("ESP32-Bluetooth")`** initializes the Bluetooth radio and starts advertising with the name `"ESP32-Bluetooth"`. This is the name you'll see when scanning for Bluetooth devices on your phone. You can change it to anything you like—your name, your project name, *etc.* + +**The `loop()` body** is a two-way bridge. If data arrives on USB serial (from Serial Monitor), forward it to Bluetooth. If data arrives on Bluetooth (from your phone), forward it to USB serial. Each call to `Serial.read()` or `SerialBT.read()` returns one byte at a time—the same behavior you know from the [serial introduction](../communication/serial-intro.md). + +{: .note } +> **Spot the parallel:** this bridge sketch is structurally identical to the cross-device serial forwarding pattern from the [Communication module](../communication/serial-intro.md). The only difference is that one of the two serial connections is now wireless. All your existing serial knowledge—parsing, formatting, handshaking—carries over directly. + +### Pairing from an Android phone + +Now let's connect! Follow these steps: + +1. **Upload the sketch** to your Huzzah32. Open Serial Monitor at 115200 baud. You should see `"Bluetooth device started!"`. + +2. **On your Android phone**, open **Settings → Bluetooth** (or **Settings → Connected devices → Pair new device**, depending on your Android version). You should see `"ESP32-Bluetooth"` in the list of available devices. Tap it to pair. + + + +3. **Open the Serial Bluetooth Terminal app** ([free on Google Play](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal)). Tap the menu icon (☰) → **Devices** → select `"ESP32-Bluetooth"` → tap **Connect**. + + + +4. **You're connected!** 🎉 Type a message in the app and tap Send—it should appear in Arduino Serial Monitor. Type a message in Serial Monitor and press Enter—it should appear on your phone. + + + +{: .note } +> **Alternative terminal apps:** [Serial Bluetooth Terminal](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal) by Kai Morich is our recommended app for its clean interface and reliability. Other options include [Bluetooth Terminal](https://play.google.com/store/apps/details?id=com.sena.bterm) and [Bluetooth Serial Controller](https://play.google.com/store/apps/details?id=nextprotocols.bluetooth.serial.controller). Any app that supports the Bluetooth SPP profile will work. + +
+Pairing from a computer instead? (click to expand) + +You can also pair from a desktop or laptop computer with Bluetooth: + +**Windows 10/11:** Go to **Settings → Bluetooth & devices → Add device → Bluetooth**. Select `"ESP32-Bluetooth"`. Once paired, Windows creates a virtual COM port. Find the port number in **Device Manager → Ports (COM & LPT)** — look for a "Standard Serial over Bluetooth link" entry. You can then open this COM port in any serial terminal (PuTTY, Arduino Serial Monitor on a second instance, *etc.*) at any baud rate (SPP ignores the baud setting; it's handled at the Bluetooth layer). + +**macOS:** Go to **System Settings → Bluetooth**. Click **Connect** next to `"ESP32-Bluetooth"`. Once paired, the ESP32 appears as a serial device at `/dev/tty.ESP32-Bluetooth-ESP32SPP` (or similar). You can open it with `screen /dev/tty.ESP32-Bluetooth-ESP32SPP 115200` in Terminal. + +**Linux:** Use `bluetoothctl` to pair, then `rfcomm` to create a serial device. The process varies by distribution; see the [Arch Wiki Bluetooth page](https://wiki.archlinux.org/title/Bluetooth) for a thorough walkthrough. + +
+ +### Workbench demo + + + +## Part 2: Streaming sensor data + +Typing text back and forth is a nice proof-of-concept, but let's do something more interesting: stream **live sensor data** from a potentiometer to your phone, wirelessly—the same data you'd normally see in Serial Monitor or Serial Plotter, but arriving over Bluetooth instead of USB. + +### The circuit + +Connect a 10kΩ potentiometer to the Huzzah32. Use pin **A7** (GPIO 32), which is an ADC1 pin. (On the original ESP32, ADC2 pins conflict with both WiFi *and* Bluetooth Classic, so always use ADC1 pins for analog input when using wireless features.) + + + +### The code + +```cpp +/** + * BluetoothPotentiometer: reads a potentiometer and streams the value + * over Bluetooth Serial to a connected device (phone or computer). + * Also prints to USB Serial for debugging. + * + * Circuit: + * - 10kΩ potentiometer on A7 (GPIO 32) — must be an ADC1 pin + * + * Requires: Original ESP32 (e.g., Huzzah32). Will NOT compile on ESP32-S3. + * + * See: https://makeabilitylab.github.io/physcomp/esp32/bluetooth-serial + * + * By Jon E. Froehlich + * @jonfroehlich + * http://makeabilitylab.io + */ + +#include "BluetoothSerial.h" + +#if !defined(CONFIG_BT_SPP_ENABLED) +#error Serial Bluetooth (SPP) is not available. It is only supported on the original ESP32 chip. +#endif + +BluetoothSerial SerialBT; + +const int POT_INPUT_PIN = A7; // GPIO 32, an ADC1 pin on the Huzzah32 + +void setup() { + Serial.begin(115200); + SerialBT.begin("ESP32-PotSensor"); + Serial.println("Bluetooth started! Pair with 'ESP32-PotSensor' to see live data."); +} + +void loop() { + int potVal = analogRead(POT_INPUT_PIN); + + // Send to USB Serial (for Serial Monitor / Serial Plotter debugging) + Serial.print("Pot:"); + Serial.println(potVal); + + // Send to Bluetooth Serial (to the phone) + SerialBT.print("Pot:"); + SerialBT.println(potVal); + + delay(100); // ~10 readings per second +} +``` + +Upload this sketch, pair your phone, and open the Serial Bluetooth Terminal app. You should see a stream of potentiometer values scrolling by—twist the knob and watch the numbers change in real time on your phone. It's the same experience as Serial Monitor, but without the USB cable. 🎉 + +{: .note } +> **Why is `delay(100)` OK here?** In the [IoT lesson](iot.md), we warned that `delay()` is dangerous because it blocks the `io.run()` MQTT keepalive loop. Bluetooth Classic SPP doesn't have that constraint—the connection is persistent and tolerates delays just fine. That said, `millis()`-based timing is still better practice for more complex sketches where you need multiple tasks running at different rates. See the [IoT lesson](iot.md#why-no-delay-in-the-main-loop) for the non-blocking pattern. + +{: .note } +> **Serial Plotter over Bluetooth?** The Arduino IDE's built-in Serial Plotter reads from the USB serial port, not from Bluetooth. So you can't *directly* use Serial Plotter to graph Bluetooth data. However, since we're also printing to `Serial`, you can view the data in Serial Plotter over USB while simultaneously streaming it to your phone over Bluetooth. In [Exercise 1](#exercises), we'll suggest building your own wireless plotter using a web app or p5.js. + +### Workbench demo + + + +## Part 3: Controlling an LED from your phone + +Now let's go the other direction: send commands *from* your phone *to* the ESP32 to control hardware. We'll parse simple text commands received over Bluetooth to toggle an LED. + +### The circuit + +Add a standard LED circuit: LED on GPIO 21 through a 220Ω resistor to ground. Keep the potentiometer connected to A7 from Part 2—we'll stream sensor data *and* accept LED commands simultaneously. + + + +### The code + +```cpp +/** + * BluetoothLedControl: bidirectional Bluetooth communication. + * Streams potentiometer data to the phone AND accepts commands + * from the phone to control an LED. + * + * Commands (sent from phone): + * "ON" or "1" → turn LED on + * "OFF" or "0" → turn LED off + * Any integer 0-255 → set LED brightness via PWM + * + * Circuit: + * - 10kΩ potentiometer on A7 (GPIO 32) + * - LED with 220Ω resistor on GPIO 21 + * + * Requires: Original ESP32 (e.g., Huzzah32). Will NOT compile on ESP32-S3. + * + * See: https://makeabilitylab.github.io/physcomp/esp32/bluetooth-serial + * + * By Jon E. Froehlich + * @jonfroehlich + * http://makeabilitylab.io + */ + +#include "BluetoothSerial.h" + +#if !defined(CONFIG_BT_SPP_ENABLED) +#error Serial Bluetooth (SPP) is not available. It is only supported on the original ESP32 chip. +#endif + +BluetoothSerial SerialBT; + +const int POT_INPUT_PIN = A7; // GPIO 32, ADC1 pin +const int LED_OUTPUT_PIN = 21; // Any PWM-capable GPIO pin + +// Timing for non-blocking sensor reads +unsigned long _lastSensorSendMs = 0; +const unsigned long SENSOR_SEND_INTERVAL_MS = 200; // send sensor data 5x/sec + +void setup() { + Serial.begin(115200); + pinMode(LED_OUTPUT_PIN, OUTPUT); + + SerialBT.begin("ESP32-LEDControl"); + Serial.println("Bluetooth started! Pair with 'ESP32-LEDControl'."); + Serial.println("Send 'ON', 'OFF', or a number 0-255 from your phone."); +} + +void loop() { + // --- Receive commands from phone --- + if (SerialBT.available()) { + String command = SerialBT.readStringUntil('\n'); + command.trim(); // remove whitespace and newline characters + + Serial.print("Received via Bluetooth: "); + Serial.println(command); + + if (command.equalsIgnoreCase("ON") || command == "1") { + analogWrite(LED_OUTPUT_PIN, 255); + SerialBT.println("LED: ON (brightness 255)"); + + } else if (command.equalsIgnoreCase("OFF") || command == "0") { + analogWrite(LED_OUTPUT_PIN, 0); + SerialBT.println("LED: OFF"); + + } else { + // Try to parse as an integer for PWM brightness + int brightness = command.toInt(); + + // toInt() returns 0 for non-numeric strings, so check if + // the command was actually "0" (which we handled above) + if (brightness >= 0 && brightness <= 255) { + analogWrite(LED_OUTPUT_PIN, brightness); + SerialBT.print("LED brightness set to: "); + SerialBT.println(brightness); + } else { + SerialBT.println("Unknown command. Send ON, OFF, or 0-255."); + } + } + } + + // --- Stream sensor data to phone --- + unsigned long now = millis(); + if (now - _lastSensorSendMs >= SENSOR_SEND_INTERVAL_MS) { + _lastSensorSendMs = now; + + int potVal = analogRead(POT_INPUT_PIN); + SerialBT.print("Pot:"); + SerialBT.println(potVal); + + // Also print to USB Serial for debugging + Serial.print("Pot:"); + Serial.println(potVal); + } +} +``` + +### Try it out + +1. Upload the sketch and pair your phone with `"ESP32-LEDControl"`. +2. In the Serial Bluetooth Terminal app, type `ON` and tap Send. The LED turns on! Type `OFF` to turn it off. +3. Try sending a number like `128` for half brightness, or `50` for a dim glow. +4. Meanwhile, potentiometer readings scroll by automatically—you're doing **bidirectional communication** over Bluetooth. + +This is the same bidirectional serial communication pattern from the [Communication module's I/O lesson](../communication/p5js-serial-io.md), but wireless. The ESP32 simultaneously streams sensor data *out* (potentiometer values) and accepts commands *in* (LED control)—all over a single Bluetooth SPP connection. + +{: .note } +> **Parsing tip:** We used `SerialBT.readStringUntil('\n')` for simplicity, which blocks until a newline arrives (or times out after 1 second by default). For more complex protocols, consider the character-by-character parsing approach from the [Communication module](../communication/serial-intro.md), which doesn't block. The Serial Bluetooth Terminal app sends a newline after each message by default, so `readStringUntil('\n')` works well here. + +{: .note } +> **Fun extension:** The Serial Bluetooth Terminal app supports custom buttons that send predefined strings when tapped. Go to **Settings → Buttons** and configure buttons for `ON`, `OFF`, and brightness presets like `50`, `128`, and `255`. Now you have a simple custom remote control UI on your phone—no app development required! + +### Workbench demo + + + +## Gotchas and limitations + +Bluetooth Classic SPP is simple and effective, but it comes with real limitations that are worth understanding—both because they'll affect your projects and because they motivate learning BLE in the [next lesson](ble.md). + +**One connection at a time.** SPP is a point-to-point protocol. Only one device can connect to the ESP32 at a time. If your phone is connected and a second phone tries to connect, it will fail. This is a fundamental constraint of the Serial Port Profile. + +**No iOS support.** This bears repeating because it catches people off guard: Apple does not allow third-party apps to use Bluetooth Classic SPP on iOS. Your iPhone can use Bluetooth Classic for audio (AirPods, car stereo) and keyboards, but Apple reserves those system-level profiles. Third-party apps can only use BLE. If half your team has iPhones, Bluetooth Classic is a non-starter for collaborative projects. + +**No ESP32-S3, S2, C3, or C6.** Only the original ESP32 chip includes the Bluetooth Classic radio. All the newer, more power-efficient variants dropped it in favor of BLE-only. As these newer chips become the standard (the S3 is already our primary board), Bluetooth Classic becomes increasingly niche for ESP32 development. + +**Range and interference.** Bluetooth Classic Class 2 (which the ESP32 uses) has a theoretical range of about 10 meters, but walls, furniture, and other 2.4 GHz devices (WiFi routers, microwaves) reduce this significantly. In a busy classroom or lab, expect reliable communication at 5–8 meters. You'll explore this in [Exercise 4](#exercises). + +**Memory usage.** Running Bluetooth Classic consumes significant RAM on the ESP32. If you also enable WiFi, the combined memory footprint can cause instability in complex sketches—the original ESP32 has only 520KB of SRAM. If you're building a project that needs both WiFi and Bluetooth, consider using BLE instead of Classic, or carefully manage memory allocation. + +**Security.** Default Bluetooth pairing uses ["Just Works"](https://www.bluetooth.com/blog/bluetooth-pairing-part-1/) association, which provides basic encryption but no authentication—any nearby device can pair. For projects where security matters, you can require a PIN using `SerialBT.setPin("1234")` before `SerialBT.begin()`, but Bluetooth Classic security is generally considered weaker than BLE's options. For a classroom setting, the default is fine. + +## When to use Bluetooth Classic vs. BLE + +Given these limitations, when is Bluetooth Classic SPP actually the right choice? + +**Use Bluetooth Classic SPP when:** +- You need a simple wireless serial bridge and are using the original ESP32 +- You're communicating with an **Android** phone or a **computer** +- You want the fastest possible development time—the `BluetoothSerial` API is dead simple +- You're building a quick prototype where iOS compatibility doesn't matter +- You need higher throughput for continuous data streaming (audio, dense sensor data) + +**Use BLE (Lesson 9) when:** +- You're using the ESP32-S3 (or any non-original ESP32) +- You need iOS compatibility +- Power efficiency matters (battery-powered projects) +- You want to connect multiple centrals, or communicate with standard BLE peripherals +- You're building something that needs to work with modern phones and computers universally +- You want to build a [Web Bluetooth](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API) web app to interact with your ESP32 from a browser + +For most new projects—especially with the ESP32-S3 as your primary board—**BLE is the better default choice**. But Bluetooth Classic SPP remains a useful tool for its sheer simplicity: when you just need a wireless serial cable and you have the right hardware, nothing is faster to get working. + +## Exercises + +**Exercise 1: Wireless sensor dashboard.** Modify Part 2 to send comma-separated values from *two* sensors (potentiometer + photoresistor). Write a simple [p5.js](https://p5js.org/) or vanilla JavaScript sketch that connects to the ESP32 via a [Bluetooth serial port on your computer](#pairing-from-a-computer-instead-click-to-expand) (using the [Web Serial API](../communication/web-serial.md) on the virtual Bluetooth COM port) and plots both sensor streams in real time. How does this compare to the wired serial plotter approach? + +**Exercise 2: NeoPixel color controller.** Connect a NeoPixel strip (or the onboard NeoPixel on a Huzzah32, if available). Send RGB values as comma-separated text from the phone (*e.g.,* `255,0,128`). Parse the three values on the ESP32 and set the NeoPixel color. This is a great exercise in serial parsing—refer to the [Communication module](../communication/p5js-serial-io.md) for parsing patterns. + +**Exercise 3: Bluetooth chat between two ESP32s.** The ESP32's `BluetoothSerial` library supports both peripheral (slave) and central (master) roles. Flash one ESP32 with the [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) example (peripheral) and another with [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (central). Build a two-way text chat between the two boards, displayed on Serial Monitor for each. + +**Exercise 4: Range test.** With the sensor streaming sketch from Part 2 running, walk away from your ESP32 with the phone connected. At what distance do you start seeing gaps in the data? When does the connection drop entirely? Try with and without walls or obstacles between you and the ESP32. How does the range compare to your WiFi experience from the [IoT lesson](iot.md)? + +**Exercise 5: Latency comparison.** Measure the round-trip latency of Bluetooth serial *vs.* USB serial. Write a sketch that listens for a single byte, immediately echoes it back, and records the timestamp. On a computer, send a byte over USB serial, measure the round-trip time, then send a byte over Bluetooth serial (via the virtual COM port) and measure again. How do they compare? You can use a Python script with the [`time`](https://docs.python.org/3/library/time.html) module and [`pyserial`](https://pyserial.readthedocs.io/) library for precise timing. + +**Exercise 6: Custom Bluetooth name.** Modify the sketch to include sensor data in the Bluetooth device name itself—for example, `"ESP32-Light:742"`. Some BLE beacon systems use this trick to broadcast data without requiring a connection. Does it work with Bluetooth Classic? How often can you update the name? (Hint: you'll need to call `SerialBT.end()` and `SerialBT.begin()` with the new name—this is hacky and not recommended for production, but it's an interesting experiment.) + +**Exercise 7: Servo control.** Connect a servo motor (from the [Servo lesson](../advancedio/servo.md)). Send angle values (0–180) from your phone. Parse the incoming number and call `myServo.write(angle)`. Now you have a wireless servo controller! Can you feel the latency compared to a directly-wired potentiometer control? + +## Summary + +In this lesson, you cut the wire! Here's what you learned: + +- **Bluetooth** is a short-range wireless standard operating at 2.4 GHz, with two fundamentally different flavors: **Bluetooth Classic** (continuous streaming, higher power) and **Bluetooth Low Energy** (intermittent data, very low power). Despite sharing a name, they are incompatible protocols. +- **The Serial Port Profile (SPP)** is a Bluetooth Classic profile that emulates a wired RS-232 serial connection over the air. From your code's perspective, `SerialBT` behaves identically to `Serial`—the same `.available()`, `.read()`, `.write()`, `.println()` methods you've used all along. +- The `BluetoothSerial` library ships with the ESP32 Arduino core and requires no installation. Create a `BluetoothSerial` object, call `SerialBT.begin("DeviceName")`, and you're advertising. +- **Everything you know about serial communication transfers directly** to Bluetooth serial: parsing comma-separated values, bidirectional communication, formatting sensor data—the only difference is radio waves instead of a USB cable. +- **Bluetooth Classic SPP only works on the original ESP32** (like the Huzzah32). The ESP32-S3 and other newer variants do not have the hardware for Bluetooth Classic—attempting to compile a `BluetoothSerial` sketch will produce a clear compile-time error. +- **iOS does not support Bluetooth Classic SPP** for third-party apps. You need an Android phone or a computer with Bluetooth to use this lesson's approach. +- **One connection at a time:** SPP is point-to-point. Only one device can be connected to the ESP32's Bluetooth serial at once. +- Bluetooth Classic has a practical range of about **5–10 meters indoors** and is affected by walls, furniture, and 2.4 GHz interference (WiFi, microwaves). +- For most new projects—especially on the ESP32-S3—**BLE is the better default choice** due to universal device support, lower power consumption, and broader compatibility. But Bluetooth Classic SPP remains the fastest path from wired serial to wireless serial when you have the right hardware. + +## Resources + +- [BluetoothSerial library source and examples](https://github.com/espressif/arduino-esp32/tree/master/libraries/BluetoothSerial) — the official library in the ESP32 Arduino core, including `SerialToSerialBT` and `SerialToSerialBTM` examples +- [ESP32 Arduino Bluetooth API docs](https://docs.espressif.com/projects/arduino-esp32/en/latest/api/bluetooth.html) — Espressif's API reference for `BluetoothSerial` +- [Serial Bluetooth Terminal](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal) — our recommended Android app for Bluetooth serial communication (free, by Kai Morich) +- [Bluetooth SIG: Learn About Bluetooth](https://www.bluetooth.com/learn-about-bluetooth/tech-overview/) — official overview of Bluetooth technology, profiles, and specifications +- [Bluetooth SIG: Classic vs. Low Energy](https://www.bluetooth.com/learn-about-bluetooth/tech-overview/le-vs-classic/) — the Bluetooth SIG's own comparison of Classic and BLE +- [Random Nerd Tutorials: ESP32 Bluetooth Classic](https://randomnerdtutorials.com/esp32-bluetooth-classic-arduino-ide/) — a well-written tutorial covering additional Bluetooth Classic features +- [Intro to Serial Communication](../communication/serial-intro.md) — our lesson on the serial fundamentals that underpin both USB serial and Bluetooth serial + +## Next Lesson + +In the [next lesson](ble.md), we'll learn **Bluetooth Low Energy (BLE)**—the protocol that powers fitness trackers, smart home devices, and billions of IoT sensors. BLE works on the ESP32-S3, works with iPhones, and introduces a completely different (and more powerful) way of structuring wireless data. The code is more complex, but the capabilities are transformative. Let's go! 🚀 + + From ce021318acb18e7923be151e4e307bc79bdeaad1 Mon Sep 17 00:00:00 2001 From: Jon Froehlich Date: Fri, 22 May 2026 11:17:08 -0700 Subject: [PATCH 02/19] Enhance ESP32 Bluetooth lessons: Python & BLE Update esp32/ble.md and esp32/bluetooth-serial.md with expanded, cross-platform guidance and working examples. Added Python client examples (bleak) for BLE discovery, notifications, and NeoPixel control in ble.md, plus notes clarifying iOS/Android compatibility. Revised bluetooth-serial.md to focus on computer-based Bluetooth Classic workflows: pairing instructions for macOS/Windows, pySerial Python demos, Web Serial / p5.js usage with serial.js, and clearer explanations about ESP32 vs ESP32-S3 and SPP limitations. Also cleaned up wording, added troubleshooting notes, TODOs for screenshots/videos, and minor formatting fixes. --- esp32/ble.md | 232 +++++++++++- esp32/bluetooth-serial.md | 721 +++++++++++++++++++++++++++----------- 2 files changed, 737 insertions(+), 216 deletions(-) diff --git a/esp32/ble.md b/esp32/ble.md index 445f89d..eac4b6c 100644 --- a/esp32/ble.md +++ b/esp32/ble.md @@ -67,6 +67,9 @@ BLE is more complex than Bluetooth Classic. Instead of a simple serial byte stre {: .note } > **Did you skip Lesson 8?** No problem. This lesson is self-contained—you don't need Bluetooth Classic experience to follow along. We'll briefly cover how BLE differs from Classic in the first section. If you want the full comparison, see [Lesson 8](bluetooth-serial.md). +{: .note } +> **This lesson works with both iPhones and Android phones.** Unlike Bluetooth Classic ([Lesson 8](bluetooth-serial.md)), which is blocked on iOS, BLE works with every modern smartphone. We'll start on your computer (Mac or Windows) using Python for the smoothest debugging experience, then move to phone apps that work on both platforms. + ## What is BLE? **Bluetooth Low Energy** (BLE) is a wireless communication protocol introduced in Bluetooth 4.0 (2010). Despite sharing the "Bluetooth" name with Bluetooth Classic, BLE is a completely different protocol stack designed from the ground up for **low-power, intermittent data exchange**. Where Bluetooth Classic was built for continuous streaming (music, file transfers, serial bridges), BLE was built for devices that send small amounts of data infrequently—a heart rate monitor broadcasting a reading every second, a door sensor reporting open/closed, a fitness tracker uploading step counts. @@ -199,7 +202,8 @@ You'll need the following components. We use **[Adafruit's ESP32-S3 Feather](htt You will also need: -- A **smartphone** (Android or iOS!) with the free [nRF Connect](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-mobile) app by Nordic Semiconductor. Unlike Bluetooth Classic, **BLE works with iPhones** — so everyone can participate! 📱 +- **Python 3** with the [bleak](https://pypi.org/project/bleak/) library installed (`pip3 install bleak`). Bleak is a cross-platform BLE library for Python—it works on macOS, Windows, and Linux. +- A **smartphone** (iPhone or Android) with the free [nRF Connect](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-mobile) app by Nordic Semiconductor. Unlike Bluetooth Classic, **BLE works with iPhones**—so everyone can participate! Available on [iOS](https://apps.apple.com/app/nrf-connect-for-mobile/id1054362403) and [Android](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp). {: .note } > [nRF Connect](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-mobile) is a professional-grade BLE debugging tool made by Nordic Semiconductor (a major BLE chip manufacturer). It lets you scan for BLE devices, inspect their services and characteristics, read values, write data, and subscribe to notifications. It's free, available on [iOS](https://apps.apple.com/app/nrf-connect-for-mobile/id1054362403) and [Android](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp), and is the tool we'll use throughout this lesson. Alternatives include [LightBlue](https://punchthrough.com/lightblue/) (iOS/Android) and [BLE Scanner](https://play.google.com/store/apps/details?id=com.macdom.ble.blescanner) (Android). @@ -310,21 +314,85 @@ Let's walk through the key steps: **The `onDisconnect` callback.** This is a critical gotcha: when a central disconnects, the ESP32 **stops advertising by default**. If you don't restart advertising in `onDisconnect()`, the ESP32 goes silent and no new centrals can find it. Always restart advertising after disconnection. -### Discovering the ESP32 from your phone +### Discovering the ESP32 from your computer (Python) + +Let's start on the computer, where debugging is easiest. We'll use [bleak](https://pypi.org/project/bleak/)—a cross-platform BLE client library for Python. If you haven't installed it yet: + +``` +pip3 install bleak +``` + +Here's a script that scans for BLE devices, connects to the ESP32, and reads our characteristic: + +```python +""" +ble_discover.py: Scans for BLE devices, connects to the ESP32, +and reads the greeting characteristic. + +Requires: bleak (pip3 install bleak) + +By Jon E. Froehlich +@jonfroehlich +http://makeabilitylab.io +""" + +import asyncio +from bleak import BleakScanner, BleakClient + +SERVICE_UUID = "4fafc201-1fb5-459e-8fcc-c5c9c331914b" +CHARACTERISTIC_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a8" + +async def main(): + print("Scanning for BLE devices...") + devices = await BleakScanner.discover(timeout=5.0) + + target = None + for d in devices: + print(f" Found: {d.name} ({d.address})") + if d.name and "ESP32" in d.name: + target = d + + if target is None: + print("Could not find ESP32 BLE device. Is the sketch running?") + return + + print(f"\nConnecting to {target.name} ({target.address})...") + async with BleakClient(target.address) as client: + print(f"Connected: {client.is_connected}") + + # Read the greeting characteristic + value = await client.read_gatt_char(CHARACTERISTIC_UUID) + text = value.decode("utf-8") + print(f"Read from characteristic: {text}") + +asyncio.run(main()) +``` + +Run it: + +``` +python3 ble_discover.py +``` + +You should see the ESP32 in the scan results and then read `"Hello from ESP32!"` from the characteristic. 🎉 + +{: .note } +> **Compare with pySerial from [Lesson 8](bluetooth-serial.md).** With Bluetooth Classic, you used `serial.Serial()` to open a virtual COM port—the same API as USB serial. With BLE, there's no virtual COM port; you use `bleak`'s `BleakClient` to connect directly to the device and read structured characteristics. This is the fundamental difference between the two Bluetooth flavors. + +### Discovering the ESP32 from your phone (iPhone and Android) -1. Upload the sketch and open Serial Monitor at 115200 baud. You should see `"BLE server is advertising."`. +Once you've confirmed the ESP32 is working from your computer, let's try it from your phone. **This works on both iPhones and Android phones**—unlike Bluetooth Classic, which was Android-only. -2. On your phone, open the **nRF Connect** app. Tap **Scan** (top right). You should see `"ESP32-BLE"` in the list of discovered devices. +1. On your **iPhone** or **Android phone**, open the **nRF Connect** app ([iOS](https://apps.apple.com/app/nrf-connect-for-mobile/id1054362403) / [Android](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp)). +2. Tap **Scan** (top right). You should see `"ESP32-BLE"` in the list of discovered devices. - + 3. Tap **Connect** next to `"ESP32-BLE"`. The app will connect and display the GATT server structure. You should see your custom service (listed by its UUID) with one characteristic underneath. -4. Tap the **read arrow** (↓) next to the characteristic. You should see `"Hello from ESP32!"` appear as the value. You just read data from a BLE peripheral! 🎉 - - +4. Tap the **read arrow** (↓) next to the characteristic. You should see `"Hello from ESP32!"` appear as the value. You just read data from a BLE peripheral on your phone! {: .note } > **What you're seeing in nRF Connect** is the GATT structure we built in code: one service containing one characteristic. nRF Connect shows the UUIDs for each. Since we used custom 128-bit UUIDs (not standard Bluetooth SIG UUIDs), nRF Connect displays them as "Unknown Service" and "Unknown Characteristic"—it doesn't know what our custom UUIDs mean. If we'd used a standard UUID like `0x181A` (Environmental Sensing), nRF Connect would display the name automatically. @@ -333,9 +401,9 @@ Let's walk through the key steps: ## Part 2: Streaming sensor data with notifications @@ -474,10 +542,86 @@ There are two new elements here compared to Part 1: **`_pSensorCharacteristic->notify()`** pushes the current value to all subscribed centrals. We call this after updating the value with `setValue()`. If no central is subscribed, `notify()` does nothing. -### Try it out +### Reading notifications from your computer (Python) + +Here's a Python script that subscribes to the potentiometer notifications and displays them in real time: + +```python +""" +ble_sensor_reader.py: Connects to the ESP32 BLE sensor and subscribes +to potentiometer notifications. Displays values with a live ASCII bar. + +Requires: bleak (pip3 install bleak) + +By Jon E. Froehlich +@jonfroehlich +http://makeabilitylab.io +""" + +import asyncio +from bleak import BleakScanner, BleakClient + +SERVICE_UUID = "4fafc201-1fb5-459e-8fcc-c5c9c331914b" +SENSOR_CHAR_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a8" + +def on_notification(sender, data): + """Called each time the ESP32 sends a notification.""" + text = data.decode("utf-8").strip() + try: + value = int(text) + bar_length = int(value / 4095 * 50) + bar = '█' * bar_length + '░' * (50 - bar_length) + print(f"\r{bar} {value:4d}", end='', flush=True) + except ValueError: + print(f"\r{text}", end='', flush=True) + +async def main(): + print("Scanning for ESP32-BLE-Sensor...") + devices = await BleakScanner.discover(timeout=5.0) + + target = None + for d in devices: + if d.name and "ESP32" in d.name: + target = d + break + + if target is None: + print("Could not find ESP32. Is the sketch running?") + return + + print(f"Connecting to {target.name}...") + async with BleakClient(target.address) as client: + print(f"Connected! Turn the potentiometer.\n") + + # Subscribe to notifications + await client.start_notify(SENSOR_CHAR_UUID, on_notification) + + # Keep running until Ctrl+C + try: + while True: + await asyncio.sleep(1.0) + except KeyboardInterrupt: + print("\nStopping...") + await client.stop_notify(SENSOR_CHAR_UUID) + +asyncio.run(main()) +``` + +Run it and turn the potentiometer—you'll see a live bar chart updating in your terminal, with data arriving wirelessly over BLE: + +``` +python3 ble_sensor_reader.py +``` -1. Upload the sketch and open Serial Monitor. You should see potentiometer values scrolling by. -2. Open nRF Connect, scan, and connect to `"ESP32-BLE-Sensor"`. +{: .note } +> **Compare with the Python Bluetooth Classic script from [Lesson 8](bluetooth-serial.md).** In L8, you used `pyserial`'s `ser.readline()` to read data from a virtual COM port—a byte stream, just like USB serial. Here, you use `bleak`'s `start_notify()` to subscribe to a specific BLE characteristic—a callback fires each time the ESP32 pushes a new value. The data arrives structured and event-driven rather than as a continuous byte stream. + +### Reading notifications from your phone (iPhone and Android) + +Now try it from your phone: + +1. Open **nRF Connect** on your **iPhone** or **Android phone**. +2. Scan and connect to `"ESP32-BLE-Sensor"`. 3. Expand the service and find the sensor characteristic. 4. Tap the **triple-down-arrow** icon (⇊) to **subscribe to notifications**. 5. Turn the potentiometer—you should see the value updating in real time on your phone! @@ -669,16 +813,68 @@ The key new element is the `LedCallbacks` class. When the central writes to the Notice the pattern: we don't poll for incoming data in `loop()` (like we do with `Serial.available()`). Instead, BLE uses a **callback model**—the library calls our `onWrite()` function when data arrives. This is fundamentally different from the serial polling pattern you're used to. -### Try it out +### Try it out from your computer (Python) + +Here's a quick Python script that writes RGB values to the NeoPixel characteristic: + +```python +""" +ble_neopixel.py: Connects to the ESP32 and sets the NeoPixel color. + +Usage: python3 ble_neopixel.py +Then enter RGB values like: 255 0 128 + +Requires: bleak (pip3 install bleak) + +By Jon E. Froehlich +@jonfroehlich +http://makeabilitylab.io +""" + +import asyncio +from bleak import BleakScanner, BleakClient + +LED_CHAR_UUID = "a3c87500-8ed3-4bdf-8a39-a01bebede295" + +async def main(): + print("Scanning for ESP32-BLE-NeoPixel...") + devices = await BleakScanner.discover(timeout=5.0) + + target = None + for d in devices: + if d.name and "ESP32" in d.name: + target = d + break + + if not target: + print("ESP32 not found.") + return + + async with BleakClient(target.address) as client: + print(f"Connected to {target.name}!") + while True: + rgb = input("Enter R G B (0-255 each, or 'quit'): ") + if rgb.lower() == 'quit': + break + parts = rgb.split() + if len(parts) == 3: + r, g, b = int(parts[0]), int(parts[1]), int(parts[2]) + await client.write_gatt_char(LED_CHAR_UUID, bytes([r, g, b])) + print(f" Sent RGB: ({r}, {g}, {b})") + +asyncio.run(main()) +``` + +### Try it out from your phone (iPhone and Android) 1. Upload the sketch. The NeoPixel should be off initially. -2. Open nRF Connect, scan, and connect to `"ESP32-BLE-NeoPixel"`. +2. Open **nRF Connect** on your **iPhone or Android phone**. Scan and connect to `"ESP32-BLE-NeoPixel"`. 3. Expand the service. You should see **two** characteristics now. 4. Find the LED characteristic (the one with `a3c87500...` UUID). 5. Tap the **write arrow** (↑). In the write dialog, select **ByteArray** as the type, then enter `FF0000` (red), `00FF00` (green), or `0000FF` (blue). Tap **Send**. 6. Watch the NeoPixel change color! 🌈 - + {: .note } > **nRF Connect write format:** When writing raw bytes in nRF Connect, select "ByteArray" (not "Text") and enter hex values without spaces or `0x` prefixes. `FF0000` = red, `00FF00` = green, `0000FF` = blue, `FF00FF` = magenta, `FFFFFF` = white. Each pair of hex digits is one byte (0–255). @@ -1143,4 +1339,4 @@ With BLE under your belt, you've now covered all three major wireless communicat - + \ No newline at end of file diff --git a/esp32/bluetooth-serial.md b/esp32/bluetooth-serial.md index ae6f539..d329c6e 100644 --- a/esp32/bluetooth-serial.md +++ b/esp32/bluetooth-serial.md @@ -23,62 +23,68 @@ nav_order: 8 -In the [last lesson](iot.md), you sent sensor data halfway around the world—through WiFi, across the internet, and up to a cloud dashboard. But what if you just want to talk to the phone in your pocket? Or stream sensor data to a laptop sitting on the same desk? Sometimes you don't need the entire internet—you just need to cut the USB cable. +In the [last lesson](iot.md), you sent sensor data halfway around the world—through WiFi, across the internet, and up to a cloud dashboard. But what if you just want to talk to the laptop sitting right in front of you—without a USB cable? What if you could run the same Python scripts and p5.js sketches from the [Communication module](../communication/serial-intro.md), but wirelessly? -In this lesson, we'll do exactly that using **Bluetooth**. And here's the fun part: the code is going to look *very* familiar. The ESP32's `BluetoothSerial` library provides an API that mirrors the `Serial` library you've been using since your [very first Arduino lesson](../arduino/serial-print.md)—`SerialBT.println()`, `SerialBT.available()`, `SerialBT.read()`—it's all the same, just wireless. By the end of this lesson, you'll have sensor data streaming to your phone over the air, and you'll be controlling an LED from a Bluetooth terminal app. ✨ +In this lesson, we'll do exactly that using **Bluetooth**. And here's the fun part: the code on your computer is going to be *identical*. Bluetooth Classic's Serial Port Profile (SPP) creates a **virtual serial port** on your computer that looks and behaves exactly like a USB serial connection. Your Python scripts, your p5.js sketches, your [serial.js](https://github.com/makeabilitylab/p5js/blob/master/_libraries/serial.js) library—they all work unchanged. The only difference is which port you select. ✨ {: .note } > **In this lesson, you will learn:** > - What Bluetooth is, its origin story, and why there are two very different flavors: Bluetooth Classic and Bluetooth Low Energy (BLE) -> - How the Serial Port Profile (SPP) turns a Bluetooth Classic connection into a wireless serial cable -> - How to use the `BluetoothSerial` library—and why it mirrors the `Serial` API you already know -> - How to pair with and exchange data with an Android phone using a free Bluetooth terminal app -> - How to stream real-time sensor data wirelessly and control an LED from your phone +> - How the Serial Port Profile (SPP) creates a virtual serial port on your computer—making Bluetooth look exactly like a USB serial connection +> - How to pair the ESP32 with your Mac or Windows computer and find the Bluetooth serial port +> - How to use Python and [pySerial](https://pyserial.readthedocs.io/) to communicate with the ESP32 over Bluetooth—using the same code patterns from the [serial introduction](../communication/serial-intro.md) +> - How to use [p5.js](https://p5js.org/) with [serial.js](https://github.com/makeabilitylab/p5js/blob/master/_libraries/serial.js) and [Web Serial](../communication/web-serial.md) to visualize Bluetooth sensor data in a web browser > - Why Bluetooth Classic does **not** work on the ESP32-S3 and does **not** work with iPhones > - When to use Bluetooth Classic *vs.* BLE—and why we'll learn BLE next {: .warning } > **This lesson requires the original ESP32** (like the Adafruit Huzzah32), **not** the ESP32-S3. The ESP32-S3 does not have the hardware for Bluetooth Classic—the `BluetoothSerial` library will not compile on it. If you only have an ESP32-S3, you can borrow a Huzzah32 from the equipment cart, or skip ahead to [Lesson 9: Bluetooth Low Energy](ble.md), which works with both boards. We'll explain why this limitation exists in the [next section](#what-is-bluetooth). +{: .note } +> **What about iPhones?** Apple does not allow third-party apps to use Bluetooth Classic SPP on iOS. This lesson is entirely computer-based (Mac and Windows), so your phone type doesn't matter for Parts 1–4. If you have an **Android** phone, there's an optional bonus activity at the end. In [Lesson 9: BLE](ble.md), we'll use a protocol that works with *everyone's* phone—including iPhones. + ## What is Bluetooth? Bluetooth is a short-range wireless communication standard for exchanging data between devices over radio waves. It operates in the 2.4 GHz ISM band (the same frequency range as WiFi and your microwave oven) and is designed for low-power, close-range connections—typically within about 10 meters indoors. ### A brief history -Bluetooth was developed in the 1990s by [Ericsson](https://en.wikipedia.org/wiki/Ericsson) as a wireless replacement for RS-232 serial cables (the same serial communication we studied in [Lesson 1 of the Communication module](../communication/serial-intro.md)!). The name comes from [Harald Bluetooth](https://en.wikipedia.org/wiki/Harald_Bluetooth), a 10th-century Danish king who united warring Scandinavian tribes—a fitting metaphor for a technology designed to unite different devices. The Bluetooth logo is even a [bind rune](https://en.wikipedia.org/wiki/Bind_rune) merging Harald's initials in [Younger Futhark](https://en.wikipedia.org/wiki/Younger_Futhark): ᚼ (Hagall, "H") and ᛒ (Bjarkan, "B"). +Bluetooth was developed in the 1990s by [Ericsson](https://en.wikipedia.org/wiki/Ericsson) as a wireless replacement for RS-232 serial cables (the same serial communication we studied in [Lesson 1 of the Communication module](../communication/serial-intro.md)!). The name comes from [Harald Bluetooth](https://en.wikipedia.org/wiki/Harald_Bluetooth), a 10th-century Danish king who united warring Scandinavian tribes—a fitting metaphor for a technology designed to unite different devices. The Bluetooth logo is a [bind rune](https://en.wikipedia.org/wiki/Bind_rune) merging Harald's initials in [Younger Futhark](https://en.wikipedia.org/wiki/Younger_Futhark): ᚼ (Hagall, "H") and ᛒ (Bjarkan, "B"). -The technology was standardized by the [Bluetooth Special Interest Group (SIG)](https://www.bluetooth.com/) in 1998 and quickly became ubiquitous in wireless keyboards, mice, headphones, and phone accessories. - ### Two flavors: Classic and Low Energy -Here's where things get interesting—and a bit confusing. When people say "Bluetooth," they might mean one of **two fundamentally different protocols** that happen to share a name: +When people say "Bluetooth," they might mean one of **two fundamentally different protocols** that happen to share a name: -**Bluetooth Classic** (also called BR/EDR, for "Basic Rate / Enhanced Data Rate") is the original Bluetooth. It was designed for **continuous data streaming**—think wireless headphones playing music, file transfers between phones, or serial port emulation. It establishes a persistent connection and can push data at up to 3 Mbps. This is the flavor we'll use in this lesson. +**Bluetooth Classic** (also called BR/EDR, for "Basic Rate / Enhanced Data Rate") is the original Bluetooth. It was designed for **continuous data streaming**—wireless headphones, file transfers, or serial port emulation. It establishes a persistent connection and can push data at up to 3 Mbps. This is the flavor we'll use in this lesson. -**Bluetooth Low Energy** (BLE, introduced in Bluetooth 4.0 in 2010) is a completely different protocol stack designed from the ground up for **low-power, intermittent data exchange**. Think fitness trackers that run for months on a coin cell battery, broadcasting a heart rate reading every few seconds. BLE trades throughput for extraordinary power efficiency. We'll cover BLE in [Lesson 9](ble.md). +**Bluetooth Low Energy** (BLE, introduced in Bluetooth 4.0 in 2010) is a completely different protocol stack designed for **low-power, intermittent data exchange**—fitness trackers that run for months on a coin cell, sensors broadcasting a reading every few seconds. We'll cover BLE in [Lesson 9](ble.md). -Despite sharing the "Bluetooth" name and the 2.4 GHz radio band, Classic and BLE are **not compatible with each other**. A BLE-only device cannot talk to a Bluetooth Classic device and vice versa. A device can support one, the other, or both—the original ESP32 supports **both**, which is why it's such a versatile chip. +Despite sharing the "Bluetooth" name, Classic and BLE are **not compatible with each other**. A BLE-only device cannot talk to a Bluetooth Classic device and vice versa. The original ESP32 supports **both**; the ESP32-S3 supports **BLE only**. | Feature | Bluetooth Classic (BR/EDR) | Bluetooth Low Energy (BLE) | |---|---|---| @@ -94,29 +100,25 @@ Despite sharing the "Bluetooth" name and the 2.4 GHz radio band, Classic and BLE | **ESP32-S3** | **❌** | **✅** | | ESP32-S2 | ❌ (no Bluetooth at all) | ❌ (no Bluetooth at all) | | ESP32-C3, C6 | ❌ | ✅ | -| Typical use cases | Audio, file transfer, serial bridges | Sensors, wearables, beacons, IoT | **Table.** Comparison of Bluetooth Classic and Bluetooth Low Energy. The original ESP32 supports both, but the ESP32-S3 only supports BLE. {: .fs-1 } {: .warning } -> **Why doesn't the ESP32-S3 support Bluetooth Classic?** It's a hardware decision by Espressif. The ESP32-S3 chip was designed for IoT and edge AI workloads where BLE's low power consumption is more important than Classic's streaming capabilities. Dropping the Classic radio reduces die area, power consumption, and cost. If you try to compile a `BluetoothSerial` sketch on the ESP32-S3, you'll get the error: `Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.` This is a chip-level limitation, not a software bug. - -{: .warning } -> **iOS does not support Bluetooth Classic SPP for third-party apps.** Apple restricts Bluetooth Classic access to its own system-level protocols (audio via AirPods, keyboards, *etc.*). If you or your partner have an iPhone, you **cannot** pair with the ESP32 and send data using the approach in this lesson. The good news: BLE works great on iOS, and we'll cover that in [Lesson 9](ble.md). For this lesson, you'll need an **Android phone** or a **computer** (Windows, macOS, or Linux) with Bluetooth. +> **Why doesn't the ESP32-S3 support Bluetooth Classic?** Espressif designed the ESP32-S3 for IoT and edge AI workloads where BLE's low power consumption matters more than Classic's streaming capabilities. Dropping the Classic radio reduces die area, power consumption, and cost. If you try to compile a `BluetoothSerial` sketch on the ESP32-S3, you'll get the error: `Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.` This is a chip-level limitation, not a software bug. ## The Serial Port Profile (SPP) -So how does Bluetooth Classic act like a serial cable? Through something called the **Serial Port Profile (SPP)**. A Bluetooth "profile" is a specification for how a particular type of communication should work over Bluetooth. There are profiles for audio (A2DP), file transfer (FTP), human input devices like keyboards (HID), and many more. SPP is the profile that emulates a wired RS-232 serial port—exactly the kind of serial communication we've been doing over USB. +So how does Bluetooth Classic act like a serial cable? Through something called the **Serial Port Profile (SPP)**. SPP emulates a wired RS-232 serial port—exactly the kind of serial communication we've been doing over USB. -From your code's perspective, SPP makes the Bluetooth link look and behave like the USB serial connection you've used throughout this course. You call `SerialBT.println("Hello!")` and the string arrives at the other end, just as if you'd called `Serial.println("Hello!")` over a USB cable. The Bluetooth stack handles all the radio-layer complexity—frequency hopping, error correction, packet framing—invisibly. +When you pair the ESP32 with your computer over Bluetooth Classic, your operating system creates a **virtual serial port**—a COM port on Windows (*e.g.,* `COM8`) or a `/dev/tty.*` device on macOS (*e.g.,* `/dev/tty.ESP32-Bluetooth`). This virtual port behaves *identically* to the USB serial port you've been using all along. Any software that can open a serial port—the Arduino Serial Monitor, a Python script with [pySerial](https://pyserial.readthedocs.io/), a web browser using the [Web Serial API](../communication/web-serial.md), your [serial.js](https://github.com/makeabilitylab/p5js/blob/master/_libraries/serial.js) library—can communicate over Bluetooth without any code changes. Just select the Bluetooth port instead of the USB port. USB Cable --> Computer (Serial Monitor) - BT Serial: Arduino --> [radio waves] --> Phone (BT Terminal App) - Emphasize that the code on the Arduino side is nearly identical --> + USB Serial: ESP32 → USB Cable → Computer → COM3 → pySerial / serial.js + Bluetooth Serial: ESP32 → [radio] → Computer → COM8 → pySerial / serial.js + Emphasize: same code, same libraries, different port --> -This is the key insight of this lesson: **SPP is a wireless serial cable.** Everything you learned about serial communication in the [Communication module](../communication/serial-intro.md)—baud rates, data framing, parsing comma-separated values, bidirectional communication—applies here. The only difference is the transport layer: radio waves instead of copper wire. +This is the key insight of this lesson: **Bluetooth Classic SPP is a wireless serial cable.** Everything you learned in the [Communication module](../communication/serial-intro.md)—baud rates, data framing, parsing comma-separated values, serial.js—works unchanged. The only difference is the transport: radio waves instead of copper wire. ## Materials @@ -128,23 +130,27 @@ You'll need the following components. This lesson uses the **original ESP32** ([ | Breadboard | [Huzzah32 ESP32 Feather](https://www.adafruit.com/product/3591) | Red LED | 220Ω Resistor | 10kΩ Potentiometer | You will also need: - -- An **Android phone** with the free [Serial Bluetooth Terminal](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal) app by Kai Morich installed. Alternatively, you can use a **Windows, macOS, or Linux computer** with Bluetooth (we'll cover computer pairing briefly, but the phone experience is more fun and portable). +- A **Mac or Windows computer** with Bluetooth (most modern laptops have Bluetooth built in) +- **Python 3** with [pySerial](https://pyserial.readthedocs.io/) installed (`pip3 install pyserial`) +- **Google Chrome** or **Microsoft Edge** (for the Web Serial / p5.js activity) {: .note } > If you only have an ESP32-S3, you can borrow a Huzzah32 from the equipment cart for this lesson, or skip ahead to [Lesson 9: Bluetooth Low Energy](ble.md), which works with the ESP32-S3. ## Part 1: Hello Bluetooth -Let's get wireless! Our first sketch creates a **bridge** between the USB serial connection (to your computer) and a Bluetooth serial connection (to your phone). Anything you type in the Arduino Serial Monitor gets forwarded over Bluetooth to your phone, and anything you type on your phone gets forwarded back to Serial Monitor. It's the simplest possible demonstration of Bluetooth serial communication. +Let's cut the wire! In this first activity, we'll upload a Bluetooth serial sketch to the ESP32, pair it with your computer, and communicate with it using a short Python script—the same approach you learned in the [serial introduction lesson](../communication/serial-intro.md), just wireless. + +### The Arduino code -### The code +This sketch creates a bidirectional bridge between the USB serial connection (to your computer via USB) and a Bluetooth serial connection (to your computer via Bluetooth). Anything sent over Bluetooth arrives on USB serial and vice versa. ```cpp /** * HelloBluetooth: creates a bidirectional bridge between USB Serial - * and Bluetooth Serial (SPP). Type in Serial Monitor → appears on - * phone. Type on phone → appears in Serial Monitor. + * and Bluetooth Serial (SPP). Sends a greeting over Bluetooth every + * 2 seconds. Data received over Bluetooth is echoed to USB Serial + * and vice versa. * * Requires: Original ESP32 (e.g., Huzzah32). Will NOT compile on ESP32-S3. * @@ -170,16 +176,26 @@ Let's get wireless! Our first sketch creates a **bridge** between the USB serial BluetoothSerial SerialBT; +unsigned long _lastGreetingMs = 0; +const unsigned long GREETING_INTERVAL_MS = 2000; + void setup() { Serial.begin(115200); // Initialize Bluetooth with a device name. - // This is the name that appears when you scan for devices on your phone. + // This is the name that appears when you scan for devices on your computer. SerialBT.begin("ESP32-Bluetooth"); Serial.println("Bluetooth device started! You can now pair with 'ESP32-Bluetooth'."); } void loop() { + // Periodically send a greeting over Bluetooth + unsigned long now = millis(); + if (now - _lastGreetingMs >= GREETING_INTERVAL_MS) { + _lastGreetingMs = now; + SerialBT.println("Hello from ESP32!"); + } + // Forward USB Serial → Bluetooth Serial if (Serial.available()) { SerialBT.write(Serial.read()); @@ -192,78 +208,165 @@ void loop() { } ``` -That's it—under 20 lines of logic! Let's walk through it. +**The `#include` and compile-time guards.** `BluetoothSerial.h` is part of the ESP32 Arduino core—no library installation needed. The `#if !defined(...)` blocks produce a clear error if you accidentally build this on an ESP32-S3. -**The `#include` and compile-time guards.** The `BluetoothSerial.h` header is part of the ESP32 Arduino core—no library installation needed. The `#if !defined(...)` blocks are compile-time checks that produce a clear error message if you accidentally try to build this sketch on an ESP32-S3 or other chip that lacks Bluetooth Classic hardware. You won't see these checks at runtime; they prevent the sketch from compiling at all. Try it on an S3 and you'll see the error in the Arduino IDE's output pane. +**`BluetoothSerial SerialBT`** creates a Bluetooth serial object. The API mirrors Arduino's built-in `Serial`: `.begin()`, `.available()`, `.read()`, `.write()`, `.print()`, `.println()`. This is by design—converting wired serial code to Bluetooth is trivially easy. -**`BluetoothSerial SerialBT`** creates a Bluetooth serial object. Notice the naming: `SerialBT`. This is not arbitrary—the object supports the same methods as Arduino's built-in `Serial`: `.begin()`, `.available()`, `.read()`, `.write()`, `.print()`, `.println()`. The API was intentionally designed to mirror `Serial` so that converting a wired serial sketch to Bluetooth is trivially easy. +**`SerialBT.begin("ESP32-Bluetooth")`** initializes the Bluetooth radio and starts advertising with the name `"ESP32-Bluetooth"`. This is the name you'll see when scanning for Bluetooth devices on your computer. -**`SerialBT.begin("ESP32-Bluetooth")`** initializes the Bluetooth radio and starts advertising with the name `"ESP32-Bluetooth"`. This is the name you'll see when scanning for Bluetooth devices on your phone. You can change it to anything you like—your name, your project name, *etc.* +Upload this sketch to your Huzzah32 and open Serial Monitor at 115200 baud. You should see `"Bluetooth device started!"`. -**The `loop()` body** is a two-way bridge. If data arrives on USB serial (from Serial Monitor), forward it to Bluetooth. If data arrives on Bluetooth (from your phone), forward it to USB serial. Each call to `Serial.read()` or `SerialBT.read()` returns one byte at a time—the same behavior you know from the [serial introduction](../communication/serial-intro.md). +### Pairing with your computer -{: .note } -> **Spot the parallel:** this bridge sketch is structurally identical to the cross-device serial forwarding pattern from the [Communication module](../communication/serial-intro.md). The only difference is that one of the two serial connections is now wireless. All your existing serial knowledge—parsing, formatting, handshaking—carries over directly. +Before you can communicate over Bluetooth, you need to **pair** your computer with the ESP32. This is a one-time step—once paired, your computer will remember the device. -### Pairing from an Android phone +#### macOS -Now let's connect! Follow these steps: +1. Open **System Settings → Bluetooth** (or click the Bluetooth icon in the menu bar). +2. Make sure Bluetooth is turned on. You should see `"ESP32-Bluetooth"` appear in the nearby devices list. +3. Click **Connect** next to `"ESP32-Bluetooth"`. macOS will pair with the device. +4. Once paired, macOS creates a virtual serial port. To find it, open **Terminal** and run: -1. **Upload the sketch** to your Huzzah32. Open Serial Monitor at 115200 baud. You should see `"Bluetooth device started!"`. +``` +ls /dev/tty.*Bluetooth* +``` -2. **On your Android phone**, open **Settings → Bluetooth** (or **Settings → Connected devices → Pair new device**, depending on your Android version). You should see `"ESP32-Bluetooth"` in the list of available devices. Tap it to pair. +You should see something like `/dev/tty.ESP32-Bluetooth` or `/dev/tty.ESP32-BluetoothSPP`. This is your Bluetooth serial port—you'll use it in the Python script below. - + -3. **Open the Serial Bluetooth Terminal app** ([free on Google Play](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal)). Tap the menu icon (☰) → **Devices** → select `"ESP32-Bluetooth"` → tap **Connect**. +{: .note } +> **Troubleshooting macOS:** If the Bluetooth serial port doesn't appear, try unpairing and re-pairing the device. On some macOS versions, you may need to open **Terminal** and run `ls /dev/tty.*` before and after pairing to identify the new port. The port name varies by macOS version and Bluetooth stack, but it typically contains the device name. - +#### Windows -4. **You're connected!** 🎉 Type a message in the app and tap Send—it should appear in Arduino Serial Monitor. Type a message in Serial Monitor and press Enter—it should appear on your phone. +1. Open **Settings → Bluetooth & devices** (or **Settings → Devices → Bluetooth & other devices** on Windows 10). +2. Click **Add device → Bluetooth**. Windows will scan for nearby devices. +3. Select `"ESP32-Bluetooth"` and click **Pair**. +4. Once paired, Windows creates a virtual COM port. To find it, open **Device Manager** (right-click the Start button → Device Manager) and expand **Ports (COM & LPT)**. Look for a `"Standard Serial over Bluetooth link"` entry—note its COM port number (e.g., `COM8`). - + {: .note } -> **Alternative terminal apps:** [Serial Bluetooth Terminal](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal) by Kai Morich is our recommended app for its clean interface and reliability. Other options include [Bluetooth Terminal](https://play.google.com/store/apps/details?id=com.sena.bterm) and [Bluetooth Serial Controller](https://play.google.com/store/apps/details?id=nextprotocols.bluetooth.serial.controller). Any app that supports the Bluetooth SPP profile will work. +> **Windows creates two COM ports** for Bluetooth serial: one for outgoing and one for incoming connections. You typically want the **outgoing** port. If one doesn't work, try the other. You can see which is which in **Control Panel → Devices and Printers → right-click ESP32-Bluetooth → Properties → Services**. + +### Connecting with Python + +Now let's connect to the Bluetooth serial port from Python—using the same [pySerial](https://pyserial.readthedocs.io/) library you used in the [serial introduction lesson](../communication/serial-intro.md). If you don't have it installed yet: + +``` +pip3 install pyserial +``` + +Here's a simple script that connects to the ESP32 over Bluetooth, reads incoming data, and lets you send messages back: + +```python +""" +bt_serial_demo.py: Connects to the ESP32 over Bluetooth Serial (SPP) +and demonstrates bidirectional text communication. + +Replace BLUETOOTH_PORT below with your Bluetooth serial port: + - macOS: '/dev/tty.ESP32-Bluetooth' (or similar — run ls /dev/tty.*Bluetooth*) + - Windows: 'COM8' (or whatever port number Device Manager shows) + +Usage: + python3 bt_serial_demo.py + +Requires: pyserial (pip3 install pyserial) + +By Jon E. Froehlich +@jonfroehlich +http://makeabilitylab.io +""" + +import serial +import time + +# --- CHANGE THIS to match your Bluetooth serial port --- +# macOS example: '/dev/tty.ESP32-Bluetooth' +# Windows example: 'COM8' +BLUETOOTH_PORT = '/dev/tty.ESP32-Bluetooth' +BAUD_RATE = 115200 + +print(f"Connecting to {BLUETOOTH_PORT} at {BAUD_RATE} baud...") +ser = serial.Serial(port=BLUETOOTH_PORT, baudrate=BAUD_RATE, timeout=1) +print("Connected!") + +# Give the connection a moment to stabilize +time.sleep(2) + +try: + while True: + # Read any incoming data from the ESP32 + if ser.in_waiting > 0: + line = ser.readline().decode('utf-8', errors='replace').strip() + if line: + print(f"Received: {line}") + + # Ask the user for input and send it over Bluetooth + user_input = input("Type a message (or 'quit' to exit): ") + if user_input.lower() == 'quit': + break + + ser.write((user_input + '\n').encode('utf-8')) + print(f"Sent: {user_input}") -
-Pairing from a computer instead? (click to expand) + # Brief pause to allow the ESP32 to respond + time.sleep(0.1) -You can also pair from a desktop or laptop computer with Bluetooth: + # Read the response + if ser.in_waiting > 0: + response = ser.readline().decode('utf-8', errors='replace').strip() + if response: + print(f"Received: {response}") -**Windows 10/11:** Go to **Settings → Bluetooth & devices → Add device → Bluetooth**. Select `"ESP32-Bluetooth"`. Once paired, Windows creates a virtual COM port. Find the port number in **Device Manager → Ports (COM & LPT)** — look for a "Standard Serial over Bluetooth link" entry. You can then open this COM port in any serial terminal (PuTTY, Arduino Serial Monitor on a second instance, *etc.*) at any baud rate (SPP ignores the baud setting; it's handled at the Bluetooth layer). +except KeyboardInterrupt: + print("\nExiting...") -**macOS:** Go to **System Settings → Bluetooth**. Click **Connect** next to `"ESP32-Bluetooth"`. Once paired, the ESP32 appears as a serial device at `/dev/tty.ESP32-Bluetooth-ESP32SPP` (or similar). You can open it with `screen /dev/tty.ESP32-Bluetooth-ESP32SPP 115200` in Terminal. +finally: + ser.close() + print("Serial port closed.") +``` + +{: .note } +> **This is almost identical to the [serial_demo.py](https://github.com/makeabilitylab/arduino/blob/master/Python/Serial/serial_demo.py) from the Communication module.** The only difference is the port name: instead of `'COM3'` or `'/dev/tty.usbmodem14101'` (a USB port), you use `'COM8'` or `'/dev/tty.ESP32-Bluetooth'` (a Bluetooth port). The pySerial API, the `readline()` calls, the `write()` calls—everything else is the same. That's the power of SPP: your computer's operating system makes Bluetooth look like a wired serial connection. -**Linux:** Use `bluetoothctl` to pair, then `rfcomm` to create a serial device. The process varies by distribution; see the [Arch Wiki Bluetooth page](https://wiki.archlinux.org/title/Bluetooth) for a thorough walkthrough. +Run the script: -
+``` +python3 bt_serial_demo.py +``` + +You should see `"Hello from ESP32!"` messages arriving every 2 seconds. Type a message and press Enter—it will be sent to the ESP32 and forwarded to USB Serial Monitor. You're communicating wirelessly! 🎉 + +{: .warning } +> **Only one program can open a serial port at a time.** If you have Arduino's Serial Monitor open on the Bluetooth COM port, your Python script won't be able to connect (and vice versa). Close Serial Monitor before running Python—or use Serial Monitor on the *USB* port and Python on the *Bluetooth* port. This is the same constraint from the [serial introduction](../communication/serial-intro.md#only-one-computer-program-can-open-a-serial-port-at-a-time), just with two ports to manage. ### Workbench demo + 2. Pairing from macOS (and/or Windows) + 3. Running the Python script and exchanging messages + 4. The "aha moment": same pySerial code, wireless connection +--> ## Part 2: Streaming sensor data -Typing text back and forth is a nice proof-of-concept, but let's do something more interesting: stream **live sensor data** from a potentiometer to your phone, wirelessly—the same data you'd normally see in Serial Monitor or Serial Plotter, but arriving over Bluetooth instead of USB. +Now let's stream live sensor data. We'll read a potentiometer and send its value over Bluetooth—then visualize it in Python. ### The circuit -Connect a 10kΩ potentiometer to the Huzzah32. Use pin **A7** (GPIO 32), which is an ADC1 pin. (On the original ESP32, ADC2 pins conflict with both WiFi *and* Bluetooth Classic, so always use ADC1 pins for analog input when using wireless features.) +Connect a 10kΩ potentiometer to the Huzzah32 on pin **A7** (GPIO 32), which is an ADC1 pin. (On the original ESP32, ADC2 pins conflict with both WiFi *and* Bluetooth Classic, so always use ADC1 pins for analog input when using wireless features.) - + -### The code +### The Arduino code ```cpp /** * BluetoothPotentiometer: reads a potentiometer and streams the value - * over Bluetooth Serial to a connected device (phone or computer). - * Also prints to USB Serial for debugging. + * over both USB Serial and Bluetooth Serial. * * Circuit: * - 10kΩ potentiometer on A7 (GPIO 32) — must be an ADC1 pin @@ -296,55 +399,210 @@ void setup() { void loop() { int potVal = analogRead(POT_INPUT_PIN); - // Send to USB Serial (for Serial Monitor / Serial Plotter debugging) - Serial.print("Pot:"); + // Send to USB Serial (for Serial Monitor / Serial Plotter) Serial.println(potVal); - // Send to Bluetooth Serial (to the phone) - SerialBT.print("Pot:"); + // Send to Bluetooth Serial (to your computer via Bluetooth) SerialBT.println(potVal); - delay(100); // ~10 readings per second + delay(50); // ~20 readings per second } ``` -Upload this sketch, pair your phone, and open the Serial Bluetooth Terminal app. You should see a stream of potentiometer values scrolling by—twist the knob and watch the numbers change in real time on your phone. It's the same experience as Serial Monitor, but without the USB cable. 🎉 +### Reading the data in Python + +Here's a Python script that reads the streaming potentiometer data and prints it with a simple ASCII bar visualization: + +```python +""" +bt_sensor_reader.py: Reads streaming sensor data from the ESP32 over +Bluetooth Serial and displays a live ASCII bar chart in the terminal. + +Replace BLUETOOTH_PORT with your Bluetooth serial port. + +By Jon E. Froehlich +@jonfroehlich +http://makeabilitylab.io +""" + +import serial +import time + +BLUETOOTH_PORT = '/dev/tty.ESP32-PotSensor' # macOS — change for your system +BAUD_RATE = 115200 + +print(f"Connecting to {BLUETOOTH_PORT}...") +ser = serial.Serial(port=BLUETOOTH_PORT, baudrate=BAUD_RATE, timeout=1) +print("Connected! Turn the potentiometer to see values.\n") +time.sleep(2) + +try: + while True: + if ser.in_waiting > 0: + line = ser.readline().decode('utf-8', errors='replace').strip() + if line: + try: + value = int(line) + # Scale to a 50-character bar (ESP32 ADC is 12-bit: 0-4095) + bar_length = int(value / 4095 * 50) + bar = '█' * bar_length + '░' * (50 - bar_length) + print(f"\r{bar} {value:4d}", end='', flush=True) + except ValueError: + print(f"\r{line}", end='', flush=True) + +except KeyboardInterrupt: + print("\nExiting...") + +finally: + ser.close() +``` + +Run this script, then turn the potentiometer—you'll see a live bar chart updating in your terminal, with data arriving wirelessly. Compare this with the wired Serial Plotter experience: same data, no cable. + +### Workbench demo + + + +## Part 3: p5.js over Bluetooth with serial.js + +Here's where things get really satisfying. Because your computer's Bluetooth serial port looks just like a USB serial port, the [Web Serial API](../communication/web-serial.md) works with it—and so does your [serial.js](https://github.com/makeabilitylab/p5js/blob/master/_libraries/serial.js) library. You can build the same [p5.js](https://p5js.org/) interactive sketches from the [Communication module](../communication/p5js-serial.md), but with data arriving wirelessly over Bluetooth. {: .note } -> **Why is `delay(100)` OK here?** In the [IoT lesson](iot.md), we warned that `delay()` is dangerous because it blocks the `io.run()` MQTT keepalive loop. Bluetooth Classic SPP doesn't have that constraint—the connection is persistent and tolerates delays just fine. That said, `millis()`-based timing is still better practice for more complex sketches where you need multiple tasks running at different rates. See the [IoT lesson](iot.md#why-no-delay-in-the-main-loop) for the non-blocking pattern. +> **No changes to serial.js needed!** When you click "Connect" in a Web Serial dialog, Chrome shows *all* available serial ports—including the Bluetooth virtual COM port. Select the Bluetooth port instead of the USB port, and your existing serial.js code works unchanged. This is the entire point of SPP: the operating system abstracts away the wireless transport. + +### The web page + +This p5.js sketch reads the potentiometer value over Bluetooth and draws a dynamic circle whose size and color respond to the sensor data. The code structure is identical to the [p5.js Serial lesson](../communication/p5js-serial.md)—only the port selection differs. + +Make sure the Part 2 sketch (`BluetoothPotentiometer`) is running on your ESP32. + +```html + + + + + Bluetooth Potentiometer Visualizer + + + + + + + +``` + +### Try it out + +1. Make sure the `BluetoothPotentiometer` sketch is running on your ESP32. +2. Open this HTML file using a local server (VS Code Live Server or `python3 -m http.server`). Open it in **Chrome**. +3. Click anywhere on the canvas. Chrome will show the serial port selection dialog. +4. **Select the Bluetooth serial port** (not the USB port). On macOS, it will be named something like `tty.ESP32-PotSensor`. On Windows, it will be the Bluetooth COM port you noted earlier. +5. Turn the potentiometer—the circle changes size and color in real time, with data arriving wirelessly! 🎉 + + + {: .note } -> **Serial Plotter over Bluetooth?** The Arduino IDE's built-in Serial Plotter reads from the USB serial port, not from Bluetooth. So you can't *directly* use Serial Plotter to graph Bluetooth data. However, since we're also printing to `Serial`, you can view the data in Serial Plotter over USB while simultaneously streaming it to your phone over Bluetooth. In [Exercise 1](#exercises), we'll suggest building your own wireless plotter using a web app or p5.js. +> **Compare this with the [p5.js Serial lesson](../communication/p5js-serial.md).** The code is *identical*—same `serial.js` import, same event callbacks, same `connectAndOpen()` call. The only difference is which port you select in the browser dialog. This is SPP's superpower: your existing Web Serial code works wirelessly without any modifications. ### Workbench demo + 1. Opening the p5.js sketch in Chrome + 2. Selecting the Bluetooth serial port in the dialog + 3. Turning the pot and watching the visualization respond wirelessly +--> -## Part 3: Controlling an LED from your phone +## Part 4: Bidirectional control -Now let's go the other direction: send commands *from* your phone *to* the ESP32 to control hardware. We'll parse simple text commands received over Bluetooth to toggle an LED. +Let's go both directions: stream sensor data *from* the ESP32 *and* send LED control commands *to* the ESP32. We'll extend the p5.js sketch to include a slider that controls LED brightness. ### The circuit -Add a standard LED circuit: LED on GPIO 21 through a 220Ω resistor to ground. Keep the potentiometer connected to A7 from Part 2—we'll stream sensor data *and* accept LED commands simultaneously. +Add an LED circuit: LED on GPIO 21 through a 220Ω resistor to ground. Keep the potentiometer connected from Part 2. - + -### The code +### The Arduino code ```cpp /** * BluetoothLedControl: bidirectional Bluetooth communication. - * Streams potentiometer data to the phone AND accepts commands - * from the phone to control an LED. + * Streams potentiometer data out AND accepts brightness commands in. * - * Commands (sent from phone): - * "ON" or "1" → turn LED on - * "OFF" or "0" → turn LED off - * Any integer 0-255 → set LED brightness via PWM + * Incoming format: a single integer 0–255 followed by newline. + * Outgoing format: potentiometer value (0–4095) followed by newline. * * Circuit: * - 10kΩ potentiometer on A7 (GPIO 32) @@ -367,175 +625,242 @@ Add a standard LED circuit: LED on GPIO 21 through a 220Ω resistor to ground. K BluetoothSerial SerialBT; -const int POT_INPUT_PIN = A7; // GPIO 32, ADC1 pin -const int LED_OUTPUT_PIN = 21; // Any PWM-capable GPIO pin +const int POT_INPUT_PIN = A7; +const int LED_OUTPUT_PIN = 21; -// Timing for non-blocking sensor reads unsigned long _lastSensorSendMs = 0; -const unsigned long SENSOR_SEND_INTERVAL_MS = 200; // send sensor data 5x/sec +const unsigned long SENSOR_SEND_INTERVAL_MS = 50; void setup() { Serial.begin(115200); pinMode(LED_OUTPUT_PIN, OUTPUT); - SerialBT.begin("ESP32-LEDControl"); Serial.println("Bluetooth started! Pair with 'ESP32-LEDControl'."); - Serial.println("Send 'ON', 'OFF', or a number 0-255 from your phone."); } void loop() { - // --- Receive commands from phone --- + // --- Receive brightness commands from computer --- if (SerialBT.available()) { String command = SerialBT.readStringUntil('\n'); - command.trim(); // remove whitespace and newline characters - - Serial.print("Received via Bluetooth: "); - Serial.println(command); - - if (command.equalsIgnoreCase("ON") || command == "1") { - analogWrite(LED_OUTPUT_PIN, 255); - SerialBT.println("LED: ON (brightness 255)"); - - } else if (command.equalsIgnoreCase("OFF") || command == "0") { - analogWrite(LED_OUTPUT_PIN, 0); - SerialBT.println("LED: OFF"); - - } else { - // Try to parse as an integer for PWM brightness - int brightness = command.toInt(); - - // toInt() returns 0 for non-numeric strings, so check if - // the command was actually "0" (which we handled above) - if (brightness >= 0 && brightness <= 255) { - analogWrite(LED_OUTPUT_PIN, brightness); - SerialBT.print("LED brightness set to: "); - SerialBT.println(brightness); - } else { - SerialBT.println("Unknown command. Send ON, OFF, or 0-255."); - } - } + command.trim(); + int brightness = command.toInt(); + brightness = constrain(brightness, 0, 255); + analogWrite(LED_OUTPUT_PIN, brightness); + Serial.print("LED brightness: "); + Serial.println(brightness); } - // --- Stream sensor data to phone --- + // --- Stream sensor data to computer --- unsigned long now = millis(); if (now - _lastSensorSendMs >= SENSOR_SEND_INTERVAL_MS) { _lastSensorSendMs = now; - int potVal = analogRead(POT_INPUT_PIN); - SerialBT.print("Pot:"); SerialBT.println(potVal); - - // Also print to USB Serial for debugging - Serial.print("Pot:"); Serial.println(potVal); } } ``` -### Try it out +### The p5.js sketch with bidirectional communication + +Extend the Part 3 sketch with a brightness slider that sends values to the ESP32: + +```html + + + + + Bluetooth Bidirectional Control + + + + + + + +``` + +Drag the slider—the LED on your breadboard dims and brightens wirelessly. Meanwhile, the potentiometer data continues streaming to the visualization. This is the same bidirectional communication pattern from [p5.js Serial I/O](../communication/p5js-serial-io.md), but over Bluetooth. ### Workbench demo -## Gotchas and limitations +## Part 5: Android phone (optional bonus) + +If you have an **Android** phone, you can also communicate with the ESP32 using a Bluetooth terminal app. This is a quick bonus activity—the main lesson is computer-based. + +{: .note } +> **iPhone users:** You cannot use Bluetooth Classic SPP from an iPhone. Apple restricts Bluetooth Classic to system-level functions (audio, keyboards, *etc.*). In [Lesson 9: BLE](ble.md), we'll use a protocol that works with both iOS and Android. -Bluetooth Classic SPP is simple and effective, but it comes with real limitations that are worth understanding—both because they'll affect your projects and because they motivate learning BLE in the [next lesson](ble.md). +1. On your Android phone, install the free [Serial Bluetooth Terminal](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal) app by Kai Morich. +2. Go to **Settings → Bluetooth** and pair with `"ESP32-LEDControl"` (or whatever name your sketch uses). +3. Open the Serial Bluetooth Terminal app → **Devices** → select your ESP32 → **Connect**. +4. You should see potentiometer data streaming. Type a number (0–255) and tap Send to control the LED. -**One connection at a time.** SPP is a point-to-point protocol. Only one device can connect to the ESP32 at a time. If your phone is connected and a second phone tries to connect, it will fail. This is a fundamental constraint of the Serial Port Profile. + -**No iOS support.** This bears repeating because it catches people off guard: Apple does not allow third-party apps to use Bluetooth Classic SPP on iOS. Your iPhone can use Bluetooth Classic for audio (AirPods, car stereo) and keyboards, but Apple reserves those system-level profiles. Third-party apps can only use BLE. If half your team has iPhones, Bluetooth Classic is a non-starter for collaborative projects. +{: .note } +> **Custom buttons:** The Serial Bluetooth Terminal app lets you configure custom buttons (under **Settings → Buttons**) that send predefined strings. Set up buttons for `0`, `128`, and `255` to quickly toggle between off, half, and full brightness—a simple remote control UI! + +## Gotchas and limitations -**No ESP32-S3, S2, C3, or C6.** Only the original ESP32 chip includes the Bluetooth Classic radio. All the newer, more power-efficient variants dropped it in favor of BLE-only. As these newer chips become the standard (the S3 is already our primary board), Bluetooth Classic becomes increasingly niche for ESP32 development. +**One connection at a time.** SPP is point-to-point. Only one device (your computer *or* your phone) can connect to the ESP32's Bluetooth serial at a time. -**Range and interference.** Bluetooth Classic Class 2 (which the ESP32 uses) has a theoretical range of about 10 meters, but walls, furniture, and other 2.4 GHz devices (WiFi routers, microwaves) reduce this significantly. In a busy classroom or lab, expect reliable communication at 5–8 meters. You'll explore this in [Exercise 4](#exercises). +**No iOS support.** Apple blocks Bluetooth Classic SPP for third-party apps. iPhone users can participate fully in the computer-based activities (Parts 1–4) but cannot connect from their phones. -**Memory usage.** Running Bluetooth Classic consumes significant RAM on the ESP32. If you also enable WiFi, the combined memory footprint can cause instability in complex sketches—the original ESP32 has only 520KB of SRAM. If you're building a project that needs both WiFi and Bluetooth, consider using BLE instead of Classic, or carefully manage memory allocation. +**No ESP32-S3.** Only the original ESP32 supports Bluetooth Classic. The ESP32-S3, S2, C3, and C6 do not have the hardware. -**Security.** Default Bluetooth pairing uses ["Just Works"](https://www.bluetooth.com/blog/bluetooth-pairing-part-1/) association, which provides basic encryption but no authentication—any nearby device can pair. For projects where security matters, you can require a PIN using `SerialBT.setPin("1234")` before `SerialBT.begin()`, but Bluetooth Classic security is generally considered weaker than BLE's options. For a classroom setting, the default is fine. +**Range and interference.** Expect reliable communication within about 5–10 meters indoors. Walls, furniture, and other 2.4 GHz devices (WiFi, microwaves) reduce range. -## When to use Bluetooth Classic vs. BLE +**macOS Bluetooth port naming.** The virtual serial port name varies across macOS versions and can be long or cryptic. Use `ls /dev/tty.*Bluetooth*` or `ls /dev/tty.*ESP*` to find it. If the port disappears, unpair and re-pair the device. -Given these limitations, when is Bluetooth Classic SPP actually the right choice? +**Memory usage.** Bluetooth Classic consumes significant RAM. If you also need WiFi, consider using BLE instead—or be prepared for potential instability in complex sketches on the original ESP32's 520KB SRAM. + +## When to use Bluetooth Classic vs. BLE **Use Bluetooth Classic SPP when:** -- You need a simple wireless serial bridge and are using the original ESP32 -- You're communicating with an **Android** phone or a **computer** -- You want the fastest possible development time—the `BluetoothSerial` API is dead simple -- You're building a quick prototype where iOS compatibility doesn't matter -- You need higher throughput for continuous data streaming (audio, dense sensor data) +- You want the simplest possible wireless serial—your existing serial code works unchanged +- You're working entirely from a computer (Mac or Windows) +- You're using the original ESP32 (Huzzah32) +- You don't need iPhone support -**Use BLE (Lesson 9) when:** +**Use BLE ([Lesson 9](ble.md)) when:** - You're using the ESP32-S3 (or any non-original ESP32) -- You need iOS compatibility +- You need iPhone / iOS compatibility +- You want to connect from a phone app that works on both platforms - Power efficiency matters (battery-powered projects) -- You want to connect multiple centrals, or communicate with standard BLE peripherals -- You're building something that needs to work with modern phones and computers universally -- You want to build a [Web Bluetooth](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API) web app to interact with your ESP32 from a browser - -For most new projects—especially with the ESP32-S3 as your primary board—**BLE is the better default choice**. But Bluetooth Classic SPP remains a useful tool for its sheer simplicity: when you just need a wireless serial cable and you have the right hardware, nothing is faster to get working. +- You want to build a [Web Bluetooth](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API) web app ## Exercises -**Exercise 1: Wireless sensor dashboard.** Modify Part 2 to send comma-separated values from *two* sensors (potentiometer + photoresistor). Write a simple [p5.js](https://p5js.org/) or vanilla JavaScript sketch that connects to the ESP32 via a [Bluetooth serial port on your computer](#pairing-from-a-computer-instead-click-to-expand) (using the [Web Serial API](../communication/web-serial.md) on the virtual Bluetooth COM port) and plots both sensor streams in real time. How does this compare to the wired serial plotter approach? - -**Exercise 2: NeoPixel color controller.** Connect a NeoPixel strip (or the onboard NeoPixel on a Huzzah32, if available). Send RGB values as comma-separated text from the phone (*e.g.,* `255,0,128`). Parse the three values on the ESP32 and set the NeoPixel color. This is a great exercise in serial parsing—refer to the [Communication module](../communication/p5js-serial-io.md) for parsing patterns. +**Exercise 1: Multi-sensor dashboard.** Modify the Arduino code to send comma-separated values from *two* sensors (potentiometer + photoresistor). Update the p5.js sketch to parse the CSV data and visualize both streams—one as circle size, one as background color. This is the same parsing pattern from [p5.js Serial I/O](../communication/p5js-serial-io.md). -**Exercise 3: Bluetooth chat between two ESP32s.** The ESP32's `BluetoothSerial` library supports both peripheral (slave) and central (master) roles. Flash one ESP32 with the [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) example (peripheral) and another with [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (central). Build a two-way text chat between the two boards, displayed on Serial Monitor for each. +**Exercise 2: Compare wired vs. wireless.** Open Arduino's Serial Plotter on the USB port while simultaneously running the Python sensor reader on the Bluetooth port. Both show the same data—one wired, one wireless. Can you see any latency difference? Try it with `delay(10)` vs. `delay(100)` in the Arduino sketch. -**Exercise 4: Range test.** With the sensor streaming sketch from Part 2 running, walk away from your ESP32 with the phone connected. At what distance do you start seeing gaps in the data? When does the connection drop entirely? Try with and without walls or obstacles between you and the ESP32. How does the range compare to your WiFi experience from the [IoT lesson](iot.md)? +**Exercise 3: Chat between two ESP32s.** Flash one ESP32 with the [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) example (peripheral) and another with [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (central). Build a two-way text chat. -**Exercise 5: Latency comparison.** Measure the round-trip latency of Bluetooth serial *vs.* USB serial. Write a sketch that listens for a single byte, immediately echoes it back, and records the timestamp. On a computer, send a byte over USB serial, measure the round-trip time, then send a byte over Bluetooth serial (via the virtual COM port) and measure again. How do they compare? You can use a Python script with the [`time`](https://docs.python.org/3/library/time.html) module and [`pyserial`](https://pyserial.readthedocs.io/) library for precise timing. +**Exercise 4: Range test.** With the sensor streaming sketch running, carry your laptop away from the ESP32. At what distance does the data start dropping out? When does the connection drop entirely? Test with and without walls between you and the ESP32. -**Exercise 6: Custom Bluetooth name.** Modify the sketch to include sensor data in the Bluetooth device name itself—for example, `"ESP32-Light:742"`. Some BLE beacon systems use this trick to broadcast data without requiring a connection. Does it work with Bluetooth Classic? How often can you update the name? (Hint: you'll need to call `SerialBT.end()` and `SerialBT.begin()` with the new name—this is hacky and not recommended for production, but it's an interesting experiment.) +**Exercise 5: Servo control.** Send angle values (0–180) from a p5.js slider over Bluetooth. Parse the value on the ESP32 and control a servo motor wirelessly. Compare the feel with a directly-wired potentiometer control—can you notice the latency? -**Exercise 7: Servo control.** Connect a servo motor (from the [Servo lesson](../advancedio/servo.md)). Send angle values (0–180) from your phone. Parse the incoming number and call `myServo.write(angle)`. Now you have a wireless servo controller! Can you feel the latency compared to a directly-wired potentiometer control? +**Exercise 6: Replicate a Communication module project.** Pick any project from the [Communication module](../communication/index.md) (the paint app, the shape drawer, *etc.*) and run it over Bluetooth instead of USB. How much code did you have to change? (The answer should be: none—just a different port selection.) ## Summary In this lesson, you cut the wire! Here's what you learned: -- **Bluetooth** is a short-range wireless standard operating at 2.4 GHz, with two fundamentally different flavors: **Bluetooth Classic** (continuous streaming, higher power) and **Bluetooth Low Energy** (intermittent data, very low power). Despite sharing a name, they are incompatible protocols. -- **The Serial Port Profile (SPP)** is a Bluetooth Classic profile that emulates a wired RS-232 serial connection over the air. From your code's perspective, `SerialBT` behaves identically to `Serial`—the same `.available()`, `.read()`, `.write()`, `.println()` methods you've used all along. -- The `BluetoothSerial` library ships with the ESP32 Arduino core and requires no installation. Create a `BluetoothSerial` object, call `SerialBT.begin("DeviceName")`, and you're advertising. -- **Everything you know about serial communication transfers directly** to Bluetooth serial: parsing comma-separated values, bidirectional communication, formatting sensor data—the only difference is radio waves instead of a USB cable. -- **Bluetooth Classic SPP only works on the original ESP32** (like the Huzzah32). The ESP32-S3 and other newer variants do not have the hardware for Bluetooth Classic—attempting to compile a `BluetoothSerial` sketch will produce a clear compile-time error. -- **iOS does not support Bluetooth Classic SPP** for third-party apps. You need an Android phone or a computer with Bluetooth to use this lesson's approach. -- **One connection at a time:** SPP is point-to-point. Only one device can be connected to the ESP32's Bluetooth serial at once. -- Bluetooth Classic has a practical range of about **5–10 meters indoors** and is affected by walls, furniture, and 2.4 GHz interference (WiFi, microwaves). -- For most new projects—especially on the ESP32-S3—**BLE is the better default choice** due to universal device support, lower power consumption, and broader compatibility. But Bluetooth Classic SPP remains the fastest path from wired serial to wireless serial when you have the right hardware. +- **Bluetooth Classic's Serial Port Profile (SPP)** creates a virtual serial port on your computer that behaves identically to a USB serial port. Your Python scripts, p5.js sketches, serial.js library, and Serial Monitor all work unchanged—just select the Bluetooth port instead of the USB port. +- **Pairing** the ESP32 with your Mac or Windows computer is a one-time step. macOS creates a `/dev/tty.*` device; Windows creates a COM port. +- **pySerial** connects to the Bluetooth serial port with the same API you already know—only the port name changes. +- **Web Serial + serial.js** work with Bluetooth serial ports in Chrome. Your existing p5.js sketches from the Communication module can be used wirelessly without code changes. +- **Bluetooth Classic SPP only works on the original ESP32** (like the Huzzah32). The ESP32-S3 and other newer variants lack the hardware. +- **iOS does not support Bluetooth Classic SPP** for third-party apps. This lesson is computer-based, so phone type doesn't matter—but for phone-based projects, BLE (Lesson 9) is required. +- **Bluetooth Classic has a practical range of 5–10 meters indoors** and supports only one connection at a time. +- **For most new projects—especially on the ESP32-S3—BLE is the better default choice** due to universal device and phone support. But Bluetooth Classic SPP is unbeatable when you want to reuse existing serial code wirelessly. ## Resources -- [BluetoothSerial library source and examples](https://github.com/espressif/arduino-esp32/tree/master/libraries/BluetoothSerial) — the official library in the ESP32 Arduino core, including `SerialToSerialBT` and `SerialToSerialBTM` examples -- [ESP32 Arduino Bluetooth API docs](https://docs.espressif.com/projects/arduino-esp32/en/latest/api/bluetooth.html) — Espressif's API reference for `BluetoothSerial` -- [Serial Bluetooth Terminal](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal) — our recommended Android app for Bluetooth serial communication (free, by Kai Morich) -- [Bluetooth SIG: Learn About Bluetooth](https://www.bluetooth.com/learn-about-bluetooth/tech-overview/) — official overview of Bluetooth technology, profiles, and specifications -- [Bluetooth SIG: Classic vs. Low Energy](https://www.bluetooth.com/learn-about-bluetooth/tech-overview/le-vs-classic/) — the Bluetooth SIG's own comparison of Classic and BLE -- [Random Nerd Tutorials: ESP32 Bluetooth Classic](https://randomnerdtutorials.com/esp32-bluetooth-classic-arduino-ide/) — a well-written tutorial covering additional Bluetooth Classic features -- [Intro to Serial Communication](../communication/serial-intro.md) — our lesson on the serial fundamentals that underpin both USB serial and Bluetooth serial +- [BluetoothSerial library source and examples](https://github.com/espressif/arduino-esp32/tree/master/libraries/BluetoothSerial) — the official library in the ESP32 Arduino core +- [ESP32 Arduino Bluetooth API docs](https://docs.espressif.com/projects/arduino-esp32/en/latest/api/bluetooth.html) — Espressif's API reference +- [pySerial documentation](https://pyserial.readthedocs.io/en/latest/) — the Python serial library used throughout our lessons +- [serial.js](https://github.com/makeabilitylab/p5js/blob/master/_libraries/serial.js) — our Web Serial helper library for p5.js +- [Web Serial lesson](../communication/web-serial.md) — our introduction to Web Serial (the same API that works with Bluetooth COM ports) +- [Serial Bluetooth Terminal](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal) — our recommended Android app for Bluetooth serial (free, by Kai Morich) +- [Bluetooth SIG: Learn About Bluetooth](https://www.bluetooth.com/learn-about-bluetooth/tech-overview/) — official overview of Bluetooth technology +- [Random Nerd Tutorials: ESP32 Bluetooth Classic](https://randomnerdtutorials.com/esp32-bluetooth-classic-arduino-ide/) — additional Bluetooth Classic tutorials ## Next Lesson -In the [next lesson](ble.md), we'll learn **Bluetooth Low Energy (BLE)**—the protocol that powers fitness trackers, smart home devices, and billions of IoT sensors. BLE works on the ESP32-S3, works with iPhones, and introduces a completely different (and more powerful) way of structuring wireless data. The code is more complex, but the capabilities are transformative. Let's go! 🚀 +In the [next lesson](ble.md), we'll learn **Bluetooth Low Energy (BLE)**—the protocol that powers fitness trackers, smart home devices, and billions of IoT sensors. BLE works on the ESP32-S3, works with iPhones *and* Android phones, and introduces a structured data model that's more powerful than serial. The code is more complex, but the capabilities—and the universal device compatibility—are worth it. Let's go! 🚀 + \ No newline at end of file From ddea52929f122fa20f62d1e42c0f698ed54d7e19 Mon Sep 17 00:00:00 2001 From: Jon Froehlich Date: Sat, 23 May 2026 05:30:44 -0700 Subject: [PATCH 03/19] Update Bluetooth serial docs to use Makeability Lab JS Replace in-file examples and old p5js serial library links with canonical references to the Makeability Lab JS repo and CDN. Removed large inline Python demos in favor of existing serial_demo/serial_bar_graph/serial_draw_circle scripts, simplified instructions to changing only the serial port, and clarified SPP behavior and usage notes. Updated p5.js example script src to the new makelab.serial.iife.min.js CDN path and adjusted README links in the resources list. File changed: esp32/bluetooth-serial.md. --- esp32/bluetooth-serial.md | 173 +++++++++++--------------------------- 1 file changed, 50 insertions(+), 123 deletions(-) diff --git a/esp32/bluetooth-serial.md b/esp32/bluetooth-serial.md index d329c6e..a5bb8b9 100644 --- a/esp32/bluetooth-serial.md +++ b/esp32/bluetooth-serial.md @@ -48,7 +48,7 @@ nav_order: 8 In the [last lesson](iot.md), you sent sensor data halfway around the world—through WiFi, across the internet, and up to a cloud dashboard. But what if you just want to talk to the laptop sitting right in front of you—without a USB cable? What if you could run the same Python scripts and p5.js sketches from the [Communication module](../communication/serial-intro.md), but wirelessly? -In this lesson, we'll do exactly that using **Bluetooth**. And here's the fun part: the code on your computer is going to be *identical*. Bluetooth Classic's Serial Port Profile (SPP) creates a **virtual serial port** on your computer that looks and behaves exactly like a USB serial connection. Your Python scripts, your p5.js sketches, your [serial.js](https://github.com/makeabilitylab/p5js/blob/master/_libraries/serial.js) library—they all work unchanged. The only difference is which port you select. ✨ +In this lesson, we'll do exactly that using **Bluetooth**. And here's the fun part: the code on your computer is going to be *identical*. Bluetooth Classic's Serial Port Profile (SPP) creates a **virtual serial port** on your computer that looks and behaves exactly like a USB serial connection. Your Python scripts, your p5.js sketches, your [serial.js](https://github.com/makeabilitylab/js) library—they all work unchanged. The only difference is which port you select. ✨ {: .note } > **In this lesson, you will learn:** @@ -56,7 +56,7 @@ In this lesson, we'll do exactly that using **Bluetooth**. And here's the fun pa > - How the Serial Port Profile (SPP) creates a virtual serial port on your computer—making Bluetooth look exactly like a USB serial connection > - How to pair the ESP32 with your Mac or Windows computer and find the Bluetooth serial port > - How to use Python and [pySerial](https://pyserial.readthedocs.io/) to communicate with the ESP32 over Bluetooth—using the same code patterns from the [serial introduction](../communication/serial-intro.md) -> - How to use [p5.js](https://p5js.org/) with [serial.js](https://github.com/makeabilitylab/p5js/blob/master/_libraries/serial.js) and [Web Serial](../communication/web-serial.md) to visualize Bluetooth sensor data in a web browser +> - How to use [p5.js](https://p5js.org/) with [serial.js](https://github.com/makeabilitylab/js) and [Web Serial](../communication/web-serial.md) to visualize Bluetooth sensor data in a web browser > - Why Bluetooth Classic does **not** work on the ESP32-S3 and does **not** work with iPhones > - When to use Bluetooth Classic *vs.* BLE—and why we'll learn BLE next @@ -111,7 +111,7 @@ Despite sharing the "Bluetooth" name, Classic and BLE are **not compatible with So how does Bluetooth Classic act like a serial cable? Through something called the **Serial Port Profile (SPP)**. SPP emulates a wired RS-232 serial port—exactly the kind of serial communication we've been doing over USB. -When you pair the ESP32 with your computer over Bluetooth Classic, your operating system creates a **virtual serial port**—a COM port on Windows (*e.g.,* `COM8`) or a `/dev/tty.*` device on macOS (*e.g.,* `/dev/tty.ESP32-Bluetooth`). This virtual port behaves *identically* to the USB serial port you've been using all along. Any software that can open a serial port—the Arduino Serial Monitor, a Python script with [pySerial](https://pyserial.readthedocs.io/), a web browser using the [Web Serial API](../communication/web-serial.md), your [serial.js](https://github.com/makeabilitylab/p5js/blob/master/_libraries/serial.js) library—can communicate over Bluetooth without any code changes. Just select the Bluetooth port instead of the USB port. +When you pair the ESP32 with your computer over Bluetooth Classic, your operating system creates a **virtual serial port**—a COM port on Windows (*e.g.,* `COM8`) or a `/dev/tty.*` device on macOS (*e.g.,* `/dev/tty.ESP32-Bluetooth`). This virtual port behaves *identically* to the USB serial port you've been using all along. Any software that can open a serial port—the Arduino Serial Monitor, a Python script with [pySerial](https://pyserial.readthedocs.io/), a web browser using the [Web Serial API](../communication/web-serial.md), your [serial.js](https://github.com/makeabilitylab/js) library—can communicate over Bluetooth without any code changes. Just select the Bluetooth port instead of the USB port. -This is the key insight of this lesson: **Bluetooth Classic SPP is a wireless serial cable.** Everything you learned in the [Communication module](../communication/serial-intro.md)—baud rates, data framing, parsing comma-separated values, serial.js—works unchanged. The only difference is the transport: radio waves instead of copper wire. +This is the key insight of this lesson: **Bluetooth Classic SPP is a wireless serial cable.** Everything you learned in the [Communication module](../communication/serial-intro.md)—data framing, parsing comma-separated values, serial.js—works unchanged. The only difference is the transport: radio waves instead of copper wire. + +
+How SPP works under the hood (click to expand) + +SPP sits on top of several Bluetooth Classic protocol layers. At the bottom, the **L2CAP** (Logical Link Control and Adaptation Protocol) layer provides connection-oriented data channels over the Bluetooth radio. Above that, **RFCOMM** (Radio Frequency Communication) emulates RS-232 serial ports over L2CAP—this is the layer that makes Bluetooth look like a wired serial connection. SPP is a *profile* that defines how RFCOMM should be used for general-purpose serial communication. When your computer pairs with the ESP32, the **SDP** (Service Discovery Protocol) lets the computer discover that the ESP32 offers an SPP service, and the OS creates a virtual COM port backed by an RFCOMM channel. You don't need to know any of this to use SPP—the `BluetoothSerial` library handles it all—but it explains why the abstraction works so seamlessly. + +
## Materials @@ -126,7 +137,7 @@ You'll need the following components. This lesson uses the **original ESP32** ([ | Breadboard | ESP32 | LED | Resistor | Potentiometer | | ---------- |:-----:|:-----:|:-----:|:-----:| -| ![Breadboard]({{ site.baseurl }}/assets/images/Breadboard_Half.png) | ![Huzzah32 ESP32 Feather](assets/images/AdafruitHuzzah32_200h.png) | ![Red LED]({{ site.baseurl }}/assets/images/RedLED_Fritzing.png) | ![Resistors]({{ site.baseurl }}/assets/images/Resistor220_Fritzing.png) | ![Potentiometer]({{ site.baseurl }}/assets/images/Potentiometer_100h.png) | +| ![Half-sized solderless breadboard]({{ site.baseurl }}/assets/images/Breadboard_Half.png) | ![Adafruit Huzzah32 ESP32 Feather board, top view](assets/images/AdafruitHuzzah32_200h.png) | ![Red 5mm LED]({{ site.baseurl }}/assets/images/RedLED_Fritzing.png) | ![220-ohm resistor, striped red-red-brown-gold]({{ site.baseurl }}/assets/images/Resistor220_Fritzing.png) | ![10kΩ rotary potentiometer]({{ site.baseurl }}/assets/images/Potentiometer_100h.png) | | Breadboard | [Huzzah32 ESP32 Feather](https://www.adafruit.com/product/3591) | Red LED | 220Ω Resistor | 10kΩ Potentiometer | You will also need: @@ -141,9 +152,20 @@ You will also need: Let's cut the wire! In this first activity, we'll upload a Bluetooth serial sketch to the ESP32, pair it with your computer, and communicate with it using a short Python script—the same approach you learned in the [serial introduction lesson](../communication/serial-intro.md), just wireless. +### The BluetoothSerial library + +The ESP32 Arduino core includes a built-in library called [`BluetoothSerial`](https://github.com/espressif/arduino-esp32/tree/master/libraries/BluetoothSerial) that handles all the Bluetooth Classic SPP complexity for you. No library installation is needed—just `#include "BluetoothSerial.h"` and you're ready to go. + +The library's API was **intentionally designed to mirror** Arduino's built-in `Serial` class. It provides the same `.begin()`, `.available()`, `.read()`, `.write()`, `.print()`, and `.println()` methods you already know. This means converting a wired serial sketch to Bluetooth is as simple as creating a `BluetoothSerial` object and using it alongside (or instead of) `Serial`. The rest of your code stays identical. + +{: .warning } +> `BluetoothSerial` is **only available on the original ESP32 chip**. If you try to include it on an ESP32-S3 (or C3, S2, *etc.*), the sketch will not compile. The compile-time guards in our sketches below produce a clear error message when this happens. + ### The Arduino code -This sketch creates a bidirectional bridge between the USB serial connection (to your computer via USB) and a Bluetooth serial connection (to your computer via Bluetooth). Anything sent over Bluetooth arrives on USB serial and vice versa. + + +This sketch creates a bidirectional bridge between the USB serial connection (to your computer via USB) and a Bluetooth serial connection (to your computer via Bluetooth). Anything sent over Bluetooth arrives on USB serial and vice versa. The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/HelloBluetooth). ```cpp /** @@ -208,13 +230,11 @@ void loop() { } ``` -**The `#include` and compile-time guards.** `BluetoothSerial.h` is part of the ESP32 Arduino core—no library installation needed. The `#if !defined(...)` blocks produce a clear error if you accidentally build this on an ESP32-S3. - -**`BluetoothSerial SerialBT`** creates a Bluetooth serial object. The API mirrors Arduino's built-in `Serial`: `.begin()`, `.available()`, `.read()`, `.write()`, `.print()`, `.println()`. This is by design—converting wired serial code to Bluetooth is trivially easy. +Notice how similar the `SerialBT` calls are to `Serial`. `SerialBT.begin("ESP32-Bluetooth")` initializes the Bluetooth radio and starts advertising with the name `"ESP32-Bluetooth"`—this is the name you'll see when scanning for Bluetooth devices on your computer. From there, `SerialBT.available()`, `SerialBT.read()`, `SerialBT.write()`, and `SerialBT.println()` all work exactly like their `Serial` counterparts. This mirroring is by design—it makes converting wired serial code to Bluetooth trivially easy. -**`SerialBT.begin("ESP32-Bluetooth")`** initializes the Bluetooth radio and starts advertising with the name `"ESP32-Bluetooth"`. This is the name you'll see when scanning for Bluetooth devices on your computer. +The `#if !defined(...)` compile-time guards at the top produce a clear error if you accidentally build this on an ESP32-S3 or other unsupported chip. -Upload this sketch to your Huzzah32 and open Serial Monitor at 115200 baud. You should see `"Bluetooth device started!"`. +Upload this sketch to your ESP32 and open Serial Monitor at 115200 baud. You should see `"Bluetooth device started!"`. ### Pairing with your computer @@ -233,7 +253,7 @@ ls /dev/tty.*Bluetooth* You should see something like `/dev/tty.ESP32-Bluetooth` or `/dev/tty.ESP32-BluetoothSPP`. This is your Bluetooth serial port—you'll use it in the Python script below. - + {: .note } > **Troubleshooting macOS:** If the Bluetooth serial port doesn't appear, try unpairing and re-pairing the device. On some macOS versions, you may need to open **Terminal** and run `ls /dev/tty.*` before and after pairing to identify the new port. The port name varies by macOS version and Bluetooth stack, but it typically contains the device name. @@ -245,7 +265,7 @@ You should see something like `/dev/tty.ESP32-Bluetooth` or `/dev/tty.ESP32-Blue 3. Select `"ESP32-Bluetooth"` and click **Pair**. 4. Once paired, Windows creates a virtual COM port. To find it, open **Device Manager** (right-click the Start button → Device Manager) and expand **Ports (COM & LPT)**. Look for a `"Standard Serial over Bluetooth link"` entry—note its COM port number (e.g., `COM8`). - + {: .note } > **Windows creates two COM ports** for Bluetooth serial: one for outgoing and one for incoming connections. You typically want the **outgoing** port. If one doesn't work, try the other. You can see which is which in **Control Panel → Devices and Printers → right-click ESP32-Bluetooth → Properties → Services**. @@ -264,7 +284,7 @@ Open `serial_demo.py` and change the port to your Bluetooth serial port: ```python # In serial_demo.py, change this line: -ser = serial.Serial(port='COM13', baudrate=9600, timeout=1) +ser = serial.Serial(port='COM13', baudrate=115200, timeout=1) # To your Bluetooth port: # macOS: @@ -281,6 +301,9 @@ python3 serial_demo.py You should see `"Hello from ESP32!"` messages arriving every 2 seconds. Type a number and press Enter—it will be sent to the ESP32 and forwarded to USB Serial Monitor. You're communicating wirelessly! 🎉 +{: .note } +> **The baud rate parameter is ignored for Bluetooth virtual COM ports** on most operating systems. SPP negotiates its own data rate at the Bluetooth protocol level, so the `baudrate=115200` argument is passed to pySerial for API compatibility but doesn't actually set a baud rate the way it does for USB serial. You can pass any value and it will work—but we use `115200` to match our `Serial.begin(115200)` for consistency. + {: .note } > **This is the point of SPP.** Your [serial_demo.py](https://github.com/makeabilitylab/arduino/blob/master/Python/Serial/serial_demo.py) was written for USB serial. It works over Bluetooth with only a port name change. The pySerial API, the `readline()` calls, the `write()` calls—everything is the same. Your operating system makes Bluetooth look like a wired serial connection. @@ -290,10 +313,11 @@ You should see `"Hello from ESP32!"` messages arriving every 2 seconds. Type a n ### Workbench demo ## Part 2: Streaming sensor data @@ -302,12 +326,16 @@ Now let's stream live sensor data. We'll read a potentiometer and send its value ### The circuit -Connect a 10kΩ potentiometer to the Huzzah32 on pin **A7** (GPIO 32), which is an ADC1 pin. (On the original ESP32, ADC2 pins conflict with both WiFi *and* Bluetooth Classic, so always use ADC1 pins for analog input when using wireless features.) +Connect a 10kΩ potentiometer to the ESP32 on pin **A7** (GPIO 32), which is an ADC1 pin. (On the original ESP32, ADC2 pins conflict with both WiFi *and* Bluetooth Classic, so always use ADC1 pins for analog input when using wireless features.) - + ### The Arduino code + + +The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/BluetoothPotentiometer). + ```cpp /** * BluetoothPotentiometer: reads a potentiometer and streams the value @@ -327,6 +355,10 @@ Connect a 10kΩ potentiometer to the Huzzah32 on pin **A7** (GPIO 32), which is #include "BluetoothSerial.h" +#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) +#error Bluetooth Classic is not enabled. This sketch requires the original ESP32. +#endif + #if !defined(CONFIG_BT_SPP_ENABLED) #error Serial Bluetooth (SPP) is not available. It is only supported on the original ESP32 chip. #endif @@ -379,12 +411,9 @@ python3 serial_draw_circle.py COM8 115200 ``` {: .note } -> **Both scripts expect float values in the range 0.0–1.0.** To use them, modify the Arduino sketch to send normalized values: `SerialBT.println(potVal / 4095.0, 4);` instead of `SerialBT.println(potVal);`. Alternatively, you could modify the Python scripts to accept raw integers—but normalizing on the Arduino side is the cleaner approach and matches the [AnalogOut](https://github.com/makeabilitylab/arduino/tree/master/Serial/AnalogOut) sketch the scripts were designed to work with. - -{: .note } -> **Same scripts, different port.** These Python scripts were written for USB serial. They work over Bluetooth with no code changes—only the port argument differs. This is SPP's core value: your computer's operating system makes the Bluetooth connection look like a regular serial port. +> **Both scripts expect float values in the range 0.0–1.0.** To use them, modify the Arduino sketch to send normalized values: `SerialBT.println(potVal / 4095.0, 4);` instead of `SerialBT.println(potVal);`. Alternatively, you could modify the Python scripts to accept raw integers—but normalizing on the Arduino side is the cleaner approach and matches the [AnalogOut](https://github.com/makeabilitylab/arduino/tree/master/Serial/AnalogOut) sketch the scripts were designed to work with. These Python scripts were written for USB serial. They work over Bluetooth with no code changes—only the port argument differs. This is SPP's core value: your computer's operating system makes the Bluetooth connection look like a regular serial port. -Turn the potentiometer—you'll see the bar chart or circle updating in real time, with data arriving wirelessly. Compare this with the wired experience: same visualization, no cable. +Turn the potentiometer—you'll see the bar chart or circle updating in real time, with data arriving wirelessly. Compare this with the wired experience: same visualization, no cable. You may notice a slight delay compared to USB serial—Bluetooth Classic SPP typically adds 10–30ms of latency per packet, which is usually imperceptible for human-paced interaction but can matter for high-speed control loops. ### Workbench demo @@ -392,14 +421,14 @@ Turn the potentiometer—you'll see the bar chart or circle updating in real tim 1. The potentiometer circuit on the Huzzah32 2. The Python script displaying the ASCII bar chart 3. Turning the potentiometer and watching values change wirelessly + Include captions/transcript --> ## Part 3: p5.js over Bluetooth with serial.js -Here's where things get really satisfying. Because your computer's Bluetooth serial port looks just like a USB serial port, the [Web Serial API](../communication/web-serial.md) works with it—and so does [serial.js](https://github.com/makeabilitylab/js) from the Makeability Lab library. You can build the same [p5.js](https://p5js.org/) interactive sketches from the [Communication module](../communication/p5js-serial.md), but with data arriving wirelessly over Bluetooth. +So far we've sent data in one direction—from ESP32 to computer—and visualized it in Python. Now let's bring it into the browser. Because your computer's Bluetooth serial port looks just like a USB serial port, the [Web Serial API](../communication/web-serial.md) works with it—and so does [serial.js](https://github.com/makeabilitylab/js/blob/main/src/lib/serial/serial.js) from the Makeability Lab library. You can build the same [p5.js](https://p5js.org/) interactive sketches from the [Communication module](../communication/p5js-serial.md), but with data arriving wirelessly over Bluetooth. -{: .note } -> **No changes to serial.js needed!** When you click "Connect" in a Web Serial dialog, Chrome shows *all* available serial ports—including the Bluetooth virtual COM port. Select the Bluetooth port instead of the USB port, and your existing serial.js code works unchanged. This is the entire point of SPP: the operating system abstracts away the wireless transport. +When you click "Connect" in a Web Serial dialog, Chrome shows *all* available serial ports—including the Bluetooth virtual COM port. Select the Bluetooth port instead of the USB port, and your existing serial.js code works unchanged. This is the entire point of SPP: the operating system abstracts away the wireless transport. ### The web page @@ -497,8 +526,8 @@ Make sure the Part 2 sketch (`BluetoothPotentiometer`) is running on your ESP32. 4. **Select the Bluetooth serial port** (not the USB port). On macOS, it will be named something like `tty.ESP32-PotSensor`. On Windows, it will be the Bluetooth COM port you noted earlier. 5. Turn the potentiometer—the circle changes size and color in real time, with data arriving wirelessly! 🎉 - - + + {: .note } > **Compare this with the [p5.js Serial lesson](../communication/p5js-serial.md).** The code is *identical*—same `serial.js` import, same event callbacks, same `connectAndOpen()` call. The only difference is which port you select in the browser dialog. This is SPP's superpower: your existing Web Serial code works wirelessly without any modifications. @@ -509,20 +538,25 @@ Make sure the Part 2 sketch (`BluetoothPotentiometer`) is running on your ESP32. 1. Opening the p5.js sketch in Chrome 2. Selecting the Bluetooth serial port in the dialog 3. Turning the pot and watching the visualization respond wirelessly + Include captions/transcript --> ## Part 4: Bidirectional control -Let's go both directions: stream sensor data *from* the ESP32 *and* send LED control commands *to* the ESP32. We'll extend the p5.js sketch to include a slider that controls LED brightness. +Now let's close the loop: stream sensor data *from* the ESP32 *and* send LED control commands *to* the ESP32. We'll extend the p5.js sketch to include a slider that controls LED brightness. ### The circuit Add an LED circuit: LED on GPIO 21 through a 220Ω resistor to ground. Keep the potentiometer connected from Part 2. - + ### The Arduino code + + +The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/BluetoothLedControl). + ```cpp /** * BluetoothLedControl: bidirectional Bluetooth communication. @@ -546,6 +580,10 @@ Add an LED circuit: LED on GPIO 21 through a 220Ω resistor to ground. Keep the #include "BluetoothSerial.h" +#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) +#error Bluetooth Classic is not enabled. This sketch requires the original ESP32. +#endif + #if !defined(CONFIG_BT_SPP_ENABLED) #error Serial Bluetooth (SPP) is not available. It is only supported on the original ESP32 chip. #endif @@ -588,6 +626,9 @@ void loop() { } ``` +{: .note } +> **`analogWrite()` on the ESP32:** The `analogWrite()` function was added to the ESP32 Arduino core in v3.x as a compatibility wrapper around the LEDC PWM library. Older tutorials (and our [Lesson 3: LED Fade](led-fade.md)) may use the LEDC API directly (`ledcAttach`, `ledcWrite`). Both approaches work—`analogWrite()` is simpler for basic PWM output like this. + ### The p5.js sketch with bidirectional communication Extend the Part 3 sketch with a brightness slider that sends values to the ESP32: @@ -692,6 +733,10 @@ Extend the Part 3 sketch with a brightness slider that sends values to the ESP32 Drag the slider—the LED on your breadboard dims and brightens wirelessly. Meanwhile, the potentiometer data continues streaming to the visualization. This is the same bidirectional communication pattern from [p5.js Serial I/O](../communication/p5js-serial-io.md), but over Bluetooth. +### What happens when the connection drops? + +If you carry your laptop out of Bluetooth range (or the ESP32 loses power), the connection will drop. The `BluetoothSerial` library handles this gracefully on the ESP32 side—it will automatically start advertising again when the connection is lost, so you can reconnect by re-opening the serial port from your computer. On the Python side, `pySerial` will raise a `serial.SerialException`, and in p5.js/serial.js, the `CONNECTION_CLOSED` event will fire. If you need to detect connection state in your Arduino sketch, you can use `SerialBT.connected()` to check whether a device is currently connected, or register a callback with `SerialBT.register_callback()` for connection and disconnection events. + ### Workbench demo ## Part 5: Android phone (optional bonus) @@ -713,7 +759,7 @@ If you have an **Android** phone, you can also communicate with the ESP32 using 3. Open the Serial Bluetooth Terminal app → **Devices** → select your ESP32 → **Connect**. 4. You should see potentiometer data streaming. Type a number (0–255) and tap Send to control the LED. - + {: .note } > **Custom buttons:** The Serial Bluetooth Terminal app lets you configure custom buttons (under **Settings → Buttons**) that send predefined strings. Set up buttons for `0`, `128`, and `255` to quickly toggle between off, half, and full brightness—a simple remote control UI! @@ -749,29 +795,30 @@ If you have an **Android** phone, you can also communicate with the ESP32 using ## Exercises -**Exercise 1: Multi-sensor dashboard.** Modify the Arduino code to send comma-separated values from *two* sensors (potentiometer + photoresistor). Update the p5.js sketch to parse the CSV data and visualize both streams—one as circle size, one as background color. This is the same parsing pattern from [p5.js Serial I/O](../communication/p5js-serial-io.md). +**Exercise 1: Multi-sensor dashboard.** 🟢 Modify the Arduino code to send comma-separated values from *two* sensors (potentiometer + photoresistor). Update the p5.js sketch to parse the CSV data and visualize both streams—one as circle size, one as background color. This is the same parsing pattern from [p5.js Serial I/O](../communication/p5js-serial-io.md). -**Exercise 2: Compare wired vs. wireless.** Open Arduino's Serial Plotter on the USB port while simultaneously running the Python sensor reader on the Bluetooth port. Both show the same data—one wired, one wireless. Can you see any latency difference? Try it with `delay(10)` vs. `delay(100)` in the Arduino sketch. +**Exercise 2: Compare wired vs. wireless.** 🟢 Open Arduino's Serial Plotter on the USB port while simultaneously running the Python sensor reader on the Bluetooth port. Both show the same data—one wired, one wireless. Can you see any latency difference? Try it with `delay(10)` vs. `delay(100)` in the Arduino sketch. -**Exercise 3: Chat between two ESP32s.** Flash one ESP32 with the [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) example (peripheral) and another with [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (central). Build a two-way text chat. +**Exercise 3: Chat between two ESP32s.** 🟡 Flash one ESP32 with the [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) example (peripheral) and another with [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (central). Build a two-way text chat. -**Exercise 4: Range test.** With the sensor streaming sketch running, carry your laptop away from the ESP32. At what distance does the data start dropping out? When does the connection drop entirely? Test with and without walls between you and the ESP32. +**Exercise 4: Range test.** 🟢 With the sensor streaming sketch running, carry your laptop away from the ESP32. At what distance does the data start dropping out? When does the connection drop entirely? Test with and without walls between you and the ESP32. -**Exercise 5: Servo control.** Send angle values (0–180) from a p5.js slider over Bluetooth. Parse the value on the ESP32 and control a servo motor wirelessly. Compare the feel with a directly-wired potentiometer control—can you notice the latency? +**Exercise 5: Servo control.** 🟡 Send angle values (0–180) from a p5.js slider over Bluetooth. Parse the value on the ESP32 and control a servo motor wirelessly. Compare the feel with a directly-wired potentiometer control—can you notice the latency? -**Exercise 6: Replicate a Communication module project.** Pick any project from the [Communication module](../communication/index.md) (the paint app, the shape drawer, *etc.*) and run it over Bluetooth instead of USB. How much code did you have to change? (The answer should be: none—just a different port selection.) +**Exercise 6: Replicate a Communication module project.** 🟢 Pick any project from the [Communication module](../communication/index.md) (the paint app, the shape drawer, *etc.*) and run it over Bluetooth instead of USB. How much code did you have to change? (The answer should be: none—just a different port selection.) ## Summary In this lesson, you cut the wire! Here's what you learned: +- **The `BluetoothSerial` library** ships with the ESP32 Arduino core and intentionally mirrors the `Serial` API. Converting wired serial code to Bluetooth requires minimal changes on both the Arduino and computer side. - **Bluetooth Classic's Serial Port Profile (SPP)** creates a virtual serial port on your computer that behaves identically to a USB serial port. Your Python scripts, p5.js sketches, serial.js library, and Serial Monitor all work unchanged—just select the Bluetooth port instead of the USB port. - **Pairing** the ESP32 with your Mac or Windows computer is a one-time step. macOS creates a `/dev/tty.*` device; Windows creates a COM port. - **pySerial** connects to the Bluetooth serial port with the same API you already know—only the port name changes. - **Web Serial + serial.js** work with Bluetooth serial ports in Chrome. Your existing p5.js sketches from the Communication module can be used wirelessly without code changes. - **Bluetooth Classic SPP only works on the original ESP32** (like the Huzzah32). The ESP32-S3 and other newer variants lack the hardware. - **iOS does not support Bluetooth Classic SPP** for third-party apps. This lesson is computer-based, so phone type doesn't matter—but for phone-based projects, BLE (Lesson 9) is required. -- **Bluetooth Classic has a practical range of 5–10 meters indoors** and supports only one connection at a time. +- **Bluetooth Classic has a practical range of 5–10 meters indoors** and supports only one connection at a time. Expect 10–30ms of added latency compared to USB serial. - **For most new projects—especially on the ESP32-S3—BLE is the better default choice** due to universal device and phone support. But Bluetooth Classic SPP is unbeatable when you want to reuse existing serial code wirelessly. ## Resources @@ -779,7 +826,7 @@ In this lesson, you cut the wire! Here's what you learned: - [BluetoothSerial library source and examples](https://github.com/espressif/arduino-esp32/tree/master/libraries/BluetoothSerial) — the official library in the ESP32 Arduino core - [ESP32 Arduino Bluetooth API docs](https://docs.espressif.com/projects/arduino-esp32/en/latest/api/bluetooth.html) — Espressif's API reference - [pySerial documentation](https://pyserial.readthedocs.io/en/latest/) — the Python serial library used throughout our lessons -- [Makeability Lab JS Library](https://github.com/makeabilitylab/js) — includes serial.js (Web Serial wrapper) and other utilities +- [Makeability Lab JS Library (serial.js)](https://github.com/makeabilitylab/js/blob/main/src/lib/serial/serial.js) — Web Serial wrapper used in our p5.js sketches - [Web Serial lesson](../communication/web-serial.md) — our introduction to Web Serial (the same API that works with Bluetooth COM ports) - [Serial Bluetooth Terminal](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal) — our recommended Android app for Bluetooth serial (free, by Kai Morich) - [Bluetooth SIG: Learn About Bluetooth](https://www.bluetooth.com/learn-about-bluetooth/tech-overview/) — official overview of Bluetooth technology From 0b865f6929e9d8f035849743f15fa3e84e6fadc6 Mon Sep 17 00:00:00 2001 From: Jon Froehlich Date: Sat, 23 May 2026 06:07:25 -0700 Subject: [PATCH 05/19] Refactor Bluetooth lesson formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the HTML
block with a {.note} blockquote for the "In this lesson, you will learn" section to standardize styling. Add a brief intro to the Exercises section, remove emoji status markers from individual exercises, and rename the "## Summary" heading to "## Lesson Summary". No substantive content changes—just formatting and copy cleanup. --- esp32/bluetooth-serial.md | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/esp32/bluetooth-serial.md b/esp32/bluetooth-serial.md index 2d7d04b..44c881c 100644 --- a/esp32/bluetooth-serial.md +++ b/esp32/bluetooth-serial.md @@ -56,19 +56,16 @@ In this lesson, we'll do exactly that using **Bluetooth**. And here's the fun pa Apple does not allow third-party apps to use Bluetooth Classic SPP on iOS, so **iPhones cannot connect to the ESP32 over Bluetooth Classic**. This lesson is entirely computer-based (Mac and Windows), so your phone type doesn't matter for Parts 1–4. If you have an **Android** phone, there's an optional bonus activity at the end. In [Lesson 9: BLE](ble.md), we'll use a protocol that works with *everyone's* phone—including iPhones. -
-In this lesson, you will learn: - -- What Bluetooth is, its origin story, and why there are two very different flavors: Bluetooth Classic and Bluetooth Low Energy (BLE) -- How the Serial Port Profile (SPP) creates a virtual serial port on your computer—making Bluetooth look exactly like a USB serial connection -- How to use the `BluetoothSerial` library and why its API intentionally mirrors Arduino's built-in `Serial` -- How to pair the ESP32 with your Mac or Windows computer and find the Bluetooth serial port -- How to use Python and [pySerial](https://pyserial.readthedocs.io/) to communicate with the ESP32 over Bluetooth—using the same code patterns from the [serial introduction](../communication/serial-intro.md) -- How to use [p5.js](https://p5js.org/) with [serial.js](https://github.com/makeabilitylab/js/blob/main/src/lib/serial/serial.js) and [Web Serial](../communication/web-serial.md) to visualize Bluetooth sensor data in a web browser -- Why Bluetooth Classic does **not** work on the ESP32-S3 and does **not** work with iPhones -- When to use Bluetooth Classic *vs.* BLE—and why we'll learn BLE next - -
+{: .note } +> **In this lesson, you will learn:** +> - What Bluetooth is, its origin story, and why there are two very different flavors: Bluetooth Classic and Bluetooth Low Energy (BLE) +> - How the Serial Port Profile (SPP) creates a virtual serial port on your computer—making Bluetooth look exactly like a USB serial connection +> - How to use the `BluetoothSerial` library and why its API intentionally mirrors Arduino's built-in `Serial` +> - How to pair the ESP32 with your Mac or Windows computer and find the Bluetooth serial port +> - How to use Python and [pySerial](https://pyserial.readthedocs.io/) to communicate with the ESP32 over Bluetooth—using the same code patterns from the [serial introduction](../communication/serial-intro.md) +> - How to use [p5.js](https://p5js.org/) with [serial.js](https://github.com/makeabilitylab/js/blob/main/src/lib/serial/serial.js) and [Web Serial](../communication/web-serial.md) to visualize Bluetooth sensor data in a web browser +> - Why Bluetooth Classic does **not** work on the ESP32-S3 and does **not** work with iPhones +> - When to use Bluetooth Classic *vs.* BLE—and why we'll learn BLE next ## What is Bluetooth? @@ -795,19 +792,21 @@ If you have an **Android** phone, you can also communicate with the ESP32 using ## Exercises -**Exercise 1: Multi-sensor dashboard.** 🟢 Modify the Arduino code to send comma-separated values from *two* sensors (potentiometer + photoresistor). Update the p5.js sketch to parse the CSV data and visualize both streams—one as circle size, one as background color. This is the same parsing pattern from [p5.js Serial I/O](../communication/p5js-serial-io.md). +Want to go further? Here are some challenges to reinforce what you've learned: + +**Exercise 1: Multi-sensor dashboard.** Modify the Arduino code to send comma-separated values from *two* sensors (potentiometer + photoresistor). Update the p5.js sketch to parse the CSV data and visualize both streams—one as circle size, one as background color. This is the same parsing pattern from [p5.js Serial I/O](../communication/p5js-serial-io.md). -**Exercise 2: Compare wired vs. wireless.** 🟢 Open Arduino's Serial Plotter on the USB port while simultaneously running the Python sensor reader on the Bluetooth port. Both show the same data—one wired, one wireless. Can you see any latency difference? Try it with `delay(10)` vs. `delay(100)` in the Arduino sketch. +**Exercise 2: Compare wired vs. wireless.** Open Arduino's Serial Plotter on the USB port while simultaneously running the Python sensor reader on the Bluetooth port. Both show the same data—one wired, one wireless. Can you see any latency difference? Try it with `delay(10)` vs. `delay(100)` in the Arduino sketch. -**Exercise 3: Chat between two ESP32s.** 🟡 Flash one ESP32 with the [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) example (peripheral) and another with [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (central). Build a two-way text chat. +**Exercise 3: Chat between two ESP32s.** Flash one ESP32 with the [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) example (peripheral) and another with [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (central). Build a two-way text chat. -**Exercise 4: Range test.** 🟢 With the sensor streaming sketch running, carry your laptop away from the ESP32. At what distance does the data start dropping out? When does the connection drop entirely? Test with and without walls between you and the ESP32. +**Exercise 4: Range test.** With the sensor streaming sketch running, carry your laptop away from the ESP32. At what distance does the data start dropping out? When does the connection drop entirely? Test with and without walls between you and the ESP32. -**Exercise 5: Servo control.** 🟡 Send angle values (0–180) from a p5.js slider over Bluetooth. Parse the value on the ESP32 and control a servo motor wirelessly. Compare the feel with a directly-wired potentiometer control—can you notice the latency? +**Exercise 5: Servo control.** Send angle values (0–180) from a p5.js slider over Bluetooth. Parse the value on the ESP32 and control a servo motor wirelessly. Compare the feel with a directly-wired potentiometer control—can you notice the latency? -**Exercise 6: Replicate a Communication module project.** 🟢 Pick any project from the [Communication module](../communication/index.md) (the paint app, the shape drawer, *etc.*) and run it over Bluetooth instead of USB. How much code did you have to change? (The answer should be: none—just a different port selection.) +**Exercise 6: Replicate a Communication module project.** Pick any project from the [Communication module](../communication/index.md) (the paint app, the shape drawer, *etc.*) and run it over Bluetooth instead of USB. How much code did you have to change? (The answer should be: none—just a different port selection.) -## Summary +## Lesson Summary In this lesson, you cut the wire! Here's what you learned: From 65c387ea48e33c3bf702d697a07b57fe4ac93eea Mon Sep 17 00:00:00 2001 From: Jon Froehlich Date: Sat, 23 May 2026 06:10:33 -0700 Subject: [PATCH 06/19] Add Serial vs SerialBT API comparison table Add a concise Markdown table to esp32/bluetooth-serial.md comparing Arduino Serial and BluetoothSerial APIs (initialization, read/write, connection checks, and callbacks). Clarify that Serial.begin() uses a baud rate while SerialBT.begin() takes a device name and note Bluetooth-specific connection semantics (connected(), register_callback()). Reword the surrounding paragraph to reference the new table and emphasize the initialization difference. --- esp32/bluetooth-serial.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/esp32/bluetooth-serial.md b/esp32/bluetooth-serial.md index 44c881c..1344e90 100644 --- a/esp32/bluetooth-serial.md +++ b/esp32/bluetooth-serial.md @@ -155,6 +155,22 @@ The ESP32 Arduino core includes a built-in library called [`BluetoothSerial`](ht The library's API was **intentionally designed to mirror** Arduino's built-in `Serial` class. It provides the same `.begin()`, `.available()`, `.read()`, `.write()`, `.print()`, and `.println()` methods you already know. This means converting a wired serial sketch to Bluetooth is as simple as creating a `BluetoothSerial` object and using it alongside (or instead of) `Serial`. The rest of your code stays identical. +| Method | `Serial` (USB) | `SerialBT` (Bluetooth) | Notes | +|---|---|---|---| +| Initialize | `Serial.begin(115200)` | `SerialBT.begin("ESP32-BT")` | Serial takes a baud rate; SerialBT takes a device name (baud rate is negotiated by the Bluetooth stack) | +| Check for data | `Serial.available()` | `SerialBT.available()` | Identical — returns number of bytes waiting | +| Read a byte | `Serial.read()` | `SerialBT.read()` | Identical | +| Read until delimiter | `Serial.readStringUntil('\n')` | `SerialBT.readStringUntil('\n')` | Identical | +| Write bytes | `Serial.write(buf, len)` | `SerialBT.write(buf, len)` | Identical | +| Print text | `Serial.println("hello")` | `SerialBT.println("hello")` | Identical — also `.print()`, `.printf()` | +| Check connection | *(always connected)* | `SerialBT.connected()` | Returns `true` if a device is currently paired and connected | +| Connection events | *(n/a)* | `SerialBT.register_callback(cb)` | Optional callback for connect/disconnect events — no Serial equivalent | + +**Table.** Key API comparison between Arduino's built-in `Serial` and the `BluetoothSerial` library. Every read/write method is identical — only initialization and connection management differ. +{: .fs-1 } + +The key difference is in `.begin()`: `Serial.begin()` takes a baud rate because it configures a physical UART, while `SerialBT.begin()` takes a *device name* because the Bluetooth stack handles data rates internally. The other difference is that Bluetooth connections can come and go — unlike a USB cable, a Bluetooth device might walk out of range — so `BluetoothSerial` adds `connected()` and `register_callback()` for connection state management. We'll use these in [Part 4](#part-4-bidirectional-control) when we discuss what happens when a connection drops. + {: .warning } > `BluetoothSerial` is **only available on the original ESP32 chip**. If you try to include it on an ESP32-S3 (or C3, S2, *etc.*), the sketch will not compile. The compile-time guards in our sketches below produce a clear error message when this happens. @@ -227,7 +243,7 @@ void loop() { } ``` -Notice how similar the `SerialBT` calls are to `Serial`. `SerialBT.begin("ESP32-Bluetooth")` initializes the Bluetooth radio and starts advertising with the name `"ESP32-Bluetooth"`—this is the name you'll see when scanning for Bluetooth devices on your computer. From there, `SerialBT.available()`, `SerialBT.read()`, `SerialBT.write()`, and `SerialBT.println()` all work exactly like their `Serial` counterparts. This mirroring is by design—it makes converting wired serial code to Bluetooth trivially easy. +Notice how the code reads like a standard serial sketch — compare the `SerialBT` calls with the `Serial` calls and you'll see the API mirroring from the [table above](#the-bluetoothserial-library) in action. The one difference is `SerialBT.begin("ESP32-Bluetooth")`: instead of a baud rate, it takes a device name that will appear when you scan for Bluetooth devices on your computer. The `#if !defined(...)` compile-time guards at the top produce a clear error if you accidentally build this on an ESP32-S3 or other unsupported chip. From 6eef4e0c440bdd1eac9590b7e04e326f69dabb08 Mon Sep 17 00:00:00 2001 From: Jon Froehlich Date: Sat, 23 May 2026 06:11:46 -0700 Subject: [PATCH 07/19] Clarify analogWrite() usage on ESP32 Expand the note in esp32/bluetooth-serial.md to better explain why analogWrite() is used: it was added in ESP32 Arduino core v3.x as a convenience wrapper around the LEDC API. Added a link to the core implementation, renamed the lesson reference, and recommend using the LEDC API when you need control over PWM frequency or resolution. --- esp32/bluetooth-serial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp32/bluetooth-serial.md b/esp32/bluetooth-serial.md index 1344e90..922f57f 100644 --- a/esp32/bluetooth-serial.md +++ b/esp32/bluetooth-serial.md @@ -640,7 +640,7 @@ void loop() { ``` {: .note } -> **`analogWrite()` on the ESP32:** The `analogWrite()` function was added to the ESP32 Arduino core in v3.x as a compatibility wrapper around the LEDC PWM library. Older tutorials (and our [Lesson 3: LED Fade](led-fade.md)) may use the LEDC API directly (`ledcAttach`, `ledcWrite`). Both approaches work—`analogWrite()` is simpler for basic PWM output like this. +> **`analogWrite()` on the ESP32:** If you're wondering why we use `analogWrite()` here when [Lesson 3: LED Fading with PWM](led-fade.md) taught the LEDC API (`ledcAttach`, `ledcWrite`)—both work! As we discussed in that lesson, `analogWrite()` was added in ESP32 Arduino core v3.x as a [convenience wrapper around LEDC](https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-ledc.c). For simple PWM output like dimming an LED, `analogWrite()` is the simpler choice. Use the LEDC API directly when you need control over PWM frequency or resolution. ### The p5.js sketch with bidirectional communication From a4cf96cbb27c34c64190fe23dc225311574c2290 Mon Sep 17 00:00:00 2001 From: Jon Froehlich Date: Sat, 23 May 2026 06:21:45 -0700 Subject: [PATCH 08/19] Update ESP32 BLE lesson content and accessibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revise esp32/ble.md to improve clarity, accessibility, and developer guidance. Changes include: add descriptive alt text for images and TODOs to include captions/transcripts for videos/screencasts; clarify iOS and ESP32-S3 support and adjust BLE throughput wording; replace some callout classes (note→important/caution/highlight) for emphasis; add TODOs and links to push Arduino and Python example sketches to the makeabilitylab GitHub repo and a future ble.js reference; add inline note to verify Bluedroid vs NimBLE defaults; expand NeoPixel/Arduino sections and supply repository links for example sketches; add improved nRF Connect and Web Bluetooth guidance and UI screenshots TODOs; add a comparison table for WiFi / Bluetooth Classic / BLE and a BLE security note; enhance Exercises (new challenges and accessibility suggestion for color indicators); assorted wording, formatting, and structural tweaks to make the lesson more actionable for developers and more accessible to learners. --- esp32/ble.md | 113 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 30 deletions(-) diff --git a/esp32/ble.md b/esp32/ble.md index eac4b6c..37a579e 100644 --- a/esp32/ble.md +++ b/esp32/ble.md @@ -23,17 +23,20 @@ nav_order: 9 | Class | Purpose | |---|---| @@ -197,7 +201,7 @@ You'll need the following components. We use **[Adafruit's ESP32-S3 Feather](htt | Breadboard | ESP32 | LED | Resistor | Potentiometer | | ---------- |:-----:|:-----:|:-----:|:-----:| -| ![Breadboard]({{ site.baseurl }}/assets/images/Breadboard_Half.png) | ![ESP32-S3 Feather](assets/images/Adafruit_ESP32-S3-5477-11-vertical-cropped.jpg) | ![Red LED]({{ site.baseurl }}/assets/images/RedLED_Fritzing.png) | ![Resistors]({{ site.baseurl }}/assets/images/Resistor220_Fritzing.png) | ![Potentiometer]({{ site.baseurl }}/assets/images/Potentiometer_100h.png) | +| ![Half-sized solderless breadboard]({{ site.baseurl }}/assets/images/Breadboard_Half.png) | ![Adafruit ESP32-S3 Feather board, top view](assets/images/Adafruit_ESP32-S3-5477-11-vertical-cropped.jpg) | ![Red 5mm LED]({{ site.baseurl }}/assets/images/RedLED_Fritzing.png) | ![220-ohm resistor, striped red-red-brown-gold]({{ site.baseurl }}/assets/images/Resistor220_Fritzing.png) | ![10kΩ rotary potentiometer]({{ site.baseurl }}/assets/images/Potentiometer_100h.png) | | Breadboard | [ESP32-S3 Feather](https://www.adafruit.com/product/5477) | Red LED | 220Ω Resistor | 10kΩ Potentiometer | You will also need: @@ -212,7 +216,11 @@ You will also need: Let's start with the BLE equivalent of "Hello World": create a GATT server on the ESP32 with a single readable characteristic, advertise it, and see it on your phone. -### The code +### The Arduino code + + + +The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/BLEHelloWorld). ```cpp /** @@ -386,11 +394,11 @@ Once you've confirmed the ESP32 is working from your computer, let's try it from 1. On your **iPhone** or **Android phone**, open the **nRF Connect** app ([iOS](https://apps.apple.com/app/nrf-connect-for-mobile/id1054362403) / [Android](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp)). 2. Tap **Scan** (top right). You should see `"ESP32-BLE"` in the list of discovered devices. - + 3. Tap **Connect** next to `"ESP32-BLE"`. The app will connect and display the GATT server structure. You should see your custom service (listed by its UUID) with one characteristic underneath. - + 4. Tap the **read arrow** (↓) next to the characteristic. You should see `"Hello from ESP32!"` appear as the value. You just read data from a BLE peripheral on your phone! @@ -404,6 +412,7 @@ Once you've confirmed the ESP32 is working from your computer, let's try it from 2. Running the Python ble_discover.py script 3. Opening nRF Connect on a phone, scanning, finding ESP32-BLE 4. Connecting, expanding the service tree, reading the value + Include captions/transcript --> ## Part 2: Streaming sensor data with notifications @@ -423,7 +432,11 @@ On the Huzzah32, use pin **A7** (GPIO 32), which is an ADC1 pin. ADC2 pins confl
-### The code +### The Arduino code + + + +The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/BLENotifySensor). ```cpp /** @@ -626,7 +639,7 @@ Now try it from your phone: 4. Tap the **triple-down-arrow** icon (⇊) to **subscribe to notifications**. 5. Turn the potentiometer—you should see the value updating in real time on your phone! - + {: .note } > **Comparing with serial:** In the [Communication module](../communication/serial-intro.md), you call `Serial.println(sensorValue)` and bytes flow continuously through the USB cable at 115,200 bps. With BLE, you update a characteristic value and call `notify()`—the BLE stack delivers it at the negotiated connection interval (typically 7.5ms–4 seconds). BLE trades raw throughput for structured data, power efficiency, and wireless convenience. @@ -639,7 +652,7 @@ By default, BLE's ATT (Attribute Protocol) layer has a Maximum Transmission Unit You can negotiate a larger MTU (up to 512 bytes) if both sides support it, but 20 bytes is the safe baseline that works with all BLE devices. For sensor data, this is rarely a problem—an integer like `"2847"` is only 4 bytes as a string (or 2 bytes as a raw `uint16_t`). But if you try to send long formatted strings, you'll hit this limit. -{: .warning } +{: .caution } > **Keep your BLE payloads compact.** Send numbers as short strings or raw bytes, not verbose text. If you need to send more than 20 bytes, either negotiate a larger MTU (call `BLEDevice::setMTU(185)` in `setup()`; both sides must agree), split the data across multiple characteristics, or send it in chunks. ### Workbench demo @@ -648,17 +661,20 @@ You can negotiate a larger MTU (up to 512 bytes) if both sides support it, but 2 1. The potentiometer circuit on the ESP32-S3 Feather 2. Subscribing to notifications in nRF Connect 3. Turning the pot and watching values update on the phone + Include captions/transcript --> ## Part 3: Controlling the NeoPixel over BLE Now let's go the other direction: send data *from* your phone *to* the ESP32 to control hardware. We'll create a **writable** characteristic that accepts RGB color values and sets the onboard NeoPixel. -The ESP32-S3 Feather has a built-in NeoPixel (WS2812B) RGB LED on `PIN_NEOPIXEL`, powered by `NEOPIXEL_POWER`. We used it in [Lesson 2: Blink](led-blink.md#part-4-blink-the-onboard-neopixel-), so the NeoPixel setup should be familiar. +The ESP32-S3 Feather has a built-in NeoPixel (WS2812B) RGB LED on `PIN_NEOPIXEL`, powered by `NEOPIXEL_POWER`. We used it in [Lesson 2: Blink](led-blink.md) and [Lesson 3: LED Fading](led-fade.md), so the NeoPixel setup should be familiar. + +### The Arduino code -### The code + -We'll extend the Part 2 sketch to add a second characteristic for LED control—so the ESP32 simultaneously streams sensor data *and* accepts LED commands. This is the same bidirectional pattern from [Lesson 8](bluetooth-serial.md#part-3-controlling-an-led-from-your-phone), but over BLE with structured characteristics instead of a serial byte stream. +We'll extend the Part 2 sketch to add a second characteristic for LED control—so the ESP32 simultaneously streams sensor data *and* accepts LED commands. This is the same bidirectional pattern from [Lesson 8](bluetooth-serial.md#part-4-bidirectional-control), but over BLE with structured characteristics instead of a serial byte stream. The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/BLENeoPixelControl). ```cpp /** @@ -811,7 +827,8 @@ void loop() { The key new element is the `LedCallbacks` class. When the central writes to the LED characteristic, `onWrite()` fires automatically. We interpret the first three bytes of the written value as R, G, B and set the NeoPixel color accordingly. -Notice the pattern: we don't poll for incoming data in `loop()` (like we do with `Serial.available()`). Instead, BLE uses a **callback model**—the library calls our `onWrite()` function when data arrives. This is fundamentally different from the serial polling pattern you're used to. +{: .highlight } +> **Callbacks vs. polling:** Notice the pattern: we don't poll for incoming data in `loop()` (like we do with `Serial.available()` or `SerialBT.available()` in [Lesson 8](bluetooth-serial.md)). Instead, BLE uses a **callback model**—the library calls our `onWrite()` function when data arrives. This is fundamentally different from the serial polling pattern you're used to, and it's one of the biggest code-level differences between Bluetooth Classic and BLE. ### Try it out from your computer (Python) @@ -874,7 +891,7 @@ asyncio.run(main()) 5. Tap the **write arrow** (↑). In the write dialog, select **ByteArray** as the type, then enter `FF0000` (red), `00FF00` (green), or `0000FF` (blue). Tap **Send**. 6. Watch the NeoPixel change color! 🌈 - + {: .note } > **nRF Connect write format:** When writing raw bytes in nRF Connect, select "ByteArray" (not "Text") and enter hex values without spaces or `0x` prefixes. `FF0000` = red, `00FF00` = green, `0000FF` = blue, `FF00FF` = magenta, `FFFFFF` = white. Each pair of hex digits is one byte (0–255). @@ -885,6 +902,7 @@ asyncio.run(main()) 1. Connecting from nRF Connect 2. Writing different RGB hex values 3. The onboard NeoPixel changing color with each write + Include captions/transcript --> ## Part 4: Web Bluetooth @@ -1146,7 +1164,7 @@ Let's walk through the JavaScript, step by step: 4. The sensor value should appear and update in real time. 5. Drag the R, G, B sliders—the NeoPixel changes color as you move them! - + {: .note } > **Throttling writes.** If you drag a slider quickly, `sendColor()` fires on every pixel of movement—potentially dozens of times per second. BLE can handle this, but rapid writes may occasionally fail with a "GATT operation already in progress" error. For a more robust implementation, you could debounce the slider input or use `requestAnimationFrame()` to batch writes. For this lesson, occasional errors are harmless. @@ -1158,6 +1176,7 @@ Let's walk through the JavaScript, step by step: 2. Potentiometer values appearing in real time 3. Sliding the RGB sliders and the NeoPixel changing color wirelessly 4. The "magic moment" of browser → BLE → physical hardware + Include captions/transcript --> ## Part 5: Nordic UART Service (NUS) @@ -1176,6 +1195,9 @@ The naming is from the **peripheral's perspective**: RX = data coming *in* to th Here's a simple NUS example: + + + ```cpp /** * BLEUartService: implements the Nordic UART Service (NUS) for @@ -1274,16 +1296,45 @@ void loop() { } ``` -To test: connect with nRF Connect, navigate to the NUS service, subscribe to TX notifications, and write text to the RX characteristic. Or, in newer versions of nRF Connect, use the built-in **UART** mode which provides a chat-like interface that works with any device implementing NUS. +### Try it out + +1. Upload the sketch and open Serial Monitor at 115200 baud. +2. Open **nRF Connect** on your phone. Scan and connect to `"ESP32-BLE-UART"`. +3. In newer versions of nRF Connect, tap the **UART** icon (or navigate to the NUS service manually). You should see a chat-like interface. +4. Type a message in nRF Connect and tap **Send**. It should appear in Serial Monitor. +5. Type a message in Serial Monitor and press Enter. It should appear in nRF Connect's UART view. + +If your version of nRF Connect doesn't have the UART shortcut, you can do it manually: expand the NUS service, subscribe to notifications on the TX characteristic (`6E400003...`), and write text to the RX characteristic (`6E400002...`). {: .note } > **NUS is "serial over BLE."** It gives you the familiar send/receive text experience of Bluetooth Classic's `SerialBT`, but running over BLE—so it works on the ESP32-S3, works with iPhones, and coexists with custom GATT services. Under the hood, it's still GATT: the NUS service has two characteristics, and data flows as writes and notifications. Understanding the GATT layer (Parts 1–4) will help you debug NUS when things go wrong. +If you want a `Serial`-like API over BLE without manually managing NUS characteristics, check out the [NuS-NimBLE-Serial](https://www.arduino.cc/reference/en/libraries/nus-nimble-serial/) library, which wraps NUS in familiar `.read()` and `.write()` methods. It requires the [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino) stack. + +## Comparing ESP32 wireless options + +Now that you've seen WiFi ([Lesson 7](iot.md)), Bluetooth Classic ([Lesson 8](bluetooth-serial.md)), and BLE (this lesson), here's how the three compare at a glance: + +| | WiFi (L7) | Bluetooth Classic (L8) | BLE (this lesson) | +|---|---|---|---| +| Best for | Cloud/internet connectivity | Wireless serial replacement | Low-power sensors, phones, web apps | +| Range | Depends on router | ~10m | ~10m | +| Power | High | Medium | Very low | +| iPhone support | ✅ (via web) | ❌ | ✅ | +| ESP32-S3 | ✅ | ❌ | ✅ | +| Complexity | Medium (needs WiFi credentials) | Very simple | Higher (GATT model) | +| Browser API | Fetch / WebSocket | Web Serial (via virtual COM port) | Web Bluetooth | + +**Table.** Comparison of the three wireless technologies available on the ESP32. For most new projects, BLE is the default choice unless you need internet connectivity (WiFi) or a drop-in serial replacement (Bluetooth Classic). +{: .fs-1 } + {: .note } -> **Library alternative:** If you want a `Serial`-like API over BLE without manually managing NUS characteristics, check out the [NuS-NimBLE-Serial](https://www.arduino.cc/reference/en/libraries/nus-nimble-serial/) library, which wraps NUS in familiar `.read()` and `.write()` methods. It requires the [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino) stack. +> **A note on BLE security.** In this lesson, we use BLE's "Just Works" pairing mode, which requires no PIN and provides no protection against eavesdropping. This is fine for learning and for projects where the data isn't sensitive (potentiometer readings, LED colors). For production IoT devices that handle sensitive data—door locks, health monitors, payment systems—you'd want to explore passkey pairing or out-of-band (OOB) authentication. See the [Bluetooth SIG security overview](https://www.bluetooth.com/learn-about-bluetooth/key-attributes/bluetooth-security/) for more. ## Exercises +Want to go further? Here are some challenges to reinforce what you've learned: + **Exercise 1: NeoPixel strip control.** Modify Part 3 to control the 5-LED NeoPixel stick from your kit instead of (or in addition to) the onboard NeoPixel. You could either send 15 bytes (5 × RGB) in a single write to set all LEDs at once, or add a fourth byte for the LED index (0–4) and set one LED per write. Build a Web Bluetooth page with five color pickers—one per LED. **Exercise 2: BLE range test.** With the notification sketch from Part 2 running, walk away from your ESP32 with nRF Connect open. At what distance do notifications stop arriving? How do walls and obstacles affect range? If you did the Bluetooth Classic range test in [Lesson 8, Exercise 4](bluetooth-serial.md#exercises), compare the two. Are they similar? @@ -1292,13 +1343,15 @@ To test: connect with nRF Connect, navigate to the NUS service, subscribe to TX **Exercise 4: BLE servo control.** Create a writable characteristic that accepts a single byte (0–180) representing a servo angle. When the central writes a value, the ESP32 moves a servo motor to that position (using the [Servo library](../advancedio/servo.md)). Build a Web Bluetooth page with a slider to control the servo wirelessly. -**Exercise 5: Connection status NeoPixel.** Use the onboard NeoPixel to display BLE connection status: **blue** while advertising (waiting for a connection), **green** when a central is connected, and **red** briefly on disconnection before returning to blue. This is a common pattern in commercial BLE products. Implement it using the `onConnect()` and `onDisconnect()` callbacks. +**Exercise 5: Connection status NeoPixel.** Use the onboard NeoPixel to display BLE connection status: **blue** while advertising (waiting for a connection), **green** when a central is connected, and **red** briefly on disconnection before returning to blue. This is a common pattern in commercial BLE products. Implement it using the `onConnect()` and `onDisconnect()` callbacks. (Accessibility note: for colorblind users, consider also adding a blink pattern—*e.g.,* slow pulse for advertising, solid for connected, fast blink for disconnection.) **Exercise 6: Power comparison (research).** The ESP32-S3 Feather has a LiPoly battery connector and a MAX17048 battery monitor chip. Connect the 350mAh LiPoly battery from your kit and run a BLE sketch. How long does the battery last? Compare with a WiFi sketch (from the [IoT lesson](iot.md)). Which protocol consumes more power? For bonus points, use `BLEDevice::setPower()` to experiment with different transmit power levels and measure the effect on both range and battery life. **Exercise 7: Web Bluetooth + p5.js.** Port the Web Bluetooth sensor display from Part 4 into [p5.js](https://p5js.org/). Use `createCanvas()` to draw a real-time visualization (bar chart, oscilloscope, *etc.*) of the incoming BLE sensor data. If you completed the [p5.js Serial lessons](../communication/p5js-serial.md), compare the code structure—how much carries over? (Hint: also check out [p5.ble.js](https://itpnyu.github.io/p5.ble.js/), a p5.js library specifically for Web Bluetooth.) -## Summary +**Exercise 8: Port a Bluetooth Classic project to BLE.** If you completed any project from [Lesson 8](bluetooth-serial.md) (the potentiometer visualizer, the bidirectional LED control, *etc.*), rebuild it using BLE. Replace `BluetoothSerial` with the BLE library, design your GATT service and characteristics, and update the computer-side code to use `bleak` instead of `pySerial`. What changed? What stayed the same? This is a great exercise in understanding the conceptual differences between the two Bluetooth flavors. + +## Lesson Summary In this lesson, you learned Bluetooth Low Energy—a fundamentally different approach to wireless communication than the serial-style Bluetooth Classic from [Lesson 8](bluetooth-serial.md). Here's what you covered: From ae6c1d82ed3f91ad03ad5de0c8a2f02f9e18a8f1 Mon Sep 17 00:00:00 2001 From: Jon Froehlich Date: Sat, 23 May 2026 06:54:39 -0700 Subject: [PATCH 09/19] docs(esp32/ble): add comparisons and clarifications Enhance the ESP32 BLE lesson with clearer guidance and supplemental references. Added a new comparison table for WiFi, Bluetooth Classic, and BLE (including ESP32/ESP32-S3 support notes) and removed a duplicated table elsewhere in the file. Linked to the Arduino-ESP32 BLE library source and API docs, and added a header table describing common BLE headers. Clarified the server/callback workflow (including onDisconnect advertising restart), expanded explanations for discovery/debugging with bleak, notifications (BLE2902/PROPERTY_NOTIFY and MTU guidance), writable characteristics and callback model, and Web Bluetooth usage. Minor copy edits (note vs caution) and other wording improvements for discoverability and tooling. --- esp32/ble.md | 77 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/esp32/ble.md b/esp32/ble.md index 37a579e..fa90351 100644 --- a/esp32/ble.md +++ b/esp32/ble.md @@ -170,25 +170,53 @@ You can browse the full list in the [Bluetooth SIG Assigned Numbers](https://www {: .note } > **Don't be intimidated by UUIDs.** A 128-bit UUID is just a unique label—think of it like a URL or a barcode. You generate one, paste it into your code, and use the same one in your phone app or web page so both sides agree on which characteristic is which. You don't need to memorize them or understand their internal structure. +## Choosing between WiFi, Bluetooth Classic, and BLE + +Now that you understand the BLE concepts — peripherals, centrals, GATT, services, characteristics, and UUIDs — you have enough context to see where BLE fits alongside the other wireless technologies you've learned. If you've completed [Lesson 7 (WiFi/IoT)](iot.md) and [Lesson 8 (Bluetooth Classic)](bluetooth-serial.md), here's how all three compare: + +| | WiFi (L7) | Bluetooth Classic (L8) | BLE (this lesson) | +|---|---|---|---| +| Best for | Cloud/internet connectivity | Wireless serial replacement | Low-power sensors, phones, web apps | +| Range | Depends on router | ~10m | ~10m | +| Power | High | Medium | Very low | +| iPhone support | ✅ (via web) | ❌ | ✅ | +| ESP32 (original) | ✅ | ✅ | ✅ | +| ESP32-S3 | ✅ | ❌ | ✅ | +| Complexity | Medium (needs WiFi credentials) | Very simple | Higher (GATT model) | +| Browser API | Fetch / WebSocket | Web Serial (via virtual COM port) | Web Bluetooth | + +**Table.** Comparison of the three wireless technologies available on the ESP32. For most new projects, BLE is the default choice unless you need internet connectivity (WiFi) or a drop-in serial replacement (Bluetooth Classic). The original ESP32 supports all three; the ESP32-S3 supports WiFi and BLE but not Bluetooth Classic. +{: .fs-1 } + ## The ESP32 BLE library -The ESP32 Arduino core includes a built-in BLE library. No installation is needed—just `#include` the headers and go. The key classes you'll use are: +The ESP32 Arduino core includes a built-in BLE library ([source on GitHub](https://github.com/espressif/arduino-esp32/tree/master/libraries/BLE), [API docs](https://docs.espressif.com/projects/arduino-esp32/en/latest/api/ble.html)). No installation is needed—just `#include` the headers and go. +The library is split across several header files, each providing a specific piece of the BLE puzzle: + +| Header | What it provides | +|---|---| +| `BLEDevice.h` | Top-level entry point. Initializes the BLE stack (call `BLEDevice::init()` once in `setup()`). | +| `BLEServer.h` | Creates a GATT server on the ESP32 and manages connections. | +| `BLEUtils.h` | Utility functions used internally by the library. Include it alongside the others. | +| `BLE2902.h` | The Client Characteristic Configuration Descriptor (CCCD). Required for any characteristic that supports **notifications** — without it, centrals cannot subscribe. You only need this header when using `PROPERTY_NOTIFY`. | + +You'll typically `#include` all four at the top of your sketch. The key *classes* you'll work with are: + | Class | Purpose | |---|---| | `BLEDevice` | Initializes the BLE stack (call once in `setup()`) | | `BLEServer` | Creates a GATT server on the ESP32 | | `BLEService` | A service within the server (identified by UUID) | | `BLECharacteristic` | A data point within a service (identified by UUID, has value + properties) | -| `BLE2902` | A descriptor that enables/disables notifications (required for Notify) | | `BLEAdvertising` | Controls what the ESP32 broadcasts during advertising | -| `BLEServerCallbacks` | Event handler for connection/disconnection events | -| `BLECharacteristicCallbacks` | Event handler for read/write events on a characteristic | +| `BLEServerCallbacks` | Callback class for connection/disconnection events | +| `BLECharacteristicCallbacks` | Callback class for read/write events on a characteristic | Don't worry about memorizing these—we'll introduce each one as we use it in the activities below. @@ -214,7 +242,7 @@ You will also need: ## Part 1: Advertising and discovery -Let's start with the BLE equivalent of "Hello World": create a GATT server on the ESP32 with a single readable characteristic, advertise it, and see it on your phone. +Let's start with the BLE equivalent of "Hello World": create a GATT server on the ESP32 with a single readable characteristic, advertise it, and discover it from both your computer and your phone. By the end of this part, you'll understand the full BLE setup lifecycle — initializing the stack, creating the GATT hierarchy, advertising, and handling connections — and you'll have read your first BLE characteristic from nRF Connect. ### The Arduino code @@ -314,17 +342,19 @@ Let's walk through the key steps: **Step 1: `BLEDevice::init("ESP32-BLE")`** initializes the Bluetooth stack and sets the device name that appears during scanning. This is analogous to `SerialBT.begin("ESP32-Bluetooth")` from [Lesson 8](bluetooth-serial.md), but the similarity ends here—BLE has no `println()` or `read()` on the device object. -**Steps 2–4: Creating the GATT hierarchy.** We create a **server** (the ESP32 as a whole), a **service** within it (identified by `SERVICE_UUID`), and a **characteristic** within that service (identified by `CHARACTERISTIC_UUID`). The characteristic has `PROPERTY_READ`, meaning a central can request its value. This is the GATT structure we discussed earlier, built in code. +**Step 2: Creating the server and registering callbacks.** `BLEDevice::createServer()` creates a GATT server, and `pServer->setCallbacks(new MyServerCallbacks())` registers a **callback** — a function (or in this case, a class with methods) that the BLE library will call automatically when specific events happen, like a central connecting or disconnecting. If you've used event listeners in JavaScript or interrupt handlers on Arduino, callbacks are the same idea: instead of polling for events in `loop()`, you tell the library "call *this* function when *that* happens." We define `MyServerCallbacks` above `setup()` with two methods: `onConnect()` and `onDisconnect()`. + +**Steps 3–4: Creating the GATT hierarchy.** We create a **service** within the server (identified by `SERVICE_UUID`) and a **characteristic** within that service (identified by `CHARACTERISTIC_UUID`). The characteristic has `PROPERTY_READ`, meaning a central can request its value. This is the GATT structure we discussed earlier, built in code. **Step 5: Setting the value.** `pCharacteristic->setValue("Hello from ESP32!")` stores a string in the characteristic. When a central reads this characteristic, it receives this string. -**Step 6–7: Starting the service and advertising.** `pService->start()` activates the service so connected centrals can see it. `pAdvertising->start()` begins broadcasting advertisement packets. We include our service UUID in the advertisement (`addServiceUUID`) so centrals filtering by service can find us. +**Steps 6–7: Starting the service and advertising.** `pService->start()` activates the service so connected centrals can see it. `pAdvertising->start()` begins broadcasting advertisement packets. We include our service UUID in the advertisement (`addServiceUUID`) so centrals filtering by service can find us. -**The `onDisconnect` callback.** This is a critical gotcha: when a central disconnects, the ESP32 **stops advertising by default**. If you don't restart advertising in `onDisconnect()`, the ESP32 goes silent and no new centrals can find it. Always restart advertising after disconnection. +**The `onDisconnect` callback revisited.** Look back at the `MyServerCallbacks` class we registered in Step 2. The `onDisconnect()` method contains a critical line: `pServer->getAdvertising()->start()`. This is because when a central disconnects, the ESP32 **stops advertising by default**. If you don't restart advertising in `onDisconnect()`, the ESP32 goes silent and no new centrals can find it. Always restart advertising after disconnection. ### Discovering the ESP32 from your computer (Python) -Let's start on the computer, where debugging is easiest. We'll use [bleak](https://pypi.org/project/bleak/)—a cross-platform BLE client library for Python. If you haven't installed it yet: +Let's start on the computer, where debugging is easiest. We'll use [bleak](https://pypi.org/project/bleak/) — a cross-platform BLE client library for Python that works on macOS, Windows, and Linux. Unlike [pySerial](https://pyserial.readthedocs.io/) (which we used for Bluetooth Classic in [Lesson 8](bluetooth-serial.md)), bleak speaks BLE natively — it connects directly to BLE peripherals, discovers their GATT services, and reads/writes characteristics using Python's `asyncio` for non-blocking I/O. If you haven't installed it yet: ``` pip3 install bleak @@ -417,7 +447,7 @@ Once you've confirmed the ESP32 is working from your computer, let's try it from ## Part 2: Streaming sensor data with notifications -Reading a static string is a good start, but the real power of BLE comes with **notifications**—the peripheral automatically pushes updates to the central whenever a value changes. Let's wire up a potentiometer and stream its value to your phone in real time. +Reading a static string is a good start, but the real power of BLE comes with **notifications** — the peripheral automatically pushes updates to the central whenever a value changes. In this part, you'll wire up a potentiometer, learn how to add `PROPERTY_NOTIFY` and the `BLE2902` descriptor, and stream live sensor data to both nRF Connect and a Python script. This is the BLE equivalent of `Serial.println(sensorValue)` — but structured and wireless. ### The circuit @@ -652,7 +682,7 @@ By default, BLE's ATT (Attribute Protocol) layer has a Maximum Transmission Unit You can negotiate a larger MTU (up to 512 bytes) if both sides support it, but 20 bytes is the safe baseline that works with all BLE devices. For sensor data, this is rarely a problem—an integer like `"2847"` is only 4 bytes as a string (or 2 bytes as a raw `uint16_t`). But if you try to send long formatted strings, you'll hit this limit. -{: .caution } +{: .note } > **Keep your BLE payloads compact.** Send numbers as short strings or raw bytes, not verbose text. If you need to send more than 20 bytes, either negotiate a larger MTU (call `BLEDevice::setMTU(185)` in `setup()`; both sides must agree), split the data across multiple characteristics, or send it in chunks. ### Workbench demo @@ -666,7 +696,7 @@ You can negotiate a larger MTU (up to 512 bytes) if both sides support it, but 2 ## Part 3: Controlling the NeoPixel over BLE -Now let's go the other direction: send data *from* your phone *to* the ESP32 to control hardware. We'll create a **writable** characteristic that accepts RGB color values and sets the onboard NeoPixel. +So far, data has flowed in one direction: from the ESP32 to the central. Now let's go the other direction — send data *from* your phone *to* the ESP32 to control hardware. In this part, you'll create a **writable** characteristic that accepts RGB color values and sets the onboard NeoPixel. You'll also learn the BLE **callback model** for handling incoming writes, which is fundamentally different from the `Serial.available()` polling pattern. The ESP32-S3 Feather has a built-in NeoPixel (WS2812B) RGB LED on `PIN_NEOPIXEL`, powered by `NEOPIXEL_POWER`. We used it in [Lesson 2: Blink](led-blink.md) and [Lesson 3: LED Fading](led-fade.md), so the NeoPixel setup should be familiar. @@ -907,9 +937,7 @@ asyncio.run(main()) ## Part 4: Web Bluetooth -So far we've used nRF Connect as our BLE central—it's great for debugging, but it doesn't give us a custom UI. What if you could control the NeoPixel from a **web page** with sliders and a color picker? What if you could plot sensor data in a live chart—all in the browser, all wireless? - -That's exactly what the [Web Bluetooth API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API) provides. If you completed the [Web Serial lessons](../communication/web-serial.md), this will feel familiar—it's the same idea (browser talks to hardware) with a different transport (BLE instead of USB serial). +So far we've used nRF Connect as our BLE central — it's great for debugging, but it doesn't give us a custom UI. What if you could control the NeoPixel from a **web page** with sliders and a color picker? What if you could plot sensor data in a live chart — all in the browser, all wireless? In this part, you'll build a single-page HTML/JavaScript app using the [Web Bluetooth API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API) that connects to your ESP32, subscribes to sensor notifications, and writes RGB values to the NeoPixel — paralleling the [Web Serial](../communication/web-serial.md) approach from the Communication module but over BLE. ### Web Serial vs. Web Bluetooth @@ -1181,7 +1209,7 @@ Let's walk through the JavaScript, step by step: ## Part 5: Nordic UART Service (NUS) -Throughout this lesson, we've worked directly with custom GATT services and characteristics—the fundamental BLE building blocks. But what if you just want to send text back and forth, like the serial bridge from [Lesson 8](bluetooth-serial.md)? This is where the **Nordic UART Service (NUS)** comes in. +Throughout this lesson, we've worked directly with custom GATT services and characteristics — the fundamental BLE building blocks. But what if you just want to send text back and forth, like the serial bridge from [Lesson 8](bluetooth-serial.md)? In this part, you'll learn the **Nordic UART Service (NUS)** — a widely adopted convention that emulates serial communication over BLE using two characteristics. NUS bridges the gap between BLE's structured model and the simplicity of serial, and it's supported by most BLE terminal apps out of the box. NUS is a widely adopted convention (created by Nordic Semiconductor) that uses two BLE characteristics to emulate serial communication: @@ -1311,23 +1339,6 @@ If your version of nRF Connect doesn't have the UART shortcut, you can do it man If you want a `Serial`-like API over BLE without manually managing NUS characteristics, check out the [NuS-NimBLE-Serial](https://www.arduino.cc/reference/en/libraries/nus-nimble-serial/) library, which wraps NUS in familiar `.read()` and `.write()` methods. It requires the [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino) stack. -## Comparing ESP32 wireless options - -Now that you've seen WiFi ([Lesson 7](iot.md)), Bluetooth Classic ([Lesson 8](bluetooth-serial.md)), and BLE (this lesson), here's how the three compare at a glance: - -| | WiFi (L7) | Bluetooth Classic (L8) | BLE (this lesson) | -|---|---|---|---| -| Best for | Cloud/internet connectivity | Wireless serial replacement | Low-power sensors, phones, web apps | -| Range | Depends on router | ~10m | ~10m | -| Power | High | Medium | Very low | -| iPhone support | ✅ (via web) | ❌ | ✅ | -| ESP32-S3 | ✅ | ❌ | ✅ | -| Complexity | Medium (needs WiFi credentials) | Very simple | Higher (GATT model) | -| Browser API | Fetch / WebSocket | Web Serial (via virtual COM port) | Web Bluetooth | - -**Table.** Comparison of the three wireless technologies available on the ESP32. For most new projects, BLE is the default choice unless you need internet connectivity (WiFi) or a drop-in serial replacement (Bluetooth Classic). -{: .fs-1 } - {: .note } > **A note on BLE security.** In this lesson, we use BLE's "Just Works" pairing mode, which requires no PIN and provides no protection against eavesdropping. This is fine for learning and for projects where the data isn't sensitive (potentiometer readings, LED colors). For production IoT devices that handle sensitive data—door locks, health monitors, payment systems—you'd want to explore passkey pairing or out-of-band (OOB) authentication. See the [Bluetooth SIG security overview](https://www.bluetooth.com/learn-about-bluetooth/key-attributes/bluetooth-security/) for more. From cd3f5e856ad403058f0b89e4ed131b53c39f6a3b Mon Sep 17 00:00:00 2001 From: Jon Froehlich Date: Sat, 23 May 2026 07:07:18 -0700 Subject: [PATCH 10/19] I split up ble.md into two lessons I split up ble.md into two lessons as ble.md was getting too long --- esp32/ble-bidirectional.md | 752 +++++++++++++++++++++++++++++++++ esp32/{ble.md => ble-intro.md} | 727 ++----------------------------- esp32/bluetooth-serial.md | 8 +- esp32/esp32-ide.md | 2 +- esp32/index.md | 29 +- 5 files changed, 802 insertions(+), 716 deletions(-) create mode 100644 esp32/ble-bidirectional.md rename esp32/{ble.md => ble-intro.md} (54%) diff --git a/esp32/ble-bidirectional.md b/esp32/ble-bidirectional.md new file mode 100644 index 0000000..edb0562 --- /dev/null +++ b/esp32/ble-bidirectional.md @@ -0,0 +1,752 @@ +--- +layout: default +title: L10: Bidirectional BLE +parent: ESP32 +has_toc: true # (on by default) +usemathjax: false +comments: true +usetocbot: true +nav_order: 10 +--- +# {{ page.title | replace_first:'L','Lesson ' }} +{: .no_toc } + +## Table of Contents +{: .no_toc .text-delta } + +1. TOC +{:toc} +--- + +{: .warning } +> This lesson is in draft form. There are missing circuit diagrams, images, videos, and other content. + + + + + +In the [last lesson](ble-intro.md), you learned the fundamentals of BLE: the peripheral/central model, the GATT data hierarchy, and how to stream sensor data from the ESP32 to your phone and computer using notifications. Data flowed in one direction — *from* the ESP32 *to* the central. + +In this lesson, we'll close the loop. You'll learn how to send data in the *other* direction — from a phone or web browser *to* the ESP32 — to control hardware wirelessly. Along the way, you'll encounter BLE's **callback model** for handling incoming writes, build a **Web Bluetooth** interface that runs entirely in the browser, and learn about the **Nordic UART Service (NUS)** for serial-like text communication over BLE. + +{: .note } +> **In this lesson, you will learn:** +> - How to create a **writable** BLE characteristic and handle incoming data with callbacks +> - The difference between BLE's callback model and the `Serial.available()` polling pattern +> - How to combine readable, writable, and notify characteristics in a single service for bidirectional communication +> - How to build a **Web Bluetooth** web page that connects to the ESP32 from a browser — paralleling the [Web Serial](../communication/web-serial.md) approach but wireless +> - The **Nordic UART Service (NUS)** — a widely adopted convention for serial-like text communication over BLE + +{: .note } +> **Prerequisites:** This lesson builds directly on [Lesson 9: Introduction to BLE](ble-intro.md). You should be comfortable with BLE concepts (peripherals, centrals, GATT, services, characteristics, UUIDs, notifications) and have successfully completed Parts 1 and 2 from that lesson. + +## Part 1: Controlling the NeoPixel over BLE + +So far, data has flowed in one direction: from the ESP32 to the central. Now let's go the other direction — send data *from* your phone *to* the ESP32 to control hardware. In this part, you'll create a **writable** characteristic that accepts RGB color values and sets the onboard NeoPixel. You'll also learn the BLE **callback model** for handling incoming writes, which is fundamentally different from the `Serial.available()` polling pattern. + +The ESP32-S3 Feather has a built-in NeoPixel (WS2812B) RGB LED on `PIN_NEOPIXEL`, powered by `NEOPIXEL_POWER`. We used it in [Lesson 2: Blink](led-blink.md) and [Lesson 3: LED Fading](led-fade.md), so the NeoPixel setup should be familiar. + +### The Arduino code + + + +We'll extend the [Lesson 9](ble-intro.md) sensor streaming sketch to add a second characteristic for LED control—so the ESP32 simultaneously streams sensor data *and* accepts LED commands. This is the same bidirectional pattern from [Lesson 8](bluetooth-serial.md#part-4-bidirectional-control), but over BLE with structured characteristics instead of a serial byte stream. The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/BLENeoPixelControl). + +```cpp +/** + * BLENeoPixelControl: bidirectional BLE communication. + * Streams potentiometer data via notifications (peripheral → central) + * AND accepts RGB color commands via a writable characteristic + * (central → peripheral) to control the onboard NeoPixel. + * + * Circuit: + * - 10kΩ potentiometer on A5 (GPIO 8, ADC1) + * - Onboard NeoPixel (no external wiring needed) + * + * Works on: ESP32-S3 Feather (for the onboard NeoPixel). + * On the Huzzah32, substitute an external NeoPixel or LED. + * + * See: https://makeabilitylab.github.io/physcomp/esp32/ble + * + * By Jon E. Froehlich + * @jonfroehlich + * http://makeabilitylab.io + */ + +#include +#include +#include +#include +#include + +// Custom UUIDs +#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" +#define SENSOR_CHAR_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" +#define LED_CHAR_UUID "a3c87500-8ed3-4bdf-8a39-a01bebede295" + +const int POT_INPUT_PIN = A5; + +// NeoPixel setup — one pixel on the onboard NeoPixel pin +Adafruit_NeoPixel _pixel(1, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800); + +BLEServer* _pServer = NULL; +BLECharacteristic* _pSensorCharacteristic = NULL; +BLECharacteristic* _pLedCharacteristic = NULL; +bool _deviceConnected = false; + +unsigned long _lastSensorReadMs = 0; +const unsigned long SENSOR_READ_INTERVAL_MS = 100; + +class MyServerCallbacks : public BLEServerCallbacks { + void onConnect(BLEServer* pServer) { + _deviceConnected = true; + Serial.println("Central connected!"); + } + + void onDisconnect(BLEServer* pServer) { + _deviceConnected = false; + Serial.println("Central disconnected. Restarting advertising..."); + pServer->getAdvertising()->start(); + } +}; + +// Callback for when the central writes to the LED characteristic +class LedCallbacks : public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic* pCharacteristic) { + String value = pCharacteristic->getValue(); + + if (value.length() >= 3) { + // Interpret the first 3 bytes as R, G, B + uint8_t r = (uint8_t)value[0]; + uint8_t g = (uint8_t)value[1]; + uint8_t b = (uint8_t)value[2]; + + Serial.print("Received RGB: "); + Serial.print(r); Serial.print(", "); + Serial.print(g); Serial.print(", "); + Serial.println(b); + + _pixel.setPixelColor(0, _pixel.Color(r, g, b)); + _pixel.show(); + } else { + Serial.print("Received write with "); + Serial.print(value.length()); + Serial.println(" bytes (expected 3 for RGB)."); + } + } +}; + +void setup() { + Serial.begin(115200); + Serial.println("Starting BLE NeoPixel Control..."); + + // Initialize NeoPixel + #if defined(NEOPIXEL_POWER) + pinMode(NEOPIXEL_POWER, OUTPUT); + digitalWrite(NEOPIXEL_POWER, HIGH); + #endif + _pixel.begin(); + _pixel.setBrightness(30); // keep it dim to avoid blinding you + _pixel.show(); // turn off (all zeros) + + // Initialize BLE + BLEDevice::init("ESP32-BLE-NeoPixel"); + _pServer = BLEDevice::createServer(); + _pServer->setCallbacks(new MyServerCallbacks()); + + BLEService* pService = _pServer->createService(SERVICE_UUID); + + // Sensor characteristic (Read + Notify) — streams potentiometer data + _pSensorCharacteristic = pService->createCharacteristic( + SENSOR_CHAR_UUID, + BLECharacteristic::PROPERTY_READ | + BLECharacteristic::PROPERTY_NOTIFY + ); + _pSensorCharacteristic->addDescriptor(new BLE2902()); + + // LED characteristic (Read + Write) — receives RGB color commands + _pLedCharacteristic = pService->createCharacteristic( + LED_CHAR_UUID, + BLECharacteristic::PROPERTY_READ | + BLECharacteristic::PROPERTY_WRITE + ); + _pLedCharacteristic->setCallbacks(new LedCallbacks()); + + // Start service and advertising + pService->start(); + BLEAdvertising* pAdvertising = BLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(SERVICE_UUID); + pAdvertising->setScanResponse(true); + pAdvertising->start(); + + Serial.println("BLE server advertising. Connect with nRF Connect!"); +} + +void loop() { + unsigned long now = millis(); + + if (now - _lastSensorReadMs >= SENSOR_READ_INTERVAL_MS) { + _lastSensorReadMs = now; + + int potVal = analogRead(POT_INPUT_PIN); + Serial.print("Pot:"); + Serial.println(potVal); + + if (_deviceConnected) { + String valStr = String(potVal); + _pSensorCharacteristic->setValue(valStr.c_str()); + _pSensorCharacteristic->notify(); + } + } +} +``` + +The key new element is the `LedCallbacks` class. When the central writes to the LED characteristic, `onWrite()` fires automatically. We interpret the first three bytes of the written value as R, G, B and set the NeoPixel color accordingly. + +{: .highlight } +> **Callbacks vs. polling:** Notice the pattern: we don't poll for incoming data in `loop()` (like we do with `Serial.available()` or `SerialBT.available()` in [Lesson 8](bluetooth-serial.md)). Instead, BLE uses a **callback model**—the library calls our `onWrite()` function when data arrives. This is fundamentally different from the serial polling pattern you're used to, and it's one of the biggest code-level differences between Bluetooth Classic and BLE. + +### Try it out from your computer (Python) + +Here's a quick Python script that writes RGB values to the NeoPixel characteristic: + +```python +""" +ble_neopixel.py: Connects to the ESP32 and sets the NeoPixel color. + +Usage: python3 ble_neopixel.py +Then enter RGB values like: 255 0 128 + +Requires: bleak (pip3 install bleak) + +By Jon E. Froehlich +@jonfroehlich +http://makeabilitylab.io +""" + +import asyncio +from bleak import BleakScanner, BleakClient + +LED_CHAR_UUID = "a3c87500-8ed3-4bdf-8a39-a01bebede295" + +async def main(): + print("Scanning for ESP32-BLE-NeoPixel...") + devices = await BleakScanner.discover(timeout=5.0) + + target = None + for d in devices: + if d.name and "ESP32" in d.name: + target = d + break + + if not target: + print("ESP32 not found.") + return + + async with BleakClient(target.address) as client: + print(f"Connected to {target.name}!") + while True: + rgb = input("Enter R G B (0-255 each, or 'quit'): ") + if rgb.lower() == 'quit': + break + parts = rgb.split() + if len(parts) == 3: + r, g, b = int(parts[0]), int(parts[1]), int(parts[2]) + await client.write_gatt_char(LED_CHAR_UUID, bytes([r, g, b])) + print(f" Sent RGB: ({r}, {g}, {b})") + +asyncio.run(main()) +``` + +### Try it out from your phone (iPhone and Android) + +1. Upload the sketch. The NeoPixel should be off initially. +2. Open **nRF Connect** on your **iPhone or Android phone**. Scan and connect to `"ESP32-BLE-NeoPixel"`. +3. Expand the service. You should see **two** characteristics now. +4. Find the LED characteristic (the one with `a3c87500...` UUID). +5. Tap the **write arrow** (↑). In the write dialog, select **ByteArray** as the type, then enter `FF0000` (red), `00FF00` (green), or `0000FF` (blue). Tap **Send**. +6. Watch the NeoPixel change color! 🌈 + + + +{: .note } +> **nRF Connect write format:** When writing raw bytes in nRF Connect, select "ByteArray" (not "Text") and enter hex values without spaces or `0x` prefixes. `FF0000` = red, `00FF00` = green, `0000FF` = blue, `FF00FF` = magenta, `FFFFFF` = white. Each pair of hex digits is one byte (0–255). + +### Workbench demo + + + +## Part 2: Web Bluetooth + +So far we've used nRF Connect as our BLE central — it's great for debugging, but it doesn't give us a custom UI. What if you could control the NeoPixel from a **web page** with sliders and a color picker? What if you could plot sensor data in a live chart — all in the browser, all wireless? In this part, you'll build a single-page HTML/JavaScript app using the [Web Bluetooth API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API) that connects to your ESP32, subscribes to sensor notifications, and writes RGB values to the NeoPixel — paralleling the [Web Serial](../communication/web-serial.md) approach from the Communication module but over BLE. + +### Web Serial vs. Web Bluetooth + +| | Web Serial ([L2](../communication/web-serial.md)) | Web Bluetooth (this section) | +|---|---|---| +| Browser API | `navigator.serial` | `navigator.bluetooth` | +| Connect | `port.open({ baudRate })` | `device.gatt.connect()` | +| Send data | `writer.write(bytes)` | `characteristic.writeValue(bytes)` | +| Receive data | Read from stream | Subscribe to notifications | +| User gesture | Required to open port | Required to pair | +| Security | No HTTPS required | **Requires HTTPS** (or localhost) | +| Chrome/Edge | ✅ | ✅ | +| Firefox | ❌ | ⚠️ (behind flag) | +| Safari / iOS | ❌ | ❌ | +| Android Chrome | ✅ | ✅ | + +**Table.** Web Serial and Web Bluetooth have strikingly parallel structures. The main differences: Web Bluetooth requires HTTPS (or localhost), uses structured characteristics instead of raw byte streams, and is supported on Android but not iOS. +{: .fs-1 } + +{: .warning } +> **Web Bluetooth requires HTTPS or localhost.** It will not work from a `file://` URL. Use a local development server (VS Code's [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer) extension, or `python3 -m http.server`) or host your page on [GitHub Pages](https://pages.github.com/). Web Bluetooth works in **Chrome and Edge** on desktop and Android, but **not on iOS**—Apple's Safari (and iOS Chrome, which uses WebKit) does not support Web Bluetooth. For iOS users, nRF Connect provides similar functionality. + +### The web page + +We'll build a single HTML page (vanilla JavaScript, no frameworks—matching the style of the [Web Serial lesson](../communication/web-serial.md)) that: + +1. Connects to the ESP32's BLE service +2. Subscribes to potentiometer notifications and displays the live value +3. Has three sliders (R, G, B) that write to the LED characteristic to control the NeoPixel + +Make sure the Part 1 sketch is running on your ESP32 before testing this page. + +```html + + + + + + ESP32 BLE NeoPixel Controller + + + +

ESP32 BLE NeoPixel Controller

+ + +
Not connected
+ +
+

Sensor Data

+
+

Potentiometer reading (0–4095)

+ +

NeoPixel Color

+
+ + + 0 +
+
+ + + 0 +
+
+ + + 0 +
+
+
+ + + + +``` + +Let's walk through the JavaScript, step by step: + +**Step 1: `navigator.bluetooth.requestDevice()`** opens the browser's Bluetooth pairing dialog. We pass a `filters` array that limits the list to devices advertising our service UUID—so only our ESP32 appears. This is the BLE equivalent of `navigator.serial.requestPort()` from the [Web Serial lesson](../communication/web-serial.md). Like Web Serial, this call **requires a user gesture** (a button click)—you can't trigger it automatically on page load. + +**Step 2: `device.gatt.connect()`** establishes a GATT connection. This is analogous to `port.open()` in Web Serial—after this call, we can read and write data. + +**Steps 3–4: Getting the service and characteristic, subscribing to notifications.** We drill down through the GATT hierarchy: server → service → characteristic. Then `sensorChar.startNotifications()` tells the ESP32 we want to receive updates. We listen for `characteristicvaluechanged` events—each event delivers a `DataView` containing the raw bytes. Since our ESP32 sends the potentiometer value as a string, we decode it with `TextDecoder`. + +**Step 5: Getting the LED characteristic.** We store a reference to the LED characteristic so we can write to it later from the slider event handlers. + +**`sendColor()`** reads the three slider values, packs them into a `Uint8Array` of 3 bytes (R, G, B), and writes them to the LED characteristic with `ledCharacteristic.writeValue(data)`. This triggers the `onWrite()` callback on the ESP32, which sets the NeoPixel color. + +{: .note } +> **Spot the structural parallel.** In [Web Serial](../communication/web-serial.md), you write raw bytes to a `WritableStream`. In Web Bluetooth, you write raw bytes to a `BLECharacteristic`. The data format (a `Uint8Array`) is even the same! The key difference is that Web Bluetooth writes go to a *specific, named characteristic*—not a generic byte stream. This structure is what makes BLE self-describing and interoperable. + +### Try it out + +1. Make sure the Part 1 sketch is running on your ESP32. +2. Serve the HTML file from a local server (VS Code Live Server, or `python3 -m http.server`). Open it in Chrome. +3. Click **Connect to ESP32**. The browser shows a pairing dialog—select your ESP32 and click **Pair**. +4. The sensor value should appear and update in real time. +5. Drag the R, G, B sliders—the NeoPixel changes color as you move them! + + + +{: .note } +> **Throttling writes.** If you drag a slider quickly, `sendColor()` fires on every pixel of movement—potentially dozens of times per second. BLE can handle this, but rapid writes may occasionally fail with a "GATT operation already in progress" error. For a more robust implementation, you could debounce the slider input or use `requestAnimationFrame()` to batch writes. For this lesson, occasional errors are harmless. + +### Workbench demo + + + +## Part 3: Nordic UART Service (NUS) + +Throughout this lesson, we've worked directly with custom GATT services and characteristics — the fundamental BLE building blocks. But what if you just want to send text back and forth, like the serial bridge from [Lesson 8](bluetooth-serial.md)? In this part, you'll learn the **Nordic UART Service (NUS)** — a widely adopted convention that emulates serial communication over BLE using two characteristics. NUS bridges the gap between BLE's structured model and the simplicity of serial, and it's supported by most BLE terminal apps out of the box. + +NUS is a widely adopted convention (created by Nordic Semiconductor) that uses two BLE characteristics to emulate serial communication: + +- **RX Characteristic** (`6E400002-B5A3-F393-E0A9-E50E24DCCA9E`): the central *writes* data here to send it to the peripheral (from the peripheral's perspective, this is "received" data—hence "RX"). +- **TX Characteristic** (`6E400003-B5A3-F393-E0A9-E50E24DCCA9E`): the peripheral *notifies* data here to send it to the central (from the peripheral's perspective, this is "transmitted" data—hence "TX"). + +The naming is from the **peripheral's perspective**: RX = data coming *in* to the ESP32, TX = data going *out* from the ESP32. + +{: .note } +> NUS is not an official Bluetooth SIG standard—it's a convention created by Nordic Semiconductor that has become a de facto standard because so many apps support it. Apps like nRF Connect, nRF Toolbox, and many Bluetooth terminal apps automatically recognize the NUS UUIDs and provide a serial terminal interface. + +Here's a simple NUS example: + + + + +```cpp +/** + * BLEUartService: implements the Nordic UART Service (NUS) for + * serial-like text communication over BLE. Type text in nRF Connect's + * UART feature and it appears in Serial Monitor; type in Serial + * Monitor and it is sent over BLE. + * + * Works on: ESP32-S3 Feather, Huzzah32, or any ESP32 with BLE. + * + * See: https://makeabilitylab.github.io/physcomp/esp32/ble + * + * By Jon E. Froehlich + * @jonfroehlich + * http://makeabilitylab.io + */ + +#include +#include +#include +#include + +// Nordic UART Service UUIDs — these are a de facto standard +#define NUS_SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" +#define NUS_RX_CHAR_UUID "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" +#define NUS_TX_CHAR_UUID "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" + +BLEServer* _pServer = NULL; +BLECharacteristic* _pTxCharacteristic = NULL; +bool _deviceConnected = false; + +class MyServerCallbacks : public BLEServerCallbacks { + void onConnect(BLEServer* pServer) { + _deviceConnected = true; + Serial.println("Central connected!"); + } + void onDisconnect(BLEServer* pServer) { + _deviceConnected = false; + Serial.println("Disconnected. Restarting advertising..."); + pServer->getAdvertising()->start(); + } +}; + +// Called when the central writes to the RX characteristic (sending data to us) +class RxCallbacks : public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic* pCharacteristic) { + String rxValue = pCharacteristic->getValue(); + if (rxValue.length() > 0) { + Serial.print("Received via BLE: "); + Serial.println(rxValue.c_str()); + } + } +}; + +void setup() { + Serial.begin(115200); + Serial.println("Starting BLE UART Service..."); + + BLEDevice::init("ESP32-BLE-UART"); + _pServer = BLEDevice::createServer(); + _pServer->setCallbacks(new MyServerCallbacks()); + + BLEService* pService = _pServer->createService(NUS_SERVICE_UUID); + + // TX characteristic — we notify data OUT to the central + _pTxCharacteristic = pService->createCharacteristic( + NUS_TX_CHAR_UUID, + BLECharacteristic::PROPERTY_NOTIFY + ); + _pTxCharacteristic->addDescriptor(new BLE2902()); + + // RX characteristic — the central writes data IN to us + BLECharacteristic* pRxCharacteristic = pService->createCharacteristic( + NUS_RX_CHAR_UUID, + BLECharacteristic::PROPERTY_WRITE + ); + pRxCharacteristic->setCallbacks(new RxCallbacks()); + + pService->start(); + BLEAdvertising* pAdvertising = BLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(NUS_SERVICE_UUID); + pAdvertising->setScanResponse(true); + pAdvertising->start(); + + Serial.println("BLE UART ready. Connect with nRF Connect → UART."); +} + +void loop() { + // Forward USB Serial → BLE (via TX characteristic) + if (_deviceConnected && Serial.available()) { + String msg = Serial.readStringUntil('\n'); + _pTxCharacteristic->setValue(msg.c_str()); + _pTxCharacteristic->notify(); + Serial.print("Sent via BLE: "); + Serial.println(msg); + } +} +``` + +### Try it out + +1. Upload the sketch and open Serial Monitor at 115200 baud. +2. Open **nRF Connect** on your phone. Scan and connect to `"ESP32-BLE-UART"`. +3. In newer versions of nRF Connect, tap the **UART** icon (or navigate to the NUS service manually). You should see a chat-like interface. +4. Type a message in nRF Connect and tap **Send**. It should appear in Serial Monitor. +5. Type a message in Serial Monitor and press Enter. It should appear in nRF Connect's UART view. + +If your version of nRF Connect doesn't have the UART shortcut, you can do it manually: expand the NUS service, subscribe to notifications on the TX characteristic (`6E400003...`), and write text to the RX characteristic (`6E400002...`). + +{: .note } +> **NUS is "serial over BLE."** It gives you the familiar send/receive text experience of Bluetooth Classic's `SerialBT`, but running over BLE—so it works on the ESP32-S3, works with iPhones, and coexists with custom GATT services. Under the hood, it's still GATT: the NUS service has two characteristics, and data flows as writes and notifications. Understanding the GATT layer (the [previous lesson](ble-intro.md)) will help you debug NUS when things go wrong. + +If you want a `Serial`-like API over BLE without manually managing NUS characteristics, check out the [NuS-NimBLE-Serial](https://www.arduino.cc/reference/en/libraries/nus-nimble-serial/) library, which wraps NUS in familiar `.read()` and `.write()` methods. It requires the [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino) stack. + +{: .note } +> **A note on BLE security.** In this lesson, we use BLE's "Just Works" pairing mode, which requires no PIN and provides no protection against eavesdropping. This is fine for learning and for projects where the data isn't sensitive (potentiometer readings, LED colors). For production IoT devices that handle sensitive data—door locks, health monitors, payment systems—you'd want to explore passkey pairing or out-of-band (OOB) authentication. See the [Bluetooth SIG security overview](https://www.bluetooth.com/learn-about-bluetooth/key-attributes/bluetooth-security/) for more. + +## Exercises + +Want to go further? Here are some challenges to reinforce what you've learned: + +**Exercise 1: NeoPixel strip control.** Modify Part 1 to control the 5-LED NeoPixel stick from your kit instead of (or in addition to) the onboard NeoPixel. You could either send 15 bytes (5 × RGB) in a single write to set all LEDs at once, or add a fourth byte for the LED index (0–4) and set one LED per write. Build a Web Bluetooth page with five color pickers—one per LED. + +**Exercise 2: Multiple sensor characteristics.** Create a service with *three* characteristics: potentiometer data (notify), photoresistor data (notify), and LED brightness control (write). This requires reading two analog sensors and exposing each on its own characteristic. Build a Web Bluetooth dashboard that displays both sensor streams and includes a brightness slider for the LED. + +**Exercise 3: BLE servo control.** Create a writable characteristic that accepts a single byte (0–180) representing a servo angle. When the central writes a value, the ESP32 moves a servo motor to that position (using the [Servo library](../advancedio/servo.md)). Build a Web Bluetooth page with a slider to control the servo wirelessly. + +**Exercise 4: Web Bluetooth + p5.js.** Port the Web Bluetooth sensor display from Part 2 into [p5.js](https://p5js.org/). Use `createCanvas()` to draw a real-time visualization (bar chart, oscilloscope, *etc.*) of the incoming BLE sensor data. If you completed the [p5.js Serial lessons](../communication/p5js-serial.md), compare the code structure—how much carries over? (Hint: also check out [p5.ble.js](https://itpnyu.github.io/p5.ble.js/), a p5.js library specifically for Web Bluetooth.) + +**Exercise 5: Port a Bluetooth Classic bidirectional project to BLE.** If you completed the bidirectional LED control from [Lesson 8, Part 4](bluetooth-serial.md#part-4-bidirectional-control), rebuild it using BLE with writable and notify characteristics. Update the computer-side code to use Web Bluetooth instead of Web Serial. What changed? What stayed the same? + +## Lesson Summary + +In this lesson, you learned how to send data *to* the ESP32 over BLE and build browser-based interfaces for BLE devices. Here's what you covered: + +- **Writable characteristics** let the central send data to the peripheral. You created an RGB color control characteristic that accepts 3-byte payloads to set the onboard NeoPixel. +- **BLE uses a callback model** for handling incoming writes. Instead of polling with `Serial.available()` in `loop()`, you define a `BLECharacteristicCallbacks` class with an `onWrite()` method that the library calls automatically when data arrives. This is fundamentally different from the serial programming pattern. +- **Bidirectional communication** combines notify (peripheral → central) and write (central → peripheral) characteristics in a single service. The ESP32 can simultaneously stream sensor data and accept commands. +- **Web Bluetooth** lets you build browser-based interfaces for BLE devices using JavaScript — structurally parallel to the [Web Serial API](../communication/web-serial.md). It requires HTTPS (or localhost), works in Chrome/Edge on desktop and Android, but not on iOS Safari. +- **The Nordic UART Service (NUS)** provides serial-like text communication over BLE using standardized UUIDs. It's a practical bridge between the simplicity of serial and the universality of BLE — and is supported by most BLE terminal apps including nRF Connect's built-in UART mode. +- **NUS is still GATT under the hood.** It uses two characteristics (RX for writing to the peripheral, TX for notifications from the peripheral), with naming from the peripheral's perspective. + +## Resources + +- [Web Bluetooth API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API) — MDN Web Docs reference +- [Communicating with Bluetooth devices over JavaScript](https://developer.chrome.com/docs/capabilities/bluetooth) — Google's Web Bluetooth guide for Chrome +- [Nordic UART Service specification](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/libraries/bluetooth_services/services/nus.html) — Nordic Semiconductor's NUS documentation +- [NuS-NimBLE-Serial Arduino library](https://www.arduino.cc/reference/en/libraries/nus-nimble-serial/) — a Serial-like API over BLE using NUS +- [p5.ble.js](https://itpnyu.github.io/p5.ble.js/) — a p5.js library for Web Bluetooth, from ITP/NYU +- [Create Apps for the ESP32 Using BLE Through P5](https://www.hackster.io/lemio/create-apps-for-the-esp32-using-ble-through-p5-55292d) — Hackster.io tutorial combining p5.js + ESP32 BLE +- [ESP32 Web Bluetooth (BLE) Getting Started Guide](https://randomnerdtutorials.com/esp32-web-bluetooth/) — Random Nerd Tutorials + +## Next Lesson + +With BLE under your belt, you've now covered all three major wireless communication technologies available on the ESP32: **WiFi** (cloud connectivity via [IoT](iot.md)), **Bluetooth Classic** (wireless serial via [Lesson 8](bluetooth-serial.md)), and **BLE** (structured low-power wireless in [Lesson 9](ble-intro.md) and this lesson). From here, you might explore BLE HID (making your ESP32 act as a wireless keyboard, mouse, or game controller), deep sleep with BLE wake-up for battery-powered projects, or combining BLE with sensors like the ADXL343 accelerometer for motion-controlled wireless devices. The wireless world is yours! 🚀 + + diff --git a/esp32/ble.md b/esp32/ble-intro.md similarity index 54% rename from esp32/ble.md rename to esp32/ble-intro.md index fa90351..81552f7 100644 --- a/esp32/ble.md +++ b/esp32/ble-intro.md @@ -1,6 +1,6 @@ --- layout: default -title: L9: Bluetooth Low Energy +title: L9: Introduction to BLE parent: ESP32 has_toc: true # (on by default) usemathjax: false @@ -22,33 +22,23 @@ nav_order: 9 > This lesson is in draft form. There are missing circuit diagrams, images, videos, and other content. In the [last lesson](bluetooth-serial.md), we used Bluetooth Classic to create a wireless serial connection—simple, fast, and satisfying. But it came with real limitations: no iPhone support, no ESP32-S3 support, higher power consumption, and only one device at a time. In this lesson, we'll learn **Bluetooth Low Energy (BLE)**—the protocol that powers your Fitbit, your AirPods' pairing process, your smart thermostat, and billions of IoT devices worldwide. @@ -61,11 +51,9 @@ BLE is more complex than Bluetooth Classic. Instead of a simple serial byte stre > - The BLE communication model: **peripherals** and **centrals**, advertising and connecting > - The GATT data model: **servers**, **services**, **characteristics**, and **UUIDs** > - How to use the ESP32 BLE library to create a BLE peripheral that exposes sensor data -> - How to read, write, and subscribe to BLE characteristics from a phone app (nRF Connect) +> - How to read and subscribe to BLE characteristics from a phone app ([nRF Connect](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-mobile)) and from Python ([bleak](https://pypi.org/project/bleak/)) > - How to stream real-time sensor data using BLE **notifications** -> - How to control the onboard NeoPixel by writing to a BLE characteristic from your phone -> - How to build a **Web Bluetooth** web page that communicates with the ESP32 from a browser—paralleling the [Web Serial](../communication/web-serial.md) approach but wireless -> - The Nordic UART Service (NUS) as a "serial-like" bridge for BLE +> - The 20-byte MTU payload limit and how to work within it **Did you skip Lesson 8?** No problem. This lesson is self-contained—you don't need Bluetooth Classic experience to follow along. We'll briefly cover how BLE differs from Classic in the first section. If you want the full comparison, see [Lesson 8](bluetooth-serial.md). And unlike Bluetooth Classic, which is blocked on iOS and only works on the original ESP32, **BLE works with iPhones, Android phones, and the ESP32-S3**—so everyone can participate. @@ -170,6 +158,10 @@ You can browse the full list in the [Bluetooth SIG Assigned Numbers](https://www {: .note } > **Don't be intimidated by UUIDs.** A 128-bit UUID is just a unique label—think of it like a URL or a barcode. You generate one, paste it into your code, and use the same one in your phone app or web page so both sides agree on which characteristic is which. You don't need to memorize them or understand their internal structure. +### A note on BLE security + +In this lesson, we use BLE's "Just Works" pairing mode, which requires no PIN and provides no protection against eavesdropping. This is fine for learning and for projects where the data isn't sensitive (potentiometer readings, LED colors). For production IoT devices that handle sensitive data—door locks, health monitors, payment systems—you'd want to explore passkey pairing or out-of-band (OOB) authentication. See the [Bluetooth SIG security overview](https://www.bluetooth.com/learn-about-bluetooth/key-attributes/bluetooth-security/) for more. + ## Choosing between WiFi, Bluetooth Classic, and BLE Now that you understand the BLE concepts — peripherals, centrals, GATT, services, characteristics, and UUIDs — you have enough context to see where BLE fits alongside the other wireless technologies you've learned. If you've completed [Lesson 7 (WiFi/IoT)](iot.md) and [Lesson 8 (Bluetooth Classic)](bluetooth-serial.md), here's how all three compare: @@ -694,688 +686,32 @@ You can negotiate a larger MTU (up to 512 bytes) if both sides support it, but 2 Include captions/transcript --> -## Part 3: Controlling the NeoPixel over BLE - -So far, data has flowed in one direction: from the ESP32 to the central. Now let's go the other direction — send data *from* your phone *to* the ESP32 to control hardware. In this part, you'll create a **writable** characteristic that accepts RGB color values and sets the onboard NeoPixel. You'll also learn the BLE **callback model** for handling incoming writes, which is fundamentally different from the `Serial.available()` polling pattern. - -The ESP32-S3 Feather has a built-in NeoPixel (WS2812B) RGB LED on `PIN_NEOPIXEL`, powered by `NEOPIXEL_POWER`. We used it in [Lesson 2: Blink](led-blink.md) and [Lesson 3: LED Fading](led-fade.md), so the NeoPixel setup should be familiar. - -### The Arduino code - - - -We'll extend the Part 2 sketch to add a second characteristic for LED control—so the ESP32 simultaneously streams sensor data *and* accepts LED commands. This is the same bidirectional pattern from [Lesson 8](bluetooth-serial.md#part-4-bidirectional-control), but over BLE with structured characteristics instead of a serial byte stream. The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/BLENeoPixelControl). - -```cpp -/** - * BLENeoPixelControl: bidirectional BLE communication. - * Streams potentiometer data via notifications (peripheral → central) - * AND accepts RGB color commands via a writable characteristic - * (central → peripheral) to control the onboard NeoPixel. - * - * Circuit: - * - 10kΩ potentiometer on A5 (GPIO 8, ADC1) - * - Onboard NeoPixel (no external wiring needed) - * - * Works on: ESP32-S3 Feather (for the onboard NeoPixel). - * On the Huzzah32, substitute an external NeoPixel or LED. - * - * See: https://makeabilitylab.github.io/physcomp/esp32/ble - * - * By Jon E. Froehlich - * @jonfroehlich - * http://makeabilitylab.io - */ - -#include -#include -#include -#include -#include - -// Custom UUIDs -#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" -#define SENSOR_CHAR_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" -#define LED_CHAR_UUID "a3c87500-8ed3-4bdf-8a39-a01bebede295" - -const int POT_INPUT_PIN = A5; - -// NeoPixel setup — one pixel on the onboard NeoPixel pin -Adafruit_NeoPixel _pixel(1, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800); - -BLEServer* _pServer = NULL; -BLECharacteristic* _pSensorCharacteristic = NULL; -BLECharacteristic* _pLedCharacteristic = NULL; -bool _deviceConnected = false; - -unsigned long _lastSensorReadMs = 0; -const unsigned long SENSOR_READ_INTERVAL_MS = 100; - -class MyServerCallbacks : public BLEServerCallbacks { - void onConnect(BLEServer* pServer) { - _deviceConnected = true; - Serial.println("Central connected!"); - } - - void onDisconnect(BLEServer* pServer) { - _deviceConnected = false; - Serial.println("Central disconnected. Restarting advertising..."); - pServer->getAdvertising()->start(); - } -}; - -// Callback for when the central writes to the LED characteristic -class LedCallbacks : public BLECharacteristicCallbacks { - void onWrite(BLECharacteristic* pCharacteristic) { - String value = pCharacteristic->getValue(); - - if (value.length() >= 3) { - // Interpret the first 3 bytes as R, G, B - uint8_t r = (uint8_t)value[0]; - uint8_t g = (uint8_t)value[1]; - uint8_t b = (uint8_t)value[2]; - - Serial.print("Received RGB: "); - Serial.print(r); Serial.print(", "); - Serial.print(g); Serial.print(", "); - Serial.println(b); - - _pixel.setPixelColor(0, _pixel.Color(r, g, b)); - _pixel.show(); - } else { - Serial.print("Received write with "); - Serial.print(value.length()); - Serial.println(" bytes (expected 3 for RGB)."); - } - } -}; - -void setup() { - Serial.begin(115200); - Serial.println("Starting BLE NeoPixel Control..."); - - // Initialize NeoPixel - #if defined(NEOPIXEL_POWER) - pinMode(NEOPIXEL_POWER, OUTPUT); - digitalWrite(NEOPIXEL_POWER, HIGH); - #endif - _pixel.begin(); - _pixel.setBrightness(30); // keep it dim to avoid blinding you - _pixel.show(); // turn off (all zeros) - - // Initialize BLE - BLEDevice::init("ESP32-BLE-NeoPixel"); - _pServer = BLEDevice::createServer(); - _pServer->setCallbacks(new MyServerCallbacks()); - - BLEService* pService = _pServer->createService(SERVICE_UUID); - - // Sensor characteristic (Read + Notify) — streams potentiometer data - _pSensorCharacteristic = pService->createCharacteristic( - SENSOR_CHAR_UUID, - BLECharacteristic::PROPERTY_READ | - BLECharacteristic::PROPERTY_NOTIFY - ); - _pSensorCharacteristic->addDescriptor(new BLE2902()); - - // LED characteristic (Read + Write) — receives RGB color commands - _pLedCharacteristic = pService->createCharacteristic( - LED_CHAR_UUID, - BLECharacteristic::PROPERTY_READ | - BLECharacteristic::PROPERTY_WRITE - ); - _pLedCharacteristic->setCallbacks(new LedCallbacks()); - - // Start service and advertising - pService->start(); - BLEAdvertising* pAdvertising = BLEDevice::getAdvertising(); - pAdvertising->addServiceUUID(SERVICE_UUID); - pAdvertising->setScanResponse(true); - pAdvertising->start(); - - Serial.println("BLE server advertising. Connect with nRF Connect!"); -} - -void loop() { - unsigned long now = millis(); - - if (now - _lastSensorReadMs >= SENSOR_READ_INTERVAL_MS) { - _lastSensorReadMs = now; - - int potVal = analogRead(POT_INPUT_PIN); - Serial.print("Pot:"); - Serial.println(potVal); - - if (_deviceConnected) { - String valStr = String(potVal); - _pSensorCharacteristic->setValue(valStr.c_str()); - _pSensorCharacteristic->notify(); - } - } -} -``` - -The key new element is the `LedCallbacks` class. When the central writes to the LED characteristic, `onWrite()` fires automatically. We interpret the first three bytes of the written value as R, G, B and set the NeoPixel color accordingly. - -{: .highlight } -> **Callbacks vs. polling:** Notice the pattern: we don't poll for incoming data in `loop()` (like we do with `Serial.available()` or `SerialBT.available()` in [Lesson 8](bluetooth-serial.md)). Instead, BLE uses a **callback model**—the library calls our `onWrite()` function when data arrives. This is fundamentally different from the serial polling pattern you're used to, and it's one of the biggest code-level differences between Bluetooth Classic and BLE. - -### Try it out from your computer (Python) - -Here's a quick Python script that writes RGB values to the NeoPixel characteristic: - -```python -""" -ble_neopixel.py: Connects to the ESP32 and sets the NeoPixel color. - -Usage: python3 ble_neopixel.py -Then enter RGB values like: 255 0 128 - -Requires: bleak (pip3 install bleak) - -By Jon E. Froehlich -@jonfroehlich -http://makeabilitylab.io -""" - -import asyncio -from bleak import BleakScanner, BleakClient - -LED_CHAR_UUID = "a3c87500-8ed3-4bdf-8a39-a01bebede295" - -async def main(): - print("Scanning for ESP32-BLE-NeoPixel...") - devices = await BleakScanner.discover(timeout=5.0) - - target = None - for d in devices: - if d.name and "ESP32" in d.name: - target = d - break - - if not target: - print("ESP32 not found.") - return - - async with BleakClient(target.address) as client: - print(f"Connected to {target.name}!") - while True: - rgb = input("Enter R G B (0-255 each, or 'quit'): ") - if rgb.lower() == 'quit': - break - parts = rgb.split() - if len(parts) == 3: - r, g, b = int(parts[0]), int(parts[1]), int(parts[2]) - await client.write_gatt_char(LED_CHAR_UUID, bytes([r, g, b])) - print(f" Sent RGB: ({r}, {g}, {b})") - -asyncio.run(main()) -``` - -### Try it out from your phone (iPhone and Android) - -1. Upload the sketch. The NeoPixel should be off initially. -2. Open **nRF Connect** on your **iPhone or Android phone**. Scan and connect to `"ESP32-BLE-NeoPixel"`. -3. Expand the service. You should see **two** characteristics now. -4. Find the LED characteristic (the one with `a3c87500...` UUID). -5. Tap the **write arrow** (↑). In the write dialog, select **ByteArray** as the type, then enter `FF0000` (red), `00FF00` (green), or `0000FF` (blue). Tap **Send**. -6. Watch the NeoPixel change color! 🌈 - - - -{: .note } -> **nRF Connect write format:** When writing raw bytes in nRF Connect, select "ByteArray" (not "Text") and enter hex values without spaces or `0x` prefixes. `FF0000` = red, `00FF00` = green, `0000FF` = blue, `FF00FF` = magenta, `FFFFFF` = white. Each pair of hex digits is one byte (0–255). - -### Workbench demo - - - -## Part 4: Web Bluetooth - -So far we've used nRF Connect as our BLE central — it's great for debugging, but it doesn't give us a custom UI. What if you could control the NeoPixel from a **web page** with sliders and a color picker? What if you could plot sensor data in a live chart — all in the browser, all wireless? In this part, you'll build a single-page HTML/JavaScript app using the [Web Bluetooth API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API) that connects to your ESP32, subscribes to sensor notifications, and writes RGB values to the NeoPixel — paralleling the [Web Serial](../communication/web-serial.md) approach from the Communication module but over BLE. - -### Web Serial vs. Web Bluetooth - -| | Web Serial ([L2](../communication/web-serial.md)) | Web Bluetooth (this section) | -|---|---|---| -| Browser API | `navigator.serial` | `navigator.bluetooth` | -| Connect | `port.open({ baudRate })` | `device.gatt.connect()` | -| Send data | `writer.write(bytes)` | `characteristic.writeValue(bytes)` | -| Receive data | Read from stream | Subscribe to notifications | -| User gesture | Required to open port | Required to pair | -| Security | No HTTPS required | **Requires HTTPS** (or localhost) | -| Chrome/Edge | ✅ | ✅ | -| Firefox | ❌ | ⚠️ (behind flag) | -| Safari / iOS | ❌ | ❌ | -| Android Chrome | ✅ | ✅ | - -**Table.** Web Serial and Web Bluetooth have strikingly parallel structures. The main differences: Web Bluetooth requires HTTPS (or localhost), uses structured characteristics instead of raw byte streams, and is supported on Android but not iOS. -{: .fs-1 } - -{: .warning } -> **Web Bluetooth requires HTTPS or localhost.** It will not work from a `file://` URL. Use a local development server (VS Code's [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer) extension, or `python3 -m http.server`) or host your page on [GitHub Pages](https://pages.github.com/). Web Bluetooth works in **Chrome and Edge** on desktop and Android, but **not on iOS**—Apple's Safari (and iOS Chrome, which uses WebKit) does not support Web Bluetooth. For iOS users, nRF Connect provides similar functionality. - -### The web page - -We'll build a single HTML page (vanilla JavaScript, no frameworks—matching the style of the [Web Serial lesson](../communication/web-serial.md)) that: - -1. Connects to the ESP32's BLE service -2. Subscribes to potentiometer notifications and displays the live value -3. Has three sliders (R, G, B) that write to the LED characteristic to control the NeoPixel - -Make sure the Part 3 sketch is running on your ESP32 before testing this page. - -```html - - - - - - ESP32 BLE NeoPixel Controller - - - -

ESP32 BLE NeoPixel Controller

- - -
Not connected
- -
-

Sensor Data

-
-

Potentiometer reading (0–4095)

- -

NeoPixel Color

-
- - - 0 -
-
- - - 0 -
-
- - - 0 -
-
-
- - - - -``` - -Let's walk through the JavaScript, step by step: - -**Step 1: `navigator.bluetooth.requestDevice()`** opens the browser's Bluetooth pairing dialog. We pass a `filters` array that limits the list to devices advertising our service UUID—so only our ESP32 appears. This is the BLE equivalent of `navigator.serial.requestPort()` from the [Web Serial lesson](../communication/web-serial.md). Like Web Serial, this call **requires a user gesture** (a button click)—you can't trigger it automatically on page load. - -**Step 2: `device.gatt.connect()`** establishes a GATT connection. This is analogous to `port.open()` in Web Serial—after this call, we can read and write data. - -**Steps 3–4: Getting the service and characteristic, subscribing to notifications.** We drill down through the GATT hierarchy: server → service → characteristic. Then `sensorChar.startNotifications()` tells the ESP32 we want to receive updates. We listen for `characteristicvaluechanged` events—each event delivers a `DataView` containing the raw bytes. Since our ESP32 sends the potentiometer value as a string, we decode it with `TextDecoder`. - -**Step 5: Getting the LED characteristic.** We store a reference to the LED characteristic so we can write to it later from the slider event handlers. - -**`sendColor()`** reads the three slider values, packs them into a `Uint8Array` of 3 bytes (R, G, B), and writes them to the LED characteristic with `ledCharacteristic.writeValue(data)`. This triggers the `onWrite()` callback on the ESP32, which sets the NeoPixel color. - -{: .note } -> **Spot the structural parallel.** In [Web Serial](../communication/web-serial.md), you write raw bytes to a `WritableStream`. In Web Bluetooth, you write raw bytes to a `BLECharacteristic`. The data format (a `Uint8Array`) is even the same! The key difference is that Web Bluetooth writes go to a *specific, named characteristic*—not a generic byte stream. This structure is what makes BLE self-describing and interoperable. - -### Try it out - -1. Make sure the Part 3 sketch is running on your ESP32. -2. Serve the HTML file from a local server (VS Code Live Server, or `python3 -m http.server`). Open it in Chrome. -3. Click **Connect to ESP32**. The browser shows a pairing dialog—select your ESP32 and click **Pair**. -4. The sensor value should appear and update in real time. -5. Drag the R, G, B sliders—the NeoPixel changes color as you move them! - - - -{: .note } -> **Throttling writes.** If you drag a slider quickly, `sendColor()` fires on every pixel of movement—potentially dozens of times per second. BLE can handle this, but rapid writes may occasionally fail with a "GATT operation already in progress" error. For a more robust implementation, you could debounce the slider input or use `requestAnimationFrame()` to batch writes. For this lesson, occasional errors are harmless. - -### Workbench demo - - - -## Part 5: Nordic UART Service (NUS) - -Throughout this lesson, we've worked directly with custom GATT services and characteristics — the fundamental BLE building blocks. But what if you just want to send text back and forth, like the serial bridge from [Lesson 8](bluetooth-serial.md)? In this part, you'll learn the **Nordic UART Service (NUS)** — a widely adopted convention that emulates serial communication over BLE using two characteristics. NUS bridges the gap between BLE's structured model and the simplicity of serial, and it's supported by most BLE terminal apps out of the box. - -NUS is a widely adopted convention (created by Nordic Semiconductor) that uses two BLE characteristics to emulate serial communication: - -- **RX Characteristic** (`6E400002-B5A3-F393-E0A9-E50E24DCCA9E`): the central *writes* data here to send it to the peripheral (from the peripheral's perspective, this is "received" data—hence "RX"). -- **TX Characteristic** (`6E400003-B5A3-F393-E0A9-E50E24DCCA9E`): the peripheral *notifies* data here to send it to the central (from the peripheral's perspective, this is "transmitted" data—hence "TX"). - -The naming is from the **peripheral's perspective**: RX = data coming *in* to the ESP32, TX = data going *out* from the ESP32. - -{: .note } -> NUS is not an official Bluetooth SIG standard—it's a convention created by Nordic Semiconductor that has become a de facto standard because so many apps support it. Apps like nRF Connect, nRF Toolbox, and many Bluetooth terminal apps automatically recognize the NUS UUIDs and provide a serial terminal interface. - -Here's a simple NUS example: - - - - -```cpp -/** - * BLEUartService: implements the Nordic UART Service (NUS) for - * serial-like text communication over BLE. Type text in nRF Connect's - * UART feature and it appears in Serial Monitor; type in Serial - * Monitor and it is sent over BLE. - * - * Works on: ESP32-S3 Feather, Huzzah32, or any ESP32 with BLE. - * - * See: https://makeabilitylab.github.io/physcomp/esp32/ble - * - * By Jon E. Froehlich - * @jonfroehlich - * http://makeabilitylab.io - */ - -#include -#include -#include -#include - -// Nordic UART Service UUIDs — these are a de facto standard -#define NUS_SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" -#define NUS_RX_CHAR_UUID "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" -#define NUS_TX_CHAR_UUID "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" - -BLEServer* _pServer = NULL; -BLECharacteristic* _pTxCharacteristic = NULL; -bool _deviceConnected = false; - -class MyServerCallbacks : public BLEServerCallbacks { - void onConnect(BLEServer* pServer) { - _deviceConnected = true; - Serial.println("Central connected!"); - } - void onDisconnect(BLEServer* pServer) { - _deviceConnected = false; - Serial.println("Disconnected. Restarting advertising..."); - pServer->getAdvertising()->start(); - } -}; - -// Called when the central writes to the RX characteristic (sending data to us) -class RxCallbacks : public BLECharacteristicCallbacks { - void onWrite(BLECharacteristic* pCharacteristic) { - String rxValue = pCharacteristic->getValue(); - if (rxValue.length() > 0) { - Serial.print("Received via BLE: "); - Serial.println(rxValue.c_str()); - } - } -}; - -void setup() { - Serial.begin(115200); - Serial.println("Starting BLE UART Service..."); - - BLEDevice::init("ESP32-BLE-UART"); - _pServer = BLEDevice::createServer(); - _pServer->setCallbacks(new MyServerCallbacks()); - - BLEService* pService = _pServer->createService(NUS_SERVICE_UUID); - - // TX characteristic — we notify data OUT to the central - _pTxCharacteristic = pService->createCharacteristic( - NUS_TX_CHAR_UUID, - BLECharacteristic::PROPERTY_NOTIFY - ); - _pTxCharacteristic->addDescriptor(new BLE2902()); - - // RX characteristic — the central writes data IN to us - BLECharacteristic* pRxCharacteristic = pService->createCharacteristic( - NUS_RX_CHAR_UUID, - BLECharacteristic::PROPERTY_WRITE - ); - pRxCharacteristic->setCallbacks(new RxCallbacks()); - - pService->start(); - BLEAdvertising* pAdvertising = BLEDevice::getAdvertising(); - pAdvertising->addServiceUUID(NUS_SERVICE_UUID); - pAdvertising->setScanResponse(true); - pAdvertising->start(); - - Serial.println("BLE UART ready. Connect with nRF Connect → UART."); -} - -void loop() { - // Forward USB Serial → BLE (via TX characteristic) - if (_deviceConnected && Serial.available()) { - String msg = Serial.readStringUntil('\n'); - _pTxCharacteristic->setValue(msg.c_str()); - _pTxCharacteristic->notify(); - Serial.print("Sent via BLE: "); - Serial.println(msg); - } -} -``` - -### Try it out - -1. Upload the sketch and open Serial Monitor at 115200 baud. -2. Open **nRF Connect** on your phone. Scan and connect to `"ESP32-BLE-UART"`. -3. In newer versions of nRF Connect, tap the **UART** icon (or navigate to the NUS service manually). You should see a chat-like interface. -4. Type a message in nRF Connect and tap **Send**. It should appear in Serial Monitor. -5. Type a message in Serial Monitor and press Enter. It should appear in nRF Connect's UART view. - -If your version of nRF Connect doesn't have the UART shortcut, you can do it manually: expand the NUS service, subscribe to notifications on the TX characteristic (`6E400003...`), and write text to the RX characteristic (`6E400002...`). - -{: .note } -> **NUS is "serial over BLE."** It gives you the familiar send/receive text experience of Bluetooth Classic's `SerialBT`, but running over BLE—so it works on the ESP32-S3, works with iPhones, and coexists with custom GATT services. Under the hood, it's still GATT: the NUS service has two characteristics, and data flows as writes and notifications. Understanding the GATT layer (Parts 1–4) will help you debug NUS when things go wrong. - -If you want a `Serial`-like API over BLE without manually managing NUS characteristics, check out the [NuS-NimBLE-Serial](https://www.arduino.cc/reference/en/libraries/nus-nimble-serial/) library, which wraps NUS in familiar `.read()` and `.write()` methods. It requires the [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino) stack. - -{: .note } -> **A note on BLE security.** In this lesson, we use BLE's "Just Works" pairing mode, which requires no PIN and provides no protection against eavesdropping. This is fine for learning and for projects where the data isn't sensitive (potentiometer readings, LED colors). For production IoT devices that handle sensitive data—door locks, health monitors, payment systems—you'd want to explore passkey pairing or out-of-band (OOB) authentication. See the [Bluetooth SIG security overview](https://www.bluetooth.com/learn-about-bluetooth/key-attributes/bluetooth-security/) for more. - ## Exercises Want to go further? Here are some challenges to reinforce what you've learned: -**Exercise 1: NeoPixel strip control.** Modify Part 3 to control the 5-LED NeoPixel stick from your kit instead of (or in addition to) the onboard NeoPixel. You could either send 15 bytes (5 × RGB) in a single write to set all LEDs at once, or add a fourth byte for the LED index (0–4) and set one LED per write. Build a Web Bluetooth page with five color pickers—one per LED. +**Exercise 1: BLE range test.** With the notification sketch from Part 2 running, walk away from your ESP32 with nRF Connect open. At what distance do notifications stop arriving? How do walls and obstacles affect range? If you did the Bluetooth Classic range test in [Lesson 8, Exercise 4](bluetooth-serial.md#exercises), compare the two. Are they similar? -**Exercise 2: BLE range test.** With the notification sketch from Part 2 running, walk away from your ESP32 with nRF Connect open. At what distance do notifications stop arriving? How do walls and obstacles affect range? If you did the Bluetooth Classic range test in [Lesson 8, Exercise 4](bluetooth-serial.md#exercises), compare the two. Are they similar? +**Exercise 2: Multiple sensor characteristics.** Create a service with *two* notify characteristics: one for a potentiometer and one for a photoresistor. Subscribe to both in nRF Connect and observe both values updating simultaneously. This is good practice for structuring your GATT services. -**Exercise 3: Multiple sensor characteristics.** Create a service with *three* characteristics: potentiometer data (notify), photoresistor data (notify), and LED brightness control (write). This requires reading two analog sensors and exposing each on its own characteristic. Build a Web Bluetooth dashboard that displays both sensor streams and includes a brightness slider for the LED. +**Exercise 3: Connection status NeoPixel.** Use the onboard NeoPixel to display BLE connection status: **blue** while advertising (waiting for a connection), **green** when a central is connected, and **red** briefly on disconnection before returning to blue. This is a common pattern in commercial BLE products. Implement it using the `onConnect()` and `onDisconnect()` callbacks. (Accessibility note: for colorblind users, consider also adding a blink pattern—*e.g.,* slow pulse for advertising, solid for connected, fast blink for disconnection.) -**Exercise 4: BLE servo control.** Create a writable characteristic that accepts a single byte (0–180) representing a servo angle. When the central writes a value, the ESP32 moves a servo motor to that position (using the [Servo library](../advancedio/servo.md)). Build a Web Bluetooth page with a slider to control the servo wirelessly. +**Exercise 4: Power comparison (research).** The ESP32-S3 Feather has a LiPoly battery connector and a MAX17048 battery monitor chip. Connect the 350mAh LiPoly battery from your kit and run a BLE sketch. How long does the battery last? Compare with a WiFi sketch (from the [IoT lesson](iot.md)). Which protocol consumes more power? For bonus points, use `BLEDevice::setPower()` to experiment with different transmit power levels and measure the effect on both range and battery life. -**Exercise 5: Connection status NeoPixel.** Use the onboard NeoPixel to display BLE connection status: **blue** while advertising (waiting for a connection), **green** when a central is connected, and **red** briefly on disconnection before returning to blue. This is a common pattern in commercial BLE products. Implement it using the `onConnect()` and `onDisconnect()` callbacks. (Accessibility note: for colorblind users, consider also adding a blink pattern—*e.g.,* slow pulse for advertising, solid for connected, fast blink for disconnection.) - -**Exercise 6: Power comparison (research).** The ESP32-S3 Feather has a LiPoly battery connector and a MAX17048 battery monitor chip. Connect the 350mAh LiPoly battery from your kit and run a BLE sketch. How long does the battery last? Compare with a WiFi sketch (from the [IoT lesson](iot.md)). Which protocol consumes more power? For bonus points, use `BLEDevice::setPower()` to experiment with different transmit power levels and measure the effect on both range and battery life. - -**Exercise 7: Web Bluetooth + p5.js.** Port the Web Bluetooth sensor display from Part 4 into [p5.js](https://p5js.org/). Use `createCanvas()` to draw a real-time visualization (bar chart, oscilloscope, *etc.*) of the incoming BLE sensor data. If you completed the [p5.js Serial lessons](../communication/p5js-serial.md), compare the code structure—how much carries over? (Hint: also check out [p5.ble.js](https://itpnyu.github.io/p5.ble.js/), a p5.js library specifically for Web Bluetooth.) - -**Exercise 8: Port a Bluetooth Classic project to BLE.** If you completed any project from [Lesson 8](bluetooth-serial.md) (the potentiometer visualizer, the bidirectional LED control, *etc.*), rebuild it using BLE. Replace `BluetoothSerial` with the BLE library, design your GATT service and characteristics, and update the computer-side code to use `bleak` instead of `pySerial`. What changed? What stayed the same? This is a great exercise in understanding the conceptual differences between the two Bluetooth flavors. +**Exercise 5: Port a Bluetooth Classic project to BLE.** If you completed the potentiometer streaming project from [Lesson 8](bluetooth-serial.md), rebuild it using BLE. Replace `BluetoothSerial` with the BLE library, design your GATT service and characteristic, and update the computer-side code to use `bleak` instead of `pySerial`. What changed? What stayed the same? ## Lesson Summary -In this lesson, you learned Bluetooth Low Energy—a fundamentally different approach to wireless communication than the serial-style Bluetooth Classic from [Lesson 8](bluetooth-serial.md). Here's what you covered: +In this lesson, you learned the fundamentals of Bluetooth Low Energy — a structured, low-power wireless protocol that's fundamentally different from the serial-style Bluetooth Classic in [Lesson 8](bluetooth-serial.md). Here's what you covered: - **BLE is not wireless serial.** Instead of a continuous byte stream, BLE organizes data into structured **services** and **characteristics** with defined properties (read, write, notify). This structure enables interoperability across devices and applications. - **BLE uses a peripheral/central model.** The ESP32 acts as a **peripheral** (advertising and hosting data), while your phone or laptop acts as a **central** (scanning, connecting, reading, and writing). Once connected, data flows in both directions. - **GATT** (Generic Attribute Profile) is the data model at the heart of BLE. A GATT server contains **services** (categories of data), which contain **characteristics** (individual data points). Each service and characteristic is identified by a **UUID**. -- **Notifications** are the most efficient way to stream data. Instead of the central repeatedly polling, the peripheral pushes updates automatically when a value changes—dramatically reducing power consumption and latency. -- **The ESP32 BLE library** (`BLEDevice.h`) ships with the ESP32 Arduino core and requires no installation. It uses a callback model (not polling) for connection events and write operations—a different programming pattern than `Serial.available()`. +- **Notifications** are the most efficient way to stream data. Instead of the central repeatedly polling, the peripheral pushes updates automatically when a value changes — dramatically reducing power consumption and latency. +- **The ESP32 BLE library** (`BLEDevice.h`) ships with the ESP32 Arduino core and requires no installation. It uses a **callback model** (not polling) for connection events — a different programming pattern than `Serial.available()`. - **The `BLE2902` descriptor** must be added to any characteristic that supports notifications. Without it, centrals cannot subscribe. - **The 20-byte MTU default** means BLE payloads should be kept compact. Send numbers as short strings or raw bytes, not verbose text. - **After disconnection, the ESP32 stops advertising by default.** Always restart advertising in your `onDisconnect()` callback, or new centrals won't be able to find the device. -- **Web Bluetooth** lets you build browser-based interfaces for BLE devices using JavaScript—structurally parallel to the [Web Serial API](../communication/web-serial.md). It requires HTTPS (or localhost), works in Chrome/Edge on desktop and Android, but not on iOS Safari. -- **The Nordic UART Service (NUS)** provides serial-like text communication over BLE using standardized UUIDs. It's a practical bridge between the simplicity of serial and the universality of BLE—and is supported by most BLE terminal apps. - **BLE works on the ESP32-S3, works with iPhones, and consumes dramatically less power than Bluetooth Classic or WiFi.** For most new wireless projects, BLE is the right default choice. ## Resources @@ -1384,23 +720,22 @@ In this lesson, you learned Bluetooth Low Energy—a fundamentally different app - [ESP32 Arduino BLE API documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/api/ble.html) — Espressif's API reference - [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino) — lighter-weight alternative BLE stack (~60% less flash, ~50% less RAM) - [nRF Connect for Mobile](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-mobile) — our recommended BLE debugging app (free, iOS + Android) -- [Web Bluetooth API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API) — MDN Web Docs reference -- [Communicating with Bluetooth devices over JavaScript](https://developer.chrome.com/docs/capabilities/bluetooth) — Google's Web Bluetooth guide for Chrome +- [bleak](https://pypi.org/project/bleak/) — cross-platform BLE client library for Python - [Bluetooth SIG Assigned Numbers](https://www.bluetooth.com/specifications/assigned-numbers/) — official list of standard service and characteristic UUIDs -- [Nordic UART Service specification](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/libraries/bluetooth_services/services/nus.html) — Nordic Semiconductor's NUS documentation -- [NuS-NimBLE-Serial Arduino library](https://www.arduino.cc/reference/en/libraries/nus-nimble-serial/) — a Serial-like API over BLE using NUS -- [p5.ble.js](https://itpnyu.github.io/p5.ble.js/) — a p5.js library for Web Bluetooth, from ITP/NYU -- [Create Apps for the ESP32 Using BLE Through P5](https://www.hackster.io/lemio/create-apps-for-the-esp32-using-ble-through-p5-55292d) — Hackster.io tutorial combining p5.js + ESP32 BLE +- [Bluetooth SIG: Security Overview](https://www.bluetooth.com/learn-about-bluetooth/key-attributes/bluetooth-security/) — official overview of BLE security and pairing modes - [Getting Started with ESP32 BLE on Arduino IDE](https://randomnerdtutorials.com/esp32-bluetooth-low-energy-ble-arduino-ide/) — Random Nerd Tutorials -- [ESP32 Web Bluetooth (BLE) Getting Started Guide](https://randomnerdtutorials.com/esp32-web-bluetooth/) — Random Nerd Tutorials ## Next Lesson -With BLE under your belt, you've now covered all three major wireless communication technologies available on the ESP32: **WiFi** (cloud connectivity via [IoT](iot.md)), **Bluetooth Classic** (wireless serial via [Lesson 8](bluetooth-serial.md)), and **BLE** (structured low-power wireless in this lesson). From here, you might explore BLE HID (making your ESP32 act as a wireless keyboard, mouse, or game controller), deep sleep with BLE wake-up for battery-powered projects, or combining BLE with sensors like the ADXL343 accelerometer for motion-controlled wireless devices. The wireless world is yours! 🚀 +In the [next lesson](ble-bidirectional.md), you'll learn how to send data in the *other* direction — from your phone or browser *to* the ESP32. You'll control the onboard NeoPixel over BLE, build a Web Bluetooth interface with sliders and a color picker, and learn about the Nordic UART Service (NUS) for serial-like text communication over BLE. Let's go! 🚀 \ No newline at end of file + + + + + diff --git a/esp32/bluetooth-serial.md b/esp32/bluetooth-serial.md index 922f57f..9472513 100644 --- a/esp32/bluetooth-serial.md +++ b/esp32/bluetooth-serial.md @@ -849,15 +849,15 @@ In this lesson, you cut the wire! Here's what you learned: ## Next Lesson -In the [next lesson](ble.md), we'll learn **Bluetooth Low Energy (BLE)**—the protocol that powers fitness trackers, smart home devices, and billions of IoT sensors. BLE works on the ESP32-S3, works with iPhones *and* Android phones, and introduces a structured data model that's more powerful than serial. The code is more complex, but the capabilities—and the universal device compatibility—are worth it. Let's go! 🚀 +In the [next lesson](ble-intro.md), we'll learn **Bluetooth Low Energy (BLE)**—the protocol that powers fitness trackers, smart home devices, and billions of IoT sensors. BLE works on the ESP32-S3, works with iPhones *and* Android phones, and introduces a structured data model that's more powerful than serial. The code is more complex, but the capabilities—and the universal device compatibility—are worth it. Let's go! 🚀 \ No newline at end of file + diff --git a/esp32/esp32-ide.md b/esp32/esp32-ide.md index 345188d..9017d60 100644 --- a/esp32/esp32-ide.md +++ b/esp32/esp32-ide.md @@ -3,7 +3,7 @@ layout: default title: ESP32 IDE Setup parent: ESP32 has_toc: true # (on by default) -nav_order: 9 +nav_order: 11 nav_exclude: false comments: true usetocbot: true diff --git a/esp32/index.md b/esp32/index.md index 2457043..092d08c 100644 --- a/esp32/index.md +++ b/esp32/index.md @@ -17,7 +17,7 @@ usetocbot: true {:toc} --- -Welcome 👋 to the **ESP32** module! The [ESP32](https://www.espressif.com/en/products/socs/esp32) is a fast, low-cost, WiFi- and Bluetooth-enabled microcontroller that has become **the** platform for Internet of Things (IoT) projects. And the best part? You can program it with Arduino—so everything you learned in the [Intro to Arduino](../arduino/index.md) series carries over! In this module, you'll learn how the ESP32 differs from the Arduino boards you've used before, and you'll build projects that blink LEDs, fade lights with PWM, play tones, sense capacitive touch, and connect to the cloud ☁️. Let's go! 🚀 +Welcome 👋 to the **ESP32** module! The [ESP32](https://www.espressif.com/en/products/socs/esp32) is a fast, low-cost, WiFi- and Bluetooth-enabled microcontroller that has become **the** platform for Internet of Things (IoT) projects. And the best part? You can program it with Arduino—so everything you learned in the [Intro to Arduino](../arduino/index.md) series carries over! In this module, you'll learn how the ESP32 differs from the Arduino boards you've used before, and you'll build projects that blink LEDs, fade lights with PWM, play tones, sense capacitive touch, connect to the cloud ☁️, and communicate wirelessly over Bluetooth 📡. Let's go! 🚀 ![A collage of ESP32 boards including the original ESP32, ESP32-S2, and ESP32-S3](assets/images/ESP32Variants_FromS1-S3.png) **Figure.** The ESP32 family includes dozens of variants from Espressif and third-party manufacturers. They are fast (up to 240 MHz dual-core), have built-in WiFi and Bluetooth, and many development boards cost around $10 USD! @@ -110,6 +110,18 @@ The ESP32 has built-in capacitive touch sensing hardware—no external component Connect your ESP32 to WiFi and upload sensor data to the cloud using [Adafruit IO](https://learn.adafruit.com/welcome-to-adafruit-io). This is where the ESP32 truly shines! ✨ +### [Lesson 8: Bluetooth Serial](bluetooth-serial.md) + +Cut the wire! Use Bluetooth Classic's Serial Port Profile (SPP) to communicate with the ESP32 wirelessly—using the same Python scripts, p5.js sketches, and [serial.js](https://github.com/makeabilitylab/js/blob/main/src/lib/serial/serial.js) library from the [Communication module](../communication/index.md). The `BluetoothSerial` library intentionally mirrors Arduino's `Serial` API, so converting wired code to wireless is trivially easy. Requires the original ESP32 (Huzzah32). + +### [Lesson 9: Introduction to BLE](ble-intro.md) + +Learn **Bluetooth Low Energy (BLE)**—the protocol behind fitness trackers, smart home devices, and billions of IoT sensors. You'll learn the peripheral/central model, the GATT data hierarchy of services and characteristics, and how to stream live sensor data to your phone and computer using notifications. Works with the ESP32-S3 and iPhones! + +### [Lesson 10: Bidirectional BLE](ble-bidirectional.md) + +Send data in *both* directions over BLE. Control the onboard NeoPixel by writing to a BLE characteristic from your phone, build a **Web Bluetooth** interface with sliders and a color picker that runs entirely in the browser, and learn the **Nordic UART Service (NUS)** for serial-like text communication over BLE. + TIxdVQ{xq4>XhT2}caC+>OU$0`!Ewczj1h#CCkN+H=KBca5_>+eD#x)mk`#FVAeURc}F z_w4wS$d%Th)XX2#LtB@dCb+cLPpxyAXAK@62x=hPD?Vt1B~O5!e50*Yw-)y8b#R`a zr)}00j7yFb`^Zs<2c!UirM1f#^C>3sTQhMGzybnUR4H$eNhu~H%LT#IcGp=r?hqpH z%)!*7d2H!j-`04YPj~oy&LtXL$}FQClJ~Uu!X>qpEWd}QQ0RyVz9`?J8(@n3Ek}Js zg$~|+QKRP~{%(pa$UeX9+UD_^*TJ3-t5hfOyy3mQ0^K zQSoClUcDGM5)dCp=&*rx0^$)|9^KI#X068r^9KccbgNJ2EE;n9{plq6wiZPOA7c?^FpY3v_?;is z6Z4HlYpUt~)D{=*7%yBQK2Eu8^aiR93rDuwaPdrOs`oS)G-#=T7A>v-u7J#bGfU_0 ztQoz0r(AlR6Mg)b5C;x44I@=@_q;Ug?C+UBGN`8W_gl8zhPTtl>NhWM8z}~F#e4xb z%lbDOl4t#bf{wdrjHmQwNuAkP?l+4NxqMCTj zj_^E)mTApLh@f*Fc{)4*zlTi{z=L+S%IT_e8}R`DxbNupgc3YO$1CT`O6)`{0K3Lrn+dk)z zgnY!WONPFi^mlV0mr!)RKcjo%)U#vd1X-y0FZ09B-;ArBlPImZ8z(ZI9gA~@TBQcw zHYQpsaA&aGYx)xW;6!|WjcddCD()4Y3fYF2(^9 z`0tJ3fA`h`y8mTOnG$n_i4yJxQ}})~u(F8N&= zUIp>y?dex4qDE|Ov%a|6=d04?GZNJRUsB=i_DbwnF{12za@=`Bp|SMS<^T3>c8`?B z(C21tJ^T2}O`t3|!aZ5S<(R(^1W~VUQ2H@(!R?gppoSv2;ZI??r!>Nl_lA#BM>ASN zl0V8pbY$p1Twx)JP2wR#p7aN6uM_?;62kWP9%o{CwYG4w!D>lEOJ`FA0&;5=F=Gv9Xa* zbbDx|IiEz^K)4)}G10YsLL<>1Np!b{K0`CNYGDxg_Ch~xb*~Wwz`xB<3M%$P9#gSF zJ*@53=rjsm>d-bP%>d-llDpz$NN7}f<;@TAbea4OPAonf%LjaUktS;_ri3v2+d30~ z{gq2np0}g4aevt_$<@vEm*tP>p=$vWUH~fyHPmJRITsVPi$!q1*7^DEm0@XPgbjf=m9_cLvdAYbXao>$ha4mlk2FBeA=ul*5!DRzbt-M_%7G8 zug^bcjivyg@NCi~PhO(0uWVY2RHac8 zG;-$qlNq`-(#wk@?Mv82Qz$Z-{iL#ZY;QCn&ygpBAyT8aCu$fE6zjUdy#!KyNghz^ z0Ot~5)CLR?qdu^U2-n0dfUB0)L9!r)5;Ih7?Ij_c2<|+<%uBbB*V7h3!(Ny6z-)ox z!?_)0v!36778XW|xH>(oud8i5J_~}`(nssk-_*9OvdaK$S%A1v6kk~OdRwudXyPK1 zZ~wjH>e0owVh^6`Rq{|JfrfQ2OR}hAgaw)4Y?7X5xyz#pVx4`_?Aa%SpIF11>v!yA z8cGcs{{(Mwtp<4ha~$5SKZ z>r+7ofNkn<4DdP+0cb&pd}Re+X>QSeE#Oz%S|cPvDtfj{S9vn)fuq0QRW6FxH4w^Y z@1l{06h>9h$Y@Y&_!Bxtc>oe!AB@q!Xd}t~K>?>ox}gm+;% ztwj1kjZdT0Lwi6dR>W18`Zo?fQuQ5e^EFSuRUr*{&_?SyQFkQ50PV+E$_-E>@HumM zVy(hcEzyc3ZBbgPa1N^C0*AsvddbkxtNN%fn|=WvJGP3t9AAI*W=HDi6niS9|5`u& z;^X}V2;kLCO~Lgl>Ad~pwN%rn=L??`x^hQ7=|-KXaX#>#711gZaYhF-Z;mAQICStt;Y(n!0DJ4e_aCI)E2E77C9EN z9IU2KD;kEVabpQ}LgPVcnX$gdGL5C|f71Uu(ccyLMd|-%G93Cy{yRk?^Ps zFznE4+C!7&P(aiwrWb?R5J$0XLm)8`oKrE74eiik|S$j#HrT92WbDIc}cdqg_SPzKRu3rZXcDE;Amn& zH%A0wDn^%aOu}?VNMZtGZm2wJub&D^9~n!4hBAf3Iv1DJ_R?b(8I6&2f{bzM(eSn; zHuRfNEu5j-r?0Pd3f8K)L)u{xHd;$#EW(qW;@@|DKk<2FX8xVjqZlfl6)rJ4DXd+n z2mA{kLn0lK@@}S1a4GQ3r)kfOY1{C2r*Cm_M`be0`m~&ve^k$oO0j2(Uqje?tXvGSc>1k!%0Zt(B z`ek)GKg1f7cjdKQNNCCke&UUKyPXIcmF&=0v!JIzNO={>>dS_B^-QNmLv92M;%Fg+ zfW9`gwj?wJD|E9G_j3xPIO0fzYi#j=LJpYyWq9 z9{u&2b~NA9Y`IVJ&j8|m1RLp}k_%@BRk}L&rD}Zx>`{Pyq_;=twQFuGV7jS}sfK3Rq%#Owr=gLGcgZSCls=oEX)afx=(V%l+RzO5k1+u%1B5%wrD(k$H zr0|D^S!#&&4z@-Cvwl*(W4C=ZSot4iD&E-Tcj1jmcg+<_{X3mWi6p%t*qxh$_#z;w zBv~+ZMLNK~-`DtU)7$K*^-DsUNj(}G*UOCV1p&tTlst!G+Ga3iU{nWW1im@)vMOz? zzQ%5$>RN_hfr~&uuSN7KX;EUM+IJ%&JX_Ss59Qz z^wiug_@rEX7NM0c9{rDL)iT?`o8=IUp@7*#IUE>4%jPy>g73E1>L7UlfH(`_oS2KY zfO!~r7aN#SG%{SO&E|}6i(`4Nl_~L83x+lXHX9qxaVL84swgNceg+xoV=<<5^+U;c z?S1ml*8cHNU|Q_wHY@AY$;$TB$yn9N?w>lqCS8)Msd!+!_p=3K^jwODT3o5RYferd z&8*>VNtvxb1e}Qde3ro{8xC|K7@icqNQZ9XT(*el71b^7HdsWLZj`+?6v?LX(n7`< zgU{{?i3Q7&w&TNr{?tPk-9Ei#L?Fyg^S%RYou?iZx|2xr?Iq=O8m`OgncQmuHviB! zN4WJZ=ZNuJRS{x4Dank(k2T5@>?{Fg6BrSq1f=xe!%;@=!y;Ox0NY_>z~0t8DN**+ z^wJ_;+Ub!dJoZwVsde#qMqL}-uJd?;1K0i^olXI%tQK;vE@WrAk?k5)fIJ5@F^;3V z?xBg#(la|t{TMRfjN0E`2|k>y1721XV01wTHxk1rka0*FG(bJOB zx_8)mG^=vFcZ7ciul0^7AJ#z%JyJt3w|XZjdbum|=6Ps$TgZN$&<0&0r&URl15A&g zQZ$U{urBl#D#wE-!UL8!s3}9Z)CRlrTX29^7lr+Z^mi*bnb>)7+;h4KdyoA@>`s_6 zRQ5z4T>O>yD8q-HA7uJ*H5_}ztRCeET2!gxy zBwt9J1OUR~gxDF>^E5SjZ!fR<26^3C$V4+Wba>RqvWloJ{js@6mnZf~g!#`u3xFk< z6^M96-tf0E36B|*s?%=MV;pF%XINcx_t%qlOlIi6835@w_z?rJ4p;lD4uC-|E8mQh zamfSu6HxH2!(Ek7U^;xyv1B%K=M4gwg93kqMi@EI{NiTsIYXb6Ypv z({h0+EeHYxVTV42utc=Vy@0#3dkGs4IpP01^}XGC@y#e~j#X1g3of-)J(LTKakv z^2IE$iA{U^D}dfTG5LcxCW1@c>h$EaKjZTC_3fM;TvMNbQ-g9$tZL{ZBk$bbqANZmM z%*B3+?P&F`mhbSOSC3MULUwc^`2_?Qx}uf;d^aC`mYTG>mL~jYWyMFQ%~dE0q=gA> zZC@C!IZnOjpg6o7;P@|XfG7L9W#lj3f1|3s1aL+Z6M#b&Sa6`v&de|Oq+E{x4?rPr zf0hW08BG3YgE25LCneR$KM|;2eOdRw9q{Yq+HlLEAXIP8TH@jmfS;k(wWPS9P^(MV z8=a+wl9c^v!U@7bn>4STR$3RpsHzvWufX3aN4Kuch=Oc-sN+VpJ{nLM<*?pkwz z`R7u|cE`XtGTFx~bQ!^!eCfS|1ppxL4KB0rxpF@U3IN>{gv0@sJZwnp9U6PXZuv(O zc;i?Pi$p9VsM=;xQ|(rI(()&09NOKmyW*XYmo)iZ+NbIhx^%~D_oaFj`^PI^i)3Rf@|QBKH&}FNB#kLreO_$5 z7xuGCwVtW<{N9-;8rWO?w{#i&MPAS@r_1G9*;mhCcL)c$y?meR8Q+VS6T}jl49pg@YrPX082RWp|IWdE%%j7-nY%r0JV}8g zJ7;ax1sA5pEuAbX0~GpqSXoH{CDQCR+DKxTZof&L4R@}i0#An{cc+Ipm7cT_i0K`# zF2T3}M@mT)c}iWA#jdu}U(MuIPfjY?L-XlTP+;@ymUUH@v~Uh1IiB!Vn<#WV{ukdb z06y;j{OzZZXsy1e>6zTP*6%%${_rQ0vlrME$5wI2A?0aLRjwoC_-vW+`Z8Kl>(OT zvnRn;=SEZylirejCf_!b!a_cT6w?MJ8|aNhb5uxLkN(5l=D~}nZG5=irA7`ZG#}2W zzeS8gA;;2OM$Ir`B9CnuRwF#GDJ>qj_6J@k?p z9g9Wv9WM`0oE!%qx1Iip3l2DnJ32b*pD9R+fvBB#$QH{s&v7H&zeRL}ixV}Si+wvq z?8N5d(F`+EqoZdfORT)grI+Eip}Z0|!iomxFg-tl-{T>Rmwwh)=>1!2Dx;ReryJ1m z@NJ3yg3iK|ZC3YYm_Ob0PdSrrU{i4IRvbn`AZ}MQ`EHgWG&Ytk)nsIP#gL=|U8G%9 zAN`&)Fc4uhov|q3{9nLqr42ty2X~W%*7I=LSRm8V(8j+nvOu*k;H4;;LSC5tYbU^j zKnv}0Ju6D^wE~9Kq^j9>4($Qn{@efQohoZ;6vNeKQkWuuidQqsZ-c;EqH~Uqr}hIe z+c(;7S;KH$(QwKA+S40S0(?+$hsgKfJ`6D_sAa&fPgZ>_4 zfJHl_nt|*p&*>+R)r8dV-$I(tnU9YDxcV-HG_0$cpIg)eYE1v>)wj$4F$R1$HA%b6 zhZ%E&lZ~2r@%Zr%3^u{;*Ne9(ZAGqD7j>2wlg=3{>-LXzZw^LtlvvkuhU2x6)0g7E zO6AOKZh(6qgaXjlNT_xNgKS_X1Whf=(iDMD3P3FWt0j5_SiqVaaRNv&68pVz!=nKH z`S|ATnu(lWW-##6g1G}*5>tdzZC#b`?(|wZa7rulecIXC*cel-2lc?I&++j-z!E&l zBt;ck@Tg?v8TNf-FA5Du5zZ_<3VJgNj58^JT%al|ps0x?)PcScQdg$$abe11Wt}*p3joo7`GF)Ak;yZ66%oIpYP1B3yab16M8NDSxtdyYHjae*Gv+mHgn+h z)>qb5)ztwM#@y;EAYo{s$Ww?eqV+4tWRnD$hpq?ymlR(;$f8b< zRgV`=cPfHUdrnW*Pr*N3S6dSuf_ypjv1`Hn5-SYgQQYEa%syr2q6m}@9QP#Ugg+-J zP-0%1f4rapBcss+d6@@X;jn-c z*;dZ;QaD#d(Ae{93zrRidi-w||EX7y9Yw?1jp0HOb;xz#$AK|7J@iuevzqRHvX|_B z(hr286DPlu)19JpMM6b180=$E8wyM+He* z2Zv?LJ@{~WqW3n1_uEWv2nzJ~;so~gKIOs4PkCs3%5%_AkbTxP8Tyk?M|}BGkJotli|B@W ziGA{MK1(D9t3PHV2iyVBUEV;ZwK9=czgHmX^IV4^5yo~G* z?E+s5+KW^U9(-)z4%u4At_A?wjt;75+0)ks z$q6E7ze23^@AEOixA$#|?iTvW6+lg0I_@gJ;=e|^e>gSuW;P&$3G@`e=x=RJLV!x> z<4}&T#~~8wphiAO6q)aS@9Y?r3vI;5pAW;~@2I^#frX@3+q_CNxYj8i2+h|`RTz|iqixM$?n-28iPbtu}h@Kkr@iaVv5KJPGn*PQqj z8-c8o2@PNiwRG%cvn^;z-plY3Ck=>U%QN`-_`WWHK^B2+opq;Av*G*W)m&EOR~h8FFXNBBhWkKnm?}eet|t8Wx$<3d^wPG5?dJF>N+y-3v5)rU>ay7oDKV| zpkE9l?LVz$rG%)*b&%84bH`H2ZKL&PaYwYStEpGJy2O1buujg&V%B*dmpQY?2A@Pq zzG6NR?F9l-ReGBXde?xZ?hG;lzHNSkIPkCmR{#q`+m)4tT1x`J4AO^5`;-FHYer5d zc@32%j@DROX@L~t5XLI(i#?mnHr4L89W^ay=hwJ%_LWtNpxmBLcL(13!jk%+-6arK z-Qz0G06KPRteR4#bj04B(tXml{gC0PKkKMQ=Rl24jww6q2eE817wc{@q?90%avt29 zeNWMmj_YtEudJ8KqHr+1#pv?!N*&VF`-(OPsq1PoG#dEzzjjnaAagHY^o!pZWgKC6 zQ+JnH@XFuoCsCP2U|x+A4aPTPK(himBY@seEkQ8(zHl|bW%%ySpFcsg_segP6U8tt zt|!A{22XO)z31)}67FN^;LYu*rwQb?JUj?bVBM9XATt&LhV~;61S>#$^r+`F;&e6m zbid(v1e~k%8P^yJvJ|?|D3e6G;?H+&!yO!JyyoSGMJEfqrpIiLf^CL%B$hwUiUa>! z#zIDPfq=RvSa8C^VNar!1rff2**Z342kP`k(}fZdD6yYmoRJ;=BKU(}EE5BR z+}~gkh?e#)T)s4QLryV9v224ti=~=YbHZyx70W8;q8-N{M?#P8x>+VwN|^`o z15Fl{zn{`*pWJQWmsB6Fv8VNdI*9)x6|13L1c|r1KW&1P21URlGmM<%ehxyff3c!f zDt3m`9_cVFHz9~{QBGQOSaW*=4S#Lc_ib)oQ+WP4h7RFV)vWQ-ChM_?cc$v-A?a*R zza25iXkp}dD*x0KtBIbz+z*}Xpq~id<|7xPlr>9yT%p6^;4Gd+$qR+2NWlO~Eh^rA z(!5lwKscR_TdPR%UUD%xzcWNr<~}JjYjPn2D}bqR?>^&_x6r^)(+!setC}{7Wm9S9)k+##^j;2K>fDb-{A<4 zS$L{L6qL8t!5z?qK5AjHBF@*SeV0C=qxSX7N&11F*@013Dt(W$?kC?z+HiJtvA>0X z($$=uPAU=^zW{-1O};S2agxjU>p)T>&8du$7vu^H3IqHx*+NVzVD+{Nt6HcOU!+ik6~K{0_<^52&kR4TH6nlyIA zy;QXPb<^jXDB-F zAQ($Zdf~MfJFr}_BHhfP|KFPsb=c<&rieFx4Eq@x5mtKv^Ar}Ipl)lYp2I096RAwv z_0{Hsr>X7{Vb7H{k?xzzW>(EWHCw?}cnY=h#Ju;YP9;N{BAaAbI z&lzSlbcrPFLvqj}Bf{QdST339jFx4xj~ds8Yv6JDwrjylAGvQ#BR^b?W8&{LIj)5rT@ZT1NEX=quzBSC(fjRfWPVqDf7hN zI~`HKAXe14ZuZ@QZn8Yvb-Gc8a{d(~aUiCa3{EtOz~}YRsK!YP&re=CCr!DpCNF0q zh|6s+n|b>J?+8IOPaeLM_YKNWO|N?}k#_D+OWOGe`X>=EJ3PWihLZfrCjzafyT2Ml zR?gsBeu(@HADM^{I3i+l6V3hNY9VVW$#ME4$C-1`xqxIEZ=SB{d{qrA=zey5I@ba&)emy=yi6sDN-VEk@GbzGwzF>WjWxPBiUX zkfeKWGgqPWCva9a3}*QS2|D1viZ_vR-tRzRfw&}q|6UJc5fEHm8V&eItWx3;zG$#d zm?M+#1h#RDd6LgXPMCH*WfG?JLJcj$w%PIBd5x1Ak4K7O327!&YEqX3j1$CcVYPK~ zVJVoHPYWurz8QEht=t7rI%>P5z*wo|41>iv#yx3Xa@yPFngg>5;I>#Y)(!oZeuG_z z`+DQV{*3pVMTL-)kw~`PSvo48129J$zGP8xF?S8Nb(2a4ffbu6T>s$;gQyMI zF`=&uxt8(`T{%x1`8`jz_8NJB?qFlHmtrql6XxfF#!G|X-f;pMWG|QH-_GD#)IT9> z`M{+W;qlN51{hFQ!x>(ysgaWZd0-l@?hR~v6~9BA5N z*;qk1_9?L(J4SRPe08Z0R(Lf}5@YK_p0TC;&JxsAcC1>hSvK3Ng*otAEzC@)j7+u@ z`3%VhbsH%M%7)U+`nA>Kr(vzqu^PO_c-Pz1rZRV~$Kn{&nt3AXI1PaR(Co#T>`1m6rM(Im0_sfP--~VDv9*yCi!|Ow-STB_LGWmWc>#o z=tXR2c`6r@0+$b%4cCVWP(*9O^ILsSJAkB0+&wc?tt9ndxgwE7U0Oy%GDrs=M-kpA z4d%C?uBiR}d(cP0)|T$i%LWS7j_rv~;DWGnJ^Xrz^;b9d*VLu4TZ|h!0r9}}N(t_xGBXyvYo99#tobs>r`)^QvB_SoEUll$E z0yt~QFrqoZH=T+J3TphX1U8N?w{qn7@xiP${qvt#ZzNN8WwMb$_-l46TLKL&XFqGU zMhI{lU77z|-4M3fjASvz=C)y95FQz;u( zfOVd`?9ri@2Y^`vWq3|pr=s;*@U+uSstOuuY~n)1#axtN<`~HCTJ0I< z-D|-g_%PeoT#jBE`EkB6#9>jKhmSQt;eajYz%6}fNG@dZixs}H*m^KD<1vtRFt}YL ze~n+g1$m+4Hf{@Dld>ZUyPp}9l62CC9?;UsxQITFq-bL^jw!arx+IGE3*jM;oxW2- z)-NLHoCPvB4-PKsEyVrL?gTLAV-0T-fCUg+FgTo#`2x&!A7_Erv~%>|VL}4Zd_)(C zTVOUB^oNXP6gnx&Gu6pBF* zVYfvY3kn=60uMdRHnVa&tPnnz$<;JH6YT`l=|YebgP1|Ha%bd*2+BYMe=O(lYujdUpPEo)dgS>Opw zGON#ONDyWHnsoWod>tQ@wmYy%D>a@%Q^Wy=LTZvyun;N}G?gKx@Fk>B*f|4%gDTn( z=$oMzV1T^+QNm(;2)K-j28h|?!eqV3v^@Sq=QIA4ht`a2B@t~rZ?f4xc`S%mS>?fh zUy=7>T>Yc}e-A_2z1b`*Y(ZhGEqz_SM6B~l$p{hy>E7ORlbkDg&+*UCpQ|#@R**?O z6P*w>=RpxNq857esHJCVVg93r{yo@{#iUgZFfSJSX=z>HH$e zQt_5wzV#OJB&XnvWTR(^n#w5{?5c@4u;ghO@h%=MxM!~xO>cug9|(}=kcpx*yz5lZ@A5;cI)K{-^X*L=}TYU(K` zl9lsIlf$Xv*TVh^7Q^@zK()rF;-}O%^!@#~;{%*Ot*uv%d z=;(hlH`= z)$yR;4peU@F5Ok{)&_qJ`58(}QQAVtx2c)7w*LX_HBTrTxfFu+66)VX^PB{8%`t{% z>Hc#HvQ=WcJ7{|_dG;)g3ob32z5S%{aZTbf&kewS_{anbI{^c z5XjD-&+zI{xkN-#JLj$)OtsK6g`{GwnreibyF?XgZFU(;KY##r%6R5)3NzIW4yv$e zNBSgd6n&hlEvjOZ-ks}pzaNF{m8i*j?V%JiqYyju9OF`)kc&EAS%sxfdx7w-p#O6C zC{U3BfevnLXjaHUP*UTDj&8XWwV1s5VU5cl8q$7)?v5Un5$}nj=U4Y0Zk8rkIDk0L+w%kfBhQgL@~u&vlza`OWJP zRb!f-t8?0AT;I=zYUrwLrvOfvnij@o+6Oo%6!e@J+D#u>$jf(8lGr}O>|&(D74#x% z(re60>OqHb+x~EJwmA+54WrajG%JvE_Z=~1r|=?Uc;Wm)^CJ)*mQOEn&~SA8aBCok9LW+vy(A#UX zgZ4`a$A^2PesRe@KEFLNb*+|nk9Ql zoQ_!TP471Y2|?H?@VYTYjLd9a4i_3kzc#fP-VI2zIo)VdJw5CJibGf7?6ZD7cepfx zO&#t0>sUDm!^g9yf|{tSl=(8&hWt3&5O*oO576Gr{TN&j`g{F>z5%9 z?h*o>VnR~W6UvuW{0ty3dvIm5&6$NaAnPw}9c+{$+ZQ-h2A!+u^%c6Ux-8u>gENum zst^7ZN6SykJ9UTccCv@(ybnxxj-s-28B#x0wnX? z^clUVNOd*!k|WFP^JpZ~!%dI0kN7ZFYPEZ@oVgklf3AcCoynlAL|2Hp5_{ z?d~i49L{M4{qc0#>khApnR+yRX@&Sp@U)>cP;^H3SluUdbpl;}(xY3zBcqqbMB4IytSOhFEqg3g%0>9#`~@r?m{6 zo_Lqq6s*feKhGP|+rbm+=*YkEnZn460sq8^T?T@t(~Xz%)Iu=AQ}H485YIf%Zbd;P zlA^af@rAHEDS_w=-k&Ehb2GgG=xyyYzxy&011pnz=Xoa2o$10_Dxk^K&3z?~rm#L zA`KlA$2)hr)npe|>@%bZPFEP3HuTLl?^Q$b-->(4dN+CdAcKw25KgjzE*_~79f8-x`3$Q!oq#QLYsgYN-OJUXh^}TQ zX}`mIy{i=3r6fjKnP31@Lu(fm%K~35kGpDldd~KZzfE?pzG6Q(>`jp^rVx5&89)$H zYT+RddXg$qspMn~zP2^4;jLVNkS=rKk%f-9tEauq?jL64UQkn$>_2hf+^g?gk0`f} zY8U3Vby!z)oMVPi+GaaI)W=nCyUo0*VQ3ohyTugN6Ea&&c%gw$GVi%md#Zc z4bO`>b0kXy7n^Ld$^o&A>vA=aWgP+KW(mK3Ug_n-`%YVyz1BB0yVH(RYTgQD-#|Gy zxOp*6imYUV94m_Cm7O(T_VDEW->$l|go{Z{0u96w>rLVCn2`v}c3&0`sQ-3!x71rB zyfK7=8>n-zngN=wlJ4b_g+=FM!2yo~;?e$x3Sd$JgpFPc#+W6ERXD&Cf^UcRhiHtfQuO{*P$8RwP-8ZJ2xkeKP$`X zRYWehX7&ISK6BpoN8qW_&pVtt+1y<|I+T5q%Dv*69#%6zz=x25fr71w(DuyZLsv%> z99xJ4Ko{Y{EPwUp%Yr}ukN-8G)akW8+=ri(Nu5y$hbiMAjx1~rVi*%*6bvDqc2m46 z$<91dYR!+fNlL2JSLj`lEG z-w#A)HzEiR`#di_nA%`|ONBg2KOm^AoZNftAvD*B&UYpa<*mUeC^ixzQ%UtS%-6)CBO~rK|OFIYW$=2Iyi;wwmj=eF~Rx6`vbWbZM zQY~J+x%V<9rKC>riVg4I$jVr8urw<@DQk_BJq(pEd5#{5<`aL zvS;AX#Fsx@t+!2X@#QpUgWKWCf2T>lCJoiP`V$~lb|Dl%i#f27OZ#)~f)dp=yvnmE zD7CY}i6H;WtOs56*Q{@DY;-n47(1?NSxS{zDt~H>fdvNbBFl~wE=q%zc$7|%E4aCU zZ|6lRUTX6>_5Ic*@miTMhd-JItfF)RDtv`YPu`D*{ECmR$s_up=Tz&Hcz^3v-npBp z+Iz@;7MQl%CU2-n9KZd;)g%AATMGSv`918=Cu42R4SYlh{fN!^y%fyDH`kMWCmW@& z)2%E;=_YK0eGXxb85mBGn@G1bhS*KYf~Y6{58VE~2esewY}#=D;U6EB1#_|vsAk>i zHOsJ(88}+#y4_Db{nhMg9GdSKR#m3qs!C-bbg-J|SoKnr#WT1f+^(fM4Pmyt-y}7 zHC4%zlzi^jBURy?>3dI!HzI&P7ard!`8qi(Eoeb>?p4ExdmAj-e|%q(usvg$)kxnX z@AqH566CFPI(&am@H8jbz@zD^?@uozgLE@nn}-&P5%>q;A0$0>XA{F=KWeDnS<%## z3H!w&&ae&aojO@L^ui1?i@sE<_9`y#=W5;3@jkr*OJf~lT zc{DzyBiW!}E#t=)U9!f}%{?FW39UT6}zV7H-&7EW&u7iMES{EUM2xZVCp?H6H)te|1M7*K+(?M`}$Mbx)9O1l+FgsRK;XJ2L@c9r9;k2V+V}qxu zj#M9Ein)tL35YPZ{^#K+Mtg2@uZIor*mfajLKK4hWxTC6 zz_%kPnVO4u0aUh?ZD!6&S!U|o?PS}}kez8UiR|v)FE95^H6_HKmG9G7W?mpw4^$8> zfus2u+0rhyoCcbVu0Qqo#YT%LD{DErm2|h;BL4nsJ)Lw#--AR<%m=w#LxFiPt+>#* z8&5QMdQ~#*X>#&>L3Hv(bw0MayNe7W8Dh53`8Ptn+_-Zs=+p9Q5SbNmARFxN7=u!f zX`{fd5&!a0{DX{E4oPd!+_|kaqo6zUsY|zyn5r&r9(|x71VKDURVSW@7ogt2(`>Hu z#{tygywn&ks5_n&i`_2fc|!*QpWhjdM5N+fKFO~nJC%Uo`WJhvd{s8<7&pnP2`?H` zck1cHHTbC^h2THRfeIR+lmderT+?e_hQVOnSIyzjc(Mm$<)EPUeU%I(#HHGlNRU(m zE5=-rT(Ce6;3BN|p10j_GtGsm)A7FdeScf02{??2q4`*>@k0$?AxcVC8EI^^G>eyZ zJiO1+G{@q3@c$&_rfEKx3~88o2aJChRho6^u7 zFn^OROmDgHW#ZyNqW2_BAy-zve{)_T=B3;wA(Vm^p7QG{AqYx$zSPT^1Z`RCXD&t^1~SoA5t*`&ZVbOTGwO?+#zki~!(YuYk3|2>CtqqO#14^G;~lzZt`a{54@COn-<&F$^{W&PJqgAWQp!1f$7pYuyDsNw&wmKE7V_7 zjHm2@e$MaXI-BgjYG|%a`rwAveO(+e5d(`)0ipxsom@`!7>~0b|0MlwXdf#@P=Phr zB4R3CQQ!$LIQ|%vMSBgov2F*pyn(-n2m^OE%u?mJ7Tb?yGa0aHFWrSa5LWrHZ91?S z?Nh!|-i&Xffe=No&IN!Zt0N)2VCnLRw9@JC?=a1BD)n;Yo!6a`V05;VRz*eIOg9ir z@=|*n-gB6S{j5UnWj$-KD;nf6e*WBEcNHaF>77r*NL0G(IVH(gdGDwlD z7UWKpgTRqqNEc&g`UfaW-(BvOv@q7xY}Do9)e84@>f>PY*M(Ve4P{(7F76a^vM1d5 zf)pZfUk9pWDdj+Lb=)%%+U>lU?8(Rog=e6k0s_8o&w)1?$g$L*V%4PRF(tX5FMfuE8${*x&d~oouwkcL}N_Ml* z;7i;eH=C13N=GzXf(E~8in%UV=C3WUOKs*jDz{rY|PvAr`9T)k*O3%&S7iw zT$~UzA?>{EZK3t#`}UlxRr5M{=h6n^BYyJTY@AKZ`g~5k=t-Tom4a)w$-)q}eTYudZ(Tuwu5VZY9GA-YJCo%?bx* z5sA{imCtEQ1TuIjPmZs57#@f#T}q*kikPyN@=v;XO2+@MjrOjr&(PV5RU)8w!$ErkZM#7&Auavx>{4fzRl zR(2Av0)6T82| zAdIx*H7f6Lb#;jvr6_`kFO>Zs8pihmUaFZ*Lm)dabl}LQ57u0ESy*iM19zS_R<49g zS|$x4;2(?s{tr6x`KY1ngP7ZRCt$abWpuJtXJ7sFf8+PO`KoVaaZG6|io2IN)SA1- zYZjs>tUnt{-obN1w6V-La-6LzYVX1yxkxp-FpA0;i+pdp0gL=Ye&YAOR8u@TUMDzr zNt4vUqq)EAft-hZmIB*x&Kazt0)D3fOR8=KQ3b9JCis<46mat{$ z6d)beIK=Fb4pENHoaA|cKm=y@S`^#~8Kf_gsywe$|8||Tcqkq$zgzk^m{~meK$^+b ziJt#0k`rzk;xXz|N&MgNGLN>7vOV_n7s}=R)z_?|zRG`~!R?KaZooIm?8keqUA9 z%t^S^v)wcUemhx}62mz$fE=Oe`S@z_V+YR;{f=V8VwD>+({HhN01FCK9>C2-#YZ@3 zE-(Xl^VM^2nd5(leeE}TRIl_`c_V0T2m$8%+Gw&qGl{M6h6>3I<)0fwGb|Ncm(kXssXb)a>3KQf?0?Mp)6(}Pr;5h> zqjV%91W4FG6Kn|&kEAFQEp7LJiRPV=a`QrM83~%5jpi<06VI>1m**70Y<48c>nn2F zwLm&I0i%m*7T_~@*ZHw){MIdJankOGH9z)oU7h9_Pze2JCZhOY<9d1#Ol0Mo0_sfq z0Y0y#kOuE_OCr#8+9?iB8*imxEG}7?@C6q?Ms3`gBy8s6+3a?&wF}ypC^D+G^6a0@ z;c*Kp?4V?&7ivv?Dk$Y7{}6{N4Lv^naa19EGge3kHXCheGT0>ud1(4*eMMyz)~(vr z8Stm;iusQy;-Nquhd4TiRPCRz!!xI-O&1Tbhbp#eW!Njloe6!Z7rcKnRMe^Oqz!BvT9d3(|{znd47vuZzeSQtf6ptI#ZWfQ55O)fWL768X)*Ya#v0CL28E zNwT#%gYH0)aeLMbCs>~vrZq5El+vE3wAMih(5m5_sZaKwS({lf1^6nwh@_xl3XoV? z(xkR+ZVyqYG-oL{wJ5Bvpl__>hbdVeiv0u89h_rGla*nVhJ@mMdKw}jYVryb6VoL_ zLw{5Rg^YZrcdR#hiG6&7RDp1SDDq}glj*{Cw7J{v?_F7Mv9bTN`q z-+I4#dN4YFtX=nhii-&urR7Q*0P5XxH!usrq?IV2JR zuQ3dhxlrpl`82{by%sFt&1S`d!Xm7SyEF;g(RjDA5zih+3&1w7XO|rdlB(#l)~nG?44=Q-^qeYj*+d3 zGY5~iT`?g@K2D{D`z?Q}IZ{LO9(1S6H_wLB+MZL)VbjbR_{IvApSWZ(OiHA4rhKiJ zt+=Ty7+tj|q4Le{b(ft=>sD52|CR)f<Cd}?YATLidA zr6cgv47^fOQi9T$^*AYbsq*v78OB`3l%YQ_FVtS~`dq^omf)3{n-QTEyh^75a8CBZ5jYnQpKGb)>A(!2y~ zUDi8ClEs5yGj+t<4s|s+x5OXlG>bcm!P)mMHjSQ|TU&lf&(Al|%1QD3TAb-yV!iV# zR{yDwqAYo(29=Dj93koJ(9ZAE<r?J9D4{VwoU`R*0jw*BzhPQUD{o`nPoqhwTr zyVoRr^X4W$I4LEJ?!2RIS1ggA=S2MP?6W+5__XlIk%HXMG!&wrxv}UyQ5s>6qL>H`q1}Fid|G>il%uHf!<%%w@NcJ2a^Ag8Kc@u|IefS`9&)cWU|uf zK|KP_Vhjy=ejHy3S4xEcvt-bM?Sm3rvg?d-n`~ieesg9j#~QcQkR5Y^KL(HLl7n}ILYKfu9Ko7OpI9jA6?L6dyZ-rne(i(Ebbw^({p}_ z#9-4?|K(4B7^n}(=E(v@C!9eq#**`Me+XX=8Lg%4wBSw}U8P1v@K}V|^T)#;h7=VW zTa6P0g|q?JktB9XK>Sl<^d8ieqL5XC72q2~Dll%tBVgA>t);~9@*GA7!BM5Y5Myq} z%rRCDBr5Z#*?EqR)XG#|C`kyFr~PK}fv>oK(<@jS5HycAjV!A-l{7DV?U#q7CSlwvfUvCC zA#k777nKB)HvU>=EJ@~4v<*DvEuE6Z5vz5P$B!SK&^5MIJZ|`9&9(JHLpwedzWG)7 z%?)H%pqZPm-z0tO|E^Ix=ITJQ3)uk1_OTd1(w4=L&`EC7l8Ne>Ol6<%yFPQI3VaB z=sGtizp(IrNmm)E`eG*6z);#RovbJA&y*FzHuhFWJOI66MuEl1#m?DZtR>`7SWaUr z?v84+viL~9Jj6kM5-d4Pkdfa1swuc^;-2JA zrHQ0RC_>5)rJm(-@#X4^(dqGi1{x;juGWPRH433w&d;*3dB0>CxZv3CCrihh+nXQ5 z_eZu~=ibys&&pCYv=05Oes_1II``hXNv#PB08nxpECBx#YC%Z|O^>JzJeps2uUCB4 z(D&$g9NZOEz{{XBYdJi$)%6cW*g8|mT#-LQ+I_q|eOg{bNHDh?Dd@R7pl`A=KI<^atAWM-qI=$);lgHF@-a;a${{tC_0-kW0Q z$QLpqGK{0pJ54p-lhL35epm9Xd2i{a$3Bmkq@Hg{vAg3y`5=}Yml|16SsUVS$*8gO zU=aZpalX`o+7~qjaFnf4J@bD`ZVR@jr&>Xp-pPmaJ*i3c zdo=Z-5r^wyfI1kuSOJOAPjlnaamF8mf@n&ZCFgSHBWW*f)Euw9(6nIc!DkO4*0WfY zxEPK-Ie;gxzM|*CXgAMNsu>lLh+N3|jKHC{LmyprT(BgPX&w6|h9_c>=NE3IBJ$xz zD?5$Nx^;%9K89%Yo$KzpfWrtnf%kK@&KU!TJ;}<799~PuLOut!$fr=)*)&HlDM@ZC z*^~_XW&&^BP>n>>jK_NA1YPi9#JO3@_cae!Ee`mw@CWT+mqH#}3V~$042EK|Rj`O; zNx$?Q8x+D;-k4o77f+l|7`rlR;Kk9Y))R65J#Z3ULiAY~)J&)$DPYD_RA`a)6^KAM z%!|)1CUX<-?5ZNQRn_ZT&Oftz{i-!^gs}4P9~3?K`{<+tkKD#Ka@IO&_woDg;sn{4 zx69J|z2C2Hx^?v>o~ucj(@74?u%3Jqs{w{4oR3LQ%*dKx(yh-i55wHtew@xV7Rv-? z;a8qAE=i;mbIi@BlFrm}XV8zVvOn}V2a%v}P@K1Gcwj{sn}VU_#|QjhN8c(n>JKdr z(y9hGMD#i@4?mscPKvuxzkV&?&VVru(tBp{BKw*m4a=3=%}#8^d`myx?BjU9`E6}& zhA;)(`kT-HY4wRLQ&y)y<`bg;0Fx1s!wGz6V4*>62aK^sHipn^G zj1cUT8kyCA)5NQgs?zI|Fcf-PjaP~i8J@vP4mmG9ivmz30zD2dLM9sxfyf|nUe>Qartc|ZM-x|$HYbrZ~KZEVS! zc+zqVqp4T>d)uD?>~$cjkTAfPx^Y)v`mIp&@K~7l9&VVC zPOi@2ww&k*7FSLJ-s3eBMKF+%VrcT=4o56xcrhU^Mf5&FA>fd*p>mA&4{em*&nJuh zK`L<*e=N@n;CKSp`Rrd&P5sV-Kf=9p)XM?5M3DhN;FiDP-v9$s4$XHNiGU zUw#EGcfFJQQ4XT+$HWspq2^-oDH6={>2};RwL0r5t~W#rpOtZ2=NosY>Dx+vvx7{u zF@(QO)NC0=@Zbg9t+qZ3W)<6xun-?0K%s$D)P^R6XHb9cJ-wa^?^9sXo$d54(S;#c zpEV`)xYDc#=U(a64dH1m5hh-RjggtRUyhi2%>kjVeyq5{ z1+e)r+P?2z9yt%+<@fW1;BZ&vwg_K?gF7$Kcu`QO$!N-md`0Qa_*{8q^M!{RokJuH znX6i5-|(Ji2+6qlY25XfI7Ku6EUhYQxUFQce>aFR7A_+nzb;=cS-#(EDfu=*4~-v{ zA6>s`c651Ll#RhsMG5@S4T{62=%&vkxuAZoN;{aADF%3+wXbVe-;qp*TYmN|o$S^H z&CaslGui2W?Hyq29iqB%_kRy@tB-y^&R}!=YCgg39|GyI0UTXZ_GDR(43dKIz4QrK z+3!|gWA27AP#f_ z1h?&gR|}m=Hfbhyg5e^X=zyQ4avlx+L(SV1@$;S*cuqUsh%PjBuX%d%VN(P%NL*GQ zyA%~@7XV^7rZ5c-_p1DVM16NWmHq$!WrmD%LPo+lN>SltDo)}xh~Mi)}b za1>cFO&__>gSqw`il~CI1mXPpU;K^?+eF<~5_iZX+S=n4ey+(71}cxzdc6FkW<{3z zZ)hdawYAxO!yuZ}t_mm!N-9QNW8XYFY^{N81d&9?MUTq%{z0i|hP<{G44!!FjeK|> zLDCkB*2}gfWD^C2>4MCOu?_}B@r&V}e4mexDp^*?%tSkfihFey^uLwfDxhm>K+pX= zHxkkw5kolhc;ni9?hpB|t4nO6U&lK(#NZB^yn!#|-fm1sP}R8p?@nO`cW*^2Z=gdJ(L$4vA zjIGAQ6_XEtw^OaQ_VA63hQEyq@ZAz*5_lCpY&cYWxsy+!%Joljbp=EvYrbl&v*Y?4o=UC10(a5F?2xg4aG^D{Q_vq6{ z)#`Bv0fXwPQ5=?0jn96B1_R~mi)#txF{cwONZkt=<1pS%ex-Pk=>US1_=4{CUfIi z<-g070`jt!20@EOrU^rmF?R?T9K_ud^Kk>WBY$49{q$0+*+KOz@ie?b?c7)`7d>uD z%KYfSiS6KV&BdY8&E5a~)vuqpo9ldC*a*Sz!78$1l@d^CY-%|a2ihFLF`o9RxZYW2 zB*flk8HKos1Tshh5jgl9><1!^N?#j2bAiy3SBRzLgPGCn2Gw`*+-sXkkF*okh;BcE zMH&8XS~TKwqXvAH8Z#-nQR+B4e`J??CJEE4_O-#^**kFNvzUur*xvVf`5ZW0{3;ix zcoXOR+qm&hS=-jt^(GD9$b3YyV;R%;H?-&r0VMyK&zH((_lO@%zg5Ib!5;GMQEy~+ zG(V?okY5Y;?F+>jfKrwJ)pb^wip0suJOk@SWY(nry&`L!qOM6(QpgF_aa7{fN8+!B&beSzI%KEU z=dY(~VU`3=iRj%@f4KdYo>J+7txQ`kKYD8l(le>3<4b4;(znpTg;Ij`&^J;dzCwso zDT*uF#Dz85{>>23LIFQlu|uH%J*4n8I8ywe!pFXA!}=>QBTY~J<7Q`tOA{z!~&!?~-1xz@cdiC_jdqO^5DwYiD@)@fZ zBQmu7j|2&QgP_8u&nELo3VqHJeU%E$zytfv#i<}XLH(Tq#(#ajwuNwG{pX##j=6gK_0J!Qg>3sikb@L?S%pPVSmi$8+_5s!dZ&Oia{v3ex_vu~g^xod&i)+#W1?>ffU`#<}-B zT4_V%8pzFe8Rz_Y67}W%y>2Y@_DtB-+!*6()NIrocYM0dMNSBq-gzU<@Kh{r-juP^P>>m~c#MugQCL~Z&hQq>nPLx5dwk-%% zm4i=A4Ae>zm6fpw4>*A@;IgPS*9AYG9pv9Zx2k-76Z0IFxC?>>WYas_mL_kHK77nB z#PS~G?~i0&Una2?Jt6;e3%zZD%8`NkP);XUgR6nTLZeR z!C;6k>TTe3)$(rfZn157dJ(UVuDjA}g+T#jyN#fDb#g()+kFM(J|t=ulqi%D+;gSt zj6rGtts{JFgm3lKi+&@XolF0FK<^ASEh^@LVgAIp>ZbPOriUVn$2Q-w^GO%82UH>4 zI9prI+U^9a$eS1Oqp#Ok_51XJ4FNzu?^W4w^)W-rb9w~UZcBX_<8`H_qzgKQ;D_mg{?yz>Kz2^)fY9@+YFaOa4bzUGhXsxtPY32k zA7ms@k^R!0-Bk;6*oej3uA-j{8Hp!YRA~SFn zWh6c?p4X6~!~2wnvYtg`lSWbXZ8=|S&EqqoHXtKswkNsFsV1%IlaN%f0|8VH*`JRL z7N?~0ioYRiZca&a;aTKvVyXXJJ!7A`6uOEZDDRrTkWJ6|B{Ul?o1|<{avQJYCy*GDtnNO`(zt`PL}R-SYz;u;Yvo#*)3Z-0Cf9V`5?B z#e7OXA+Fj2^3r~v|YaSh~brNHu(IvNJzwm zzgw@w5e!R)$--iQB=Bz$Ks_;_64P}UY&aBer|X)Jm0Z-O#KbsLzK-+teaGf(Git_8R3(`u{Nloup= zbF2wNI(JczmB&+PA)UMM0^nTKN#gQ40gxoi$QLoc#rP*v4F-%ZjxQKqBswe_+S_Z! zxo=+2V%0I_O~2T|vvWA{@4m#<#ZhctH!DmJzw2>+Nxwk+Ji38bLI{2bYhM87t6xuH zGLL^hj7PdY?(B3Jvdd3RR_VEaoCni2HhQ`nHJ1uN9i}X#Gn|T#+ZaNX-6(9}gEAI_&SJW)la^U`+#!&5h zL4cG3kPmyTps?ZMv(9onzWFAE-he-G7}}bVUthVp(2aq}hTwa@WMseW%+vcR)HHB) zB#76b`qso3#%=dciHQl4JvkY?L(wqJUi5oVF7JU*U&hDFPw(7T0^PeX23dn(m2sGC zVuHl;m=?O{-(hTeG>kZ|eCjmOvtbJ*i{G>AV>t~%G*Ce}1>mIf`eG9Hp{qHpLDxah^J1f3#IM9|f^vi5PT?^l2bW+8=8%u@uXDKU1<5{9$NQ$gr zP?k=uixoRRn@Y(U^z1}O0(@WRrOT; z7osC7v=vUBL1kRBo{n+lO?a|>7BWxw-`G~Z&y3hoI?BJck${mI+Q53LimLLT+Q~}3 z4{>IMft&^&ml>Fj2IfXm3<2;iZDsn>J%T!_NnBM^I+~?Ar49u~zyfFzUkqTCKRtH& zl`*A}aSr0Ykjx=ST^wTO`jkbK5d6eB+H=SK@+x~}0b@XNvmb%G2uDy-P`{vVXbI5W zIycYZ`NZ^?4mldgyt*`U&9r9s!mqvd8it}y#$WMANr16=(LZ#^^mnNg^L5Rk;0rFw0TN3zW8GH<#q4|opuYf zeXidkX;ReL338)AT$Fu2v3=dI+Eg^Ym2?@z+&Wyc z|7Axd%pcSrN$JYZ4C=)YA9iC_R#YdeqkNanA>jsb1AHXkJW9ydcUrpq%!#9|zq8(> zAGw#R%`!4quEy#h&*={FX5ibVzJ^|NYJ?>WEZ>X}dzyCJYYQ5$>m5GBh*33kr=f{9 zT&!wa@fwg!LL2K0eqytntnJ!AoFa3w9oWBHIT&~@s9+i(_cr6gneEvCrj@U8TSnQD zk-^FuwRsS+5129lyar0ad%@CRc`NWA0{Ah9mOZM6?FhmPJ>~epq!pIQ`q$eqF9XUU_6%P*($2QaH5fQ$6A+jJF#q9dYcpu5g!jcyPN` zA=)Cx4ha+nf)9ht1sATwB4!hcrOiQE$iwZT-`-gFReCY;3Nvk%Y#gqo*IjVs{EFJQ z3DLKFmNlxr3KO(ePlGVD|J)WLa{sdy-JbGhC~a9xTwD?xznG_qreRD5t*x)Lf6BU? zyFVMoekCc z%aM6%BoQKnIAKU}+Al$N-FocNRx;IzTH3i5JXS7TPEL)(uJo>+FRQ;> z=onp5RrMX9p=UHcd;RHLr_9^B`2-Q&`OML@a}}IIh*HBwt~8ci3b<#$MO4KkR$CGV zUu}=4GGqIzhB%3)II@u=hpV-1)0 zPECqmsWdoHaNt%h(^NaBd`_ib{8;l!i@ffxZB;;LXOj~#U6kwpe#!@QCWvoFEUhHJ zebBBEcw9Zpy8YY=sJ#CeZw27_+?*1z!hI)B8@|y$lVL9@$V>qp%B2ZGt=+TBW7X}Ovc6f9n1~1pzPtJ+XvM+|3m3~h*lHi@nP*c0Je9go zW38$39V{Qa`!liltTo3MX4yUWu&PRZtS<#=zl+l|iwsSan{@_@!v6Qs#-vQI;8(n= zM?{+!<-zU3-1AV-vu}{kb4lQ3k#qHEob@k{`Z7>nWFe~O_0r18kN;|t!8e0GJNpq9 zJ z(2F;M|0KbNVZzVppE)%<&*nn=&Y=Ke1V;2)2EiPL!u#2ytRRe3>*x+lsq^)U>)Z4y z`5MNefQ10c^aG(o)ImejOHujBKARfKqV4jZn;wBr{wl9-%B8?Wu{0_S=l_cw%!ldzJ-#aT~oX}ms046Bo)bD5DC}#}G zS|~^f#NK-AS6(G@8cSqVhN4t0C6?8cl)e!%f~(Ns~aCOZt*^7HLA%S$1Y5b}g4BcE#rrlkKCNm9y^qeGC{mQx5# zQ=-6Vhf|`%l`8fe8}8|J3x(I*c|#A8PUVilIQ-_W>OY-|<~TH>(z~kqo#Y5g1bnEz zbOuEL?BgQ!3rvJi@it11^J^F%`du%`TXY;Y)rfu?%J$^U+eB8yM0SEk0YM7R&w#Q7 z9RW7?x2Blk2Uk`se=`Ia@EN^2mMRyW45Ta?a~&`GJI>CA$f|uG5h%GQ=%Vpcg1P<` zh-ypIx^Us_)e~s6naKWCl5Fe;jZ4*+DONJOnpylX;!SLp9t1Ff1D$QixzSMhl41{03ZMNq%vm<-S8upo!Zv>R+AUnJ7BQ<-= z6y-0!oPzN$HA{*ASfw3Q(3+e*H~A#9=7W~&xM%Rc^SM)0e9OW>=m`!g@bsLH0YF&p zFF!fO)Q&N~b>I+PSz=dKmle=ehkp=f(J;`Hr0tOX{9Ry+Yc=HHCl#+J@ zGHnymI%a!hn7p}vb6UA|E$AB&*lWK(mwi=-6Jps#v(?f?(+`|2=_;b4fb6cMo}FiL z<626i-dL;_M+aPejeHf4gh4@7T@zfP{pYJ_PFbPN9ZK8JP$bdijoqZ=cU7hYX}O$D zuavoUG0~tu5zLO9%`xKqz51ZE$PTWH8ZmSj^hPLgy6A-pUoC2_x?=ea#VFehQzAY} z#txAC&NsF}jM%p4Xh?}E$@fL+jC+>0ha9sX{a#+g4QJ&@R1R>OtIO_R z&U2bRQ`v+>Ue(pGO=$uKbLVd=UrfSKp@2pd1APfF(r&I%q;DV-qTsL$iEOEl)th=(|}=h6W?(+du-H$Q3Sav#xlFvH>L;n--? z>eXqw@|Rk7IN~AbB#(|pk4zef83z1WlSP~C86^iDJCoMZ7zaYOdOhbW^~&nybmf2zBhLxCBAUwq3C~)sK`OYv@qyV4e1$40cVJ)lBd|1|hIY0@&L4*o z2O09wbL+`C5%u$wHVr(J@)!8g5}`T8WKx`tk-e}Tx22NcT>=3wA$D(iytYnF#flEi zNW1N9EG_>_3R6=J(LJQK6DANAeJV$;)A&^tQ<*XU{Y(_R_6J(El_$KYm8dx?-BKU1 zyGyrohKPoYq<3H2ZUedkS1s9WHm#nWnR!12O(8*>9IZ0+lMcr3 z>J@ajwCG+@I21xBo68CMgwV`w8RPp~F_Z`6ghV>f-wV~Uvd(#u%HCf;)@83jUchV& zuZY&pF23e5=$QRip_S2Gde5u6OM5cw{^Z22|ME-C6pevlNh2`x;C8l_@0s~;VtI!} zsi5e@b+M@wE5?QxOU_)OM(PY|n5hQi()-(DXh={C9B(UJFc*-Bzlj1kA|}`Qn{0A0 zK7=6zDQwAlCA*OLh^+awmJtKCJGNR*q1gtsY_3HMs?ky0Mq$*urZ>LXRLU#$R@I!y z^}*W=^-7Z$&>Eg+=dp6=~*R8EIc1NtvmO5CWnBPv?at9M@ZOk z1E?%_n1~?l<157R!3ku2G7^c7aka_e)MX5=jEI+0`xI+P)--heS};1cwiskGuzznN zi?7ZstlxLo`S=d6Vv_df=}lhGs==i(Hq-P)u)X<9{U;CLUl2Icaa{?`aqoJ1XW;gB z;PJ*rZ}=4^^gC^~C5nupXJrdMNuwylIS#__yImcxadj0bBG7V4P+^sMkjVTGNo3e} zjA6kLX>?{O#9^F<#COH)3gB#Ct zR#b&@X>;I-x6KDS_P?f-&=fFwYYxk+*rln4@5H?1GZ7Jyy@O;>x8h*(OmVdf=C^5D z>QGHc!@!z2hv}<+)mzngyZpm5du` z)J*`+zv$W7a04*((Q5Mg?(!d4bF|8Pea27WW&OB_*~|Lm70!i8J^wWimR#O5TiQ{H zU(Ft?kym8{|Z7OJ<2iFn6FLp#Y&g<`?urc;IY z`s|(uxA$h`PChE!e99ulD`P~n9d?SiJlfF6Qq2J*tc-{ef5p??${qJ3%$>M zMJ#A(sbee|H!?zLXvs!OCfyQEDK6t;ou52yAXx2{yB;?4!J^Q=!%z+Fb;UeDbqg+g zB+q(FeR57p7--B-QNO#-7Oc)Hb}_qTVbNSy5-l)jOSja~pF!J=Xg41A;Yd(oSZPf(ijzfK>@w0d#3}qhK*Vw zw!RY*D;FS0os;rq{bPmH=6N>PFR&60Pl(Qw6yfH)w9ptogG|r?Vm>l(Lrl9=w7c3r zk1*vd;Mp=N-*;Ym-1$o(;)y!O^b)CN<@lGhOD*hcK3k>J#flanLS+3r!A4YviV&JB z3^lH7`YEJp<$9-q0>hnfcLNzQRG-c_eX{#V>EufQNdc!%HgVw-yTUfis!fF%K?*H> zC~j{zqZ;->t)0A340OC?a+TwR(sA<_(^spr3xnO}H=__AS|9WclDl7VnT%U-R0i;L z>`3m^`ButuxMF@C03~dhlXmX91oQq(OH135%}U|5f#m@st4Y{DdWQCkr1tfy%eM>I zVOEia75+sSudwM{LGCTrb%W6In(I^Ok|z+WV9o*hMsV69_nuWg^oUS_IvPKth>G_SaMuB^*-FGRK3v zQ;0dVu76j(p#j=(J^hn5C*#P=k9^o{793$21;HqD*|_rGFS;ZT>9^^%YX~h?T`t@G zJyAcsYhc$S*uUtW$e|pCO0eYzWs~Z906t2f!v}NYG`-E00yoag>0Y`9fWzSt5{&Ie zdo9L}iVDeCM##@fVVS+xQ2Zf-}C4=+%+=EykGJV=I^H@(nY5Z&bnXL;Pf- zN)$aj^%@R`AK5D)FW9>R@XMI<)3J%3>t_p>k%)v>>U!-4>^H0NUzch` zJw-L48dEH{5X{@xoF)TU{pVs5E6)gqkg{U&d6m`&E*YNx_|+Y+Nw|sYR>%Y#Zr+!SbtWWV|R^Z@uS^@ z*@|2yDs)aG2Y4G?Wmdu!)@c61n#tpx23i830L=YLGM+-2(W1p9g#m)sP3OscP|N28 z5hHC&i%$!9+#-16m7kFjYNO2fBZXZ$(u7XWCEbpQ)|^G<2%d8Gyl3uK?m zYRbNp)s}r3Y~^`+nRk|KD6XqK34^xoGCr}HJont}V_K!rt7{ftfSjzFjx~WwAUd&+ zJmYYM;7B-~PsHAiO3(mTQj_iXFGH*X+orbW!Z+fDTF)Rw-Gc~vPrGy|8&hKOFNBz_V*3& z0qakC+9)hs5Dd~o++mm)%52W3N_7s`_T@$%a5JW)!>z6^4jN>~IgEVMPbx8s#`v95 zIB#zv9GMVJuSe|Fd>7ekLVj!Sc*^7Mb9Elsy^Y8>GJf|mEzMn}ba;^q4!p&jxGOtOj+_NW{I z=|kt7xDtexo!KxN}1XMcE|1nhMUnMUdgJ}w`t1lW2h}bPt=)Du4lfV6fe||2%=`YD5jPJQ$g}e zVs#-0!eziQ+K+oFq}KTC_w61uv=MF6}mrX&iuw$+PiJ%D(gg6ygUONT$9fR}vB zDErg;HVJ1Fc!uu_oX<*KAYMwZUpMaNn1t{v5Tjswum2%|C=v>C`#&a^uU=&-)bbuH%3l^GeXK+%(OGaeU%!tv>F>KuXEVy+T@ljJ zxRisKnGKsOiR@TgYfnvE$X&FY8G$dqIscr>jP~!H<|Oay1Q}1k`z|Qfl=}&W;@N3-oJLmKlYFqnO7o+AGjjt5{bH-`_Ly|;DcuvuU3|sqq+ExQbLSn4yw^M#f8^6vi>$g z{@LzaRjn({@t2cK)pxqS685FG7s5Q8`m)-8h5h_PS?=_Q9yWSaH=EHoov-==?yILf ztAQ+F_{k<-Hi+x-c#13LRv%-Kaz-ssGy)VF>$FZ491;hXr0TT~qO}n%Z|L*8H3;j# z5vadNHjLG`8ya4sVx<4dSQnHaBt|n?%hsYsk@$)#m#rDq*kW!Ti9s|X!lG((#(S7D zNqyZ(FdDQ(z0N`@_QLHgx`lKlGkoCinH@UO$X7>!Be}+v#phA*eRBpx1RVwFZbUW8 zOr_{Dr`7Pw1tY|oVO)u@K1_0+@KtAXA#s-?_fYrM(-fbev zWJSkBY*?1l(PA>$U9t4gb?bHXI`;6}3h~*I*Y&2(+GfQkXN#mMcd~1)6^$LtuI(M# zC`zgA?WGyRigN`N<_hR7;JIk(0G{rSEUYmO4&Lb=nId&fnMjG+Ga> zgZZklrNLw!4zFz0v)3%?EsY&al41R&APF!n0(lVpM%|1-36>0qW=;WMLPLdd0xdy| z6%zEk#1Y;)Pw~hK6l<70?jN*^RdBJ@zkS8%SC5sA_}a05s5ZK=d5DU)Vl|c?jaEY5 zd^xq^AXr!iH$FF{8y>H?L$|-7#y??<99tOiDaBiLm_^ExhR{RN-w7*&nRUxrxv`>Yfw-UeyI*>NnL zodD5aajC!yiz6~CF)}ZmKt3T4;6?etJCVy>0D!Kryg7+ z$Cu<5Qu*(lLHRontV^~KzaVEWYS6&)JA$uOEZ}j+iGcLKn3!P3OFmw13J9%gC@#)k zX$&+{STqJG3tOkX)10n75Igl&+HGAX$C*J0MRV@7IEtUSEngoSY>@!UX;?swsON0Y znJ?p1k-VCT^YaHAefP|s_vG1tXT#zk8n14PRbsNZG*s!iS`&DDH?8-kh|2 z7lg96(mX}uHt0mKluuK1wdmmyV$(}KmwF^fnRyrPt8~zz8`SGy#x@cxveY8PQODLz zxw0HI1uCXnuifeWc7mZjSRTGzFACg?cd9wu0`E(~SftEh=)kWxk-z3*wcJ`|?Z1v5 zSLl$h|H4Irl!MU#_)@MG35!LkbbO5;12(mllMjbgljwuk;4mzv5n5Atg_@cGPu~N# zG=Q)rxuk*hED3jU8pu0yLAxiWclxRk0puZF)x#_J<8x9#)`IK<7Lw_fT96VVEWr{3 ztV`j}$_+ZDgv+BRcls#S!|c~kyq-97n+4{dqiXPI^4@quYw66cW*Lnd<7oTG$Z6KIC01PFy}^YU8==a91eXxTt@7Rk2s6j`VIuWn^+% znb{BVcjQpuhcv*t(Wg_izFY|;$bkVO#FS282B;vC3X|1c36u}U5y&6aRX4idOUC99 z67l&#bhsdm{&3FU;8FW@LV}U%gh$r%6j$yO%y3wet*)&wlF&neVrg|*?OPCPJ zW~*vwi@ibAl_A07;oKgs>-$u6LdDwc3Hdm2<1_r_Q+YscvUY$Bg{epYO0bkbWGj;1 zF&I1&0UF}V)>jC5l9qJQDNmJI;--Ba@MVuzI{9|0|IWzXZ|w+VL7pk6MDS!wI<5K>)S;~0f+G*D zZP-i_>Ke=ZDA!F_`DaGTs&_^nbB8Af3s9-DcUdeIrT8a-k0-!F zQvrDMMfWtP9Jv?urG-G3&_6^3x^Q2NPM@7%_WLsLv{|EEg_4<1^w}})24F+(-z;r2 zDo`CvFlaS3_H;Gx6)dVSKs!X-c@oxYAD9!F7 z*Qa=tcUX>ljwN1DWuSC{c_$7q+7AX@y(T6a>6ogOLm2X?HO%h^*_l&jsNcMgu8o%M zl40}=j(~B(+*X6iT{tG69X=2W!!=p_FBz6Ivn0p7fjX$eX*2x{iB*)Xb~xl5?Tr4= zAM+>shnx`1Y>#bQy;6hBsy3IX{=YJwxl39bQPX1v4F5-A$TO&CU19IVuS> zL=6X#^E#kE>7f$-A^CaFk9}qkm(awi(jr@#Udfkg?D{i6%Z5M?!F1o~|1m&imzVwX zhWswr=_RKncyA!Xof}qXq(=z2f8*%lHRti$|K0v3c;B~W#1P0DXnA^0S`HkqS`o*_ z151p_q1=wd13E;n;jDK+z~{F0Ogq_G3(gc1P8GLq8x0Fikf7xN-V+&5v~|#lcmF&p zQnu?+F#`P7Bm$087bEM;uO#+|bqH3O`*Jr2a^cA1M@qN;Fk%!fHjdmR&uCH(U7{$|I!g;J1g1+lD=(Vl5QBh(0$Ws=! z4%um;es$R;S-BRH8&cDtVM=STkY*F25y5#w)U(p?rnaIp(kQis}UU% zBXFvh)JKXajrl3Tgf4XeeszQxic(m-%G))q2}7MpqXgFk93q22MVfJ4}yP+O~uf8o3yU4yQgt%R>0pm^Q@MAsa9MWJB%~}-vaYr z@GorNWgszXg(@H|rx=s~OIl^l{qD1~*)sn9kbgq$^`%o2^;%B~te>^4^geHM)c^RTGV*@e+3cW}bqC<=0iHR6XT>w^ z4@}2by%3Xqx(eZw%TM=vfN0Ch+~HL}eTo`VIA{i=Bkn+O90G9m0yi6re+tK9*GO!P zvC9xvk+-N9EB8(^*WmgW?FQ*X!fJc)fBp(Tk-Wq_P{`E`3t>fCw$zUYBy@}nX(Yxs zwlz7QvtfBP$pRMyK>i;q-RHf9f-(~pGao#No!n+?%t>k0IIT)Hu zzJBw5jwxS9%9#a^v^>e$x2mw%6>+>`K2GtYF++hgZU&NS$iJ+lPp$_=T@PXeg zpM(p%k>D5P{!7RS=>>^*)lNug{S<>HfqG~fxTQ3E{gU+1b|6{C&~C)e{z?O1z2v2$>kCnH{lO$tKoX|H@@_;KjZ_ zbZ!zhDW>&PW(CD=?_g>ffm#VZ3e(08q=HN$7J2{{Ded;v*wMa&QhPVG8~J< z9bY}z%le9LmVYzn$jef+wEFm^JGSg9MQw2`>9oYUNK|FyektMB6`~}Z-IL<*AK7mQ zLBfM)PIb3M(XCPrK|s4r`W_n3)6#dH0z(n4qak!tOoFJ7M!(Z2V4|q{(Ic+`@jbW^ zI0cXd`Tqe5GHVs%haQwXPp`iapd=fno|$-0qdN_Q-rmyn9|`g-msJH}rU}=}!{(^N zJ6y^G+x1F8C&b%0LBdHVR`+ctsC>k+wYb+18x|o0JK=KX%DsW!{!0_4?`{dzc>Ama zwNuP%mI!=H(c_Z629yfe2QgMH5dMFi5yjf zOpvT#+2==uL@w4!jo3>9gjSzQkJ+#CRm-jZUpQ4dyg`k*Tw{!Kl=>Wlo@g8T?p-V# zyQx~`)gn&)B&HkCZfR+w?_$XA?ksNb2~bd($XM5YEh+MunzscMWPFnn-kG~zv+o(W zQ$Kb%BB6=LccW>>1+LbKQiJB+WzbkOzX{j2<@M02zLx2~>|}#zNNEPs7mqPw$ZAWi zG2+mOogGU}7p&~YAe^_iygpSY_o>*!s@t%j()-HdLPIBK)-#J;w>j;f_r_wV0<(73 z75{_;$gC}n3qKFy)J=LSVGOK`hh>3#U={We3NYco(mc^O63Ql1LOn83 zD!fhCHS2e;hbiF+r6dR7do7Be9a<*6zb%v<0i*gT+E~DHHbFgOO+x-qJMj1ql+KrP z-S(5aL79UQnRw#v`f*}Ddl8s=lvstbC2V;@@_^&0Xe=OBw~*Meo{0>_vBAFM@z9F%73C(($P}mm2 z2@)E51Jpm1ICC`}n>MR9+b% z!#8DGE2GY0M)@C=P&hGnU!niH22ZK`rEGOp_VbxB-D1ofM< z{Z6L0J8F#>;FKAv9Gg>p(Mn#p;5)nN}CR-N_32I5tv!5_$mSqNLJxjx( z=&qF`HKg?%7Tay-pxJwN-P4UvrMB5j7Aa^ED|*dh$L-37{wQs ze^?=iQ~95`X<%?3B3*UWh{)5{`#iceTX+5wUplf|n9sEO~?6^$4BI2mFP4+zVu%S_0cBvgyFP30Xzy!H!)hEb)KyX`P z2fmfY5h_eif5{pE>>tzL0f5Hsnh+X22z>mGL#0<*zhH#2f&X10-L<3eXex|Ww6fK| z_{$P1WUuUqai!qVr;aqYPK>z9xeuma*CJlmrdWRSZjtrn4T6a8v5_Irf=Fu#t6*Dg zkP1c!M%x_*4#E7x0*=Q@gi++x*%UG$H*Q#2=D)>y2T-)@#OCo&I7+V!2K1 zu5m=7`j7?)6&R9=Klm+QkZ%-Pc_U9doNQ=kZ{CDM&y`y48+}jJY;tZ%;Y*ECou2bQ^L)(0}m$PVj1v`A9+{>%H{^V(wo^OuWH?f^dI6-Ib|QIu(gU&w(`kCd&#FeTYqMT`6r%JrL zb|&$vSY3^Jv7M4h|9c8*c$+^_td#tS3`rqmAEwD!>`j6f=Nom<+mVpdBQ$+Ev(-?C z`>BN-z&&~*5**6_>4>!a#sy22xodAgR@I|?Qy`7HOIY@(tOjtfV1dA$|ZlA2Hl(}#R*To1+#I-N^R0ixXr;k<#ZXfP@S{G<0QMk2=5Z!?oz>dHW z6vZG&h;>*;zF2&0mR1D3*EJ)K@vYVdGegT{yW2v~eLphLU!$2_zu1eKH0Am=Hf7knRv$<7sC9^8tKC z8~L}3$`TTH9!1VMeD*&++#Ulj>(f_@Zadd8iVw9nm$@6oS(||FB;cpX#)I-BR`H6& z7E)oh-dGmE`8AXAq>{OpseT=RhjLCZeif4d)RG~FtI`!e$_>&7r)z~~Ex6_Te5)$~ zQK9hbnGcAnpsL~WIFAP**aiaeU+DHWmkjz(}WEHAdk7(PQw36b;=yrL{L>!YxD!qe^e1ig7mFhd$?qzLe z>YlC7*iQTxzfsmMjy>$V2)$V0{ZL`0Xi^^&3{*?W+|=rV3g+||9MX#VftJ70v}UwW-0VE73A71WkX}% ztpUapnl;Mqm-ZfKcT)dO8QwSAM8w%CXJbHpXim?rn}TL;%o{hO4#8Brh!s~&_0JtE zUn0|3emnzG8uzEoA43e2^GR5C zB+h!%_}lxFjzL2iZs+N(X4u}iqS4tgI;EDDQEZ&~>54LH?9qq6u~_W8J_i#xV;vnV zr2)~brRV!&#koJ5QT9GgWe7HsyZt$H&~}>CPgGfN_7bec3-e%g1<@}iAjmT5XgJ8 zf=XNayO~?UHF#P+7fn$H}TM$8IkL@ zecE&W-F{skBUNJxr8tS5y;fp#R3qMpO`PKKAq_v|*74NWq$rF=tphbXCzzlurbJWQz_asx|fUu1(FWvi=aOV-N2CL=T134p0i1Lg|_85{uUFfy?u9RV&cf>NVrf_RD-&_ z<;cn3N3#V)8#*=_X72=GL1Vg0(c5dl4c&yy^-DE1Wnf5tL%NUTNOd#?)b4xnX^`WY zCUrKewe=GqrX^bUh30*Oc%4gdSahdPLL%iTpYM5SHR5}#$uCh@6x;9)mCuCgyAhDf zH*J{{tP&YPZ=Ww>g0C0Ve+CMjNc6>SjS)Mc)zRvj|HspL$5Z|O|NoG2 zNF1Z66z7Pdtc>h=MD{w$LD}LMak9zCI3yw&$ChIp9c3J{$*RokO^K82Bq98+KJUIi z{n<_3&g;Cc>v~?#=i_mISmva9PiW78{u?zLuecYKH4(zZ@K*liPLGb>DO1&94%pe4 zbTw;R$!*h@FyVMjk7m^*OOYFrKSa7TmE~TCypp?kWAAqR$`GjC`z~(< z$hU{cbN+b!4>aNQPDd~YXB-z-IzAE8v#Qit+@kWv)(G_}CC@>)H5r-S)n& zpUTrs@~9nuLsZR0a$nmeMmTRC{c_7X`4lojg%}G3dn)S*LNZP!io=c({s7vODBJ$b z_@m$==tIvCr*t)l2Bs+$AaZH&*zCLsgPmw-!}P+J=Aj*-5%$1ZG=I$tgQQs zkVTl)BY?l3s=kHk>ETGTyw9h>IsfB#kt1DqMKVd-$tae{W(~;gKO1NGc=Jmi$Ymr$ zS_9QZI`oj@4{kW!MoAzL%t%){WU{e9zHx?$D(Kg@(Lb7h@_(nY>PSJ%HZ00hS9TBA zDw$OXz5!1zFDCI$nSx9;$)Qo?2nf5-4Q5zd`39q=j(uP4K2=vsUsB@2j-|Lmt|L#} zjO#gqw%&^E=>e@wZd;sSQD*dCTfV*>_|x``o;mDIU`F$+^4@Bo2SI-X*b>1Eoomxu zI#b*i=It$=XP2dt1ZjlW6vSqXt%185-NmPa@`P*^4;rymGce z1Bo!eJ76u}*NrO1mk=%5>z~T54(m`dsRL$c8(uud2@+t`yaAPb5i0E>0iTn2f-h^{ z+|u~}#>EaBr+Wx%kiPk&@5Lnnwf{l%)*Wx@y4y3%U!~lA@Cz1+>-)i;I4Hl2UvFz!CJ zR=?4FuwK96F^0jM%DP0wtCy{;aJ+o)Xz}oXh2)}rf}M|=nk{9K#3n)s?!c(KN8SySU!h=EBp?O4Kp!Dcr-5vZC`GiHLU`b%!-}**m;NlR)ZCksze0a<`{X|YGWN56%fk>6F_lZRisXiepOeOve6D<%@#nQ4 z&k{R8*EZWL>8a?p+q)ooUs;6sOEnE$ZuIfUZMx?aW_y{ZXC+`N#dxJIWl#F`_BC?# zBtTy-+$X&-4ytQ?QFeF<83~;cxkmYu>KE+I#q~2PJi`$v>_BT+QBe_8^EM!1Zgd(( zE|$IlBr@@LFEii*tz3FOH-8g*}{2e&Q6HgxXHv4kqV_1|0Q4{Z=wNE|yy zZ(KDPoBqI_7Zijt`m#l^#}wm7)AQWVVLVnkN_E|%v?{^Vrlu5!rrsJ-vVfj$qG7Kk zU41p0fO5|Nhy>gJr&?Cx$9Ay2u`_2HH*nsA<&A;@mgFYx*_U`CU1|fm(=-q!%JlF4 z$&7rsp_kB-HE*4*<+t2&`@IX@`Xf(|CJGz?=i=@3CyL}Ox0mnMJR7wXwb01?GGHD# zP;`s1vr6;nQ0%3|89S&r-O~K*B4HSv0dz}31k=lY>y(p96tp>{WLl52G#zkNCXUmhU?XB@o z_xQ_z_D>)4#@ew$#w!U+JhX@h{g*1PMqkI`@wPQ zgH~NT$)3>mEm10BUN{5nNTbHV(?9z=^=WbsKhNct20RWgaj^nTrhwqTOsxRb2v2Uj zq*3Ec86mm(plvRAyLW6zGTpqSqX+mkP~@1{v%_c;-31xMyNsfu?LB)s9;Kk)Lpeu3 z*L>$l-PBMepKjeLv*F}t)6By~8pgVhQ$y0y-#sf5Pe^>pF3DOCi^N0*To1eNj}xam zR_gq18#qdqg#--#WLOnFwrJPC?*A0{&VBrXeS40c&gJv`+sDt(^RY%Y66c@(?pl-y z;N1~XkCSB)Fo{9@L}=_^EVwl@U3D3zq@xA*_8}*@AY~TQ1ipFN=tSf3rbV{1xqPRFH2j@RFI7se zqwfg5?VT#Jd0mCwQ&YsZ>lalAxK&z?rBgpKFBv(k&tOSIoJ*WJ&C#Pm8X@Whz4hdd z;&^#`JqFf-te<>|-#=T5CXrmdr=$}dL#u8JszH%idi#%2D=h2nT`HSyErHULXp*A; zj~j2Jylc!nYzyPEwGy4!!e$gMWR91+>j-w#GLNn7c-1BwLwHa5b9H4(Tpuy>Sh+5$ zV?vt`dw0lj_|8h9jS14)s2p@@gh^)tEsPjZiFr1`GUKz6R5%IY_~hdqZ*cE-*xc3s z>l7*teD*&f5qP(}M~6fhu5eqa=vk?ocCT@0Dv4zYDJ~J>g0bFU72~x<{(!8w=-}?V zAi32Z5*~9@?&@34#hx(POpI6b;=67XYZd%gZX&6tesOv#zXbO`Df;Ty6J}(<3G_y- znKDa#<2Z$KKH@%_(C;#6>CrA3TOlQ%VuB{(7-G_69^=ba5PHwVq5ua1nfkwJOiPcY4o%z7jjezF`>8Q%V;R6j<&^b`1X&*6BZNyilVieTzMEAWV@Rih z&Ws73el5DwvcUtyt$$l8^p6Aro}9?qH!PJnV}zDKsWHNTGs+XbVyWVjy|h0SDW|2S zYZN3n?H4!-5;(SO7+F5zKxL%TP6FPIQ8x*({>wpXc`>|SWSH(X1|K|p^qt;rR!^pj zOO^rxkk{K7rmAaC`rcSbS$bSTH&9R?HQ9aZkL9X|DhlYtzBgPWm`1EW#7BSX6;(-; zef#J#ym4T=M^ngW;#N_zd)1`2UGejz!3_rV<(MCHs#)rG>r(t@PrOM$CWZM|Ew%%@#!bG^ zT&q{anESra!1s|oawXV}W{ze%3qi$0PjfNm^?jhKk)>tEjr;DGFfF!hT>RhhJtwVn zm)Hc1203T->jUR45Y%~abBX{WuQ<8F%-Nqi>`e)XkvcxfK@BVOKJDh>0>QO&pU|wy z0dm8%&SW-3aV$K|8RIrny#g#l9^Dmw%;NVvysrv{hh~+3K;rH;f~2!47pAS`%VN_X z>t2vY--Q_%P!yQNHJGVdkicE-+A+nWv~gt+jjO=S&l!U=8mGVpCU#rG# z^RfMxrfFKpeJ}v815)Q(vhd2WAuHHW4^FVt-q99aUt~ri!;?T!yCS_)J0JpX>44`| zJ5vS@=eKu7$5zNAY``LvhSi4u6-97ULtIw^8t;0fPALHXCIC%lNW+o+-Y&v=M3xwc zH7+bh7n12W4x0V|ip4JB+B@nnHTuQ<49{g)LV9}w71jGVbR}BvG#bTf$J{2ir0`a8 zUnbsT?veMS0JQ>ihP>yFba?vZ=XbxTsCY22R+ijyCJlqjZ^c_V+PeFNs=`W{0Hfb4 z!1HW5XX;{i16>$2;@g47C5ReQY;(&3l}i1jef8{WKkKZ_=E1*P>+7)5f*8mh=<2ZA zJ&-U7!px}HPX&gwGTm)Z;jwlEq);HQ5+qa!=+^=Vg#hxE1%H8fLeUnW?seM40e|PV z$m(0b`FgcdC$fG0-fM>$%MP#0_sv+w@18sx1-!0}p_AY1%C^^*gjqz5UQMC3jVkY* zQ<`af2bnI>!D|hdbX3)Q#hN6E-OS^STBI~{bh%B%F^t{?ECk!EN$Orzr^2uvUE_`dP?JXbaaUR z(ba$Z|79ji&P2KMya@|w*m!ZjJChovEoWI|9T2hNUoY%-J|&6(dyvQa(Aq=&1Sj#E zm-Ux2=bHQhY##6_lCkk&!KgKb*1mkxEoWRZ2%$D7IhdaTLs6v+ZCscvVVs=DRB)@r zVRqEtDnrsBL0ga<^YQh)CmCU}F?bwsVL8+*-cxP}QSPtt2l0>QOSR-PCg9)@?kY>r= zQ7JyqX;>~TCgA*XtJh*n>i_K6Eo z@IuwF_GfAV({Of5GH_u>h2gXXL51N{>)uVwmo0qV6mZ_|p|6OuEnQD5Arp;>0P-~F z%rrl%+sYc8YXWLg4C49*ChtGJ7qbSDtz2m_hNdxsls`+oz^nP8ry58Bhmz_)?~8`z z-Jmt~wzz!)9?pTlS}v^}Y|I89&-enpGEm`c9D#am4~scp8&7C^RT*I6TD`96Ui>Tj zkFEEt^Kc>&MhDR(a+O(-@u!Xp4Lc8%a{ekffU(MvTl02BUFwxI^*DIPZ>~=+r0%+5 zV?30db_tf2CX%Y-)?30g(_U(J+WWjPWFGcsgnI~hK!A~~2&)ZH3NExQ$tH2jsa%Q5 z_7|EOG%q1M$Pq9v{UJ#L7a#-8f+^9?evtp}%n>v*EU7`ke1puo3?=Jb@?KZ<08L{3kL!}ob-}v0U>KxgLm^WeS{lRNTGUtSvOYrzfe2 z$V3jkD1jNFs*TY*oq85E0HSA^ExO&1Y>Y1+^Ft!hv|>x4TI(M^uU#Bd+MVrcP5*7X zr4vH?zfaED_R-O428%~EbO?10jGZmEK^xELw8<*uHqWTiUA%_4Cdz3p@){b7xv*$wxT=?^y@j$_WVPX!$p<26C zIy7>1dx5w6Rq5@%-Z&hH}um!E$j@ViR1~B@zIJ` zgcw#EXkPN)$u$d)Qct&~%ks-=@+jI=suMW8qHSP9gLpWXnn_*@P{pb&RjyWDR7Nk=UV|_si*W-ix2Q5+Q zb>GyWt0~q>bj#0AHWiz_Km(hB#g=1ia~Y6*249%HXXrd~m0P4F-Roi(&;)a}<#fX@ zZhhhV-pBwkkpL~EMR*qnYaXB!;057P?}_;W)%R34+@=*j62=@{NFbh!(9`Wzd-w0O z8SI#fA$}m}ua0f6O!HCmvjf^FE~`To%X}rOq_^jbC36 zp8x+0110%s_3nkB=hbDUlAmFgl9Qj+Xyf4&XP_Nbc&Z-Ps(BHOX%u)}F;X#-FQk=b zqAw^uWM<~ABaV{TEbiz26)6Z)xflg|Nqn_J6e7EI%Xv(F-=S461(V;Y2FujN(IOEr z(|8#;=QN)Q1T70<4{M9=L8p)5`Lj;&E03;|-v&qF5vtaGk0J#-#+~j{smutNB9YKf zr&=5Th`nA}^a(x&kbf4Q>5Zz9YCxKss&0H3pQ-j~w~$B-1G|sxWe_t=9<6>+fx129 z^Vkb3ttkqbe(i9)e`h76{GWS7>cMNJG&Nzp5jAL=SZ4p<=moKY#)Xz1%Ftgo1imo2 z@;NJ2Psf{)9(v9o{|jo?0yL%M>hJ5Rj>Vy%S;=k31YZrh84ITY^(JZ940SG??QA~a z=K?$D+lJ%y17OlPnws)5dB&AhmPaC^Gqj$-3zK22!CCS5>E71Je#@KtTsUi87Ih0U z-YD8LZA`-uQ!@M`=r3gqWa5DQlN-SS6RIX3+hmyAxa(F}~&@?F|j>35@va@#26pG(2IKLZ*S?}^k*HN3E$On({2k*1h_ zA8_n}{y^LL?xj8KyBzvQss9Fbj@I|WO*TXythg%Eh9>9xBGP0#xH1LKhKJQ|vLWaS z=S{f8#n`{NOX5xXKq#Dw1$OsolZ=2N%K}t9io;}_PzpR=Ak>cwQN(S+7&@c$GI`Bw zZ}Skir@#xjy?AJLX5%_<;#t3@FP#?T>h8Ze4T}aL`$HjnqQ{iut>)v9qut}fpGJ{}7>;5q)y0#IF|zyu0RS~JlA z$=@6jQg2mLk%D$9UBXWg31*z**34S=j=d!;`nHCUQ2)E5BNH6tWTJ~MT<(-q=U=rf z$gGmmNSBQQqjG_?)U6#)Tp{$->{VYQ4C{w33&Qfl(${|Wj*^Aq zKengF{*yR%bjzJ)%`*HjjKkq=MSs8qeKl&q|96S2+mdK3`wx6oZo_KJ;(VF<+JOI$>Pm{YZg1xet2 z)~9TX#lbZgl{RA9?Q@|^!cp>s+#ASD*>6rZH)#YTxwz_1`YPAkaAgDL6X=WnL4FPV zrA;HD8L&C&lU-CLtv_`9qxp~M@zn9J=EK*=E64lF$IZu-q9OnHvvp_fpn-mXVVL3| zIAx|oC1LV>QrrA>w_eMSXWP&07#E)P56S$M#{loiT--vgP+?Tu-Rc;CQMp)quCMDF z`PvHDgqQqht9y5v{~*&pn21X}X)RLEjQqqC@pb4TB0N-yEeXpV)f%nE(5o^7aw$yp zhA}z`6KyAzf3~DX{R3Yy*G&1SQmeFka+}2BW(+^RI`HIE5nkN;@#ko-t-+1^%id4P z0xDK2j^63$a0u1uPf_C0Ex-ti?<*==4q_DNP5SxaWVh_OFmStpsCIKU zZoI<+z4#;M4lGd47kAawiLr`+EZ^eD?eH;&g? zj$eZ%x&S)Rs8}kh8O-kd}pzApNNDrjeCs`>cfc+)rJ z*q2fy!Hd(1lkMbIGkq*X4ds5!3JDMI#mq5?8S+9j)KYh$$QboYbSFG+*XnoPJ-z>} z$fl?}C?cWy_a8rQ_TY9<$^du*-QkGGr+fcL`VC(Z<)Ri7Hx~W0o9grMW?mZ;Qx9Y# zo;|@{=|(x*Rv%F5K6nr!czeO@G{U1G4WpY*#CNOXKod>p#{RwU-sU=B7BQGC81+nD zm%Hs5n3MPJ{p@7Yc!j#sfgUjf48CjIbv=U-xKk=4Eh-vHL4F~7n?Z-0LHRMJ zDdw;k5T5mQSmz87P4cmyJx-1<8dR?u;FW{5pE2leDchMB}h`#>&-m7uTW|-lJ<~=7<_i zUmnT|dGqK_|DkEl5Y}SED$73U79A`@)UmL;CZ;DcO+H*Toc0;hnOo!PC%!$neH&#W zQ3K}TyEAJ(R;!uY3AN{qPzV|%t1#iKTiIPblZ8AIO45%rR15Eteg+z zj*f6`%4FY)6Nxl3?c)Bo2TT1lnWnW<=GlOFrJ%k1FRQU#^|{^FjF>dvzVDZ(tIC`e z^+2-xtlUM@j2Jt#y)|uorE!E60=e=!D0UDh7BR4U2rvciHRUUPMOG^hNq!0DaPVtvgXGEzKc=yg~^2qb3L-Tm{ zxgKx#(NY>QpfzT!ExUroDg3(iFnBBy7PJYc zY2~vejoz%d)Ad+d6|s@&0Oyu>d^CLOcChK$;}&OE?k=EZoZG0GBKgLrv#Q{AxBq|= zx@Kdxdem4*kYMb35oyZ75uCFuoGIkPsUbHdI5+HKFbk$WQlVI+bRtulV7eNMvIknsvykl8AABQJEitVaWh=| zVd^xt8ZNPfTPKQR!+9Zu5o7GCt>B`cg6z_a52u>U1%sjGi0}-XDeqwIy`!VgehO67 zFvPfZp&Z3-ReAxuEl(Hd5_94{x|9kMobfIsgSFSh0J+}iHgVF(b;dTa_OcVX==0Ba zMdWy%WlGt%%fQ6SFWaN4JWq{a*TZmifY*mpy0-mCl5Lyw&Q|kgv=@Vbh~?YOEkg}j z$R*yJ0=8-bWu)t%S;NLA?RX!pBSQ1*E>-_B%_nRi6+5f~+a`l%4haeN-d=UAnPN{e zj{=_B;g@~0xAjm3w=kz$8kz(<#h8NUcC5zIZSIU&EaoMM;}{4cO%H+q|C}XU)qfAAix4E$pK`Ub@AVgtyc21d_g{7-4!`EYOwpm_3 zTB>(w`OUSW%-cpbU2$L2GqgU|jzr~~5;Pyn1$gEnZBE>d* zuDecurD4gmK-f8J$^X_09xJpbmIVL?IwgXlLxLbRLAPkx)a8~eyAcQ=OEvDUxE9^k z<}7D!YJbO~M6si210GIxqvL7tMd)dyIHVUkTcsEii^n6r*NF%^I15u0M7uxxfuA%A zAtlAcYP3qk+3NW?$Ek2cW`;ABDnl|5aJZBb%=lFV0&7Kslxu0&IYlgg-_MK|=TJ$H z;p*+1qMzIG<0Z*N!}EIlwiE?;(Vy{7z{RTjnq*R; z)Q!gI3HGmeDO}v(S!XGFUM$AWTW$74Dm(nj{pXJT#hHrjE~R>^!kM``T3Z+Pu3kB5 z6&`bv^N~Te+~=cjL4F0zcU<+#^|iKV3{4UD5!-T8q@#!UkewfkrMF)fIae1WQjG~E zdP3BG8+w;w0Wk@M)&@f>|Lj!n@&m6QBJGAcr>tmbu2S9MiNaNnrZ@!qy_LVn<5H@D z7Fl%F{S1X-O8GhKf5cy4&7&?3*gy^cDYNBl+zowZti;W{t&nOw+<7PQLSTRPKo|_l zCJSL>6>!pHfFiX*2Z&Vy@P{-7gcnkjWYdm-D;6)jdj})l*A67IXtevnA6mT#P{}-K^S(Q*GnkR&HxY>%V^enps<`pZfb# z?_h56yy<+|YmZLPg~rs;_~-@j7r@hhi<=v9t=mfuyuaunG$Gk+w5l-K?ItIyMJXdi zCVUP9J=DMR>)VaJ2laCwqC@nF%?lpi+ty4&x;l9t&n@71vdg~v&a`#S?*@Gk{kzLg zS)UAZ=prSD;fTV7pATfFXB+FAn{)J^pS@FHjArl93~{SJbkkGOds2}CPJyOtU=X&x z?rv^I`(V`tvuH`%va5_{&5fyYT*wt(bk(1hbrM^4vnZRjcyqBi46>OP(<0*2C#%Bo zY;qEh4OZah{Wg(is>%w>wwJh2>9jFn{=H4UUkf5;0Q_v-3KS`STg{%YeX(~T`JwG! zxy$*w;68owmrPAtwxtMI{mAsJTNc%3CfY?qo_Z@4*M=UtfX#Mp7gPcDGyAZGcU zu0J;xtd*fe+pHcmZPd@YC`z|o1@14Y+a-h-#yTQ`i>4MsU3C4}P7VBW6gYX04?3ga zEjg;N&8{#19eppuArE{a1OABZDDm2UbjEX1Icy{r16E=6L|>t?MX8<(hHxgaGRQYZu^OxUEm^F2R2(t``rNti zSJgNBo&e(YAK88scZ9X=JirznG@XxX+MxHD22MgU+Nf2&E1uPeklq$alyNlZE8m{Y zY3!_TN$BA8;;!%Wr$?R{PdlPx&9-B(y;^@KF+bV$<2ioHsE|bZYC9NbZu~kpeAL`r zaXhsFN-BxU-Pu5=*QY`w=J)f?M=3EUrnv}%NLH5;+GlEUN;De6Btj;|I~^n~ruv&d zQlDRVw~Nye^ZfiSGNEfIm^g9@!lC*})!Onvok{cHJL7bWYh;j zL1wChzO%6GNRovxKLM`;woenK^N&xTeo^#B1Eo6Qxj8F)6Jb<-y%`5F6p>oAbiwGs z#Qk_0oGuN6FBO_TQNU*l6{p!~6x6?NvYLM?L&k9^z51it+^#|4cLBUPh9PfTq}W#9 zKRq?s3lOES`huj6Y1J$YqE`CS54azX8ZP#IU*0L>OrF??LN>-+S%=fs56Hf$m1s&I5-$^#lyy! zlX)v@NLrXPIVBmZ&A-@CxVu3XJsZ1m{$H8=q6?+be~c@}_KjxFw+$pLyq$OdK8*`ZAlZ|z~KTbEK#Q@}o>|)g`(k&9H+9fh(Td#un-G4K0#F0(cpmq@~ zjURPO#zY~RAG7ou4gNR;uMo_L$)t9L{gDz!}Uw^T2vS7xw)x{Dwupd6b)wk;JATs+{1DSGB%+8aNxf|C1 zu3wnY(9>N}X#9kq&9&iOL5X6e#G#|307zu5noOh1E`lmqcE3U)K$6F!*h?I|6l2T> zFlmg>dYZ5FLK+&@H^|}171irlIpG@glQ298royM#ttAseuKX6$-&dT}iI4|i=$?#W4PEo8oLN)jr2V<_D1IA@LPxL*+l!_%MrrXM*3RR>2yJ_hSK;NQrWNKCCYVnrg}Ot{vUb=T^G_6S*hh2m#Ws(OAyOm??uuU@?^W0=nqR5UzDH?WJIeI?F84c>rRKngH=HHx8Hc1W zhNphzP>)kSdb|U$fyIBfkdl)}lLu#J4(n??D9(4cjWKjI7Cm)kC*iy*<|emFR_v62 z#xX-QhWDYkEA8)*zaGqjP~!>L>M4@l_d3w(9qHXE%6U{b;hwcnc@DVxpg3Y|c&3!3 z)QgH&I?!xf;(LFO@0@}~f1@{qAn%yI!D39MUQ66xz@|olo1(d@ORsKd@$5mb7%yWk zn40+>xLc(FcRT%tEmQrPJC`&sKE(kqfLd0=DSdmn2UV!cg{v@mHqS-F8hqQtR;v%V zUQ&NG)hPk=!nQ{>JY7%u#iDFhqgc~NEn};Qq~ZMsL4G^mQGy)@u%I{8dT2AGwc7Kg zifot~J#O^c_Xd+hDN@nUEsg9X1A!lTbLC&RK3l9Mf`^tB^!rBC{qVeI@0?#lEWTTx zes5M?{O@FMj{9x3yD9$mzXH<4n(rwN$|$XVA7Q3PW0X~C|M-08=ZQ+E{v1W1ZXpJQ zguEs?>gmU})?$qnkr}EuxExrcDc_ZOPJa3$owZxo1#94mvZFx{(oI6mrN_r1so= zKp7E6p-h1+%jE88Rl^PAJOp_((@S`y?m7c2L^pWqj49$02p)VfivJKc?g|BjiEHGS zx#VGgJP^}J^V3)TiMCRyA4vFOH76YUc5|%tzsr0M4aViqjt8$wDe5%ty{ywAO`90l z{Qo>RP?}ix-CuEoLAl0vw#t{qeZ+5qb7Hl@&c{bNm|0-jeA@Ulhh!Ak5+Cmt%D@ri z;X+Dw)ULrQL;Xu(40=oh1;W9R?byd)6nh^7Cdm)MJ0eJ!yzY7`$4eibS)OOcstR!& z^R;@|RIROb2wu|xZ>u=)XH0{VDd|j>_2HG{DN3sJZBm>h=}7oTW3%4T8ERbe5pVA^ z74KmdCfE<&J=0aC$?lW5G+i4!808!M0Al=+v3NlyO{GJIS$s0?K3PQnDvSBy6#_YV z8chz3`KI9R_4%OFaUhjH7(G$@)Py)wr%K zaO=b6es_0>3N5Vv`Lm^Kr`0xRE!M+a->`mKZ|D_0-#g7611PBYERa7M2s&FP+Oie~ z`Lx^=_M`nCRSkw)q*)`43_l+@jiwevH-b?h-R3+B4{~z4jDw*{?wvC}^2{0K zD}jz?1EY9;t!orSelPU}BZM^E5aa{Wj&$wyznNNBI$RxEDJ`9GS7ureW3rlK-=3Ij z7m=K=cr_$hlzgrE$B|USX5+tlE`j>6^8^GWehlIhicCakA*zBDB5_|vwzg+`*>Aw? zr7r^H1o8Kl2%s)>8PSqXdeu)%(m0Y{KrWPvJH1%m0%!9<~933y+{4pzGq#Uv4F2St6`o*#GLZ^{w29PR5+1w{l z6$_f0v9|*%q~j^Z>VVQK&(GhmQ)Uv6YFfDib#8~?y=rUr&7mJ6MO|{EyB1cW}v082jJqxL|bu29n1ZRX=%d}wU*lA~iPAZr% z^@-;*#v)qGcNlU(!}Uq5f=I#WqdbTlQ!rRvdd}pbYPC2)B$di7SyIW8qY*4yQ<<7K zR;xrd)t-W3%QT?Q#{HB@jwOcUW&^v9#*pvUc0wyn{k5He!X|sW4&Or1R;TH*)J`v4 zP|za*hq5qXblQa$>q`%z(eeA5Nzz1($XUd7-QIn-8}qN&eVSbl?fW>m*w92o>!L?Se>;%uPXyrh3-EZgNDA>GS1+Tpmqb5+{inqiT=Av|I5WL+Jcm1FJmJ_746&X z$H|qbu7%^Qm)ui%T9xebfdRvnyG4ALkoUjD$b<7$=uT9N?C!(!WyH|%0%Yv(owjob z>|GNObpO#m(F{dfU_SK{7b+wXIgjmIsRP6B-d%O=53-l#@3GfBN;+}5uyT*SGBim& zWA*o@gCQgm9jn2%t#Bcs%Q+j{mpcz4L)|N9WIEAa7=D@zAO5cPKeH{6@O+LBn7ci) z8p3C{r0)5~TK>*{@V9aG+hp@L_Vq8TsDW$hypHD+vBm@FCsNEx=!gtPc04*cc4jX8 zY~l?gq*tH356*s>5p!7C-c~2_>jHv3d;aoSC))c6XDdL=>YLKrt1S>!!|_hKJV*1a zbyeLmK|z9&9?1C`0J0Lb3{5nR9(15mzQzF(o}T>#l8NG(ZH5sMwl1f11S6qiQlu5M zwmV>ss`h-aY}~aP>*7kcBJrn=;9p^0K|f$X}U=eMUHOpHFz5 zp490+;xIt{{UtS)t$-_@Z0Y;jJ&CBMgkSRd-t6ySwhvlmFALd*(neJ0;~Es9ffPzP8;vS`T{L1#Zzrk-z2p)@s6}pB5vA zBxh!3$Yy$}t!57|QMXSLN#SNBYYI*`KBjS7{8yV;=XlANy24C$asLfgaf&^rGMtUI zTu(^p;&~OMmmtylucdgiUN84`wJS9fH-b2?t^Qf&mIxF$4ZpNuDOj7b zI^hk!xp4toDpfS>QaMtk9XOYjA2W(hbtwNd0Ly2H&3NVjUOH-MU+p8V{ifa74IhgQ zMTGwbNnp@>MkaoV?#F%T7p4ux(9=qTb$w)M$BR+x-(5TqFZyIzOUPtL)p7jTC6dNQ z-TVpmFvNWfKcPeZ;(-WkX(5KT!IoE`K!6B+AAzhLJ!osgo5=^v?Z9bx1BZf&aN8m0 zns?_q=o^}IcK@{*9C33y=N|d})>N8af9d(JA*zzWc_(FW{m9+Q?4WFW*1rqba9m7` zR$^r^_Am7=zpZ3@yiFp5;?Ha))z9^f3|&C1Nnb7a9FN1j{S_EJi91$AZ499I zktho%FEA3tWA@n z{qz~qYTJg2_D!y;Yx`Rbx%!NCXAZjLsguZLms+2bqJ7S%D0N(V_U|rbT+4wYoSwS5 zkxy?UJdAU0p34bmIG_EnFLFK$OUcs{&MDupLVw-jP{(ER zP>6sJ=PKNLPB+zCmiuCS*K?G5+J|$p*#WoprdBL1Wi}vV$uLiusQ_8|8%QX)T`;x! z2Cp87(De5;)Q94NHvh{CTNq#w&pzG6Fd)uu*vC&e&6*aY0&-8la9E@^29db?h`V## zJM@`O`R#;x+q3)sT?N1t!RF+pD@=!eSgc(K)HVU9hnEsb)40qBSLr1Hg_V)fbM<2K z*UTOs9gQ(5;qJP!2}VAWa~~nO(8Y+RgA0_VUuBrG?Cy>&{=GQazZ*P*`Weh=_Ym1C zuNJy}Dg1-7MNLGPozduX7mioDg8!bOt-9uw5%#8XCN z8XLOaCqVYJSbXpp?FJ4yVe~CX`DghP?#vf=Ov9j$cf}*}R&FeecdeJR(m;4$SXx{q z6oC6T(DKyvZBJ`&&F%*G_mGmS3h~>on}1TeA~zWRbrGIi_FwYk_HfVc7?4dZDoz_T{R$nPp6@cnPePNTN$7mT%g!QcgrX^*p>!AViT|5p17 zBgB8hSvuxi0}C9D33s|VGK$t0EK0^2(^h|iIz6RE6-YVPzCZvHfbsca|LEs@C#f5@ zXX$OD+i^@P2p4rkf;nTAVH7ScYZ2|@7SYq5`)!=%urn~n3s31#_<(y~J8!wE^ag9d z;BOerv5rKM6;Fg}S)^!CMcIt6RZq?M)J*+Uk1j^gsyqwj`oO5Xe(k+Y7`p@@$Z<7d z<0sg(NTbG2%p2q=4ck4gY?D@T88)Vg-sUbMqwE2n1H1n#*fnVrae9^4X*M3S%zkGc zt#@KOS^X`$=sK?VM#E?lwtO(m*(j&uCB}`6e^I-0xiHySo1fEp?V1wmBi_uAeEn!> z!jE#zbZge1@@muO<~cIi>^!_eivJCtfU~j72YzMlix-($e7mCC9-_U30J!6d%L%u? zNP>Rm<-T{UlysyWHdC1N%ZV(qmcCiiQlLVw6qoArEFaCooqDtCs0 zbZL^CIxgR(vM6_Q2aF&mHfnD4m+juR@G-O~5w>uqGg5zG1sci7Yx%ZKuX^B}Wh?5? zGg--9pC(2lp5eF=vW}GwbM7_pc4HT9jD)v=VyTPe@1}p7C#w-8ayRq(@9C_r_ClOn zaJ+OY4vMqC(ML4Il#<8omn*KV)MbzGSg04wt1B~Q^mfWRy<-sM@4krxupNzwtpS#5 z^m#L#t_5@M$5hl&chPdC7KxsiwkY0ut6DPQPKtG#hyJp~A0M zRfFvc(>fx#_9a=KpuckyflmcvA2SPb`i*%x=K0ipKlyK-2q+YHUbwsEbLq2)m9rag@6uC*GqJlI=We}?Pr(}_)w(n)h zDH^d#LK1B1bDESZMdT4jjQ`O7=H@04cV|}aDs^7Tzt0DADKC5W)4Dsea|dSKCUWB>)yw+ycpB$*>uZ51#W*Iid>Xl6SoM z6;{{lc<^UpyL9EehIUESD2)~b>xL1MPQD5_>%1SeKGACqM-H$gp78I--605f{{UiZ zAfYZWwWU)zZMC$wzTPx?PMxW>2L0K{dLhKNzuj(k{q@%8o6XNzLiRu(;l%F?Auo8` zcjfmswTN>M-+Fv$Yg7L5*#|PW^MJ>_Xy4*S(|>J*w|6)r_}rVhnkq*5hRUETe z_vv0&ecWG#eM#bX2$=$-`s-B|E z${mgD3vYu~>)@U7S$toF!h2NoY5&w}!HMS{&$&u3h$%5BlR;3e8){yGXsdnZ7tM#1 z6|)Sx*|-ePX(sgq2)Ox_3V-X9KmYR$#etcdR1NBeS?af zS7VJgG5D@1y=0+Ga^dw>QJq34JRVdSBsh39$9Itj2u)YtIlWgFL$BWTs7OT&u&B?m zjE;QH(!6BkrdL;XKKhgFZJiPVoAKOEM(?*qb|YI`TMT34tE*sqE4u%`@vRS!Fk~B_ z&;_Oh4ptN8pjdMM7F}9edU*8xyG!$w`$3bFEql(JYzXpNtv$9yXhhy4NpJL`mKM_9 z{myLQM*m#Rf;1~F#1J8w{=IBv?KTc~)|L{y*>jC3&0>o-HSl?Ph5>H887Cw}4PO1? z7M1J|>z%ZDVM1zs4(7%mr524{*u&8LMaC7UG=?*E&}07D8Y6u)91yNVlqz110>b*D zTbT_a2+7G<(&*C`XwaDk62H*?9FaZ`>UWe<4;HnV7Y!BqolK<=k)L=_+55Q=>*{>gpQo#hjeGAtL(c z?<0}pPaSd&@b#4!ErotH#R`EkuA*#P7h(lu$8Pz0uUOvU`P85XrH5c7v*xqlSmlm9 zDVW_O*mR}=!3;-hM#ff~VLuQ?1@c3COfjsdH-g8!XXz2PHz``EQNY={ln)v2Ys@+Q zGt#v&4!KJgXK5@D%EW1U^ z!+04=JuD3*P4(#X(NekDo1)IC9J)#EoD7+<{5#JT3A$!FcXhKAPl-HzOX$ zw0QRjbM}@1^18(*v-4N(yyIate4)aS`@}|`8SE_cF)&l~)$)YACn{P%ebrJXG%Uaf zRe@ZJ)$5bKi-2f>+6w9TgCZU8$*l$z;19L=5oA6sCkPRHT&n&<2Jd_L}v z+x`APr?X=7S1r?hcE?=~4->y54p_o1!VAn$o^b8fNzBAbfTD`l(+AZM2k<7EyCJXi zRzx_FT8}n!SFl2!_%trSUqv}_7R#9N5|)(LWk<0t=${zqcLIR`tg8c}i@J;3cgBxS zy9|3ge<*hp3?jzrB{al27a?>hkf3L zI#C+};u@xh+d>zecpZ=0^EwR$3GO#6(kC+uehrpb*VNP?TZ3J7#!i(qPy)O=O+$?T z)3$F8=Q`q!fIM9O?M6W*r`Yd#x!S^k_eT%f^G3detl1uDMDuYiqsMB=@e;R(6QYmSconj6p&6_IM@O}i(M z_uBfx2yTK!cm{nn@X^}Vn)L1x*|!b@uAr8*I!xT@S7qKb|e(%T?EX=^xra|6*FBuI$EqDpea#Z>^2 z?yCy8uvDr_z9mXmo2GlTB0eDs_W7<1sw5X_;Vub(aaN6%Ddz^IHV8f!Ztq*mq?bhr z{cLVL~*kph`4fE0p=l4CMZqWl7dPdt;twel8;-ZjZg0sDkSb_0brZDD9{Jti!eIoHGd@niqq*%1K9G~lkA zO_ruD(~fsc|ME?vZcdB^IE1dvT7&;|IWT`GH*Eo?e4UidTrAWAl=SY7L)h*W52^T!oVcS$#86o~n+l8m(^&r`I+wna}>1f0C!uyI&E4#lMoMuy+jyHCx?GYZHdbZ)GIX=($nZ6s{ zq#>Af>gRopntxSAhYL+>T)XjKYABU!hv#0=1dnq?zJnYTJfH@%nbXS;qD9^jX-CCK z2D%nX!m0eSVxNOf4yfterAn|~JU@g&gXsv-#Yi9M>&&zupJ8lKarC@XT%OHZOYs?m z9XgX*o9Ng`1?KVw{K*VkDR&GZ_Y}Gt^FG&L8yr&{Q#iJ z?vLdkKX$2FdqdgGg{H<(=GOZ1`dW##bkois>wmwP`PX%CAL#$}KdyhU%VB?wg9pAf zC>`df3?MLFF_mOhWMLx7g+J`?J3*@1WJ7R(Y9>fx1c>A5G;AD4s&p5%@>3lO0FJv3JeJtt_v6M8D@0!bKb4cwU+r+#}%% z=#Nco?dO8B3i#kBycEy4EZ2E8QP^qO-}YPZ(wX-+OQoIT_Rki(Zku=4)r^IQuW@HZ z{`2@l)SO47T`sm2L9|o#=)9nPUdOdEWv=VZzdYCK@{dp?+6`Zo7K;4wTjI)(hOjhV zcF5~mGt-jgGx1p`*4IYP*#E9ggJ@Gfeccj+CYTJ&( z>71}PD6oJ5jAY%k(IyRc3-7c-1spv@m7j~QE@<50rdsB9vqawK-9I(jGg7BPsO3ndD3%1EE>{s;C%1$P#yJW+3O4baU|^Ve`hViLV+rgoBoiy z-XUqki#|e7_GK!6f*PRFl0^e>R>apE2`9fl`*2!m+MncS&kg1a4p`X2ia1~Sq|G@Q zlqh&a51{Dky=VixWk>x4C}Hd=jJVS$-EoSepYbNsscE1ex7zCN~*R(=be~!rbTMrFsZGDdq-DnXEU2WqPjsP)aV2rxiWjPkO8WkfG zgzKo(LsWV7029su(}M_YH{_uDHC5WVN_74lu(aCD;gcLkdAj6#yF~g+$@wl%2d74mLCrSfu8hdHrW9*w4H4v(&>DD_8X!9SAWA2K=Rgg7APJV z!&wmPp#)092530B_HI3dt;Y zv#-#S{cH)2SlO&K5rIhk^yr)*FJZD3x`cN6nHDlkog6h-V3n@Of@AP3Fw~-MNmiJw_OVwmU�_(_DWY`7+e9iy9c4w2CP4gdHSeT$@hpqo? zqm%zpTaJ8;odbgmg&+Hz)RkfQlgO%(npR0r9yixJhw&Dya7SW3`5&jn?dI+Il;*!h z-SzdO`GfQu7J7I0F+1dhI@K=bMOPI_azgTeOHOC{P&uVONG(&8XTA>XtfW)YUo0tx z|J4wuIQtOZ26Xx43|k!1ou{bZjA)sErmjcPzh$caT<^?H771$;+e^44vu>KLB@bR- zF5s}B&Z4T|6RurmS{W`7Kj<#}1gl^9&$Bm>Nv#H}ba|X*p4j_NZF6*PZur-3tO(M* zNM)A((GwT7K4bE{F?jXoCRfwO&LORhMOx^en!T0yu)Wt!+v&zym^;sNAUf}xA3jh& zKC!>z!Zx}dg6^S;WvJ5;S6=cPJjX?n?!1I}$}ds1b{uetqJ zofI4GSE&RG?)r_|LHAlVg#5KWcVhy1G_Tr4B}oA%TF0aF;b3RwKeayH68*z}OS=h2 zZXb&S3gHkIgf-#nSGcxLmP-itcM&+f76p1_=y5Ab`HZ|7g|HTLJh_KIg1av*_?T3emw%^D%~oLtO)3V!UQE$MuI;w2#!!F@1T zEI$u28RX(W8Ss|A2>CjC0*$NXwK+Roef&Y%KPGTn{~wJPAHKW6W+1Zc+4rX_+GUpvzUeaoh|EIXd*!Vdx@bvX!2aS4u#O4H=OUz#?4aMkgF zfB5dw#1a8?NH*P@1S22Hc@X-7sZWn^Sa@IWLK$MV=Z?J(S$!wy$9!qPf)La-P@#Gx z*#mUakaY%32m3p;jTQ{)RPmR64!PYUZj|LCiN0mY4s!y$d|e-CxfyU%nSET%o3Hwr zObv*KVmkC`bjlBuTqBvk$f3GvHF~GpJG5*Qez$OH9?I^_1#q_PA3wm1_)Bn?skJ*p+ugk%x>Ms2 zvO3+Xwf7S|GeT|9Lm&F$+!k0KmFejq18tDxR704gl`#kpAP>8{-;cWYh?T>iaf~GB>kSMC(Tb|QmHBTqJOZqD*Yv7B0yESGZ3rOV zZOuFb>Y}gR8)#Cc2R&Oc#}ut05VufgfR^1Ti%~Qmo$*LLrE}XGGM}j{0>hu^d`9E> zZxe+fY+E~nXqm2XgppXo=I_ChApntc3g5D~kAw~>@YpIpMxhn6K1eK(-nYF|yU3ao zWC9YzjyCvAp5PK@tAqmAu#1#+Eto}B@JtV@*ahJ<>h@QKoYJ~E+*KXcgcOb1Ii)=qLMFvA$gZsuZ+m#W%shR=Pyl7y_dU|}ow z&@-JXua$`ES`FO!T~gk-^QQ~I<7TMX37OdDLtX9=2%IH%%@&gO`%p19DyW+dxD|xU zw^}TgK3S&t9Gbpl}(AHrcAZv?kL2`0mm_%L4OUf{5i$2Vutv?y0Q=Ko{ev8G>v)G*u zg_xiYfF@AD6 zNYKr9LnS$%eSVBJ+065c+y+Ou%V!oLB1y&{Zkab%pC=Du{JTkYM*S#WH8zmKw7VRd z%4;H&GX=kxWajQE{*%AbNe>1+V<{^a2Q=)X2QE&IkB5LmMbY}_aB7PhtZjISF+`Y{ zRC7Q(`&)6rLA92vk`}s=1c$Ui6U*pPk%R&}Twhxe^vuoE`FUfEnR>}eYp zaz~22F{}3}Y`K%_S`q+mpDPdQ2~EJJLy|vxJaU_`J?(}fw_S!3RRq;5<$f7WSJd4( zeL_cv9Ve+KdhMR>88>?~lo`tQl5wsfPQerglD9pdrPecWo$@_}ZXY!}DkD|sHmN5} z5JL*dc4-$`)z*!&IuEF_e8m?e#)G?YB?sgq>xqhhNkVulHtuC-nsBF_noiO|z;VX_ zvlZ?Q$Rd7Yg}Q_=$Xg6Q4Pjpi8QgvwyuLHyRbxI#@>S)J>-soc8uOw)gn79rI^)n4 ziG|9hx~-Yl#vm|SICdIzc_;kri9mQaD`st#I*!qbZ79mB45-dFgsd|EOr`Cx}h(TJ?6r&jqB%a?@^*GEV|k(=A5_D;!Ay)_-*$0;eX^qZ!4kzqwkj{dZxZR z--sTPRyZmyOWK_2ZDtd%7H4opPOr)v8{&FyOqZhG-gLJ$Zwylg)7y}>3VL@z@OFvg zjq`;WW>;#Qf@hR2i zpLU8h4koN<>_4521!|E34FiOPfImN^OLk4ySL_4+B(t+#)HwiSyIa=pEm@Rk5q(71 zA5>%*%C&_jBHnSj9Frm^)lopM5mtRGJ`I`k9h2;k~r4YKgAiw%mezZ8wLqa3pzIwW|w z2nazH(Yj(tgrOKo-Zn-bZ3edJ_;Bcx65L$k5PmpmJr9L04rlYYJY10f_83feMfiD- z@-2IZ0Q;e|9)}Nf0VwG5AC|VXA#Vl-eia+4l)BfW(nCu05zT!o*uaH15Ob;LL?F6B zwHfUrAb>O6)o#pc2#V(dV{p%gnG5dz381!|v)?%NUq#G+va}>8TBt%?v7*yJ1R?58 zdZ@cv#*8{Z*+NEcQrqBv5so(zBYJOPf$%i)g}#U$_wCS zdx{z@;cLfK!|M*e)3B(oD)&{75o1+TqfSHWfg8|Eacm)dp~s(F_Zk9sm{kSbyE5o_ zMMLjIGjjt57vsFEi_QR`yA|@&%%o}!f>ESQj+;;+*CxN)E^NToYi6b~Bzy9+ifelg zR;U>6TJ&dnb>sJ12{5$_aCKz(hy`VV)ES)EP`?M2DsZ#vz1~uBwN+|G;?A`w5zQU) zvnJ^OwYzfD43Uc2zfyn{%&+LQn9DWU4#UK{NZdm8oR9h?%kBUDemj!mPSaSWPeB}V z@#Kf-GBK)I2BR5R44&V)ODzbxmE@OJu)PiRk!_MMikzP~ng#(No%l;6JH(^t)En}* zx-0{mks=>$vf{nL(}t!(tdDDx#+p2RPo_fNMkSHc1~Mw;Ss=8Dp2~FT(498d>@YId zfy<*$Q-|v=rAC$s)`iY*OZmsCMD+PFgSub+3W+R786eTB`~nh1fPL$D;nVyFX2n)< ztq539aOBWpToEUjYBQ^zaK&RYwou^=i_t*Ipv&d)g)}f_)Gf{I2Hv1kfvS$A69Q_= zZ#Af76`)Y)SKimp7rrvP?qZv(H~|WZ?*DD?9XdP)Mdx|hL|hE@{$d23sP#&j7rC=# zrac^s&4v_u=ynE9F6Q@74i<1mw3cFVztRB247@wE@^!+*4L#bj7j1cYf3C&v!G)o6 z2f_GjuTdv>;CJB(Rt7vgB4#ED?Xlq~Thn_8ZP!T7ZQcyhB@WK7-A2R$K|@@ds4;kJ zldbgfXDVHlV1AeYKa9q*BKz+?j`Xo+}B%32pZlZQmq%<3Q~tio4Ej%I>)A$g3;jh>i`U ztzA)IoPZ&I*X_DDg{=d#>IAC%`Vbe9kkP;NZy$k3vakh4Lx5G9p(XV!i4AZXjnPmp z{r^+$m4#*!<05smB%2KElKkLVC%37LVd~eZlaoY~(dZN2dBp)yt>NrxB&<94s2zNp;u<5DudlN-> zoDF!e^AdCOjzp5jZ`F$-7?e=xB>sNn85%XpQW;z-*s*mUIKCRb2k~S-AztBtpg1w z$y2n{yWJ%5H|V}$VGiEMHNBL8KTZiWp}or1twC`fw)*q+!UDL1PG<&pFJ(*Cfl-H6 z@IEp^{ASD5u3XE(aY85Tbrvs*YG;7{wvg6e4_Ql_{c0sE%`U&1^jeV>6DR!b8Q`Z;djop29XtcZ{Ok?guqT~> zl}YyaG?XyRV1@?x`T4O&lcj9jZAk8-_xh{INj}KhJPV7P&9in~T!k$yzkI<1a8|{+ zNy2acgepR}@`Bi1>?XC@5jj!SqWCB-V5~2TG4j%sqywuR?z$Lm#_=4XIJ^}kGrnWE zN?t~wqjw(Z&wOD-{&&57&I*(DmQ=u9=NVRE|FElRavqM>d$9a4yuTsR zyMHDFz%^^SjEpK77qcq@6u9pCk@yY79S9762v(qWYzkf2?BlS5M zY^#qzGju_z+@T5d8hVxpk=xsmz~(yL(wtZsU+5&Mpi0ZUq%!sZg!|I#CBP_;q$K4o z?~=4#U*Pzg1AWVYn)|>ala~@V^DzT#AHHec2FM5~fDoD`B>8=gRxCIU0aQhn1S~JR z6UL!`o(k@Kplzc{0&bv=HT&5s`8KdCb=w)R=&<*QqiLtBsUR`` zI?nIb9FQYG^%U9Cyjbrkkf(4Dyz`!tvu5d#+Z^^o$7FrGmt`%&%?v#)5wK=k8hgTF z!;H2ssSONKN)b3_BzI3;e_xChI35YMcCc8s21{x>rrlC`VRzaa*5sbp_#%JVqr)(z53hT!wn-5(s? z#5@r+QYAg(0Q_dBlWLD5CB+OloNpz8C!>&mK0m|T{33o68X5ZG2UhC2s}d+THO|z1 zlDH%%t0r=aU6CTju2+mim*jebS>PlQ-18|zaqywkH(=g$b(f|ufwX;6N6D0;@KH?! zts%TXT@ZXGx#9a(BE}fAdLh`{@gB~8sXR-I5cfSs9^s*PqXU@Oy6Wca9An3pyqYHb zD$0?RMgnGgt7ohxfb?U);Efd;mtTEh!q^d{aw8B|IQ$Dj45w1q<1$VQ=;qg{qMp$?`R3Kf7x4hLxNycy^-O8#CC!in8bAPS zdQB6d{82l;RXEc^4c{;|UTirhyc@T$F4;R15b+v#@IS3YIzIDd%b1&8UKW5EN*QZe z4rch249+}H!|J2qz+ppIHwG)?S>G`xnDSU&wmvk}>k#q?L-*k8kZRX#<%1v4#7vHi z&yn6njYLijpUY(xd&P=Fr|u^Xz;nLo3-sj=7&)3i@jXRKMLiYWnRZ24Rx%!>&$w=6csLD`=53$zj4Vmb~iz^a`J)$)* z3WiP-hS!*V0n9!%YMK8wFW6rl>;vqr(e}v$?%Z$0qg&%NF3woY1y#7W)RlEiKg^v3{d8S% zv^-EW6AM6rz4_~W1+n^7=YeA=(Q>`aGjYl=4r?{fKPO#^w4)bHX*Ct0w&@H)}z58V|J^(|KJ zU1<5CY`m~qb;IzwjqSO-@cF|UEZOO25SCSgD0Ej*l_=hzM6xhM9b9j9i6bgQHimk! z={=(D$D!%>6y8B+8W)t91uRw4HaoI9FVa? z5Ks7+GJk;us;*2f=$i|Yv)^$s1%vYhua=FW6iD^!a(o=aehGBpNSCGYiB@1VqB}@7 zPn#pT-I_a}TCF6*$^wN%-NvmwP|k=eG%Ie%0nolZ8jpW;{Fwv@CapYRLPulv^lDcy z|3M#4kFlUy1Nh(2HU1v+x$lI$Ffed`TPMey%rdpRkC>s00=#Zcw1u*Lbg37u19>;j-6rCe|+)-XQ|Ec!ZmrSn`EtUZCtJE5G-4= zT9558&=F0ZS>=<{d{XCT!8b9$ekE)Fwp$7112RejS5^aKQmum+wBCJ#J?+@b0rxm( zJP$BQ7Q3@rVyE~CQ!hVMKT;L|za}TZ(XhV8WDFDg*_r;UFNsP+TB>gNYFvi8S%9C=I^R3G3)n@ov6G z!*C>wjO0Y(rO0Lm#08LWc|Mo9D;}6lK2NoO9pCh3MGJN7PeX>9T`ePy*l+IMY^K)ejP*cg{D{&q# zc@9VMorTmC;1$)FsABeur>5j#+Uz>Md`=&{^tFXqzkkdN>hyW@=fS7owXH5YAFp3O z0>hNYdkb|hoj&{$0(}WNJXAlBR5GA|%TMH+4s9aT)s521tH#O?4?&W)0BwyWrs3(SEd-P7Sz2#69xLoinjxDXbhn;l-SZyQiiXO_DO*A;lv?si+ zqBC)pA#TIlc;Ww^9A8CDC|{kM>Li5{Q{|kQdL4DZ#86Z@U^gHZ@H0ShfB2v|-SUuZ zwm|A!kWDfw=J2H={TmCQCB?rCsv-O2N)hLtB){JC)C}{^d@I;RtE?ZUX2eTrY-z0rbb7#_H9(mI4Gx@dx9YJNs_u$x1Ro$@8#(O3Z`tSfR|jp1zR4Pw^5KMK@ZYWT@p}vWU@PHR6gHZ9my3*QZEeZ3;=HLs*JhBS3I}i-q-k3HPkw? zMk?Q595rVtX@llEZ#!YTXEM2(xnb{7^CoSJQpAQgwTXVnd@I=zH%OOJ1Rr*hQ!M9% zus6QETOTG~5a~>&r_=)2f_#-T1m;4u0qufd~`7vE}oNh;4GV7hh}@IoEOmH%Rqa@t8yg8FSYX?t2ReMs^`&;EM9n8 zDVCubv9hc7BR#Ncb0>|f=F>`Y3%K#E@ODND>QK5Pn>Mw6wot5@qUO_FVRXjNmQ46= z#rn?b#>(&ap(MYn+NOSS0R$xWtzaD#4x3F(iGnuJ#~yO)28xdbQ=K^C>{s5#*z-=W z4eq*!`QgWI-LL5lupQz|3eswCVy^P;t?oCsnKQI3t>EWuMM>hXyrpnfMYVZ$25&@j z@OYA2W0O`H`p%!l`lVYIdLKBSUZquwH=eW*@;#m!WuxugBSr;Yy*!0{XIwsOcn}yM z07)}I5cSd&znh_@W)~$Vi&Nd+I5wt(#y)^Ro)kMBZ#G1?-b4%M4zv55_*KV|eA zVTb}d{zBboc*#BUmzA=Y-uq;w*rFB1yw&%q`9SqFxouxS!jhOR%+h7qaj6WYGRH)D|GGOo*R5$kFd@!*5JpxU^8)7QdVOdC3xn~QMW&5r5oBdz|FRj1} zA)l2RTs1?inKv|dX0K`P_~`6t>=tOM4=V{S$A5`DWX>GEwzD1*h$?Pc8{d~|n!H07 zwt-R)z1y+PY^14y1p7fVP)4%8S9D8CeBjD7T%Qc4MqPZ~$7l!$tvt;DFVODq&B3)8 zW}|DwtNsvpIB0&aDuvOfnQH=v(KsZ^{LEBoev;j{+Wv}yDv_emwmVH=m`ZgzVDr5| zj>^_!m4U1MH^mQp5Xu_NzrvQMDf$mMiseDI!?(~m%w9z7;B&IpS z2yr*{%)*k%ckoSXEh~N=N|4;aksk@i9PmI|$b&@=6PDIs-gg&Rd%foCm@f6Bp6#G5%OUP&Z%8y6 z@O#X`qYYzwj17lkhh;{B+@u487fI)m2CAAQj;cZVZb@k_s!;ts5vaVPC z#ku4OVWhw^Ek5!owzW(vz;rZIH5Yy{#6B7Vk3cAU2UOA=Msu z<5^WZvG$sZgop>yTM9eh5HE`|ZK+t;4juP^^s$K>rPmL-yslZO%eZC=5?;C$Ci_oB z9Oc+26zUnxAis)smRDuzNEmZRfQQ7j(ZX0khSY29MVYpC9Q<5veVbjrMuJ^ru75Pm zTg-Vsav=|I_N{L%{h^49rL&0KIwE`u^f|qLu~aQg%f#jg6@x)FYm=~qDwi(__8jRw zE?MB~9BBZe1tD=1IUxS?HaJxo=%dM>U#62$oWdT8?-&A)>&oIQDsNuX){_SS9!M$+ zpm~Acf&$A|);258z&8N78W6yE4+Q8*y=$?ER*(D_1vh&~u%e?V&*JD}tiDkWq&Pgh zHAzGpj2f!%-e=r)L682m=;S^|JmZI1Uz~Gqimw=>`A>s3CjrVTt43qVc~c-h`3&?4 z8AG~S%2cQ}!U80|atc49Zb{80=2?n5Mjo$7g7>G?E~wHpE~;-m5r?zBm%l?ztFroL z)BW@;>>P}>L|hFt6p5L0=3=v;-%RNk)_7(T7#a{#!q}`C@7}m^CXAcnc7ftHt>wDA za^X*U@V-*EyS3TFURcxiN5L%y!0{klD<}(;ZuY#Sw73o@ z<#eaxliQ*_oTLbcoeSkv3>Hk^eCQf4!u3<`wS4!{ytM43L{D`~ zOW23&2iSR7co1|D2xZ4X45p39ny)kmbH%$I1f+OE-?-IMae<#?tq?2B_W1#bUR%3T zh7+uT5DWxDUahS!LHDJz4!^kB)E0a{=KhSWmrF?Di>4@A)oWVSYPMY12KQ!<#{PX1 ztnaz)UBaJ8+K=>&z~J3!ILDTnphL~k9o6_|1oIETNgWyivpgY>1fC$i=csSLd;xVm z?w9F9^ge;T$DLCAWf7W~2^vzgLkJXkt!H7#0kbyyV@0UAVxgNP*ACH7dUz2Od!yY) zD+kT;6ihr-kKbqZ;^y7P;K~J-~Dgw8> zJqLYKj0GV&d@u#-AE1wc9PDe-x71y8FT`*KD`*8;hj3GV_5M)v+(CvEW`d7lFJrSM z`|JJX{qh^gMoJV0rBzA6BWznE#9DJQYwuIYu<6E`5ObNgIXN#4nS;p=01yG!cVX&c z=9q_~QKHYsg3u3ypV!_!fWNZRQ()ubKn%1=J-R=c26Wr~kBhm5G`Nn4-1n5nnC3|? zqD7s)F~A9bb2}z1v%g$s+UTx?3H&)uVVUoJKoATPl%SSF z03T$vpuorZ?TTn*RV$P77w#S-|XqKXNJ}>zXbqH7>{jZ?7d05y*OTGlUq+^6W zjI(7cNbtZqgQ)eq-`&y*f^_l(F{{(AO1(`RKd)(l^y`4JC1nrCSi+JNFc`vRVXu9N zvL#>Cd+8q&>#GZL9J%2}r9yCIy086^?NQj1pjXf4!ABqmi-cl}2DbisiHN}2fQL$U z(CW(LK2_lX+xdeWIYuXS?tw7Yt>yKl{SW@bm?y>f5=%WLV@qpFjj8hgvHAga{36$K zO)F#vOuya6z^J{6_fgVN=;6Ykx-jLGf*F~kh^m4-loM~dy!LzCfEm<68)5-;b{U8;5PQNLP;` zDO@-O>NwrCS1V|B#EXzk^+TSH^6mi|g@)Yy>hu!kB$-hms1uv>X=G{Ztt-_Qy|@u0 z-MBHTX}bY5ZC?p7w$=H59s| z^;6Ar??=M_VvqtRcE{*H+=N5xoiNs#>XNOLM_&I!eVT~(H*+>b1!lRLR8sEc=2wFg zYxiezQ!%o=r+~K2=eRN{TU3m^0MDJKV-zn|W%x)H>)b7~nFOrLd8%6$Xs9hQf!5z$ z4+_v}K9FamN+0K>)<2PxHKbawX%nQ@F?*rWdX@;V$$DRD1)qj+L{1Lb9k4?mC2)8? z(D(&Oi2&!$-u;!WxjADFncps>MfPfLF9KA+k?)|}i&WrO>v%yQU(-;dFqojHr=&DA zGz4g&q24Te2J>QWi?T9x@mI;$!NI``z3WaCir|f=ompvWkU)DyRDCdg4p<^8_jdPo z7-IxmlO@7M@%+0GJ#9-9i`UuTf_RFGzeM=MfTg`v@ttg3ccKp}iD&it6pMrhYcLB3 z?8D$e&i&Ydn7 zbWR&~MWe*<9II>_c;(Iera(B*x_zOzxET;uFOZT?xYdfdy})`CJErg0^TH7kugocJ zWwaz`Re|Hhs(+c4=~TkfRm3uF*}Vsp*7j7l%c+Gv88by(M3rSnNDc_JRp!4z`URpl z!Bjsl3XnmM1EoWgzj5dHEVBh*04leVHkZag=OSzq_--@EeA6<=LD<@*6YwY4n|G)9 zOBCUEJM2MdO`DW*!Kk?0n*Gt{qACzK*#@2*-XNvHXfDDm-R7AkjbCnX)SF1IjKV^` zwzgWJ4c$DEDQ@zZ=MrQU0Q6}9Eqwzn{=*QRWxyu%Rx_pH%71@Kjn zCqcBEtPy-sxYf4D*T(o6&9I6V{mfQuQmn4dzc=f;r`q$HR@d^Yb<(DeFcYG#j{SW> z`c^BSg-7)jmhUQ&#S0%HpIs`K9QoTHM*)3wRw19T4Wid5Nc!TFrn<&ur>gENv8D)% zzpH0+Bkl^^#3zwa94x6fNQ)@}+h>K}ph~Kye{2A7UXv{bl@ZVkPVeL(aLOp+7GyxE z-tiV~BeDGH)kO1Z@vDH6j|q3tiAo$M!hJ`&n~C&b?eqs-408A&b%V?g$2EiemvvwsXJ9AiIH0-YagtZd|= zcqeRYY!t*N#|N}hzA0t4XQ%ADPg4JNHlB0kD!LyC$p~IwIyfGx$AUVb{oZo2zIJ;A zn3i^T-zs+Im#S3wOpagB{R(191IFwZRlgq$7tbx83^vJ3&QJW-jp2R5=q?5JiGDMw z{FAhCmvN5(TiZDhPw99FVrC1}de%I|z2Xyaoe0-R}8A(FvGwwSlB~qXSG?xKTKL8H8d7stXJ`H->!*`_u&TUDK(xgDwJh zA|QSJbpmmbAoo85s2N}x^f;WfIQyFJRe81{0N(S6#~ekf6UQ>jXw!WG+hATGTuqhn z#FxcXPaNJlmD;D`@-a^TLASV>x7GI^7jE4TLkXu-@9}Tl7UOr(=1F)(|5yh9M)oTb zef$>Tf#*X9LbT}&xC;%i#Sbf4+NM`6(599hf7h36Ehju{Fua4l^2GD&9f%&m`1`eA znXpZg;A-#V{b&7egmmZ&#sMtl7%F>LrBpd=X1GajCNOPx4H%hf92yoQg<|j(v9??oub+2GMRRo@g5++orIxEw|0Q&%2I$@%kM(A;3z12hr<5Tq4FM6v5N*fUaI)49ulp2@ zamt{TA#qZLYF{$=gwKT)l3Px>w$~Cc5b*Q=wY&V^PQIB#*$r!*UYeUOe8KY#CQJoy zdO2VrJ_byG`t|%cG_9&-6^j-BNTKCdTP?^O#amiN2`eUK&}$_j-&L+5z=fCQ$P4o< zLaVr%;zK*{@ate*eD(Bkrz|TtV||WW_}qY>(D5aLS)Xl--JT66dCZ+3Ob((9J8^?R z5u?zy%NFWDlxq6YZ~%tF5Z;1*>0_iXwFmPOZkG_~MhGxri|JoOp_Mxx1qbGK2_`ln zr9J@o>+K!Tm-08J7}jboCp=qs7U$aUD%NQ#cNCnR^jm#xoE7$`Gp3Oi`8Gy4VrsY| zH7jyHwf6cYV6n@XE?cnhQ$@O6Ck8J>&ewf4!dtyg`ZGzG(wpTsf{JNNo}ZOKO85q9 zrQCLL(Gl@q%(x(GDYNh*DAk*&zp>l{m;uUI5sp zG;W~@idKElwp8nITB6;Pc>AHEC)XuDO^vAdR2r$UT$HVF(z)9~^uabCDlf*9`^ANz z+;A|q70YqcRC^Y^$8k9{Bv7j#3 z{w})>&0w@@0;Z~=2o>A%i2|Z8CskB!@7|_>E4P0WFjW#jkipTXJ`$s!>vif<49&g+ zkYxlg#NbYYmKZHXmfOKN#tjg}EDevh&ie$!A_$5O$sSJd%}Hiv!eS@;{f zB` zGCYy5jzC6Jo0TcRbVDA>!IK55b@0Vw^vj9$Ey%l%>6&YlqL&MG>aQFJD@;8NSdfO+JEs*_!7|RpC ze9gZ5*)IzU%sE?GIEH?tSU|ObF-#2PY<1b?iF3-ayf22{L4&cG&i39na*+r~vl?%G zSm|cd{l6^T#0n?T4x*;U(k%@zt1^9J*8T zo`X(OC3F8vwgE<12Bgvskb2uFR~S$BP?np0)u3=SkUBonbOx5d5pMBaMNs#UfjEaY zk=-T!bAHt?`EzEV%cU!K{QT9sJn!@KErx?YN9Vvxzx)qQ>v0X|sKY9bF83Xj&97ge zWil4kg{plTo?7N7c>@Z|z@OO0=aDn#t4gGcm=$jN25grNbQ>*Zhy|%qYX}o`SLu2N zUET0C10^c8qu}#zh#F+YcW7hddwDqPy%Wa9EFJfQAe>W9I`J+g)qym}Sdd3KeJ|-PhC&aH8^-DbsEc10k(j#ONb#t)9|E)TIEd`F z#pVDBOH#=9)2r08Oh*TXxk|Mw{{@p+&M1wQEj+1t%me6zW;Gh@x?U1+?*iq8^y^-G zJ{*U)@~nDCCU-BU8@(AjaZvns!+pF4h-4BFKs^5X_?W@)8|x2y0Isv+4|eGYS#Fkp z$l+2gz~SgUX`{q;xky~iKkg|5!}~PAh)?IJ><1sj-}_BFHQ*GAEnWd8k?g&nyj+n7 zgvlrYfn}<*Re~Gfw4Oeh)EM8}p*96F);+PIVSbhd_GC+`XWwXtk}r3F>oi;A_d`ck zb~bthG4$zldh?%9n;*b?dSp>uFi8E?lQccH(Vr2;7mM}3LZV-m$XBp!2DjuSebydh zQMA;qZ)ganuUFHaJ0l}oiV{ya@++mIE6pb8kybt(NH~DM%Ferj zu>I1?w+a;@T4@hm(Z$~oIYLP7H&GUBJRE(+5F?ME;~gH)GBWz>O7R0$;^KWlick3I zuayo751MJSAcp+*onSUYf454?0l4Erz^wj!HmisI3OaQ8mTbPQlR;N~!CE{UAbh$1 zaxYyTHZ=_JauupX66`}3=lR?uLxWCPP$>ZFkv6V;)IQdz`_!>0vK_zd`?9W&MweJs zT}&?KvpRCzI+?+!h*`{3Nt1F@$-Dvl79xQQzuHYiIh4&p+}fl#D6ecW8KI z={>UKzr9qQ`1>U|W!`no(->LItGl18cAjx<94M#$i<-rMR@%O;u{(7}X+tvONO#k- zLP9+dp9B7^1%)zs;BYM~R<<0m#8K}eKsXEK%lFcO(*zeqKFI0oZ~Fn0f##4$b`d~% zJiomP4195gooew2#b<9hLF~Zty5g*a_wuh2yd)TX=1eU${HzwqHc8-XcymzV%AFH0 z7V5_-6tG);9P|gY8!%DjxSHQ*mmwHJ-sjJ~vPDObAG*a9p@x00vO`u(Cs&Jp40U%} z4BWWfKHpH2UF?qTxy!RS3VY?`dPu{#5_0n!3k2F6a)l*4D#_V2!nHSRiLq^G@C~q) zX5Yl3*1{m~vDg%m_kJp1#w?azM%%grx+vKA1KGtU1|UvYDqo@t3u7hF<{Cr?(Q5*|O&A(1rn^qn`)dy@dCpDa(hh{StmHr%(3gy+D;;PU3S5nbp z4f}KZOXDulhV%8yK8O277JcGrXj`*=amIZhB7MUZj&tA(C;M`gk7#lGz`^u*MQYhwbg_2)QvGebQ zfjTGA*MH@$!)C^*rwNQZi$r}Fcl)&hs{o#4_+g=h?GY!&1XcLNZC3pUZYOO@i+2Jg zQnAw)`s1&C+U9MV-F_4CQlcyNyR+%nYIc^B>AB*U#Ll24dDXiv3$sP^sYJ@0hz(Hf z17YE;I`(TwTT7(npr551PDUrQBf@Ny=J)Fa8~ms+oAAvAZ4M}0u>N~HYN6pmgrg4h zi~Zy~x`0l&?DLfp_o=h*ejntxGSGSRG@6hXNxU{yPjB9K)oTH!j9?=fVK&W5Uv;hP zR6GZZuL2=6fJ2!02_Qe}nMTjwnXXLwn!YPoxbQYsgS+hDghN}(?TA=BpK!m5G(>x& z*jkuvIs;Eui-%oC)gVa;vHIAH(ZUglvay64prJ}0RpZq$G4L~D4Zn1ym(6u7d}`A=>#(#`p80%8aqRw!p~%Y<^I@SH3`mZTtuJs_ z@kEtmPfX4~RVc* zgp846IV?F%c$<(3nNwPt^C73``|R_(e*SQ|t}ZTlJzw|pzVFA$FJDd@s{a#=#~Q2( ztYhfJh)fI*V|Vht#kteL;rl0^ZN*;))EPj_P{_w?f(5Cx04j=HEjxpL?cU9?v|gv! z3PZwM)8-{1jBs*bXO{w!XbMF}!*3fXu)$GEJD_k67p*w2f#vTT$vFPx00ZSxGDp8CsiY zu}G$lze>{6`>GwH!IRA?2jP#o*Mjh=IUCF#96r)NJ|n-T#t0bnP8=js%4+dG>|C4v33(~iK0U5 zySC}lXqY~{=^iaGttWO~X|D*tTo|f}50#0~QxK=^U6$caR3tkJ^m2^v2Hg?ECk0UWJZyqf? ze#StpSw=nyE{1;u&n$Xo8nk)~4Rg8*5si29B5&Fm@J55!EI15KbPfy(s=Fl@PGRI| z24^FkWEf=>R+z*D!^GM)*baehb_IF!J??VS#GRk-+{Jj}p=ZhY0 zKH69bZCfUtJHQTk!1Hn2f&7l{K0{Q&g5T8H03?Q38z}p+FBNIn8me7^bug!7-@H~ugd({np^-`9fSO^krn|725fuQ4( z7S)(~5Zg#*+MUi5x<_p7xFl+N7VxkzCiz~DK&BR9BoNfH69G$ut+m69r`uDzW!(amSA-?2yzNv67WdQ)l%2i zCX+~4)TQIm?hm=jOG&baAnYv$(t(kYD-(Zr?J0XS&6yR{)@R!s@uUIS`tmn>8zF1w z76P~SX@9cfmYkHmyV}orublQn930JR;8K7<4Y@#ggUBKOR?A-bCD z7^&bS+3e75DDRtJ)9Zg;d;MDR{i-|^R{e@d$5AZh5~@%MXhB;X&V=|34w6kcm&y(x zzlWCJDXmqe1|Uxp`AW)LRd~_BD9z-{{l05QTCF_@3t!3&jyt=LI-f<6bMD!utzDxw z-lVo8juAB7KP4FjJUIb8wPMV$*pU^K$2qE+@lEVVn%IRFTR2A5+g6Da+`Oz?7PVi3 zo3##Ke2=}furuK9Aw5S5k1mYrbN^^@fiSjF`n@ z_y8?tw+e@7Yu}d(kY&bMa_pu>K90?etf?_gsbHPd`zYY!oW%@vwlmXc6CRd3?U>49f6N^!Vhz+O565xvEM5JPiCLma>2 zK2V{&n1~$d%>*(d6KQEcg?`b1?4b~asPOvs)`qtzY2O6W1zcx9o=*Q4c z&+>5og4R(sX;#wCOmf@|c$E|v4}}K&=8I88et+?VBdALV)>`fuoPp$G^QHBepCUI# z9P$8>c2ADQNIMbW0}{X~I_F-_hdZh_XxpwChl09K+9s|RxvLm5q|F1jd9&|fjrcv- zAR!-C9{b|(d)QZeGjd+F=WVwpV|gqJDaiQ%(FltM?P$5TXP{AO12J8=hQ~YzeVRH_ zeCu;ZAs+}_&gSyaM#tS_3@v>f9~mDXIbrhszGa1KXJ=>+r~@J&HDM&QV7dd*pHKl6bC! zicFk`ei-78JDY&ll5T9HYU)l-^vYC$hDa2*cbs>YAaKQ?wkDgZ;plIL$66O3DCt3< zPBabhMruH#6{%28Sj`2~v#w>6*?fFxx6vXLxN9?uP^C?%dm=)}=Qj@V9%8s!)zwxT zbJaIBxs9fqYS_zWHXKCyQX6AtXqwW1L7|=1tI^?xMp4C$tL^AcgkZ)Yj8(>SINFzn zEuoiQfQTA9QW4az)(6-fh>93#XF`>n0z3Op%40}SSDr=w(RmpG+*uCDPugbzK2#xG z3?qPld6w?no0d9_bw2}%Ff@Z3ylISt>q`vHbS49Lhryna|1=)Mr_nGZ0`xH4&w?$S zyUNAi`AZjqn9qCKh4d}b&5n~GeavT{&rnw0DD`8 zgTiz9lYfW*ZcOB9sb^j-`j?jtMastK53>r5ra?9;4wojmLi?>!_`O4OyLL-QrT*x| z#EYn7EB6W1b1&X^ocnObJNpq_XLn`(V{M*&EbB;l>XQn6<`)>78c*3_+5ry={o37X z%kqrU4aa)v9#UGj#$$zp2u?@@SXPR?Qcjvt1{xzqh#l3x#fdr6gvP*pEtrb!3~uUJ=QD*W3pM^w1Ddh*M(!A-!m>qe!Kn}GC7!~0a zn2|m(qNZ_{1GzO)*f{!)Tp601mo1c+on1~pOFrJB);l2nL?H$ywnV9R)q9HjNHVMI{B*)%{r8mXBOXNKH*u?yU>1<2ia1GvkLF&Wl(z z!r?fBd6vG7OpJ_cYU}Fi=!Alm5u(tx>Bje5}QmX)d@?u20)b2g$LR9}){$pwR_ zH@XYrf~MF-LzX!BZ6!#k_(t3AQ2yw{A0JIB#^Cv4xD4K&g^r%nfJfK4=bh(@;Sz@f zu~TZ*5qN+Lv%j>nhDeEXZ}e-rLAX? z%IK)vx53+28`dm+a@J_UhMyw%{omAjkDWvl@3?1*ySlnEcK6?kT*^-%ea4iYO{v zW&q2vxAR_Y8eTfg3%=4(57Wr%?XEfmfk_T1_YMTq-rC=r_`6pi-z-jCoL@|mnvv~+ zK%H?|>4{KgPTu}{F$j(g-`$n!?8Ij6QSRekIs|~;*P^HKG3VpQoH@?Z_5TfD*<1^Z z*lYBOSz7w9`N@_JW+wgWAMdFlX717)b?4N#ua76hzbRYiB+Qh)eQ05AYf;;a3raH+KXPmXD56|fQsq~xcW?6x-|d#TXe6pY3sr;IXoPO6k+EVix-o_^XMeaEY@e6 zNN%lVW*^rFF_XrFhW0V=no5ScN6y;56)fgFJ#48W;)v}IDw-Bb4m3$~Wil^a&!f3y z1dgK$8(&@_nEZUh6+^5nkCtlv8a%5TbGnsYpUTK72{| zVYo3n(`ju5|L9p6^5^@UOEnwFqN2`pg=k$fFgr0DwcYo3HY0Cu06}@zxH-A-?p<(D zzM8jT#5Zr>?GuIIvuH^xK-?E~j0P z-D43WRqu9IdiSDm2$#I-&SFSgD(Ji>kP*G)?bTN{5l6g*$yv!CqFs&4RVgc(w}wl7 z88%FI;B&)@FiFo?>loRdpP!%pzP>&^?O1D9=f!I3L>vIx5J=25MQM;P$sy_xfJ0QB zojt;)K$RJ>W@cB5hM?g{sMEkgCWs6%9#qEu)4GkSFGXy^g&I8DX8qInAF8DLo{}ix zvAcVOEnX~1QKoyyMce1sw{WuA*r%Xy*QK1tOWP2a>W8(FK0Z9qk0{DLCQWkUyJ5d` zs*15wqF13f@!Gq($FU|>W|%D5o}JhS^i$E%ivA4gLX<>Xze17|9BqZm>dg!YRE8mm z{!{^1{0#y;1`b;0E9Hc7F9gy81}_I zJ3;;kx6I#LTU#rsQlWM~Lj8jL{KA6lj&n%f(E@(QHiXJL_v^XBQGXJE*WjG1p$Q(2 zVA_guqHnkds^{G%ED3#^!#+F+6^Yt@Ln>8%;yhLpSZ{p}ZVmkto>**^0u zk*=z>Gjr77*3BiuS!9+|!zZ&1I zlHc>|Kc`pUm(jg!u1J)UB=9_sj`6%zEFWeWl_(et&eaTt$dy*f9wrCEK58^t`|aLjQ1?T~^7mmG@m!wR4g=+A{dAxoM9 z^KyrY=aYEn49>-F((B8ms9&!&v7tX9IuJpEs*<3raU{>E%@w-KC+4F*zO}2!71CB$ z*S0#xU*#?e$)VpFtNE8ic@!zc&54c^H&V$;99W&4q|pO@l_80e?gT~PR7d%htE4G6 z5Qsp3st?gI;(CR+O?V4(dy+-lVSY%B#ry^scbq7OHcBF;DUUuk?;etAe&3Yc3!Du0 zx0&`4>Uq6vdbq(d^LjHGqm=%T%+~@jZuOQr+8R6a)z_1fb5#O+)vt%YfU_TS%(>Sx zY+OJb1(dd=NBm5FLlaLGR`Xs~vz1&rbY}9tEw01m{4XBKR9vC75*Gl8~e;tJHnprF@Pqap$&IR~@_ z9Y+fV+{iuoDW*Yz21tyFxIzme(E6#lM?no~6qbrk-@VI^+#;YARf0Z%Sm38+npF)7GwOZ!$+M zUS3}Q+O_K+BGzZ+b$6XJ#@uV%$LJd2u78)ugD1u(#_cLpWA*>G#Bw%#TqiJxTi zrDG*D=g8tu1e|Q&8@;PgHBK$!l5Dpus8Jb3cn~VLUC!tAB~;abjY<=bjg5^vU6oFB zp1Y{_9@Mgy9C(DuagZ~jQC&^BFwfHfA<{TLr~UWy7d}v05RP8TsZ9c;x25mJW!2Ab zIb$vtlGnyNB=By9t0bcJZ7f$Y;V}1&F=d>U`b>9K!~6H|)tdjcXm{c4g=TSX8aW!A zqA^C9;uJfp^q%cM^INYiePU`E0SoOVlbKOH zGV5Q@&4wrpdKV0paIP#uL~ZTw7U(CR_y4<3nev6%|A*gykdZSyb!i|`aHXMem8#QR zzVfa!v3Tz{XeXO5hK$!nwuS#}oDLk{V)MmiPw%+whkX;}*f@A+I?yR%#=&g{8H0?j zGwJ@R)t9Fgy1F&TDpbnbI_m(Nrtg$H9e9~R_8hC5H1G$9&qqX5`i{FfSvcpI? zsMu2Mh0*QLU(Q8~ioz6Ip-yT7CUvU{jwoBGKmBklsD}2u{HPS8-R3>k^~e>#CU8Tc4l`Yg0|(KUUDr}p_VfO%<=tN&)V1y%MmQl2 z#=p>F2L}fe5)Kyr9+qSDXX;szDNu@FRIW2sb{Y=WtK2jY5_F#65S+;mKEIv2BH zFDq;*v|VHB2-ba28HmZ%CBJe`QmW}e5;E{sKcTcx@E#iviWxM-%uz=!x9{!-V+wBD zdB*3zB$^Ni{n=|w6~1^b>YFvkfM_^-G}zP!a=ubbzeh!|WKjSFhzLH*xy05=A2s*z zQcf;_=$8`jitCFfiH&r3IBs|F+h=EIo3v^muV4++i`x3%92*QkeyLIq4g0g+W%9vl z3X&Su1Y?+POoi5j%6mS;i}_QNLYN`;TxR%yY`=O{d4e3VF+oLOFxqmL-Etj$Lvkz4z1n~W*m@=|cc zvA_A1{zN&csv(84?;GsO54l0?*dE!Q8&OBT*8M3WEF>%>vUD!<={(BpMxO*Q_d>7!(wg0?e4oRI_>#dPrr&6lW7}^QIJF=g(lYEi6#R$M55P zGw+1&1`jCLSDB^FZg+Id&2@#vJ|njzCP;Al%`KJTBKkVyk#~06l0Yj-koo z#z!l4t0D10&6g_UW}r^oYytGZ{ur!u0eMpg0_A-a2Nf~f%nf$7^`UPAB=MI%^~CJg)Nm=~M_rah36SGG~J@plk%=s3KciSuqc`^)vQc z?lcHq+9P?hL9!2lmsjOFXc5BJ5x1LaDcZu<^HIMU=lB!qp3y=HewpooI89epgCb_w zIFVS|XM@%s@2xUw)=Jw4lZYrEH~%DQL$U+~wPb!)P+kI?jCFFCQ@ zK!1W(q*^rOA#PqpIbln*?1utpDaq4nNn&UiMl@u?9UUNtjE74=*&s-kVImdZA$8ZcgD zP3eQh#A;AE66raQLaoeuHp1%d&SkK`fh{QRl#(iD4c)D#$;-L)3^jP+j(2JTD!^DH z>=lZSQpO)`PqvUME_QX5;?Ds4)d9B-l)&%ZV4kCl&|Uq^*K|#%bGHK&gyK;c#O!ua zNw>HW3J3$kgO_wdSmXwoJp0B_idmy!~(qE%||0{_gFlHlt=gLIoPh%MC{yj&IV?*4EV3&Ff{t zUWpqw7TaJi7i07kG4L=To`s&FYC5U2!yRJ;obgrVTeT`wOMdnms+E%#WckG-+_^Cl zpiR;e94jqv(d06EoUJSZ2hE&c_^8kjkm$g2_q!5l=BC(sMp;k(o3SF2N6Ypi!#hRX z*{TLSVnf`I&g*$6osnu%cxIMMFmsvb@3L##lzHZFwPU42VJcb0MyEPf!YFk#LqDw- zSBnRwsh>`b;oyT<8z+FAg_f8B=x98IslqbGWjI^iCG*Aru6^hfC3!~thsh}^zwBs8 zxu>ABj=k(^{+q0ZPiws{1+Sqq$L^QP-F`f>1k_0IF5(tMbkJuY^}^`J8JRMY9`$dXx>(s zBVK_Dg(A=vlEUnG_Gr2$zZT?E=#u6`V?wPmcCN@hs{yQJJ|$@N$-7n$4pv{fE-a!Q z83xK-sCu6K53jS*PGI1^c-+t^I|&2QDNY%(BPYvBvaGvzwzlSGI_-1qfkjA3+G{A! z&R*;uh0|v|>sm1#AsKR9N-X|S0dMq65@{y2cy0TZk#u49RY?GSk}KD?r`P&)&)@;! zN!$-F>PwR;X}V`}{K%!#FW#%L`DF5`3hm^sWWC?HfBk-B+aQB__0Q3%;9u6eKJ{{x zQ@Vb(ywfK>dgT2)4*9@kVLW-{E}sQV2O8J334z2s$op(e2*tSbSVtfkX%qp1i|90g4O_-yvZ>_(V zO^8c~Y;LxelWw8Z6ent^s|zGcHUABd5}k&LeN|qa>t6wzz$Ym?Q{hW|Xlv;{8ZA4R zM?_~`PD@*3v`iIe6aC zOS<#jq!JVjtz^x62CJ(Z+)*6_zR3r7M-ARC%$PeV?bp&z#jWgOW zSF(!+0y$`ll-Ssux%8n^XEYE;wWCeD=4b)6BU;+(03HU<%Ou-*?v7Gd6~m=^zoRe8 z&o4A`X>nZlPi*q<%^)s3!0o+Q}JL-GF zvS4JRO;7u|NX->5{z5_Pao?Znn~fIh@xgmmR`gK@e}8W?YlJou@q zJgbfkUg%C=;sLZl8e?&v!EjT?z{&Kpt_yBzMMNU5{&^q0XLd%)K4Pa!>Uyr0hPJw0 zg$327+bT*SWOsp+XCl;9>(mCYcn6(i80ABp!FbJD$Mm1+`To?-e|tkYd3~6T&EVXf zUpXF`E)+X26;{97`ee&q4%uBCZ#rOo_#d-K8fi2zB-Y$8miO$5$J%7a_QsiZLGO3E z{!LTw8bP14wa}g%do|)=1@ag?Ncw?AZ4P0hXLe_OecfNjr?4Gy5scnu?1<=QlJ#8K z(5UtJIW{De8KXk8bj{h63#jKJd!`LgPZb8>aIB4;^*?`B{mm}~mIe%c2^_>0mc4_- zh#P@mHX=$QAsNbw+O|QB@57;o$>~-}p&J;%!pq@yj8l80>{6e>c=m~Y84e(WJ z*Dy1RPG!4`^vp?!Q(0QP;vNwix@W>J!XvOsd``bd;t4E(o_9!w#I zXyW08!-+zj%7R}_uns_y@^ozFEKH>f2?GtNo(|ypbU{xc9^gS$%83Q2MDS-tI1?(x z5|_K_>!S5h~^oO7IGt{2%n{@2ayF0?fQq%`j4NyC*8 zg-mZRWE|1#QfDU!AQ{o!pJraq6DF&&CNHKJrLI`|nxv(rbcc6Jk55c!HidufF@-)z z2fOXAI%gu)q^7oZs7EQzuJ&rg1zx~$sNnb6TJRnhYQDIY(?GAdcdu!>9kyIlP|+3~ za4+IYPy30D2M{$8k~P2=c7FEHY&*J>s~Lbv&%*|l6Ki<^C-Ai@OC8Q`{6ZaT>!-AqvdvUZd#Jhfmy@#eGsA2M<1mcN=ra?Ri`9m2v|)Okb+j|$2%yy&dDv{*2V`2;JUI^P0$B>YJHia_DB$-#b9 z!m%Wyx7V(eWCm3}*VT^9bRL>p|EY>9yJfPIu|gX<~|8 z(+T#UP4cXwp{EH~Z5l1hVtDYA@aQ#UeE$AR`S%Lc8dG!J&3Cw{G@tfKO)@}n|N zx1_g0Fhb=1wtVeC+teq7W@EN{>F=Q6HLZ!`91_Y#(`CA9@56&#qg1;Fl#PLf)brOS zTA#v*pVv|ctKJBUoW8$5%U|8W?WlGt5%4k?i!}NjEZE7z3DQo80x}uE2tNpx1*Cip z9gP^6mvJ%0?)PL1K+sxIp(9EwVw3Ok;+u~)O$F_qvBys=kB$FB1pZvJWeIk*8z06& zARn_B?|COwUwo#L=^emiKg{2MRGF-Tk>O}CxJtNGpokWQE)iNpeKFC&?kR98vYkyV z`n{4h=!#`}OzX}Wz{GxD1kuoO^wP9}bj3$pTyQt?Xpv&K0)9|jfIEyfsx{$BXXT@a zDX><#z#BankAm6&8ZaKg{3}w(=&03d-R*>^U4Cbib3YQcBVN^vj*kc?VT`ijST+a@ z?L=nP-B>C>RdzcP6032zsO_Kq{K+E4MmtlFMUEbfT^k$(iyqKne;XOset%DDI;OJx z{lRCZU_|R!Sy`Fg4mBZCtz8obs@zX4H4(kWm9sAqD^W?+kt*ZkjxjfBFtj`0($#lT z1t#)I(nz6{$!ybJsl13&QY&C3aOI$OA#PCFw1h;;Y&gnry4v9X(gd`n0I(|yq@oDG za=nKx7|X5z{PWd?j!4aLF`Lr7?0%etwxVXTl}LoHgcwIO*W98AjJFLRSkgr3@bfGy ziSKq36n!hKkog2fX8oA|^DS(mCoHx_A$}SHc?BF^6_jXRD%(Y0Z(wMB*X8ACnsXjb z1d|3*ck0Yc{wH1oqA4@tCeEF{+r_!WZ}==j!qqW2*hk^i0%N4_;Qi#sYf=px?o(I zRbX0DneC&rlVqw8$%~F0JZto&xL@q=`u05Y~62ytC%?pj2a6btRfU@61VK z=?#ZYQ{7me5H>wLmrJ$@I83*e0h|h~d$nZaSL<_4!SFQ$VR!NzRH0kPy^M2`69eF^ za%1^jRvFv`0?|W=TKcH4;l-~(AkH{JC-oT1vhul>zQE zrs>XB#85jGa@jAJO6wfEY+ZGYoj(bEc|zLdzwXv&=H=$of=aZejqj2g7<_yLPcOh9sdwaKeS0wMx^vvMkvAE?s zTGy)YfGXt^rP?!q0?6xtIPa}?6QZ*_ztim;>D5F}YxEnq7~rgNp}|7B$Q`?U);o!R zWn7BR6aT*!`rpCvc(HZ5b?Hm(ey;4X;gxfb)@-aK(LWs}A<&oJ;Ch(uk-Gk)XX7qK zIzED8=SNEwpDWyJYm4oo-%&axVbsor`FN#d)I2B8UMKR;9a}Tgto*yHRirUf58&J! zbC~xg^*KDd^4iQBoM~NmsE9-fz2V%Ic{Xn0+Xjk@!j1e14;725e?5lRJOj@f`GMV$ zaLNg^iT|R(+?8@}W%r?B&Q_oe*`vgY8!5EVwj0W`HwlNkLsN>}v*CENf~4z7wY671@zYt@wP1elC;V5X^{l)yVl5CpHe8 z2KJ-K=~pChX9fAS+Aj;-q&tt-LG-Cs+2VKyI6F66n8N%9paO_6>d)s8qP9m|af9;< zOXJN^y3r8cUpxm1iWmg*oBAd70)mxOchNMV!>BCH+xal>07la*Ow0w65enE6qZo|I zH<9%jH5rzY-sLkbXJ{at*H6NW3&O1cdGlHvP>~fSpF4mcodlM)Ox3GPgRS5b=dmWn@@*@JH{F{IX9OUPYWru#IErd7iSbRr9eNFEZj*@_uyGP z&7cIs6a!i=g*thn;a2fjAt8#ATRprx+h^Ara0ks)ssQ3hA>3J;5;F)J60gvT2wg%#ZM%#?rz?AMWs$}Ji%{FL1oJvH%wxe< z;cEU@!~yoVbVszbbB;`~)N{ogZ)ZxbIVp_~jgWeBn8CphDPy@*OA{*52H4WNk_S99 z{i09A2)wVvubeMPH2cAzG;S_V3|p%PCh{)wg!u^_K)_q*R`}b;FJ&Kwpa;KzR?M)l zP^PEqzr#Llb8{o9oymDx_f6?1W+FaVmJI{cYkoc=Nd2bimBPd|qZBJICT${N##QwWXPq3tMGm`30XA0(@)-LC%e<++m!*fS0>2@BIFX=(%;q9wcPP75(= z=~1h5#q>wOe8NH5+*&tu{ril41jxZ!i~^0NxIMYa@7W}1_IMbfqR;}OFavl!=ll-S zroHjZf}??pJhm-FWVEh6+g6Q9Gz-KX02SBxrk@-*Z|;1-cGaa%{03{nRdC)bS&zZF z^O0iwsrrzl+O+*53b7^F_}5lAykS&mJQT3vn2Nwn3ss)XT(hsZCJ5LR`qA*Rtlxk9 z_rFI3h1JWhetT}-lgt zCk(Bpo)7iI8XmtS)`}M;z>A*qL83hi`|C+5$b&IK*r&4IsRX&kDe(Q ztMj5%gOxvghH&qs79yGYcgOy(2Q9SpbuHM%1M4pTo2J;r%7odJ1XS;Uc?rqgc9~+g zL|bIsQMQv$55=)V*rRb{=0L_{4CH-QX@*nTrKCe4W7kuYb^dhy4)~Q*F-8x)L9bnN z@bR%Xh@e=`veL}?4px{|ORx2e0Lnod@@ zAy~mm2tkxq#qd>gAn>BYt>lxAoirSrJC1yv<3|Idmn@4HO{j(4j(e)8!WW}=D}DBE z<>%1_&!r=e4jeL(?}~uvKwAY)e0vy;s`{wDlp?oX=*9cdw5zJDiRa_vBKP#3*|1tR z225*90G`e0)cCaw-bhpK`{L? z13132!3O8(ZdwnXClxn>s`L2yQ{Zg=_jgxko+IJiW{{QmYtyWayVVS}LO%#pANp}B zN7HA#v9VUOH-X(Dz&GS$0ZNTUaA#o@K2%p9lX|lGp`2yEznW@Sks)qkV*%~&4}l>+ zTl@I<=tgYOLXqqB(cinV|4YDJTwDaa((UbSPLYVW6w3XGfD{8itK-$P{#q~M)v6dLoNJ{IK|a2j zn3x#9o`P_4BtIK9^Rl6*sT@4`rLH$Z#r{8LLPvhLYE0_F%2ol7ZuYezvG@Ydmq1xz zEa@cjZDh{fc2=5c($33ns!|$pFDTT`JaCZId-vw>Mi`}gE#KXGsn<=dEFO%gYX2yM zYqgugPV7KY<4@h)i_9!Uw-fx)Misho1z*)}5(_t@`3{NdJ#Y6z3oKw`cn!uHy4HFb zv>YCttvTB7BvaENFRNO)_i`Jlz6W{ZQc&3ZeqS}AWR=iGPaq$u2g_!G*-(@0+}v^t z4~WBYLu&wjJb`mFh71!$xf$k$>djiJ*kPPNlPeJkt+|jrSd)>2Nfp2Ha8f5^DV8%= zNh6m4yi4-|ySl}#X@tmMy?v>9Gu&n{#~uuS{vWh-)Sp?K8szMAJ_k zrGnfSm+1lrqAR-59suVa2DIlEj^`O^rY9Y^6*=P^u<%!q7I@R<$q*jMeC{p9R+?rD zhtn5zA7T|<-IWZ2gRq(t9IcXt2`8%%>Gwd9^!Qrbyo_wxWsQ>!UXJzpXG9qBl0ysB&?-=)&+IXZBh?QbLU@=Pe z!_JFDEME)98iVdtK)?`d61yz`TPLAI3<`mmRZ*h;zRlR!?}^&)69EF}P!q(6UK|7l zIaqoGA8n!{oHVW0f_EfP4!DmFV&pB(l0j<4^QUFQPWXGsN3pjDRjl2?|1iB#GaNk1 zsP`9M$Vlf@_6$)&m@%D1f~1qMU+X9O?;2eM!by&Ko(y6aU-Y_^_DVuOD;tm1w8YkV zxvr_RzfG%k;AY3Oi9@j?G9wst^dv9}c%_!4=1M;$5)q}=bdTwvCLFp{dx3tc@Oa^R zTXJNWukTYPha~sSFo3G`GWYbOltvDU3IU+S&ktEk8Y_~!5~FbO`ArRhBTJ{j+&l6_ zY`@2TUx`)xcylR1+>vkqMpk5~V@AL++qqx(1@O97R{U%;Y!mDDfb2SW={6oe8QbEZ zd)^vAzXLDRkRES5^Ms_vTVwC0IJQ91jI!D7c$%>|d1@27A@ zc`2A&lI+IV-J*f{0%zQVO62e<%_o;ObhD~%RIx!UJ+g|VdrYNq=7ApBejj%nw9s+O zm-Wzz_mEq(1LIw2UpX}=sx?88Nl+Bd_V@+bBgz5z!6gA^%sr^Sg}^*X`5+jAnCr8i zMK#JmWCV33n8H5Cz7zff+yzAlDsTs<|J;<7spaM#a7c8t>F@RL@5@N!@deH$t=HLk zTH5CUBnxZH^!R^Xy4NyhUT$&Lr`Pv$j|FR_qpuQ~XfmElf@y&PECg_~QcsPv%ALpR) z;;I&mI$Gzx7Li)Cr>`=ZeNiMut!s^s7tJwaQWNg#qjmZM_9!M6l>~?=b8{sFMP;Pk zu$$(Eaf9#}b1b$n?Gcb_DIBcwvQ4`bYb2DQ_5{_U0D&~Y^K}ugjo2ODu&iOvHg>I| zo{Ae;rOR!p#Uq%b&&Mg_JUV~iX9jBgYpp9(Sn|ygLZVIKn@^AZj@pmfZ#FbpzjPn{ zTc2hC+20fMlwDH*Xg8U5n=$kX=K zaeE5?NJOBK?+F|H!5Jyxx{vuoPkrL*v?W`9TIq9H{{V<3e{wkjIM3 zR+a3-ou<_evU#p<{L@)F)_=RqlKn_MFmr!Ya8(Wc+>&*F*>(iQ@`SxQrj$~3o3OD< zQA@&|&1y(DWrx9APrvwyugPJ_JZYG$Am+0gWV`d9B`Rv*KMFV#{Q*9@N%_0A^!GkE zxZ~)!0buQPPx55X!wV{U%d-WSt|#aHeiZw7>4WO2`VYl}f5cJoQ^X}&os<>%Ksv?gkh}r+0joRx2hm%(D{J#Cz>rihz%7r7IaOtDU$FbEp2FduJ>hoA~!DWwT> zNZ3c~zK1VkfFc&eLV5W6g<4&ZFo2&SW;oxxQYgMG%*)r|ew+((drW32B2&^R#s8W< z%y=y6(HXQ~dLgV}*6}EWfd9FKk(gMJ_>nY+^KJgo2WU@;(CmiJjv?r_$ zPRPe9*)$a(&-9LO(EaH}-?sldWPc1>9Z3~%ey&7#S3DRyPBHL3mqzSuu+&_dRzB_H zW9WCh(=VlnXcF&!suPYx#F*@?&#!l-N+I7*`Nk=H!6xq%BMd)#A_86BPWEYMwKm%`wknowlh~J6Lq8Oat4jE53Tx==Sn+Ay~|ljBY~PaDnuq{>RXC#?4!vJAjmUd+?U^2s~P zY$0$h7&1Um1_>4WByh~69WjW#OKu1gg0n-=t~H|2;1`-S`x3Nt;b>hTL*2D8<_@Bu z++ovK4fJ~#yPr?8qd%&L?=HMs5)yL2UtG4;9>_#G;~jV1x(Ep;!!`@e@wRKE!Dq2 zlJ_T*_m?-L{`T$9yZVerCGgHut^lG*K9C=@{T<8u+Y>CTbEC@7T)p_AsNa8Tv3^$z z;?De}3=><`PQo~7MyDeWkL_htGvheT6u?&Z& zl)xq6TEMuZyEiG-IF{P~@?CQyU`5g>;b2W50`y96DcT({HCH72^OTmi&5ezkx!0z} zuT^_0XEGY2qFi0Wm0v8Q^bt0$iM3ck5y&wyEFbl`ii<6gIx0)cBx!4eRoPXb3XS+A zOuk$hjLe+(0)6&wOC!$&SU-zy$zEB_zk%g|A(&wAhzDHN_!$%$cDInShH&x#wpl9- zcdrOvIJ=K+^F&{mRl1}t?kLRuQ}zx<$#1Z7>4^M(#^f}OTjxrv z*3F%k5=phPi8AC0MHSUsUNKXg|M|e z_oJ$JB22F$0Nb7<%W6n59YfPnd7F-%vq%Rei2uYca46Y^g^z@KQ(gu&J#k`tS zPBawaf}?FMj52|SrqD`uTHI*Is*h8*vFV%aFvTvta3qHUn5PpJ-K26A=Xz8rh@YYS zW$d~W&79SGc%6W*QU1^lyHh&P*~9KyuVR@nS%vVINZk0edukgba+d@ zuMqoFQ}(z!rKO}8h>Lqg-Ue!hY8?&NL$RDiz^UyDsIrt-32hN*tZvp7zHU9D6Sf{w ze@i=Ld2)|O2YyxP^l9y|Kd(t=uYx>J6LHaYXDhiM2@UQF5`MtNu#GaV&D#-Z>)`=! zr`YBBkE#qD_*@6DP2;ijz{3g=tOd^Cqet(I+0k5pcB_^oHPAD-R@`|VY*RzDEM@s= zJGa3Js-i3`#O`St37yz3lDUFj?#zo!`5k7G2^!KEV410KifV#aT)ZsB3IA_vp^virXi(hw#?rA@1U2y@Q?(yVtbZMBsu|;i+cCb{Q`bs1NJrKz9xf^6R`6A` zbdt(}Cc&&WyZ2=2MpemKAMW3@u}p}e?|~bP%oi#$@?Y-0lDn2U`%PV5#&)QDsKtZl zmR__&oIor40d_6?%k$z6G{g+|nahg2yv%H)l0u^K%~MXfMkZ6Jq=#_EDBw1l0ue}U zT~Qi;e*quYesP?#`}1cB-P+fWNz2J0pZ4&yJN}PipmVl# z_2=A5L1(fBpn>g7PEOkIZ8xWoZ^@oC#TJsyWV!~(Wb#T#rn5HoiMcfvXO6QS0;cATXVs?bxTVU!UC?BDO#_g@cRU#r>&7Q=uG?H>{n!kmPkX=0Qy*MP6V-8*Ag=Q91c%hHX#PtFv`x??)`kUz zKDl}$@&AZA_i(2FH~!C|Oeu5tuu3uHlrV`ogyxjxkO`4fmL%u%`49^+Iv6>OLQ~E; zSI)^4nIyzAhs8viaz6iFeSg2}`u*E=RXe=*y6@M0Kc9~$LHsWFD{3e+!d-})tyvV@ z<{d>LVpeC!oMLbs^7K_-eWlpjN^?dQJi51O$MFxz*~_g@z&3t4Ww}OXQ2xA~l|i;X zIJW+toYbjVVpQDbVFcAE(9aH3@*!}d2 zZHjQ&lpx3rAFz>&uu=VTyHDmnq8_BQRD_pndGp>f0PwAM#5V>vHsYPTyQQIz7Z-u3 zl#@|DQdWxYSz|cu*!%t&Fw$9E$Fev8#NoP?74$BWsxFPc2+b|s{M#$d6lSLXxfv4D z510@h8Nd+$EEH1db>Ol>;)rOnq#BRD1`19iBO~!-U>g-yxKmzBJ^2)Dg2Jy31+`7M z5rVH1uyPYWj7iU1PH|5D`UQk<3c?$CA@sX2{YT&E^z5q42cn|Dx#$wNzP7ft8=cRj zz^QYaqd&tNG@1k2)i0=r9ddph5sI2ybsZGUCGn$y8P|m%2KXZc=_Y`D=Sr@IO7vK2lnP&SXOhW z!>D?WQ%MX@SFfl8GO!cqcBmy9UfdB@RF|2|hnAIqC&GpoR$Wxnv0=i^s}_P5JuZEXRSzLW zT)w1FI&6{zQeAar7J0V^e_B62nq!S|{SqBhbN*PW^kBtLUsS$l>cM!zt8Z_vSObr3 zj^c>DWcuRC9s`T>3(ayp;Idf@Ca`vAyj~||G+<7Yn2digwJ-)Jd+*RziqQiq6}Zq3 zLH1UPCYmBxjwDHJNtgeS%30>sqz`uInwsqugiOch8ms`g{RkHaycwxsn%k)r#W%#e1AK54T~Jx`cV>iJCBNbhht-s#^QWzP|ezhL2J{~>;gQxOT)_V zWDsLA6|2rlbL+L0F7v6OuEEU&A5UM2R_&E357pVKeX-CmqBpl>xTh`1xVyaH#a@C8;8AEzoVC?%p-Q`Gm*i8D}mZhVt5n- z#?JI~7&0BI3p!bTa%F4RQIxal<_V*L;bE0zaUMRN*ns@^+)NQP2!o;DgUPtH$P1vs z7orcIGZn~1C|^p_;i;A<7~s4N^BYj3dR-G-Emkq8Aa=sLi4?eH93QaS>H|Q5t1&AUPy4_JSE8W2+pc{DZC0$Xl9(xRC->Y0E?R(S+Kfp zlLcdu2Hv_0#$LH%DBBX?`%tpF_9!~5_~UJ@9J6BM$AR?hp>T&xb!dUN9Lr(&^8OO< zp0n0*-~eRCY=^|uUi-xQ#cJDLn%bjBXOgL*9w)nAR)R~iFi5TB4E6V~u`idwSq=UO z%YQ!VtOQC|FkOzE1#`84^#EiWi{2LF>ucm51xC?f>bZ(Qqmit95cZ+QF{e1l0mull zu7vwC%^nvo43&D9Hh2lAxQ>4v9-H#r5RUmH9JBQzCK=iy;5%b^U_jb^b*r22dhq$nf&W@tw!U(6uY?| z=?z`jA%rd-?wa%rBBl!yFoAYJ#i8+B?eT!m_AxLSg2mQjgN9zg8GfXtODLAj0+_@_ zS4qEyh+VaECkm0aCfSxq=P=x-uk{4KxpviR{HN7>3z8Ht)m={4hyEscUH?gPB?j)n zlVwj6ocX!U#Qdr5WGEVFeo$!GL76O=cpNO87Y#*2nY-YQDlaT8EnU00Gwsr9UqQ1* zn~Yg!x>~87g?{FGmdXv$5Ph9=j45tLTBma*SyZVd6+L$chYt#vM}UE(&3@;>{^o<2 z)sdKhz(5g*NE&6qbZ=AG3FCFDdHMHEkEXJ5$04u?JjP>WoO2|h2*US1v_&?}ykGIw za%pA1!Y$zDotg1Gs?-{?UjZi3pK9oX>5S4lgk>=B^(rd{ugGKY1P^7<*ynR1Toy>V z`&?SH92^bBlNr|0_EA3Z25r@?h+Ih=ShRv3rX{V&@IBV$vEUezT-Rxfs>a;qXAR{N@Q(23bz=Z zCv251Y(T@XB5gAq{PjsUgB%*YXqyp*C|h|US6c%=;&XRkeR<4JfuX4pOf4xDvo9)( z2OtI_=8X+HTXRKVJ-8a4z8b;W{lTH|{$@mk(y1ZS2>&Gr@AyDPQnwEz;s`}-6>x=B|PdPDGj-uQU=#BzrK zrKhxfK?p5_Vy!Ay{1_c|w-R)H)aa!L>!}I+%;KgpBn$C(ipWG62;ek)M6khDQd)?39KjnKh?wb(!pxUM`m_MGuqbhy$ z-;Ob#*Xbb|P9tvb8sF>u)SEbZ|yeC z8w4@D2EMIK3rbJnHHBGh1Losoln6H@j(Aq;x%_f*33rFFAc8Zm)~>#$f^er<4XOc? zUpa-i^21~D0y_-xmE5%jkts6H@uxa0Y4OKTiS=Rm42U&@LE|jGc(|;q!m{zgahn@@MZFOaVX9+?*&PmkTuz~9YMWL7`UknD(DUu zt1U)U4BWfR0|=H2UOBGzNvl#ZJ9B=Dz0;DFJ$JNo^YZh~$mWFr&5*Ot=Ls5ZoHkK} zmlvu{PiO4;LXgLK0C9$kt-aJ6h~pGHIXR%ysNbvM!*;Om&n7grP=MZ4ly}aqp?cC- z(3Fx6;FTS|&UtG#eCIN;XfU<4WkI`a6))G;>C6F&Ed(ai+tu~UU;X-5s{_ciLMZ-W zmtT$~!H@Gs>&M);LUAvQbI7u%^?lQjw+LV_8E4mT?j;aD0?jPr>+L;j+5`{Q^i?2E#jl8-rzxw6)ka3@OOw0Gw5&2VU zYnvI~t+8c_t9KG(T5gK#LMHzmZ@uPyI+EVb(50rnd*0e@zNa>Jx*tGC4vy-iWQJy& z;2{LnnvBwn;cx<9mrUqkzQCh(LDz@>Gkh0Oe8ex))+qT)`QbOzTvJDzjA6N0T|^<& zkDyM0-+)@gzOw9^mn6bE;33CE;W)xuBNNs?KpPcq07XFZ&chM0&w_+3kH5|M4?%z# z!X>`;hl6k!XI5IsDFKpe_LpKWTJxt2B<5$|t&?IO!n2VS+soXm)J88x^Ak*cjaN=4 zpB#P;d==k@{B6%?V7)}T9oQC1Wr_nf}zs zr7@Wwh|`>qInru}1pb(?gFHf*-4Z(zWFs(ScUU(oO6*FqrWMt8?d%h(9aI;37bcH~K>VrA%e&G0Pj?4IcY9+trCS^y z7svSr2L^t@Y)(#Titenu&8odKN6s5w@fG48xL4IZ!S@CE`nYe2u^rKc1J@ zln8KGr+)wTmNuS_Psa{hkyouWc*t2;v@G8vI4~i8B>K@+7QxGotX3L!#*3lteG&L` zs%hewlI2sn&J_mG)Pzo88wbc)C?Xan@!^2!^oQfXEt@NwWB+R6+qIZ?H}b2;j$6K&(r_>=JAxqFn6?a18? zUbaxspB;ecs4BCy((FTlV=swnVyd@%Z0}Q*OmWFq?*IB!JMxvnG1mEj;-r`SloegIn zw-D5Ef??0KgoJ_Sh?Cl zw|T4l-<>H<*3OTX5TI0b`+BX`UI7BJ%|XM;2mJWE<0POJ)`q>&ZED#j#pxEp<|&9@ z>%f6gD8o7kSe! zsD)KvY+^tWSB7Rhqu*TnM1E|{A3%j(6i<7MnkKAp?aHK;*K2cPxS8_FF06PU%Cp43 zg4yef-^Wotbajn}xA+Zvvpj(k=Cab=$)18WFW>VwDt(@gvlQ#zzFVaziiD3A`!22? zYSjo{92X^+*q_|mvKg7*R2g5zEN#y ztrm7zS}wagI`U`s?ud`}@sSVuPrCo0GZbM;kk8v!Mizk+edI*Nf8q~eKPn92GUQve zy$l8pOp?B#hCX0Qz+HUxmP2DIQumls#@W++H`vjK*#EGh@nZ9(R)LD2?-@7~-X!JK zQ{WXqAUkY_zVzf?hs+5Sq7Qinfl>wseoX9?#hjmeU}kPs zJb3n;Da6Va80)o8rD;d*bNH-8YU?z;p3^^7g%?Me)&d|Z3%zs^ ziiGn3u!5MRv7L3_oqD-mFw$*{$&&hbr)9L<#!ql{n*;qJ{LNn~2aJeqp+7_l8F1^r zEIq?)_H*<&0)8nTz^68R4Q;HLs%fP#is78P4UDe0TO6g0{e45Tie=F<#_2UO3JPwf zwsdtAl#b)!eusYyjt6$k8U0rQ`A7`ZR>3A^^pkrGYtpf5LbI)T=O2Ctb(xFd*M1wk z3P4f2^Pk^E#8|$!CKEX1@HM4dyV{JMU%xyXvev^}5?L(^EsDTa_bjyoZb1=?&4S^@ z$Y0?AD}vaVEJRHc{Svr!KPQ^$NXE9mb|xqr>OrwRW_1##STwgA2^M$7&GjAq&0D#V zg;hWkqn{x+#bOew*DvbF1q^%*%5)_y7rXOGS%~29spqj60+@<4oIePHzc4O0Dz+Bd z_R0W_7nQuX@pSi(&UU%JZmqhv z$R~}AKtH?+dp2b&fZ*a@}0do&1C0}-;Bx5R_uJ0@A8Sc zY=zFUo4c;T`{Iu3OCIfq<9V7S)4VAm!{3>i-2Xtyi|2~`z_J3?Q>t;HiPZn3Ea)!x ze}3geg)-|=u^=TOE`7dY0}DPgL_&`YGnH!?goEkM$<^`WOpYze(}-ArR2_zU5h!p! zD!_gzQw`qVn5u#1zV83I5Kw4R^sRn(4IZ%G8q!Iv1yZO0#0 z4t!|qvYB6h-yKiaN3OJAzn*!zK;F2v{OM_9eh3!RP*brWH6du23*m5+zb_8aB736X zVZf)q8eV@?8^tWGk?DPmRLwJKd~uz0E=dgWd}QGs1Omlhp~A^m^(}J9q!e(TBzY8( zkkGr-c>!)VT`{;ahJxJ%cmT>TzJX%sO~GuS1$?I6S|Xe(#DedB1V2W^CDVfWii|c6#u*189u}G z?Y=uf;o%hZ6Auh&n!rX&l&5vBC zuTOTnXa6HuZXiCqA34jRHaQ!tCVF7j|=;SYFhPsD^(;~M?I z50wMsdT#o@nVYgp&s#)gqO)00UCzz5cU(!ukrU-%`-42(4-aNZ(dKB@4 zz{LV4IYZvW_~^Do*g=>Wp-@H&e;Y?Y(j!Jc^xd+wI!(C^7DZE?AtAxR<@K(%jb01! zZX|)8w?<(K_{s0rI3Uh|J}ChB*YO4=3TjK*d%ADV~G$Ns`sJrrq(F~3!W$l zU`5nnIWJ<2N$-ik;}mdIPwV&*qoRSETCD+0U{tCqyHlOjh^5+;we2>wMeJ-Kg;l1T zz2(^7?MAGxg@kamc&flxB91Z3pOUvj)>z}3V9pl4zZ>$#847_;0T2F7lq6JkbiSdY z3|oKJEl}fBYJwi-)twViEgm*bR^DOiF`$fjgtc{x3qkAeUQ{%8fr^m@Z~SWU$(fy= z2FSr5;BeG_nqgoJO=Dd19WXBTrygKHVijWGvAVJ;g}`zIeKc%m{PW_R9Tvm2t4+Dq zGpz1pMfRit1LW}|jSa<}Q*f7+t<=>s&0nWomHh(PzYYCs(^~t)*R9fpr4|}Dex&^G z89E8(8XIg&;@P2lZND4ONc5gl9tbqN1&L$|aCb1fZmH@hCVy97yvz2@HC}R|OB-MK z8R5&i;aHB~p=!qQ6{%>6X25h`+YO3AVC_y?Pw2ee8bVM;7#;-bjlESxZ+WfdTe8=PM`QvE| zZvlc6Oe|VjfGMlX56TAlHaeB@m2!>xdh(s7TdFmdAHx?nd>nTkeA@_pL2l}Sbvn3+ z3g#BO)4<2uQ1LFy-jVwJDglXqn1o*k$#tYbyAwrxcpF4woMrOeb<&h05Oo}LBVwnU zImC21TSCM_J$T$aKeHm-GCV8J|3lwQ10)_pCIR-cVF<&<>MpWqd$RiF7tm#}v?D`( zLyb=4F>@J=7gm->x;uXcvR{PI+oJXX5Xd`Iit%Ue_Y@F8=)p96-ulDoO_%iX?R{^* zd8(p)J<10t>PAo(qSElOOVEx>J>WcVUZ-n#5C)(S(C&{=fwuYG?awR_v`$FSqr42L z^v(eS=*XRwKa6ewxLA-mZ45pYdHkh8eP2HAN5!%UFVA`VQNhMdL>dpnzp7u8tKkx$ zTyrafu<46W1B=R6aHWtk9qf44R@;;-Y5cl|q0_WoWtzmykF)6wa(p^wQ{i3X6IjuD z>*R)N%6A*nO7mebu;`2Z$GC>>nga$kAh4!Nfod|8konPf!XCL*x0BhuMHFO9?`_?~D!{;0J9k6i>ne0?pA4SS&Bt zUMh9K9Ky6n^^cNHwJw97Ez|zJpNQCV!muf>9D(OY6Tbvm31IldshSvdMzb1xWh)Au zq-qWA2)kJ^GIj<1PcdYOer}9Wsxi#4vbY*%QJD(R{V7Ss?%#XAsC?W4nZ|)RuGzJ} z!B27-WEuanKWT-zR4np_Gd=?HmC>V1kBNTslIKTS zAv7Rj`=p*=kr)js7n^5}o$SxNWdw{M27&8!go$)pNaB-F!g+`rC=pLDQ*dCQU&;3Z zgyCv*3i|>F@(;4^xG8cIUU9rpP**L8etp*mR#i_eCMFSQ_Nh#OWQSkuAe}zfM3p5ARHE zTej?3P4*@JHlWP1L2S4Sr{r$2qbEscdcuKQ%la_Lq?Wudfq6Kv`0?l91D(CDu9?$P zS;}VI3$F1p$tk7TXRTe&W<0iXIByD$N`GYyOD+hE^IrtX6*OCHzd=czGJUHuSr`wX zsnj+8N@+%#d_mvIrYqv z*3Gh2+nwXBtOeq_83;1*+{IVUl4j`yWE$*F&f4_O-=BjohT}_1k(8o=+aV#q;&0$* z0zJD>BX=0oU&6Vu-p2#CC+`ZAu!gcyFm@IPMPJTpq{hqcw3Q8IQ1b!u5SuTBRFA=U z$Q#Ne<4o?a)313EN=o03^g>iuKvk zDyBGv+h>B#91#{|zl2;#s;_XrzWQW;Rq;XosUrtleg=wjR+W~@AAScF*5WjWCP0gg zwT>T!N)2lm9w@qsajhV8YO*rRHi3iH|4liqcx2%~Y-x?j;OmivAY%mx-YiC6$?Vb# zQv);lw%oW;xe6v&d}MR9-?ZoM6T zQr(T@0wV>L%Bz|`_;=N^E0JLs1NtA?f4QqUV=UCI!t45|N(M&(jcc-2JQV>UC@~1< z3hIxr!QzkYtCJcj_-;>8#bbTC;lKE#P?%;fKI{J2c%Y&H<*G(jinDn2M`1#f`D(tbtqF zPBI>@fP1Mjd~_>*@7V)BInaXswO3uet>S{`Co~o_BG!*?#{)F1*<&c;5)uKo70z66 zsi$6q#CM1Z@u53zR}c-M^xbfI2@C=cmDB+~+VN?f=(WLW$iHv-O)^h)(8PM$Ln z8YV2$0c8U+>bv}cV)}4Pb_4_)hGWN{LcFq{6|Pms7kFQ#)eW;LydGYw+S_&l!b0`t z2q5a>!u=w}!wjp%1kY4JPuu437{yDb<<*)>v>b+u<4gusdS`&tEuHbgyr;CM<|+_d ztp(?-mRH*X(id9R0E*_+=+KBm8s=4{pa8rK@GCB$>&h$?@M6SECFMx^TQE*}?>E>G zm+~jnUa(7NuTw{`OUk%V#gugllm#jcP|2gUxhngUs`4C1CL->d=q3S_$OA4=(!hH9 zQ+?}c0kvr;2?P*s2>O9u?P%d7!A^k*ghNki)d2@YB_Y;Rb!aBi zairofJ))|3{`?siUL?J3Hz^+wGj$qKWOFff^aue&OYPorwJ*d1L=u+;Lm7Hbqp0!;c?1b3aQl zWql2PaLK%1`*-uNo$-vYEXUEXtdo!AOpwnGaZ4WYFR^6wtY7rGX=wOe*YK*;LvFFO z(8nI$mEOg-N`rR>S(?)6wz{tzeO|aYo2)4(G(=4(+N6MgwiG1Qg<39uFQ=iNH^LYM=Q#y+XHjP;`Ozb`j3)X=$#jUVQTG>MjRSnI*!m z!oxtNW%sz%+WN!JQ*PtnWcr&fmq)VoE=`&?-j2#!&LVqw6 z_2blqU-YG$q&HHpOT+iu_7^AiHoAc%hS7fta72~{B4Votz=lS>aoEw`ad&G()Y0DF z+SRL~#nwkWS=vY%|JXR!Jtwnw$fbV%?TwLNWpY(Lp1&e4@DL!UW6@ck1YLaT=7TTm z@3VpAE}WiPox>BRLB1;k#fQ%9b+xdm9VGy^SKqQ$|KI4jhNf{9Gs6=XQv3FlR$9(C z$Y18X-8jBCm#DKtYulyO4xYn|4h^lgMQu!_zc617c&D2t`^rz5vj8&>l6ETVTW*+vI{`JR#tW=M+(Pt zWs=0JCyG;|!z+M<8f6xx6UszN(KT_VJQvMzgw}EltMkvm$ALf9lb+gT>P!SD>m;I) zS`A0&!oVb#Xr<1hH^Dpnw#&uB<~-v0!rO)gY+TBu%Nu|iJDR8`H5A;q-8HfA0;JW< z)$Ip#%?p|tXi{FjpzBn#^hU31n&yb+@8fRZnG)rqKf13Yu>%TY9(b^%{wQaM_G$f% z>QH07Z7Qa!oGT`A<6(z7LZaHny^Jn|v*H^&uE&WNzzZk5fppA#zi!lXVe>D&g^Q3h zUeMIsJhsT&sdAL@@`bExy#WuBlW~%1?|V`Gh5HfG^A}1*;20Et$3PXAwh=GCtdVy$ zgHY%itnW&xR6G6qM}!{BNTCP9eH>nS|Kf5RkJ%U9XZ-WQfGF)3thW95^_Ues{AUzT z7Odyk!RAqK?d=uNpB_e!s+cjJTNO)MYKIE5L*z4!dWZbfR{E(=6XyQfAHQIX$(W2S z92$HsO{fm2T-aK?#b_=fVtWXFNc>egU$YVD$Zi(nfrdEt=2TucJTCwb6MU3kJjeLV zyIAn^E%iW5P}tABGk^UZ`*nUvqfO(heW~YX=R${q^43p5E*D^1Zd+Nw8PD6)k2SU0f^#f5 z>I5Ht66s79WRUzD?B#2<1nduT4ysURm*3_H#L*f6S;ZKQYovLpo>(|rz*#UyI$2D& zyL>Di{T>3zLLvzl5U74vo*N_zEYf#sZf;|4%a5v!4YAf#a43o{FstUU~uU-2{z8>-iglIwMhtsOjApi4IpBIdTMDjaQp^RS&t94OLN;zqha$X9JM<$9qM>RUe%TIGpue`zWH)tlS>HYj1#zI@rAM9v-4Yj=ZihUsjj8g5X@^q zB0p14hlf->7~$5T*$xHmjt}h?{2=o?DoszvIqvl&<`%rmPvnI=du*XRK-Zg_QPXU? zmq$&Yd~qT41^44GWH&;Cf`Yz*@vU}3xOPo zwy-)2PCk2i;pH%^nYP`zqQ3B5oqe5s=F{jU0a5nn2Qp|U_R{$N4Ee3iKZ`JuYHbTO zlG-CICB7L32T$JXfcZ#1I1F7a`eM<0WUZoJ19hUvh<) zTCSiLIM?z|=2IQ@HhAh9ePUi$Opp%~d;)zaKa}GgB9uY8DrcD-U?v+d?12*(>v=qM z(AqYW`G)w|dAdBWxWtPVJl7I{2v>L`$j|ZZqqCrF!rVY~Q%oq}%WQ1+FLZ(aUzwto zdxWCWuT04b@@}Lpu5p2Aj$m5fFi7k(u+1R)%DrCSo8Jnr)|kd>H-(1#ZPu0cM7XV| zrDfhCQChoW;fOb%*xK!Ayq(@n*~LgspYn!bwr9noYF;U9BUT2SgLXI|38k2T;s6ms z`+oe-ro)KmiqMQpgEN6m-|eJZ^M}h6e1Nt%s_qE;mFz>vQ&027lhj7k2(|D+n8~I4 zuv4o)@<5mg$Z&t|3}?)K7IeJ}o6iZ33XmX^`h|^*z`!S*IaX{eP)s2jd7&~(md~3)By=G;%W z2^=QYMrF1wuZGWqtlA+@>j>6xZf=8@3?du5Jlb3?$Nq4`Id=(UjC{5-nN~;>EJT% zwCA+n>$KYyGnaVxPoP@iNNN&jcOD3{0;O7An};l!)TtHg(6XxS&dE34?BUU&e}We( zvNwdQCde;#S)B{v3~F?11XD9)S9PiW2!|NHT|>vLD2NilBAv6d1d=4?_tn)IQ1SC> zvp+pqp1I@q{HBnFNc~!Wx&rc6$+x=!Y_Z3Lgu1dsoQZO~O0ko5a+f>Q(U%@rCf#_WVW%L>K&?e3Uiq~ADHrN?XsF;Yo^HqqHl|@D7 z8LF)gPv__B9sr?hNhT5>V?Uv2iw%@)STk0+A7oN=z!54x-PgEcE&$lDCh_sxbk z(d_N>&2bYAT=*z!UlXkY#F=lA`Bi4K;JM7pd;TmaBY^T3eez`0?6Pg9Y(|N^4LTWK z)brKl4NCn&*wPXoMG`NA|AD4A?K{`oV|((JJ5hIViGJT%Cxqjc2Q>P~Vg&sp^nLF+ zg(@JeirD$J1F}xKKqr~6y}R>=(O>LtUtv8|{+`p)@b#qj>m+gKCB&!M+QC{&6J!0m zS8`m#Y%_x{l=bHD7uFvn^i$2qL`;c0snW-rQ<#^f0~T0uhnWs)fqZDkAGT6aOBA~} zzkK1i%jBB3`6rJiwu)|7K27*|{77uFRyrZu{ZPk$2HJt+(T$B1PL^zuy)PPi=+8jW z`d=-Oh(#G=q%(?&B&0am+kKlV*K_#(%)jJO{B%6VB(#s4o~rqx$cO%prux?uRIkV< z8}SaaI+Bk4Fvo2Q>x9oxzfb*gE@L6rboK$&)K1e)kEbIMeu1qWUVc8eug~pilpMY} zgtgbQz3#Srz%5dF_U~-*iEw5V6tSr$j(@B&RH1-CcWe_wjsICD3@tf1a3*5e>4i53 zvL%)I(8FVJuv~loms?O40gr`TA;?Nzx8N6->-`IK>HvAZkZ_}JxYB1Bgp+_DX6%jX zYX`w$|Fa!lKzO_x?NO16bVpk)(_WRk96)K9m|xW@YNB!ST-H-i6@SR70Qr{#X(2t#GnHs93F z$VxQDyCy_H?N8Hg+9CMXP(b>?|l|gr7b>}M&F(Y zp^bYtjhYSqyH9YkGKe6xfOR4KwT7c#hxno4H$>cJs1WwkKUF9g!Jm_LmHYOwCe9)O zHf=9*QnV`bO#5Vu8v)2=VdNUvcNBqvvM>xN=@GwdcM>qnBsz$&c@oXLaeMs67t0mI ze>~FF%2Znm;%fOV5(s+>_&Buti=I8HMfo6;*YAdgR;=#5awF!AYg%R>LO?Jf(POSS6z zq;!@4aK!4Qhs&pY^qOFfF_;9#{7!>`bcwsAQ@Yi}@aP0)^ zC_|~itBtm}p13v>b2A>m^VMN9vXWD zpXoD3L(@;S)ItEdx%mT%Kz4f#tZBm zk6adNtuUl>f+i>AzRow-J-un5UlMSlc@mHZgh>I~wtk68;(w`Zu>)Ja->!QgVI@}| zJ<0AVuU+Vy9UTf%TcN%IEaQO)QM4HRMa_|(Yc<8~5a2Xmkj_#0&~PZl_~qQ%w6n?M zc3pxD{<_bPn>SA3bU|V@H--2RE>2d#Pm=ooMpj?*r@)d;2ko7lPT*Xi*h{Qk?=~(x zoM}2}GDx)Uk_Cn4L7d;M97B^U7s}GCdzBSYuAJ#}xL4XJ(YPmAc~CSQ+-#!(lBP}r zYb!-A2LZFmn~~WoPfuxuZgh(7&HbXs52n`^6{UB%Ans{sXzzitzEC?DF&xfw&DVh2 zGz3S8g=835^$V?f3gK3UPb_R1Kj>634JQ%Ks~SQ(JSwEUa`ZG;^a>9TK2JpsqQaSk z^WY(HcmPwTh#XCne(==Z!Qo#aSl~4U{zV-gXe`$52Z$6|$bq>y{#Y$HL(I$f&n|~q z2!0HR$CeWL(O||TSRlCpLw~5Thh{TJU0P+5`EepRB3cP^jM-Q@tt(SNebX1*L}R^~ z1dzS5u+jR?ecf{|04umbq-3&BVw8`csW)LW&ze5^InDZjco=0-n8T zf*ko)kVD3QMS))i3%n?PzQgRX582sJ9~V`PR_?x}81i;OKzwqrXxvMPH>hRkFI>|8|7C6$LoZP%n6!`Uc(1 z8*;ryR)I-UXMZyWb)jWMbzE_Ou`_0Oj*&Zl>&tNn_oE}7FtjuAKJ96l76l%8X^(+5 z&Tz#)1ZtXh>I-@x;m$*;1Dpex_Q||;dJ$ZUE6w2TGzFqyqi;qo9!1N-z zztP>)CuKQW;I6&>>l}~1>;XvBgmeoR`lrefbdm{1_tLFn&fkxY?}2uci}R9eY2~fQ zmy_CM+^&l8BJnT|SKt64!qBr;7onr9b)1ebrF;mYdu*NFKcC|~wlY5Y(>BQu2(pI# zI&e^M+EMKk-cR|y9{sM87&X{1oYUZ??iOTKViM-o5|loWo?q;zJbdLHTi1*W5I{nn z!E+mU=>Z+;!thuaKi^+^H|)zi1Py^65UdCw)(|~!1FZs*Vr^uEclIbpg4>Lh5V_|n zw0bd|e6<*)w4m>DJC2-3C%Nz!E^IquWbshMH4jA(x?$4t zX5>-G)wNdFe$b2@pu>P}M&zR4|v#r<2WV`PeYY!(!(hSW%b=9K@};WT!z*2tUuRVTWu zrZ_?Sl3^OsyuUbEv9(zN9-~OFS_rgY4y+hY6zL_!!XTk;k-mBpJ`K66eHw+Kfq^^p z2%W5<+DcJ{s;Yj)s<*A{9f`0joJ`N2Y+vey5T3;MlF$w`hH_0Ki^xBPPC^25Z7jEO zI1d63^VZ}0XrguR0+cL>OXg+>3TT-g7pTcn#KXJ>*>#f;_=hw1LMlZMg5d6J9xdbE z1f-SKS>Y5IP9NbKBqmsKPGRE)d`0O1(;_MEkeRxnjBA0N$5o)&Wf<%VGoue<=SLG=Z|jZo=NfwMy{$$}8wGCM%hW)R7CS%ot9i0DJ7 zT{D?-z0V(_lj=@Aay@ns{=!ehkZGS;QYa4+u@VYj-l`pSsWypTaJ9wArZmfx$@LOp z@6?}qwjL1v$gVxK#g9Hm1{uCaqU=)oPy-n~u0?R{6g_Yw_7qOf7V^{AD~W844j2kC*i+rH$QQc+A(#K_J73 zUrI|K7c|4(B?82m4i7S6(?$DfUwU4*FmB4j=zY_N_i8>w_j%O?QQ?L_f(Iui=;2u=nn0VY#m4|ehu%T1v1sHLAA z^Hb4|JNyWSc>|}EEN)qNERe8awj+R4$b~J9;61goA+3|$C!F0=EAIrNJ-PtRZd|j; z2svY-L?K@VlVyuyyv$!0>;B}zBm@K<7mzXIYWsCnzCY#t37H}Sl5ii~qN=m{XJxN) zKub&iP5Ktz^4miZ^WhEGDoaaymdoXPM**rqz2LoO_pv7!D59Ac&cWPi;L`^QzealKLUfjCzoXCx^>75xE@N*c+{v=rhWS~%rbL!9S=(dRoP{$n{ z8%#Y?J0P*u&hq_#yCNUexIgZ{^jOH$<_M%49+G$gW( z{3HHbYfDjQJwx^P_w_S}PgmVQ_}m>?rR44IRQ%eReO)^$%myuhQ;b=_Ii-r=#6Vp` z=bPM*D=6ki?fmhnQlKt3Z;U$aB!cNT8{_Zj=8VqXvd;c2;{h!?kSc+H{EZVw!V2+W zG06N<6(s~dAamvbQv?#h!a=es$h|proWlfPyKDBzs!VWM3(LH))e%AR!|{kc!^6Ge z)&&{6-YgP_t~TCpzVErZn}NkmTMFDX!~oin7z-<12>X(qRaZb%HKhgR!KQ!wxQcl* z!OETe3@&ei?0%W>XMSF;ACTd};_Cpe@ewyQFCcdn2o{@V z{_g+w*_-{bfqJhZu~T^`t?Fo9)ycq+x}^&pd2Z{PzD%BF>(uX~|MzmOp#0~o#Lw=Q zTrB0DS@87^GzXLz0Y&moRpL2`N&H+YQ|^I=6!KD}ynlJBi;mCn`=Mzl#6 zUN#bzud|1YqhT(ATu7;e4>FhA0=WwioOp14Yz?p|F*s;vSEEK$!D<|r^$eL{Y_4pX#ZL{(WTFq@U6!;dlO)hK zHZ2OV4U7>wRovraVN!4=F@W>)I=K2QBTN`yRlRgpMr_oY#)G43Pi-N@^|{aXCc7lF z3x?&(W{3>HPsc42HF8`x^zOUzXJuWDdwibUoxBxvz|0d)0Ks}luBLJIVY}Sx`AvP|qTmKf|Kq|&IU&BNW zR7#zHg%ZX9inAq46q1rJg%Tg>@~<6wq;Q!JRNf`=-5hyP)aJf20InI}eU1}VbO<%V zfLQ60O1B~%%_>}{K=JEVGQzr3J4?-_PHEq}jzVB0<-7-C=vG8ZGD*AIym&>5g&-E? zYSgtn$GYA-|Kw>>o?ysj#fqfml^Ldnb3B9dOLIyMVm!gQk*>8}*@OH&{13sL zZxbYu;-;gkxt90#0;)zv^L?yrpJ~DzR{1G1e;kE&+-FNlE~+2QW<}@4RgK&ntQ;m< zxM7VHq}$7gAYSwmi$y5`G9|&la*)*1z(}xZdw0%B%7JJg06T%1)TS!6Rn<5_5xknS zyTy*?n6HJ!rk!>YcEsiF685!lv57e5VA*pkw|&eP`Ofc68SLQA&Ns*_it_7;6r_#@6JLyy|dHdUm^E7;r+z%2We>iCyZCP_6SQm z95m>LM79-K9P|1;(W=*bG^p{0>;quQ{J@JtUPS_r>H&Y?cYiF$b9BwnqvDbhP2jAU zcu;X7bQgY)h^!lm+!AYg^X+-v$$P5vU}n(GTO!7DpSvZzob=K|wr~DMbm!pjf5MBa zM-%s`jszwW5&~gr)r|`rbLOf|O`R{87o<+jZDptQE41cyQwK+4Zr<93^*G;QR^-Fk zqMCp!hm{=>f9)CRIE#ML7@QsT_vwp@qf8JA*@Nmbb-Z`ICHaIN98dZV3mrHLOcdux z)=h989VNu03Q!-4;Xvy|A}J5j=64$yHTn6#*`dkt1~kG(2p>$l{XFM>wrEk&F{?=K z6doh<5`&e#-dh_PX_!y44dub2#6mvCAzFWW{ku9Za0OnzgRckG*r6XuE1=@~f+-H# z{0a8?%H_w4{ZoEVex5Fx4&F}+cK7i3b%xU~{c!63-rhC!J;Rp{=@*%g9#w=jw+ZL1bn`J3Yk3 zbMz$J`8#DR?tF^_y!P!V&-B~5&)2+!x3Jn>HB#|{=*g+5%*eKp<-7UBcV}&Rd%G{gwdl;ceCv3wyT;e^ z;?Z@+uSHo|bV%RNs>T|SWQW@FMZ1|~a^$~cX2Vb+CaVQ{?zMvcCVEwBSCr&QbY|PC)6uJh`D;yaQ%FzRv zFgPCi0u&tbkuP>Kvz(~`1QqP|)^frvwfzTP<^GHwO+3)}2qEm1&Onka=qy;R9L-85 z8meSyxEbS40)GNOWP*swA&j3jIhsc{0Q4+f-dDINCebK#D=hRyX}%=pt744vAQPy1 zmeCUaChtxK;~TkHRg3}ezgD9FwOdLV!8Y=uzi%;!G}e;zb#MiCh$<21>3;dOwexQ9 zvG}Kh&II~qxT)(DLn&yJDerF-dS|?%lK!p&O)(c-$j);CMx%ZEGKB#TR2VN)hGt*D z#^kEzpbbVe6wZyU?BTY?9^u0x5uadWPaUvSkm7K+>pd*IOm4)lelzvwQ2ilR8pu|- zjRulG=!jEVg^u7eHVL8|wM?hjHE zaSw?fX#l|nV&<91Tt^(%9f(&2Sy}j3D5nL*7#%^UHN_1gn;tYv%gvq997qtgCdiyJ zU?nEdGI1yH7}T>!BHD6f!RKy!ScUgR(Hjb@0I{lYH}c?n@<*hG>)js_hD?@tJ; z?`&mNI#7Bc4yY^zZfJX0JkIT^OuKR7`(F<ik3e0b~ zzuX6n4PaaGs##14EUTg_JIIJcJw5S_|2Nsx&TzoQa2h9x{a{>*l%*(Ik+VAzBDEu% zl_Ho}tY*@B?0XYlWERiE>E30Iy8!8<*u6qLk(u}Y>%Y%USf#Tj)Gyt^?6xT&^XQ(7 z`DH&`7jSrJNWZlhK;!toRr8PV(K7zOBWQ^dc%&wtz9kilyYATcJk)EG>+)w(T&l** z@M0p)mSgMAgDzEfInL%Rguz*&EJu`PxS4hCfQf7ZghvPuiG<@H3wnh_8sz_RqaG7R z-gI|4Ar^H|DZ?tW0R%@7P<|`>3Z;$GhS-@Qb08Uxy$IhKGC0}ycTO=wcsNM1*gpXZ zd>HbZH;m0E2wTfRph3OI5QPtR1{=2*U5!q%9aV|V0;InVvq2xtbN~=mC*J^P8w|m03|^{+H`s1=l5}p@oBQHz=VTI<`*#g^tAkAq;maLzf(MI zmVN_~^8zq5jMLG2Q07e11V-jKCDW1I@ZoMk=%mt-kOtwfaXYhCI5<=S@+uS({iU$@ zJmdR;jM^1-;hl{9x%@(zr@HfJUoF<>C0~DeQrm1&+oY>pA)+P2aX3zGXZC*Z{`_j^ z>hyOPpHx88vMsAd5NtR|a)=`{dQh-e6D6C=^rp;iPlt7o;$Oe8uzx*Hv|%p#Hg{EX?qC553nzVw z9dq4-V>{*P(zQtSdO3fdI{$&O`H2MABR=Wl1*eyte^X0#&rICtnde&${n0W{rAPA+ zBFC#MeCN8?{*+w5R#*JWl~`31+L+f8xomfL@?r;#wgK%~C9oAak36Pl?^>(Kcgb+l z^l#QS4q3QX2|DOSK9!*W@f9c^u7dOR>oj;DSAE&lw{51g_^?{M;qH-YdVyR}etey$*QEs6)n*5*iS`$G z6-59HfnIkY$8AReZg*V|`f=2`-jkK5=n^wL4^6pavflIXPvG^?2|`bPKDp9#@ZZ)t zeMth2D7TOb+B(>k?9_~e2it{jd&v5!-3hv-xxN{4S$Oo~O>WnNX7x;(1~|7=#a(Iq z`y{fqy_G#+!fR$3_!*wMCh3W2phcZ6M!a`5`xHhqoOd%W8pHGpOfB_6+(5%FRvnR@h4rQ;)1D9M5 zFEbb}hG4Y7;U}c`EIrc5>llQ&DFl}NNS8yG8}X7&!_7b7bC?xr!0wVhUec(1V8imV z)%&;Hb6}G;jfbmb`^-PG{V>MRSbM*`^x^1CPMCEHD|2q6xbn}yW4A5n*C~z?X zSdnk@opgq>+uHU1C>JIcOg(H@TBZGtB)}*s4Z^aB=*-!ajk%o;c&fkM?LnfPMw8-T z-@BOClpep5QmOXKs8=9E318fyne&ATuYc!y)~C;AW_rnPZD%@Mwwa$!WFEJM?^@69 zo^I)K*tlH`GvA?}7tx!kLJSHaPWf+9^Bktkkaa6s;3|UAXe7T?r}I1f<%>U)YEhxdVXc{tZGqT$V2(~*92AIq{4 zXVEAq9*g|)IGM7a;h5_EqefU6|2X&ftCNyOq*AGi9r?Zf4^!#~G$Yg5U%n@@QD0Az z5n2GCc!i;Y2dvVZNbb-^)%V82$*tmK&nkftv<*=yt9>NiDl@xq{x!Nr(jh(?h~}A1 zQ1T_UPvb1ilVoSkQP7d&QgyiK8oax(*WMkp(>LYuC(sJROz|>tm+&4L?eDi6scdU2 z=o>A0u8vw3){DpRk zg?HVbJSbYG++l!rR3Kt>P6_e+`cG4NJ`-GO<1Ks{Oiy8-?_TDphdsL24bSrLrI@3% za*Y%15L(zjHt06^$k_qg3**p`G*8+!3|oeL>sKY8fxn!)qb_4rsyV2l-U*;}MQ#=| zB1XLjy-r(6eTqZ^8k8eF;K7J}<5-+OPLjvMK)))_JR}9LFdDYa%vv=`HUVg z9c&5gEw3H*2j-Q)U)x?|n*Wr4p+mKQHzBy87Pr{-qB~CKit^gaod@MDN4%W-V(9QJ zzIZX-@^sFK`gI8rEjBzsU#H61$IGw3d{HI_4w?<0;3Op!MHVnH+(Xs>@R$EID{1oI z@Y_P>o={CGXNA4hv(tWg<2@!)H(2!bBR@u(mvsB%yq)+N|8`KLphUUDrUdL%w#cl| z<WW;OYs%{mfaaQD%^rC2Ytim8>7vj%f2f z#kk!D9$Fn$e&OZ^mpQW1(cv|qkTHkdDTmlpq&t#TU^3G4M6l)u?0?>y*64PJUC%xf3q z?~jH4CZee|4LlgBMD}JssCCsSVLXf!^5Ua{QGOvnEOusMC+x{+{G&0i-O;OV(w}B` z&TNYi7IqW}cP7JtTyuj0GWVSz<#N2~K@k`U^!N8?U5i8J)Q%P-e>`ER?yU9Q%5&cn zK3EM_yP{e#@cZoHc7P4AH3eNh@bzb@2Ma^(?_Lc9L5tE0u;x9OV*{G&MVIZ{*n ze5MgC&Ay-oMk*1?WX-{&{BTiow#K{nSw+G}9>gc94lNcq7{4Wq=D;Ryi;EH(go*mS z-F=FBD9t{lO^cIqHbj2>dnCzFz=oGtl6WmXdemj6-c&Lx8HqxJMhZ%kqN3F>y08QIyjZ6MKHw&n?5x{#t_3q6V^9<)r{i<;1`0v)ovHUk1G^RUDK3`nKZF6+ zX!}39isfVcx1cIuY?JJstC8-U``r?uZ76k$T{r+2n7o$!jS?l=UAo}*)5r2$j!<~e z?6FtC(k)7OF$0P+29ig;N4QkQ<^AJeBD@jSL}`$|2!~@#NOopG>7A+eIR%LyzD)UE zIr`;lwFtd#SO;k!p%wvrf0rMw<@fph0mgL$m|F^!`mjRSCo`cE27Oh=`%>Xhnis*&aujM#Pj(nPnEs{!;}@NF~(-?sG47r7@^LyFMFi; zc}RA=rg}K698H%`v}1!~I7WaVGz4}OPaQ#L`5Bc?<8|5%aAVVa2nK-MoQO-2 z6oH5=!wI4QlZ+=0&yGJ!&z=7MNFlWaL{5M$PW8z~A!ApId${=Z+Rt+5v30bL1l*1n z4{!Sj&gE^^z?e#zC2_OCt%>ohiM+ZVcOfCGv|UIDTuje^a_62c+^TA z@3%Ig`dSlYSV_=acD(s!O7@IOrsghT)%-*x89g2N zefZ9dSk%C_wUF!S8We)?PAW#s{Uii(xTdRh)i|~56!?J#S8LMUr8TvvPlQG7q_!Ru z#z2vD=+lpX2kKc6yiajaXsgf!CR8)QYJuDW?wl*l`^U)9(W|SY-fc>z7+ybpXpgunBX5rS{x??{o-z6VI8CK~ml@cRli=RXg#zj>#L2*j> zj~=ooVscST*ct`qvUiJbuiM=2H@P?M_p%#+^vn9D9=<+q#+E^V31f&~m4q=5QZ&t_ z{|r;%MuV>acV7?5hVT_G1QlnlX`A;@uWyUOM0B?0W2n_&I#k*U-wXtgV8#NeG zS8lO+QsY__*Xnx&wBE%FmO#mBt#Tbr9D$6P+Jx0W0Fa)C9^SpGHxz24ktbL zsHg57PH%cn)Udk-l7n|_MIDRl2}wRXKEJQTTn#j;yDpI~NRarQ&9_AH zzx&AjEquM(eI^}f8>FgCCqMX8;C!?oMPP*MS$esbzSCkF7nu5<^<+MhXFx% z9vG!_QzcF_mkub;qY;08FKS+&H%7mOu`p}EA!2$^an=lYs1L=1;;>%$l^we*A2aYk z9Q@|Pt-sr+tofGRlhetG@5=C7*;?JVjx*4k5+U_wWo1oyOg&>nG&qhFGYUOJn3zOa zuO!WZmH+_=H@0GcF3*i|SoO0sA-QX4$VhjB59V86g*Vq&2_H-I9l#y6T18DwO-ZT2 zhq2K74A>CIu9%-5^s*c*d$LJ2PCR{D*gCYfVU>2ytK@N}f3M|WEHKiz4=6jtpy@IM z_z^xxS;0S4P@mjFK1X^7j&SYEa}LbGS(-x(CW%RY z@3T9~GK>FxZ?*eB%7E+NBGUZ_oKEj61BBF4V>8{?O&X#Y=Me|LgW3Jf=+YNBDZU$6 zr5rt|$@CZJivJ`?zdA_P#8)^tz9`QfSmhy+HbMb1{&OSVLgC{9OJIc3z+lTTOFVbk zSnoQn9mEc(HTyvhF^FV{1Tu5-zOdoKZV)_tJK&zlCH&(Q3heW5x7l4a$AIl|?pBy6 zEg##jAqIIszx`2}E zTviz!=i z9;e3YRJe&aU0p_lKSRetx5ve5Ocr9%RuCN&L=?iBAbYW(l!#VQG{aGzd6MOvy1-lB zKXCN1rPfEO^Euh+x$E{t>y!077##K$4%P7Cj?||~oUZhicNOp~&_J(O*fY(C!0ka?N9j9YC5VlU zjV`q~ExZrT6n;zNw4R=x<%h3klti>->`A#dOq1+ho(nww6nzSJoXYg!5*1LKVz|MK z;qhZF)Je=Fhy&igkn|b{1P#4GuZWHB8;coA*(m~86kP>q7SUin+Ak+wR+A4lmAKp2 zOiX6{sMU|b9&ej?(ey^sr~K(_ZRfmH@gzA3@}}-m3Oa~!u&>goDXab5@c8qmFsz~j z)^2rZ;Q^rG#e2GxyQF}t8-Edg3I4*%TOh(w$jHqmCD$EJ_QK}p7q6-$y|y8HHs^GZ zNV|*0&cn8@)8shh2_l{Yoe2w=iy=*BtlJi;3UM~??rsYID3ja@aa(J~bFlXL3WC0s z4BuL{t$_S(n>7(agAA*`+Pied+C*$4p7Y6~Ae(EK(BG!2@2x&jB}xaEZB2uB*peH; z^v-8Ank{*`Vko(4OO#1Yl$X}?d{E5fQwUd;JhPZqQ`m#FI0W1Y>?8>T6umwW#1b$d zv!i$=eui1qztM3frh)k5HRur{7)NcDtAvUiWo@s)2s)AHYuBF9@OlJZnl>MpLohFF z>`u1x18li=B&%jeuvId1lVU8AQvMK8Jx;y>(%{@r2gDq{3CP_{@H*<2a$ZHG6^dY0 zM6f1&0VZ=P$oE@8TP;^piycRDm4rB*NB(+`=%!{$0{-d43R#K;_;dfh7$FL@WP}<{ zKXV|Vso~b}h#q*^sLMYZU*I#Qu9;PO0*~rV@IMsZ@DRl?7SN7Qo@ZFDzc$1Iq!pYg z3aL;VsG7>woVGcjL_~D*N;D}Mh2H9m6qWAmeNsNM_~``DY_-o|eigeaj1*N+&Hou9 z zPPH>6nY|P&P|Cte;>#~pB0I@-=8qRxl`HI!atD!V?s##5?>ku2vTBa7z~5#_r8FEvIuQN?7JL;%VA;$ z9A7=Guz)tBB}nnW*O5b4oc0Sh2-sQs*I}Ktd1fDEsb7I*$eX!J#fOUX(YECuLK+@k z3mBaEQxG7k-Fa_x^<+TTr1#9Tl?yW)wJBSiOSjwhfOYf$_%XO5)#r-;#eS7~SvTue z$2()Aphmnb9%o`GXNK+J5tZOh4TrEC4MpYM~Z(@yXF{=Q~;Sw1ics|jP~b!QzXJKaS2Og4LzE@7WSbhD>aa|4`{0FK)QA`>MmK*}Jz{Vo{=R-ZorQoDhQ{3h*RCCa# zzS9HLrslr98R3JGMnnj7*-g=xAr=LFi;SvCUk_A|ZE62g@19~qgo}I%LB9kCl{adE z{(+v0g{gxlA#?x6-8GII5bzQOzSR0GIvynsixL%}w8O6yIQ%QdFif24viEd%@3|C% z4oBZkJc;lHIb*K77zi*v@oGO6g*%^${?gME<(^Lx2)`HC=K=ic983!eBc0LFy0@aY zGrz4`!}CB0vgGnzNH(dX?6djcX8o#~uQ0P@l$2^*nkSMK?k(od9@`T2q zsbS#sbQPNJ!4AkXJ7~5r>phiETqydw}>@EV9Fzx_W2-dai0$VN)j9MK0 zbY$%Hh~`E*^%Z?G=J=7~D+}J#l&t=_o+oiDqU_B^Sl2~kST-xE_zHL@!10F>hih*R zLFbKVPQVH9mLj9qjw|`b@{aDFXvBN?m+@~EcaOyf0(DztZM`knfv-NwM+rCqw>GEr z0ulr_ZgExh(b#Q8nL{I)G0+#Q9|hO#tJE7mefrcubEz7rmbdG>YlfgA>16h1rVm`; zT9!6AtUOQlqCH`aG$4v%pfcgGfR2w%toWvO<`MHN9GZjw)sE^rje^gxSBq^xWcz(F zo$H-K1laY@KjADeqD=FTU3dU51`SGCp}$8&jxsaqD=1g^@E->Fv$&%mJx^xp*#SA# zK#MLcsLW@!sI04 zF?^@ed8c9IZ)L>3b?u14ZXygfcnR^zkrVQLv&FyOC6%J&kT&9S8N5sAGR%;p4{BWm z+F%pQ;6w&qH*1g7Qi0Di2TCEy&RFy&447Y>j#e?EMyPaxBiyNI?I>WPSLCxZyn$kq zfFdY&dVg~wSovIqCns;~aNrl}xzt#BAtCM`Eu_Z4x~J25I{w`Oq))Y-y9S^Uvih1! z&Lh8~5>BYR>Bpf76Y~Gjf12f4eyAPY`P0`1Tw|PFF0)VYZIKv{)MF6Jdsyh$sc6|8 zl5rGlqW&1xHL$KQkEA>gbp42QSgD0nQfHW_w8@*?{6y08?X^FB!Fz4N@bKlewST6} zw8{yIl}$qVOEQCaGi#Pffly`^y}`=TYdIbR~j1{%u6=AKyENc%2QnNhBX@~N4q1* z6e4yUu@(7Zvwda6+$qfm3S(ZVyFBnPs|c;;AAFwqcOY~aTp=Ue9}I7NS4bF081OHZ zCXjmAAkEht0wY7%ep}=&qO)b8DJP`hQ%F(a%o{gQYIkPp`=Hx!F~rvg&P6O5WTR%K zEMpm}(yifkn&0~$HWjQGdoOK%VBpx@FLu7`0}{_VDSwkXVt8w}B||tOp)VnFqG3oqXl3iW!f^6@YU;ZEY3`2b_#1yT z;d#p|D;`4Ok)j!_JdcP&j|KwAlxA>BPWL83N@?Mk@MjyfO$3aCI=t!tUcpN(TwvDj zFw-rH{TQ*gwKiG5379{RT^oQmEgA?Lz#kHw2{xrpaS#L|+W}^o4PaFjRbbyoFjW8D z-G#>Nq)lhT!ilc9#HyqMWs{jl^vK-`<>C`Kttb8 zuPV_2;zp3o(1#d8~Do|Ax)125{XXbFz6c$E8`V&t4b^gWGUGtjZmS!##(=G(Ft# zHm^2tqVTD0kyJVr+d|NkK6%S~_h`Q?)WP^0EVNI-jC7bNE7yxt5~BJAXNe7ZoDc*n z_jokh%ngaB>4)9yVOh)3SA9({{qg*@PGvV55>!J4pZnj+1E((6`fp%nyZ3sc=xghh zU(b`iYF#g67ZZG;nZZBYnL6L)a(Rdi0!9EGvhU$`-Og1^cs*2%?i)#({Z~PJOb=z& zSnOfB?vCL=vimF>*n`gG+1|Z$(;uEoA~IiiDUyI&Fe-0Y^spjH3#b7asC01rE)bq3-VP)D{Fm0M@~ekHg@eSy^h*AXU}`26Oc2|On8o&0EL2?b&xhXciIq?(4*d0=>G;dJQ)tm2LKl- zl`81Kq1Yh2bl5XbFnx}p>uInOL?EoJOc@~}<4M96_hp~M6Ji$AzWt89S>?Nb1qyaF zSC1vv>k>5Zl1$oaczj^mu7&%mACXAgZh=2N;AXlv$D_f0)qL~=lNm3dX1Rh-^PjT3 z5VT!+aemge3SX3UC>p^kE^rmvUi!^{#v&35aZ``I*>{@rn3Hp9yBn2HyE#XLb_|bG zI*KRZ@?&00;JMQ*e(2n#N4Ue=f&kY>C0B|vtGPyNixdsDE#R&bt{BjflZ1+sehoih z!swo$SIdVVD`c`T7h1W-ya@=~N1WW7q$OGHt&${cP5 zFGt^pGz|^u65VJ08EKXN@M}&&8ALhIxBBc_+!-^5Pi>kf^;oweJJr&HtRA>AIXykS zwKY32ae@vC&oI#TRUsxqkOqsPw7TlMvdY0lRzOX5^?}WBo?Tlu}ngQpPi3e4&g=`~ipnk{sH1pb8dmmTu>Tmlp-4sEy#D1>}VBm*1 zO$$()AuBo5SCRX=0Q<#LDVFY1OJiKVSynO!68!JxYha-ucv!MdB2^cF92y7g`fI#i z4ykjhRC2xn?7`gH;wL4H1)p&*(-^5OE>$h?MxVpx_PL)|YR8=U@!Ezs9e%u7x-Mv* zvm6AOvnLEzx?iz<*+X4xmIB!#L1&TkLq&AMh{uh&H z+?W9nDOa!)vSN@BR*f@9=35%()j+-n-0L1M?22~h;LOsyq9y6^xsrNO{NjMkDuY*{ z$R{vIy%TQJ?EC9oYYneo4RI$TJ3Tt?xSgtV0QOv^8Ipl;T_x?Pioj(eJ=@vy0r7SD zfb`GECfaa7ZYvuR7LWS^FRB_4--i;ISjO*89S=Fn&l&<# zkk^|XOfC>6$>(!8Yfs-a$9bJ3zv;I3OTX)MQCd29yCC@E0Jvs3!hLoZ+uPeO2CsL{ z&pTy}_ALMT^Jl21=VONl{y)Uz?AALZJBM4)!2+;9*3{HQaxZS~!sg?G|zL|=PW)@@l8;c(Cd(xtf9ioBj6x>A%~TfT5Ej2CfS6xo7Y{e z_GEAS;5(#gy}$q9gAcVR_Ljar(E4sgWqzQl2JSoxRs^t4&cMMkN-8) zh3FGD9MmUH^%b}d|Jzp>{CGPPd%z&r%L4_2AYcPb59w*-94t1|rHTt<+wV==TRMXq5kT)? zoES@@9s+;($$-`7B~Yi`uEjcu_Gpe9RtefzxF58AF?Bs$F42}F8%8n+*NxHvRzh)7 zF7k-3Xg`#Pp{cHavk$y8_y1ZIp2VRkIV4a#JRp!J+Ka>Lm}!k`!rR_2hHLh5w#aj6 zdTfB)GhFjiTJ3nXKblVn=F5vGI12SOiOgm{Nt(ZsT#-@YE3gQ)Gg@f4lUu@E6hIZz5?jNq- zzbIV{`z#4!M8z|!0FfENb%qwaCDK{ez(@z~wykytFgbS~DF+og<7BTut`LG1*?q6h zH6eES?&xsppX>V5l?S`Bj<0T_^Vjs0W`;cVfx`xggSV}YFi+8QHZqn`lGo- zGs2#8u0RvNyTiF6>OXo5T+_Q=>XU@k%~_H1R0H@2(ym#e_Sj~N;vdJ3j*-v9xz66Z z`&0ioZfC-;&ZGX^1qFCdTM-=?_p4!V5x$JN7spvXQauutpGuh)sC2VQQ0`#OO!^51 zyewH#LvO_h$Q(6^%~h1|8>ke;w{d9w<~64CsHjql;@ea+)}~ih#8GwC-P*?8-TV71 zAcs5AlXcB6(Qn3P>0Dcz$;)dcVQ)j2@md`mEC?d=)XVSJuiKP|z}`a96I*sdpW7~e z)v8IlUw*t6uk6nvySzBjZ?;mgMMv;loVX;sC;5L%E!b0bc~_o!U+nW~TjpmG56Giu zHX8RAT>(E+ZDF@qYGoT#o`4^Icy^WrK`@d~#Dj<27kXqS^f*)U9RNysRQr3{zW!cG zMUUk9QYi=0m6=-W*&Th|oKn3GJ?LvG@zmTQM#_HBSVf?gqvLksRZ!?WF2A0A<2f3l z5dz2mNH{9e&PkFBM~jAVH?7_ff|Wvrj*{(Vh*z;!WuDV+AeaygAo41iV%4_yR)zOx zuc_}W$Kir%Qv z<#EtnmhjjUw>Jj8UTFha=-cyuz`Y@>!k&17BehFM@Pc@^9CzrY+dN>CnZ>he$=t?; zfuHaBDGrdk%pi#nc7lYIFH}oLUDcgWofqr?tQ&U3oq1?;$W^FPfdgto zEc>TR6{zSAGxmVDW&a9;&9{4|(HPx}#{8syNzmh{y zTGuqm2K1^Etln}UZ>kk&9p@K4j>v`MmVQr879u?e-{l>#jwW50CHnVcGfXhR-+oA} zpdCkWcByrHbc9{9Z&ZJLQ?Rf*TWST^)4He205eO-MxLVb$>(ryZ}0Lyp-9`!Z@ZJ!QC5S1+D0N z@USXh)z_c!GrPtACdqd%YBOJY3ZPk zR{cWp`JBp;ik@MCvgEGL(tjdl-?>|uwdgN4aC3YeTHndj&#Q0!nU@*>XMo)A8>Dn#{@PChU>Gv?yywiA+K5s9Z7QB;KAnXXyU!b zxFP~a*ZOes``?th{bAh)%-8)Lid<@hoy27tn; zfB3hSmh4zN;#_q_)lpD0(M|^(&@4YZe~ z>}uUl#Vy7AQc;;2&_B8?N1LZ))|~qcFe@rz1ZZ=qN*>vYc(FuUX@>Ttfw3E8O9I{^ z*lQRL_5Q3Cc}7VTWY~|K!1%6gEz93@aBu(yeg7Zx1%a0qxcCfM_sYZEsyEe^Pdv*>SWvl1?BGSm5NMy zpI+)(I;ST=Gx4lzIltKjfq&B*IOvLnuhU(bnCk`pTWjGhRr#(fsM-#`LtrAH+t>+ln)7?aB^mmeNU>j=b*lgN>@j zw6#{`-3z8|ZF#btC$9EV3PJs>cVFdc%u7#BNQ+FsQXdypzgra3m61WZaH_Nap~_29JHL+Chy`KM!gmWD`I+xxC$5R{=-$%NnbpbEQh<=|U z|LA5tsk9J4!?H?|6i4|13aqx09qh%jDE_R30bt~FOqs;Xa z>AIigTj3CE;&WIX5}QNfRcZI^vR^HI*O{50Z)P?C@l7eOh_!l{wkl1elk|E=Dm|%r zlJ{qXn8C3W*OhM#%3agaAA?6BW2Fa3|D~dx#)+t=@xUesR#%!8;}#eQT4NQ7xQ@x- zflazgpG~XbXBv%as{e} z*GXkFK>Y8zZ$k?om-eUq8TO-)`^52!DgJ++@2s$FoUD^!3K(4uI8vhae(V%TaNUmv zXS%WVX@)<8{r|&nz|9w6Pwr0ie`S@hdNy{(JIORD?v0w7(8l8L@w5aC4l`GCN-tR# zu#P04SD`(A!rb`|Wu;Ok(s(VSl_H%GQDBY*jd^_!U`;YH5iYakV^#asRaL|90HHh- zLI^2Tpbd|UWk{hMtwY0jX}fC|NQTmibRtYB%ZEA|bc;x_J%6PVlAG?B&&iv%#zmp}r_x0`-{y@*bGG%i+Gr$LeHV>FPJx;d+ zBC4I)!NO1Z-&Q>*MB&+#u%>uz~8`h@Fg19+iaes{HzoLe0=L1q5ng?@`bhzAT zj`yjx9FcF1aGzB=NA%M$2Uhekm&(5E1W{(4@7`(XqdZYC?8f}?&q~4E_Str&MNpXb zu2eFccYwd>9FUxO69y2hz%@a#3mcF)+NLC&_Y!@Eg*l|(#?RZs-{Y|{@3wte!>50e zHMMqx9G(k+bbZ+sA8}X?E8t9ngy1AQWoLwP9#@zv&6K~UxO1r4YR3XK!~mOM_^IL_ zz)m66T_}en-Kr%4Z0K37K{gzJdf!4xfH4N%jQm;1qo`_Jyt@R!ShghpbpHx?dD}gW5e)#w#`C3TRm$-o>7cqq&?FtQ%eH3OnQ4bSd=hY^W6g?U+`- zxP%h^u#@r43B?Q3d1s5U`V4hQ{tkrzUk2K5EWm5d|F1*P6Nj;*vMxRVD-pF6a5$3y zSBdkl`*x=HjgOY1%kq;*y*lLz+D(CbHze*IY@PqKYE(krIlWj1AO>GR`0xUqdJxc6 z(J1IsxpeGvr{>}m`FWLcIb%huA?h;YaPahM=LIc-Vaj_0Fp>QXe?9A}aQThuK|q=1 zX5iqZV-7`DnO|4?J+#s816h$WOj%%4yg7K&e6Y-4;f;gYQ3&lAQ8yA19=Uws_s^=E zSe4X5SLOPV%Yg1AuTOYkJoNJOAgi1nJmZI0a=91P&d;UK=okWYc7%FTl-6l?9ncaX zVo_)UoF&xuLM$2q9GOdiKMsX?(D?C4e8|Vu;`x!{`MOPgr-H7B9|7~dzD6qUR43`} zIB5Ce!NOXH9_h&Zt<^sc%57tqW1O(U?p*nl-(8)(4fk&Gze-q72A>7c0_S0o<_R0KF z=`NK@!i+<4kyAETAw+a-%ir%p<>}e+#OIT^flWY2K#F4A%+E-6*r4xcdl+Frz|NB< z21OsGZnY0N;v`p_jXIFl?FTJz9x+hA9g1H9Ug*9^lmy`pK3*7Wo*plIMOF2D6h`uS zXj=%A81_LfFJ88L72aZBR$o`Qu$wN&ZA0u4BiMvQW|jdp)V8qH!VW7-E$pK!3ZcD*7lMur+DbYX$1vrI}LULBE_g23oVG93|fOKhdc7 zNxKyBVAFq>?Z22oRqtm+1$-0#YQWJU!`ns13S#A->rR!5s+g{ax@i+wC1Ko=Zd#7< zk2cX;<4QRYxL7EL5F+BQ!JQG(#G*xTBdTbvOmX<6uC0A(cxY-((0tVw2>ko*Wl4#Ug!Qk`YkvyD%&OuZH$ZFTx4n31I@Mq z*Id0$jJ+`mN)@Yq(w$^}ogZ42I_@2PEn_hS1Ol?#;Gno%Qv;e`Dp{&0``XUzC7)mV zxz5%~F#5T1#`OJ4s1+7{6>*}82w0X5Dw)^$yJSsl?SOUPAt&Ce7%SeXC!LRxJwg6R z0o6yXW_%b(6I2sQYlDZzAz>JBK!t&75Kb@$-Wu10q9K^%?6aJpGX#G11d+LEpvF3R z=ObeWR8lXVO8+%7^uN+Irv_2`irgFeUkQ5gGn;B9kT}2 zMjgrcQ4<1u>~>~KZ!Z3mQ1tZ+{2P)>z`)ILV0F9nYk?jZ3lZ5UKc6H`^(tS{$3vL_ zbUzMhfQ3&HSKvMJjv&g%`2|V(W}I7E_|=o>z63&;AT_<-C2{nAqBu|C|D)-q`@TJQ z&-3c>u3n%%_xyh6KIeR|Yw;HdT=xSIax@6*i-rqz&u*&3&*AD)0q?;uMI{Okqt;Ld z--PV9*mw~f0zMKguM$*1oT8#@yV-v9ckhY(t9t?lDXuMfNj_%GD#pwPx=El@B;fNw zrfBhkRWS1Y7pa-O+AZIrle3?a?h{-SY&+6KH9-8mEolKy>%BU%^VRdE*O078n9!Fm z@cPk}@POB$hBgfTQtX!sx88DwPbeFtj77{Xl%|!V@aph94O)%zO^V7I-UlUWn_v;c z9eHj<_|hZWOFwP~n2gL{&>FV*cx$-|=j2~gzC5JuC%c^Gl(iBvKzTanju8%y?L6r z?o6{RPp9=OV(ZVYHZytEfGQSDXI`uwe)MkU^q-Mh<(&z1*qhBd1#$#eRjQ;RcR-8- zFVjrdD}-Apt+z@-sTT#Tzl5QZ7&Ooba;9qPQuLyX5GPhtx?WU z+iR{Ne3_NopiH0PQ%SiJk+9%7!o$UI*YCbp$mNT5PJaQ;upilH>(Q9j8Q(sCD8H8 z@w&vcr0hZ=ye@Ma9_ACtidV zd_yJ0P*HHOKcedvv8%Ts33>(wHiSt2bDWk0qMMS7AP;Y7E3Pt?pjE3jnXu(WOn2?i!O&+ z{Gei^{gH@{IcR6Tk`CZxUEK`<8#kByZ>NKwJT4K@>*V+3>f4(wxt$gJASUjH2<<07 zS#AWu;B$+_@||0<*X|SeUqge?Ezmd*;heZ6k`g8@ZVRh2;T~`W{ zd9Q$koD(Y0NS`*@#5q!`0=9~jg7lR@COI89Njy6jvI$2dTu=reY6O>R`UH`Y-HNUy zY@!71II^S6N)0LnJ6dj^_!%EVqrsBW?uvKO2~-^QEB&o^cUMQ1(b?u^>>0{X3$R}n zc|SocDHd{(p2*4RKy+g@sfXmpwm%@9j%e8QxX05KYywCq*(Iu zxdI_^zbiK22t1%)*>3){ZS*@m=9Kr}b204Ww}2uPrMjOnzj%zyYYW;G3KZ^o%x`rX zxN~CvC}HsnwzkT1A?YT%!W{D6?w+3IptaeZ49h7J6v$&XxnNVmU~&P`;HIAN zU=Z1Nkx~nSY6q_Dc0A5`-+y!a4%bnC0@%5pFYLGsQ8L~V8V@PxQY#duh!}Po(6wNT za|NU1)b&Z*4&E$EaeDbU!O%1U*mCP|IYk+vHzl0KhSrj-hRX^bJka?;V*sPL95%qs~onkmwL3s&M`#lw!ztTA1hYg zmz-jdM!Zc$vIH@3^&D%61b$tbnaVrM&~y|z9wyv$&CD4>0MxZXn$DhnCV+HGFV`x zur>5kP4{V+RClFB-?MXRJdx8%=r>`oPUbm4q&zI1$-!mvy;3O5^etuSsVL#UkoSG* z#(dWKV4+?lSV`*(0OL=()=zkK;pFcvKA;Pk-?ZvkQ;%DklMlne>FYx_wKdS`^PXM< zo+R|jdxdQ6UTgo6EhD4hDJki@j>DWW1$KSrJt<2b0GcZ4^-8d?(JlC59@Cs9^iT6q z>glu7lUB(wZ*Hvt`25n+(VvhAgDU=RjYZTzq2UFn60|ZR>_GxGAf=#F zQ7{r8|Md`tcl{c4Mf49+r}A?7=kxQuYM!Brf7Qv*#5>}G3iD4wum1eL-&DOEAY)cl z&w9M>DYyLOUHY4 z;5{8w_+k_nIlep#g{jKk4qRV)t0SNN8;>?rF`LOth@5Cx{M98zu7w4=%D?1on@|R> z$SK$ygA#!uGzp=~Nlbd$RGAAYuJ}?J+Ixp4YEy(daeay}9%=n)RP6s{YzR*A*+r3|oRLk3qH# z7-Iswwo)NV9h~pLz2=j^Q={Qak=g?&Qj|(|9{QvHb9~FSSU>BfQLnM%zSEA=KP9W- z3=9LBIuv(h{bU=18(=^X?#d4Gw9m(9d`go77D-+QZ)zyu+(CsCP+gVOv>#FcMj{~a z_v*sIcZmXE0;3Py`4eGa%wppymo0y?H;mXbZa|PH2=;)+H(RpY(GNdEEX3Sp3U(`g zT5Bc@x2qqy%G&sy5$0Jx1%wAALqK6Z0jIpN(J|wfCi!efTprHX)ir)j1$yFMlqk^! zb~ay@R~9dnxU|!BSDFY^nK{p?>gRpuYu;}tTzp#oQL0($dx4$KD-XxJ@s{|?L+L4C z3f}yg-K)t2dBXD?uM&So73lM3ohnL_m9|<%FNL7bF?b|UUJB|7A~}Qk@Wv_DKA+*6 zW8sPr0u|q9iQX(XW~+=RdDa=W#O{9@p$wb$2#X2!=$t2j{Gp>4RUw$CN0C{)P0be! zr=@;?qa6x*WzBw>Z6Hh2P1@u%WaRYXf!Su<{nuSjgOD?HfS;uFxCi0(iQPq+_FdSQ z?h@=9?FZHTMpw<8_7@nsht;bm>S)ptyq!0d$uQ|&9_E0ZZ&Z-BRG*h3H=i^-W7sqG z_qnsDeD(AsgVsBJ;^U(m43Op}ubsh}#jBldtMg3zGG@hRW@6juttVy4lD%`+n@@}; zGgbF4{y8tUUi9kNKAx8I+Ip0bd65*;H2J++HDo9>NIipE z2?NtZz7P+8`*6k}o39fR1Y=-(LfVj~c{QgI^+xhoDio@vz%}J#rXK%$46M$B5kONz zT{c-=&|q4cOZ)Bm*xLyVO&jz@P&*XJr%TXp-ME3BEm;M9&lq88$RgGs1S1TafSCy1 z?3o$w&x)d=3X?KJ&^J%a0?hM)?#1F*g+q4k#Zl zEqTh?H+lu=k|=%E%t!MdQxh1@+V@Ds3>|`l=*901sLL4|VLs{3eUt=LCa)dIK67@M z^SQg9TjrdPF3XTga&DwHP#{R8KUfs%*3a^_udCJ?m|h2}q)gz?+57YM{J#U~+i0lK z{+B*NdEk5N4|`H>645n^iXq%p>Sk4Xk7XmaRI-1+kTVws>ykZ>2^P=d0Sg{)0yd{3 zWB*JZDP2H!gUNM;kiOnC#FvUBB@EYU2p=+MBE(HzRg8Qe^*F6ziE9vhjUH_GbXWZ1 zq?eSG)GONd9oTLKMjHt&Tte?9Zb)4I!O^7ukT6>v80F?MQPPK$>}MLTg*TOEwpxtu zHlle$;Z`sc$Yb3emVBwJm0Zf?I5#!@tlY>d{ox(FoK`dpsjM0bjeC*|SP40WBRDbj z42PPlh+MZA^n?=Z>$>-Sz!5b_v4Oo=(iLJp?zE;`Co>?{JQO@!1@g*W6;+ymz<;u&F$=iw=jSf|P*;6V^w` zWobnp1w-G#c*JP%ozQq&Y0oxkA#|$sH`6X^1a;ugfpyaQ-MGlICK?C?>h<}LxzBd; z#b4%Gnn!W7;M69YpYAdSK2|WF3Oyd17|}Vo-r2?~9tMG6`p=Gg9{+K7A4{YsUW{?b z$gjg`cjzk+w1&;bO%(i2{A&~>JoLRB2dWF|oHAy=e>WYMo#XD^NJ7Jm?IHpcsX-RS zXO2(YhjRrBY;pDdtO>3hN>3JKfQb$`S6ZbQ_qU%m{&d<9(qU|uCM(MC;jWNwG7B*F zk~rR`gO&7O)sFV|ylwB8bv|H)i-qoeFvJ!=D2N?}EyzpH5AFM4`q`Q*Jq zR?L*B_FJFzBe376MQ7$>mLe?{;NemD!K}<^D6PA=SbwxlO>chLw(?yH4f9(gEOje9 z*ewPURrHXQqW8N$Sg4ORx*Zf1PD7v`iLL;TR9S`QcPtmXK%1iYsqST!^f^ET0YAjzY$L+e)2`UEZMTQ_~TzLaO zh%QxNpO7N?dw~u_|CM&f0FaOE58mY*{cXY~POUdwQ&S@e@)qE0cz8IXwLeXO%%7Km zOH3m2Q-j=?dct3faFL*v#FW1$O%}PU_EYVICXC?@F+ZL^NoBsVxuGEekd*dZDu240 zrslCBW32jMFDzZ;yT5HeO-9k4rB(v`GeHYlRgN=ZaO54-1xP%eYEJX)Bt>Ph;bID$ zb{Yd7&^W}PWwjW z)Ga7oq&zE?Urwn zmcrkZe96b19*&>hhB!#tb^cg?2o?sHd}}V!j8ra5V8N<$ITQi;BcXM8O!A81hp4+j!S&5z?{i-<5>{4F*dl|`nCC^ zKSyw~k}z02c{*bSBhrJe^{soGHU{~TmQ)XEcwth6#F`->uFs$MuiT~-;E&*#i@hX+)wA2z=z+IXcCmylTo}WLie~1snr(~NMUdYmX(rIX!eF=r(Oa^*!JBc5SstA8FdFW2RA|vVGO@_1x`ch~Wjpoq_!+}jx5FoedW#w! zBJv@OwWw)DuT}eN!TahZw_cO-p3-S#mH%KCN32B90nJO0Z}@w z;Xy6gm}tm{`n{qyTYZeKpmi^knF!5XCA;PTxfCxD~tOo0xCsToYKO;Cz zOdLp6fv3Bt$1YO*Bue#2W#tVk7oet=V=n=#u0q4~942xBTThIW@(o$*Gg!C^-0Ux?-~~nvz4Ymu+5^x1(_otDD&VW;B_e;m&dR#bdM+Z zp|hcZG5K!bD*n|VY51Gg)Nl+@h16P@L#K(B*v&__xkg6q4GgD z$3!F5voVuH%FIwk^@>tFfyE*prH$5dPYsxMvX?Q#?%UEXD!-~ zEIZU^W@HBZrXO&8&&R??U?xrJ-^!5MNh``0M;)tv*54d}N|( zZ6rToU&P!D+XUag$GHxk*|HBann7?AA-2x?`TE>`via!snxpI>$mHscqP<)H|B1aA zPfNCVc4F&wd~{I6`K$G0q8DGe9^#>dM|DG5WadijGpetKTl`hV4@fY4``xC%Hl_TY z;@UD7>b~`1)PZ7{x$K*`K*Jwu>;R3tM@7^cikZTH3XL;PK~st>)8~A$3-EuHVR|g! z8Ws}|OtTRdX+U(dK7Mi-cz7hK)3B>F|Eyf70?fc9wERDyAGWZ~Y1${x`6N7{PB6(8 z?3YQ`l7U;PC-5WKkievrte4qqsPU#sK3g079SLkxgIx!C=U*`wYaa@~sH|Ida&kVj zc#;v0^n6}ZVmQ)ksK(I6q=N7suX#SKH5H1XQ*@zn4Ih8IWb75Ud1s1pI7^ zOQQ)8QI|;CwRBVnC8BCamrKh^J1nqew?K~q0})>9P&h9CMlA~aGw+RzB1Q|{*g(1s zanMJUbAABtFza+%ViYnO0j?7|1$F#UxC+y8KJ{v|8=Dg1t@k-&r=El{&(RBS6k#yp zY!}>ral$P#Y~+E;Cd*4tAo)q*1H46}+0D@()i0~GT}qR#bbz4Y&hcM>cfQ9{o!J{3 zur*Nh1t_V_!Og*HS&9y41_F}hxRiX{uPPFHc7MPwqScB0ZjhAwOL{|r?3r{8W*Fli z_CF7WQ=?~cgt{k`@%_eg&xtc7@SGuagJeC8)weK4;F6F^Rl-lSN@)?nl0#mS>9FQ8 ziv#m*QaI@hjs(=V#HDjV=9z@S`@V!MvsFzXrdEEZ5Ik-2vW{?#@WK8 zYTd@8p{0>2=jM}Qo!PrTqJF|9!a3c3Hq~C(P?MLR$Av{Yx^igHC~(CbsEgRfD?Uux zSW{1wKAsv}nvT}lKPR?s6svip$a|vXJtNn=QS3L9GR_44Z0jGUiJ`%`jIGAhfU?YV zoIUog{11lc+f}?rsmy$bH+FhOFAw#*wK+ZY}uLe zQfD^C_Ce*S(dC-qPxmS9JC-*J#%I+Six<*jvUe=15bBFU-uo~cJfo71qO~KU&vlY5 zd^a-r0#6kJPDGjyQjsDFsGr$cH&X2dl3*GF3~!_RXP3?UH_^P}0yaTC*VO|lb(lCt#le_5sKVXnH& zcH-G9}Jc=2%bkED)#*+{;SM$7)!?J-$9A%tOcdx#{b zD*~ANMpt4ZrV{()-4abpQ-*3wS6RAe_S^TLHfmRVSUenjdImG}vvjcl5Q~Qj4t6~4 zUK(hq^Hdo|7x}JDyc~RLv%GiI9^KttoR9m+OmtnnJ;%=QD?gKD98oTwh=4MiLbdJF zXXmqW&b&`Qy1@eMN*{(caSkt+BLJ=1z9h-A>X$=Jri2!0n;93Q2ZCav5GoW_JUpWH z#QO)1)NN_ZoSZ<*Aeblc&8g;UM?9JfPn`Ps)3e^RKs^IhsE6g!VY~(+caN z8i;$%+c!+y|Khd&Ts62TK>glD`la^&vp(YSFPnw)9%Ct@Ucigdb>aI z^5)R5E=@EIB`rzs0x*lk&tb2(tmdp}bQKkWS8#N6R+*7*EpG2P_ytsx zij=OmvuRL%Pg_DY)aA8uoVXcp1PNEdtX0{ipI!?8b@|wuQt?> zw~y}+Z}T;uOalP$tAOKmKK#d@C1B%h|L4AC`FBA9FmtX@F?KTS?gd@48(-v-l~5Wf zK8Dt~BBng+gxqM5JQ33U=I14IZMWVObe)GE+9yifOH6WmQx%1PU?}PIC!T?BGS}ik zoq>0#eaLku1BG3X>kWG6C?l@*Tw%$p{^0w=Dflzezihf9%93zBD=9h*UCK#rU3Zrm zqWpp@jqmo(|EM9c-L)$yUv+YJGLs858}5KnTgBPpQtUdW{wyr)|8ZX&O`1{9D8gJ1 zS3}FJhQBFZoLYDHUqAXe@2-&)h1hW%0leQ=WDCKKZ--yKuE89J7Lk2G7fp_EmOJRz z3G`q6^L(*2dU4Te;NwI`ze9~(?3n)+AYeLFU)7QD5^dPuBmKjibPryEl~g5G1xf5~ ze=r@n_21k-_|9s>@s4F}3CqP*Io-H~)t#F9QDK@gCP&Z$YW?#bD9U1#b(nKu>@T<& z_a*cz5k<`3u0#g~yCP~Ih=FN=7F7_x?`p3#+4XP47@Rv6$dC*BsZSGr2y0klVN)5$o{5hdP65zmm>D&So*tIBwUgvS8rN2MU8 z=d?ZCapB>sjLxYzhsr z*Ryydhh)g2=>nlo2tY2*9&wkR^RkVPOg8MNZ{vUR(3VZ)Kw%7;Fz~e+$bBGaEqw@Y z*sqdX#tCGYcEQ1Wh40(*vpdyJz*2^33;QmUtkh$4lMB_BgZ+!5nl_bncf8tQ2L;Q| zmm*4WAzs86H)q?U=Q^h3z3rB*Nfrb)@vMcAxSq3aQrD#J3K(bSjU9Gr4rRcOq=1K& zsLdy?r8WBd_iuT>gZ<69zS2?=XD81AYdfyTMfwmia_C>9MIZ;KWi~f4zqaTL_Z1jC zTx~pkbqd1NKY1{SQpZ&>&gF2@xaN6;fx$hO0GO90)p)m+M1zl*%70Iy2b~-S!s2p%}c`a_7nA`^&LNkSU#xsdjxv`&B{~+lZa7}d;YA`7EV-!B<1=nN=GkqJL zftIxj!KT;-?GJhN`$1;m%HealOicVcPI3VJIbp~TM8`&3-X*-l-M*7lVk~9d)M5IvyZMc^(l1ST9WoVp2$p-sw6z|+0+oSUjm|ieb z!`P;xRjRNzKqVU3S+TWTGtSnbE2x{2w=3MXM$UA8V6eZnSs-H8@D*E@YH#nKlf)d1 z-l9B`M3dvtc~#o(gv~o(C8)}zX??BV)6dW_8h~7djIOeN79~Jl=Q0z^Qlcd}Z#Q@a z@Y4A0t+n`8ZnVtV2=j2}X9tBBj&phvTX!6;b;S0&w3m^%%pL6v9eg@ba12?8P#}&q( zQAn|-3QN2HOoy&dGY-7vJWc1aUghgT<9P&ncQ}9zs=!r-@wj8W$v)J?PHi&r1rzFgrPyDI6|Uj*QqV>S4iW#X4ms z8epqA4_Xc%lV$*5IlR1Valo?Nd$afMloa@-!FL*Suw$hsyUdOg-5{!;xXWSupjob- zfWjfeCN-h?xnC08)8F;HG;=kzPEJu5rHm-P;6L|T4Nn7y-PYw=!!RJY&gDw+Nio3V zt6#I@@oEz!<+X(K6w~on3j>bBE8%}6cKGbEs}X;1t5`C_kajQx45r&wTSDcU&#-xx zeQpL~zMy}!LsfaTGu2teOfP~HD2`tk@xC`-1DUp(2TUK~!Rz z-z0jU3Fpxxyq}Fd09af_r zT5AEdSZm{qS(}7h4L%w5aMxeUUdK|_#?`k+ zj$VF#_4SRnIY7@b14lId9^M4lEkjtsGy$irb0?xsy2_EsRt08Pa`X6W z1n8WgeFYw77ep6L5{&J$+~~l^Jq@=pMl#H-z~)veJDOc6d=5eK=2B0S>)Sy}zI8osO9ysIL9=h11bgPzEy{`9NZ+&epq%?j`q_T2+E3NR`Fh^ip zMO5Hfv30HCU#rt%YZ?thon=+)H68ZPf7?4A&9ydX0X31?sp&MMtr+@rWv&X*_N3$* z*&@Y_qa$9_7RMW^Hh|L7ofYamv}b7r~F^)NjV6YN$R-%t|r@swJJ& zMH{o}%;kKc&3-~neWvRYFsg6DBHdy-i5>$I2+N#Aj6FDsF&D{a@4klR>`s)}{{nbZ zJ7ApYa;nM95*-2bJ|Gx!%^x8u;!WNd6S#_k!*`cWa4?%vr3enG{O*q8KXE&#cY-gC|_qN4PtU)kN2ripz;IC*b-2bYxK2zXb-1PImWL8l$JgbzL$KNb?~ zN)Yv?bD3NBDg5lg} zIkPrFsM@YqcI!pSHX2xkLUYbiG)^e$>l!nE{bS`zusFUZ2 zu@!5nAIZ!dUD*WU+d&DZV>T07KB|?<$t(!0-18hpug#$5W zdS96fqBzN(2i~w4Rm|Ak7C^}JF$1SnqL-x`)MVF_ZB=N4w%Tv*6;uhv6w9uGWNW=OjHn<)lY0Ew|9!+*e1wg<#n4K-8$U zKOtR|s6NroKBDEJ2M^ZBRc>h--F>3gN`T8GyQVh-+>6oV^4*`KOg zCp+GxSU=LsQ~$jhW!@&b3~pxgipw-X06Xkl-?VrjANmP|ub+YCHf8}}kOdQD8QH^| zbH>8vb@wUUToe8(PY$YoN-AdRaTYfh*&Et_2o0*ts-Yi~8gfXVfJ)q;r1-*BS3&9~=ppmj zxd!`sP==txZ8J(sg&XNH2ya&6jM`w%Z-=3vk0v+90(Y~T_kZ?lrR?sK+;r#H8aFMLC zWlbu8>TOJ|OFVMED9~ZCR41(ZO=kY^IT;ON{LjgKvtK;jV~%@Ndwcs z7r0sH8GzNyVc7O+o(_{8YXVn9FiK-oMDZog* z9e8rIvC%GZ347iCKV?H^&}e%oWH@w?nfWM65#p8^?lz{GNPkDI97_t=Iyqb%d?xnR zjiRZl4#vljhxP)h;8&(*up+pTgKVGmrfD-GWwNy;>qqJwe>HKITr24R5$Sq~`8o7c z9Bq24O~z%x8$yYrQf!ilcvvSwEJ_VR!;ClwbyK+8R;wn?c=jXHY*c*CMR+8)7&Qyt zM~O41a%|i4>Ct!95&GUS`kVI^F&i}TuDtQ;86HyWD`SsYni*kmm2)rdD87~*cB7_d zF=q@b6G4MBze*R_wsI2bO^P?SpK^{JKKMBNYp*XNFw>fP)Th(W>k@GEK2zJ+3GDd3{A^R>A{J(CvUDGSS|=%t+zz=XvMG z?T>;N^DxGHY^grvbIYwA0e|Aw^PvFHa!StIUz+^raJV6Y<+y}uW}c^o@XXd$=^iVB{% znf^`-jIix`rmYkKZIRW42YcP7XKTZ6u6xF}_My|Qks|Cf-U^9vr#?=F0K0l=E2Zi7 zoRXAQ>jc#Eqai;VgKM!K!@C66JP8H~N6D>L&?WY*`n~E@fJ@S_HU{&gAwZ%ro-v*! z-d^(Rm^#_nIcSe&t&toqn6mf_5`WiB-VgD}0JZc`T`7p8QX#_B7%C;sKvvnQsvHw} z=VezLDjy2N<^iJ|drSwP&a3QSz8lpm zBX#oEv?B(}FEMk+$HuEi>S@X6^i&MqPB-HC1V003Qze)wHFT>mwn5@WRS7}aT#&QW z)YN2AMu;fQ8UuAC6q$pH3ylhy*3D^s{OLdC=T?UyYzx&m%QX!bQdN@1``VGK@beT1 z(gi~_D7V{&wxyo4^m@wZc42z)9^Ir@M!z@D$@dq{uIfiO0=SsWTS0BVypHAE#a=z# zUvo~<6a}>KxZVDTell4*fI3jsawvV;0vE%O*{0-r{+#8ac;_TY^nR02A=Ate%3-bd zLWB{aX*WQ%r-Ya5V+HeU6UKJ%$*!V7lP4M@r>SN??UtCSVML8ev$VHG>Ab$AF%O_j zNhyF-OnDT`*}Ojc_HJ|$<{WT?iVa&&N7@)7j=v~O0_N?DVd@oSd@Tk6>s)x0ros^1+I3DvePYTm!jIt(eBOZzi z@I>c)jm*w>ZLUY#!sv)M)pHDsJrYoo!$!>~e}|ioW<)w%OLPiGj{nRL*wr69RiyBP zynR(m?F0KRPzV?p?>y(^-czIl@2TUOao^peB@X5CpG44G=X4l;q_7V^!_c@rG=eQy z+!j>VqX0=G9+*$S1(=j2u8-JjS|wi8=n~SBWKw@* zDypRq)wS=1gCC^ye#mFllHheYnqX&~G7W%tK@V~Ugxtowlw;{W4Ee+-tN5&r9fNx& z>kP=Y9_^7T9>QMeWuR3$t4G`b=I08W6SS6jb2{f5^?qd(;_7i32c`A?>yw*(foIgB zRXk3Ci=8J}++It;T~g8rTwROp`d(d&IWPWl>T8FZakgNx#v3p{IX!sS*0u1nMS8Uh%H1md+-!@zF}}BzhTz84!CDTr!v9 z5fHH`Ji{C|tP>%cD?(@t`Z4NpteqXD)K*Kj6lTbQTjBfLMJgW{6$zZ%Q`OyBM#cP5Q6p3>U-pF@NX;F>Hd0zb{cvClQt2dao5c^6%21Rju-2 zU`#etR}1ZzW}PyzLCy+=eN!js@;6`m_d8s~Ws)wuOzkJW$rXQ5s7nB15yf*|w z?b*Tf5W^C8e)la9JcuTA&!E3&)q45h%>SPD-!;u2h&z(ce{i#Oro zj3$%00|%gGzd<8Zi@TX|e9N_reLDGS^RsS+>yyRWU8~k2O~>W_eEJgfN)nQuquVYF z@#U@`rlfXEM*uO(jA)Q^?kmGrP7 zA-uSalf%{QtgO7kogw{PiF;K;khHvXy>D16Rq=5YLOGn^rV4AUf`He(t+BTIuoL4M zE-QI&DE>$S$>hetpOCxY5uZ4EvPO}0W>rDt5$_6g zBfB>P;4vOqHibZ@^s=SCe36(Qb2w65%zAiC(e$h`8~0mtDK`-@%sk!WJlWi2O>LFR z${HVE)@eQ(yjxHguY`nge@UEns00+I*l}<7)0W0MM*szUi&7t2ylGV;KZspCWCb~K zH*)svW1?GWE&!h`vYNafUGW4&6v^x4{dw=DI?qz7Bt0<@5;9(_b3BCOfSsMEzO;1l z444zsTH!mhq7`3zSdxtNViF4%f2HBr`7qh}UFLeUqRm#6@e}* zLp*IZNHcLDjM#XAkgY%TRDWlaVOnLF9vS~#I@@!0N=!0XX z?YwQHcHUDRz7}tTWbBub(cVJ&CnRU5vf<3UZ#j!~1v>H<<)v10<06Ofnu~4Py-2(zV0|E?_&a%>pGPc*U3?EJq71%F<-70nv|2qBmuWfIahG4C}J=lHjOqwBp zh@c(Y+-K}!!+BLDyzC8a8VJ$K0YOe@UtOHq?C#E=4^2SqjRvHmjCGmua-sY-!Gs7k z*nM>Ar^v5mmHhtZ<8snqqh)r(>Y5B&mb>=(GAnD??T}Aqo)(m46cjZ7-dt#_O?+xA z^@$2D`r^e4k6cDFO(i}J7pwkBY$2~mxM(?KVM({#N1uhY?jhRrz4g2698MEP&IRoOZ1hs?OJb~eg@0P z3MwKB>rU^DIiCJ4aJ_Pf`}+@HUE9ti5DuH=cZx3nvV^1wqU$BdlJK3N&9Zo^Z{2@a zOa}jk+$3Y|Kf+90Ft?m9b~5-7Bz_hy1Dg5GUR;LioYwF*#n=8=G^UeFy}|-cc8!XU z%8?r}V~z%Zk&jL{#B&A` zEG+`@(mL%wQtBlo*I+BM#3lN|R)g&rJrRrbk0-}q?<1m|0lxP%kX1Oa8ldZQof zn5-3PLW!qq#RU(0z6RDY^xk(k%PlM%d>q%^qGY^T+&w%V>;;v7_e{n`o+L9NBV5Y8 zEII!*HG$*#j(>_oi9IPTE5e_nrKR=ESfk=(^wg}sW66Ku5{?z*dQW*q-jpzP9#UGH z080jeJ4=Onf?6JC%mk2MCX@pqkh;J>tf|lH@S+ESfk7H1*U15d9! zW*tV_AfR$LH7GW|=guAhq9*^4mA4Yn6zwVgP&&kpX)L~Yn>s!(eP?XYvG~K6XiJIw z&U=N^pep^hU=V(PIvvQ~ufs=Hy&NS&AwyWwz#DPOSqcqnWwiZdN#pIMlHD=c>5|o7 zC@qfPfiBh9ktVw!BAUGB={5S{CM%dG*VGJ?Gg0a^XONHS&a&!3!Q8<23gPA@D4a<> zVZ7d}tVqN9oqm;BnP>e-KJH5nMA53}#CK+g)e~hNKL#i@s?86(Y zpf6sSv*7Zj_WRkhO^-JNcOweEu2$hvdw3|F69V6|e3=zLCMHt1td|yt_GaZdT-rmk zu$^ytEZoCP7dC;k&@KP;QF$f(f=P&mN7aqKv0g*x6uVdz9~}~hvDw*lDKhd*%qJ=g z4aQsUnEPvx*eUDgiDzA0c~~@E^3&{L9piUYcyxVArh>C zRNiwhuNB}bhNvgmk;JK21X@l@D6;@qUe-QdcYm^wSk4;?ntf~}dJcFvtixhUJ|9|ETA?0sfU5Py>dnA#u*M`v+`FPuMgZH$T9&ViT7O7g;fg<9}R3@3i};cZAS(m<5+ ztL9A@QWu3G6DmRfW}*G^V}D?eZaidl97t}ToYIj$JUwbYZ5|tF-)}4u9QQpWZTn_D z;mIY$LtVUnAHs#pgmnt^GdeY|6o&bN*tj`|auX#X=z%aQVlU8G_gn_@ZDD-p0&>mJDy5 zGpdWez>ant#AB=mz7I$k8bspjN1cRI2xw-Nagn3(Fvrn(CVqB+sVI9~!hqldxI0Ylp`!XYedLJx;g zrBQk&5b71cexBkz?twFGQ+pL~@N;>YBfdbr3G0|3@e)JMD78LsxD&H5XRh1Tn4He!Tlbs|`y`i^g z94j&Gme7Jmx;fMjVKY&Ym7Z{5xL_z3>c;Sai3v^&=)eL2G%*MJ!Lf3j6I{$2quuhh zh%#$q^%D#&etmGO1S-gWy|@UuGfp6nO_7dS`NP-&Os98#V`0JlY3NtG%xEEzydehu zufO3cL~;B?h>gBh1mMV>KJ(t_D`_(Me4niDbC1$;PoBZnP5vAaVb=+VwBq6Mqd$Go zlXNtY^Ni3aHy*eVo|-!3lc*?%bTrYg)H>h|EB*Gy8|?p3b>`tve}5YvQbzgOQic>` zC)r~xAzR22SsIa@B>TP#A;!LCFKbz|4B3;6Eh7mr1{sWf?6Nxmzi_>Ji>_m5k7y!=w|iHg_rKoAzFu$ae6qgzB6#!e ziM&|n`Ox{!`3b)A&rn^p!tAxbXG1#Hp9e1E%5zCZmJPM@L7#puzyLi~r#xdMWqC#|WcjkHt1L7L*6nxP;R}ZA#pH zJn#+LyX|HDWxdk&GQ+ra6JDxEshaVGN8?_4^YFhT%M#j;(?L!bPEHT><7Y0>n~RJ4 z`};ftKNqatUmb)A6obk`j!0JeNXwTv=PXu;20w){fG%E1DsDV@6t>R4D%M8M)vWEJk4MLcac1jZd-7uw$(&%Y}M=8qLQl( zI~S39M-VAgCN>l!rBr?Q}okq z^$f3ID9DY)`fB9{L0t2nY@chV5%K#MdPm2V4B~{NAtXLWo8AHP*+X8C=J#?6K&+9e zyE<1=bzTDqcy11c?#zmwr8m!6qom={p`wTaM4b`#bF#jsbjzgX9dtS}PaV{Z3J=tl zX%=6z{vyrS`Pu?#Y*U|?$OjuNSG#3~G%r0b_y6qnVp?vOGVW^q|6EYlh_E3A+g_hAxrz~0Y z@rXnZ!LnnfQF}f2B1h!Aq96KH{0M6gDV1a{pVv=!f=-z_q$8wR=-=@DoT>%p?i5iB z!k+kfR`6KiU~0&0nF7WcXE#MU0OUOFAa|@-B=v-Z&OfEWQzo~$%1p?ZmQ7wOSpp<+ zbLtGh1JA8FRG|bF`b-zr18egzy^NWt@c*_rrU5$CJ?_d_Q%65fhqh*Cw4A#M!NhE+ zGa)K$VLQ{(Ly2ziR$3?@dZk%M^K>6aV)S#9x!GgM2VfHnj_W@T;1p?G@V~(@BVa#0 z%)C1?QmWhPVQZ-V5%j($({>(OROFUusHfR}Oa!)&ViVWJ+?z+-p$MoW2VbM~x_t>b)p|0V8VeSJNyCekXW3_p%u1gyk5C%PRo4gBy|b5!%E|(WM7!Fk zF8H^%C4C^nE2F_Mcv0M2Y)ri`7Rbe|0`7Ngsf{jIMIbf~bQMC}gS`Aaf`Sg`fOnO; z)1wn%kEOKcwfRu5uQ`;Qh0Fq?ql!ITg(95@#JC)=+R{p>*!_r{uPtG)TCUM9#MJbZ zfvuMtDeoY-<^x0JK&{ruFF#@qUXq>)bvQJmuu*no>tl`dodp4@=K1wJz5 zibyi;SQf$f87Qo^l86JNwG{%zUMRSlE+e4I1dvl;D*hY0$QHI7M<=8GxL88WIcP0z z2hL!nc%9i=U+tUkgME5ep*fo!54B!$Lek*9T=ON3^9DDM4H<4Lbq2DE3yyud!_>~t zPk)HuEG5+MGrZuT*lt2GyT$uWs|t3Y{{OQN#;G&bCwGa50|k{ctxVO4-lzATo-=Ra zb%p~G)ht^ZlW!oQOF?f-+!}Fapt!>fa0>m0eR4gn^O38nu*ZzSNV&=Sj?w{!-#snI zsPl}eAu1NVbV=es?6-lnx@38$D`e%qBl-5?<=N@K7hfCGDjjhXOVJk_60aP!`EJ>P z1D5yF#|pcudclAH%z(j^eZkl*LQ(DuGE}D8frJJ)og_- z)MJ;yI$AVBc(ks|^sqBj9Fyn<`Gmb;%?t=f?WF7yRhxm)pR%O}`bLHYDSQ5e9NC)* zz+96fr44@TK?qhJakSY$@thLfH@SiI*fP?jC9Ld)n;Xe8*@j@l%!GVKJ>n~ui+P{_ zosU8|Hn8SHf9(^Y^4ebdP9&uYHmmBR^=|nBhwlw*#vCdd@2pzEpz}5#1%Uoq9qjj$ zithrE_41Iz4D~G_#Yuxmtt<|(caxsqqY1yuqb<%KK_>@L3)<4wj2{Kd*Y~x`Y(VKU z^2uriT2)UI&P)jNfMBGDcIMXBUbca^I|%BaHT!FSnQ(&qL~1exO6|y>i0`%U#z4cr_)R^bQpUmC66?iXDnUsV=Oxxzxfa#9Liu)f94@Tuhj^@y|Q~s!QjM^DlfCp2LT993B0;BgAy9$b~EycK8Vg_arRRRQoOuMUi}C z7CWDvrJI}hwY82bvO}!DJ9mTtvZxEF&hzm=&ww6dQ5iNOqw^-5!ew2=vonAj!2z?j ziU!{ll4NK8t%X*_CT9j8Dtg`86Z>>^5h4tsP>8y-=qQ=*(6ja#h;ky-rke`|`kMa* zg?Iti@QS}r%MDBoUpX)pkt!Rf8I(lkJzl?K5_C;{f&3 zDmk`N#FzmXXSc`<5B5~hC;I|<=Swz*R<_7tzjE|-rFthv6u?g#8p_zyBax{N>6b_& zg1|p&nZz`dcdwc;^n2O169cy|9PLo^^Nw!-bsul0GdSwbnL# z6zsVDe2I_{ayZn%8hKx{$)vI$d`O}g`w^;l(Y*}045728n*6WzHN{jQn)T0wj8{j+ zG`7pi{^iiiY72f>7~A8t^-_~QtR9VQ)z7R49}fJ3S$kvQ1x7NFzdhHNJ?qE1VMp!d ztIGHsnyAx-9s3O7y!C@d!Vi$|Ed^*H-3O#~#6EbdYv~V4XKUyq)0ASkGyw9!!~;7b zVW`wim!=8MNe)$pUtyH&n75*s$v(gFgPY12nCvaumeVT10aZgJaa(TYWrO0o`eY?m zny73*M$bwg=mz%UG}XHgmgwBD7qFE#b{|FTyu9@EDnfKgJfJ`n z{uOjYvm{=)+WQ1Rcl+om3RN~$GyUx+t8#PFka-o@?S;&`c2X21x#+q^!47#ExrP3B zZcLJ0@ppAWhQesZiK(+M(R3V-BAQ-$wBJ*VnZ0-MhIHsWJ3MBoDLa*|$nonh6WNQ_ zVIC2z#rs;minDdC-Nqv4{j)+kei`n?Gk0l@@3a#P-7v;cCo3MIhpMf|BxCdQ_mG|H znEzd@W%EviM0+cbOeVlq1Wq0tg$UhkeZCmFbR|To~XcXs#lfN@#-@2Ee$*AFpQPmXUqXLiWL8g=|;$&G@!Iy|{?6K5Lo?ly|rq5Rh3I4~g&JTQ7z}MqYj|Dwk z353n*V^aIUbPLhm-U0Zlqv!rSN+5h=E^#P{@W$36Qv~$jD%RBZKex9r^Lmh`RkMn~ z)jvroi)$-uE*^3&eyw(V;fL4@( z&|I~UT$yp(e!U`Mt|E?cL;~p4V7Cy%$Yd8IYd*Bn>X*q4L@+wxG~qjfx?cJ=3#Q_3 z_AXJ0whki_Da`zs1{co)vUjVKINXim-KPmNnsqPhp5^D7seeTDRISP%5AqTak#t}o z5v16NNE){Wt@{`RebcP{bRTGapb|n{^>Faml*dFvl%~?eImI|=RpyUS3_LD>h-le#PP7m4C>5s&(-@_pHE-xP6uvl{}pLDE@31My5e|&hk z9Rk@5xFTY%&C|~Nw}k&Vd>j=r`gbGY$S~u4MwxwS^?a^;s3S(fZ~V;Wq;ul$X$y)% zj{M71rdm9?2+QE#xx+f9A>o8$|26;kPkeP{KQiYA-5NXEq&H|WERZJ#vFjjbSQxcj zz@-T1CV!C&v)0w_n8l;TCv4ANkKS7F*?Ow_CnK{LE93Qyc3$|x1UHql~e!Jj@$&fc~ z-FO{c*cEs&7%XEJFUu>vrBdPQuS11~0l$^vJg|p!9{Y(l-G1*&)ya*&XwUu)NhK}A zv?vj!4^R-Gvn*pkdwhR7l1t+=9jIYL-Q5p4C54>0fFS)HLRb_ zlZX1TDN!eVsL&*yg3`6oz4fjK31j7H=!P53jWd47l|2a{U++>?otEmCr@<4lH{2sN zE;Z0SSIQRnB~jW@Dtq0%MlLsg$lP>ac_sm%sC)gM%~ON0MPCyvki8ZV{dXi}XYy`y z<4Pv*8;du#8l0+KTsXRshu@{y_>F8ciHB>z!ju4~>4JbGnAQkroYonUh|`Zgrrj7q zg1L$gplGc-6U~0-<>O^L?7#oIdxxl`p-KTNHWVXF94bdy6KgRxNPome$m!Mthvcai zAImsk@q&j+&G_zsGaiVPt50|ZA?@TNKs`#s9c3_VFe0WY0^c1@d2Dd`FYmkagg`R z>f?HY{fSa7e}6;AxU(6ww>4x}&RypC{r;YrLetsFxNz`}a6`M!bA20wT>*;w-;xk? z$`-JRHFhC7Y3zT+9@i5^Q^}LaR29kJ;-*@Q_Q=2HQ@29DKY zosTSLC1$$W-*G*nxAa!yjfQyg7E?ugjO{)gf9=w&c0zVynfqquFj4qS&FAu&dAITP zKgOlfVEJ7wT{D+HqkeE&MrOV@dGp!U*zIRW?SzAk?WxuOc4(>Li7vRs?uDHJrVQ(u zD?Hm0=69}_3z!RSt7gWpTfWdyeyST3FomD2X|#JDx%g{T)VC7-Q;UB?dFl8SBnT>s z#p+sm$A|%JJ>Rq{SB}rLAIR|z3cb^Jja;h8t}J))8E?UBn2J_%56xCb&c$+oNt-<<6bu)dj4xqj$S|5jQaO^ngX=-v&}?to#u_(D;v4 zQErOgCWg!e?u$Y@IWGc4nS|3RC<?4c1KoA@P>Cb_J-hL&(Of1f>6JO0q0HCv^m67GX6kY%za>ALcZp+;+ zXK?i{r|tT2L;N)zvD(upWLut&UTj|LdF4eW8I7_s5RKMchP@K4c~SwicjNLsi6)0y z3O-muo>eGUUv2BA5OvqL&%L!M@kM2Jj!tGWYUKk^u7VGi8fazsRwmGxJ=jH=aD5c~ zM#%poBo_5aXgiG~iPsI0>BV$&wyCQ^-xriWdDo6%9podL^557U?jP2-9$PZ77yOhN zOokO6&_iMFIjfPcAu*x|(o1L_XLj{xiZ3vGExwOwnh~1xO;*LbIj)aRpcP2i1ZNiO#k>cC6s=tF%BO6ik(gs zrNp3|Fw0Ew>FQguLa#8ngydINy&NLsTokk4d`~KC4+gNcO*dZZa0F7?%#{lVUh^$o z-b44?=Ib4IA^w{t$eu9A9~oX~UqQ>Z&Q%(>?gsUc@Cz-!*uLiU7sH$nz&L-r6Iaj+ z@>|<-LkxE=+RvXN>IV_=*k&m3-Kr3kWwpsf!Nc>y&@fhFu;O6v(9rF92 zO9b_}>B-rAX~+(NEhMqzBK>21@p;V^iHAQW3{8eqojh{F;h?@o_#$l4^O8Mkr|IUd zPM|B#^_}fr`>M^_msV#{N>Gj%6>2^8Lw9~#;2KF$@>aIz$tcMjn>=QJy*r&i0MrNY zrvLNl0891=xRl1FRB8k-SK26e0_%ykcsya*_r)mYu_V(Z@3tddRp2EeX#2{wl`(n~f%%}Sp<;D-~jIsz?>aqMcG4Dc*JA8fp z_BFq~M|Fv`*|Rp^{WT;iiQUA-USX6@?*1>$N+4T|YGm0UFRPf1yJNAEH~a)u8N+rk= z&oI7JO+I}Etxlja1u0-FFD0>qv4<^no+#+G8>o961e|*LLHo#&UoykMIjPqns9jbj zBdcI61Lq)d=us4`uCA6iq4ja=l7qFGkU=f0bnAR4W1t9J4i(;hzNPaichEhx&N5EX z#^csESrUHDtp`R3yTUyxnDiCqzF#}f;mh{5qFyq;0DEz@GNIFt?Y>B66Z-auQls(d;eJ=hY9mj<# zn7ai^6l>;5__0qIKH|j4GilaP!!Kx(YYsILVa#-2ShK%GqY`H>CjJxKH~KQB{|dPH zatEt>1d=xKY@gG7z10>@WgP7P~>nN-mSwiE1tulGNwR9NNZDT6$C)#eK##?o`_(ay^ncy^YCjr zpgj5e^`D(@`(T_!Hq`b}cSvSUPjd2ejbmd(jmGyZI}~owIN>mKX0F&K2f#`!pnEg- z$91hoQmq2F=yJB$l^?wM2LQJO?-c!-ZdnR95*Qfa(kMy=ka0y7)FX#9u0GZ)WN+g- zznTU}&ve1Nz>)qIfZoE$Pcyj)T%+tbi+`C=vb7%c zKH}~h9J~v8*@&wfRCBy$9Suh~u9nE>(j-5;G@E@4Q zZc52|vmiO8A`am|>fX$Q;4B`tKn3c~0Pk5F(g{@$JcK~@(1v^W0`{dv_Lqjcq}bZXLc2u1 z!HN=RTfHdr|M}!t`@j9^bfSErNNn zy3*`DCQGziKY(#SPy~bV|MY&n$paA`1A!WhTSY@^g3C{F4) zn&}zfJw5YqcGS>O5w1)Ug}&=$7Xa2Xamp+|=?9$!782DTJ-m1>C|+z%<&t*2smkJO zSNKV*R`uDlR&?9nmc7H7zP$u0uUU(WzV{*D$ZOOE)oziIaXf%Tf7xL4GM~$?q7Q+D zhztT&Q`kmoXE3F?`KyqBn@!-sgHy`t@{Wgs?OLE1X5k@mt9*Y>cN(q09O5b&Jam7^ zYnWBv;E!M6kIY`Y|vo zoP@H%b6^-FAXu!Gph@ZwfQ-z!2JG#t;0)(dCqFLpSmv>&_DJfBG+TZM(lJI*H(3SP zCuN9>-alGu4_geg;oGue_rFQ=7R+{4xJeJKj7KH?#bcK@MP5u@@{Zn*(_B!{g^og zt|Nh}a<_Et#DKbKB9t)(Zqm3OmkzHM993r{E^dD6_>+k+`seYfb0aR(jW1^E=>rvq zvZLVE=Jt93X3P~g!y)VwMM(hMlcYV;8@dg4@m9W=s#U&kf)Azbp%IGunwZ0>X@GX6 zJCukoJ^GMp;vzL-Llc$a@ya8wsPEh%p+w6=Iga;jnH#ryzU&twow z2u??`_Q1&juC{n$aKS660xxktI{6{C+XnSRQ(Zc$Rte?tRh3(8m<3v-IhH;6-KxhD zV6Q>J9R`L`Ny-3_si6%8-{+OGtTZk7JdQX!nOqjq1qeO8_1anYJvgv2Ij&c(9}9sR zg#pZa&}P?ycgo_1AA!JNjj0WCF_-hQem~eR?*WQEdWt>9Qbc>)#2VbzboQ3dx{le- z*1FdH0}!l>^W&yhSvYg^^DD<4!=8-awSH+=?(tX;B_Z|DBVMUr#StFi5p0(!3VQR@ znjHx?y-gO>L9QOAgC;W)+8~E3p-p(3p{jRX@yYn02z8yuEqdt3dL0*MA3M+3y_LZS z2f~sM2MeLr{p4Dwdv&_`K_?w93a6?e#}Q5Ni#=NTzNON1l(!M?lCd)w^=ZHD_rL}Z zfvCM>?6~q#-Gcn>oT($_a}JLPGWxqJnZnp}{Hf2Gx&NM}+m_JvWiE#ZC`|g*Cf~hH zXs9Cf>A;7%gZ%#ySf~FCx&8`y{-wJ0JZ7-N^VT_b6$nImH&ua!GwW_vWQ~h1Z**1f zPgO%M6B)wF;2n}bFEu|S)G=jz>7Hn#Ot=LSQiDAXdTJ0G)+AY7 zCk2|q<*1q)rCizoom4KSv5SZ+eH?_iwK(7{MT5}>`-9mCy5+ReOHw1{1+sE1cF?ZP z^iE7Ioj#P`K23WSKVNa>zQ!pQN2&sNCiDHj-x=P>(-?{hN1x7GQD_U?*)2tiAxmQ;50*9SYyZffbE`GPJ*t0 zG_|tAey6O^A`Q6|_34&xb9?*Bu`??rW&%OoLzoU2m-r{9iat)a(}%jlBiTPQYKeq# zX&99oW)+7*Ri*<-CnD7N9|y`(S!B$voxoi-Gv=hNsN~9jjVP$Xr0gmG*5QSY*UaAV zgJ^mVHw^togr@z+8ZM2P+V8c3+Mo;#5YG56b6;cn2g*p+|Gsq%qoQY^ns)_Wxfey~ zgBcr+`lBs@qcP{UiUGjJ2tM?PeA&=g3{&1k=0(ot-vdCDk(pn6`~wp7w#fdbXgCH2 zs@nn_2LU`(b-|j8+!1`RW6UHoJsVoKds8nPS(|9{?DV|9!8rADe0&-j-iTsF)0*Cf zMMD-1uIZyJtIXf%U4Ea+pu}E~s(Jf$@8b0$>2*=2^CAa<*NkBuQ~It#fl#cpknJ-= zWZp5|aUX)Hqg|)4UhPutaxmWOmu!oCMwM3Z!*o%ph_&^mi7ZW)xMzG%?<>ggh2fWv zXy`~03$N%!$YUTcH-Z+?6Litg5Rqpc&Xh>MYtQoDU zdLJ&jD+v`n0xX#vdVPwes3ho!;LJ-&VDY`J?XDQv+e%9iVR&UE044yVn*5O>2^Ty# zaax>-TgWh4Qu{Wt+4uTr-oquL;mu%2POY7rgaIn$U|xn^GWJNmA_J4V+K=;B3Iv&z zqkDmN0r~^LNlfse{o!SCZOw-kKWM>|yEK`8qL4h++C?gDQo}qyevA zmVR`nbR=sM+*)&)YoJKq!~w2amV#upYI_C(0vy6Ig2LtQbrUv+tV#O+=#DVL*kQx! zaqz4bqiWx4mbkl^NV+$Q{JFM%Sw(hYy$JHiSxikwTa*9xd>z4!R=pRALxXM>7o6H{ zw5eeIPX~}GL+k%b+kW3Nu%|Ptw^k=fl zDUX2knT+i2ZF#<(64435NokKSs_Ge}{p7c1u}$a6AfJz zq4Nz2Q&FS8Py@}C54iH}9d|Ca4G%<|4PZ`be z*7M@`QaC>pK3mQ>-`?%s@m_i$E+!PZQ^lrmI9~^* ztmlUb9VZzxa(?@B+hxvKZaIqsHwbbOvu(Nzxi(Zpa)yIRP-&iT zZkm%zCG_fv>nn0Mp8B6Ar9waFbFNrQV4h?w)$Ty8)zMHE$p=qNoaymF&A})^3_Ztm2lAS+>W0H+gYUhQa1n z+9UCV&nBQFLHd@C6YiP0Ip9T2w|q99Z`#qhyb+!+U4HQX^t|rCd@$X%FOz+-{a5;f z*m6z|PJIJV#7^}tw5(<$FVFcmb@u$D)&%6vE6I)v9nnQe$|g4)#B-eAi7rL*C8fzI z_oO|@uUpW^MtM2g6!E zRpYAztE*PVFzZS*S#=V4Ol_x|n1r8I7~SSx@bv$^y4Qk##?YfeXPRFt)Ej_p+G*#D z#aGek(_HFW?(F>Y=Z}R%vZfz9BqoJ@vl9BnZ|0X*XsD!LOqvfb$n!zP?_WnGI|6K-8jy4b)GRTn9GiF&2M%%!0m;E$ot z8}9(`52(~}e#((->bX4?090Sk@)W)#V69>%I;8JWhTjiK#Ap;1$dPuB+EP+R2n52g zFKdsea(c>C#^-I$34pxN6F%>Xrjh%v)%4wikhYb89vI zK2RnY1Lpq<3L%o_QzG#K`k)c`DgVN7=P>a6gE;D%4y$Td-80Y> zveB{dsf`Hhf5}`<*+#DPMMPYQq5j@co7{kMU~DUT!**V7ci~H>8df&spDqTO;)Y--6inXoK(ex(b3uQkQR{ulX3&LXN}eUMq2^MdW>X-6X$TaXPYgHQ@a* zo#MN4MMj8z0dMW>oh73T4CAb3yd(omyeislh`HvpS!fq?PL2JRp%zxn?9$;+8!~?P zs(D-Zx!}Izpjyb#nxi>>=I{My*UnFVN(bL}wQ@0kD!%o!remw_;cF82|Qm=S8N=%pNMJI*Eq_ zgrO$KVTl9B$5eflvFDthf7@%k5fOPw&O!K;pbLRZICU{U7T_RV7+3v7Cu7$*7=Pvd zt*4bquju+Oz#J<)y1ngDeLqprF$E_}g$W@i1hy;ivxM{G^RBHew-KW;=}H`zc9OW` zl(R9QzX^`r=3r`NaWum>>`Yk6n}hXZ{W7@-neJ07r;+@}Re}|TAnqKphTgn&>lPc^ z4Qt?)8fgdz-lo+mqk)o-JA#ijN40HH!_9wkh)8+XUG%V*nTcbL_%yEew*dErE2Ze3`u4atocF|j{Ql)KOHuR z`~F;c2SnWl*AR5kngUWkWIAOxfgq|(!$uk^MJ0cY*dVW~if-SVgtC7hd#1^(Dw@;? z!ly}p?Ak!?!Vu|4?ie&uKlwz6f_}Y!-M_B4C6_D7sZ!x+mQYeb!UwG5{^xHG|6`%j z?SI&LesFYpe%Kckg0HBG5_QGfBqNlyLs@gTrv13zT0D1BL|%9Rm2-iFQp38wCN}RT-F(01myWnpnMSN zAI`x$bHhE|CppWxE)CfWYlpE+Ac8SGG=01@XSdL*fM5wB9kicUpYNS7AB1d%pSeC6 zy{7!V78F93_}S$M54>o>-Sgl5dkRJx^C`N|a?GbpXXHR=X1K6NH(#!$xqZUP=f02P zN4_B${j!EpFs1ey`L(`dPXs=k88*5aD`OYQZuhq7vAq((jM!1vM0ewH-Az5j9r1e0-lS(7CRrV@aj|Q&cK7#tf#ZCEpH{bb0M^8Q{<$#O* zEwzg$ISwcLSEH4n@QAu+H=J^nZG@K_0YK5cNhJb|8%VUbz)#E+vc=@my5-MH0&5ty z;oVXoNTm*CF6Fnb5S@I&nP!8!>s5D0v+@p6F2?$!0bgNx*^5T}HPzvUJA{}1uJ4NE zWMt&--5cBqY{U)P*NytyqSPqZ)eHDE2z>fsZ^FYrCTl`(J)pOLl4i)N+S9|!+w;Iw z#Qytm=bz^iI?229^MCg!X*Z^tj`5^m5^cz4SKWxLL$aGt3Sw|)!$O2Lfp?_O6TxbS zyv4g^fuIh1F*X^RW|1R~{pzOQUr>=6qqN4=tHtHUqDsYq(Gz2hR|}{2R}A}O;pyr7 zcOU1H5UEVzPuLqjZp$-xA(NYvH>EMc%B;}hVK0&OfsY6LL$2bA>;}G=ogE;N43sUR zdfdo+V`^JJx6Wy~VqaMX`}HQ*JHb#8_{FHoNj1X zn!>9g_?m-U#V*b%%Se5A-Lohe9upc3nU-dP@RM1!n)l9Jzj9UY3&FR8vggvM48QFx zg36in@Jo`H&J8CNV5w}s7XTUTMI;S{7v9v|40uNGYAerIi2J3-N1kq3@D&S6f?SAH z{vFBe{~(&o6V0aPfsz6H6Yio{$6QU5+X|$&zjFl74T_l)Jnkh-uTWHFV zb*wOsl=CJ;WFHsgbqq84{p^kE$@Zsj)wqhYX_KWn3Mf0>o0FBf!@`7M6G5T3{GLtC z?M?C>pAUEc)bZ+8XOER2w{uA$2O&Eh$1dl_=PTy;rU2el%KetMuJG{i<@y=6_?{H- zl}_o^Ulch$*vag}lRt(3=5KvbAgMkLmh9m%Tj2I`S8Ob>MdX9Q(h>;m1IrW6OpkHF z9jzy@F^@OOUM-*KUKku4e2Jc}@=-Nx6wZ@BpYPIDI9}4rn^*XIM&i|DSUGt;tHC@4(Bka**igd7Yn6>(DvSp&^b;gUK_7wJ{>l8Ziq(wK_7wua6=xaN=LwNG5e^jQD9bm1BmUNVOhGV0X?ygb>4iH3hr z^oPUGZBSz-oCOvYg5K1kLv>{W*LRR3^<%%EHA*qZ(X+o9DH$F^L<(yE9QOUW>`7Zf zIdi;m5VG6F7PR_wMn*;^rVtU6GBPp(+RCtw2PC#zH~)())M>m?s=>QQ3}m=9@` zJ^#TrEq(89e0up{-&S7>Dfo6wotYkjR4cbid&w^g;Q|;v3di$>=L8i+t=U6&T;Ad6dds2c%H=qy$$8K8(6jk&OzL?$={mb;(C6-VX5RgYZ_q9AKtw^2g&8@-h*)`rq zNh(^@gI4cf#nX4}nS|}6JS;e3t_~&kP^rA(*~t8KtM@9UP-qG_25~898>bncp}aTn zoa~aV$R*Uym&8G;R9@Ah-p?ic-m-W}>~l<0w3W~`cFG1?j&_#xzuLqw^Ml!Q8~ZsQ zhj_5?(A66*C+yWR&J<3qr$go*Ny5JsmLz%}T2m~sB6pU}&nI-xPeST(1JD=tW#ywA zb+LOx@_}c6y9Ji_%>z~|75l9?XlG)oev$>(u>PV>bWD1?ZeneD zgy>}!g+6mOme4j!H#9W7KXjG8PLNx7+JxUQ%V!R8J&bc(*4`(vX4D;RS{dh-$G7Ua z9c;|KwYM-@m>_?N?)<3Zm~@sMawuFm*5=F`&pFG-Im))1B6wHrDw*H&?2;-+u78Cs zjMmgt^nEgf3hRI%j!USnJMe3S?*OoK5vsQ^Wcy1wk^Ce$kQW$m51s){3z!<%*J9=- zM(oFacNKO?XcRxnUcW?k1{(ZM?a(WpvMGH_8;;crxvdU2$Sq78FcR9Upwg&0n(z(Q zGWimXo)4N0nRfPR0T&2dnV=Vr#TwSdr32fptCIyL2r0F$qyu@4$B=&ki?RYiaAZnV zahvYb)zx|PybZ68tsK7ZfyVWronJHR6?tb5K9`f1mjOTlKa#z|$YiQ5{l}%ww((o7 zXYU*)%Lg8AOJt&Sb#);CA@5;5=qWQ;`~9j093?sg_)hIj%yDXC6KalFX%6T$aZJvE z+70f7;Vp-BJFmx4r5{%NWsMnegLWgN{Y$6!9Zd?ovbx6_Kobl0e&dJ_O>Ds%gEiK@ zfUZ6pe-DqHrD0{_$yT3Ra*5aDQ7>DN6J5yFsh$CX{7@~QzEo_tRn0Bxqv=K|sn}8f z^*#{dRp-v$TiFJG=75o{v}L_{>Y6}u;qW7kk8$*%le~xynJ11d($`~n$gIIE8i`B? zrCU;Z{mge>zr;mGJ1S7-Juc?1N1a#QS+PxtrJpN72WbBACY(WyBFE#S!Dc+!Te{@v`Z3j-9SXOi zIj$rnmO`>mW&MM8H+pKujzAjItkT$NM4h{UPiI7M$b+J_x!G@PP8IhY9&xuM#b?@o zU1!F4=K&iK?>~I;WLPVD`CFTVf2B;qYr0}}u+qC49+Ro*7poC_-W2Y4RH=7vi>k$i>NF>RB{Jpb=fUv(~` z-O60kBe1W1k-Fod$H|3;nT_(}u#wFb;f@uKjuq0m2#W00a67-S{INywR;GmPScTc+ zRPBJKDYK~xgVdARD1{^Y^EvaWpiPrh9?WE|z#Be5$<-;~iviiC6v3esi8ydX*%lnQ z6#mCk=HA;|d3m|u4wMi{0Efucy$i*naAi#8&g!5ydRj2OyxV=}r27y=4f5}WxCM#N zti_bQfV}l^md}>5CDaEIvuDm+&d1MjDTUVMakFy2h5|PAxC;5c(zyf4GV(*wFngQ6ZrcUq~bBYzG8pOE8M`y2l zqfNWr+(quqD)|z*nEZH2Ub3-=b3kk#Xz_!@a#$tvCw^f4pEP*r*La)Sg&IS2<`!;9M>KI&c1fa+T7e+AEC7E>>X~I?45<_Wz}1iHTs&X zK}bd~!%-)vwg+EIoP?^YeoE}A#E$kq!7Y0ocLg)@{$n?G!(^rJ#S#!kZj9Zah{yrB zj{@6&S2T84{dSggV~o4R$$bq;3mNGCij>Wazer4qIcf{;P+0Rk_M5g+h z)5pv9`9aM%=ZfJP12;i%`yPSyp#drv-6%A)v)oy)uw)P9IzPrz(_ZkB>vW~#1spYP zGihRfnMsuq2opRNWYX_14DZ?k(;K~XTfB1uG&9jHN8o*h7gh#z9B}1$V0=HgK}|DX zX~=$W>3sd)_12hBf}uY7y92D>x%(Pb@Pp8@OO4|uPo=aIjTe*!q&MhQDityXc8fZAdzy0^HYvg1bo8K`NmEWowU~YqBar#1f`1c+AU5 zyP{-u?Vi3|EnDn;t@R|eAR2bu%5^3g_W8glI9KD(xb&s3z3o0c?aikq`?B_PY^YOj zbG*xVrtdZTqrDr!dB%Q+?~R9C9fi&C)u*d2g9v&VN1p*ET7@U(@-czjPMt3w*Y9^* zHS+JZQM#POf-UKAOqNuuZs^1rVUzPfk5N_ARp|92eQpO9UX5fPzf$pBogF#d5sCN| zol;rWINhO*R&Nq|c~@jeHteC0Ex5-~_xP3G=+;OsNs4)$8fq#qy6hcrdY_S759|{h zuYYQ1t8C$Aea_3zxAQxW*L@=BX4^zDGQ?JbKD4iiF@QWY^c{{U#$GWW8Z8MoGjU%CjTqF|sQ4nF8|tH$xto(7Y4!OU;hS0azaG26%k zQ|Z-WMSPP5Mw5-%R^ttmexw}TWUf|FKbqZuto&Dq; zUP)|r_Ne>lplta44u{E-s_>R3+%;@c3yeT*YqPWPg6WKpVm z3RjF3ajHrXLG;;}&efp>*QcxnWO^yc!Y*4N)RT(@$_u70Rz=sARXJCAs}7S6cvJd3 z#csx_fp@h=St=kp88UEds=o5lzD)l>FIsf!a{Jl>uM#Kq9&3OB-}-8Wd4L>*% zfu8y`-E6x$)adk+?Yu5z>%q)Tp+I+Unn@x zL(u3@U@uTt)$A7>XwG&1LT88cc6av=3>0IDr=g*xp-DIne-*>QZ(FU|$_(S*>{#CAM?c&;~iyCySNl z=OTY%UBIVA0sjjwqX1WP8myqfu-dl6$cs$2yI;saUmR1X!yA+GsIT{PbZS4y7>cP( zIfFTUbJat4P%WL9b5{k+f|uBHZZs2QGB##nVj_-bFzu`YaAu83HCFhUXG>e>r}NoP zU>m8McnNfI05@!%u4tO|D@`HZ#QgsAXSlPo)2@zN*B0q6baeX42Y$rhr>j&3M*OyZ zI2K}Hqipot2fqG6@17>DpIXofFt^AmtH`Ny%dtW7y#6(5V3^B;WGID3f8inY4TI+( zRmxl1{H0WOEnl>{Ca5f_x!qr8qxEDpj@xERMqtIx*r>2iVsLxHs<_B^9X*0D%3vB_ z9UL=xs16LM85u-d1!d0v2JsnZn(yzMGsrdYp!7)+?`MND9NUxCjB@m&?Kr8KELN=@9pS-k;N#!|K{YgzY|gH39}7OM`@rOtkrD0d z?JWtTdBq-Y&7bx=MWyM{lP+c#Fawpams^^MRC^r_>9pQF_L5BU2=I}#K#(bFGBey1 z?rEDVKG+x2k?yUPLXkIPHf)GOC(18X|d+4R~i^VUT5MoBlL@!w!i_ zT=$kGFFKaD%+cnlT1Ro%lLdRl zlQ{V^+TLe6JD)<ntk*}gGgFOMIF@a3Kg@+*NpbS-*U>A z$*2{fZ!ajmOKk1=boD~tE3bK05tYuw`xXgqC_%l|z||a4tPE{lV&dxoS0x>qJ`R`? zDO0M!Y%qT)4>a`TY0iY!;eN_J8`YNaJ$P{5?Q^~vh41?Y=|}X-n!&FTlQ{|0exbgR zh5;7i3xFj8GuG7TyhsGK1a4ell1HzX4oazgzzER8-`}6OhJET1tgLB?(nw(py>yzV z|MPhlY(Jpwe#gwJcZ*+Dkz9+%(WK)+;``we=NAdT*1a!vz0w!(HPgmNsKtEYD9))d zL?-(vY1+V^*Ift|+NEC&$5<{gE#-`i(X#`~Du2WyfyEqIVpa*2gvp<^F&S)l13#yt zQyltw^c=WAq>7fLQomp!6O_r+`pG5VAvd!gGk!~MRw>Wi)WB;%+9$6l8TyjVm7PK9 z_44e}5?}Jlh^_+ONlM$$EJqY+2f{*Ymcno`}=!% z_}{qi&*%L*uXCQ~yE9T!1}?WQw zb-D)N;5rrM2cO{mCaf_Tb%qjJRp|{{+lyzcOs7G~W&`(UgoL;lsXjW86M`*i)m-kwrg^zsDSi^h|kX*yA7Aw^^aFM~A5IHNK|{B^O&3yAsm-uU_vwx}|thEHrNQ(#o6T z=tu*#^5mw_xfD#K%k(5(4ML-I@~tz7A4X5Py+pc-D1=C@kQ1lM+bpK=Cll1kXNK9U zr9NR}4-;|HjFkJ<;W$s|Z~aG78cCdmn~BTme{>%!_>`{1IS!5Y6Zv|T@GAH?P}LX3 zyuxD4%&nWQ#&AD_*!sI`IbA!4EyDX&jARxYyds?}Pq25W*8Ii)9M3idT`r%3Vmy8$`57bflv%$NBes1XX>5xSp7npCM!b4# zt-y{Ka%UkZGnT?5L_sq=13QVp{*t>>RmXo^$ky4HO}V0WZ-lKX(G^oKyg`89-~Yqf z>0Dds#p4>x#&xb&Zf@)KAACC>I@B8f^iIQ`?vAV1Ea;^1#}%6Pb8gK22!8xwE6`I(NvYq$N9%U|#F&rw-B|i{(|J%WZgZY3d82grke%_a3*V4` zSs@oIxSSkSojho9yz`@fCxswSck<}+G~`6$YJK7S!12+|Shu|PW3<18L0g|^=PZAo zY)IWazi(UBarHEwT>)Sao)NKrtSK*W#lZL!<+8Sev1&J$vP1_0@-Rd1+-50soZ*5|bHQIt%s6s`o<nj4RQ|rWQ~A7iSB*O z+>dOvnDNu8{cc$;kT2UR72@IL-C^mL{C<(L7HU9sNHXJ|eltLq*!x*}l{i|R%^ylg z;&7js*d{VJ^qIBzwNO|k^qB}NtG|4bS~pyYoI{1Oo>0^5rS~&0Ugg{!o@4WXq#s13 zuq5}TyS?KaD`zz83qL;i^#ynI_P$uX5!gvPvdd(3iQA-$BI`t7PS%{n2^=>%URE)m zCm}7lz63aTjVngO&mZut-gxkLYK)1Eo$a{Wjl$m~dzHb&A>u|-s2YC^+o!IC5Y~^- zK^S{YnCZ@~+={p=QP*y62$_J*Cy{&4swdo^7>3&REF6>fu)AF22#r}Bx4OWLUiMyf zwEE>sJb5;CllM_j(9X!+TS?o8BpizxpVj(Is2t;!Y2F8RuwkSfbB~dxD+n*S)jq{! zbYM+m6Pmc>4y4IcAg9DbsdxPA^j4MOeLDp*^;KN!ky6B^b%47NSg+gSM%DoYq4|EJ zn;>d*g|o%?Sb*RqI%m!e>j1W!#e+q5WEcdf^`3AyZ`R%W=r z{sBGT;e|axd1TxBml~lBTpChEbS7HM z%eM?&CL5-v{woN$fi!+LZD8U&x7kw_50w?sSNN{SD-hQHF!P2$dfj{iciOI#G=hb% zI5RFP-4o6*?R~g9_>5%pVAW0vc5{TWq3!QLtLej$k#_#r9%~_nq&85HhvQTyr}1=GaoOrf0;k$f zoqs9!#>v=6{lpjz4FO_MFYKq22ZwF;!6CWFO5ZKZ7Xxa5vw@c@Locx%jg-0ja|Bb; z(wS#9XHKUqobw=F*d+6}lnhhC+vii%s(e}#V}8+*3Qlk|!un9Mbf*d!H^ z_gkvdw@XwuHgJwd=gzMeG7|N4g29(rNefrQfB&jGh_|>zRx!}06Emm8FbfgB?Y?Hq zocx@gkAaj;NGL8kkrZm~xf%}>qr(}Vo`3N@-dbr6`PFvpIxgh{SEdT559dDk-Yxtk zK2Yg#u5OI+o1RV|y)%2-_uIi47pM=vFt64YL&T2qw>964pBuf284bBL-kyb068bjA z1rLj6<$Fwioq=FKdw{?nqOB%1H ztN#^FVcY9Tau2o5N~3GB9{yo82^0hq4xOM{%jo zZ~0`Gw0s!3x3asj;oP-Av8QZcP-8eeJd7)G22bx|7-@7gdUnmG*1RgW5uu$|eBG9Y zd)y9=s^c8HBaOq9Bp7^`vSn6G{4gNnI2cGS#lenO*#01j8YtWc6Odkvp^Gg!1j+^= z>IHx7dCiT*OkEPZW{q|7ygKK$#VfR!`yzTmW0qyDlLGP6!x?(1UYwD`6%}3QyGaXy zSG{X5M5QF*ZD*#L-hb;hUQ1Uw8{&%NmrGnftj<~Dt>FwwZ=I=Ru;3*sFbX~xf&m?Q zjXw3JRnq`dLj5I0p^kreLQT>fJm zu73lhWuJ;@)c-IE^zayO+Hw+Gj~}Ui_1+rPlA&M2Ka4o2XLerx!_A*<`6v=!1nX#+ zOiek7!Qt@tBh?{$X<(o}_Y=#`&C3H0Bdot1J-PVsRK24h$ldP^a_5^{T9O2%&$*Sd zOMTGHJ*+~js;VAu|8{12W>_3kAgOLw6tiy%g02Fzajn&oBD|d3&}&5o&zeoGEUjKx z`0g3^rRiA`kQCHJzsqNUjM?qW|953IXNmh2h^!Gdf9Zeb$50}EWH>0GHAN2Tktf_QA(%y_9 zCRX5sygjpt(Jp;vU|^Dtk}Bq8XSaRK+v%L$4 zt_0#=<2Rd{EPmu&oD1e%9fZ_o(hE~DpWQYUv4E(~+u8NuI=q@2#QpfXH8Cx-Q*DeAuQ0KwA;4<#kGZ_IGF zYg-V~>pQuz3S9j2SeT9buF=*0Y5!HzjGXt#P(c3O-)W=^FPAw|4gz~YK2YTolvq)l zbAZ}k$B^2YUG>kgcWF0dY!*E$pN_5c_O=Mbzx(Kh8Hjb5Yp+Eg$N#&(7HeJbz1;;_uvHAqzwQ?fEDn`yP@)r2%!0-_PTu z)8Hkfi{*MZ5EuuA#6XBw??is{vx|pIJC3j{ydu1rk}9I~&VYshV$06@SOHOTlRpB* z5suz+YjgSAG`Uga%*e|?tU+L1Z|XeP)Ox6dZo^{fz#$c=aT{vgzNM0)ac{-BYZ^m~ zDb>k;;TTtbpoVb6ADk3TZ!uOy!L%m%*KgQj2K|2H4r82J%;AAY2kYw&jk!#P4E;*V z2r=4FyAE%(6wt3Au@ju?dWEi;#Y!L~WN3f;&BtALa$;`-N0Wf#?T%f)hB;S3lwiBp z$}Z=3%zr|+ufo20jl}+G<*(c7%&L53ZXhV^?|XH4c5Kxa;_bb=v!sXxUV01TNOO>^0BZekFxGz;cV1z!>KUS$rl*Hf7;wysh^!0*=YRvWBEo~P4Y67XP6F> zk`nj%sl$nqZ`w^E1F`j-E=;m=k^^_GFhH@Y+FERUn&%fpP4^30ZBK2&nNv@KArZV3i z+P#VNnt=iD*F~GVmt?(_XlWX2suWnbC<}cjgKd~8Q%pL!+x;7q!`-4i$^Q88tRM7g zdO#lVh!7<@epLBkS{77hT7(pW+6>FCFqPX0FcqzdOmcixZ_wA zk2bGN7BgOqB$QG`h6W}pO>i`KU%&k&=6x!{Lqs}mLXo#0E^A$PgZ;76#M(J`$kCsO zMuy#opR&b|Yq7RGlR3OL1>IW`Jw zlyR!tef|W~9kT|*vshQH3e#i*Noc!o&Y?rwyn_kor<~yQ|1jqE_iaph`DbrTQ$Wl7 zXCB_a>l>4$IR%v!>mw3f{yv_1;^0!<*Thc?*2o=A^WJS1sP{B`0ENbw&=2S{2*Gua zN|K1j*~RlMBR*ysYXKdm)tLq@qTam(oY+Ocy3UPT`C56y8u*PlBgK$_6w;C`BKaaE zzK*{hO?cAtk>ZOgEO|eMwYUyV!uYwodSKFB44_j?Cr4Tl+DXFXZ%FuJTRXIw`_VI; z+KGut#6}fULsD6G&hi+N*{8*z37GKF!PFFpSY~)_gSrvjt~A*<2L}sRXCYnhM@V{~ zry{+dSy(PqHUT1sS=DeWF}}X2BIn*41bVi$DyJzi&A9KkRIg-Q;Q%AMP3vLW;OgRz zyvs`aGmV7kUa=?d-b^;kQxX#CM3bs=_jCI<`^x5Q4W$atFuGPgRw_)W_wf-05V}(v zVG8?ig^wTM?U>7^2h%tWQ`!TMQSOrLgm1}pA)y>N&`JMOOR>9vXL*3I$0zrD?(=N> zcd?My`f^N~?xTt> zGf}7)ONxI%d9^rZZiQQi76&dYe~(FWwvP6e+g)=4eevy=i$H~#aci!aD(Cmj8Tr>& z-#+d6u5B!hf~IV%OJ05}wV(WYgHCS_7DoaXF6RfC7HmXrd%OhjwcvB? zql^4YtKi_gU(#8$<^+rUp@;JX1O+(8BZ%ACZ|68O`I{xw04rJkoM#n^dl}gZeX6Hm&iIrVA9O0y>yY6?NhhM1t zcW$jrLr=MW^kqrRMm)5fWA(fKyo!p9SCNaDgIJ+ITt19-kwuDtL*W2|ZfUBUDxWb= zA1=krtSqmucvP>J24nSQ_`fkuvbuvyqo_0Q`5+t?)S@ax2QRd zE_;W;gVfnZUi6la{Se~8lV|DG^N$-Nr~HHV-5-XSr(<3UZ86XHZzHnxJ^&+qgcv?R z9=nvOO&S{7P2@*HlbZXO&tGTzOGp$AXB>SmPi#?acydEyHOK%~3M0S5)Ki6!4FDhG zct?@5pj&cvkb{*q(|+csw^O>{^K4yaE|Xk)=gbm~>s(yy`zV5suv9j$d4f||U?}YT zjj|qZw_ZETy+4ARU9f{(4v5^Z-NTpr(| zpotum^e$w3w@3PU^^MX^J5eC0zXZJ6yQ%tL>xhf^=*%wD01VT(;m2GJ8z_=|x0 z4}x?RBjr59CC;)>(Ob6wy6ed@=hiBs8}dNmBvM%E9>>(yVS9a`i7~5=UHpyfV(jdI z8VIRLf0^ys28=pIsgTY}KHEm&R#)6%z{8x8^71!Fn=^fV;EL-|Z&Hg1z|$-0RP)E} zgReNSt;#vI=`^hpsHw@%f0RFh#f>=BW8?ylHkW~|=UopK*lNl-E_=m#5Nz z`3Zd0CrqY~kW9?b%+QQVMQ97+UmMW$djMcyUBfh9Ro5>5=Gb*R{@CUEHeY}}oD&P> zw@w7)Pm|mBE#_70`~H|Fg`uX0wWncaaZB-SBv2-S5d#Sko$u zA(1ft-4jYxVSl4c1KL7 zO23_=;a>41`cormksj;PdiedaNE(QBuE{GjSc?I!8`wKKf&N$T?4pZcD|P31aik}T znv2853&~}4YZtR{Y8e85q1j@AXzt_sm1;g|sN6DxZX0qodudoP>FRTdf$qt5o|jiQ|pMTYtPiGtEM#3^<-EY`Q){-r>yz)k{*oHs43XmxAgN{4U9 zzLsbA>3+vX2xV1aJ3l*BJDBKf#Y!~Q6v|$fi|)1!e5c!#kOo)fAXht^yV8Drk4{G7 z!yn<2p-_gMpbuQ3_DWC!17c$9JN`KDEnEgK-N<&ytodxfI_AOqo7oJFOiNlnV$8O3 zV$%?*pNDJ4_{Qr6~o(^gJJ@hzg;|sBFfkVJ%5IN?|zva zXA{pR#LmjBcoipl-6wrp>&X?#5)pV!IpDj@-M#=B~pLaN+*pAfYz|A4TkYPeo?5 zrl)dHGc!cAr@1y&G*um^kg#Q>>hZlbHk|To`Q_#dh&rQnn}2o&WJHkU|02YO%j;gx zGr1J-pph?qfgRV2m|W3`JGP*XpNK#)Mok!*UGk2dE7ECpwxPAUyveP-Swn-DYeiGJ z&J|-}Py*T|#ZXeX2oc|B(~k$t)YOU1q0sd5c;2!C9?`dvsl7d80sT@qAL-nB$#=IX zC}6vL%bqRf*BmGM>hX?39yedY4%=jeQG-b{M!uO@-~|&sr-<5Zhm-)hBcsp=tH~*G z!>oCp9?aAaS3FTb(kPo`qNJW>w*L~#8ELP)L3*`z_hNj> z?qDY%#*mk?$)c4nKN!Se#d!mv>sjQ7z`v{1P{kE4o8RzhGR}m2sS0+~{O#B;^ zBH(FGFA32WOmS#_+hwhHHnKS#uX(-;xOiBr;rmvjA+15DMO{BT&zG!TT>Wu8?y^1e zv|AQ0hcW)k>MFOgt~uBa5=kEO7h{35rf?rXSUQg76aDYE+iO2-nXK>^?W(MPRQ@X1 zA@gqIzRtn2Xjjm^@|<7%8S^|H)CTHpRWEYXT#6sKFpGaTgOM0N`6w&;{eiIJ517RF zn_tkjE1yM-n+jZ8T*jvjgk6U3n{|w}VGsYQTRdpeiraAVJH9i7G8K=PiQpfFP^NIK zfUS#`F?Zy9VhCGg_hb4#h0vp770Sin7%YDbl$|0HMEh0M*^3~^R8E7ipN}GJ|Gud9#@e69rME66)hVs^)bMnfE0n&}&b9+{_rRvN!LtUIvF zTwoe!Z(^u5>4~ZryR86TypAT>6eIwHhR;YJ0J&VY?KRFKSU5*GF!c2&w|mRW#p;)) zt@+dT*MefQ^`1aHG1ep9oec(|M}h!oYsdV|%*8ghDMHk<%fRDdfQONsL_L)x&)XJ&r7kY5g*HhuXjhXR%J%iAK(C|U!O3o4pK|VZ zf9__qik^c*sR5CzIOEMznnajfA1_QANn3 z81F&ZMjFTXYg^5*NWbgcS>}FNTr1i%nuM80&uvK=zIyGO7=uIj*kJ>j0P;;Tso;HR z{LR<%XydJRA|;nCV3&C%4jGVQw4E*4IBt!2{3y`|vKr6eGCU$(hok|IVDs|c-UyH< zx;z+M-gWfxVawqoiEp7Xr;KB|(dLO8??<2xPPP%vok3Sj3n4p46p44+r)1xY03d#Y z>-A21YboP(sG>g+n;+|4cCtXzCpwE^kg%xY_Z$%Gfg*)ZlAbRcEZuO(STP*8I^BnZ znCBVPZ}+SwgX^V^r{gqt9$l_H3O+nun7O(;YXsz{kkf33g9%HIGAsM6U(K>f9|_<# z#%e;uNVsDEk6Sqz3+6M2{-@^=%jdm+_lP=9OxpY@%DMHeVth(AO=qjVL^<6@|9tB5 z$-+*Zxb!i{3%g8@8`hzw5Uq~{KY|q%1tlEdjJO72E!XTJT4f>a1#i3z+gV%|Q zSa6|3;Vic^kc{=@X$MjjrRXW6K3G4}SqPvGrI)OSrFg9J6VJX{q5^D#_~$VzpDyL0 zDWEq}8PE?jp$y8pp{B&Jf3Bff-{Pa<8(nb-7mRqaO}|I_TG`?c(_tx!#^u0Q_at}a zd&aLrsKXbr#Dd{bm89%1T#b_t+Z}?j zHgY+xO`z^InT?Q)Yeh^HW$0blc%2Ts>UHwk(XJLo=!TWulatk7QeHv+Ao`qJ52Xho zGfm!^!Tr`skbZ&2cllg3YUk0lA>1$@#ii)U!LUlz4+c5a=x7K}lpk)S`PMyBdlOJ6 z7laS&>ZiA=LO(8-iCqpVK(xbhW8&TF`3?98-cMPyhKc~dBlor$C}pe= zKhcj#C3YoUPGGwyk1mAc)ru9A?I83_F0mG$5|(m(rRO-+LxDrgImc94w+3@_^bY9S z=?||TYiF=!<6#My8h(CH&6n6tAF3vVQXtT=?);94{dkeOCw@yccWw94Sx>s~28(%gGLBogyj+^encFq_{pjh%W9dz@i9@&f zmySR5W8>ZPTAtd_W-I*h3Y$yf`BDObQL_8#%%+qEZ6m1}aM@^A@im(kItwWg9Jj>v^Dzyek<3R!VJUgPFL zMX%(XU&%eJ*ZDh~f41iM<@5(#l3M=#S!ml@K(wp6)>=h2)BSkr%t#`KFcV0Bw~z?4 zEK&4)==ADMzbAH~{3%>@^0eIqCh|I~15OJ~XqOwNXQpih1hz&|OLM*R8#4FgOdEB} zgz@Wh+RKAxF2{f8<6^-0fdXkR5 zZCeftik4qeG}Rn^~Bf(alG1rc6~NA-zFKmr+qIH1j6c@T;t|Ypsq>1 z=;vg=jwL(VSe$HNlGwijyd#o{%aV-bXSt#-2$+o!y*6@^a}e^;Sqwt<38EnF z)Rn58`Z~aU41XBV5!^g!pUdEqQ!(Lq*(Aeu{D$Sd^RJk&_nnpl@e@!y7 zRiSEM?Ct?6@bYO*ChwCC@jK^&v>Lcv2L$+vG5YRVW_pucEZM;`MEGLMoi(#p{pUHB z(W$=4_6SMsz4m7kfE#KK)p<%&tS9mgct&$d5|$(3{{gM4{~Wf)*YfDu8^D9lojOcq zLyisxS5$FR8f1C*-aVW(na2CDb1^I*SO@sI3o#~2cgV5Zej@N?@x>a8a;E#ViK9 zlXVia6{L&AvKOZVNr7FF{TH3GOf$v}I4VtOJc`)M+P&sm77M?t7ZedgfRC@$8F%P_ zk#>2fX>lKqP0EL#ZUlb0-+_)HOw+u{eLB;z0pfs{>oN-fbiLhvxwSOj@m1ovE~&C+ z_dDHZRc?7f0s9AOKB8$&DJTyed46KHBg>y#`a00Oxx_qJYOg$GK-XOfRmtIM{w$~D zg{Hx$W_4!YJ-9Yi39)UiC0cQ7%O~{T1pS@MGc)&lM|HbbUp61D$cD(Co!&q4uDQS$ zcaW`}Pbda0F?8NDJDNDk-;Wf4^|FQ$xqm8?dOMpo{@|fmo7uyhoVjI%SAx`{alcK! zzHPoOey#q&Eb=Mt>l)Q~noI7~EoNa=G6vGsNIQZ%&)xNpyl<=yQ2Vj#!1V6tFPN~- z9NwZ=MSb%5>E{V$3FT+NRdwGUE+7pV&= z$oFeZC=ZP#-ilh`a|98ml8!tYF#E_j?%ilmR_bZ9j`?BYXlfh(7?rMvYAN8WXk{m4 zQ_922f4v_Ikim;w#G0xGQ!&uRQqr_Q-_dj`bq*&=pOZlqKPZXIUC~P}?ep~a z5_JK~AY9rcus8r72UW2y&2`>^w5e8Ca6+oHhor3x);wD@m;GwZNkX}>6V%{i3(W83 z<=WcXNr_2v7n`5FwsRKVn3;Kb2Fx;%SJ%`Gm5U(FEiKf!l9F_^wG$Z%M71G)E;+5v zL!Qm^G|IA!3HqF%{cvo{2Q*}K@IR^Y610Sa_@D$zJ27+EB)d%OGc-OszGl&ZOEqSP- zstYafV^8KIfGO+ZePoLDX@>dZ1YQZqw)EIlHjblT%OEV9!Kf*dU*e2uGB8j{0RdS4 z;krtntSlptChc0!b*XB`R5d2D{TH>W*G6kC7yY8uh?TGkS(%>;)Ma*Y{oATOSv0u; z9YpNg*MdetbPG@7+lZy{U0uxI8BZUN;GX2fTS?N0YGG5gah%Tz&k-8hlcD!q&Gu0gtL5}^fOX@o{TC5w*M%f{-v_xQ`drME3_6+yzf9qK#U z+fA!!bA^k4dNu;@$MtdCVRY~FOoyHiJE*@+waDZ~*Os>6qj^8B@ZPJ&}XBzuxEX^<{7at@Xg$)`do*NwDrZmq{A5KO#hxfOQHY;-3LUgv8mo$kLb^buv zinbvixt_^P($9(Ym6(qnx>XN<;9YMu54DWfXJ`wT>1}YRazKXHX13ceQYLqs;j0`& z*AB_FX)Jk_L!W*i3}-*-FRda8`35+V+JI~KWFaqQI5s85x@U;PjH$Xj)R z_vhm+I|CZWQq`JAU%5HC*>~jl&C)n$968^`yopg`7wU!)?1VxCZw2Gol$_YyCs~EC z15$Ut9TG^timw_PqUXpUd^`Kc&;@Hgz|T{hyjxz58WjYvZr&<0)QL~CH;Vc+B4Ti^ z%{Nu-o_nsSyR~a~tu5>C{a~G|Yx3bFjwU zja|`I&S0UmJnsHl=z|)PgR69e)y)gsimdYW4Iq! ziIqWUiew3CMdiRKUFbpF!eLEJ(6M!B8g6qqhsh4OvB|;TNkBGrg(| zOOI!znD5SaTv@*s8d0^FQ5SxPh=s=yucB<6%V!_f|JTuu1+s60h2_#VW1PzjKed&* zQG{zxi}7_-3Fc*Gqx;ar%3{QAZ!!ALLy&h% z3wd~f#Ls*l75*lRdb!Z`>Q3x`H{@U6WJ5N*&*$I+S=c#1PRSG9ZOoc?oCDETvSi{> zw%1=S2)5UBtgbhozeN%6Luk7LShqTy53BhN+YS>JEC!c9>SM%DJKXvr zGpE=KZIV^80aTXBv^2@Y!N5dgBe0Qu5X*jY-xPQH#sOg;enWt^0xSc7ALo6uPuq;C z%d+ImcI?cigBSydWJ|sSTg>uSU%X|Am^oe?W6{&1RzTnGNDK&fe#Z!3xwDhWz7d-M z_W>9H5#_;*Q}2Z_Dq&Rk(CD={a=7C_0|Pg445xZ@uWq(o&QytOj$4fcO9DD4L%3ub zH)}Yp#Z_!xWr*OvlLXvM{U({>T4qyP1|ZWJU_|53t&>{xf)UG%1>|*LF#N#z?l@Qu zpw%zotTGC{nR;aRvNi6qFe4CmuJ-^M+#%_OjAN;W8a~B?bq77s*9Z15J>Eu4C7kXih5S1he5Qm?sngDLxMS-&^>hA|AJu)fzrR1{6Gu+a zzTY%80{$e`SygC-FFdjB`)E@0>0<^tud z_x5myreq!<7v_W2SB`~`VE2b}0G*5!$Xy5-b!H>)5h>j2ogOJ7Soo8&m^V&aN~@KV zu1v38Eqw?etb6i{ZvBz4mtVKmV0_eyWO(~xN-T5AHPb|)N)wj|QQ`atH6TA+EzpF~ zGBAjFDYl)TmusquHc|b4jY8=G%l143fW}B=Rkiv8gQQH9atIiodl0zwEh-0N;l?U5_n0mNmazu-|}w zqmLpOObk7**#B9x^B`CjL}lGazSsC&cHKGKYd^bvW)O14G&>zYwd84amL-TM@9L_{ z3Rmz|8xE?zdK2?hH~uw}ZKn7nSk7k8YZStLc49+)bkpFVkGyXrq^ewE0` zJY1QtG=wW3PiT~@oKs{36m$h$S$X=i^9KPDp$g&zlnvuy>Jw7;mB#vKb#Ra`MoPa+ zrIMlX;;2Agt}Mcs@FQOu<>p}-nkmHk-`wLGv5r(Y-u|C>bS(_?z}H zByqxnq?q_!4BsvCuQH$#WHV|==r`3hE@IdC#<#-TvINOqG}}K@BvA9T558UUHCMPQ z(JE8YP0*Ve0fRq`66E619s)(_Ju>Q(uLbwQoD#;Xj!+&*$YW*Q`He`0>5o+E^I2`* z0;5AsvOU6wao~ciYXH#3Mw`T-9jeqnPp5QpCQzE;f&ws2d#H2t7-M`Lk zM=rkVy6`C~=zG)i9uhh3-c64+|LHB$_Ce-JZiS)QtDu@ke~!=e)Qi*g^jusI@``)G zLI|Ye7~FUxV{Ldrlt!9ChdT`n&NT%^)!8NE7}w{G2D;?m6N-TwjIP3d@`b$GB&Sve znzkDR_wz3Sq9x=i2z%iq=0HB=Nyk;2N(MQ4ScIf$vuQN0n#OH8*j81Szi7#=F|5Gl zRFs!P)HE{euPc^#V+Qvp>%rSQjZ+(3g-StWClE~U_}APk9@*>2>=~QKdEz->q%f{A ztUuM%@b~e-UPhc1jzfX5#gc!0cOR?8sm0KYq1sU$tgg z;B%L-Xz^hrtCCamCx~dnj!>59?<_|WVH#d8Y-Jg)!x!IyHf35Fd?GM7>C@KP^1&Yu z5*t+g&Hx-${Kx$V=&^>K?L0RILrQxk&QvV)`9h0UdCh^f@vsdA0Y za3xht76jRD+;Xzn@UJ09$PPfw$?dpA=BPRz-z%lKb+uFW8AYG_?mW1!ZBzIp+w?3;LhC{ zgpdH@f*|7KwO^Ol&g}O$rn&G}VLjdj{o~V0V*8ltK_~r7c+avYz(zzp%GKUmi_G#!OnQQt!WmpA& z<1PNML+f@5wE+AP3<&3x?@~x#5ec$f^N~lGXH)i3&xni(x|}w@2|w7^v&~LSq`;RBIp(>R}#GfS4yD107im_OC#_5$7w2rsw>eC3WQr1|j6)pyny z$si(7q=cl~Z#kArw6!yyYNTOLEL79z0q4*YT=cWoB_{B%HQQ1pgXn0<9ps#9jD2KT416ZQGn7 z?#TMTGpYwgCBsczqI)U*;tTu&+^s9yIzMD7dk1;#Pv!%&RGb%svVxM9t);m+*jR(# zbgl2Ur#@e6YhKXFQgq0_(vUrXrbJ=AFO z{+H()HgXuZ=HayodJBn++E!;q>yPPmDA(q;HeWozsq&Ac$AeZt>u%*#2a~+}8NkQw z!3)=|z{FL=0awaQC9ah@;VlI)E$Se3i=YJbaslTIoMf(?A@{e=?%efuQYE%)>|{+8%EW@b)Ka#XlACLEx~&}=q`atVezdAYfBEnZg%5`Z?Lb890uhc8ENr_I; z&f}_aMDsn0PSN(Wxm}lq{P`f#wC$H2CY6Q>&Z+N*FS;Q#-zuSb5GXv1yPH*-45BnJ z=Jh4~IlnUJ1oU4m{+`}CX}2Dpd3ioR^b3-Zf*?PMI7aRV!%0i&F4x)L-?0R9XMJ14 z`;?0dE{@9;M^o5yOr4-P7XP=vs@9Br{QhM(_9)7tx%%3hjc1?od_#V?{$TSfJ^M@t zdpl!))&HdfE)jr_pF}!ChEq5t&3;Tz=T{5J2{=;3tbI_Pw+$Ma+HF_u%VM&3(RSeR}j)FrvM!+jJ-US^ja9eL;f?$#Z-2l9NrYF)G9f zJML1Bt{5>vqnGg9Bp8fqJ5?#bJOW zRH-F{=vHB#J{p!}@0Q#19KQKok~;nd=&nFBDAD8+v9fBEB|Fv6J#?iG7hCP2o-#;i zW^iF20%h`^iO@(YDWb*j(WP0U{&ASWe~^s?E)Q-@5=rZeh&D41%udoHF)E;`-J zls0|Z(ErvvcMkyiO3<=FE3IfZ;NjKjXm9{{X6)?joc!?{!>ekTI4Tatq*E~Up! z;Fhp3QnIUZ&K6(w6~~P9-wk^0;lWn?5(6C0tBCEv!RskkyH;0zjg}N77l45EAGK-q zmkFM~k1uaD3o|ExTP<92_mtF1J8NMS^M>UD$qQPC)%!k-7-W9p<|T zq{rXfG=-p}on2CV2q=$${qlp$!Qq+{4ds7^`9H9f0y=4>X7$2VvV5 zmU0234IF6RGAPfem+NL<-M zHP?e}f-`PesqBw+KuoB;iK_0;jiZ2z$EARg)H)ZOBn;9VO>J`^>f}@ZAhy8O45Be< z2XIQ-+=b)GUY5-xFB(k+=#+K;7*a&{?z+?OaLl*x#1i3DAd+)?b(`4YG0LKJb>^Fhb#@Crh44zix&o7^8elRsjVUy%H!;;Bw@LD5VGs6d&iY1zy&~QO87*y zS2h0=+m|$bB6Bd|&$0cXWiu+!Q$U}OP-;&=Nf~0P68X(`(;^mgMIAt) z^h2r+9o_hF>)rb?{}&Bw@n;y$=VQ~giS7MQ#WpD8Bapf{lbh$K?O#oQ(jVH1XF4a9 z#drv3ACUICmF8gmStK9!Zgw8GE4*hrp=ws9{4}+N2<;x)*~9sLScKknU_Kht`z5MQ z3Hm4@8G5n8iJ`>b8Mt)<=ULd5KI1^rF!@W2?QK;J_1pcrpS_{NmM%mT>km47PbMfK z-GQZz=vh{U&X;Y{Pq^Qi_4rYYHYO9$j^!1DPI~VYzw+N9lKm_jW97iJg z7;pWTX}HU~@varDzA#TF8k_-{%KS%`vdK?x69cY-tEIc=Jt0>MSNUE0+cKc*3-sp* z2vUB+;EJ4QH&$cZ+AOHQE`4#-^aAbUUS6_{Hw%rqJSx*Q0QkTiRSZhZV*bOX2IIC~ zaXXuCHfaoP*a2qbPyw+5m%-dmle~_@gy{+XncIC+hsu6Cb-yT|rj`JRZF%|3%XI|q zxJ`q%*aoRw;f?u&9kqhLIq+*SzMG#b`}OMI%#2AMR?xEjq@wHJFr6R@(}WmtL}+7= zgYjoq=lNHEP;+M*8pU=s)5l7#leBFXCR4*xFItS}et>g~S0S9`g z-!AZxiuh^AgMedXs&giA!R~FYt}1>0jM<|2Z;P1Lj8wO1X|snKv{wMg~iES0 z!<6o49KuSS)0H&YJy~Bne=mC=v0u@*RzDM0DlvK&ziw1*{H)Oxz3=HU^)l1$#rn+; zt(G-!8dWM`8s=6n9R+8%Gy?iNh*afR6(}LQhJWc`VMI`Lp|^y-ODZ7Fho}E(ocudtI{hp5Z%Wq6<;pMj-9lZ^l5~g> z-9_U~0=XKmuZ^QwyEQ(29a#|Q7kvLGhkbFitG!)%0&bgCNfQ;4pc|HHF5}G&7Sp(# zk*WQ|{d|GD7iP`pzg}6%`*R)Y&D@-3vZ|7&`_cHvbp6489?>W6R|59kgs_qeQ?v3{1Q=z;?>@Z~-Cf7;JwL5gKXV&XH)cww zT;>hhne#wDtj<%T!)l&Xu{8yl{Qo#Q?|7=eKaO8qTvD!4RAh5WaglY+Yj!hlA!KCB z-YYB0wX*lh4x#Klva>>nn@hGXuD!?a^ZohHKNk<5b3W(1->>)cnOOwHAuH~#1$~(S z>T%K|5>P4Mg9d&+2m4rga$=xQRxoEgs_%ET=<{tZ-pl37m+Fzm(l1as)v=oBsbSY| z;sX>%{FLp!Q|zk1aI)Zbtc>e)OPd&w*&wZ1O->xBhVN#+>kE>3kR`GQ4NCENJT z2mn5iI`@bFP9*9Mx3yx(Px0j7#$7U{h(z?$ z^r*h27HsrHDC4tncR?m6FH$y7-&W4ye@)>DK$(Jtg;|sPc`j!tu|ju`+11rKfuWh1 z$ilYiCI9OFDWF@(aB7jbcQXm?FadzC53QurkKYLaHT|i(mbrB(E@%_YzLhn*pcbmTomoA_ZZ;``otyFv z1A=GxrWr@%2A8Nq^-RTkz&>0L4DBYM3iY`|<$5LP=Dyr7`OJ&Aj>%4LHhQiH1#QeuQE|$IC zRUrVx4eCJ8-Q}gS;vAXlgAksaw(I4k9EY618vmm)&!f$=8S5?2^4JFI5F@ApWpK#P zF&OOK?hb<38Qe=O@Lu8Ph{VAi)8}G1DGk@B z4-+=^j^CDFwko^5J;Vj9Joi832o%oW*$xbz`|!8DH(;hO!0nvtcdUP<-^RVri;gXm z_TDr|_P?$9ev*?*{Ua^;gXJf`BRagN(+|JvlKKh+H5@ljzJ)jMU^VH^?+V|yW)i2) zZgErmn0X^{U_qJ(N>wQL_1ESrXJ2t4i2Ds9QJ+W+Ma`UcVaiVFKO_P~BxL-GiX`kJ z?jOIZQD_b`(q;N-)=u4{P?8JFJtq3F9sYJ*B6K~7fsCQn$o9&6tnK)~NV4>OmMd*w(`)AQwR>`xy=*_5)iJk!#+u86|#u9&ns* z^wMDyE12sh-_wQId+ojQ3R2;yqTDuTUs+kg~+D3lK;05m-Rvz^roB?j`{3!y=3@5!Sc4@-icEAGBnGN?pgjMX;+3G3^ zuM61)APE2tnu3ixf5019k92n<{kNY_xa???rt3VO|>z=%8Hx= z%4F=^V9>$2|48>~k7Yd;pyugkKjWf_b?H?Q!Q5c4dsX3KN8UwaUNcuCR-FOJQ((LV zS@8@Fm8tJ$-vH6i22ajgw9e$4T1i=1>r57=2ky;A<=8pLvf97z>J2Kz40|OQ7SDj$ zwg&pBZ}=H??7x8aKzH{<&H<}xqEO??X_i|6TsYkqFv{s)E$*3#-(yxQruxPg@w(DW zFkP+BocQ;h=F)PK(4Bm0nV;nW=lADXHT6}QWd`69*{>u2os27R6b z!y2-nLqOJNy@OkY-2-vwJh7BZU1f?yvNV5FdX<>j_?8u_mZ zwG^r&J9~$oV+C0OrVtact1`yEl3ej!E-{peQKdwjaw?u<;OXuUpPS1%W=p$&0bKi1 z^L3Tm-YvzjkA2CxD#Xq~clzPrItF74xy{MEE0e!!e~$1bj_q#TZMds!1YPB;9Gk$& zQR>UZu&5s=+K&%NQNldV15qjN0G!SPi1+9|%3_f2u*(#s{G47xQ+H0Kk1SlT9!*@U- zzq9?0k7zJQ)F`=3IHBZMxe}-oyp~!0b=Gs_l(nA}6qH@^eW7LV;iCt`|Jnn*T_#S_ zxr*mcrl_w5WPP>{$>#z_iJV84#IrTHyE?TXz*tF($GIW6LoPI?|A;t4<|`h;M*OA| z;goe*DoleK00l|mQ1AXvkn2x{8`pDpECOw!`V3~D7%G+gxP^BewdDZ^JGuLgBKM;D z@;N`o!a?1W@{AzR^}$m``4<3gXU=h?(IP4~mwx;u5HtM@5Drno zJ|f}6BFFvLqY-MWeT`51l{68cagM~-Pw>0o9{%k%GS33pyN^;-7{tt<@%3P#H#U4j+x)Ot~w;e+Ox~o zZal9iqN9OCAbW@69szQ)NY!vh0hI&Xn>Bx?zKla%L7JAlY5+W7^GXM(f|sNd_aB}! z?|tl`=wuWsWG|0i7D8*6MMLAIMARp?JPA1eEyMY@h)<*Z`pHybAyT7>^s`gy z&&ipB4}aC&(f*P=IO%)dd*8`BugLbxli+o;R{fa1CCB2v#$U6A`gK?xOKm-!>Q|5P zMV?bfXRQMkRG{X$5u3}C-6f#U{`Jr3-XDqSx^fR)l)jFok(iQxh1h*!P^h>DDFYH1 z1Y>ot5xoqkoW_%yS|qQv2Fx>(P!*GtPx;N&Wf_YNx=z%o>mOBb7t90P;-HtJI+MT3 z#{kxogvr}A1fj@fZ=jEbp_zSn9ARypFwl)y%bdI2<5*oiMdVHJubh{VmR6r=0AMYp zA>w|xfqYmpT6Kh!Aua+6{0D&XaWZJqi+6By2Mi2stEIS%T##v`R>u;9z{-20Puyi$ zej+8_Pxc~GxWf-|lFz8#qoa0{YD0f%n6HA!|?v2Mx(6RGf_OzTzU7Se_N~ zA(Mkn6~d{tin5~N{mUi!z~PPR+3|?+buoG6HN)GT4=K#UKjG}oRFC3UK&n(hBwNxM zDOcTq5u);2Wx%qN)%8qPxK_j0>$?kukg>UhR@ zxq)Msci6@;LY9!3vEutqOQJ~Kx4uSK2fHg(h3~?*$Hv5Pmq(Xk1eUBnPsb~?fRP0N zn`0>fq9P;VUD>+nODV#Dk$>((NFcp&rlL4vKq(?@;=+xAU`Pe}Bv_QMhkb=J1R_f* z;;=LJMOe|N@g239g}lLH2C_aE1^hQkknAB<{D2*#8ezRO28+n=_zWu)Q3f#BB00hR zk}BB+=qUJ3u+vYUwHi+%R9KV}>iwB|uQ(0(ck6CNt+H6Tn5ZV8OX)^~g7?Gze%^u-7?ddRmoQ2Oa?T~|m2?~(cUmaVqQH~;wY*EWJsGI`;&k&nrkfgGvtg zEX=TlP)R!fU`3^#(e%^K;$k59KbWx8#V(eQFK0>nTzZdT{d6Kl-`FkG#oY-Qo`+!I zKt*8_fRqD`zBtq)hQSSc?ojsc`AZX%Z~Wa_(X(G1bw{FgbeNf0n34xGdbMHOY-?}ySH z*P{nkBP}s5ZK+;HF(6N-xCV5Su9ZyAZ4cf=rZ26=^MJpECoFOWL1^)J^O*6PbN%)u zUO{xs#$mcHW4QO0hFzAWvR&=V5yD(^8K9Q0_s7y|Ytv6`)bN+_4+`Z6ci3cgD5gIg zpM-P+7Rfq8^C5RhAZjvNRZy<3*3GHVV( zPj5}~Wbn*;=&{UXXl@N#2VACl3N$v;Fa2mJcQt%szj#F1^n?oGPSV#;@l=s}l!=If zG~a@a5guXTuTEsvP#*Bdl?b`4Y9iFSDou{1Q?Y_VgU$1NdHl&ibVV{|LXoI>WFj)% z|M&xqwvfCjCLD=kPmpLm0C3rX5;-M{%get$Zqgc8u8-R`ZXl zXRqnUttry;+Bg&>!p5<1?Pal0K@b~s<;wAVFD2r5g!5=(*#R+_vtfVmNl!kt!>1Y(q|<n5FD~8c=lb^5^on83 z11aAVXGuHEg|GkV@Gl52pSO0R~Rsp9}QRD__aMVPq8se=NIRTVGI3SJBv_eO!%V`-?_3C zN~AWV=%*Fn*USZS8FZ$Fe^7-B!I5w2SneUQ9!Arodq(ro`AJ9%ebJ9gHV$(lmik5R z2&fQ9shhr~*{HH+eBS#S4_MMXcy9}F#1Xtk19x}B<}VY9S^U?e<_4(0mPYHR4Nf>j$O2>7?Zkf|{p$d}LFXASs zU7ogN%>~aIr$H}7qPReVeCDXIH2m*kA|>Z~=WtDSR{FZF;k4wBbkb$xy~-YEk}k4y z-H#zmDz@b{8swF{rHprf6GoB&${o^&aQ$aI16?Vh_r6lsx74Z=%R#{1 z7i2Li9~v}g8%XJBFycaes=+W?74Ae-MigVJwrURy0xh6L~mLd%)bg#T1A$X(id2=Nx4ISOq z^{OFf+{oMXvtwXKf1VQd_a-mx;}Iw0_O?F`hIi05T#07gV+LR~#~`>OV%CMJD9cuLA+Q<=`Q=C|ITuHc{ZmKV^vn&>f?$IlTIu&({-Fks!!ssisit~QOoN%@LDMPFYu!AdAcV=ZCk zZG`IO?+rDYo@wjKnlXbiiwy1Q+Qc_Cbz24m1x|KKm^0(K3zPg#NZ4`PW%K;wvZ{*v z2KX? z@xnFpj{>vs8BNCJ(?I>8M#K6p<=QkXQrZ+r9XVyjVtx=I`hZ+ zj+p+&U1uL>Z|_jnu-7juf#1oO@dJGiFDM#5yB_*C^BB8TL^vC=@G*t}hrV>Rdr9B7 zFlG=6E|AG0ZNo)#wqRP&b#9y9h&diTj%e0iIa7|anTx~{z*>* zMydHiE$D4aS1gcm5fdBTS5Jb%P3Bim0RP;?i8|q+{VMDtDd2nH$;plMJMBVki;AaZ z0+;wVZWo0i&#i8E1iUwe`W^SRdg&Mp#u1Ya;#@b`>=(U-w=0a=n`HdzT77T#&Z+(W zUTL`=M~qxx%sZxM2d{QO^%Y}Vreh?7Lpu6{;*P1UIH5FLT#YPdZ-%&JeTur#U=XJ& z?``El5eh*Ctb{|sz!TJ8jviHdMhs~X>z^Bv6faqKvfX=#-~V>IJ>k&>%8pMV2E8kW zl8~}6f>M`ovn;{y%_U-OLz?a__f>kz`gqp4;)bkxzGM&mW1mLe%hD{ha`j$2>C9J| zIAwph_hvj%T{>+fvgId=+jc!g#!l_}*$XYjI7%2OcDyy@7*NgAJNuQG?~VQ0>SeiD z$k(fUTqPxDiNhMNk)__I%vVpd)KBIreog-=N#^B9G<>*#Z;vWffojZe?Gd{b5CF!+ z!N55~;m=n|g*jQ&f|mV!{n`ryO$mcf=@l?>820nj^`vuQexjtG2B=5x<^K9JW|1d? z#U-8m71`XA9qKYBhocX1!W54Rb=g7>eStE&!u*ZgAX6saBNqeuO@#?H4FXQbN5*Jq zU(yR+=MTJs0h{4ZY9lN~_lo<2UT1$7-lR-{J2X83wDdJIhY5aJTbM2 z3BHTUdOE|MuDtJ=$nY)GD1fvj#5@pV-fldv8XkC#n7_($@?Qc7GCsQ(mi2h>v-0W+ zJTE%g5&#?8MT-D2XZ+-kkLJQ9YTV(Oy6(Qm3(F&DRi+PYwDxuWRA&AY^M5v@9)H=_ z)0;+@7Tf}LkIfEyMzU7reNHcemCjYDpG0A{#J@~uFq#Y7q6hguq|$yfkJ8V!)PG>6 z+TdJ+V>C)Ggp<+g>y=tbN=vuydtKq?4f*e|1f2ZU3_Jr!#IuYE{#$kg#Z}p}1ldD+ zg0!ziXDGs(_U$CFVg7T6jM4_eiDwi?EG7Ayzy1R?FYJt~CRi=gLiEFah; z;<-3(a#_X!PPPZk%$7c)x0W31qv1^a$=t#i@hp+*nHPK|p$Aiif|HCK+<{L@;z^nE zv{1Bh%#XCyDv~$y-q%DGRYGgW^|QCC@s5#qu0)wdN($I}V5v2%`FB}M#(BSe;fz--=6ua3SMY#)gpm978PGd_DresxC9Gs+w4 zF25;2YB~@_A4d@vTCi@2opToxa2$~_%n7XXxpWEK)%H6Y+dkB6o|a9)GPv$nF;?Jz zTaHlRz1>B~se8Flut4w>r4875ENFKpa9}d5#i4k?_Us*}OERTtms+ zQS>VmMhzeZIXF;-AVmxmqJ?>}gUvASGQN14IJBVkNtJ;TPF{4$%o``jtCki_@*JWV z2LdtPjnxK4Nb4oSgLXoV7WDM6k%v<>);iixbo4Ej9h`9p*(0MUh`ok>6(B$@?(zSAku*R6d2TbO`-IsV+(_I(h_+TcDo5xtx3>sqF% zDO~1l9`n9LoIg}e-vok0g+qeYL#W|TJzyUg{Xap&VKe(r3-5+f!;3)fK~Lv?>14eM zil`Fgo-nX0%yi4IrO!*Q;xA(#oD*ly^KfjP`C~7JewwyXXD3kkxSTmS?QTTN=Q0CI zi+4u#0MKeqP!NfU3(}_0l!xi)z8~ic70ekW%m)H5!o^2EEMWnPi6g#*chxeM^?*$h zG24cpt+Naol{xQO%L&A7`?5v_XSpH!q3=8%hyL82W$bbn`sTP9=J>VCv7QZ6J#*06 zMXoN~*rsnZ_a|zqLN}wVEMvNI)U(->sSjUvpT%r^R2=W+AZC!UX30+cl8!l2b zRr6LI-Z1f{CJ?bOm`tK~l`&zB1n^oJWja*ayhij&Iy${JR{iR_$txB@(&8_LzE+R; zR2De?YwEA25B@-$5cuMaTT9x`^Wev!{X+v(h>{0rYr#Xr5m$!*86_`nIkHFxN;4ls zK^C+O>03tDj1ZYt%`t5*Ts}z9$Dg%ffuOG*1O4aHjJ#4URS=b0h!+hc723%EqpG6Z zO$-mTnA#*|1J6#^Ds!Z{5HMCO0c=Rb>1dZ6FVFfg+{aOHI6jf7N$yWxsEErpn>2}n zE7q*A5ZW*2cQwOcAT7rmZ+o-Y@8u_YVhECzvYU#`?#)OzVV5Ps3xt)|Q&=M3Y6MacIe<*O7L~>o$%kVZ#K$;eDkUXmb(*ByV z9LxWX^sntJkLgiShMaQaEBnK}Vr+FzEkh1f3d_W*uz~FE^yt#R+6}QL?7z0@C0M38 zLx&24MrsRB5%;|Q9S2m-0s_kJRMJJVaug|azYAu5&C1SATtfOR&J_F&l!%GX!(^uB zA#D|c!0%KAG0+)uGJ5n~(-)ti7K^VrWiaumhvi8cuc8?N&MP+q2jR(!k|-qntELgH zvT|pT%RGpdo>v)F&Pbhi?B05Rw8E3*D_ZDbl~e+49{5)feG4-JPj;UlCEED<1sa!* zq9M)U{4~^!R4uG&nX?5&R{I(q6lAst&4mR5x#d2&!HQz4Gfh`3%CHRYvV3;kpcN;3DU zu-JFP<1$*jg>>M%eQYJN(86PxP{!|Vp0wf02$ZE(M54(DRxqk@o+bAMDsAZWXN;(F zGTP5BSU>M4N`GzKAeEgDP5gXE#(PvPZK^XYB&4f_f3`xlz3D-#7u%mNxJUj_jfYizN_@E8+D70#dA{PD?O{U$e zYBXIr4QxoLa$T{hk4u6_UHvpr&RA2j5_&q4cW#e8@-nMIu{+(K_2KYU%iQQjeFuOt z=i=g0JyVmRe!e*~*mhs|xlPv0*ml#DMG+sKe=z(tqeB!8!Yw)}ja&v0*VQ60InOKr}Zr?2L>S zJ&zbeOcR>6tTNL0L%+`0kCy_-9spDewGH3$bvxQy@vN>=V96x0u>55Ymk^hH#c%Cn zY*i$p|KOEcEg$cpyCgzNT#$QTMm0BiaHSy4!sib1>r{^_y7WKp0Nlr_>eWLo$K%Ox zL`kiNPPAAo`;%2nKO$v(0sWpkGRx%Gh3wIo;iISTRF3@eS-=!gB`HBI^B!B%kuS=@;qi>h_fzk32|a()#fIE- ze#&eY3_G@XsODeczN7v+k)3=L4i&UvqYNizQ;jn434Wj?ku^O`^o|I%m3Tn0Ih`ah z{d2-P;ZAC|%jMpZfMM3L>_$CsuO|bwy&Rjr=&O|aTj_FfkHj7H*3E>NGsCl!qxa*7 zvhCHGqeB7FN|~mBi>|+m6My#@YW(>6rpL1%dX@Z1x;Jh1`zfMy?A}_^O&gLhM*jji zC|#>9OCk*gMuJ#nA!vbySf0v43#AN+A_C`PSfx?3*H$#7H{_9uy{hl@i6I(`R*6CJ zjA?~X%EBtq^cL|ZH)~I4=qp7i>J9foe?M`&Ks*#>%c}?p4p-p3!^rg!t{4Gk3YPyA z`<;|sPL2ra9HFeqb%Qv9i34t`NQG%#QeUf_+LEJ^`vJ=zgT0^<66!O(Y;c&~`no?x zOlixPu<|;GOWpa#USX`keegB8uAgt8tE3%bHhnW&6(@ zst!FTu=3VvLQSw|P7YM^g5Gx6it79)jU}aTn8FTyne#@4@@v`H6ME zyW5e<1X92##)_vRF)!wx9zG&u$;GWFj}+eOYm=qpHL%lGC02c(!u}8l!#!kEK30JYh+Br#HJy^R^{%-^ymQ>rl!{*Q28&Mb3$-hh!^TUwUY) z=CRY}a9#@Ao@>omk;tA(^mYrVK^{;bkBqvC`R@HSrv;P>+uqsTJu> zWyIXw|B^bqnqb9OSTjO5hHz?kJ3iQ6Sy`DV*5uHRTLFn5O|A0}?lI<3%d;9FXshJ_ zNA}cA!1~=rmb0ccnn*h4+NjEY(X7Bf?Xq+Qm)4PK9(-NnVd!x{Z~ zYAUGtiyyzojxIq|PgUrUJGcyfI;5aWvSq@6#W%oLRQ-ydfNMS98SBbl%0C4(4wlJV zb|9r}fz`;Rr6nMp45$jy)VTep!x+PI>qmh0fC|gV=;*9NS!hE`!zR{KG{Y)wpo)s- z&VCxbYG=Fm)#h$-`+9SopaCRPF(_`!E5>cUU2y1=D>*g74&NXQz)LRPz zGck}<4_V3MM-lw7bt68C{1H`rgQXRTgYvJPc>Q~BO^{WLK# zn*a04%V;f=Bck&h+CraKnm*%>Q?t^MhU@26zk=k3(he~xSPhwpW(eG=28a{RFU5x6 zN@R%MmNVT;qgnQ&krpC~1u%XcU_rM93(5?#uI$Q3VE9XxP&wY%G-4&N+LbrOV~B>( z@75Pi)ZF9s&t1}kZ3%^8#L*qZahQ;WPo@l+B--jJ!v`-*DOHJ|;fh7Z8T@y!@2#l0 zk4yqRX#C7?9N>EyQkQ`pL4X`&Vl>z;-Xt62q_HLtC|9C(t+d`_awO9(60do5g|Czv z_fzC15D|CJHTcXK$sz*xmiDb>rTi`~w^vkr&%ZE^9y&kn+n4$hJ#X;~HJxA04rbN| ze*i7Bk`<+5qFb&R9N}PMA~2Cg5CapZmc?H-IuwnW>0NnRJ|uvuL%yJ~_-%&}p+Tz^ zKV6hLk*CZ>S|}zpXs~G|CxsOkzY%q+)W!9zvn%x~CYjQ+a;k=-Swo?862g>JAW<;t z$G7E_Xdz{GXt;Dd)i-uwnqCMK?1L&ywLi%0>o0u+F9oN3>txm5eyId9kpBWB@u{N? zx!A1WEgVHs#uv_y{`2I4cExlY#08B{F3oJAO88eh4?st6v`-3~ABTR54!GQ#Y(HVR zo+bT=0S;(ysyF5u@XfE82Kf!uxYdmw=7KscioT!Y)=s$_zGu9ASNwx&=Ec?X>Dy_%lP}_b@%M_QzHUDcSHqo;NwT07DE9bM(6DdQ z#ae$7mWfD1ATp|Pv*`jUX(jsjtmSib9tocc}TyOlbb@3 z1jPf7Egu(+61FbCIu4?(1@!#77L@P53!9sI&sy{NpKtt%Zvf%(O zLy;>&qc_N64b-ix!>ECgr2RZt)Rd3$A7I4;r96NY4-ganvp%p$oh;m+_db})Pgq(S zu%89$r%#2`MvEq9%-VKv!n=T6X1GYv-Nm!bpwgU5KiSW&tV+Z{PbtlMW)4w2e>FFM zIRy~6-QQ+H0G$UZA*0mZt9kNp<+sN~k^ab9XyLJ82f$p8{W^Vai(VE z{Kd3T8a(Y5Tj+YmfCW59Po2)}&vudWdM}W1pwUm^UfmlP{G?3pS4;Ka6KuXQH07tG}GbKS#Nx70G zV`<$ViN?-}hMS>fpFL#*-^-8rs9{yDl)QqvUy?+N1}U#Ctpi00og60Stn6%n9Y6Nj zbDc~q_0@<~^tjoknAG-*s!(JsaRLuL@h)yfOotoyf}5)dk!UvlRalS+5{?Q#Am@%I zW#=CBUz9de{nk}-GqFMQ+%-gwG!?EIT)+zZ?d?S4ZY-97P;v=M4TkcPz~A#0JXucZ z?B4ou^w4hC1j60M_}_)#ls(4T&h>2do1WQr;D$g*l(ch)z^9Is;BGxr`FO8@m30Pk zrxl`&IY+-e@G{#+Df`CuCf}owNRx|=vz{2QHCcS6Z1DE`gSAG(N9KlMx>5HZ0DlY( zKbfYvDGOIH=ACpbiDy6CZMIZKVpAx9*hPY&58$65NV0BL3q>OSjvE|8a<@5XUsuV| ze9}@)=BA{f^+2PD-DTJ}Z@P1#!qGv$ki@J#i8_zwY?45KFMCdV9I>9wG6M_=k6(OE zM17;@{P}?~mL$mXUr0;`>Y+Imgp-|t_#6F37+rD7a|<)p#a~RXdG&ule*68C-fH^B zoM%mDYMD5N%Cpd98<0<>8EgDTAYhtzrUeIslEQnuGP-4@Ni>pq8=CE$Ed<~Xy2w7TCoLHngBXkt$=3ROz`29(s&H#V}GBTwIcd-Z@nSw$tRdgfw%XZ`;CNiX3NH-8;=y~EV~j31{n8*?Yx(VPV4?r zvq|9fB{2U0>{_^XFE7coIv_Ow5Z(SYRm?d!R#eJdE}M%*1>&8q$`L#~D9loRS67z; z+lt^v8CsXku-8Duz+>72=q~c!pjYB+d~T#S*ppYvX9WnUwj5OyBYR%)zPHU)b{~oE zVr(HXEwsqC%Ri!LQ9Qui?E3AI#as>rDjx$D=xGn+KTzy|3JAU zykiKJ0p@7&k^$qtxCMM&`WZ7d`+A*}62B?_5%kj|YfMs1`Tm^9aOWPYW#I=AYN2lE zADg((BR7f!ZPQQfr$p4pe(_Bx0g??*Z*OOy7)RB0w3==XqDKl5vng>>F9%C+J|l-9 z6+1U7NO(D%qvW6Q9wRh;T?3viqX=ePt969)?RlnNAiTmB5e}+gG7Ql zVPNu|I~fC6J$p0}R9auvsOm2l_pFA`@Wgb1H{X1`E{_7Qw4KDvOW_1>gFrz<(xxYS zbc{!l>*bva_XgzC95tobORy|%H#m;JSdf9BP;d)eS8Zqc#_#W}5Y7;*SO{yb7t@6n zCBAMAyFY5~$2{w{nS=5g`9&vTHOTaZrDtSB`pqK5)cns)&nPeiXt(J6qas;{ZBE5; zu=NNU#4N-<`kK_QT!p6MGn!O{hCgR2Ur7|hH3i=rgkw>q6;5-O`yd$RN zy7x{sPX4@v6P}4Qu3YwY#q_1QU)Rl}gRX6s5HK6>H);?ATWq2(Ac ze{o0fgz=;1w%TfBDgS;I7?d08CF)Dv4`M<>aP2aP`yb?apV$JdrO3RWy@C_N!<0dV ziuvk}RP5+@Z`h-xMC85l3Cna*^`WStP89+NhjIb#BMxEr=rnetr2=160Ua~wi;9ZZ zh9$uN3eF17G7?jY%&HbbAfye@spc)4Fc(Imj%Gp07?dOnFlHeMZfR*q*DMZGAxD4G zMMJ1M4GFU67u6{O#%+g3h6G@%u@D*<9QT{1uG>N+3JL5rRU{^g>FMdEtU>dD1^@>% zYhOm0tCrSm+7pn*xlI9i?n(6AD-#C&5h|nlEVZ)JJYZV#YkqlzD_RWLFNBnHva&q3 zrW(h5^j1&*cK)>&Rp{QZZ^G7&0zj6%6F9`hb&d1k9?RvrN=nMK$Hf2rb8(idd;iXW zJ5Sa`^M8wftH%|XsjAi!Fe%jfQChLj9s~cl)L=|Ve=3}%#*%Txf z^g)y*3+= z;-j7TL^vP1^|STup(|5gDc^L)O?FA^9BF^tF#_~BqNTL#)ct5GzrOr1{}2f)yh+Kd zpoNN3pk_)LJRR%&TVQK7_A=MS;JJdQHeve&*f-Y6X=PF-eSP9YfWj%pr3|o z$PNn?BG3?qmGn(X%?l*)`a&@8M5zJhZ0ukxaBqijH9fhDB?3SF3%bkBI-nSOw&HPB zr`ddc_N;F{QExuVBm{bOkB{y;<8FH>%N4ueE?EN+2o#KIcio1{fd*T*P3QaN)RMw4 z6P&zC{Y>|YK6VCy-hl)If}M`eXT>1O9LvNaw93?;rr5{^he{d0!`*hj(`s1*+0!fU zqvwIA)o;9~e%}zTNSYh}`h3g^T5z*5hFu5>mETdzCRN=d&Rd3Us`^OWWu|_7iy%dj65!{ds%#Hz9P-tWcv;zMJ{VV0b5yGKSlMq*U?&r#eah#-Mb z#^AVugMM==c{6(G#A1|fWQd|%H~9QJ3ki2;rwnr{BQ*2{>rW+G6h*Fd@Zsy4*VtQ^ za&bR}V}hmPrf(tP)=+!$>i3XA8T_pUpU5P5W}MDI_N$)2+_-USVP)dyg^a z<0k09hHDJV^G;f#guR`>(~!XPOO}9km@xgT)wDY>GZ9v9OYLQ!Y)g*`SU$$5QJi%Z zkAH}Nbs*1*`Ngb@exs8_N?bG>5{tgyrHCWv4NZJU1Oo#?WL*@FOzat(7Ept=p+}?2 zMS9l#*JnE=VvsftU+%XakDN1_8$I#KzMt)`ZgnSG z>SwR;etbpI10w!uLl><5gMTo!|45e=1s0n%jG*}M`tr9cOi6pw6Jh;`oH}( zrkH%+^k1_EXujQT&B-6{HSc$xWh*S-;lgCKuW!7HojaP@XP~+m2D+(+^JlB}qI33Q zM$@*1h21VpX=d!7Z1U^z>hp*G^K)M+-a~sWe6sZ{jaCck`8J+hZO&iL^qfkNXz~Eo zSo6YPZ))#tHM|;%iMbV71qsI3z)jkKLyJ>8uvt2_)?&AT;z?vxi=QupcA}2Y+DKLc z!YjS0&F>gT&hmB(m!*)k0<>dCPKP}aS!y`{wMU?~h6bS0($drx!3IFSYk{NAN46I_ zI@9WT?4Cx)|5gU)9H&Kw2X+Slq1E3``Q(+96b2(8bAceV!huE;93Rx! z-cw}kWjl$@TeYgb3*sEGnf-%x0k1Yy@Te!KJ;$jv+kWRPTK*pIIfvp+vo8i0wa1|| zN87^sF|3w*iFf=Q*`41|LS5#my96Qhu;u?O+x4C`=m^`Y9UnW;HU&pV*L`jh~wAJA;F&$ByuI;n#j!b$qZwiDcUQDa#HVDQQ$u68` z6tMR|<~JOql*L`Q`MkwOyo5JjnL)lZF1}Dv(i-i96#m@g-IGLDvV_Oywt6 z>H6r2b!o1;9G;0}sWuGrv_u+q!2Egqb0%!W1)VMGWYP_u^7f8I2E9`ei?B1{y`mdJsy-=N+t*=I)dH+n|S_B2{zQ z1OFRC9b=81x3WAG=C@`&Yq4L<>xJrWHV=QDL**eMB%cK_;v&ivL=M<9=sz@relOd{ zR`psSwh9jIhxuFRFp_8iIhyPSCQzoVxu+bwyoNN0#haf+OK2m zy*lCXbl2eEk!zR3a&j&YcetgFMux3Xl8z1^N1~cbRg1xYkL|wFM*7va3f<)!JYnfgF%{U3XyHz4QF61U|7T%@8E6H;oZtoAWN{MFy%sk3xA2<%4cpZe$CkG_Ic8mNlNKf z=V9Gk4U>7%ZRl;KkF@>=)GUCRYszq>>A#-rzMg;?C+~{A40&QcbJZWF2M@eidS82c zU*pILt!{3OO>J$u%FiA>koBWPGCg3vn{~I`x*C{&GQ#>FEU^Uc?Z?EupV~V+nq-c4@f_m z=BvkJaTbd7A_;Nv)X|jQR6O2p?ax~or}Tm0!+(qae)yymO}DXFPw4LjkCZL0ulMVF zxw$R%y42gz*#*{P;X5^HxK^*@gJnfj;|yRGJX%~_JUmU4^ZLUZ_;0Yfj;tv2 zmZUd1rgM+F0TAc`X=)rlT;>F7_QN+CUUbKJR+no+GLO*=WLo}2n2yxyckwxE(GzN- z&{$j_keg>TpAc!TaKd`lV{dkWh-={^KFUoEO$}1btg9g*KJ&*@Hw{Wp?E~Jrnw1wr zX6a!yZXYp)-CI^GTPF)wbI0?3PK__Ed>&9}1?~SmTRoc`)N{bzqxk9A9I3Z8Jo9hG zIzum}q`Ab>#v-vog%wHVSJDDXRDLM0$_CP|C=7xHK_IcQ`s~j@PcsXcP!KC1p_m_v zM1GZNfI{^-FByf2RfExx+$dVsPT_a`od4cc^}L+RX+O?s+xNS+^gro%t$`x5vY@Re zlc}#pT)a13tWOHBj50AeYmXpl6Kbp3j(Lk)^wG|&OLUN;m^20uKkaPgStivW>obe^0GtTLLaxpL*vuuiY$P zt#WF3zI3ZeLxShOi5Ruuqz=aZBQTN%qxw!&=&41y1yND1y_uy9gt@fD$?9ymCg9|1 z_dF0V2YRhK1-k7mgsg5)ry~eDDumCgA3w(^`G6;hlF79mIJ?O8jBngcdL}KcJHa8L zpL&|LdLSR*T`%J+*nB*)H#SW@e>S^|m~Yvyb(#w#7#35{JKQ2{Y`|BaSC&3d$LH?j zZfqi{&}LRI)9SqZ@vdplenBF%6@xk!f?HXCQG$?BX^FGFMV1xRj_A79!#WKZnsIghHAgpS#EWUkX+XtA0+g|68%r~b!UOS!Tow#( zs9fj$!gL^_Im(m3E4Vo;3a+fxI4+>>^b;tgN48OrJRA4nT?qsF(6Se@S7B0vNGf1* zrtu}RU_rr34ah5euCvq2nEdZP;VI)?$jQ;i*pzEhsp~&a2)w!YOa7<9Gq$$}Ba&7l zLgrObHUgB)<4@Cxwr*7E;EwPzUGTz%8E|r%{X}`Uc8^^b0bj^Urz=zMH$qLKrSaWzfXDZ@6Ikv*P6o)78|Zm7 z&)qa)XjSPLvhdIWVA<5v+c@cRd{e)$72gl!)7*l1#eM_B`&0_F zCcnqn&8*bY7?iS~@d`T>#48yyJzxULHG%M)+ddjpQ%!C7J{Nnht)DTVm(xHwhJk^h z`(WYf(hC=$f|B@Xj>;0`ro*I78I&;Q(~jF@S?e23d+7M$f#L7!Q5IR8y{L}i`qyKpAhQyRGo<8#GxwtaW&dpp-0zF7$uBf9Fi}I4J6E#N6V+}6H1TfqxUQ27AE?H zrtHC~ibXF|4O5NG92O}hCJg+tSl!wATwzCsQ53IO{O9W`ja$qJyl&a$km>8Jq0=ZTVDgSmWn8?bIN$*%T-(mZp>PI(Z zL1;Hghz}=a|E9_|V0%AAP%wTdeIPIM!KWc_fmKv@%P+5MvkNQ1U4l;9$)nVh!=)Rd zMrML1OS*uK5*m$mu4IoTp-|p1T zY~-)58`nyqb!KR5i3XPCt&(+Ev_FmL5V6XC?q|eE$42LV-goa6DtAjzVqvS2YxFw* zbN~7Lh(HiM1+?HrI5-xQ30Kr8pv;2~sJP193c;(m-eG5Z7taco`?P@M{K&-NrsgyZ z_A%~OP3-4@OCp+F6gx`)N6~r5L;c5b{Hz>_Gs-E&nRgNn*{id!6V51Puk0jblXXT} zm&nQvX*i>dki8QTLRptBd;5KU{pryI4`1Hj&*%Mmy`Hbq$i$33hstVUEH!5|n%Z)- zYEVuC3(PE8hP9m{Bac8SV_TwX-gL1w+6v-w;xifrtLlpJBu!lK>5R*y zX!q0u^f*7RI9LSC2;@%fanB(l{^{vj1rf-KdXbEx($Wgy*!w^kQ6_1}|xi#UIWmOKs=n839Ja z-ehj5t5TT0e8*L(WI5L6z6iU((5%>;-=%O~p7j&wsywZBc;Vc^*g+h-Xq5GvvT@qc z9rJkfz8E7FGos1vJF=wR^KV`MgR2;=Yx(A*0}do@i5D0-@=@^LqrszxUO_`Oit6-J zd*)oKVy2?0ae#Jz+k`$W6a?YjE7$9{`UjhvQ#wGU=m}T7|H0rPwSy@@$Z1UG*H|gz@wy}eyg(yOWg1n5(la1faU0vEwueQUNUHL8_Dn)E; z{AsDV)^H=@mun5^#{-H~T{Wn}Br``EYgfz(rZ|}!`K1oLDlrC1{AcAkhmA3?cQ2y>NREq{S&gZr9KFex%8%qB{{nTj?Pq6)2bFB;;I zFf{5DE*Ks$wfQDzU@BCIfntAmb$J>XVd>975n>Wbd6*sAny;>9p#x#;q>>HTeRWv1`pz}Pdcq4T&sZn( z)*jBFw#}H;^1C_U)}62xJN7GSteR=~%)9i5Uz^+B_No=p>iStcf3DdP9;uZsb+PAr zhEwoE_MX_XJUQ9n6m6*-I`imzp&-u360478z8b}1&IK5EmGnIR6*Ml}}Rqc2~IW&?sUX8K0Nn}!zZFZpq7 z(3nJ`cGxsVd_kP6E{OvlN`s}QAPVKOA=Qa%;eGBV?Ap(C*f^kKV$b{6Ydt6GR{PE0 ztvK`miAw18hRTf&iab4WQQQzw$Ka*Wi}YV`DkNsElM{As{eD4PR)FQv!nz3K^US?y z+UWmf5}?-tX@vBD14J2?zK|#otE2`IOHabfk&A{7!B*gG@@&2_;P_znZSPw4l&qqx zXM=Z3XIKGoYd#r-H_4b!wO>SfHU}p>ex#UW-!-w=|J|^MA><+N=;|^tGF2!H;W=z! zviM)_)u1Q_8QbpQJuBl5GARzMG1Pg6&gdK`x7|Z;HTqj98U|)9EI*NxR#Q#8 zP+>Qm_#N5R)FNYgMS}~MDou)HdQ7sQq2C(AxhTemt5{d!u}~O}57v{XAR|NF1RBuB z+(v_>WtKJLxR>%+D)08OGOP0a{-S$6LN%hzCI%nxvvNei%z6of0AK!K%%xeuO`y5f zr*8G=w7iC^FLkT7lxRHECEO$7azkRkA#N=2UBPQOd)z^DGle={!`$55r>?pLOON2V z^2t-U=Mm7=Q5KB~>qq@?uMY|`O0wf_HEw`B z50|C6#WhY&$|jPa?t2gS1=8mcp@@5i{1RmKLCI&njLf_Ssq^S3C69-OO;TSP$>xYw zD3k#f$$fCTjO*#C5EdNL-ngb`Xy1mLebBH6vOU2&oAW<*s(cXxTSTvG6bbg4%ODs_L$Jp-mkTp=P&sG-475#m4f8K4)Y~?TJJSNNAuAimGn2 zvCbpr+hrXozVWf*s0Fb7f;==U{I>(`Y^wYH$>m;bw@`gevtn5L3I!?%`B;n*19e$_ zH)-N%%P_HOtmQ|l9a|kA3tU+Jxw9ImB(K;YA8(s|5s{eOZYo;XABP9IWLIgI8*S24 zAs$jW4jLS8dW%n74lb)&ohz)W@^M{VICS>)Lcfpas!j+w9ZX3$&8%jJ%R$5K9KUHp zDYZXPf3*u1Os7d!(P;j}L~n1$qW09}bs|QfLWqhY?;Dcky|8*PLui4lnG_hgk|~{qkQZdVls*N)x;dJ+8Bc zjQv!O+uPvXS={?)%Fwx8Xn5yqCmccvo^vSQZbSUzDhNgeKIU=!q}p6@%KW%8;NawR zvt_3(dUalN_Aup}QtsNt$7BKbM{C}HBUU4>L|j$hXyS|scO;MbKj(%SmoC#hHg{%hd^yNGN(iR|GpIGV-;IS_SMBVgk`d%z~Y9VDMVtYdCu1oYs4fBxjt?t!`@e8``<{r%>a zqvB#;fuUODW>E<+tC^OIle728`pN0c*xu>NK=4`4$!X((^x4+zKu#+> zj;AL7XlwoCKvVhj?{@!W$Uf6)^XPPl<@KwohNjc9pCz&+p&uqzF*ptDrH$Vke}F>> zv?e`Ic!p-P&342Ji12b_3eu95G8`&QJb+}MqZCwYS}vW@C-xlOUR$bDP5ZwG;Qxvj z8}$2F3~D}ndez6h5^7*seZRJ6V8KHfUFt@Jo3X9+oS^lrUi z1QDfz7O=nZ(c2xg7Ej)f26JAvt&>4re`KdXSO|4dy&u?&vvwB9rrIwI(%799=oS0L|7jS^pfJ{B`Bs2f zYCSuhSWy8E$9$<53Q2pH6@)!c!^m6bUE^OXd-QK-i_4;M|Ifoy+xk;@jqdA!^3|%C zx_Ez8+OC zca2S%J=|XHI@t^K!u2sroqw}Xq0~zjH1Xm#ilL?~RN>dhvYBe#C}hEKdoi%x-xvvS zT>YCx!=nryT|1Blz}@353`L6KMytb_P1?Ctn_x)&p+LKVziIdAF!93qB14MYgJzx{sG2N@Vz*7vtSRo=|UELad`33M8 ziiqSIW3#~nvGL!Ea<>s`lCHT+k`Q2+7x+jKBiZK zvSDqY)^(E)@)v-8wbsRV_HP8y$VfV6(N4T4u6}(S&cnkn`y|NEJIH%BsFTD=vHIZI zcMv4sN281^=1fuxe~F^_nNfum!n`~-#-`T`(`5J(BQV^0@huN1nq=7nRj9M<+wBPA zYD~hAHcE@tU@OP&Iq@M$xSG!D3-*+gk(2Iz>P}GD+2O9MYE1 z7Q#Aa5iv;Xct)IbH~(#OD{WgiPs_Z^kGwx3Zi$` zGcWmlnOw0UjNTm``J5sz7}r+69-#7e=@1wZ&-VBG0o$;vtLxF{&bY63Q3MP_`vV^5 z3G-B^LZeY%^BP+#?q935tM3{#1{hq3WPagis{O`lFf#CPY z=iUTVQXRRv;{|?{VTQYx zH4R#flArhEdj)umeyARjpIeP-Fxh2w>Bqy9gNFxQO9xCN?}LXekJ-kHs~USJw!W`! ziaE?l&;tX;VuAV&j=~0md<|vu(kMXEJG61{jT?$#FJjwUMUq?x7<} zBhT+>&*R}a7dpSD;Y&F6D6|lg`NQ22$S9Hh!H~fOR^&5%lcFsJfpVfAA5LY}=$ySd zr|{N1XKZGHTG&$)u`5KL*EamOsI->p3X`!^0{l|qXj}R|dbEbt5ghem7@9~)lQI%Y zf!zG73LT8J3W}%55@hE^3npAY7fWE^Y38APP3%wy)*|C()9Y&R4kfp*L^hVlRn7bh zRPtoZcHI0gJBQI~;7_%M4vp0#ucN40`IC7ef!l+cX9FRp%Ju>Q`y0*cr~T{xF1{H$ zuN06h%zj+;TR6`T4PCum|Nb-&Ha`}(R>>zRh|=jfNdROva+69Av zOx6?bs{1o+>O3e=Hph~F=l0YdMLMRp;;nG3+HyYJKv1!rK&e0TZvFlS{tBhYvUtx{ z!8L3ETqLRqP5I4LPEkoNQwq#elpaI=4Nyze^JQ69z=P#+e?tC^vTi$B zDk#d^p}TZMZo+LMV>ts*ivMp@$qC&2w^gjGe0ngTe6XF86LL&qAINF+->Fz02P}e< z-_g@&DeI?QV89G6k2>ZA9xf&*9dFPoA2&PZD7#Or0qtxE2yuVFM+Xy>aG8BMA)AXi z$6bv_TOcH^33m2_x=M$0DZ2grBK;PYfye&_EF1i_*&<>1JlN*O{{HF7QQUl>c)FyH zm!IDOpuEOy#aY8Uns-|^fS8FW&80v_p;Bc?B>%|~E*1@2AyGBPDp2sI2FT|j{hJu4EcQt3qB3OsuiET4Y=2QoZ7E9^clu#* zwaaGJ9XL-Egl+4Wq_@$Jo6s<<_KVzM44K&;;>629L3h!Hn$WdyC#I4re^`L>($h!? zVwV^aagrKyi<<|Eh`_lhOtV~bZ>gg$0MR!Dm=~~n5X~Z$L5fGlcXZbr`Z5ayE}__@ zZp3>`E&JS>4hgE`3#P#Z+OOOlK7)z<`=NSv>uh~h`>Ubi*UI4OY#Ge! z2p+nWJE{<QR&0v=M46iA1QrXId5}LOpcZYqL*_bR>_Z^*niczBt5?N$VCUr z!xFU}IxP4nl#@m+rhwX!g&~w8m6L`QQg|sNQJ62Ex*3PY$9L5-i@Df&n+kLN9sBqy zM|k@5@c2)ib1-3tXt+j47_5T@!QxGk{1N!{@9FrcTiXqwpq-t}4oYa@wB)ZcMSp+8 zd1Tq!2TiUJ&^@sVqJ`g)Hz67`D*9M&($w1#7y0<7_h7fFvyh>t+U1~Vow|fWhnhn# zX_#lIsK0c~PRSCU0u&hc2~WEi)7N|mkX|_;!m4RmAu$VAZMskB@N`LQtqtinm?fYz zZ!+V;y@5PHK+EYSMQqKfYMB(3oaR8rg8OcBNqX{C^iLXt>)7mr04@deT|mI;6N^_9 zE>!zH>9gDr2gYZeNx6RK;$xu*YU^77{dj|&x1EsFVinl(%P2q}?Kn$Z)xM~FPq>6QPZz`$R_-h@GT z3MFHjmdg$5HT$(t93LbJxo;IcDEso>!#aRfoNR?tAlkLigi5aXu$Wkd>#_G;B3W$b zR^35Zk-&!ed)O~WOK9Q@gd((15o}#NDq6Wj460xx6aa$6&$ZckV_O-L2!sL_k^K(c zYtwH>ds^%zG77|{>2nKMC?gZG+T|~Z-6jFvexAEaJMMLLpFg|TxXqOCyE`eS8+zM< zRQMgip_1?ZbrbLIx|DmHOZ%>6i!d=2j(|3)HFwE0eWe9 ze-6Ok9sCv=0DKw{r-P68yL@W4l;TISvMhr)yNVqh$@V6FFK?$fidr@tu51YcpxE5v zP;rp5yYK2jTOn}?43Pi7fX&BFoX^82iT1Me3W^P8Z1ao2*Inmpz5$L>rsc+9DhLiu zzN@SMA`-hfHF?ApI2#_Yw;n=X4_f_soe%9b{EM8b?j7OEcDD8eE zmw_rj%C+#?}l zh7dKI^4N*@L$2MuN)d)14e%)bl&7XzbeNTkYP~gk^78C~1Q5~Nhuc;}c`3ER4Te__ z4h|d>xGeAASIf%-_&lD4>eWq!_e)(#y(=x;2yAYF z3Lgt@@e3}?`14DLz>h}LJ)#9#W>$BW{1&7&(vK_!z2$e8N52%@>P;G>VnFOh^bJlr z`)S(WJbyvWl9KgEeO0|2*R;k|OOu%tmJn{(q*Poz|r@&)GH<&HS;;);u#bPp$} zTW<>2Bkyarymz3JF}wO^SeGByQ~tcIEid`q!tTo{J#(Eo+PPKz5{Z;B zr~#)eEfb^L%sxhe`c zo-enFZ+}xNLb|`c_~yHCDj);uQ=@;v;LD44eor1gT3>+YHR#u$68&r3vd){{&K0W=jPGd)2XMcz z3!c?7fg67(h2M|oT8gA<($coSspx)&9`ZN7dl9^ArGeX*1Qw+PnVf;;A~bg1ufMln z&hdr>)2z&PLqb^kRz*Boj@(@Vv|mn5ZY+nxR9z7mAL&kR<&(gdR|jrRZ4MKtENxq; zm>!`OO%2L!6h!H5STMNalnNxNSF5DE0uuG3ZwX|$f?XoN`36A|`@iee=RoyC$dyrL7gy*&;Lb>sMvQO-gv7(!p4V>O}BKI1_-&n1Op; z_Po8xCHri9#D1U85Ywbj&FT??#?d8Ty(naNOPBEAyCl=vQd=Jq3pS<0=B?jy1eRcHaFJ%=a$iEy0KD3_3EKDbgH;bG2&ZwRu!ZEgOW&M zHP`rL6iOJB&)W_P*iZ2^`)5w2=#fPuEiT(+$czHMI)BM^8c&>e7; z|8izBUPwKuW3WxD<=eVhBBC9Bj?AM^um()~5x{=9X!BMu<-jJl%BO$w{v@}R(Mz>@ zbGNA6#(?#;=H?1v`g9?$&}JHy-nhKwI$)zn^K9=t`cYY<-KU1`4Pcc2xQ3PoJZ5t>5m+!xOLCgP#nd&R>LPbuRhHjtTqE)_%sUQ1|Sxe{qhVrP5QMqH38#w|*JwWOYAKtDp299Rsn&$2%c7DT) zBR<0L;*i(elI3T+AuW$fdjf~()IX^TU&x)>0SuHEFJ#oH@I@*{r+BN)6%l#)usOi;?*H*;xe_3;9p62h2|46iE|Qg#8^(`W z!x)V8?F2~SFYwxk+Ak@TX)#DfRX{?Mns~MqTzxN1`1~O2Ac(_G90YbJS$ug?H3k^` z;NQF9De?0S7iPs|mYG#h&$yGvsKl{Ejb$Fu*gQ$O9^8l|Aj6{Kz)7AXi>z_IkSN(M ze2LUmAQG!^QTA<3E0LWhoWNF?JU-U~Y)zK{V8bRfkrP$982x8+2~=94?D5|;QtkU| zwTM#rX;=Zg_-~(@faAGEvGK0Q#zscwHxV-B-bwR*slaR`C;AAG9*szg5xnz$=n?^L zJtr@}psRHEp>CrIvoZ{`^E)7*EuZbVHpjziai-(Mnd_3gI2diT7Co*zmly(*G_T+~N z_h?T7TU_3QCGml+JYixo=blC?N(=K#z^!=Fx5AS(w3&9DikTZ*Ua*5WgxeH!`lS~4 zX8q3JYnC5f8z+lqD+eFX%`7=TcIPZtNrEv+jOv&hzL3)386Vs=Pe9rbAisv6B_AFx zy&^EC(jFaupQuVptM_&1Oh*lX1wp(q=Cv^v_2Q9KGF3T|Xa8H38}y4)X`V1T#ITvaN!grDeMO-f^7ZZw3jCyo^H6{@Nwu{<4m z#|p7d;8Wq2fKjbV7ppKN4QXh-PD=fhc7t)P-l+fD&roelVpH==NUH}pWKDHghVliU z7YLpVvpi&^5?58T()#?6g;}5b{57>-v7eYdsb<^Oesl~d9p}GPJ^}ax)?Y!{b!5LM z=IwC`Z;2DoQPesy;k)J^LWhd2+5lTRPe)U;*9T52d@Ec%9u(YT7;tK>%%L1fP^35n zTat`#B|YTx)xXc+scPc6`9>zFW8wBI&RaL{_Pte7_-@pK&;QoR4Xtdtf4eJQ#Z=pt zh)+&ejW?gLw8(UmTJC)#FW5ob(-w$M7j;n2))nZp`!1<-vm`@7T41OfS!iI6$0CSq zrX{^|_U?RngK`pnd@T5a4DLlu@6_x3w;*Etcl{jQrq|ltVSJUn1!72?#XzqsBG$QT z(qdgI+r;Sx^Uc?UcywDnL@)7Y}XH>pXfF>mxg@ppg0fnj;e2v_i836cH~nBQOEx1#mDCe zkWUk<*FsM1sx1Dmei+O-8_O9<={l*~dsT}arjY+>74%T4od7-gW+G3Iz_0I~hSN?T z)P<0*fM993CR1%LaKQ-1&WhCspNyNjM0;{-q5v())I+K_)1HGzs3gq~9+kVElJg=N zdz&Uyd*poq9uoyGuR^y{f5l7W#K1#ip6;nq#R_fufV7ed_?&P(#XcXZdMZfx@Oh{xV4 z%Jc?Vlcg{0_UTtt5qJWr3zPsE8{JID)w;u1pkT=}p%XwdEg!iKXcLr>!{Gn@5V<(} zAVtf5CdPzR+S{?z@p!_hsAb4uS1~*LUCj<(hb{H^Upo!P?Q$VLK3`mpigf`cvrgu- zum4_u($$l_FJ~<~)h8h8K6$kFyv*6+5*SvSzaM&@O=YE|$lH&-hOx81R6gA30138$ zouwapjb~&Kkh45%uMtRbn()DiJ(tor{0BDTac85AU~d(?62y?irR=vmv$G8Rj;M^< zRZ~pxUc+8#?U(v58mPA6Ku~hpm-LJ;&u5_6-9K2g`Me6DD>)^ej=~3>RUj?=YOC8pK zX~|Fb2BXvBS>EofzRTBA&nByfQKoBS(OGv$y?O;~^6w%Hu}=90NU(z#RVlwH(F*r* zt8=MSYvPPj`*ry!7z9?peOM_VXm|5R9I%FGWPp_ju(ORV-+d33VWT_kaI1~x0Iu(x z?pa&?9a^A|bmJ9qF#V}hZLpXIXg#6-oHI0pe>Hp?!X42W5B8T50`qLdDl-36Lua}^Esw<_Gs_+)Bcmj{&cm}Mo-V7$2ry- z>gSCQk1yelyTM4hljndJ>Mh=hT=Dsp&9qFO{6W5}8yt8_QVuwoRjxgl8#q1?#qK#% ziaI~Z+Nz>+Sv33O55F-1ecpto7SNoNm1E2fcg#tQaJ0dxL8-eU*kVFeVBG}qr`$H% zVYczOcnr1GfXvgSpW78a^Lh1qH-nDd9WPzc$E{6`_Enl(!;x=?VLuLs#@Kwewf78n43`voZf9K-W($LL+nF$SJ`HDk&5vxJ%OX+ze4Q_%V?I|U$#ErL zfaEH7@$>kFRd@I!l*EE?#Uo~@9u{F=%3c@{Z(y~48qE4>)F=$XuXc%}-dC-)69Y9& zPNPyEm+#X~UxE{wO1{vC?V*&+`m%93k}+eQlMU-FVt0ZyOq! zEF3(R`s}sWPs>$*)?D+&(|_IF&i~}_$HBbc1mM?;w8K?F%yMq-$;W#mJKKLZ-gKVl zzbH`@;X?hm{|FYEE8J6o+zTPG;prW!`=fpz<~XnG7Y{S9~IK> zIG%`sVW8{>uAe=lNuS;>L&epC{~gbljgr;$E)EUWmc?Bs&+a&rCU+biUxw^DP9Kra zj&sfixy}av{{i29Z>e3L(bekLI8pU}VBqZN>@;LQT=}?#>-2Aj!1c0P4vm1|V80;J z>B?4zlA0TiAer9(&KT4jl#gU2g#0^?dLh2Bba=QjGjlvMGrtVTTX#6}D=%TuDkd+w z@~|$pI52>j>4LfBo2~-j8)!_e^8K@L_9AVRnExBv|Qv=x7)SlsPt*f zCTYG1WTTfez4`;>P00=3{Q+EoaN3C)MTigz=OB<$E7YSsgaZ{N1r!T*G}m8XrCtUk zD28qyhyg)H-ZAS6aB6$^?*t9>&OQK-tWE^4hh7&Hv$=R(aOeO zf*B^!W*16;@_978WLAMtbiju$kVFgX$L7Su1cl6PEDKzt)VOVpxxE%6oS&}^+)?J% zrwsWMvAs?q@TKG(f0v46K|lUIB#RU8v>LdgW)cIFbtnroJ4E64wsvIDoH2SN@# z+^?OX%!5oB$bP;>bz2Iq4$g1vJv#He6rNnBI){fObHpUU=t2{DBAS{>37ot~X?Yn2 zk3356{Ry79z&w{tx-DEEw_+odrpCr-f8OEZv$PzA{arwEe73&w;nywChwDkgON*OU zUu3=sv2wG~(@_?(LFb|ey_5W(P908)tx>A;7m`|j0EWiFbqD2)I~6#p#6-+>6pRD$ z2#U+jKR*~P6YoP>HI~kZi@TmnluA$H`Iq@ZpTH9FKtLz^u0RhjDWRYeEkMOcDA>Iy zucpSY{_cFfc==-!BXuK^p73LfAHH0_Y+Ju@<&k(=8E!>DLdAPz-2_6DM-`~VJaLBf z#2B$Fywn&6oR|7*6`+!S7y4}74ueO+D5+m-X-x9?-FQMdl`+i=(VS6HVSuHlvnr?X z7!(v-qM%%OLxg|~(2%!zx97tV3rkCHw>pdR=-jgbu$nm(JlhG`Y2i9P$O+!71IqL; z;Ko0^BPQao6&@b$$(g{IP((_vvQ5os{3qQQqKHXIQ!Sg!%OXL(}uQ7zQwTp(Eoz z{DGJ9duiu+>RSxygVv8VI0_A+rz0*VS}2GWyrX&@2jXN44bhTeEN!rQCPV~0FrFDw z0B-UcSMt(OL60Be)cQax3}|F9b)q+9vyTV#R05Kp3RzOVS66N3Q4PpSbz@a^mndEs z>PW~cD9GKrh7;U!5D(b+ozx%uzF}`C@2$vtW2Bx?zIX86R5&QASifXXnyMr_zU;PZ z-PlS{9;=!>bU2w*K3!u9-fz(j`L_t7>d%vwYTuTE#GA+^@YzaAmq3&1-nE7kpGir; z25+062Y%P_>HUf6^nP;6VxU}3SuasXHI(agt|Ld;&vkQUERL)TELi)0%PZWwOV^^T z<+5nJ9T(A zm|A9Lc}P#d^13R(9w^?auG-Cvt6r-1)$mJpcF+?odVc*_CSHj;)=qOh2&%*o1Tx1^ z8*!(K-qzpG2IJ@{MUfSN!R+@ICj8|;;SPRRNZ+X8u86{QfzxxtbkAj!%XkV z^$;FZ=6g@UZ)Wu`)f#sfNY)iOF)}f-$AQiV06TsX?0LHRqYTjG@`Te+UB>0$4fmXf z!YZ3g__<^L&{{kTzylT^r&buzVCd5guukPwQrgi@mA&HpyKnW9mM%dtDAWrchxKDS zxg>lPc-XTt+)vq>nlM(WD0$QM`>FF9WvlK6sV`u!6vTKV;22yg5vLT>8K0`5eM4W1 zIwk@FrDmXvL5i`yPW%*o;fTGsP_`KnYM7@UhQtXN31A4!%}MvJH7Yiq>A>1vrawQ+ zp<&&>(tbCGcH?f)W(Xf|R;8#i9Kqv9py*Uj=r!dQ-}u(S-bly^`gHJ*%lvr5vRvsz zwf6V}r?PUysOICrPjP|u!e6VYGd`+17VDFbd#k+wJ~BOnM&sYU@MRgq#wQKWUAGj*z5p>c#z27jqch>Gmt}A}I z+%lUIJ}cid-{o2%DXs});SY@ zaAJ6OC9L*ptzbgVsc6VX^x3B6$$;|lzl5_@P)*Er*5%u{*PwhBLfXsGsV?mC<4!#o zpRc|i;+o+C`4x9tLK01n+8*uX%G3LM_kjj8J}@=?Jnd^d4i7mHJ#FJU?gAMR(X*A8zS0S4 z`lx(t1&tO$A881ftNL0f^|2Uko~P$hQBRYjIH*`EYnOyv*u*}a%rV^wdni(iqgJSs z6$Hg(HV#&7derzP4!T5UJ`zH#_tmX7J{#c)9vm7(^0D~E(sxyOv_39fyjU%!B9S4H z4#_-#IBM!wR$qkhT)p6K#K8hbs>UX=5Meh3FsL+E0!}M>Qg5vLG7xsDT_ROpX-YH9 zDjy%6{mwZ}3E_sEasm9wMsdhtapJ+jqI&+bWSfTjU;Ga+*LVI*281y*ectz>L~qQV zoZOubZkTjmUt1@SaTLD&II_g10K1JU^7Q`{vN9gY_Eh{f8!$Kns#~?O5Gpbj1)}u* z4;t=^IFd1$9QUAqvD|#D^pB^ee@#wJO}4{d7?!nFR8&`tJg9q6hv80;eKrd`C(&pnm;o54qN;Y+hHxbk}>x%QPRjW%H+WMm-b$%oh(K=)9%ly|} z@bN7&2WbRZNAc=Q$Q~!NG5^a&qQP5jM>XqGJv;s%>6Nxy{+g??%}N%ht*>3XcC7|r z5euJv{^Y-#0!RbPy2?A~(~Vs>D;^brcdp(c0gcmFgV!CEEk)|cq99_p{7CMd^fD=K zYiMh$+ReD^g?Q0oZIM$1aniXw-b9!^p>EYz`FNx4rKJWo)TU-y;&*XQP_Vxbs8jr# z0N>aP-X*zz{MPQ{R$M94vG(XQI8CS2zO#h_q`d7jw2py??*tq(>aAm5Ox!zC4UsW? z5hNbgZ#%udH}Uk$1vPL-chs?%`(b9WQ#QUR!T;HbJ5wl9ZKGKy_;N8D$;+cy*eF|v;nrQv;v;4Wltc~6S0 zU#qV3?0i~=y+Wa7!gKEiKT9D&MO#IvRC1;TuJ`&Q_KLO|OQb(f4(tO{fzIdafA0m- zh&@fTdRAIF*P4#2sg*lf*?aL85(oLnwjt>BH|6@C}`lL=^=5{EQLXfSOhWikH;O2Z2k_ zt6b_1zkF-!aC06Ud3r+jr>C!eZ9ExL))fv}-wOt$zn49%`EG-pFBfydVghknGHXmH zE$L~WyndHPFUiFxG8_on6(~G#~MO z0Jid{Qq>igo@L9r)-VBG{!iU>;KAg}X{9NpHO2<#m8Hj|dygkN>LzDzsEabIa8s~g zM2BQb9+G}<}6AhALF#Vp7Y@yF(MDLd6oX+`rGn3}FLyo{q{&KW7L1t$! zD=II)NFaJal_FqyTt>qax?hQaz*Y z!S+@>oo)P0W0yjrT2n`K$JdRT5qgv!cj4P-w-B*e-to;e(z4R=EoJPYx_9olxGa^5 z2*^+-rPX^yBBQv0iyjF>87$l{s8(vvtJH6=jEhXBhZFU%T5ZtJoqp#95E-@l*j!k< zsf$i`dP4Q~8{*sLTBlc~rR;8IquwUnb3|%-2mwKvG^p`Hg*NYpGdSc4esn_Qjn}%f zXW@m~J8`IFVujmf^1|1vvVa3!|4Ahje4oip7VZY*7Rml0nSmj-PGEERK4LNb>v&^# zvTt(I8h#6F_Jd_!GJdb723z*dsS*tYIG2&KXHpBR8PXxg9U;eH4*kyw_!1ImrIHtT zw(%q=ARs8<2t@C}X?y*wtwT@R8`;H;8-G=yr-$_;zbZ0+uZ!;;fAi=e+g)}3$0iu` zLpN7*vvO}B>gBz2wvG37zg*mMD#oDNm3jS1==bjN(s$R*e&AhfZ$NMQNe3hl2v5@- z)(?XLPt8D}8~tpS$QlW=RXEp)Ch3pB%}lOWu~3$Ev)!0?KaydHhKHkTm&a{}%ey@V zY4RSri?l)8wul^y)ogmA5m-r`kC+mD?WsG%f%l)1_*+8(NG?lm4ryI_I zZR8pkS4NTF>1G?L%(3jp(nA?BmHx+P8^CBL)@Pva+76eP2Niri{x;>P8E#YoF*!Z$ zP3vpr8^e0soEIE&9^B(vB_{~O3h8BI(!Kg=oQAO13+esSCFas>2&i`AttCdaDwA?u zU1@xeZ12&jm~Q?pLu@Wlz2BTqB0?+g2^K;R!(O7I<4&b~0h@ooYs2$Rg9^f9%}i8^ znJa|c;LnRM=$+Y|Ax)1?YR9Be%j8ka+a2AoqC92oYYkaCG#kTlp4?6-5$K@TufCJ0 z(9V1;@+%}{Z=Nf7C;DvQ#5bfOH2^*xbNu>Y<#!HdNsVVF3pj*O@6aMl-8PQD9lcS2_2$ft@sA>=^Fz-D$iM2y*fjK|L%RiwXz_0YgxukD?dZ=3c~>S?t~}{# z_X$$pl0k&?<&&0{wKeObPm0?ulJQ$UH919}WoFz)1i>%p@ju<*;{fHOtj0Y6#oQKD z_CJ^zBgK(k4u~lG9UK=cAFMbw?xlb~ZcR~33-6wHt4p|#T#QPe{H{$Z1od{ZKuwo< zM$b{3{pdg18(nWaJ)+l#4%c1;xh=Hqx|&hjSP@gpo-mVTP9G>7T!0 zX4fS3uYLW_FI0XW_p}Xtk)Ns{(@~mhH@f9Ck)>u8JhZ%$>-~!@N7DZvrb0qK)hQ{D zNqUXj5-Yk%`?>mwTA=?MAC+KK<5H*U&Qjo@l-6-Z+uvdZ!X-yYE&DRJu)g#8rDu zfLr&KITZbDNTDtrVvEg{v804qSqF35#G>1|DUzDxm36mdwudD39r%s@+#@Q8q3pY5 zy)I$INW==K@k|Mc7n#luc&t<5v+pzrS_r=#a|0BC?C|5X-KPA%cuOcQV}|Zo@5lqI z5sfTYV{{VQktpZ!s%Ypkprf9CznZt`FHeZK36AvHAFL$|=7vc_R3%Z*+Qv>4?Zm z1q}m+T;#Wa90LVqDDx(I%| z*Y`6q`7(^~hPs4RKk3PX!nhC&>QDRlR{>+}5r}2hNY_jU@2#%(tvWZDirnq_QSr`2 zrM|I_H!tmbOUta-bK>I4O1<5INS!+g02HpMF*LL1xboYlA7CXY2w0R$CCa*5ll@MZ zz0y&+8)2j!4!RJD-7~alRmS6KGbaYAk2R}H*zi|MzC9R|tS)(m7P6=0K>($IBZ8Qo z2G@5Ixn>RlY4b`v<$2}2cyVat&|SNHEJ_VFv&ck8jew~@zhUzXZBq@)MU{_EmR2s3 zdOOU|rf;%_tS-+kpVRX{&!?f$+3K0S7W`yO@N7srWLva-uhB4C+R^!b6ZhAKPFgL+ z$fV=WW-l$aM?SKC*cchKV1JSqWw)l{hNqyn>%DF}vsTJBJY|~aqZqmk)I=nU9>#_b zR#>X-rsAyD_U3-?2pr1>O%XHGjUxlE@!px!(Tc>&xuZJs2APAE;zn8qogr*)T5K}0 zyBvoTd9psaLbiStxXqAfCVaQ&Hui_RbkL_S!GXUPh-IZp!0ZBa4N#-#K$2CKHx~i! z&tmqM>;u`BU;KAwhIB2=Ei!X*+$|cO?2ZY(w`>dy_OI|eT>(37i!T6Ty?)ZrxVLhk zZe)glB*GtI5o97#+@1~Z!XII`K-`qM!^E`5rBomAB=B{nnVF(|-TwCcGI_w#;=ZC; zmYY_Xqy}=Me==zQ;ZJv(T(uWH$A@;M_mK0gPoJY;9mn!bwonc##~B<4gaR?oi5D(p zr2aOzmK+nhi1g}|l~B$afiP%hw+_|CJY--$=V$nw2)9P)^TcM3$&wdjqYQ(wdB-bD z&YX;AyVJ+Z?;DSK{C&MW-xUar`{!}m63}8P#>rtZ72ok!?8}odmvT5`c%pu16%+AL z^!{JP!c2olL-#q#hbFFzesCZ;MsG@TVcCsH9XF{n7}{N&%68q6&=B#ZK^( z6+-7_+bVrLHwn^<%1vyQi64^eBW*1ZCbg(~G8GGRRJ^vb^}Sa!X5R9Y@Zr7=u5v8^7mYuU5)*bA2r`CPyIyz{{AY-_;<_@NY zvJUUOUA&aB2Nzen(@(D5@i)3kXMp*5m9ehI1Kchr`-ccP^U>a|V=zwO`M^_d^rMQ1 z6&m!`8N6WZy|r>c>T!H&KB0}O8Z=!jDhDjf;GLCjovm+Ncr5t6DVxtLU3v8R-ut^m z8-p>@5GzFlge8&1sW9Fc3P~(f$=~seX#$v|c0(icyGG{HfD8q4#PzlHpvupD^rj9K zU;)I)vQpAp###xGTmC$hSvmSWtAC&VZleu1I;BG;;&wpRDmL>*E9E~%mRkPQ6&(uRIf;nAw~0r$ z4-E~a?6jL^JffcAjm8R5++&!GyKZWa``D#9H(P(Vx3s%N|5JY3ni(6nFsmn^lsFd} zHs3)S=%-=}3%+AsD4KW5!hzb5(&h}}l04(r7)9*dgb;jr!W<3{h4(OA)9xZ91N{p2 z#0uhN1V1ITIWp(|9W*jqg+;$K-L86hNH=&&@hDUK*j(bDWe`FP62hs$A(H~(TW16} zh|`3#AJL+xqfhqc#g#1{)Xa1h{m0R{$20x@Z+tD)$S1?flw!(ZNQTNv4l`oT8)6PQ z?N zx1)5_(nQy|Nl7hm@y8RK?Qv|>Fu{N_j;pmU8>)9 z8@pRwH`3Ev13zppaUvmA+>oFS?`#TotFw3`J(D_K9{>iuI@;&xnZCfS#~{a$d9XCq zYG%nFk}7^f5lmT1-^Op>6I^c3=W^dzM^0n@`ep#4O`OO3#>Se4hEx{iN%(4Tho$+$ z=w8zoUTF-EjP?``E^Q|_%6)1tm+?aO|-5%&hUvv>yBM4U?gZfH8dT0 zc^y)QaR8|+*41(Sz1-YfT1sj{)_oLzaL6kKJEerIkVEe{(?sr7#>CK56(-bgM&HcV zL1Se65m9v7A%1=Xm2P#BosEC0C_~6oYXGP55Ebs|#ro;z2ip3iM35ZgN^nNeg25o$4LyQT6Ihs?v0u5sFFVy38slB4H;82U*VB;7G*V)JOWEj&eV zFFg@+8&L~;+1kN>o z5HqEVKIyNC2BxmNUlOT=xq>oq`MGt=QA{kIh7Da=YTkt(782@!_S-+v`K6Y|s1XFS z%Hdum#MJ_*o{UXQg6xzI{iOI{ZP}npjg+M}`;krewcf+OWO;8TT1qDmA!okHY@pkW z$i2wuPEd!{(n`KQQxu!Oz)*p$EAo0I2NrIFazv>gI5{3_?+N5)}kJGU2zn-t1iTGNEa+$LsfDBLr&6}dWFni zTq*U^3A5f-hL(igj=`LKSS)-g`LjTSlXt>3zUOv^+2=sXg+>R0m#$;xV!u%3&evn> zoOVriao0B^hpGW<=7g9*P)W+{-TIiJ_WPY;$uI31QBfy*4ecd3c!YC<5ptU9wIN#% ze0L@{qXp$&cbCy5gNAkfZNAC7^PhO}kvyre`w{yK%DY#`_eUD30}-(qCNjoZx7>{o zDT>7B_~&N!r}$+&J4bnfO(pmbIZD<3h%2N{Dr?{Sa5Gp!J)1|^F#A%L_3U#qs5V@d z*WpQ=mSC!oy-rK2rubAql+-R;r_ZIpRWALYwP>NS^gW$2zn!@mY`X_CeE-MGO92?6 zS54h`8cDBNfol?ua~U&17v_q7WVwI+eQw&BY$gUl3g0s23B*U-@TzHWCV@8D+~ zP};g|zVW``Qgto2kWOQWGS(K)TGH8)+LssadIfq^eJ@I5lvMPqe->st?+~JD{mOJr zH7^kSA7eKZ+kBHmYEP=loG-O@IQlUsXQ6aj%}n<`gBnRh6=urx^h!pF1f6+Y7(a3#)G>(`O$m`Z$$Vl$hOybALi@>D#?CKnH8Dgcno%-G z>?P+j+$t+4Y$975GUu{TwJvEG+yvarTRtTgS6m))ax3P6rEhASX&4uL{}*7X$I=-|6kfr#lO77a%m8gf>2%HEAdKi>!>om5s zxN)c4jJJPl)sVyA$9D%<3TtL7o@+=JdJk85+aGy)nc?P=bI05`@p1u(Y{Nr8k*h7o zoOO(%k2i94oBOIPWbu+ zD04PzwupEST+bwlPEaY#vQDRBV_*NGeo6=MkmK%mYr!fKt==T1zo?{ornMvOFlkcu z+=p_Xi#$|A8}r3?lT^M!AK>{2;o3@U&4x>^SZ z2Y*f9KA67RHag{^-rc+NxeRQ|3JTgizK|RJcgo66HuWd#ar9Tk8kH4^J)6ej{;409 z%y?*j4xk8 z7+wT^p&fcN(Qby)a!zv3qsy<`xFzSD6^GLIQ&Sl;uy!?9Vd0;b2!G6=U!%Rzc{gn|Mu8wwzD zM}^YGg|p#kZLbxC_ruNWjbHuO22cwunx1q?xW|4Dh=2!f|M~N1ywVNRB;AtzoESnW zPZygBg)eMIe!k+c)IPTt@i1;|*XHZ?-qP0A-uAusJJUdP-`k45_kMQ*M5O$7m+Ief$4PKK$Zh{p@q_o<6uWKY=V$mdy{)Ur;oCm zaTwr)gMY}D%Aj~;UP0P&ln5$w*{@gbuyLS?dP&4nLQ<0`FJx!=qxLUWC#N|FY zj5eLvtC4Q!a+zBg!7%SNT11faL|)aql0^nRD-q%xg0EV@rC!!v*w%V^26i4D-rv+-?lMpvG|yi#%19jodZ^ekOG)it%#Ix<-92zqxw1ppYaJM%yZ z(!bW|9={&yA?pTmM#fz#VraggV3aXLIJ)c^)zPkb9Ua<#I*Qv>^&PiK;owdySnh-E zkP1rr(xsx(axYA)2lAX?bwsmFk2G(OyMv0o{P{n#yYIO$qD)k-%?2j%QM6*uz~aCD z_>8Z|W@wjg8aUXp6(?4WA}_*=D!W>tDap}SM8F7VXjM^MS?gZFJdF+;8YSE5(ko99 zCFs*5iDx6IOe6^@(=4Ocd-#b_f&YT+-#jXft2^Fn|9-&U(%vp0>C!=olyjN}njY)% z;oigRGc1>eQ^adm`Q%2bK+N}~oLjYd@n+$zOZ52rcSSYX!AdX}Z!NLFUMzoZIEP5! zwv&1`DR?y;ooHUFP$^#gtKHLLG!E*sZ_=aM^05wTkAO)nTZyuLL9H*^DeIN5bK)e^ zg^y(dr!K~ngXfRMzumGdH;+LG+SO*nye=eK1W@Ehp8a<{RX9%vB871b=cK0ak|tv5o+{}YU@*}G7e0mvITWfJ?s?m2L&xB z^XgMZ%Wed!U~9AQp#Sew+zIwPwsNkUc#d&1h1Cz3i#R zOr(8mNnye7)2^2}M0>#_RKQMnYwvACO-?DHg%z8Xy>PEB0CwRLVvn{fM$3f1(s4z)|5nGG!`{7MDd-L9AYYJRv^D~>;V_H&T zO3CxIR`^=bVDgFKpD4Bo=_j9pZAQ-k2#3uy7> zA+R<{DjXb{bFQAPFljQ%eM^b=(m_k0qu@#4usVG?hF3Sh~ z7i&w*rBC%;%53o4pLhUza~l=Rip|Zz9$J040h}mP(R|({xwqi?`!koPo%_~=L%Hu> z=Yqaf<9h|=OXxAN^cU*G66n4@09dReSGaM8p!Fw_-xOo*g1|DyO1O4JaO;?e@o?2p zTCMYyg&xmJ**3+Xt-Iw|=h36^r(CIz1oCjf$nerf__pU(s$VYhiQnG>`n9L~7OG`d zZ4D)RUo;Bcl7dum70J~^x6vR9GYDHaF@@=rBk5XKa*-)ijF8a^sbgJHAFup9*U6Ar z6D};q42?3JQ@%ztHMx zJ4ri^ifM*HbjOgcWA6R>BvGq-SFkg1wHR(gBjZZ4R9)2#ffE1^++WF;oZPzo@w7Vj zQti;`oG8N*>EEI91kC-pm5g49_?1emBSVTVGm040aK4}E(#0KgWce!`>yCd)A;>Ndt98(^TrT|iN;DjDBRRq z<5ijME%6KL8SZ<{)jxlZg||mN?ZAdErl@FlcSqX2LSP+V`RD4N3c`#2ut;iY;_PUL z6^fCC?nu0@VS~enFs)FG0jHGVc^JO)H4^VYNktm+pQm=?mBOjEI@s1PS41)gHl%~z zEssbk9keO~Wp$GO3u2Ay-uT{1GZ)3;3~Q*$`~mo4b{rTu6~|&yXPucxgy96`#j1PX z>qoZhs+Zp%?AN_nUMf*bq4=+yH!PAEykg>dh(_fxSzxBU=y9kqb-x1Y0te-b<3IQG z?qD@8(M^l_Vp6fKzaVDLa?d8gK@!*~7!Hai(Jg)rB>-w#^{I@*<<>^F=@5@T`3ywd zTekJnJ+2RVG!M_LalvUdK{bRp6#?T9F;LOSeNveGJ6D_sEj8^C7S8MzQjy@t{pqL- z&%SJC9@FPXV6BIdk%6|) z+HUmLAfYl+w_IJ_m|8-o?Kp~y?vKW`Bh`F|hy)5OxXlOx;hd_!n4vd{q@Tpp{QzMe zpWYtSBi9FGUyd}KZC_nlT58^`EOqemv~|1uY&|dtrUWnl{5jTsDXc|s#yHd3 zJ!abjGhP}zhsb&`skY1(VmkhZEk{VIy2Lk{t&X0BsJIgD0nPI$TXqc2)V$KtwWz<% zDF;0R0JM+29?u?gtH4y1q#^A}$x__E!XAdeC`UXsaYDTC7YJcSZd|hn2b%ERZ|usD zOTPWs;6iJGTN*QkiFB2?XiqZMWod?B!M$X{SK#S(VkH&(NS~VcIUR@!S6UVRJI`}z zZ0SKm&9&=pI;AQ`AC94dQ=f3{HkaJr$VCt&tb4Ijz%bzN|4y*oBja1d!{r%g9D*wj zd}Zo={U5EAr|0H z<%octbv{Dq`Z6(!z@f6zFL}QBve4U-!a+~t&SbF$j6VHzU0O ztE_wvz&x)>UpR!`^$=GnG67n(diCt+*52+z%%8$8;KGa)hroh~1hEBg_H}I4(J({y zAFRa&yX-3GXI)4$s*O0C1e$Jev%F9?jCxF-1UvNBN%AfJ;km=fSjTHyABf@?ixJoC zDeSPsPnS7JSEC(Dt!T6~_c>1it}$A9S*2_x^;)aN`;#7}V#)14^Bzd@guyxT7cF=W zCwH7V+R2%EIO|v!Yp!d2C#>MA)JCb${=K`ROqrF^7mwy8_QT^N4~C>QgfxWWgK_8Y zdrq<*aw-42cJ}*_%;gk3^TSk%mJk8=p@ZM+Xs>4Li%yVr3vEbJOuoB0U6(2Ix8foCZLR<2 z+;ppJ*^s>-0Cm>6+3VU}CVeJzi-;UR%hW=sa`sRMK`6vw8gNmn?=_D922$`=bVS6N zA786{8r;)OZd<*)ZTa$^o{28W%ynpCaAap>s+)S6}+?g|OUi8-a(z!|sc*r+D~1jh=+6;LQBu<6J)R_;@{Nk}m(vi!jWX_y4Az zc$r-e(7>&J|KiZsJ7kM z#EqP~h3oi=At(CP^jL&xN{#-WGd~*~;@R6GWnbfk?=^#cSg9~LUr=xq0t%4xoBJKB zeL=jhk2~_%)jslEi6zoCmuCuMcXTkzzj+m_HgSH6-R1$|w%>sBdB zG$dU1W^Ds6SV|i=q_6jq((cAOAE-a`+x)w^F#N_!DF|2y9J~TOeL(dVI7*@x-ILjxROow_ z%HQO>>`y^6kOXCJpl;JVrOdD7=Ndid4s9wZBWPXiBT$$~hX2=P{XRXDu3l4C)qjW2 zZq@y;v>e7!KsogNfU^8TU^00mn8FVC5}i4GSb|QyLU5%g8oAIIaImzS`F64PxBFGS z0U6F_8K>g9Ds_Y<$Z<%TkJ!+7rfidWY^A1dOAZdX*-JY3?QZqhmj3zmVwea6*c>Ic z+qbIRPNP&PPfk;3jN$e(7QHp^ZVU7=ax{#T5bT6kG2lu`aEC?)a|C~^2U_GR>t4%) zfsc1lo%qg~6eL6@DEmFX_bdrD3#TFC&;{Qu zB{r0ZOdb_Hm;xK?>g)ghTNkX>b#$XwqE9dn`or4iBfDE{d^~)xExu`>O7f6xOf?IRPfxgU=aok z_;{Kv0ewu6sMoHh-2qh=%EmB+k}(?eXJdt)gT|I06Aq<_@BZ)^i}?B0kpRYw(ns2^ zIakEQbnD(4zmTQJ*ZJh<#$alFGxG9dZm-Kr(t$1@;TqGg;mCx%s?b2BnxgG0{=?jG z7ZmiljuW3_XEPnHyi9f-^wu@xJi095I$B~(7^wvfK!rVw0!dNP=`y!S^r`c1q>r32 zz1TCZF_o6X{H|eeROrZVpg^AQ1tsPdp`v}UA^k>nM>hnD#7QCFUlRWMBOs>qK|Ce9 z_>8awCrKo+`0i>$pbrRO?f@E3&CuUP@cMVRd<5_%N?iG(Tm34(6%9E$f^GlI!Y0_Q zSXj{-AFcY=kdsc#fo6$+i+39=THsH-yp1z6Xckr$V7vD3-^OBl=E3YtF2W;?wvNI>V$hhUCJgs$=2vlOCgS`Q9zB3KkCL5~2YOcA0K%4u z?khhNj(ODgpy+XMJdp##lYqbxoQn*}9O&a`#f~mB@~eOvOwiIYG_K8e8@oaj=6230 zsKqr=g+bFKB8P&*L#%C&qH>1_=!wtYr{&#+9p(~OIXzI;cPOqKZ(xF^DJ@rS~ z8Ea5&MaODn+Hy-LvmsRycthe*t?_G!f#&ze?E0)4fy|a)J7oM4J^tNlcb3S}q=MyZ z45fPJyNI)$JQRrtGfF`V{$*8<2mIW75a_cu-&)=kz0TKn>5cRy{VRp7*}rRB{Yrgz z=7HPWQ7k>W%F@|B>cFq4n!0a`eRhiqpcXRbWYcorMy|$Kq z_Dp_TTU%+}S4P>3ci^f5#usirm_U-b!txC*4A6r7KhSiiSoiccq&nW+6Y7y+LBO=i zT(5Sjd$E~66cve{5%yU@=?y68*s%o8qIPX4=&QPtbn$aMsH2g>Gch-d(_RU9#WY-%}5;6yPSf_s}X#&d|J`^N{q! z4blm&%`x~-%Mshdg1N?wGO3i5;!05QR9G+yq#HDb5e(6gw5OIj)Q|y63wTBlsL=CJ zs+SIyL5qy}d~-==Rk4Oj94X?P@Iwv#(kb@}(=+tUn;ywR>;^Qlese|GR4WVowMlD; zD`j(RhtGIO>(49p;73j$hY>m^{EeU60tr3+-uwNfjm3XcU4@%|4Q6ljt}N&)`ELFj z0gKh5m>V}({#zseyJ*z=2l{$@dwbT-)dJmM$P|3|ww2@(lfw1#|Mju%&93V!`}+Ep zDVe<);&XJob!+Csbd z+58tO4atCal#3vDewNch8DxXcZPMXk1&s%KD9S4iR0A4YW!eUrLWb;uXGmt!nV`uB zmH35_&!crdOhxMW8U?%KOZZTHOS^b*a^Hi~>y(1tx_je2z6Hlix3zNwtH(glL62rj zk4x&LXCpe~F>;RVH$z4Yol>-*u6L-xCfDh{HG%s%nS)(?Y+G+09RA8@R#Lv$rYa23kJj#5f3I0Ui*E37d(a;#cF^QS(p(SZm zFGgeBCGKp3F}*gBsQ8phl)Om&C~RpBCnAgI87AbGUlN7-SJT%A2FiQpcIM_hYl;e) zUu&y$?dw`6bUIIu7_=F+J%Bu!<_)ZhRMOphMFlpy@}0oduSG z?7Q42$Q?k67pRGyRkN7WcPvA(`uuU;7*xr`DPG0x)U;gy;2h;0gUv})4P zfQDonq(JaL!zB>|$aJMruE?3Tv-{Q}V_Q^Wq^)3s0NrQ6W*B$6`2#B?%%P znTXNQ&SnFd6r$cx8i>@auXj0bMFc`l>6Xja^0a>9gF{RTPvYj@zmwvFHzDgRq}iPW z#H8GNaZu|Jj-bK)Kswezh%6|WuN@+5i==9CBzR@SF|0T_l|p?p zkSYj$d@=P}filGt_5piUS9-?cJ`V&4e>ZZQKGr%iX>w?{yTJ@F*Tp}(5-{PD6AafxIP9Yfi`s6$Z*91unUgqJ_6|i5!R5lA^dIGa8NDad(|fYI z0!f0EesWf$5If3FX3N&|wxoPp^j~SRSSu%r2J;{<9^s(JV#1L)%7+L8asgF9gfB<3 zUVDZVMUT*%bLudE^+i_WII6;A)QKMD{Mp0%)=^uLPzV+G>sOxhXF`cdS8WNAlVV*| zQXny7arXi)W_@wm!{_^q4%*SJLN;7B`Tlwe3HIUoZJG=Y;6!~h!fjw5`qmY72Ne5y zd%iy|HntozHs*KbHYK29Bhk9+Y>+SmbQl~MeHi&;RRaV}Ipo2>*UPNAxyUOT90;gL z_VYE04&{7^wuEuh(PC<8)wkFwP1H0MO;155d;U!rdhm;!c(Z}#)D*_GzlxJ8OX)_W zWvCOp>u>Qyq@A!V7`h~vS!T*eCL93;2;ZUgN4}rh!+qXBa-v0V7F%Yh# zYTFS*)TC$YW4(HfPEEA;_~xI|w{G@0qi^x)1S&e)0E&2({psYhErO1K-HBFMB=C8A zNLa{bhjwQpRGGwlN%J#qCF4QBE8~_neG@n?{2DrGQ6uWGpIb{xy!Olp zwPk++hHr`}q#OT19r`-?r5lhk$YT%gR80%N6W94XO3uH7`qC440wgHJ23#dCTHBiKdFpo5XX>=7(L<(HmoKLrT zY>_Bgk7z~=4yEpa3!#tpCR*n@M-=_?KiyGvZvV7L8O&&*5%LBq5#(mAco zW0AyxRbRGDaFWSOA@-VS(e3+B7?O+weI{jqyVt8ZYrB_^Df5)3p?qBs`d{;-ufKPj zQ7s5t&+pgy2<`<&5^ayZ3Rcza`PA7%vJi4D)PR_BuSxm;CIxV|!EjqC(P1om7Lkc> z>JApBFIwDxv98pTLh2VL8QcKy(to-Ia4F%=X$-2T znW@fz{4-u|55~ZY7qrhTmL)}1(s-l*2)?edrI>J9zK(yZLK|}63m7n*Sn|4-!^ZZl ztB2U`1aAEsajERaqEu{diSJeXf>5JjBuNE=fhE^!JVE z7fWdAfi%pIY)$}C7w=&ck`YEx`$Z{5G$lTrkp$37V)$5!RKSNaF|2lVI&z=~o8*{bR{O*dXtF^pn zqC2RS9|DT9Q-nVfx^1%uWdp!WOFL>5eRpl2{ z70eH=Ev`+p9?Tv53EIy)*f%I4IH=_L}dUI}MF)6NgdCB@Y!rS9f4-xi-@0K|^!3}S0bGI3zh z`3jN#!h7sW8`*rMpiHFXG@KqEJ%uAo;c)qX`~S-s+a6%;EiJ8jD93Q)nHHbIXh7M7 z1Gf%A%7Z{b+R+?m>bWp?2akFvg+L501U$nZ$pm)HX zMQ8-*b(VX&Eo}xHDzovFT9A7o6wU?i-wsr0u;()>dn!v2T)SJHV%{q>z8wPn8Q+x^ z-}#>SE|-u#!zK9raFb^xGQ1xf0YlHw*4?XLwxMQdw#;sC%gees)FgrgJ>lo7$K#*_ znLg46h|@k6OnH>Sc)#5BTpQgAnN;vwez`rMuoa-(w=Ul|##;L6ah=mn2jiH=@J(~H z9vbCrrikZtZh}ZQc-G52YnIV3k49&~!%lcDirV^s#&}Y%INo6m)%`sTA?E>2%hpHd zrFg~!`rysL4Ra#fsn@8tBZo2zi%n8G%&~Nc6KAa|MFE!P8Vexh^mNwdFVH3y8NL}& zvLs1<+{*XEP#N*!P=rqX2q;fek3@;t3W2|UxVtB#$7uoSa!#|085;FPvKFU(r30`W zhQk1*tvg0QxB1SuC&;EUt1Q!PB`_P7W5r3@BKU+G+Gx9&?T6dR$siq?Oz5QY+&@J` zaJLVHwHm>hf1h)x2}I+5ncjdWQuRkqi09mK{uM_qBYH-Eu6z45Q{tFhj(A|Pj)m+O zn2L$9I;=o8db7Yi9Wl3i@B3oa?x0_QPhgTN)eL=2%ri;k$-hTGAP_i@aKXo~;QlEU zs$vvOgm849-fdB>cDxkiv;S{f?w{^e-h)NJ&TagYmbdW6Kkne4u~pdtcT+Sv*lj3dvB#!e{C@ye*NGo-JQb!ZgBU|F81 zbtK18&D7lIqpuNOG+w$C#HBEH5HD4s6)HGpidPXeM>~HwqTF{b-Y}SrEkp!$8tDnj zzK9t(6Wv=6(_d`Pm6`pb)>V}Q1xg)#^3kP|4eR$JI;iuxKX*3@>(b`XvW>* z;1ts5rbHeM%~l~x5+YO6GQZ6wC-)0MvY66| z1P$vyY?e}U!k{mwN}(YE)3CHG2LiWo;%d1#*9UJS*_O$6>K+8arM zhbBc)WbN&G@pO!40Ws-aRmfu@k7XK2xOtDqjR)@jmIp!NE|nzQ&!XUm`#<-8ZtVxA z<&D(Qyd>5uyawc3ku$!d?$zIWnt#gll+5~hiRM4x>~B}-bFX9Rt}8x!x{V5-WsE#l z*7qX(5*^-dZk;;9@eK$kdsh6GX=n2B#v?z@X1{G~L2~WBlbH6Tw_YKxa>+--SvYcZ=;P|OFyNmfFWYCfVy!{NMt@5*$ z7~0N25ro*;V@&H{V_)eqdVY_1eB)V zznkT+BNR5&^g@M*y(szw_uM}cj?jw{f!+zG4#?;>f9(s*$Qh5D1P6FGNi+)81}9R` zbfTKJx1w|~&S34&U0Fjyq?}}a<&`7iWkd3AcCr10B-YD8ARarRmzS2>d@GCxulxu3 z^CN%)d2Q66cShvoc}L#0U$uCDCM4^yR*Cul?z*ty_(Mr+jw*OtaDhXM;9& zX3_`e_tLLc4-Z3}icS)TbT8&ou$#@Fw$)e_ZeubkD?fkz%5^pmf$8uhcwQl+MRKX= zw%QWuOVTm@{g0X4@Ti44B?qd6is9CCIt3%JdNe;Y{>ifiZDB$S|EsritAD--C(~Zq zb#uv35q3gsr=ZcBDJn%0u5R>-!75^#!$f}%ru9b-+qd!MgU!ajnFoV{{~ATFHthGu z^<^}kzH!rl{foSwjpq|BfQCRRB-=(&Lp9h8Ua{FlMzWzVXnqh6Q57Q3sg@}{-dbDE zZ1{_f%ppuwAD=uJcF1ly{?9S``hJf*@4-c@pqf+&Vg1jFdu`D9=8})r!SO<3Q87Yc z3E47#41Rp&d;98}zG?h@)LWqgVwMrk){NFndKw(8$r)T!%mZb|V(f$Cy}H3y!IOe@ z=rH?4ZJxbx`1nO;T7yv{RZduw+9b?-0hp)(%|{UnBzG4l)`05&VmQ;v%EFAK4e}sVc>hw`+R z7*m@zCdtF?R2Y(vm0e;^*BO)6)4y~o+S?f5r3w~&YQ9O;#v;gC7W@KORT!v2Y+w1EH((X+mw=B+`^rO9h@t!m<+oFeGOQh$~^cBz$)p>jXVhbAyzi= z=m<=nILlKPjZ3xr+T+150!Rc+&mPHFAHn;V<#3CH-6WW)eE)2t;+uRqJ09_sDH$q|ZI0%zj&Zsg22_HE=a6 zoDEl7Q9VN%+-#m~me-q(; zrUnCg%|N+q9Mp^88}u~}WC=;mHVuF%VW&g+TGiuO3QCd-B!YRUyC#wvJkW|EUCTEn zg^0;5kK^5=v(5sQLtRszl~(3i+-p zVzIshWJ%{qrDN>^+QQWcCenPc(traFQ{jqlswYfBlZE9%8Vj zef-8wr&v0XKrMr3yQfdtc0yqH10JrwV{xEWDebJS=71Ex7U>+|N(WyA|M$miUW~HY3HdqO|-8B$Lhc#LJ`7afoRkASX+1ZVG=f5aN zH6om`tB~IPD8|izLwjDppVk=Y+4Z8Qa7Q{V;O!qjg-?F)Wb;&lW;EG9;Kos{AD|7; zvErTy9u6^>8#`|V)WRL~@r=FftHt}jz?YFJViQz&;bTx$>Yqznhl2{!BPR*@1__vBjgOU; z>s70ZF)kM_Y$+YFCGm^I%T4Lv5R1Wf6Di0e;$dVhly=s&C-Y%8X8y3;BsQ5{`3M1i zl|$?+sZjfPnoy3gSylo4H`OWBiT?V62BNokGZsfSWZ z-LI33vG%S-@Pd@V+!Rj-l{tsLrdziFWU)cQhCgCYRT4yo^BnVLW*qr+tHsmQTnia< z^Ni9e;;5-PzqzwraehpGOqGUth;WPie*<6RbXhbS?Z)G+f55Y}Qx4G9$v~DUI8Dzb z0=PwiWIpvumHTOQB0@YAhayywutacKZTx%dV1P^6|4p%bU0A6xQ%fR8BB$sO`?7NV z?%%pM2fy_9S>Vs{-*3h*x_Z^Rm>0$fomUn1)TA9hyhd3+ERf18^bGcC^{5J!AZ*)< z|Ci7MIZ|z4Ux(u6j)Py4hrcUbfc%H-#Y#4$Rg>_WvpuXIWB=*+0&%2jORpHR~)=5N(dgnsH zRb5Q?c9nFfF6}}uHCnq_1_-c&i1ICq+LOQ z`&jKDQLg;CU&Dxnr6q9kENqUB5@6i8jqk}rCh?+$tXilQgRHWJQ_(yd7K2yXX6x-7lpoK~ z-~bN=3hPEjfRr#_TOxZ3iBv&bZhXgI2qU1|;a-eQKko|%f_y1DO{4ShJ%tl5(mi{L z`8>|0u^Rf*hAT$$*&;cRBVfUQgIxY(gnesb!moXFs=hR zNkSNJU_y~jgfV5o_{sM6WUo!uMwRzrqi?mEu9h^@N@D9=nG-jKfJ=XY zllNvBnYMnf_amMg;|9 z1qDZB)b-b86u-4JKh@;TGgBGjNKAMgpCIxCnjZ@1feB$SPw_@j1J$IjVia5N{dvda z%md-b9QlpO&4)cLw`czTcECYZP6TcTj=n!>bMJ$sUOW~b#aa8A472V?jp>h8kA-|l z=7vZAXQnDjAWOrj#H8G(wA3S~dZo|L6Xc@{%!g~AGm^S=&&xkKDr0@B_ImMe=GR0s zn$O_JaGGPLt+3*>scpAeHbOiV?~s5LZW7?nJql7Vz3nMl5^iprU)oOR0PFGWXv+M~ z`ixkfBVnHAMKR>q{I?UG`EMi7d(h{1S%Ep)NQcS}&H$H~;@mGdetK-_;A%4!p^vtF3b*UP@9ynK zTvY~xabe+1uP-Y1%cyVA>~`JWdMF1Wsa_iI|q*7qWX5{ScS1jqJ-$)Omqbp>|xSS#4EUL1Bc95bh z;}2x>2joF6ukEzuM-u%rM<|7wiee~SUw$H($4&=dcRB1#E&@G;&j-&uVQ8FCwwPLA$zSf6N({-1BzLb_Ic_+o99>)4ghjuw#q_r4g) ziDFPI`gI3jEgz$L@F3vdtA&2)HK}MQikI>(`BsXtrxuvTo^g#Fi4dYAMCSfeaV@T} z4R?O9C$qS{`x~69&5M>WRBj4RRN~(`80MU^Ry%|$_LE0Q*z?0ren_s-kz5rN1QjkG zYCr^8?pFm8fZ)QO5?iTDI?hhDlQO*3o0lTtdaG+H+l^a@?KV+86hQ@D0dDl%B%Fjj z^|KD#Uty!!y;>JfUKpwI^#StE^wu=1?qP)5ZR1VPO7erV95v&=OWxe`sk2n(Of_{8 ziPb=Z;)__cV~DBopkKq$;0YVaP&k2r=uVYm#~<|p8=uK+*S_9fg4YWY)WHt4R)Kt` z#I^xSQ#GMY*dd#l23=2PY3N0IN|#=mS~$LDkl`WCd{2wq7k*c7fX+x`@2)YBMsS!F z?RSkecXQq?zWBVZwt%m&RsOnNv5DwA-*5LKSbL9xUbZ!KoOnL)B<2)>-3S^FH?XHt zh&D%0bVFW;#zPHMk`(a0e(Q@j4}Sa`$ea<&jEoxwB$ET>+c$L`(1*a3qWR&*d+)LB zBuCxy4pj&g28zgvV#~*XeAvzMGT^w_=+LPJ1%5TA z7x}d5F+{?du?owPL^A1Q#2cP0GmCnT;{nL_z{PfFh_ziTacynQvvM?7GkS{Iv%j^q z)suej&71KXir@X$K_}yCy7FWHZFjrw^7WpAe8~?-&4h0XUO4BN^}M80rAdkzX%Qp( zZt;LAeyKDVem~coms<#$sQTj2ab6Qmx+lTnzWIcOe=8e7iu*2(5DDGScFo5Sc`o*=~_g#e>_hZKG@<(tNI~Ig^7tHlOfx+DckmTd^y}>@zig> za`#cuyax{-E?bC)e^d!=(wM7qzneN6BbuG!Nl|raZ9#$MLvdw#&-B{=X2YVAbmmZ= zm}BAQX*vhyFh{Rq-!n?3YzGbS-K0hN$v3<;D=}^Z6>fHJ^w{FDDlqVy1Jnn99l5x- zw-s_yS+$z>C^qLs&j_ z$R#ar&nDdql$X5uA1b64Sl`=_%GVu|#AB`unY5Zowi;P`*>{6TWxF97RLwbDmGfeM zb8T^ZQeJohDD1y|2>Bp$444BYuBp$q24Acb=Q-n3xz%+rEw5t}3E?TZ)K<-Yzzsj! z<{=UAeEs|NWe|Kh^a_kI4O}Qj3Q5AbrWK-&7~+zVQ}%Ag8?F2mHq%4ToL@X@pOsVT zo^~x%^ZzJ1%djTfK8z0>2*@KNgn=jwiH$CaM+BtANsf{c(kU$<(n^Pfqtn4aTKa)e zO1FT3G)gL^bn{;CK5!5pIF5U}ulu_G=Xw54T#eumFYB8)5xQXc7c*WX0$}VKVlE}T zHj23>{N`gxqZ6?XIGslIZ;6G#fOrnhWA1=}03U1jGJ=(E1;`D)A30oJR^mGVC*_Kk zQ}F7NUd!B>9@0%FF{Y3WP1T90%umvv(5>S|xGJD6#f2TYXq7ckUGacS0{J@*#`Y^@ z5a=4Lp{MM|1EnVfTs#)cYP20YGqWBRtMa2H&z8g3{n$rlpneO{A$3AQ&crjgTeGDxUFxRx+1dgDXAesy{V_7C zT@{b!Wlx|ajOL2pxJ8*Yytf?PIe4+8k3Q(N%`w=*WT2UPgCsgFRMC2pv7^PgPH9yW z+#OK%-N)WTc{i*?wizH~GZN@uKlQk@s6K!PhXYEl_sN3u(U=U=R@1|D4pqFxeaenZ zou7FPRBA)v&lDb8$Wa4}q9vO`>MD>Q!9>Nhf{Sxt?wf|Oob$?kG`RlEw2nimi@T4dtMkL8P z910D>dAL>a+7ETJReg86)4=)c)iqDBcHT>pV!e5G@ecVEg`u8rfRVn@!U{3+m3gY6 zUZq%q0FKw*W+n!F%+;1HjZ5{TJHOcF<#YdpTbRRf)79(ALfN2msL^3sdEqDm^yEC))240krAs_1N7$oU7F7w^$ATVskg-ftLyiO*<)i+RDmJC4r z=>I#VIL6$VvfUFgS=m`FuTGkZ_t%YAOJh-&uzm~X5piqlp^iNn6d~q5_Lti7TOLqS zB&8mH`DuX-I9r;r70LYs%qTn$7bT)G2BlV@kR&#in>N2b0Awqn;o;b_ctpYe@u!Cm zADk`k4KwGmkuzD)Mj-ld_UUutgG=H^AR(aBmlhO?3l&tPeoSPMayFp+q$?4RtbJoS z`wt_r_lqu)M@DQJ_e+)ZLn?ZoMJ_FG8JDPAmFlXcfeOWOaHt}ZU}Wz<{!W)7z~qCp z(Y$)>Y2yx_uf6K90tAe556=A^ikDD3f+<$})gDe$?_FP4HD>`N8tbwND$zS$XIox; z`B?ts=#?+zVZQ;iXRR=*;q3zWm#J0BYK8CGXrk+d8b=IlBnhxX8q)iM+Fv)6_u+BegaDpRs)E zorD>Xrqwo&f{?PJJOU$AzQjmdlgDE?qVRY4-29avnKU`~bGxOIuPNHR9NMXmYu_IE z$9G}p=MQa8&)q&la53i~KMsRhz;WhNPG5pBnrwh*z(CPV!nuY)B!0 zT&%@{se7n1wb_H%gIEi;&Mq#F#N}AL$P-6K;qReC!1;`dTw?X>LAqw=c^B!zRR%zs zWy!gmz+QHA_)&TAY2IvqRFBmCwxv;UAb@7h z+YF;8i_Mc=un}?1&V-a8aEdh#j6lgY3qEd-x%Z7H34=+|nB-U#KjwTl2rVjhor;JS;mbL+)! z##u%Nk!Gj$>^E2|{`M2SUFHLh{y978eEk>1b{dP~F$BW>L=W=Zt~v@;+(&Wc__U(0 z^fx#VafGV~ImRDGB&z*FIE)60$q&Q$hFMJPmedUr=$pjQV}X8BC|Lv@r+%?m)o5Z6 zYVYp}Kbz(@_dpvvTL0-(HjLJK6fM}OPbs2VO@mm;l*(&MeNQ8}5~JW?{e}j_ITU)u zNiD!K-8c&$jPa+F$2QbN50xO^8MxzD_ zOg_SpgsN$zb&d8kvP92B57IQ}1nedHm@@s6f&7?<(#<`H;cCZ>I!9urJ7~cL@fI(l zKgt>u87_&(qPY5?LDIIXn@vF20bIiSyrZOBDrhx9CaZjfh zlGPOpzz=W>2$+``1RgFj=!A-9bqTSv_ry?+8jvG0XIt0~&)$MUg5^vw0v!TQuLmhe zCJi^YA`ae-LsGd#ouA_L)$tf3#ep<;=?e-eovzmJ2W~M%xbjgXQ|nWHekCr9#?S*i zKPQJfkT}5BVY=WrYa+s{q_Gng_onabP+>V+3+=l?lG<-Cre7<3vS(iN=-!KGJZhBY7+DJ2EvmJyzF ztf)H}kue$d&u3LYc2^%WHZc`ww2mo?=YfUBe+(%tp&|=g1pd~5`rD^KDD%m-pymqD zM{B!->d5&AG=MQ?He?@X9 z8b3`0nJ<9wxFD3ta)G98vuplf#^*|YZ{7lw3i%f3u0n(PQ@L)KnQAVgy?}605`H&s|7-DG zmNmX%0z*m#F=A$j(tZ;U;plRw!KmVbEvYZe2T+-1#IY3)!trXmr`!Ox=)m1NR)G8s zJ3IYKCQd&>nEGO=T`_R|saUq?Ey97wJJOH)M95;Z(2j{42XFAJ6?-3ad3)xblmPC!HI(V`QGbqW3G{H zf+YB7|EhMtNN;s_@VvA7CE1@VM8-?_1p5ct_p>q@zdi_iL?IaSv@B$lgI=sk7sK2u zPbyDokE=pwyph$J3c16z?kZmYs_Ktm$ppj2=GSJrP`Pm@)o{yV`5P7^jV@nmItOM(MTe8>;k;n zO#-D{xg}$JN^x!h+h-skxI$5oN&BJc0VGo=O7_*xst;?ITm6EZGn@BW8BGgyzZwHz zjERv54~?ed-?n?B8x>utRM-PcZd#n zTCP1HLC=VDp}eza&0AZEt!LY3J1)-KhyJY_H1$VEX93?2E}ZL+5YpiJ&EzY%qxkF3 z4F;@DYNF$Z8X!n8LzLY5x(A>NNCKu8dQIw$XPPYcLs2miBo{%S%a`z~|6^jiNwODd zgk7~^R_2Qu{f)ss?0X$L2%dUD9=GQ()%^OT*nYaP=xI=Tr9{EExFul?F1gbGBBj6s zK5lYy(%ah`4T4}v`g@xHa=o9>k&^FctXdW0~_Tqp(k{8e5w$4}pxMCNWS^bNP#op#u0*I2@LM(XP1}%#$6vAkynW7VUFUv z!!^X|VQ5W@unLX{L_`i_Vzt*hOAK1~G?PFofL6aHP2>e4TXD8O9HK8Kyr%GqmB8uR!dD^I8=X{O=Zdn9L>z`O7%WV zkWVkJ>aisZa~+GKu7f0=Ma{y7sU1);l(mnzB-B+)$W;@cSbVik6-{1d8#QbKf7 zL}IA88H1=olloLq(XncM@i$Vc`IY*R$0I)EK~&WOZuUSUR(V=BQ@)Y>)NGr^gHWTC zhDitbR29i##H*oRq&1FwF;k509tSLPfKKZMC8S6xd_~vT(1TZ{Z6&u~%~1qZ zEAfh{?*Y7BLyN!P><|dhU0-`!r#CJhBRmLxy%TN@c(LZ`cc^}4f$sy?!_BE=)yJ0o zzhNgm%W$R@lTMS#IWP#wVjc_v$g5xV+|HR>qwg#Ds(t1v@vKbqiT#o#KS?W!0J9*W z2Fi_7j2@RXHS7e}CyQ+NCeM-O}dhqp}rwNI8jR@AB{BGe1s1A}+=Q83` z*)d)KpkVL%`uekr79;)|{qTz)KYj#9GCBcdlRz`=M5_zy`V zwuL;=l<|eyk#!WYZM*nvD`)n`!kW$K zC=?VTC?mNj1wzDou%8&G?f4V&FgA#X8LRt`D*}&l>THGfbR5>7XL<%wrX6nqU+lNB ztN(J20k0myu>I7HGM<7o?e4a7>)EOSdG{Jm!Iw0D7wGqbI+M9NJ%V+V+j=v@8`9Y3 zBiV4JuHS>b7M_izw~g)>I6LVX1Y`pwhDr|oEp2o3RD+b}=WaFXMu~BJQM&$wo`2Q6 zOdvTL?97k9*O*xIIh7_y`N6&JaaN&uxiI92m*X|NSMBqG4-Jz|?6bdPjqdt~mc%nB zB&0!#wUE8#_AFDJwyGJn>3@ZmZuH6p(bQCmg4zC?&?pA@6PQ~#!WypD$Hp)Jzo0tJ1VOL_v&T+ z!;N$-AK4e)P!!UZJ;9loY9)xjo;{slN}4y(oys zyzyJsMQ`MdjUAjKJ70PDl!bgkUvpKtPxL{HaCqqG>lyOKIa-{9T0A#;fG0f7u4xa6P6zx*n7S=Hg4(`q# zM8|Yx10hRl116>m=fYTv)r$acU*F~#Cokew%YyU{I6o=~uRX~-lI3Z-T}EY@-iUqa zWTGcRP|IWK{tKI>ZW};^;*hq=Jm|KdAQdAN7hv-j*jsRev{e^u&;A)j1DF77XvB_u zJ}W4X_;vbQ^u{k*GO>5^a+q?c)c7 z&XO;V&ieZ|0N~=H9E{;W&oyx_AboDxxSSl4yAy5#Tr}-8awp608;fEE>dyS5P_#U& z_FhaW2JiPov`I^e$q}||mTHDqY?uMHj8x2F^|G!TM?|FGzTldx#UXQn5(6rXA(AFh zM=6+kYR%^vyY$#ZXj{GDM5_Bl7-Zm9^+X>_Ggd%cp>^iOKKt-&&ZZsLSZ7$40>aZ9 z2N=g&Z-(`4Nqf>0=l*})GH7#vk~Q|jpml+!ojt#%E1x0DeikqIcj-9B#i+ zl#k&c2oGPJWK5>4RiH+)9u$HOW661+HFIqSNNFr@6#ml$Fx04PGhj1}14Jq(06gh4 zJR?}#u%{?LkvFd!L2plUku}hm3%8U{E4&*CM&ARh_(EJr2mjCc9dM1K!O6MBmUE~1 zD1igPwOiiW{99<)=lfUV#pH?2b{_cC$ed3N&|UzNIt_|_9#4HU4A}m zH7MWV)@^NEz8JLl>Ed&?^B+9uie7*l8Q%L=2}bu}=V&;`-(qz8quRe)BeD8;XY}~} z;-dUE@c~Imf7j(OshcDuZ+Rfk_%~Lq3~Q1YeEw2VjcCf+GIh40++x1bn5VzzRjajo z!otsMSZlR;I#20vA54k@TuKG{M;{EMQ1WtWOJ2xY-qJ%6=XxE(anCUd)T#Y;cO=-u zJfdQ1ruhsfa7wL(qr$|m_TLZZ>z0fwP*qONpDr3~fVSgECF$Y!-WpW=eHgw_1*`jS zMGE+%8wE28-hJld!X?gw6-6ruM*$hqtj_>sQeZi61*~W12kIUizmLvfiUHqOeVk|N zkfn)HnBAciy`mZwr99wn!uAi$pKV%5st~8P>WMQYC6dF>Gvxv+8~*z*VDI!-A=^UB zYw3AsC$(smZ2rxQ>bySWJ8c+)$_;iB{vd$pVHbY9$<9G#<^y|mzRNXVck1D+ysZx* zUA7mo(QBWHtU7uZAzHdX6?mC z4bJq`i;8NX{U=X-8`lBH#LR&Hhy%}gN_UPJ-={Y0KLh0Eo$K~CYbBOscEZf%-ckR@ zRv6zCF6GM>X`(7ihyJDTUt`PEk)@irH0U>!B+Akfl=ha(U0ht8T_R3?89cw}eD1eX zvL>{>5E%bhq7GSHXWmg&p0bhG(Ztq;FST9s?_nIE2#QRLs1iaI98YN7S)2Oj;_K1d z+6iB|n~M5gJRGD^`}$$2i4a7n!fH&@az!)bzQ$SbV;C;l1F0^cTd3EM}_siGpY9 z>5b(c)E~Tu&T?^eb$038M$=Iog={=Z13F)u$Zf&_W+L|n`2gg0g8xzjr+MF7c(7`w z7cuszynMqx8!)Y!=bS3a%gHc*+_LASVpuIw!?rpz1~-`8TFE4Ha}xLBpMf$}$RoP1 zx!=%l%;@AvJ=j?bJKBPSqZ=Ri@62Csbz&;yAE-dyyL{9MJum#8*7KC^9*M=oXH+nq zxyJ#%^~6E1fQpCunl#Wj@AAY($bK&`384}UlU`*%QR0L$gq9CYxNCz`H26?Rbx#fF zJ+|Ts(c%!f!Id-u(!~eG#-#@qw>+QCwcO>}kwd^fyee`lb*Pzdp5>5zy*V?BHLMzV_>+e+?8J zfWC01VmuZU+>P`06S=75hye@T@IqkQAfYX86m)WHGF>2gA6?G*I*sY-acQd}oXnlH zRSAkQOXAe+Jsp_4*&GNZ6G@ZFWIa6wGSZvv5kW&I7v;nCTpUAtYD&}V@THTJlMDkF zQ^4`qi<6ZNy!<(y^4zr5$LH^E=jtx$g|5mrKWjyXuXkJ=W9&FU!|}!pNja0y?FnW= z@9iRfYCZ|>5#<{N({n#NPWhV(I0ezxtdo_;CKTKp=#wA4_Pl7vJV0#@74cEcRM;Q# zO@UHzS!=`(ZZ9^e3cqEfpvFA|Ao;`y(6Je!gfOJ~rT}46cnzVMKZJs5m?HZ-RQqc; z)~+HphNwDzX+i-n*{Y{pK2FpL6mkj?_wc%M!3NXaj((~Ho!(lM@ z*u@zTH=&D#!$2$gc_O?Sf&Uk|rf2vpkF)TruAUy2i%i(DEM`QcF<_kp4nrzCMl}{| zMJ)OanbTn=oc#U#bS3YIb;Cp3@W@gD9OiSlPc{@OkHb76&^@9^NX0~)`ODqBMqij3 zWQcNd`ehr3gi_hyFb<9=H?;lX2R0SSv%To(L9hOp3C0WImEfTkwjm+G0-q}7G`iU8 z{v^#YFFg=Ly&ODA!Z{E(&fKDuNJR?72Xy52qYqBAyzh!y{P~;J9k(Or7ap`x5OCD% zyJhircV%PC+576p1MeNV_>-P!1;?$dr#L7+kp-?mfs<0+mF>V)wTu?x=tAKkS_#tJ zH$_4gEtBtwu?utcS@tbnEZabY(QEFfUvuQOFaSBP<)f8aea(V`L6PbM|BFe9?#BRj z>1kr5Z*6~LEz3g#{UeKJ{=r(I{j`%82xOlHK*&*Cq-X>!l>VBI{;1kmJ`QweKo;Lr zPoM?D%`-EfLioR)2!}7O3RBbbWOsq807NBtCwRq-s=pTS_WeIxtHfX#uK>4v_wF6g zyzAGo+$`ayRB9qaIzpTs%Ys7B7o5wbPZo|>LGdgeSynlX)nN$5eX+By(MJpa^&;Mw z=R=i=V2TThGm7iFco9L;ow&R(k4M~luq@0U*{6Kf{4BKj9aa1>L!9RFKV`n$?*6g+ z^PETSq!++#6T35m-x$Tx>eMErpK)3vE4Jl)*6XFPe+WuYCt4OuimM%dc28A7ji5HKvE zX8dK=KQ98l|FgHU0!yQKgruZ1i9&Fpl+9xW#7Uv(35T+LkI&yZI*<4Jhruyvo_{(# zZvF`llnP5w>loGB78Z8%bf2j5<~Oyp+yyIpGVm(iOx2qS!D>;bh zz=0J!7(-c7t4p^)byv$OTaYAZ{0mlqj3SIxCBlaeAF8W>R>sZ$p1i3koW~x*$&UCG z(gUNUBQra!UP@)BgCTUxsY!>OU&@jOjbNT|qUG~(@*%jyBf;02s8uSODnDpiYHCnq z2#h5(MCSAnLipNH5>5%qKD&uhmQO~13WA@POjdXi=cM8guVHr4m|UwM{KuF&g}%jh zadog`?EMF@u0N|rJfZkBf#gbwR=(M@eq==X3|qa~xPmXqaA?>Br0yceGEPxjp#W|i z1*#7(Ji(h+R{6O5arAfrgLWD>cJdGCOE|*3};>JORYobwz!t-0k%n$k`F|kkA z8I|crdjU}*tqlN{MOm=qw zyjw@o7|`@$sS4iVs@|?4d2ydWAAb)Y|Ii3_DX8d#;3S_CaNfk-ZMG~sxqJ>VEkfB7 z>PMH?7tV)Vt`1K!fYI-^pFA*N{t+R*wTMBeK+WX)9*DiCL16kelj9>&-LGA9597v< zPdnV(T}5)Onk7jdlCQW%A1W`7 z7IuZiTi;kIGMsgcyGvoREPZ2{yt86E?dqADpFdc1j$bqdoMlo%lmrDn5Nm6Ul3#pQ z{Ij=txFn-K^p6MYYRN`3R4)w^RNAND@WVf~c@nMqs6N9#_q!*-qOHRx=TC5$^t)h{ zpGG-vDx-amH0Q7MJ-p;@ZN(SN9fsl%%B>A^$GwL4s00xC;_q|51kCKzolOFcQ+b^% ztwS2@r8%(^@8H03GZNOy?X4IiLePbmg>dUz%FQ{u3|9<2f8J!?+j^3<(CB?+u2 z%3mD0z(p4~F)?lQ*`D71+u&{rH3O=9tyeZ%SJll69h=2-eP$A?+lnsGfq!&n& zyAO54YU|W>9Lq%SR1|L%^OqDmq!$SC-OJan`ZTdD{csU%*DgS08xVJ1dw?cRfB(zX z!EQGH^X8q)&c||>e_egHx=kNdQH1??^IDc~OHw6@ej6$9-G~vr~ z$X!az8!%m4$<>Pdg7oQ;RO)#{-gA%#QsWagqFffI*5`*amr(l3f32?IMOLkByQ7)) z#(7B-=v=5mg5tl*mvqb|I0XS~jp)9CM^QL-$qhp@?t@?}SWpa=wlGFPm4ZJ=N#zGA z&mzMYR_I$s1w6zo5(#}uiPb7-FtWtS<0&9N99g`{O;?mTj4*oz33S4CgqTq}>uvkx zqH1|mQeWDUbG9Ni=84WN1>hJyJwLD^QjXC72>|EPV7l8*r6?_momqqD4<7`2`~`mv zsCS!ZE}48B-HG2|begPFpFyH%4ej-?OQ(0!r~rn}ej3#7WwWw*s;?BBoPrAom_H%-E+l(=@3318jS#!N>w!6;av+9Y>4OZ)=;J;y%is$Vw<_Cx&*Q@!t>S{pNef@g&{+xSdX$cz5 zesf3@bSA7#oy4pyY=QDHFX9Xc9Vxv??|K%^EGa}_kk)-_M<~0muH$WDfD4u24iTn) zD8jSaJDBHDpRv`#c4~iE-G6;sM#!iX7xF=7C2zw?;($TR2Rfmy&{-6I#HqP#5i&tPX)td@OdaT(8lt6Ly-J zm409(NCZQuj12Xg;WP8jrQcw42PY*L<7C9(0$Gi6QHzn{#yaE(QXWEvDJ~@?Rgq`F z7LD>+UWe7;dXaJGnEKx@7Yr_k<`Lq&KT3XY_MR;OG?2{MqNF^d&^)MIKQyOp{kPaYu-5-z z|Gwtm7gM^^aHoF!E@(`5_B#9FCCRnA;+7Zn8vaIP<#he~`p;DxUr$f5!@QjHO$F*q z3XW^JN8`Qc8fz9YigqOqmXYbhV5Na4T0V}`1wQ(&%rCYa^nqoF+sxQe``7g(D3tP~La z%bb-mF$Pf`Q(&pEFH5g$Xl#6aay~VlAVkq!4eZJ4Dm6$z8OsKVHWZ7zen^6e7OKwTh8Z* zR0bW~Dyp+vhwr`7j!yk*)*4D^UdJ1GH847lT#D6YHq|zymZJ$1p;97{g2a_^=SES@ zUs<}hd+#XK^y>OGkPU37!!76MUiAVSuRUv$u@&#$wH}o1`2G1@Ke0iN_Vcf{Cmv3X zRkU0g1Rm_JJY`axto57;YCCZ7bbtNY&o2g|J}2{^_s;(D@#kMtho?4^J0QvQfo;tv z)7Iv{mWIpa_c^W7t*JJ){h&n|VMX=Gksbx|3nQK;Iuc{_4|e1u@TK|jN(?q^{#G0o z8fhe?#takB=oR;!B~)}k8)Dhy#_0EP3j%=w0~^`&k9b6phKyZW2dVUoK_^2!>~GjL zT1pZ_4cq9^RE`3>7-{f&_@G)P>$!2$`R|f|g%o83Wb*MwacS6x)|Lj+AOO0-dhf_I zfzgm`OPqfWX8MIUb!m)j>whl=w@)kWQ`Cv^7$Ea!a-*QvjxORc7&JtfYqU$1fUN%l z^LNGGR>-!str=Vm&NR*(aZuxg1iwn>v3|;p!KQx+TWrp0-cu(s^~h_@QzMju@xm! z9tl<2{|sD~4rO3V>)hJ!PsY{`Ry#M(htx|p)qAK=D1#+vQTpcG>gg=|FSgc1C#BQ9 zQdr-bk(%pcF?cTHku4{&E;Z^)&1_*Lv?L=BG;uZBs8A65xemPZdkZI7|JV6n?+o=8 zJIxf_LehrTCgDUwKt4Cq!{g6qrU@2M*7%`TI=%_>4Rh}gD1Y7JhA_9qO_39jdKbyw=YrfF3$vQ70Y|ep-##ab{iP8iyV;!E>UME(bavhJ`qTc3 z%hSgFf9K=kf+$9Z_ezH4h<*osc9gx$6lLabjT!1b_SsYA#SJ>lvCciIaz&v# zyHxG1)QTL`^7lb7em-1SdkjpYvbhUu%BY_a9zO{DFW_kA`~2;XUSAmxs!I6C zlv@ddo$}Xajpm-~b*mUej*x-;zSN+?PX<-EDyRNN9&BtgFL5-P;61Mn4(BLpkymS> z@m;He#_@?yV@t4^-_U1LO;i3S)o}|l7rTcCC0iML=#OL0Q>hlLXBqZv5W#YnXT>3- zk1Y@e(c^y|JpF30<(iY-h2A?kce7Z>=iH~n^~SuSR~%|@$__2P06u2L<#mNWd!II1 zk9ID1uZ~-<qv*F9Mk>P^UJU+fGuiSk= z8QCGD@s4iAHCJt}ClIAY6)#W9oDW;gZ6~FZr$}JuW~36M)}^wtiM$?>#PKci{#$4~ zoqJ=EemtC;&6wi4FuBejF&*8gV88uJ{(k#x$OlIz^pk+-I4j7SF*=033diBNAxiyC zT5cFvKWnY^3ULKf*1x5wAi++P4khw!%iL^!hDq-;z(_Z9PqqNhuY;e-_=i37ZcdGp zk>tUtUF|de?T7!>Kdb9QTGmz-lo#h6?AkTIcD>qe2b=S_Ndh@)|L;hZGYi3rLY92N z3&b;jEp^9%#na`o%OzlM-Hus@Vk9NhbC0@BeQp(}m%ChG4?l&o(&x#q*~)1S%u3uB zyAfH3BrvEkSo|64Tns{mO6}*#+t(_0*~61YhkVzX1kg5h6T0dq`UKtdh?^hUB1Dhs zV?`#APN{$8UE~q@eJhi~F~FSQzu?POXfGw++ua*Zfi$KVlQCH^c99?g+0HyO%x!iD zOgX{uVTz`GsarGEt$s#`v450NeNJOqyaqFSO)kBqi6$bLj%vS zyh%{{#(=r64uUHERij;9su#l4OAPl!f&`)(U*JFmcNKp|BZ$40^Ofa8zNXD>o1jPR zxX1(>4@dIC)pa^y7Ev7D=ky3SU<#92Fg87350^__{c%B)E#v3P^IwA_uyolJ(T|Bs zueFO0f+ClH(IO#MYBw{(aTYfr*KAe+xYfIGV3LVqOuPWs+H6=t4f_dct*Fr^&J8uV%^ta!Hi4!9mCm;EdRQFO$_Tzn zrGOzxA##+(#3)*Ix~D^Ffa*V3ZqnvMGXCEO{^q}5`(Scp>JCQXZ++IU>h4EhPhAyq zN(tN<>ZmYKJ8!ROUF$!k@wmXJO6?1}+mW*A9*qTfT%P}udV#;)HFrOx7cGp=e!gk2 z0T%s;kTX<}Zh|u2E|w#AFyQ%wO{Ja9S~y_J7&?YZh|Yn$Q4fv`Gy|57M_g)n z;&eT~6kBVvnAioan}0uXTT9F<-<;^L6?QN1xmit<4T;g7RzSl*9gSEY|BSMcqzbAG z>Xu07`R>9+ZbaVy#>n0lP<^uBP7}DF68QIrX2AYbH=9XLE4k{` z-qp(0=8yL4CVH{N%j!5epUZIrV#Yti!FPbwk2oGgryT)B&Mte1o&Wy1dw8mk=dba< z*d6DQJ6nDnc#^ksN!$rI8orz*p8UNC7bYs87j^`*<<2(qaxRyzF9e?Uh6~AFEFX@S z_|ymc=rgcf>&FN_tt>w1ZIm_j>{lNDRwr1aXUEBiW#&qXXT8TkX%lKDe6Jdjqm@>T z

{PXdq;2yY`g7^x~vrN3i_STtIgf_wrk@M z)qLo;)DY~}XvLc$kMD&~MK zPuyjDpE2p`P;_#M(~Wi6l32O8F%~QOw4>=NG3aUzd^;J&J$a*r% zOEPjsV|M%OFJBy5wO?~s4NAdQydQZFG9>}z81UyT17Kf{;-8s+#|wb&BjsW|_RJjT zo?@SD+X+YzPaY=te~VX48IUR7e=&x` z-7AncCUn>0DDYvo5*@!UgSu@pQMsihe$qukW~P6S&Ds2zV)g+U!;MBN}*0Ok{r{M6UeJa%bdtnF_o4{)>>N?9SWU)ct@vzQA-bav7$`;F|(NymcttZZ@RH18vh=RBrKt#U@U?r6E$&lOAhY7#-o@fu?L zjp$k-MW%q0lPUP?m@=*puo!dtZD@XHcpl zTI{T+g;S0IqOuo0*sxMGJv(IhxeC8qriaS%Fd>V0w>Utd|7U&k^!ZGpbN|9QZH8$T zQP)LcZ#;mw1HQf4P}&ituB3x{WG zPv|6uf^1IDw_f+J2`m~Mzix$YXRI-A@zmqL2lPL0nSl~ejAgn?EuB<3=$+*~A6&0t z!WCPRn7#wLWy4)*P{Y^C=A)(anF3_`W|bzK@{sFlk&uy)@7L*yrkvj+TAjIEcgD#B z40^(dkiNZBS{u^mp!p0L0oFO(LLb(LZ@wJs`STEp)nWJ~WG|x)u8Ewkd~;!^Wc?-P z#YHsfB-k(l_zv2PR@;LRsy*!_ONOTVc zF~SPzE=ui#!0)uRcF?@uKXxAR<1q9&OGd0lbNtfhVZfd;^Xa9A-58<^ZwL@pxZw{_ z<*JjMc+4--F-q-@>9@zXO>IRCJrNg8ab+sLZd`xs%pV3pcaQc|hI9(FJDZuJ9xZ;W zI83u*m|Fd<+Y&uFE7ZnUYO!_ ztXe>-7LjG0>-o&Y=#E=Sl)*+W#A6E)-_6ul>0syZeb5mv*4@NKjiIT>J)Ub;80E+M z=_$M;oTTroF(1tjY1y1fkJ^wHk5ls{*Usd*XM0EsimVM!{SmLXfxML`Gv`Yyost)z zz~gUwxea9T9jrGJ6HumL^GNMyJ^oSxr>gq!M3KJn8IJc%)$awzc?@bn(fZU(qjDq=*i)*?XuT3jr;_|Cr<0=~2=~rIyxLjlnm`L-)XVKPuzAnIK^(uI75l`i z~`2<2Q22sJ02nV(-x-7mj_fW~z^ z@K`QVr<=?-|8i%Qh1}`WAh|cepp(O9sl2eh4EEf#5_Y)L9e@`$(LqOF8g;&;ZA_kD z92ce)|K=iD?6=U|Lxs3%a`d<3DOHqc! z6uX!fs&H_Su09z)_MJ4}N3!JEH}T^J+?Es`dC^SjwZ8A{WwMZUW%0NEzyci>)G7NG zGVW!?aZP+XCut46uRdQSrW1*@y}Nr$svRFVux8SkSY0!P*^oVJ@=3^bJ&UOR*0ou- zDU9fSwIjSQ2kNsij^%3pG0ST-@Rgkc zjG~Fl>iNg7Px_@fiQx?z-8(-z*v${6nCZVbnMg`D+Axj!GoyywWDYz@J-xk!@lTD6 zZ$7H|NQ)O`&fgTGa<9E^d{Co-!S;*q)BG-w^|edRX9AxI!JfTe7*huciKIB+iDeuq z*+3Gm$Y3lnzxQuhVt%&x_wu>+(l4)aejfH=e4hM5Z+Aqb#f@jeQ^RJYIPhF2CcMtQ z@LFjV)uTHDMRUXG{bL0jKY_;WKLrYJFZbD9f26G2R$lzzDH{P9$z2rMC?1auvA#g7 zF6qd;SkNM-cq|^cUZ!`Jl^Bd%?ZnNikynZ@O&mQn_oYhRuE>8~F`bzXgVr{rtDQ2= zyFcog85T`tlxG`4uTY(2PZ^ukb)3Hadc}2Z7@~_1iV7nRDCxO~Yerz3FuR%s7>82G zuaR47>KhQnztugQz&{(t%FSiWxUoQg3!`?irWUv415NIJUG8i99;^~(Sg&OiYLyv`V!NLt|pak?e1G$n#5+^=GXJ$2Q#{cW%%%VN>kTXy4jgKH_tkCh1(~`GKbr zWw?_y?hOOdIIk9!3uES*qjV5UViZZgwBvH4A-uDHB-4p#aednHz0b!&78`hLqrHp1D!L$$1YED59bF?(&^8S=WGM zeZzW9o6@Y#bhz&^KXvip2WlrxwsI`~Rq?*Y!!;`1mSGx^)bzkrJG@8?V&Rw4y>5il zyV~Df&{KCpG|`LbHOx z@I@#3lRUw-S_lV7!FJ{C@CxO)ds1cWbAK8JS`6>NfVhK?-N#X*Pml(%Tw;k8%0sP` z=UJAt(HlxN$4r9Q;3sMy3l_Jdcv!FIvhIMM=cstt9q_Q81@i#+KwGHS%D4RktnTU6 zhr%V8qi@q$x)Yb-I<6pL_RRKcs!ijRQe%Sdy{X>{^3*|Jf`*`U5)$8C^LJSgPmley z@h&ourytg*^QMp1r(Q=pAAkA6oxHeBZRvA+4S~%aK&TO9HxJ4${2EXu*C97foxj!- zdwSCJdoZ7V2a@4C4^JHV65q+c%aI+l4vjN}v|r7QdX`urOnG&o$yrCOf{u3k0l8wP zH!iS~Wj6nnv+^txFfE)ohqEbhQ2bJSkc*vG>%+T#W?U)Cilvr653fw*szTV1x!~hX z?PstC8j(U?nBJ)07S_P9EbqX@>1umKwz3Qdi+K-{xz)K~aZq7<*;BdLM4$^h3*$tC zmGFw}buMfiW4LBl_Vfsue?U(O(g-dW*!LGbAX4N`vH&K^SomGv2~&kMooI{?b~daX zA??<4$w2#^Bwnfp_H1bdBrFFmZ1|f>#^GdDT1|a^3hv~o)Ebw+-2~%EX{SH`g?9v~6Rq4EV%fux+P@0RzcDB92YF24*Cv;heYC_)?{X@E9B}jqEyzx zTUcMQC<8e&(9GzfJHUZxe35xqojx7R@*?I*@Ylj@Hp0#ndh=sZwQ~# zQE@@Q=H_U61pkdrzWKpN5s0o<=o5F2INb&_YSp8m@>IQ_Tf5k{o!n!d3k}+d9p+iQ zhF)O3rHnzB7Rl495ww4_4{^F!SJN&{wyBRsv&*#mD*8=}P!m#!;C3vWx^ul)iO!cv zM{m|WM7z?oOL3*#Ws0jZF&#^3n4Z&#;)$(iQpwKWK9{-PToh}1yhJ%u(3(0@ss}>1 zy5~jUOCqE*^TOm4r6^_`IiCnto_iA>cEUANOfQr5EkVyF%LA00*~Fi5rT`AJX$Nh! zr;XEgpm}ha=`MKtSvBvwfpwdR$OI%bYoOSE7rlddx-I-%ib&M zG?DLcE$R+Hn33V5#$i_~xv}zma1Y`^c4%9=KQbSp!BZ24v+BWWrKM zn{Wp>hd*?=RX|p>Fh@zn3MQ3;w2TcejdVGM1$X6)l!qxzw`z9UgD=9+k#AY(mGPqG z#lqq3VSKLd#fB1o?EmEy?caTKsY<|5>xsMhn;w1##1=k&5FpPY;g_kEYS}So>^gTd zDw4xu^Ig|;+0Jl#s5yN>XYOT(NB&=(qgwGb>JV~-Qk)G+uiBNCJ`v&?%7or2^&ndk z1rG`?Q%VstE6e|>zAsV^rxYQ=C<#}%rC9H(_%CsExY{f<7&MBjU{=LFWh^%+TuIVq z>&!4Lk~~S{?kP;l_lI`fviNU=A{L6{$@DR6l)WADD0FIG4dumo8X5brA@B8b~zw3BGPSc z^j=rR61?q9E6G#-YYo}s{k*z8(^>6p&9)7-?dS9Ho8iYMc_`3&XeW$?&~&`aNz7WO zq$8Kpt*G0F-$ztKVSslx(2FYdA}h@xsgb>{{FY!14>rCyb@3Nb4O@9;5O~XoVxBU9 z{)n7XOIM#5Y;OEWqh-2{-l`l_O&U8cl(~P2!%!-B0Jb-Z58Dp4+SG@INpr$RUmoJcFU_+Td32QDZTnu#9r0CkJh0|xBhQRUnqW(7tDo}sU&RDZvjkU;xm&C+ct>vepVV7cC5*jDS6FV`wy=gCz(|NR%f0;(& znGvErr`qM>uW%8flQ@}VXzhc`z&v*udzrPC&v;ti^>iiJZ_gGKA~g}B__c28O&&M5 z_j4?k{^~=sjFk%VU7CsArAn7IwUDjdQmAK#0_s%-s^v!9ys6=b(+dNT7Dkfk*3Eh} zg2Px>nlb01>wZ!PkUt5zUz8Le*K=2@cu6dq_d7D z2|mgm{JP1PSU5(SCn!?nSJXK54*bXJ?3kCiTR}_c#Kg;ryh@t$wK_!|bb*rnX&ej1 zE$`vg&l|;=oPOO|v$q@0^l}zIU;41eJYtpekpDdzl-|XH;?9N1kzrXaYB_FHQXbfU zdfJi_pFN~X!I?;|ii@EnvkUdS z?qBVTP6}Ty2_r?VvHqx^b*mIqCcJ1AWN-cm(bbD}@0ht92@xCIH5(`2fn4`O~5E1@$jtNYP40zcy2u`^mg&Sw5Z}hRn|rVVLw_fk`&%he1PS3~ zy*@H0DfzH9;&xSLEUwUER2@Uq6hJIrl=ufdu<>o0`q+t<%( zoK3@T02&3c)k?1A+NCODmoKcyPr=NOwT4HL*_p(#{x<7d*JS2H)9#rsC$|Dmi1qUX z$KH_?CI`qITcwW6q^yWyJ=$k{hf8p4xB3H`x%cOzMCzC0c)!Wf$nxoE{+Buy8SB1~ z#oV4CXW7uU->z4c!@}`8lbf!Y&2k|FZDoH$3lZfxq$qCqT4E5iBOiX~fVhaFAvPD+ zKh4>)CwFHG)4PRl1*Mojvy2O3+C91huuvIh=SEKj9OYiUn)vL`yy9im)c~d-$4JOwv_fb-13W67#1q))X5Jn9p?T;|1GZ z^!>*tU%=v_UZ97f2 -In the [last lesson](iot.md), you sent sensor data halfway around the world—through WiFi, across the internet, and up to a cloud dashboard. But what if you just want to talk to the laptop sitting right in front of you—without a USB cable? What if you could run the same Python scripts and p5.js sketches from the [Communication module](../communication/serial-intro.md), but wirelessly? +In the [last lesson](iot.md), you transmitted sensor data through WiFi, across the internet, and up to a cloud dashboard. But what if you just want to communicate with the laptop sitting right in front of you—**without a USB cable**? What if you could run the same Python scripts and p5.js sketches from the [Communication module](../communication/serial-intro.md), but wirelessly? -In this lesson, we'll do exactly that using **Bluetooth**. And here's the fun part: the code on your computer is going to be *identical*. Bluetooth Classic's Serial Port Profile (SPP) creates a **virtual serial port** on your computer that looks and behaves exactly like a USB serial connection. Your Python scripts, your p5.js sketches, your [serial.js](https://github.com/makeabilitylab/js/blob/main/src/lib/serial/serial.js) library—they all work unchanged. The only difference is which port you select. ✨ - -{: .warning } -> **This lesson requires the original ESP32** (like the Adafruit Huzzah32), **not** the ESP32-S3. The ESP32-S3 does not have the hardware for Bluetooth Classic—the `BluetoothSerial` library will not compile on it. If you only have an ESP32-S3, you can borrow a Huzzah32 from the equipment cart, or skip ahead to [Lesson 9: Bluetooth Low Energy](ble.md), which works with both boards. We'll explain why this limitation exists in the [next section](#what-is-bluetooth). - -Apple does not allow third-party apps to use Bluetooth Classic SPP on iOS, so **iPhones cannot connect to the ESP32 over Bluetooth Classic**. This lesson is entirely computer-based (Mac and Windows), so your phone type doesn't matter for Parts 1–4. If you have an **Android** phone, there's an optional bonus activity at the end. In [Lesson 9: BLE](ble.md), we'll use a protocol that works with *everyone's* phone—including iPhones. +In this lesson, we'll do exactly that using **Bluetooth**. And here's the fun part: the code on your computer is going to be *identical*. Bluetooth Classic's Serial Port Profile (SPP) creates a **virtual serial port** on your computer that looks and behaves exactly like a tethered USB serial connection. Your Python scripts, your p5.js sketches, your [serial.js](https://github.com/makeabilitylab/js/blob/main/src/lib/serial/serial.js) library—they all work unchanged. The only difference is which port you select. ✨ {: .note } > **In this lesson, you will learn:** @@ -69,11 +64,11 @@ Apple does not allow third-party apps to use Bluetooth Classic SPP on iOS, so ** ## What is Bluetooth? -Bluetooth is a short-range wireless communication standard for exchanging data between devices over radio waves. It operates in the 2.4 GHz ISM band (the same frequency range as WiFi and your microwave oven) and is designed for low-power, close-range connections—typically within about 10 meters indoors. +**Bluetooth is a short-range wireless communication** standard for exchanging data between devices over radio waves. It operates in the 2.4 GHz ISM band (the same frequency range as WiFi and your microwave oven) and is designed for low-power, close-range connections—typically within about 10 meters indoors. ### A brief history -Bluetooth was developed in the 1990s by [Ericsson](https://en.wikipedia.org/wiki/Ericsson) as a wireless replacement for RS-232 serial cables (the same serial communication we studied in [Lesson 1 of the Communication module](../communication/serial-intro.md)!). The name comes from [Harald Bluetooth](https://en.wikipedia.org/wiki/Harald_Bluetooth), a 10th-century Danish king who united warring Scandinavian tribes—a fitting metaphor for a technology designed to unite different devices. The Bluetooth logo is a [bind rune](https://en.wikipedia.org/wiki/Bind_rune) merging Harald's initials in [Younger Futhark](https://en.wikipedia.org/wiki/Younger_Futhark): ᚼ (Hagall, "H") and ᛒ (Bjarkan, "B"). +Bluetooth was developed in the 1990s by [Ericsson](https://en.wikipedia.org/wiki/Ericsson) as a wireless replacement for RS-232 serial cables (the same serial communication we studied in [Lesson 1 of the Communication module](../communication/serial-intro.md)!). The name comes from [Harald Bluetooth](https://en.wikipedia.org/wiki/Harald_Bluetooth), a 10th-century Danish king who united warring Scandinavian tribes—a fitting metaphor for a technology designed to unite different devices. The Bluetooth logo is a [bind rune](https://en.wikipedia.org/wiki/Bind_rune) merging Harald's initials in a runic alphabet called [Younger Futhark](https://en.wikipedia.org/wiki/Younger_Futhark): ᚼ (Hagall, "H") and ᛒ (Bjarkan, "B"). @@ -81,9 +76,9 @@ Bluetooth was developed in the 1990s by [Ericsson](https://en.wikipedia.org/wiki When people say "Bluetooth," they might mean one of **two fundamentally different protocols** that happen to share a name: -**Bluetooth Classic** (also called BR/EDR, for "Basic Rate / Enhanced Data Rate") is the original Bluetooth. It was designed for **continuous data streaming**—wireless headphones, file transfers, or serial port emulation. It establishes a persistent connection and can push data at up to 3 Mbps at the radio level, though practical throughput for the Serial Port Profile is much lower (typically a few hundred kbps). This is the flavor we'll use in this lesson. +- **Bluetooth Classic** (also called BR/EDR, for "Basic Rate / Enhanced Data Rate") is the original Bluetooth. It was designed for **continuous data streaming**—wireless headphones, file transfers, or serial port emulation. It establishes a persistent connection and can push data at up to 3 Mbps at the radio level, though practical throughput for the Serial Port Profile is much lower (typically a few hundred kbps). This is the flavor we'll use in this lesson. -**Bluetooth Low Energy** (BLE, introduced in Bluetooth 4.0 in 2010) is a completely different protocol stack designed for **low-power, intermittent data exchange**—fitness trackers that run for months on a coin cell, sensors broadcasting a reading every few seconds. We'll cover BLE in [Lesson 9](ble.md). +- **Bluetooth Low Energy** (BLE, introduced in Bluetooth 4.0 in 2010) is a completely different protocol stack designed for **low-power, intermittent data exchange**—fitness trackers that run for months on a coin cell, sensors broadcasting a reading every few seconds. We'll cover BLE in [Lesson 9](ble.md). Despite sharing the "Bluetooth" name, Classic and BLE are **not compatible with each other**. A BLE-only device cannot talk to a Bluetooth Classic device and vice versa. The original ESP32 supports **both**; the ESP32-S3 supports **BLE only**. @@ -105,12 +100,18 @@ Despite sharing the "Bluetooth" name, Classic and BLE are **not compatible with **Table.** Comparison of Bluetooth Classic and Bluetooth Low Energy. The original ESP32 supports both, but the ESP32-S3 only supports BLE. {: .fs-1 } +## Is Bluetooth Classic Still Used? + +Yes! Despite being over two decades old, Bluetooth Classic remains the dominant wireless audio protocol today. Every pair of wireless headphones you've likely used—Apple AirPods, Sony WH-1000XM series, Bose QuietComfort, JBL speakers—streams music over [A2DP](https://en.wikipedia.org/wiki/List_of_Bluetooth_profiles#Advanced_Audio_Distribution_Profile_(A2DP)), a Bluetooth Classic profile. Moreover, Bluetooth keyboards, mice, and game controllers also typically use [Classic's HID profile](https://en.wikipedia.org/wiki/List_of_Bluetooth_profiles#Human_Interface_Device_Profile_(HID)). Many modern devices are actually "dual-mode": AirPods, for example, stream audio over Bluetooth Classic while simultaneously using BLE for Apple's Find My network and proximity pairing. + +That said, Bluetooth Classic's expected replacement is underway—LE Audio (introduced in Bluetooth 5.2) brings a new, more efficient audio codec (LC3) and features like [Auracast broadcast audio](https://www.bluetooth.com/auracast/), and most new devices now ship as dual-mode during the transition. + {: .note } -> **Why doesn't the ESP32-S3 support Bluetooth Classic?** Espressif designed the ESP32-S3 for IoT and edge AI workloads where BLE's low power consumption matters more than Classic's streaming capabilities. Dropping the Classic radio reduces die area, power consumption, and cost. If you try to compile a `BluetoothSerial` sketch on the ESP32-S3, you'll get the error: `Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.` This is a chip-level limitation, not a software bug. +> **Why doesn't the ESP32-S3 support Bluetooth Classic?** Espressif designed the ESP32-S3 for IoT and edge AI workloads where BLE's low power consumption matters more than Classic's streaming capabilities. Dropping the Classic radio reduces the hardware die area, power consumption, and cost. If you try to compile a `BluetoothSerial` sketch on the ESP32-S3, you'll get the error: `Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.` This is a chip-level limitation, not a software bug. ## The Serial Port Profile (SPP) -So how does Bluetooth Classic act like a serial cable? Through something called the **Serial Port Profile (SPP)**. SPP emulates a wired RS-232 serial port—exactly the kind of serial communication we've been doing over USB. +One very cool and useful aspect of Bluetooth Classic is that we can make it act just like a serial cable, so all of our [Serial Communication lessons](../communication/) are relevant. This is done via the **[Serial Port Profile (SPP)](https://www.bluetooth.com/specifications/specs/html/?src=SPP_v1.2/out/en/index-en.html)**, which emulates a wired RS-232 serial port—exactly the kind of serial communication we've been doing over USB. When you pair the ESP32 with your computer over Bluetooth Classic, your operating system creates a **virtual serial port**—a COM port on Windows (*e.g.,* `COM8`) or a `/dev/tty.*` device on macOS (*e.g.,* `/dev/tty.ESP32-Bluetooth`). This virtual port behaves *identically* to the USB serial port you've been using all along. Any software that can open a serial port—the Arduino Serial Monitor, a Python script with [pySerial](https://pyserial.readthedocs.io/), a web browser using the [Web Serial API](../communication/web-serial.md), your [serial.js](https://github.com/makeabilitylab/js/blob/main/src/lib/serial/serial.js) library—can communicate over Bluetooth without any code changes. Just select the Bluetooth port instead of the USB port. @@ -119,7 +120,7 @@ When you pair the ESP32 with your computer over Bluetooth Classic, your operatin Bluetooth Serial: ESP32 → [radio] → Computer → COM8 → pySerial / serial.js Emphasize: same code, same libraries, different port --> -This is the key insight of this lesson: **Bluetooth Classic SPP is a wireless serial cable.** Everything you learned in the [Communication module](../communication/serial-intro.md)—data framing, parsing comma-separated values, serial.js—works unchanged. The only difference is the transport: radio waves instead of copper wire. +This is a key insight of this lesson: **Bluetooth Classic SPP is a wireless serial cable.** So, everything you learned in the [Communication module](../communication/serial-intro.md)—data framing, parsing comma-separated values, serial.js—works unchanged. The only difference is the transport: radio waves instead of copper wire.

How SPP works under the hood (click to expand) @@ -128,22 +129,30 @@ SPP sits on top of several Bluetooth Classic protocol layers. At the bottom, the
+## Two Important Notes Before We Build + +Two important notes before we get started building: + +**This lesson requires the original ESP32** (like the [Adafruit Huzzah32](https://www.adafruit.com/product/3405) or [Espressif ESP32-DevKitC V4](https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32/esp32-devkitc/user_guide.html)), **not** the ESP32-S3. The ESP32-S3 does not have the hardware for Bluetooth Classic—the `BluetoothSerial` library will not compile on it. If you're taking one of our classes, you can borrow an ESP32 board from us. If you only have access to an ESP32-S3, skip ahead to [Lesson 9: Bluetooth Low Energy](ble.md), which works with both boards. We'll explain why this limitation exists in the [next section](#what-is-bluetooth). + +**Apple iPhones will not work. 😢** Apple does not allow third-party apps to use Bluetooth Classic SPP on iOS, so **iPhones cannot connect to the ESP32 over Bluetooth Classic**. This lesson is entirely computer-based (Mac and Windows), so your phone type doesn't matter for Parts 1–4. If you have an **Android** phone, there's an optional bonus activity at the end. In [Lesson 9: BLE](ble.md), we'll use a protocol that works with *everyone's* phone—including iPhones. + ## Materials You'll need the following components. This lesson uses the **original ESP32** ([Adafruit Huzzah32 ESP32 Feather](https://www.adafruit.com/product/3591)), not the ESP32-S3. | Breadboard | ESP32 | LED | Resistor | Potentiometer | | ---------- |:-----:|:-----:|:-----:|:-----:| -| ![Half-sized solderless breadboard]({{ site.baseurl }}/assets/images/Breadboard_Half.png) | ![Adafruit Huzzah32 ESP32 Feather board, top view](assets/images/AdafruitHuzzah32_200h.png) | ![Red 5mm LED]({{ site.baseurl }}/assets/images/RedLED_Fritzing.png) | ![220-ohm resistor, striped red-red-brown-gold]({{ site.baseurl }}/assets/images/Resistor220_Fritzing.png) | ![10kΩ rotary potentiometer]({{ site.baseurl }}/assets/images/Potentiometer_100h.png) | +| ![Half-sized solderless breadboard]({{ site.baseurl }}/assets/images/Breadboard_Half.png) | ![Adafruit Huzzah32 ESP32 Feather board, top view](/assets/images/ESP32Huzzah32_Adafruit_vertical_h200.png) | ![Red 5mm LED]({{ site.baseurl }}/assets/images/RedLED_Fritzing.png) | ![220-ohm resistor, striped red-red-brown-gold]({{ site.baseurl }}/assets/images/Resistor220_Fritzing.png) | ![10kΩ rotary potentiometer]({{ site.baseurl }}/assets/images/PanelMountPotentiometer_NoCap_150h.png) | | Breadboard | [Huzzah32 ESP32 Feather](https://www.adafruit.com/product/3591) | Red LED | 220Ω Resistor | 10kΩ Potentiometer | You will also need: - A **Mac or Windows computer** with Bluetooth (most modern laptops have Bluetooth built in) - **Python 3** with [pySerial](https://pyserial.readthedocs.io/) installed (`pip3 install pyserial`) -- **Google Chrome** or **Microsoft Edge** (for the Web Serial / p5.js activity) +- **Google Chrome** or **Microsoft Edge** (for the Web Serial / p5.js activity) similar to the [Web Serial lesson](../communication/web-serial.md) {: .note } -> If you only have an ESP32-S3, you can borrow a Huzzah32 from the equipment cart for this lesson, or skip ahead to [Lesson 9: Bluetooth Low Energy](ble.md), which works with the ESP32-S3. +> If you only have an ESP32-S3, you can skip ahead to [Lesson 9: Bluetooth Low Energy](ble.md). ## Part 1: Hello Bluetooth @@ -153,7 +162,7 @@ Let's cut the wire! In this first activity, we'll upload a Bluetooth serial sket The ESP32 Arduino core includes a built-in library called [`BluetoothSerial`](https://github.com/espressif/arduino-esp32/tree/master/libraries/BluetoothSerial) that handles all the Bluetooth Classic SPP complexity for you. No library installation is needed—just `#include "BluetoothSerial.h"` and you're ready to go. -The library's API was **intentionally designed to mirror** Arduino's built-in `Serial` class. It provides the same `.begin()`, `.available()`, `.read()`, `.write()`, `.print()`, and `.println()` methods you already know. This means converting a wired serial sketch to Bluetooth is as simple as creating a `BluetoothSerial` object and using it alongside (or instead of) `Serial`. The rest of your code stays identical. +The library's API was **intentionally designed to mirror** Arduino's built-in `Serial` class. It provides the same `.begin()`, `.available()`, `.read()`, `.write()`, `.print()`, and `.println()` methods you already know. This means converting a wired serial sketch to Bluetooth is as simple as creating a `BluetoothSerial` object and using it alongside (or instead of) `Serial`. The rest of your code stays identical! 🎉 | Method | `Serial` (USB) | `SerialBT` (Bluetooth) | Notes | |---|---|---|---| @@ -169,10 +178,10 @@ The library's API was **intentionally designed to mirror** Arduino's built-in `S **Table.** Key API comparison between Arduino's built-in `Serial` and the `BluetoothSerial` library. Every read/write method is identical — only initialization and connection management differ. {: .fs-1 } -The key difference is in `.begin()`: `Serial.begin()` takes a baud rate because it configures a physical UART, while `SerialBT.begin()` takes a *device name* because the Bluetooth stack handles data rates internally. The other difference is that Bluetooth connections can come and go — unlike a USB cable, a Bluetooth device might walk out of range — so `BluetoothSerial` adds `connected()` and `register_callback()` for connection state management. We'll use these in [Part 4](#part-4-bidirectional-control) when we discuss what happens when a connection drops. +The key difference is in `.begin()`: while the traditional `Serial.begin()` takes a baud rate because it configures a physical UART, `SerialBT.begin()` takes a *device name* because the Bluetooth stack handles data rates internally. The other difference is that Bluetooth connections can come and go—unlike a USB cable, a Bluetooth device might walk out of range—so `BluetoothSerial` adds `connected()` and `register_callback()` for connection state management. We'll use these in [Part 4](#part-4-bidirectional-control) when we discuss what happens when a connection drops. {: .warning } -> `BluetoothSerial` is **only available on the original ESP32 chip**. If you try to include it on an ESP32-S3 (or C3, S2, *etc.*), the sketch will not compile. The compile-time guards in our sketches below produce a clear error message when this happens. +> Reminder: `BluetoothSerial` is **only available on the original ESP32 chip**. If you try to include it on an ESP32-S3 (or C3, S2, *etc.*), the sketch will not compile. The compile-time guards in our sketches below produce a clear error message when this happens. ### The Arduino code @@ -181,63 +190,52 @@ The key difference is in `.begin()`: `Serial.begin()` takes a baud rate because This sketch creates a bidirectional bridge between the USB serial connection (to your computer via USB) and a Bluetooth serial connection (to your computer via Bluetooth). Anything sent over Bluetooth arrives on USB serial and vice versa. The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/HelloBluetooth). ```cpp -/** - * HelloBluetooth: creates a bidirectional bridge between USB Serial - * and Bluetooth Serial (SPP). Sends a greeting over Bluetooth every - * 2 seconds. Data received over Bluetooth is echoed to USB Serial - * and vice versa. - * - * Requires: Original ESP32 (e.g., Huzzah32). Will NOT compile on ESP32-S3. - * - * See: https://makeabilitylab.github.io/physcomp/esp32/bluetooth-serial - * - * By Jon E. Froehlich - * @jonfroehlich - * http://makeabilitylab.io - */ - #include "BluetoothSerial.h" -// These compile-time checks ensure we're running on a chip that -// supports Bluetooth Classic. On the ESP32-S3 (or C3, S2, etc.), -// these #error lines will trigger and the sketch won't compile. -#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) -#error Bluetooth Classic is not enabled. This sketch requires the original ESP32. -#endif - -#if !defined(CONFIG_BT_SPP_ENABLED) -#error Serial Bluetooth (SPP) is not available. It is only supported on the original ESP32 chip. -#endif - BluetoothSerial SerialBT; unsigned long _lastGreetingMs = 0; +unsigned long _greetingCount = 0; const unsigned long GREETING_INTERVAL_MS = 2000; void setup() { Serial.begin(115200); - // Initialize Bluetooth with a device name. - // This is the name that appears when you scan for devices on your computer. + // Initialize Bluetooth with a device name. You can choose any name you + // like — "ESP32-Bluetooth", "Jon's ESP32", "Chewbacca", etc. This is the + // friendly name that appears when you scan for Bluetooth devices on your + // computer (pick something recognizable in a classroom full of ESP32s!). SerialBT.begin("ESP32-Bluetooth"); - Serial.println("Bluetooth device started! You can now pair with 'ESP32-Bluetooth'."); + + Serial.println("Bluetooth started! You can now pair with 'ESP32-Bluetooth'."); + Serial.println("Open a Bluetooth serial connection to see greetings."); + Serial.println("Anything you type here will be forwarded over Bluetooth (and vice versa).\n"); } void loop() { - // Periodically send a greeting over Bluetooth + // Periodic greeting unsigned long now = millis(); if (now - _lastGreetingMs >= GREETING_INTERVAL_MS) { _lastGreetingMs = now; - SerialBT.println("Hello from ESP32!"); + _greetingCount++; + + String msg = "Hello from ESP32! [Msg #" + String(_greetingCount) + + " | Uptime: " + String(now / 1000.0, 1) + "s]"; + + SerialBT.println("[Bluetooth] " + msgBase); // Send over Bluetooth + Serial.println("[USB Serial] " + msgBase); // Echo to USB Serial } - // Forward USB Serial → Bluetooth Serial - if (Serial.available()) { + // Forward everything received from Serial (e.g., typed in Serial Monitor) + // to the Bluetooth peer. We use read()/write() (byte-at-a-time) rather than + // readStringUntil() because it's non-blocking — the loop keeps running without + // waiting for a newline or timeout. + while (Serial.available()) { SerialBT.write(Serial.read()); } - // Forward Bluetooth Serial → USB Serial - if (SerialBT.available()) { + // Forward everything received over Bluetooth to Serial Monitor + while (SerialBT.available()) { Serial.write(SerialBT.read()); } } @@ -245,7 +243,7 @@ void loop() { Notice how the code reads like a standard serial sketch — compare the `SerialBT` calls with the `Serial` calls and you'll see the API mirroring from the [table above](#the-bluetoothserial-library) in action. The one difference is `SerialBT.begin("ESP32-Bluetooth")`: instead of a baud rate, it takes a device name that will appear when you scan for Bluetooth devices on your computer. -The `#if !defined(...)` compile-time guards at the top produce a clear error if you accidentally build this on an ESP32-S3 or other unsupported chip. +You can choose any name you like—"ESP32-Bluetooth", "MyPotentiometer", "Jon's ESP32", or even "Chewbacca". This is the friendly name that will appear in your computer's or phone's Bluetooth settings when scanning for nearby devices, so pick something recognizable (especially in a classroom full of ESP32s!). Upload this sketch to your ESP32 and open Serial Monitor at 115200 baud. You should see `"Bluetooth device started!"`. @@ -293,26 +291,49 @@ pip3 install pyserial You already have a Python serial demo from the [Communication module](../communication/serial-intro.md): [`serial_demo.py`](https://github.com/makeabilitylab/arduino/blob/master/Python/Serial/serial_demo.py). Let's use it over Bluetooth—the only change is the port name. -Open `serial_demo.py` and change the port to your Bluetooth serial port: +First, if you're not sure which serial ports are available, you can list them: -```python -# In serial_demo.py, change this line: -ser = serial.Serial(port='COM13', baudrate=115200, timeout=1) +~~~ +python3 serial_demo.py --list +~~~ -# To your Bluetooth port: -# macOS: -ser = serial.Serial(port='/dev/tty.ESP32-Bluetooth', baudrate=115200, timeout=1) -# Windows: -ser = serial.Serial(port='COM8', baudrate=115200, timeout=1) -``` +Then run the script with your Bluetooth serial port: -That's it—one line change. The rest of the script (reading, writing, encoding, decoding) is identical. Run it: +~~~ +# macOS +python3 serial_demo.py /dev/tty.ESP32-Bluetooth 115200 -``` -python3 serial_demo.py -``` +# Windows (Note use `python` instead of `python3` on Windows) +python serial_demo.py COM8 115200 +~~~ + +For example, on my Windows computer, if I run ``-list`, I get: + +~~~ +python serial_demo.py --list +Available serial ports: + COM1 - Communications Port (COM1) + COM4 - Silicon Labs CP210x USB to UART Bridge (COM4) +~~~ -You should see `"Hello from ESP32!"` messages arriving every 2 seconds. Type a number and press Enter—it will be sent to the ESP32 and forwarded to USB Serial Monitor. You're communicating wirelessly! 🎉 +After pairing with `"ESP32-Bluetooth"` (see [Pairing with your computer](#pairing-with-your-computer)), I ran `--list` again and see new ports: + +~~~ +python serial_demo.py --list +Available serial ports: + COM1 - Communications Port (COM1) + COM4 - Silicon Labs CP210x USB to UART Bridge (COM4) + COM16 - Standard Serial over Bluetooth link (COM16) + COM17 - Standard Serial over Bluetooth link (COM17) +~~~ + +COM4 is your **tethered USB serial connection** (the CP210x chip on the Huzzah32). COM16 and COM17 are Bluetooth serial ports—Windows creates two for each Bluetooth SPP pairing: one for outgoing and one for incoming connections. You typically want the first one listed, but if it doesn't work, try the other. Now connect: + +~~~ +python serial_demo.py COM16 115200 +~~~ + +That's it—same script, different port. The rest of the code (reading, writing, encoding, decoding) is identical. You should see `"[Bluetooth] Msg #1 | Uptime: 2.00s"` messages arriving every 2 seconds. Type a number and press Enter—it will be sent to the ESP32 and forwarded to USB Serial Monitor. You're communicating wirelessly! 🎉 {: .note } > **The baud rate parameter is ignored for Bluetooth virtual COM ports** on most operating systems. SPP negotiates its own data rate at the Bluetooth protocol level, so the `baudrate=115200` argument is passed to pySerial for API compatibility but doesn't actually set a baud rate the way it does for USB serial. You can pass any value and it will work—but we use `115200` to match our `Serial.begin(115200)` for consistency. @@ -333,6 +354,8 @@ You should see `"Hello from ESP32!"` messages arriving every 2 seconds. Type a n Include captions/transcript --> + + ## Part 2: Streaming sensor data Now let's stream live sensor data. We'll read a potentiometer and send its value over Bluetooth—then visualize it in Python. From c457a7887037f2e65e81f6e35ee7b75d7d4fd2a5 Mon Sep 17 00:00:00 2001 From: Jon Froehlich Date: Wed, 27 May 2026 10:44:12 -0700 Subject: [PATCH 12/19] Update ESP32 Bluetooth tutorial: verify via OS tools MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rework the Bluetooth Serial lesson to verify connectivity using built-in OS tools before introducing Python. The HelloBluetooth sketch now sends periodic greetings so users can confirm the sketch is running immediately. Replace the Python-first pairing flow with terminal-based verification (cat/screen on macOS/Linux and a PowerShell serial_reader for Windows), expand pairing/COM-port guidance, and add a comprehensive troubleshooting section. Also renumbered subsequent parts (Parts 3–6 → 2–6 shift) and cleaned up comments/formatting around the serial forwarding logic. --- esp32/bluetooth-serial.md | 267 ++++++++++++++++++++++++++++++-------- 1 file changed, 212 insertions(+), 55 deletions(-) diff --git a/esp32/bluetooth-serial.md b/esp32/bluetooth-serial.md index 796f756..fa2d0b2 100644 --- a/esp32/bluetooth-serial.md +++ b/esp32/bluetooth-serial.md @@ -156,7 +156,7 @@ You will also need: ## Part 1: Hello Bluetooth -Let's cut the wire! In this first activity, we'll upload a Bluetooth serial sketch to the ESP32, pair it with your computer, and communicate with it using a short Python script—the same approach you learned in the [serial introduction lesson](../communication/serial-intro.md), just wireless. +Let's cut the wire! In this first activity, we'll upload a Bluetooth serial sketch to the ESP32, pair it with your computer, and verify the connection using built-in OS tools—no Python, no dependencies, just your terminal. This way, if anything goes wrong, you'll know immediately whether it's a Bluetooth issue or a software issue. ### The BluetoothSerial library @@ -178,7 +178,7 @@ The library's API was **intentionally designed to mirror** Arduino's built-in `S **Table.** Key API comparison between Arduino's built-in `Serial` and the `BluetoothSerial` library. Every read/write method is identical — only initialization and connection management differ. {: .fs-1 } -The key difference is in `.begin()`: while the traditional `Serial.begin()` takes a baud rate because it configures a physical UART, `SerialBT.begin()` takes a *device name* because the Bluetooth stack handles data rates internally. The other difference is that Bluetooth connections can come and go—unlike a USB cable, a Bluetooth device might walk out of range—so `BluetoothSerial` adds `connected()` and `register_callback()` for connection state management. We'll use these in [Part 4](#part-4-bidirectional-control) when we discuss what happens when a connection drops. +The key difference is in `.begin()`: while the traditional `Serial.begin()` takes a baud rate because it configures a physical UART, `SerialBT.begin()` takes a *device name* because the Bluetooth stack handles data rates internally. The other difference is that Bluetooth connections can come and go—unlike a USB cable, a Bluetooth device might walk out of range—so `BluetoothSerial` adds `connected()` and `register_callback()` for connection state management. We'll use these in [Part 5](#part-5-bidirectional-control) when we discuss what happens when a connection drops. {: .warning } > Reminder: `BluetoothSerial` is **only available on the original ESP32 chip**. If you try to include it on an ESP32-S3 (or C3, S2, *etc.*), the sketch will not compile. The compile-time guards in our sketches below produce a clear error message when this happens. @@ -187,7 +187,7 @@ The key difference is in `.begin()`: while the traditional `Serial.begin()` take -This sketch creates a bidirectional bridge between the USB serial connection (to your computer via USB) and a Bluetooth serial connection (to your computer via Bluetooth). Anything sent over Bluetooth arrives on USB serial and vice versa. The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/HelloBluetooth). +This sketch creates a bidirectional bridge between the USB serial connection (to your computer via USB) and a Bluetooth serial connection (to your computer via Bluetooth). Anything sent over Bluetooth arrives on USB serial and vice versa. It also sends a periodic greeting so you can immediately see that data is flowing. The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/HelloBluetooth). ```cpp #include "BluetoothSerial.h" @@ -219,16 +219,16 @@ void loop() { _lastGreetingMs = now; _greetingCount++; - String msg = "Hello from ESP32! [Msg #" + String(_greetingCount) - + " | Uptime: " + String(now / 1000.0, 1) + "s]"; + String msgBase = "Msg #" + String(_greetingCount) + + " | Uptime: " + String(now / 1000.0, 1) + "s"; SerialBT.println("[Bluetooth] " + msgBase); // Send over Bluetooth Serial.println("[USB Serial] " + msgBase); // Echo to USB Serial } - // Forward everything received from Serial (e.g., typed in Serial Monitor) - // to the Bluetooth peer. We use read()/write() (byte-at-a-time) rather than - // readStringUntil() because it's non-blocking — the loop keeps running without + // Forward everything received from Serial (e.g., typed in Serial Monitor) + // to the Bluetooth peer. We use read()/write() (byte-at-a-time) rather than + // readStringUntil() because it's non-blocking — the loop keeps running without // waiting for a newline or timeout. while (Serial.available()) { SerialBT.write(Serial.read()); @@ -245,7 +245,15 @@ Notice how the code reads like a standard serial sketch — compare the `SerialB You can choose any name you like—"ESP32-Bluetooth", "MyPotentiometer", "Jon's ESP32", or even "Chewbacca". This is the friendly name that will appear in your computer's or phone's Bluetooth settings when scanning for nearby devices, so pick something recognizable (especially in a classroom full of ESP32s!). -Upload this sketch to your ESP32 and open Serial Monitor at 115200 baud. You should see `"Bluetooth device started!"`. +Upload this sketch to your ESP32 and open Serial Monitor at 115200 baud. You should see greeting messages appearing every 2 seconds, prefixed with `[USB Serial]`: + +``` +[USB Serial] Msg #1 | Uptime: 2.0s +[USB Serial] Msg #2 | Uptime: 4.0s +[USB Serial] Msg #3 | Uptime: 6.0s +``` + +This confirms the sketch is running. Now let's pair and see those messages arrive wirelessly. ### Pairing with your computer @@ -262,7 +270,7 @@ Before you can communicate over Bluetooth, you need to **pair** your computer wi ls /dev/tty.*Bluetooth* ``` -You should see something like `/dev/tty.ESP32-Bluetooth` or `/dev/tty.ESP32-BluetoothSPP`. This is your Bluetooth serial port—you'll use it in the Python script below. +You should see something like `/dev/tty.ESP32-Bluetooth` or `/dev/tty.ESP32-BluetoothSPP`. This is your Bluetooth serial port. @@ -279,84 +287,233 @@ You should see something like `/dev/tty.ESP32-Bluetooth` or `/dev/tty.ESP32-Blue {: .note } -> **Windows creates two COM ports** for Bluetooth serial: one for outgoing and one for incoming connections. You typically want the **outgoing** port. If one doesn't work, try the other. You can see which is which in **Control Panel → Devices and Printers → right-click ESP32-Bluetooth → Properties → Services**. +> **Windows creates two COM ports** for each Bluetooth SPP pairing: one for outgoing and one for incoming connections. You want the **outgoing** port—this is the one that actually initiates the SPP data channel. If one connects but shows no data, try the other. You can check which is which in **Control Panel → Devices and Printers → right-click ESP32-Bluetooth → Properties → Services**. -### Connecting with Python +### Verifying the connection -Now let's connect to the Bluetooth serial port from Python—using the same [pySerial](https://pyserial.readthedocs.io/) library you used in the [serial introduction lesson](../communication/serial-intro.md). If you don't have it installed yet: +Now let's verify that data is actually flowing over Bluetooth. We'll use built-in OS tools—no Python, no installs—so if something goes wrong, you'll know immediately that it's a Bluetooth issue, not a software setup issue. +#### macOS / Linux + +Open **Terminal** and run: + +```bash +cat /dev/tty.ESP32-Bluetooth ``` -pip3 install pyserial + +Replace the port name with whatever `ls /dev/tty.*Bluetooth*` showed you. You should immediately see greetings streaming in: + +``` +[Bluetooth] Msg #1 | Uptime: 2.0s +[Bluetooth] Msg #2 | Uptime: 4.0s +[Bluetooth] Msg #3 | Uptime: 6.0s ``` -You already have a Python serial demo from the [Communication module](../communication/serial-intro.md): [`serial_demo.py`](https://github.com/makeabilitylab/arduino/blob/master/Python/Serial/serial_demo.py). Let's use it over Bluetooth—the only change is the port name. +Press **Ctrl+C** to stop. -First, if you're not sure which serial ports are available, you can list them: +{: .note } +> You can also use `screen`, which provides a more interactive serial terminal: +> ```bash +> screen /dev/tty.ESP32-Bluetooth 115200 +> ``` +> In `screen`, you can type characters that will be forwarded to the ESP32. To exit `screen`, press **Ctrl+A** then **K**, then confirm with **y**. -~~~ -python3 serial_demo.py --list -~~~ +#### Windows -Then run the script with your Bluetooth serial port: +We provide a PowerShell script called [`serial_reader.ps1`](https://github.com/makeabilitylab/arduino/blob/master/PowerShell/serial_reader.ps1) that reads from a COM port with zero dependencies. Download it and run: -~~~ -# macOS -python3 serial_demo.py /dev/tty.ESP32-Bluetooth 115200 +```powershell +# List available COM ports +.\serial_reader.ps1 -# Windows (Note use `python` instead of `python3` on Windows) -python serial_demo.py COM8 115200 -~~~ +# Connect to the Bluetooth COM port +.\serial_reader.ps1 -Port COM16 +``` -For example, on my Windows computer, if I run ``-list`, I get: +{: .note } +> If you get an execution policy error, run this once first: +> ```powershell +> Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned +> ``` -~~~ -python serial_demo.py --list -Available serial ports: - COM1 - Communications Port (COM1) - COM4 - Silicon Labs CP210x USB to UART Bridge (COM4) -~~~ +You should see messages streaming in: + +``` +Connected! Listening for data... + +[Bluetooth] Msg #1 | Uptime: 2.0s +[Bluetooth] Msg #2 | Uptime: 4.0s +[Bluetooth] Msg #3 | Uptime: 6.0s +``` + +Press **Ctrl+C** to stop. + +**If you see messages, congratulations—you're communicating wirelessly! 🎉** The ESP32 is sending data over Bluetooth, your computer is receiving it through a virtual serial port, and no USB cable was involved. This is the core magic of SPP. + +{: .warning } +> **Only one program can open a serial port at a time.** If you have Arduino's Serial Monitor open on the Bluetooth COM port, `cat`/`screen`/PowerShell won't be able to connect (and vice versa). Close Serial Monitor before trying the terminal commands—or keep Serial Monitor on the *USB* port (COM4) and use the terminal on the *Bluetooth* port. This is the same constraint from the [serial introduction](../communication/serial-intro.md#only-one-computer-program-can-open-a-serial-port-at-a-time), just with two ports to manage. + +**If you don't see any data**, see the [Troubleshooting Bluetooth connections](#troubleshooting-bluetooth-connections) section below before moving on. + +### Workbench demo of Bluetooth terminal programs + + + + + +## Part 2: Connecting with Python + +Now that you've verified Bluetooth is working, let's connect from Python—using the same [pySerial](https://pyserial.readthedocs.io/) library you used in the [serial introduction lesson](../communication/serial-intro.md). This is where SPP really shines: your existing Python serial code works over Bluetooth with only a port name change. + +### Setting up pySerial + +If you don't already have pySerial installed, you'll need to install it. The recommended approach is to use a **virtual environment**, which keeps your project's dependencies isolated from your system Python: + +```bash +# Create a virtual environment (one-time setup) +python3 -m venv venv + +# Activate it +# macOS / Linux: +source venv/bin/activate +# Windows: +venv\Scripts\activate + +# Install pySerial +pip install pyserial +``` + +Once activated, you'll see `(venv)` at the beginning of your terminal prompt. You'll need to run the `activate` command each time you open a new terminal window to work on this project. + +{: .note } +> **Why a virtual environment?** Modern macOS (via Homebrew) and some Linux distributions block global `pip install` commands to protect system Python ([PEP 668](https://peps.python.org/pep-0668/)). You'll see an `externally-managed-environment` error if you try `pip install pyserial` without a venv. A virtual environment solves this cleanly and is good practice for any Python project. + +{: .note } +> **Windows users:** Use `python` instead of `python3` throughout this lesson. On Windows, the `python3` command often triggers a misleading Microsoft Store redirect instead of running Python. On macOS and Linux, either `python` or `python3` works, but `python3` is the safer choice to avoid accidentally invoking Python 2 on older systems. + +### Reading Bluetooth data with serial_reader.py + +We provide a simple Python script called [`serial_reader.py`](https://github.com/makeabilitylab/arduino/tree/master/Python/SerialReader) that connects to a serial port and prints whatever data arrives. It's the Python equivalent of the `cat` or PowerShell commands you just used—but now you're using pySerial, the same library you'll use for more sophisticated projects. + +First, list available ports to find your Bluetooth serial port: -After pairing with `"ESP32-Bluetooth"` (see [Pairing with your computer](#pairing-with-your-computer)), I ran `--list` again and see new ports: +``` +# macOS / Linux +python3 serial_reader.py --list + +# Windows +python serial_reader.py --list +``` -~~~ -python serial_demo.py --list +On Windows, you should see something like: + +``` Available serial ports: COM1 - Communications Port (COM1) COM4 - Silicon Labs CP210x USB to UART Bridge (COM4) COM16 - Standard Serial over Bluetooth link (COM16) COM17 - Standard Serial over Bluetooth link (COM17) -~~~ +``` -COM4 is your **tethered USB serial connection** (the CP210x chip on the Huzzah32). COM16 and COM17 are Bluetooth serial ports—Windows creates two for each Bluetooth SPP pairing: one for outgoing and one for incoming connections. You typically want the first one listed, but if it doesn't work, try the other. Now connect: +COM4 is your **tethered USB serial connection** (the CP210x chip on the Huzzah32). COM16 and COM17 are Bluetooth serial ports—Windows creates two for each Bluetooth SPP pairing: one for outgoing and one for incoming connections. You typically want the first one listed, but if it doesn't work, try the other. -~~~ -python serial_demo.py COM16 115200 -~~~ +Now connect: + +``` +# macOS / Linux +python3 serial_reader.py /dev/tty.ESP32-Bluetooth 115200 + +# Windows +python serial_reader.py COM16 115200 +``` -That's it—same script, different port. The rest of the code (reading, writing, encoding, decoding) is identical. You should see `"[Bluetooth] Msg #1 | Uptime: 2.00s"` messages arriving every 2 seconds. Type a number and press Enter—it will be sent to the ESP32 and forwarded to USB Serial Monitor. You're communicating wirelessly! 🎉 +You should see the same greetings you saw in Part 1: + +``` +Connected! Listening for data... + +[Bluetooth] Msg #42 | Uptime: 84.0s +[Bluetooth] Msg #43 | Uptime: 86.0s +[Bluetooth] Msg #44 | Uptime: 88.0s +``` + +Press **Ctrl+C** to stop. {: .note } > **The baud rate parameter is ignored for Bluetooth virtual COM ports** on most operating systems. SPP negotiates its own data rate at the Bluetooth protocol level, so the `baudrate=115200` argument is passed to pySerial for API compatibility but doesn't actually set a baud rate the way it does for USB serial. You can pass any value and it will work—but we use `115200` to match our `Serial.begin(115200)` for consistency. -{: .note } -> **This is the point of SPP.** Your [serial_demo.py](https://github.com/makeabilitylab/arduino/blob/master/Python/Serial/serial_demo.py) was written for USB serial. It works over Bluetooth with only a port name change. The pySerial API, the `readline()` calls, the `write()` calls—everything is the same. Your operating system makes Bluetooth look like a wired serial connection. +### Sending data with serial_demo.py -{: .warning } -> **Only one program can open a serial port at a time.** If you have Arduino's Serial Monitor open on the Bluetooth COM port, your Python script won't be able to connect (and vice versa). Close Serial Monitor before running Python—or use Serial Monitor on the *USB* port and Python on the *Bluetooth* port. This is the same constraint from the [serial introduction](../communication/serial-intro.md#only-one-computer-program-can-open-a-serial-port-at-a-time), just with two ports to manage. +The `serial_reader.py` script only listens. To test bidirectional communication, use [`serial_demo.py`](https://github.com/makeabilitylab/arduino/blob/master/Python/Serial/serial_demo.py)—the interactive send-and-receive script from the [Communication module](../communication/serial-intro.md). It lets you type a number, sends it to the ESP32, and prints the echoed response: -### Workbench demo +``` +# macOS / Linux +python3 serial_demo.py /dev/tty.ESP32-Bluetooth 115200 + +# Windows +python serial_demo.py COM16 115200 +``` + +Type a number and press Enter—it will be sent to the ESP32 over Bluetooth, forwarded to USB Serial Monitor, and you can see it arrive wirelessly. You're communicating bidirectionally! 🎉 + +{: .note } +> **This is the point of SPP.** Both `serial_reader.py` and `serial_demo.py` were written for USB serial. They work over Bluetooth with only a port name change. The pySerial API, the `readline()` calls, the `write()` calls—everything is the same. Your operating system makes Bluetooth look like a wired serial connection. + +### Workbench demo of Python Bluetooth - +## Troubleshooting Bluetooth connections + +Bluetooth Classic SPP is straightforward once it works, but the initial setup can be finicky—especially on Windows. Here are the most common issues and how to resolve them. + +### General issues + +**"Only one program can open a serial port at a time."** If Arduino's Serial Monitor, PuTTY, a Python script, or any other program has the Bluetooth COM port open, nothing else can use it. Close all other serial programs before trying a new one. You *can* have Serial Monitor open on the USB port (COM4) while using Python on the Bluetooth port (COM16)—they're separate ports. + +**"No data, but no error either."** The connection opened successfully but nothing appears. Make sure the Arduino sketch is actually running—check Serial Monitor on the USB port for `[USB Serial]` messages. If USB Serial is working but Bluetooth isn't, the issue is on the Bluetooth/OS side, not the Arduino side. + +**"Bluetooth connection drops frequently."** Bluetooth Classic SPP has a practical range of about 5–10 meters indoors. Walls, furniture, and other 2.4 GHz devices (WiFi routers, microwaves) reduce range and can cause interference. Move closer to the ESP32 and away from other wireless devices. + +### macOS-specific issues + +**Port doesn't appear after pairing.** Try unpairing and re-pairing the device. Run `ls /dev/tty.*` before and after pairing to spot the new port. The port name varies by macOS version but typically contains the device name (e.g., `/dev/tty.ESP32-Bluetooth`). + +**`externally-managed-environment` error when installing pySerial.** Modern macOS (via Homebrew) blocks global `pip install` to protect system Python. Use a virtual environment as described in [Part 2](#setting-up-pyserial). This is the correct fix—avoid using `--break-system-packages` as it can cause problems with future Homebrew updates. + +**`python3: command not found`.** Install Python 3 from [python.org](https://www.python.org/downloads/) or via Homebrew (`brew install python`). + +### Windows-specific issues + +**Two COM ports appear.** Windows creates two COM ports for each Bluetooth SPP pairing: one for outgoing and one for incoming. You want the **outgoing** port. If one connects but shows no data, try the other. Check which is which in **Control Panel → Devices and Printers → right-click ESP32-Bluetooth → Properties → Services**. + +**COM port hangs when connecting.** Some USB Bluetooth adapters—especially those with Realtek chipsets, such as the TP-Link UB500—have driver issues with Bluetooth Classic SPP on Windows. Symptoms include: pairing succeeds, COM ports appear, but the connection hangs or no data flows. If you experience this, try updating your adapter's drivers from the manufacturer's website, using your laptop's built-in Bluetooth adapter instead (if available), or testing with a different Bluetooth adapter. + +{: .note } +> **Isolating adapter issues.** If you're not sure whether the problem is your code or your Bluetooth adapter, use the [`serial_reader.ps1`](https://github.com/makeabilitylab/arduino/tree/master/PowerShell) PowerShell script—it has zero dependencies and uses Windows' built-in .NET serial classes. If the PowerShell script also can't receive data, the problem is your adapter or driver, not your Python code. You can also try [PuTTY](https://www.putty.org/) (Connection type: Serial, your COM port, 115200 baud, Flow control: None) as a third independent test. + +**`python` is not recognized / Microsoft Store redirect.** On Windows, use `python` instead of `python3`. If `python` isn't recognized, reinstall Python from [python.org](https://www.python.org/downloads/) and make sure **"Add Python to PATH"** is checked during installation. You can also disable the Microsoft Store redirect in **Settings → Apps → Advanced app settings → App execution aliases** by toggling off the `python.exe` and `python3.exe` aliases. + +**ESP32 shows "Not connected" in Bluetooth settings.** This is normal for Bluetooth Classic SPP on Windows. The "Connected" status only appears during an active data session, not just from pairing. The device is paired and ready—it will show "Connected" once you open the COM port. + +### Still stuck? + +If the tips above don't resolve your issue, try describing your problem to an AI assistant like [Claude](https://claude.ai) or [Gemini](https://gemini.google.com). Include the specific error messages you're seeing, your operating system, your Bluetooth adapter (built-in or external), and what you've already tried. These tools are especially helpful for debugging driver issues and platform-specific quirks. You can also ask on the course discussion board—chances are another student has hit the same issue. -## Part 2: Streaming sensor data +## Part 3: Streaming sensor data Now let's stream live sensor data. We'll read a potentiometer and send its value over Bluetooth—then visualize it in Python. @@ -460,7 +617,7 @@ Turn the potentiometer—you'll see the bar chart or circle updating in real tim Include captions/transcript --> -## Part 3: p5.js over Bluetooth with serial.js +## Part 4: p5.js over Bluetooth with serial.js So far we've sent data in one direction—from ESP32 to computer—and visualized it in Python. Now let's bring it into the browser. Because your computer's Bluetooth serial port looks just like a USB serial port, the [Web Serial API](../communication/web-serial.md) works with it—and so does [serial.js](https://github.com/makeabilitylab/js/blob/main/src/lib/serial/serial.js) from the Makeability Lab library. You can build the same [p5.js](https://p5js.org/) interactive sketches from the [Communication module](../communication/p5js-serial.md), but with data arriving wirelessly over Bluetooth. @@ -577,7 +734,7 @@ Make sure the Part 2 sketch (`BluetoothPotentiometer`) is running on your ESP32. Include captions/transcript --> -## Part 4: Bidirectional control +## Part 5: Bidirectional control Now let's close the loop: stream sensor data *from* the ESP32 *and* send LED control commands *to* the ESP32. We'll extend the p5.js sketch to include a slider that controls LED brightness. @@ -783,7 +940,7 @@ If you carry your laptop out of Bluetooth range (or the ESP32 loses power), the Include captions/transcript --> -## Part 5: Android phone (optional bonus) +## Part 6: Android phone (optional bonus) If you have an **Android** phone, you can also communicate with the ESP32 using a Bluetooth terminal app. This is a quick bonus activity—the main lesson is computer-based. From bffae529d3a9a2d15f1b2d99c67788fc6898f326 Mon Sep 17 00:00:00 2001 From: Jon Froehlich Date: Wed, 27 May 2026 10:59:11 -0700 Subject: [PATCH 13/19] Reorganize ESP32 wireless lessons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restructure the ESP32 lesson hierarchy: assign Bluetooth-related lessons to a new 'Wireless' parent (add grand_parent: ESP32) and move analog input under 'Fundamentals'. Renumber lessons and update nav_order (Bluetooth Serial → L2, BLE Intro → L4, Bidirectional BLE → L5). Add new pages (bluetooth-web-serial.md, fundamentals.md, wireless.md), update internal cross-links and lesson references to the new numbering, and adjust content (examples, prerequisites, exercises, and notes) accordingly to reflect the reorganization and split/trimmed Bluetooth Serial content. This addresses: https://github.com/makeabilitylab/physcomp/issues/97 --- esp32/analog-input.md | 3 +- esp32/ble-bidirectional.md | 19 +- esp32/ble-intro.md | 37 ++- esp32/bluetooth-serial.md | 597 ++++------------------------------ esp32/bluetooth-web-serial.md | 593 +++++++++++++++++++++++++++++++++ esp32/capacitive-touch.md | 3 +- esp32/esp32.md | 3 +- esp32/fundamentals.md | 95 ++++++ esp32/index.md | 312 ++++++------------ esp32/iot.md | 5 +- esp32/led-blink.md | 3 +- esp32/led-fade.md | 3 +- esp32/tone.md | 3 +- esp32/wireless.md | 104 ++++++ 14 files changed, 1000 insertions(+), 780 deletions(-) create mode 100644 esp32/bluetooth-web-serial.md create mode 100644 esp32/fundamentals.md create mode 100644 esp32/wireless.md diff --git a/esp32/analog-input.md b/esp32/analog-input.md index 53ea4b9..24c8af9 100644 --- a/esp32/analog-input.md +++ b/esp32/analog-input.md @@ -1,7 +1,8 @@ --- layout: default title: L4: Analog input -parent: ESP32 +parent: Fundamentals +grand_parent: ESP32 has_toc: true # (on by default) usemathjax: true comments: true diff --git a/esp32/ble-bidirectional.md b/esp32/ble-bidirectional.md index edb0562..17abe49 100644 --- a/esp32/ble-bidirectional.md +++ b/esp32/ble-bidirectional.md @@ -1,12 +1,13 @@ --- layout: default -title: L10: Bidirectional BLE -parent: ESP32 +title: L5: Bidirectional BLE +parent: Wireless +grand_parent: ESP32 has_toc: true # (on by default) usemathjax: false comments: true usetocbot: true -nav_order: 10 +nav_order: 5 --- # {{ page.title | replace_first:'L','Lesson ' }} {: .no_toc } @@ -55,7 +56,7 @@ In this lesson, we'll close the loop. You'll learn how to send data in the *othe > - The **Nordic UART Service (NUS)** — a widely adopted convention for serial-like text communication over BLE {: .note } -> **Prerequisites:** This lesson builds directly on [Lesson 9: Introduction to BLE](ble-intro.md). You should be comfortable with BLE concepts (peripherals, centrals, GATT, services, characteristics, UUIDs, notifications) and have successfully completed Parts 1 and 2 from that lesson. +> **Prerequisites:** This lesson builds directly on [Lesson 4: Introduction to BLE](ble-intro.md). You should be comfortable with BLE concepts (peripherals, centrals, GATT, services, characteristics, UUIDs, notifications) and have successfully completed Parts 1 and 2 from that lesson. ## Part 1: Controlling the NeoPixel over BLE @@ -67,7 +68,7 @@ The ESP32-S3 Feather has a built-in NeoPixel (WS2812B) RGB LED on `PIN_NEOPIXEL` -We'll extend the [Lesson 9](ble-intro.md) sensor streaming sketch to add a second characteristic for LED control—so the ESP32 simultaneously streams sensor data *and* accepts LED commands. This is the same bidirectional pattern from [Lesson 8](bluetooth-serial.md#part-4-bidirectional-control), but over BLE with structured characteristics instead of a serial byte stream. The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/BLENeoPixelControl). +We'll extend the [Lesson 4](ble-intro.md) sensor streaming sketch to add a second characteristic for LED control—so the ESP32 simultaneously streams sensor data *and* accepts LED commands. This is the same bidirectional pattern from [Lesson 3, Part 3](bluetooth-web-serial.md#part-3-bidirectional-control), but over BLE with structured characteristics instead of a serial byte stream. The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/BLENeoPixelControl). ```cpp /** @@ -221,7 +222,7 @@ void loop() { The key new element is the `LedCallbacks` class. When the central writes to the LED characteristic, `onWrite()` fires automatically. We interpret the first three bytes of the written value as R, G, B and set the NeoPixel color accordingly. {: .highlight } -> **Callbacks vs. polling:** Notice the pattern: we don't poll for incoming data in `loop()` (like we do with `Serial.available()` or `SerialBT.available()` in [Lesson 8](bluetooth-serial.md)). Instead, BLE uses a **callback model**—the library calls our `onWrite()` function when data arrives. This is fundamentally different from the serial polling pattern you're used to, and it's one of the biggest code-level differences between Bluetooth Classic and BLE. +> **Callbacks vs. polling:** Notice the pattern: we don't poll for incoming data in `loop()` (like we do with `Serial.available()` or `SerialBT.available()` in [Lessons 2–3](bluetooth-serial.md)). Instead, BLE uses a **callback model**—the library calls our `onWrite()` function when data arrives. This is fundamentally different from the serial polling pattern you're used to, and it's one of the biggest code-level differences between Bluetooth Classic and BLE. ### Try it out from your computer (Python) @@ -572,7 +573,7 @@ Let's walk through the JavaScript, step by step: ## Part 3: Nordic UART Service (NUS) -Throughout this lesson, we've worked directly with custom GATT services and characteristics — the fundamental BLE building blocks. But what if you just want to send text back and forth, like the serial bridge from [Lesson 8](bluetooth-serial.md)? In this part, you'll learn the **Nordic UART Service (NUS)** — a widely adopted convention that emulates serial communication over BLE using two characteristics. NUS bridges the gap between BLE's structured model and the simplicity of serial, and it's supported by most BLE terminal apps out of the box. +Throughout this lesson, we've worked directly with custom GATT services and characteristics — the fundamental BLE building blocks. But what if you just want to send text back and forth, like the serial bridge from [Lesson 2](bluetooth-serial.md)? In this part, you'll learn the **Nordic UART Service (NUS)** — a widely adopted convention that emulates serial communication over BLE using two characteristics. NUS bridges the gap between BLE's structured model and the simplicity of serial, and it's supported by most BLE terminal apps out of the box. NUS is a widely adopted convention (created by Nordic Semiconductor) that uses two BLE characteristics to emulate serial communication: @@ -717,7 +718,7 @@ Want to go further? Here are some challenges to reinforce what you've learned: **Exercise 4: Web Bluetooth + p5.js.** Port the Web Bluetooth sensor display from Part 2 into [p5.js](https://p5js.org/). Use `createCanvas()` to draw a real-time visualization (bar chart, oscilloscope, *etc.*) of the incoming BLE sensor data. If you completed the [p5.js Serial lessons](../communication/p5js-serial.md), compare the code structure—how much carries over? (Hint: also check out [p5.ble.js](https://itpnyu.github.io/p5.ble.js/), a p5.js library specifically for Web Bluetooth.) -**Exercise 5: Port a Bluetooth Classic bidirectional project to BLE.** If you completed the bidirectional LED control from [Lesson 8, Part 4](bluetooth-serial.md#part-4-bidirectional-control), rebuild it using BLE with writable and notify characteristics. Update the computer-side code to use Web Bluetooth instead of Web Serial. What changed? What stayed the same? +**Exercise 5: Port a Bluetooth Classic bidirectional project to BLE.** If you completed the bidirectional LED control from [Lesson 3, Part 3](bluetooth-web-serial.md#part-3-bidirectional-control), rebuild it using BLE with writable and notify characteristics. Update the computer-side code to use Web Bluetooth instead of Web Serial. What changed? What stayed the same? ## Lesson Summary @@ -742,7 +743,7 @@ In this lesson, you learned how to send data *to* the ESP32 over BLE and build b ## Next Lesson -With BLE under your belt, you've now covered all three major wireless communication technologies available on the ESP32: **WiFi** (cloud connectivity via [IoT](iot.md)), **Bluetooth Classic** (wireless serial via [Lesson 8](bluetooth-serial.md)), and **BLE** (structured low-power wireless in [Lesson 9](ble-intro.md) and this lesson). From here, you might explore BLE HID (making your ESP32 act as a wireless keyboard, mouse, or game controller), deep sleep with BLE wake-up for battery-powered projects, or combining BLE with sensors like the ADXL343 accelerometer for motion-controlled wireless devices. The wireless world is yours! 🚀 +With BLE under your belt, you've now covered all three major wireless communication technologies available on the ESP32: **WiFi** (cloud connectivity via [Lesson 1: IoT](iot.md)), **Bluetooth Classic** (wireless serial via [Lessons 2–3](bluetooth-serial.md)), and **BLE** (structured low-power wireless in [Lesson 4](ble-intro.md) and this lesson). From here, you might explore BLE HID (making your ESP32 act as a wireless keyboard, mouse, or game controller), deep sleep with BLE wake-up for battery-powered projects, or combining BLE with sensors like the ADXL343 accelerometer for motion-controlled wireless devices. The wireless world is yours! 🚀 \ No newline at end of file From beb5ef7d06fd8c7a61c2ff3e7d98675ae269f255 Mon Sep 17 00:00:00 2001 From: Jon Froehlich Date: Wed, 24 Jun 2026 10:02:30 -0700 Subject: [PATCH 18/19] Add SEO description: front matter to new ESP32 Wireless pages The six pages added on this branch (fundamentals, wireless, and the four BLE/Bluetooth lessons) lacked `description:`, which fails the SEO content-lint gate. Add concise descriptions sourced from each page's content. Heroes/OG images remain deferred (blocked on workbench media) and are tracked per-lesson in #129-#132. Draft-visibility (nav_exclude/search_exclude) for the unfinished BLE drafts left as an open #122 policy decision. Co-Authored-By: Claude Opus 4.8 --- esp32/ble-bidirectional.md | 1 + esp32/ble-intro.md | 1 + esp32/bluetooth-serial.md | 1 + esp32/bluetooth-web-serial.md | 1 + esp32/fundamentals.md | 1 + esp32/wireless.md | 1 + 6 files changed, 6 insertions(+) diff --git a/esp32/ble-bidirectional.md b/esp32/ble-bidirectional.md index 17abe49..21f3ef9 100644 --- a/esp32/ble-bidirectional.md +++ b/esp32/ble-bidirectional.md @@ -1,6 +1,7 @@ --- layout: default title: L5: Bidirectional BLE +description: "Control ESP32 hardware wirelessly from a phone or web browser over BLE: write characteristics to set NeoPixel color, stream sensor data back, and exchange text with the Nordic UART Service." parent: Wireless grand_parent: ESP32 has_toc: true # (on by default) diff --git a/esp32/ble-intro.md b/esp32/ble-intro.md index 8f70bb2..73386b4 100644 --- a/esp32/ble-intro.md +++ b/esp32/ble-intro.md @@ -1,6 +1,7 @@ --- layout: default title: L4: Introduction to BLE +description: "Learn Bluetooth Low Energy on the ESP32: the peripheral/central model, GATT services and characteristics, and streaming live sensor data to your phone via BLE notifications." parent: Wireless grand_parent: ESP32 has_toc: true # (on by default) diff --git a/esp32/bluetooth-serial.md b/esp32/bluetooth-serial.md index 9c5ff3d..b2a3a4c 100644 --- a/esp32/bluetooth-serial.md +++ b/esp32/bluetooth-serial.md @@ -1,6 +1,7 @@ --- layout: default title: L2: Bluetooth Serial +description: "Send data wirelessly from the ESP32 with Bluetooth Classic's Serial Port Profile (SPP): pair on macOS or Windows to get a virtual COM port and reuse your existing pySerial and serial.js code." parent: Wireless grand_parent: ESP32 has_toc: true # (on by default) diff --git a/esp32/bluetooth-web-serial.md b/esp32/bluetooth-web-serial.md index e71f226..06a9a4b 100644 --- a/esp32/bluetooth-web-serial.md +++ b/esp32/bluetooth-web-serial.md @@ -1,6 +1,7 @@ --- layout: default title: L3: Bluetooth Web Serial +description: "Stream ESP32 sensor data over Bluetooth and visualize it in Python and the browser, then build a bidirectional color mixer where the web page and a potentiometer share control of a NeoPixel." parent: Wireless grand_parent: ESP32 has_toc: true # (on by default) diff --git a/esp32/fundamentals.md b/esp32/fundamentals.md index 79a05e8..a5c66bb 100644 --- a/esp32/fundamentals.md +++ b/esp32/fundamentals.md @@ -1,6 +1,7 @@ --- layout: default title: Fundamentals +description: "The ESP32 Fundamentals series: set up the board, blink and fade LEDs with the LEDC PWM peripheral, read the 12-bit ADC, play tones, and use built-in capacitive touch before going wireless." parent: ESP32 nav_order: 1 has_toc: false # on by default diff --git a/esp32/wireless.md b/esp32/wireless.md index ec80d5e..a4a9044 100644 --- a/esp32/wireless.md +++ b/esp32/wireless.md @@ -1,6 +1,7 @@ --- layout: default title: Wireless +description: "The ESP32 Wireless series: connect to the cloud over WiFi with Adafruit IO, stream data over Bluetooth Classic serial, and build phone- and browser-friendly projects with Bluetooth Low Energy (BLE)." parent: ESP32 nav_order: 2 has_toc: false # on by default From afa13ba848e487fed03d088db2a2af0ea36f2cf0 Mon Sep 17 00:00:00 2001 From: Jon Froehlich Date: Wed, 24 Jun 2026 10:48:05 -0700 Subject: [PATCH 19/19] Fix content-lint failures on new ESP32 Wireless pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - code-blocks (MD040): add language tokens to 16 bare fences — `text` for ASCII diagrams and program/serial output, `bash` for shell commands. - link-check (html-proofer): fix broken refs introduced by the new pages — - ble-intro: 10kΩ pot image path (Potentiometer_100h.png was nonexistent) → PanelMountPotentiometer_NoCap_150h.jpg - bluetooth-web-serial: WS2812 stick image → advancedio/assets path; ../led/addressable-leds.md → ../advancedio/addressable-leds.md (x3) - fundamentals: capacitive-touch-sensing.md → capacitive-touch.md - ble-bidirectional: stale cross-ref to L3 "Part 3" bidirectional → Part 5 (#part-5-bidirectional-control--wireless-color-mixer) (x2) - bluetooth-serial: serial-intro anchor (#only-one-program-can-open-a- serial-port-at-a-time) Verified locally: markdownlint code-blocks gate clean, jekyll build clean, all link/image/anchor targets resolve in _site. Co-Authored-By: Claude Opus 4.8 --- esp32/ble-bidirectional.md | 4 ++-- esp32/ble-intro.md | 10 +++++----- esp32/bluetooth-serial.md | 20 ++++++++++---------- esp32/bluetooth-web-serial.md | 14 +++++++------- esp32/fundamentals.md | 2 +- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/esp32/ble-bidirectional.md b/esp32/ble-bidirectional.md index 21f3ef9..2bfa282 100644 --- a/esp32/ble-bidirectional.md +++ b/esp32/ble-bidirectional.md @@ -69,7 +69,7 @@ The ESP32-S3 Feather has a built-in NeoPixel (WS2812B) RGB LED on `PIN_NEOPIXEL` -We'll extend the [Lesson 4](ble-intro.md) sensor streaming sketch to add a second characteristic for LED control—so the ESP32 simultaneously streams sensor data *and* accepts LED commands. This is the same bidirectional pattern from [Lesson 3, Part 3](bluetooth-web-serial.md#part-3-bidirectional-control), but over BLE with structured characteristics instead of a serial byte stream. The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/BLENeoPixelControl). +We'll extend the [Lesson 4](ble-intro.md) sensor streaming sketch to add a second characteristic for LED control—so the ESP32 simultaneously streams sensor data *and* accepts LED commands. This is the same bidirectional pattern from [Lesson 3, Part 5](bluetooth-web-serial.md#part-5-bidirectional-control--wireless-color-mixer), but over BLE with structured characteristics instead of a serial byte stream. The full source is available in our [Arduino GitHub repo](https://github.com/makeabilitylab/arduino/tree/master/ESP32/Bluetooth/BLENeoPixelControl). ```cpp /** @@ -719,7 +719,7 @@ Want to go further? Here are some challenges to reinforce what you've learned: **Exercise 4: Web Bluetooth + p5.js.** Port the Web Bluetooth sensor display from Part 2 into [p5.js](https://p5js.org/). Use `createCanvas()` to draw a real-time visualization (bar chart, oscilloscope, *etc.*) of the incoming BLE sensor data. If you completed the [p5.js Serial lessons](../communication/p5js-serial.md), compare the code structure—how much carries over? (Hint: also check out [p5.ble.js](https://itpnyu.github.io/p5.ble.js/), a p5.js library specifically for Web Bluetooth.) -**Exercise 5: Port a Bluetooth Classic bidirectional project to BLE.** If you completed the bidirectional LED control from [Lesson 3, Part 3](bluetooth-web-serial.md#part-3-bidirectional-control), rebuild it using BLE with writable and notify characteristics. Update the computer-side code to use Web Bluetooth instead of Web Serial. What changed? What stayed the same? +**Exercise 5: Port a Bluetooth Classic bidirectional project to BLE.** If you completed the bidirectional LED control from [Lesson 3, Part 5](bluetooth-web-serial.md#part-5-bidirectional-control--wireless-color-mixer), rebuild it using BLE with writable and notify characteristics. Update the computer-side code to use Web Bluetooth instead of Web Serial. What changed? What stayed the same? ## Lesson Summary diff --git a/esp32/ble-intro.md b/esp32/ble-intro.md index 73386b4..157a97a 100644 --- a/esp32/ble-intro.md +++ b/esp32/ble-intro.md @@ -117,7 +117,7 @@ Think of GATT as a structured bulletin board. The peripheral (ESP32) maintains a Here's the hierarchy: -``` +```text BLE Peripheral (GATT Server) └── Service (e.g., "Sensor Data") ← a category of related data ├── Characteristic (e.g., "Potentiometer") ← a single data point @@ -223,7 +223,7 @@ You'll need the following components. We use **[Adafruit's ESP32-S3 Feather](htt | Breadboard | ESP32 | LED | Resistor | Potentiometer | | ---------- |:-----:|:-----:|:-----:|:-----:| -| ![Half-sized solderless breadboard]({{ site.baseurl }}/assets/images/Breadboard_Half.png) | ![Adafruit ESP32-S3 Feather board, top view](assets/images/Adafruit_ESP32-S3-5477-11-vertical-cropped.jpg) | ![Red 5mm LED]({{ site.baseurl }}/assets/images/RedLED_Fritzing.png) | ![220-ohm resistor, striped red-red-brown-gold]({{ site.baseurl }}/assets/images/Resistor220_Fritzing.png) | ![10kΩ rotary potentiometer]({{ site.baseurl }}/assets/images/Potentiometer_100h.png) | +| ![Half-sized solderless breadboard]({{ site.baseurl }}/assets/images/Breadboard_Half.png) | ![Adafruit ESP32-S3 Feather board, top view](assets/images/Adafruit_ESP32-S3-5477-11-vertical-cropped.jpg) | ![Red 5mm LED]({{ site.baseurl }}/assets/images/RedLED_Fritzing.png) | ![220-ohm resistor, striped red-red-brown-gold]({{ site.baseurl }}/assets/images/Resistor220_Fritzing.png) | ![10kΩ rotary potentiometer]({{ site.baseurl }}/assets/images/PanelMountPotentiometer_NoCap_150h.jpg) | | Breadboard | [ESP32-S3 Feather](https://www.adafruit.com/product/5477) | Red LED | 220Ω Resistor | 10kΩ Potentiometer | You will also need: @@ -350,7 +350,7 @@ Let's walk through the key steps: Let's start on the computer, where debugging is easiest. We'll use [bleak](https://pypi.org/project/bleak/) — a cross-platform BLE client library for Python that works on macOS, Windows, and Linux. Unlike [pySerial](https://pyserial.readthedocs.io/) (which we used for Bluetooth Classic in [Lesson 2](bluetooth-serial.md)), bleak speaks BLE natively — it connects directly to BLE peripherals, discovers their GATT services, and reads/writes characteristics using Python's `asyncio` for non-blocking I/O. If you haven't installed it yet: -``` +```bash pip3 install bleak ``` @@ -402,7 +402,7 @@ asyncio.run(main()) Run it: -``` +```bash python3 ble_discover.py ``` @@ -646,7 +646,7 @@ asyncio.run(main()) Run it and turn the potentiometer—you'll see a live bar chart updating in your terminal, with data arriving wirelessly over BLE: -``` +```bash python3 ble_sensor_reader.py ``` diff --git a/esp32/bluetooth-serial.md b/esp32/bluetooth-serial.md index b2a3a4c..44f7a24 100644 --- a/esp32/bluetooth-serial.md +++ b/esp32/bluetooth-serial.md @@ -283,7 +283,7 @@ You can choose any name you like—"ESP32-Bluetooth", "MyPotentiometer", "Jon's Upload this sketch to your ESP32 and open Serial Monitor at 115200 baud. You should see greeting messages appearing every 2 seconds, prefixed with `[USB Serial]`: -``` +```text [USB Serial] Msg #1 | Uptime: 2.0s [USB Serial] Msg #2 | Uptime: 4.0s [USB Serial] Msg #3 | Uptime: 6.0s @@ -308,7 +308,7 @@ Before you can communicate over Bluetooth, you need to **pair** your computer wi 3. Click **Connect** next to `"ESP32-Bluetooth"`. macOS will pair with the device. 4. Once paired, macOS creates a virtual serial port. To find it, open **Terminal** and run: -``` +```bash ls /dev/tty.*Bluetooth* ``` @@ -345,7 +345,7 @@ cat /dev/tty.ESP32-Bluetooth Replace the port name with whatever `ls /dev/tty.*Bluetooth*` showed you. You should immediately see greetings streaming in: -``` +```text [Bluetooth] Msg #1 | Uptime: 2.0s [Bluetooth] Msg #2 | Uptime: 4.0s [Bluetooth] Msg #3 | Uptime: 6.0s @@ -383,7 +383,7 @@ Download it and run from your PowerShell terminal: You should see messages streaming in: -``` +```text Connected! Listening for data... [Bluetooth] Msg #1 | Uptime: 2.0s @@ -396,7 +396,7 @@ Press **Ctrl+C** to stop. **If you see messages, congratulations—you're communicating wirelessly! 🎉** The ESP32 is sending data over Bluetooth, your computer is receiving it through a virtual serial port, and no USB cable was involved. This is the core magic of SPP. {: .warning } -> **Only one program can open a serial port at a time.** If you have Arduino's Serial Monitor open on the Bluetooth COM port, `cat`/`screen`/PowerShell won't be able to connect (and vice versa). Close Serial Monitor before trying the terminal commands—or keep Serial Monitor on the *USB* port (COM4) and use the terminal on the *Bluetooth* port. This is the same constraint from the [serial introduction](../communication/serial-intro.md#only-one-computer-program-can-open-a-serial-port-at-a-time), just with two ports to manage. +> **Only one program can open a serial port at a time.** If you have Arduino's Serial Monitor open on the Bluetooth COM port, `cat`/`screen`/PowerShell won't be able to connect (and vice versa). Close Serial Monitor before trying the terminal commands—or keep Serial Monitor on the *USB* port (COM4) and use the terminal on the *Bluetooth* port. This is the same constraint from the [serial introduction](../communication/serial-intro.md#only-one-program-can-open-a-serial-port-at-a-time), just with two ports to manage. **If you don't see any data**, see the [Troubleshooting Bluetooth connections](#troubleshooting-bluetooth-connections) section below before moving on. @@ -449,7 +449,7 @@ We provide a simple Python script called [`serial_reader.py`](https://github.com First, list available ports to find your Bluetooth serial port: -``` +```bash # macOS / Linux python3 serial_reader.py --list @@ -459,7 +459,7 @@ python serial_reader.py --list On Windows, you should see something like: -``` +```text Available serial ports: COM1 - Communications Port (COM1) COM4 - Silicon Labs CP210x USB to UART Bridge (COM4) @@ -471,7 +471,7 @@ COM4 is your **tethered USB serial connection** (the CP210x chip on the Huzzah32 Now connect: -``` +```bash # macOS / Linux python3 serial_reader.py /dev/tty.ESP32-Bluetooth 115200 @@ -481,7 +481,7 @@ python serial_reader.py COM16 115200 You should see the same greetings you saw in Part 1: -``` +```text Connected! Listening for data... [Bluetooth] Msg #42 | Uptime: 84.0s @@ -498,7 +498,7 @@ Press **Ctrl+C** to stop. The `serial_reader.py` script only listens. To test bidirectional communication, use [`serial_demo.py`](https://github.com/makeabilitylab/arduino/blob/master/Python/Serial/serial_demo.py)—the interactive send-and-receive script from the [Communication module](../communication/serial-intro.md). It lets you type a number, sends it to the ESP32, and prints the echoed response: -``` +```bash # macOS / Linux python3 serial_demo.py /dev/tty.ESP32-Bluetooth 115200 diff --git a/esp32/bluetooth-web-serial.md b/esp32/bluetooth-web-serial.md index 06a9a4b..a9e6405 100644 --- a/esp32/bluetooth-web-serial.md +++ b/esp32/bluetooth-web-serial.md @@ -69,7 +69,7 @@ In addition to the materials from [Lesson 2](bluetooth-serial.md#materials), you | Breadboard | ESP32 | Potentiometer | NeoPixel | | ---------- |:-----:|:-----:|:-----:| -| ![Half-sized solderless breadboard]({{ site.baseurl }}/assets/images/Breadboard_Half.png) | ![Adafruit ESP32 Feather, top view]({{ site.baseurl }}/assets/images/ESP32Huzzah32_Adafruit_vertical_h200.png) | ![10kΩ rotary potentiometer]({{ site.baseurl }}/assets/images/PanelMountPotentiometer_NoCap_150h.jpg) | WS2812B 8-LED stick | +| ![Half-sized solderless breadboard]({{ site.baseurl }}/assets/images/Breadboard_Half.png) | ![Adafruit ESP32 Feather, top view]({{ site.baseurl }}/assets/images/ESP32Huzzah32_Adafruit_vertical_h200.png) | ![10kΩ rotary potentiometer]({{ site.baseurl }}/assets/images/PanelMountPotentiometer_NoCap_150h.jpg) | WS2812B 8-LED stick | | Breadboard | ESP32 with BT Classic (see below) | 10kΩ Potentiometer | NeoPixel (onboard or external) | **Choose one ESP32 board with Bluetooth Classic:** @@ -79,7 +79,7 @@ In addition to the materials from [Lesson 2](bluetooth-serial.md#materials), you **NeoPixel options for Part 5:** - If your board has an onboard NeoPixel (Feather V2), you're done—no extra parts. -- Otherwise, use any external WS2812B/SK6812 addressable LED: the **8-LED stick** in our course kits is perfect. You can also use a single NeoPixel, a strip, a ring, or a matrix—the code is the same, only the LED count changes. See the [Addressable LEDs lesson](../led/addressable-leds.md) for background on the hardware and wiring conventions. +- Otherwise, use any external WS2812B/SK6812 addressable LED: the **8-LED stick** in our course kits is perfect. You can also use a single NeoPixel, a strip, a ring, or a matrix—the code is the same, only the LED count changes. See the [Addressable LEDs lesson](../advancedio/addressable-leds.md) for background on the hardware and wiring conventions. You will also need: - **Google Chrome** or **Microsoft Edge** (for the Web Serial activities in Parts 3–5)—same browser requirement as the [Web Serial lesson](../communication/web-serial.md) @@ -158,7 +158,7 @@ You already have two Python visualization scripts from the [Communication module {: .note } > **Reminder: activate your venv first.** The scripts below assume you've activated the virtual environment you set up in [Lesson 2, Part 2](bluetooth-serial.md#setting-up-pyserial). Each time you open a new terminal: -> ``` +> ```bash > # macOS / Linux > source venv/bin/activate > # Windows @@ -168,7 +168,7 @@ You already have two Python visualization scripts from the [Communication module **Terminal bar graph:** [`serial_bar_graph.py`](https://github.com/makeabilitylab/arduino/blob/master/Python/SerialBarGraph/serial_bar_graph.py) reads a float value per line (0.0–1.0) and renders a live ASCII bar chart in the terminal. To use it over Bluetooth, just pass the Bluetooth port as an argument: -``` +```bash # macOS / Linux — with your venv active python3 serial_bar_graph.py /dev/tty.ESP32-PotSensor 115200 @@ -178,7 +178,7 @@ python3 serial_bar_graph.py COM8 115200 **Matplotlib circle:** [`serial_draw_circle.py`](https://github.com/makeabilitylab/arduino/blob/master/Python/SerialCircle/serial_draw_circle.py) reads a float value per line and draws a circle whose radius is proportional to the value. Same idea—just pass the Bluetooth port: -``` +```bash # macOS / Linux — with your venv active python3 serial_draw_circle.py /dev/tty.ESP32-PotSensor 115200 @@ -311,7 +311,7 @@ Keep the pot from Part 1 on A7. For the NeoPixel, you have two paths: - VCC → **USB** pin (5V from USB) for sticks/strips, or **3V** for a single NeoPixel - GND → **GND** -See the [Addressable LEDs lesson](../led/addressable-leds.md) for more on power, signal levels, and wiring conventions. +See the [Addressable LEDs lesson](../advancedio/addressable-leds.md) for more on power, signal levels, and wiring conventions.

XAbC@{4HcaDe`ik}u#Omx}p(@I4=*WVOV#+5$`OiT7S`$d0aB*>P$ZMg$H&t2f zhUj8=%?cE|a$yS4KrIukyOv_1sm~~iLce{i^}8{vZ1!ryOnE?%9@5h?@pj~vD27j@ zD-|ldwkP3^&*kFHOLhCMS@+3W&&1^URdwLu@Z}$xt3Oj?Lfz(~6RQtD74urYkRa|E zJvxyg!u;OIkkk1HKyZo!rikJU-4Zx`CLWMzc6uyu`GPeJku=%5kgd3uI$fu#E`p<-y8B0iWl z8qu+MjeskALY(ueZpbPGnD8kDsvongO(|$9g5Um0j#i>3m+4`&3K~-bjGK1 zgfJ-JF#jh2B`Tl@vr?-sZ<%Rv6ozrje^cQr3rz%h_4o4PKtY4r_}aaRe@U9~YSUNJ z8cPlOqe+6T3z{g4sfe5D%0_yjCNH;o|27ui&`7|1QmObqF4O|}bhXqV@yG(W4WRyP z*;H>FJru4tsmI<~(J(c|-T?7t9eu(#G}=B!1bgkR(l;#D(PQMj(|d&;ezPHARR~DF z{?T_tLAz_#r|XK!L^>!_e`ki{-Q%uBHaJdSKiZaiz5lWNx8gVb)g6o}6c%c>y5+TZ zvX+A_*~z>kl#(@4{7L^wEK)&rY*Q?oGfzw>3Z;U;fm*qefFB1kteSgC)d@6#Jk}}( zhL-v9)gIeH&)c7CFk7w0Y~MuKaKD(yd_wTxO&tYxDdkB-n{b@U#`<~naO-zdV@9}M zCU0nWw2d|s`pws8&;Eg0o5#{AiD1;)pjxWh*k2q@g>b#HjlAvSq2}%dH5>cigwfwA zt?})i$8Q7qxi9@ED;VhG4V7ICT$Q{$0#8m$23JY#7&mWKvD2=;^0}`X$zyA4T^+<~ zWsif|QJLs_WftPUd0M_bQY&(NYV{{_Rp}Xn@%UH%{oeM&dEe;j$92*Qh9nNbqi6yF zA2Bd$_r5uJv`ua4WUzB%ucYHeOk*>1etgLahAIv8irIf?EFOA1fWzbPr8g|qIoyYM zI2=6-)O!BH+dtA=Jd?9f;R}8=T3_IHwOv%f zCnqDplr8s>Iwv5p+Z7Q$VVMaG5UoDzV6(3g*oe%b6aAa^GI%~%O&>8NP59;j%Bd350vl2xL77i^aR2_Hr%_JrS=Pj--j+r{$%QAZ zdMpj~5d~Y$^$k;-M~d8jMvgP(hJq~ z85AxG3E8fJQ;W>7kK6bJ9@Z{(s2E6WxLa6R-gkDieQSbYf-$rf-C#fe!r6O9J<1ef zlvh$5f!MzQmN^u=njm>azOc%T4!HlHo2fJnq7nYBPa~1alA37)5}IS1t5fRp!?MRd zcXeDLP$e}~=lZHNd0~ha7Vu1Pr19YA8>TA2+J_pQ0Z*TGxCEmBrR>So`|b$e30zniw$@l=c<# zMt_;`ti=L277F+Rn!QhE5(W{nuhwKBjMjRLdJ^9v)Fk^Gz5pjjK1LxbbIPWsa$48A zVI2hYtBrZqJiFtYjy@9=Szs3XchmaurTq$2FEUha{Al(VLqZuqdscpYTWPH{maX|} z{(U&jU41?22ik6)9_;vdB3;h7stn*7tU8ifSMbjAA#ns?IT z(%$;eYilU-mzEVfG&~#Hdl_))z!L6O?|*SV)kI9PSCP}Fd)L?~nuwzKjD8ZVWhcO; z6eT^cOd+n49Qrrr(XC=r^GcbUvsOx5s%Wdw$|$z{awKO zdo(!|6)T~_5{b?2qnc7u4H@WRkGO@`4o^>~X|K=pz&*C1Za5y+Xc?#&hz!TwoW5z} z7+v~Co)N{JKr5uM`bRVEj80k++e7`0{(7qMwmaRm8%hj49U^A}$~O(<&J8GZ(df`f z>HN~2A)y+3NS`Ixxi{ z=?H);Mzq0=U56?rOUh>^*CCLr{U=I~ba{4UPr4*qeXc&g4L{oPiU#eB#5u6Yc=%U0 zG~YS>P}4c$Fn-_3ysWmaxKF89n#qzi+?=>D=PV&YX7p?agxy7yp#kT|ZsuzCTc8A^ zu8hjD23huNdeyG>Us+QFy-0;;K*$TFqlnCxH-Z=CGxXqska0e#i5c8rMlpfC0}cmb zFl{PCxa@M~6SgLgJ#lcuzzaTj11(;Oyew(3fm$iT^<@p#>kfz1+N{j2lXLYBTxsnD zT)yX-9rsWr>a*{faZE6>Q>k4zGbd-~$ajrZ>`8+81h}Iv0v^ORD||+|FZh%A_n}rh3ey)U z(7*C??lBmU>~^rs0pI95L%sBWcn6rD^F{U`J$-yGr)+b)Oq|M`X9~)}f`U;|O-e~D zy*2pqJuo{=vnG=aNQNPx5O`irb5r7dP$&WBwqNZAPhL6EW=C zy9gV%sL?OFVM&!+SpCP3Y94zpn9TWmugRy5+T9BznK@aB-Mz}N_&G^$c8T3NuQv^x z>^}{^>Tg|DhRC0I6&hQ^TsK{wHy`hV!lhHDGXplZU$2bUt39jzFE-B)GOEgVWMA9f zU1Fs}lVMaT`>lU%QeBB9yW0Yud^GZLWSEeKb)`qUP3N`vZ`c`UGb5h(hzX?H%0F3GKK9TVsv#5xPy|jRGJ$8W2y7E7l*lcw|hOP?N_1j^l0Ak z4SZQ8^RMCYV%8A`$)&!aIcbpLFPB0XS6R~)j-=8)mDaE{gQ1P=sn*7pmjGGwkZ3-; z#Y*))=pNw$PEWz3s}PFDCl(7^XHC&vUom=l*W-Johov0DM9h*^ehqeTezG7Dqk1z7 zy4>a#G_RKdvw6*yOG#7`a!YTbfHcGDy zYm4{&m}$fyGAjN+o&o))4Hvumm;FjDGOTw{Hnc;;jT1sp;Ml?6V3nbZ6mt@2RS9o5Pqr~K_LoAL);39LiXM~1pb}TC!Z<=LIL`WVrmLL{_brss2CCws<2!v zaG2a!`oGrTx0JD9e7Ec#0a)^81*SDy&v&oOo&VVQzj$Mm_w99MqsMD75w}P>-21k3 z1QDigK6-=}iKVA1ia`|@8wrFkw0|9TW@HDNcI!U_z1_vd0PlzfU|8bd8Zfx+pePAx zJ;Smmu0C$kL+|TUc;CCGsJ zEE%L>vp5VLe;1Q?ObrIPdaY@g=(S5Z)y=rE66#XaJG6rFcG)&CdAuN!s4H`hp)6xZrrSr>%} zU6;7_HR4*iMt0fB7POq`zekWJK#q`e*%k zzqf?!Og&eKZ7(TSDE5xwfUS7JVJ>C0!e_YW3Wb|)GH%jvAN?~U;Dl1d z%-TYFn1O~++URxmHw6^;%w|7w-o}AbP8CGB(6P+^2M3GOt%fRW2-)+82Ab^6h)GVh^wWAcE%(hsm)J6mt})b zLVnNHA6H9=*EK9B=p|$o8WR@lmTW%u-QSeR{cv)NKI3F_WkW>xIK<=9_1vag_B#ni zRhBYc9wAot?`en5c!8hGZ_Ox)qb|sh(x@zFi?U{*t)bEMB~zqF%y|cqJ*nuPgT;`U8m1P$r!3i&gaJqP)6t{j-19m4{(1s5i+i?+2^Y;BwJCAA%fF5BNn~>9Xzh@6#Y=DM>6s z6u?+e6UIl|!q9e&<3B?+F?9OJiqF!X@39ju6LUi2%x0OAuB`0ku#>ZO%pq6}U3qO8 z*{AeSDLN_A)K}!r)q;rnOHWr%)5|q+|A5;j)JXJ7?dKLOH(Vdr44O8~Q}A2Q&dGTK zj|$$sVVn8vPm?N)4qCk~brl5b%?&x)>6DXtYZX5wv%%x8S&p9{gSIN_PJ!6tsHcyQ z|G#_FM_bB!ej!zp?mI`DGyh7#YTn&lR>idj;C6=PNtcs*t5!KLk*s3;SI;bdub8&B zvb3_a?jLzOIR#vj%V3ctF);XAT)Za5((sg*W%~5PlcVXwG1<$?j~*@#04a}!_=Tb? zMOQ$shsN`I+{Y>2AoAK60{Pj|jp=b8;X|HNL!mtJb!in0X=I;#I~}FMmFD)I1N$d| zl#4)h#Hro>F*hl9&i(SF;`V`M%QOITkG!4u4t|bdjm|h5M&*F1U?im(wJ8~zSH&=~ zHgX{ntbBz@Bzgz5npwKpn+y`-$S}at zZEW4I%w@-B061Cs_Xj++I~$YN)cq{IKqR0uk@q=I`Qt3?CgCN4&)B`9@y8_y6Ed2O z5p0%CPU&wBaH!*Lq*jUDanl2Tety5&t3+lF>?;}xER}vkDG}{$DDExk<`&e=D+swVYdDF6P4#@Uk~*2Hdu_QqQ{0=ju}WCoCEA z?)EI5>$;tOID0C>RWcFtXSH!51+IwEOnKK7bLoBil z1}mhe$&2d*+zZ-y{BJ^GQI@76nkE`^Drfi3^$zR(>FKYvCj+)8Ayw^d5+!8oV|J*% z`gwH`j)S%1KQktb$qO%CdaEkfAuvI@R>j*3vkFB%H0==zNn63pkb)r{sjBNj;+rr4i?zP^9|dX{AiFX|DRFQq!I zIpE~I%!0$Xp3>5A&Xj^P=RdhYX1g-}A0D3A9^WDH2H&MKj2OS6#R;8RZ3?B0N1YVs zm`Om>YjkNcx-aKdW)fbBG_ID^iKqL#aa}FB-b>*18|}`s8g(%1N$tq?9@R9Ty17gg z;AZIUsZsx;UUoG<$MT0}=CkpSd7L(1;5fnA)fRp^{~V#m*&T}}p{hu<{$miwaVk@Qj!cA_oI zPwxB17v7<|si7);Fe`i#K}k+c7&`Y|Qa(^5jGUy$W}SHbj|~IFvk$>vfXm*hKX!~@Ur33oLoBEmWNsWSc52H)iGGnLl#7`!R{ zx7>ZO0YaYO20Zb-kTP}M8>NQD729|C1;$$iuL#epzRrk_ruI19;%CLESdO3RZQ7FO zuBoIB`B(H|c4_^-_5VLf4pv|5a2A7KaH}Vl*O&kybS8g0Wd;OmN~Gvt{JJN9mYJ12 zBcs!}HYOj{r(@g+p8^rEnY}w89Pnph*)!(~t|??=9o!l)U+Q-Ir*}K@qjsi({sNG7 zPSehD0L%Kc`Rk|mu5|isWKZ2x2-^Iy{`g?0q0Y*?pEOi<$C5S{YwuDn-kWEB9ac~a zNNQ!`<>+#!m4?b2OjgfQRK&~P5Q`AuFAQPs+@RiLGi?Y%?mI2nKH%c{H3<{}DJ%uMcMkJ=NBF+T!uzaq{jaRYhWPSFwdg(pun~e<(*@Z)ct*gQ@VQ5V> zMPEf5r|yJSi(_TI(3=q2Qm0^__VUK7|D?BApLu3To<&M25nNJJPs*K}u_Jx&`uCh-;buEV)9C^Qvce#*?ZJ~NIf|^@>{chozYeQ z#k%o$U*Ra=we`-?Nxmhs3OND>>7dlTDuUdhd1O4#@?FdOVv?pa4H+`ien|ZwA2@Dx-Es z#)Z@2Ty&)8$3!m{erG1^$L0f;G;wVk71)It&&lS4BdqV(7`|5BFVgkDoboI+H<#Gj_8z=|Ce-Py`bz@vMpa-0 zs9Tc5j&8NriCSTxr3zJ|KYuIlhh>aGC}bvZRhiyjT6!Ml8V?QJBxr6(y`njmv(Fpk zeGz8*O(hVWBf0j-Y)R5ajC5i05#$eC_eJ#Wn023E3sp0&Fh$E>)q>p({r;lg?LTDO z%RLAj;4$V8rvqySUoaTJIL_R=L5hj!BcNXj0*#kJoFFR&i%^F!b#)uAr4FvQx8*My!xf3j)a)=*_4kUsXs-iabwgQ_WEvMtCgwBowO5tI#KC(pIo)o6I=qK&Bb z=ZG%R9{}cLCIW(?r!!3xk`irLUtJxT_%-2Ky99n5a2ofCe6#Xzd2aV%vqi^s5~PO;j*XCcfX9-1zSxhaHTA z4;m*r3t_HH(=ADJnyHV*uAs1%?nHZ(P- z*xR@vBl~_xps71k{o-0?UcPZ&?!JaMD17!Kphbwn*|^c_0F)r)w&t^cIiP>wMl-TE z8wX%0A|5ToDC&AW`ml)3?m$DmsRphzA z;V~Fd=+P$=RBk-A7C|AP&}p?D2(Pc`3_>2<5C)zy5}tzXYwn}mXKX z45z`gn1`wvd-pA)F!>onOa{Nob;^9sRhS)`nss~ORlFqI{nrw&r<;(n=h-lVFu~*= z!X5BnnwCPIg$Z1-FOW)MT}X0(raaLpU;g(ie}^_(y*9Uy5hqq!(xa@?XPaQHWW^hI zHpyJS<_+Ca|kaYS&s(6Z7w$ib0z@h22B2B*_`0U&f4`1mjgsl)6 zhce)k3WJ-Jp0;my)Si%8`(!F+RC3Xck@;i&T8!D(D$$i5lkN2*1(vA*??)Rr^tYYI z*O!l58^?&eAjI|j@7laWrbUi76T12>4+Y|%!JEs83Jcw=Y|g8@5&NeA7i-FBtYLsM zhMA$wE*iQRUmP`^%*eZ5H&%yfuX1k~mZ26i)jGP4XAI|FbG(MP3lj{DPrrY!c%r-= zpNor*qQ4JHVFZ|*N`4r*ntw7tRsml|6=lr&L;%#)!Ed8E_0y;w#bFFlAYGc=MC&MweHLFKchea3)qkQ{EHC8u%iX$w=a9i1$yMgxUdye;_Fe0Rap&(j-lyvBQhHTT91BHahMI5agie^zbW2_5}bq&Ke; zgxN=97e6ZGdix(QSRW4Y2K^lx4Bk9y*{xPSNPQ8!n-2#6-$lwNbKBc^eu;*K<0DX< zDBAemaDA8CaUY7SmKC>EI3le9)W}%Xg>t}lcPDR4;GRgKca0L!JGO2; zZWvva(jZz=Qs#Ms2V3#Tz{!}y9)Fe&*u0;WHR9U(SO$;^^;z*8fD`;8C&yv-@fZ=` zF3-#&*Cxr_Dig0QXkh9h6yw2D?a+=e{96BV8%%`u#_3~UUE9>?(RTm;gJU_Bji?#M zU%JSEHQ@BI#G?xc!kr;psRYk0?Y<8HocsEI#gmt^#7IPuleZ0i=z_gX8CR!M<0R%@ zb1LD_1Kp*}G44~(cm(Jnc6mY{#&t1$H$-?ndCYThNFf|BsG`ZJwht5MIBYk$?)LZ? z%KEhSwMxn@IxLcxF62d6%axn*b^a*7_Ugl+s^J~#^^x}=P87q@*h68=BG9mz*!0>V zZdQ2$zXQ@hBbj_DzXWewr^)F^8=X98Cyfr$MGO^oq5bU5=C{5~`y9D7Zcj_C?*60C z2wC~(a>Nuu>kYTw;oW2LVCBQWg>zBzn%ydM`!ulloiAlMSb6S^0J~@(1 z6gROv`0@L({rJ93RPc9etA3h?fmSCXX6)$|-ow%Ssh16_(!Em98%p zcN)a`8n(d2>bScTx_NYEW3BFJtLXJLm%q#Xy}kavd`S#XC{St_1d9?XNFh7+LRqt8 zqY)}d5lAvyVVAb627>KF5*rnV4K5< z5KM#qaLSBBXElsPs-e@a`HQ3$_hIn>i#8S|*=LAH3j;8O`$bzf5)=o#RljFuNYgu( zjfc(CN2+&i+=`j9Ld$DgCEe>TLX|-Kcxm?)N)(WAK%;MHNGbyK#Mb-{<_^EI+)zx)1$o7Zuf{~>UCB}z@XVp>|FE3LQSXV z?O!9o0veb#5)OVI_O~ncgR({T6^NvoL7EWQ&o>oU%j z*;M2Dq%-6I#$X3sd;8w1-A5kj_)~naFY1PQ83b_*tD03&H2Oj&NJzD;G*&3c%NMUa z%DD+Sl}qu=`M%1-DA?up*fb5?e|tEGqDoh;LL}AA!5-KLK)3AU&cEx7!s1z*Y!~9P zdsF;XdSYI>Ch5v+8j~p`em(~kZOW72)hH!k!?|8h>vwnz0~r3C!b$h7{r=t}>p;() z^$F6O-9Nn&Pdu6e7N=6LfEcu2i%Yde{tbnj=(3v+KP+u(L+tk5tZwiL{TbMUcX;3+ zqy)^En%QVt$|rwW9YgVC;o*pWr=FKA~+%D8Fkd8;i6uis{bJ%bz9cL;F;Wk{D~#<38Zidn293r8$Q#EAPiE zzulRWg^qiPsBjEL{o7w!9hl7ivg>DgfAIcZp7o=HI~5@NbM68ioAfQHupO2$JYPQ? z%R8WaupV+?-Ml|{=62cx+R8iLCKfMk*S^&IO$WyZi91;gPU^2;->&$J4RKmcBX@rb0(ejgPjrju*Ui z?nu1f{TN%sJ6vfwK7Z6$w9$0%%F0_bvO-IFJt}L3CcF6bzBsMwhS?=cYj-Qf09$(x zFAVeJGk38toDx+d+Vf>O2%=Ms?xcPB_6~8DB1);lEm<-qhnliFbCSEF3!T{5wr;^# z<7(9ms2^07i$IeH%TI#Fg*xS2$wRPcpd9jWd#*up$5mafkIQZ_Kti>jK;~Radlr4@ z?KIGIx13@N-JZvy32~ZyUwgg*$}+p5JGKMITvi}VkLNJ7BiY8Aq{v^q%@C@By{nBw z7oLKP6xr}~BG}qR-6cENFrk}B-TbR71Q#?#PiWHPDgRxj{PSfhdnm zmUW#cs#~dYR0KP#4e3^>QY0=(R6THp}Cg=agdfkzU~ zu1Zg8>naocVsGHcZmS|xGe*8!URS4bdIKA0;BqtI%tOZp5&O(SOyqg|d7rccBvvGB zM$&{8wEE~ROcf5`wla}xoJ?-zOjc;)uQSWb`-g|v(i!EG!IN=Z<@A487jw?ie}BO1 ztC}Wur}WH*qG(S_SnU`vxUa4X4wCC->+jqbzb;#^A(J=)ZZ$_5*~<+#lx|?u=%DNm zd^;&>Z&o?4tk{aR1H)$_IwT&suj+sMomMJAyZVJCvlpyYMp)Rk#_t&P-nJJ^Tn?6o z@~`OSNN%0s4LlV(zVgqx`Lx4g5E;a7b+;&_M}L+)?6pXEr8XQk12Q;U&aiHOeVF9*9oGYq1y@a=A*x%_c3gaBqA2TR@Ac_heqL zlaf79ktVS;(n;&JDhb7OpHeYC4+-U$HraJ4v{2Fm&1>4Bdcmo;-wq@j-%W2E*i?3O zB-PQ}$m{uuN{2(%M?Zcl>`ePF9s|W8x2-d6d#X7AEVQk~!HOO1rx-S<9}2-{ysR`` z+UjrarS2DI^SdUzpWN%IxOaMH6ID*mw$~&fSUe!Ypw4oDkuVM5fB@WY!9V!-s@j4J z#_RI9bNRWi;&zY}w&yQQLrrcZc$K<-U2EBSebWBor1#`Nvv{4i)-8=!t*&|Zauk|Y<#my7{BH*We&*WDxbpt%f3o*C=m)x? z1X!EuC6%-2H<*T3aZ-%%b3b30S&1h-i@Xtc{mA@6fVv|SaF}v_E(9+h`0!8Gmy|Vj z|1^>VWb7LR#{U->wjs}ivm=ZI=})P5Wbk#&*=FB-mjnx=mttHrgwdnuF_=P_Qk7R5qz}OrnAZiT8>Zdn zp_2&*3|eZu30^9-wxLppy#vmgoP-5~Um3-THpUV8MZ~i#^M-T*mkKJ9oJ@!t>I_9u zhqe^2miJU~5ZU=4BE{K$w0@B130kZV4yd&%>XIi{IA?Bc^@0w6$>w{`I@Bcn`tlQsCPF-|e~Ijk4q8v4uwi_k$LjuWWQ8EMW)lH#(IJS!qBvv9RK{ zyAsRw1k(gchHu}efh{u=&?Q_Xx_Y>6HM1xO==;#p1?rzYk|fJnH5DhK9PGYnuW#1{xDD*SnS0t{yax?H?Z6Ywk@R1Z8f7P#u&a*^9nz}l~4ha|X(#X1_ydQFCef;;u$(_O$qD%1N`tO;)OYI9| z0!qOf9+TVxBkTJ;CC|CnM|FqA!cFO? zthPtSkgtXe1^MX0_Taa|;L%hzRKX5XJ%u15WZ=jbKP=)@@CA|*y(R9cf@_&vphGY~ z;L`e^C=fFZY9t(~joITUTGdH`QXu?!8B>2|$kEjpw%_F+bN0%+X0M&RUSEf`-i!0-rFW~4_rbH!=W z0zC&6XK&YWUVzMD#^n;1fR3LPEWpvl2@3I7>65kx`q`yfLs^{uC|zKW@_wy7Y;>C8 z^u~h6IVHn<6dOBCJsCmzgrktzKd#Oq@~-GYlpe(7o_9v0?c`*2#pn5k>6h3SAMwvO zd4~4AXN90{;cd!=bjQ9mxW`GM)%me>$jH^KE(5Z?Wf;8mYkjGj0Y@k_vI`eB5x|T6 z!J$f~$1>Wwi8CQs5nC4Bdn!0+JK%K(czTj*lE1ZaNZfa414R@TF#q6?RIwOEi;YYZ z=zBnSDwTNQR^iSHk!#0&1aw|<*EcMBvZjB=F{rtPt58#G6wrKR0ms~1+o^FPVhIT8 zX=8|dsx}fMB$W20r~QFPkbJ*5!H6)bWB4sRI-3c?mo|()_!0IFR6@#GlwQO<_ly3j zu=w0s;*NXfr`4M4EAuxDhC9j<6G{q$_vc4=Pv$zc59gXeGNy>O2G-H5L$kMyCoHV2 zj#u*&1LMYJ>%BH(|D_oGzZ-SDnyM#TU+-f)DX$O&TD`z5`0H1(m;3Za)$^B?!VyWR z=abD_OG66L4>A`IpBK@aT+~(k8$|O#eF6S-ne}}eWoGOJd$UfsyL*M|rgn{$gx9&T z-$O)3n>3<0=QotBPU$=`uj{cgj+3nbhh~}5h4e}Bm2&{N-zSbpeS(N(nhzPdo0Qyu zd?+N8*Z2MkjzWl^{mVJcW*Ea93Njr9NtlNpv(Iq3nTv61*~Ve^*Wh%XKC{^@NEEdv zPXhz!MsUdgN96!sxnwvNc9x8i6u1?g^z6?ZWeJ{*#eIxIq!Kt)9&YR$xV3D=x7)1x zHCnc8SOdEDet*`QZx-nFUef`HslNv;2aP-HlR||*7V~FqZTsW~d@Ow|uTpW8sGC>s zn`e`>kxw{M@4_$|(LGBz%Ay>3DLbnW9RX`Y7rNU17JuKru&HK7bRqOSpA<|pVibt# zcNd_zu0%34ie6yw`et!Fr+3nxcsv<0%`H+Z;kG=sz5J-r>O3PWgfR2iNVhm|rN^DM z;F89=srUvsTh)hv-qZB@BERsFvMc7dvOArF@Sz>Buhe4hJ>ZI|e~?q3H~QN80yGzf zym7(z=z+h_zt)YD&FQ1kljF|mgZ1_P(zi5k;31vl`nL>imtg|J?m1LXJb{f}u81nC zGrv84`w_)m`QJhD^oA_WsbyzGW-ZD|d4DSMW7Koir_A~E8LHfiA3hKu9`2bQjDiSy zuRoY87O=4JPys#++g(z!DO3bmbvhI!$T-x<5yUv~&fhbido)$y`W;XO0!-|MFw~wKH>lt*1V*sQ@zF#3!PyXEiHkG3ZiF zC+Zf;zfw+0Q;14vgA@9)L{II*Rr6f^>2bvz`0Pm@5>6;yOrP;IoWL6T8Q=zCLKJ4q zjSZNFQ#(xQ30y#c5s=yCzutzuj2~!-SB3NPOWVhDf~_?r1u3llr0>HVhzgcRe!x-Y z(?liNpp~Osoo5NKyHDr|cLyYnxN$I4wVLqqHAuqBS)P#{PBx0OnA0LN)7lU05z@|cvOan8Sb6s` z=)^v5yjQfdF|E+(wY@ad+PR@9r*QKfh!vz>(E|{&MhkIi47H*J#~K>RW^Vx8ox?JT z?=tS5e))H8O?+1-KsIhxPFIIkyVhfBA78SJ)e3{*@h;wG6k`KBe*p-8s>v|XkmwRW zBvKTSQ6id^%`;u6W&lI8nrdmHg=0`^!U0bZ(Yx^7U(JM$0Oi5i;1(t%gw)Y#mS4*T zsadMp{{s4Ng~hCr9X z;fSi+S6|QHufJICtyE%aZsY?TXyw=NBIUrtW^7i!mRA|+_jAFwdKy$jTi!KKYR?*t z{(D}nP=`t*7#jy{c-B2gVC}wo_uTp3p^L~}f1sst_idE{9D$vn=?&il;HODw{hEjt zTKpbdKi&f&BiN)hd@2*MoDpbr#MgCMypx+~?w20U61X6zu}$)eqr(yZuVbLeFZ3rg zyA$W%nn;ho>c(VADSVYGNt<{hfT0{i}D8Xy%8M|cl^wd~C*@81vJy?3%aGcoAO z&D{TE(P!Mzt$wy9%fXUzg=L*q$So^-v|Z=oEIT+*MDnND8Hf+|%wv{Cs`xs(=2SJ% zXTv}xCC%$r-e>%L#AUY{nH&1qM}o;BA4yX&$IgNO_O>SyN4868u}`;x?RXF6hF0b2 zb50FnUJx*qSf>IkdRys+9?GCcb^ikNL7x?LhLTt*n!zypWsn1goyiC#IGkV#+b}{e zumFqtME>F8(gM zIq05%ri0MUtLurQ$!1z&wSPVqA+qYac}+Qm-~k(HAKLQ-Vj%Evkdhv$F%{Pv)TQc= zD7GWOL6!a^_F_4Qur3BlXFwt$C5z-yLbWDl4p-A~Xw7Jk96G)O=B>#jO$F;}#_%1b zeR%lw9#g}yG%+n(w~;zE8!89UCI1>@W!>j*l3Ox^lvy6zyLYKFP-k0g+=$Hi$nuh& zeqEFqz-r#<_y&F#S0pCXVC1`-S8gD2<351N<2K@0{;kf9HpaRA_iv4*Hv~??g&}dL z>;8XO6X|guIvfevkLvhVy3#wL<2G)ZA2$Sj>9(xkH`p`mASH|0naz!>SSFfl!PMPPshNpEXaDxMKeA|FXQ zSvZjgbcGXRooOVoEAvI41YzOSAgb3`kI3lBp;&wSZnk z>{b_CLqjO;R&hST_Qy&;N_%Vf;&kxlQnM2l9+?QYmFl>zbHH1fv0MA(+}`cuou=dc zGe9k}e*j`ZEyo{27Srm{(7SR;U%Wc#B;TZ<;Mq(BMip!i`-#)rcaQ#cM}c)SZ^+@( z5bzq%>kITSN!+=>x{yUR-qB6GRZ}+E02|>o3E1C z;QBY;YjXHkr^rbJvK1e|jNXYi8AhmTCxN!`y|%nEYL&^;PB-(gmi@m6gCU!*536}) z*8lrYcGc25cuG(43@f?wgBP2)2cLFQ{-wYWbTASk^1E%_(1ohPav4M|OTCCGTID_WjSo_~-dDHUEu54}R4eqY+Z{pXnu z;#nbj!vXDqHNJ<93{u$OkiO+7^=pju5U-?LrBe24Oe z#Y44HbS}OjSH)CmG%Vz0;aFo#E=?D&->fOxxqQ6f$GM^Cez|F6D&(uuL%W1Q!stN3 zesrBJ55Kzc>dg(yzj1tMJ2!`L!ZY=!RB^K0TpFJsxX41`2s0I|;Awul^bhK}_6DKw zvmH(jVSH*>NSL(*4_b{vCPP&;ZO-FAs^oemAuv)dk8w%-8W9afCdG4XxRi(_f)$Px zljs~&5a`K|Pd3D2g;*iU6bey`H!uddLtJi%#yr}vWyYvOu7k(lmRV$+YieG;{yGte zJ*0>i%hi1QsWnRtRVW8pV|#g>b5yyT^2R;d)m{U4e5x(V8Vc8z)wSFTDtZ{nV5EBT zb79+|ei~DGU0p+)vVCNwVfKZA?*73P_hZP243}F>9vR83ItU@&EAzCAu;BsJ-RE99 zZU!|#rz}6W|6@TY56Gf|H&pNb$N-h%lHO0;Nb1f@-l*44-)E3Ehy2e#2%2u*21ZKs z9G^@}De4i~3WM6!eyuWXxHda2^Re^cn^SIeS(Cx_G&fmVzvN%cBi&n!f-%U`i^3|T zyDC#_vj2x*bk>zm2mG;XCdO}>0#=7ZHBG0Qw(5J}@fW>T~hPEw759khFz8M_2G1WYqn(zMRRf!bqQTL1EUx^`q@+Cl2w7vJ~ zK~N$Y!{EU9QC_wak-fD?$sjQfVJ;5~M1Jr9Viqh!nl1^Rw?;&t$J@BwYKsn|vmcm| zvkQ5w((_V5%^(*ZZlF~jsol-g{>|C=+ta77#Vf4YA9B0|I(9QLPb)pL%o#jHP?D>9 z>o;j+dVL|k+HZaOq~p1Qp8nX`_^s}M`*D_{oKX97kQ;wDS@wFOcx6?Tl1}i(p&8F) zty>0PzWy`*y5%3sNyW>lQ>AV78Q3o3oDataysM^C{QWi-h2oD zh+)2@^BA|Bqi(RH%6xG=>ZdElGM*e5=agytH=13al=s~!G$Z3IJrjgENAb<$L%59z z_rfO;q1<}R+r9X}!BZl*uvZcK6Wnkv7}6sKDI8;#(Sv4{!czzf=TryYvPVS|gA3$o zm~%%B^>1$CM1}B3tj3uzygN)Y`F!RFKB4#V`#52xhZB*aZZ9eL=y-9j?4l}@iz}+k zN|)##V;RL#pF|VxqTK{sCmUbImROdj-(DI0{l<-0Lv=DYABSMkkt#5iwh_e*(EfIK zTwO1i2b7(T<%V(KIz;OiA}G7bwywElTa?C*apHe)EP|j0oqi5Y3eJ9)qbpQ{LV{fm z6-;&b5-J|iFPVT&fu^UhLhSH!)iW_+W|F!3z}E3_J6UQwhOaYO&oJ}e>CjJj2u9b# z7j7zanhhQ%pc*&CPJJwJ$~07;-%HBb1>nwx$p})HX+mDva^X-%C>)42eX%j0I6Js6 z1e$RsJ7#B#h+?krxoD~MQJ6Ney{h3efB$|(G}AWH>cU>4R<3L`x0qgL^`QCm0>k>n z(pmskBbA++0UDSLj~1)XW9OYUif8j}siVM5nH>mIqK9NG z%2SOvB5SV?w#E&q8F1NpU2PO)LfgZTLI7UFBYw-NR!Iu-TM_c;e#b|D?PHmRtyb3-YZ9&#iHLkDTgHXfD!f15t}g9nz3z>*Iv zc^x{V<=BKc`655#@%o-`tnBk*RO-|@P0q%!!Xg=P^vprhxJ> z3OB?ld`0RZZ&MesODLt0Ax%%`g$9Kgu7rs@1MEFPN zcaQ~O*T|D3p0rFHycX`Q64hZgcX9Loa=rq44_EL?bjUJ(y@PxiaZ7PCjO8#fa1qkR zWF_aoC&!Z&_Fus#LWUzZ9jkG~t`)ZyW2xzV+hM_vFGQSEe{Q7k;jLw9e*u zZ6A*jU&v)vrlrP$)lGQO@La2Hs&a>ETMk4;u*nagv@P(i<>kvUo3F%g(L)Tjb1B0z zxZ{6&dod(d@ z{nFRLHyhtol->gjt)<(_fyb*(_W$vl7+=$wLb%1*4@6CFi*qnP<2p+ezzRAoOFlKtb>C{ zvkj+NRb8k_{PuDL;evGIG|I%j%$dxa&z1LAi$eB8z!rIiS66fDoGzkq`ci}YztxFO zvXLMk@0hjx*zcXLTgoc+8%kRNEDO^I-7QW>8{FEEAAWbCFSSd!nwZ9Afui8fK;l3m z{;VyBn)0NT&cTX*$Ou=Z)VYJw{(p@=_gu;kWv)^rS^|Ifk4r=a|M_@t;NHF77l(5r zyg|nv=4jdf8rS}<%^#GwOzRx~8+#G*Cu%TcKQT{X5vj_4;I{_hc_bpZ5C2XmrP8{U2brztAS{8Do)S)dgo?Y=gDM z$$NHXOG%S7pNVkB&xc7I4?(gM;+CXn7vxnPy0qWDI+diMfBGC|jsmOtAYjN!jveCQ zF-r^lyL?78Wm%zFNX1Eu52}*zEGb&D&Ej-Gr$Q8&&U4^{N_fIly@k7$XsfQvRkVG~ zhdBJD@;}mE&%8tVIQiSY3=S}1FtqKtzaLXmW1~uz$1dz}mKu*5t&uc)=v9m|BOeU7 z*g~EmGUVH2K(4S~zOb(3X=&~C>qR`ao7GI+Zm*~NkKRvjbR5}Ct+&dp`2mLIKe-+G zy=+C~17FOegf}DCIzONnI6N8Kw6oDy)X1>vog>A44pm(~vPK~#s0(dB@WCP_8UmNP z+ar0-3(w0e)2?{nzmRPT{)Uvf$Yb`BLsSi#6O^$aFX#}Sfs_)YSLcHwHMFXT0Ay=K zrca8!_rhrT@1bk071OO*x%kZ`51n0!0St^Tn8;$PD^QR z>HJr;cITi+!5hb?;J}W@jRietk_dk}@4tWO-Q8HT3gkRq9hs!_N%C6A@>-(H#&??#m56pyaZT-*t)Q!c}rbPKi8^8dDyEA@a z@gAC5QX;kZL1j2_Yk%#acctHE!!}Mn3clZp?0Y$<=h@>n%I#J=M!0IDJph+S+PQow z0i~66i#IMS%15cnd#{g&UevlR27cezk-rUqGzzk(q#*pcUN66#Ms~2wEfMG_i`>aE zw|(&bnMHZwoZ;VPq^0dR38ELopqIC!`WIpKCSxQBsku?w@gb{ z4>eR7|GcAFj4)kJq3`M!{3;;vTDxhxcT7jxvre8I7OySdhz`ux$h1B zS5dYLOP|2I#~t_^lpgA(kaP#4;D&LR`Oa$kjF`F&4w$St`_%GIyG0dz+q(T?X}j++ z{mb6+7udU}(P>6_uKWTD462!wZTWV>)%||OYYFR?!{w*bhYN!?4JkHHpNJL0}};F--R9 zz6qOiG$A(y%g9DQgW~ysjpt}TpO~0<3M!B*YWsnW-bjT(^(QRtpi=R!-<{I$eVrot zf${o|<&mQ4`Wk}xu5*xr>!o>Cl|qRD;6eOnY4I3ssd{#-)w5W!y5g#4?jbmhr?K z#r?mx!P`3#WIlOA_HT#$`K@=dJH!&ayR^ltygPTMC^4tl_rJokj;1Dsmdr})>ay+G z2DlHfCAKq=B(}5yHl9HXk!FjxWy!W8XS;4+3{hbd%x1!H8i+{>ATMy^2C~^su}MRb zcx)K6ylPJpKEvpp@Vp6nlFBxjCaogw3x&eD3^dJpR^cG6iJrI~|KeU4ih-Je7ezql zjFz(Y#QQEWyd2}sSZR>z;CA6veB^!dQJ}p1x^Ivtaa`w_Rhp|Wf5{3_WWI^F6Ftuy z(c`ERhkp5i-r`#S{@;QXPC?L=XmE;9OwU2m!;X8xP4C~!!T!xy(o&zIuSQx{-3;j7mk3d`Ysg_$!mPOo4=1EIfB$_SUullO( zL))4$b+k|f3`n`_0X3}g7P4UYS@qUbREC!>$Q~rfKjq1p2-s+q9L)C;FPvaleC&s$ zT8#Ej>_wKZ?A(#PFY#LT;Aea3cw_4i65=@%T6aq^AwSEK9PP!475!Exs9+j|D3|&-3Jm46>p5)uHw9>s2MTM#VI9i6MVzZZ4lBIF1m{9 zTt;dnpUga0qHP@7n$xHg=C=l6&_8Rap)BDmAnrzdh^zYZimiofpA%H$t*CuH-Ve;~3$&54>wJ z1o%R>Es%40C?`m~-&dE5{RdeF=yy|*z7-+QAF>t@o=&FNraL+Ls(wwUx^{=qSgDj5C$6ON#ep2D9V`( zy6mKnroe;IsmB|*KRbB5v~lxzm4$Oh*;(T9mB~0W!Q#kr{$iL&CAmxrCCH!=M==0j znTDjeIKgX4nGP)q%ouy~QEig4c8>`wITB~)pNrYbkh@5;R5YCo_>wbao@13g6>_)> z#A_kPvnU+yr&OqZfj2ZJjuk0Mzo4xF^}=Iw2~|8J@~Zf3X*et2rFYNB8WbEtmLxLER?z5Z&8TcMedP1!!WGm zGIA}q$z8eS9zqBuw_Kv+e*1m;J^bNMv&VMM=e*yq*YnwKMY+5nw2(Iz+cI0viKRui z%?WL?g4ZvJ5e%r3%3;XZ zE{6K5QpEKQ(iWa=BEIc^d~`_NP-va4XGW*6T6d-S{Ba)Lj)7UTV8SKO;V^mfeZM|! zhX*W%XYo9Tolruu7Q%HVKLfUarWvZB_?pv%I@S3NkgRTkQ2=mN61wcui>s)-^bn+q zD;bC83n2++!PDZIsPyM?mdN0#RXb=9A*C#tW9H!}MiwN;bB1{mh-IzW#@8@)#9vbI-CG%RXoy2; z4eiWtW^i6L|2j2ADISfU!>Xqd{=DauDHFEdgi9^3C)zpLYU=HwPu@{3NMaBXJb6y` z*X)aG8f^p`jE{oRvn76p2t=|@bQe`m@3_8U@UB9=f#4X0`NJ5vB$&UGWy4*`A379w z2J#j6ZcT`J4DXTNym<@+BcLsPl++RL-iMmIaem%a@o4>bAdI~8DP{L)Z+Y6I`bf6% z@9`VY?Gvss8_SQuiKEDZXDj2->ltMt?>ffJh~L0W$Kbl^G!HEt*oNG%anm~ciTuj! zB)LA!_4}{H1fXjTDTy#J-HE`wf+X@*tt)(;;x-Qi!VS;KHLq~{#;^aK?k^tSY!Heb zI?d~(rX3)L#PQ~l=;BJ~8P@xfeFddXEB)MBPg);`6%=QsEchP06JzQ^h zs(4++DTFTDU#ARlJG#F5w@2uc(_A%B&q)L=G^g4JR~a@b2vqOXgWJWgDoGtGLxVr8 zf(^0ZnBNI*+U7G*?XHdpKho8xY!fjSM~1$h9syYVcjM_vBi+B3LhwP*bJfLzs;Jq! z0!sKusb|DN-D@JAP*;X1THajeVLu4;-97%ko7As$Ng>BK+4Dx(dG_E^6+PSRP`)IO zNNg)?U{`Ke;-X2uC%+k1z9J^Ldz>L)L&-J7`*g2E`IV3| z$yz$r$omPk^dWGN{{!*OWZ4^>jf^Q0@gXhv2k9`C_l^gX&1+`}%?UR%?u;@a+asD) z;34r-x3m~ydZJZ1tzD-0v$lUd(GEVz6bwz%fpVYK&XTIjv!?@%-Gd)@`>*~|FA38f ze<<+2M^!J2L~o}nInPaisIcEJE{h#*7cN;Bw{PqC#M;u^yDHs_YGV(HgL;}VqF#9W z2R;e(sTy;>;~ImT+BJ<)2ko31TfRAI3@26q^`~s_Z_l@9ne(0d_g0vStGegh${un? zYvD0}TO?S*QdomjKJ?xmQJvlf*BnF#(3#0`x7)9<9?Hed6~G9_CMT2>|5jIL0I6`q zkbHk%M^9LFw16K@T!r(4bPXxmOssBfa>{wC5kS@Fd*?PafAe>S5-w!@<^H-dZ=dc5 z9XKu9AN0=D!%4?p`yCyKNH7bZ&I+ZSC)%tNBD@BC*GeCk8vF|%H;#Qhn(vuz@X6BCp_9#JL4R-A; z)0C?|Yt}I*pFx5MQTVD*C6!5QWavjqxa->y5^2aSWvolT3XGBU^w76{-kIweNv|#J zzH1$$a1&GGy*72Yzs;lI=i%l?7`?{()pWZ4>9!Ylep1E1hby~21%`!%50^w4twxM< zV&Rf=v&^fPlhd5EX`~$50S{ep;W&qR^dR3{XedtPiPk`e{qcO;dDo8o!$ z&bIOK{>if}=$N(XK&jsS)2w~5NE@6zFCBfEQ#xs8ZmzC-8)!`;rWjkt9UOB92K#?V zaD$E%`Q|;2fR`t+ao<1jNapsS+z7@rO=>P#NcL|ZX05&`#jNVOz1CIw@wwfcxt}Mj z9Mw95ba5JCW|SHEeoeCr)Tkdf)WdMmwCg5%`l>8-QKyslsLyY+8o2&_zu<#Mxpppb zgkn;17;JhdTx(=Did-1!>;mPEclplUl-qw#KwsI|y40hYI`AR{wJ1KmZ> zGit*%*KJ!Nbw6GKDh;FZBBO?!etUkmkqwJRe$cMaUcaZkN5>w`zs0Nl78H-U9I1m? z06>H!4$2g-D7erjJ8$>*XC60Grk>ex-QQeH;wkXuQh!h|AEVRr!7$OR*#x~ zz6#4uO)xizE!8;nD5Yrg=TEn)(z=t37r7RQ3#40UW7|`fvi%z?guXe_&Fctwc2vdYnXZJ<1%=6l=+o1SvpDU%dMC=47DEiOvF5Q> zN76AopGl2537tpmw`4g@#J^NDE78ZQ7krlQ@9;U7it_9X6S>aYMwFe19r5yr!+~_M zqH*yE(k>Az5{ttKf>@nMi8_;G5wde0fYK7p)7tHp$-!?r@F%O zg2gic0u+D9p@RH~S$lEy?Kq}-!rA*D)U|D~;fnxsw%eIG z%7V}Jzu=1w5yTp!Z1J~BN|$I(!N|Esm6!S08K8apt}kOir^*0S%acbgyV^mh*O)}E z!1%N!vzH1{e7BnU!!Y>*p$yGqy)E+LWJ&Ac$~N{ZbKE*h;Q=onESNH(pToeBhVqg^ z5lcnI0asmqQ=BPynDKru9fV|(e zLdkrPDz(6Zc8%%mfLk;D{E`C208=mvBtnH&-i|0Bk$~Z~WYp0{upRNb zGLeu%Gsj~VV&*bc$PFhf1#J^z_P)7+xa7R_sq=JY%f#Q$tjA&q8s}66T`F^{f zNAXa(PX0~$@Mc~nrKw@El@z%CtUsgn3c$#eylAQoSYtfqVYnQpH``PduqJezRBEHV zFZ+hxn-0;ueYm+gUs85Y@1Y1x($uW!;=WJA^;LaG1{@k?B{G4aR$ewiL9{69j>DC- zC3ptj@IK3XW_s%VI9G(wnmqD6b)@^((U|Y>IEnsYO|3Vr*4tvF$k*p+c6VXZdQ~d- z2P(>z_g>Er9lV}xM(wFkn7al`klIW+hvep>^9{_1#2XPhaRPkkTYlNsqs?U;@u9 zKev0;{wjZ)^!jhx?Yl?c?kXN91%l~F;KLNo(YoE}=_BVG9o?%_GG;@bBM+@l#X;@4 zSu=Vy*WH<`>1xQ?Z#K}DfbHm}gYMDk#-pD+hthjb zJbfA_e#r&%YL69uHV@I}=R)c+DzIZw>cTPQcmsjh&sC+y!(#M>m=Exc05VRUM(|01XA0*~M4bm&d+F(p!kLn#$XpnpIx(9DTZgEPvt@>a3`%LJg19}!NEsFkSy zzDI9F=K;bGxQpiJ=Q~a4C!^bS^(Lh^-3C0taij_Wm>oKM#u2EKCwOi8C~hJYd`^{2 zt@P7MnsEj!Nq_I}O0iR2BM-&>{SBmGb_BW&Q6;{|ViS91w##RW=knhXeY4$!+RG0V zfM9L!ug|cwLTjFVI?aAu|H7Rxa-tLrQKW;f9<4?R@X*tVBx0nHDN66y?Jnw^QsGS? zjBhu%XZ_U<*&r&5>KTbr6S2CqLHvmRXtMoMVXLnm_%)6=L9ZTxcqWr)BCZ?}aK4`P zhgE%J!{je;_=-SXa3aw#(G(N|2NvBm*5>M#=0nbNrTF2og`}FhKJ!zQ9-c`kqY>Ka< zSYx06`BQ_tb>{~i1Pg_{t`zs18Y~sw*M0AV1k>+Rap-oqR1i_J73MC|p_m}tKRvK_ zU5!r!mV(=X;h-uap})!H?(f4Ql=^xrHo}&yV*Y#om^Lw1v(NfVG2md)<%`9%X_68< z*6}|sx0%7y;s^Xe8li+lG4ZnmCKNSs#L%&15X*7p4H0XEbhJEY_LeYZ-dF>GzfQWg zp(MWC#j`lusFqL(JFT}F_2rW}LYWGCi(tc)d8Yxf@UXa{VXV?=``b}VVPRyPSnRQe z<;-K_T8`9Hfeq15&a*0M4c{;|Vwa?}W5DN>9J-TZhiVIS^+s1Yy(U(t< z3(ZUKrV4Rt))l@s*L6axh^&5Mf!Xx1XiiWl#hLQHJB#1jIy(zj9qNiJNRvO?ek^1v z`fTma%)X3vA^XXT6v5)WAVE-CX)dW5^E^hk&-YVkisZZ4hzYG8$ylHCH&c(Kf3DEM z7~k*1`FR-6x=>tUmMGu27mpc~b?JFeCJ2ZGH3=)Xy?D%rOyFg2o4tg83RKwZ)W2N? zIOZ<1wxG~N=vx+9GDI*~Oy_r^xFPggn1UV*F6GV@&8_HJ@A&ITRauuyPt>LgjlED1 zTW)-T$4Kv*`i~?_E2U9ogvFJKfA8BtKC9vp&`&3M(S1<+yjES8G5Kq0DN1TojZ2U~ z&M%mD0y^|J?kuQx+(7JM|D`v4QvNUK0Z8A@B#~lE3iC>rYD)l zldzA?A#@?}8?zzI#Bv5uK8x7V%8B*PK?)@1nHN8*Bk742Jy+kQ+`^-UI2hP%dN68Q zoe$1{1p+mq6F| zFL*$|yDWCNa(9&RUP-SF$z@m+GYJf3GR<2m%Dwj7%{kXNvrS4tX5a91}^Hnw+^S|IY##SKYo=_J4a5$Q&z6#5R& zAL)IX$(0l#f!Wyu>AOGVcZqEG@Gs&tG!!lk_7I>pvFJRBYB!Os3R4YorM9ssl|K zDeREb7CQSYZ2FP`HxBac#l-fZ^qHWVhlcf;Hh-zN30e?{i2XfOzG3^9WyR1zmO z8Iy=FKztR!zL4B)rhj{FX?}8fbo#(JL?|MHTjwt_>?6U5H;To528FfuSv#ue=vPpz zdy;O*vj-&AEk~cKqBk}+YD?Kpp749Ke#1Pd&Z(B$FmUeGvB{~+M7o`pzs91leyFMc-D?R_s8PcM}OBs`7N|sH#C@Q7z04 zkqd#tsX~(BRk)U4t8e|810KlDf17G*v}Fwm9Z44mBUAb@WtK4L+`(0Q{SM|BTls#R zu-UlJI!J`(s$PNF^v7DopHBdjlGf#warZtZJae`fWW~kje3!1RC3F zV9F_URN>A?xtEVT%+a<)u5&)Qk_^Wek1Qu*31Sap(ZCm0vRqp#lHsO{XGXedrMcsS z8LoMjRAEE&oW}D;j70_UmC4s?cj%-whh)wz2tY+00o*U6w$xEp6Mag#u+X7IW7I2b z`Z~8S{Wl6E=pOt}8LRon8Qaiy1aM7DJ)l+&jEk7r>)20x-ppRr8jUV3dSn|BS`q_( zL<)4v#Lk9PN-~giW>_!_y>>rB9LH()6Sow(pJ#o#W5@a2mAl=Ql7IN!#q;TpXBmE$ zmhAM5Hd+NcSuSxvms-FQlFJ9joSe=6a246|I#v>F+rZ|^FakA#a9r)}^|YIEmI*&n z3LQa|d=7W|-h%eJeeT#9$;Ze}(AO(TRukh$6Ap#6BW7Idc8i+g#25sq0!Ie~EOeywGHCHH<83s)peFsO$sZ9up{ zqG5jvL~S;tBEYuRS_z9Rf#IRaXhhSh9|Ejig_r&TyL%wakWp*j-!D$m zH!w)OYSH+0jTM(@^ws%H3nIPHu`cwx>7&jVylL`1{!<8aP7aACe3j_)v^7;2WH#UdMD^WNTCgNVNjMf@lpv{s!Ad*Y?x74 z@?L`fJl}9`wwXYyHAOJ$+Ro%B`Z58i|C3$9Szd`*tju%%xZR@a|L}19YZBTvf`vF#n-1tKW{7UJNbUxhV!nVWATPu!yC%>sMUtou0z$;pX%KJ@n& zz=rg8mWe%MDh137snQ?}E7r!V6lWDDPE*nS^Qvv+V3aSVg22q(i;IypsO zldLO8I3%n}4k1QsTj=|z7X14P3=R6eV*wtQl3xTb~^2|Z`i16a&r9CNhNA||AL z$*)OKE}o0L{Tr1H4Yt5gy7}$>vq8no{N4F^yL3Aw^o~P3EQmK$_&e3mP6vMnNr#Yh zq$UgJSHp1lk6q(QNwyQlRFCiNBB-!LVTlKENGQ9S@JDVNmF7ujAd=U_D){ZZc1X8R zx5nWlrP|@~@E?Z(6d_*9;R+T*75Ik!RtG-;{9OKLj7T#fHMsj!SR&KlEt^VMh|U>g zPahlMCjp8qMhmoNjJ^SAj8U4NSqBOB^NrfufYSmBDm)~vXhJ&IypPw$Y{OkNIHP<% zX%e_i?>*5Y4^%zY-50Gr0O!U!#($dgTqG>J&;e9B^9miQxg+2RR#+J2HvDjiXAdzW zaVGpoLem`|6ZC%sz<(`^Snj>7uTl8U8T9qI7Ww$(Yl1a7N<29w=u__?J6MA*l#pZW zH4ePKQJ?295~&naWR7 zCl$Y=p9{x}O?!_oDID#5+F!L&c}26g#+g+E^~cGfgKPKKy)9>){hM=$bcykeYeFhx z(vBq@YMy-?ZEc4g@rr+tXNF$K7>ixk(ZhaP`5=E(GF7nj(8~qoBsNtg*PHDM zY+t+%*K;c36)=a3V+{+LS1#SOvytNC9jhH_huFkKLW{4diK>84mJP1WFxUuZB-`s- zQ!jVJM9jcA?R5O5EBedMKE|>yKAmUOdEP3I@vfT)*sKEyz^li-&P`_%&710g^Nn0i zGEy%y9pPl{OX(Iw+MZG=NESp!gvy*ELQb+HFJAj?8>sRP%j|*DncKdIeNL=E0ku@aR?|~%MF+nDPB75OFk+~oFlWRQ`7I)oNkw5H zzc%|@3Hb;d5iZdEw5W2p3yNfpywXP2;S(t8&33G#VZf#H<`rvIBe~?;IkzsG=n?Sj zpQ}o$hONsAmzaXx`@ji%xaAWtbkj6Ps|ZmuaR6SZrF9oz#@doL!Nf!Znw9(!orlPU zVHOa6>*An1U$C}4B-aY7qn*W?H#F6bJz{&i#yYX8rLJdCHBu{lkN9!C(D6nV{Diw* z&VNWeGDb36TJ+uP8tpqnBU|^YUW?cigAtDBFv2F6gyp#QdeGQ_mV$lf^K1LG-3sdo zSXDGt_xcW*%O<8pz73w1CV(o^jv!kDQa0KpB1>B?N2p-&_DHR)7L&0Rf?oZqAn|m{U~wEli*a~rO)whjQPfNvvXfA zZfLc4b$=U7N@eRNv&v=WbaTadKD<|lqBaNMqH{B2>DE&h_Yg^Nykkxk${)>VByv$H z5lgzEg`e|Z+z$Zx6lG{ZY;PJ{L7@X*+2o_@i3U|Mg^4nhkY6^S+lj zzdBq!eXw;Eb=RyYmXNJ+GFdYX=%$jG^9n{eITiO>6!!+=k8x>p!>h>4h9!4%VL08f zS`cn>LQ&_#TMqU&&5^Yin_Q}oMuH;O^wlgOIIghbWe4geA47s92j`bIH%$K!$kngV z6#7=PZ{AeAHo}LWsEnSAB&q2o7nl$@!Ul&2NABocNpEv=Eic#PuZ*LZ{!uuc>4(SU z`jKa>q8hqwKCUjAez8mUi{the^TDP`Eim*%xCm@Y%*HgcY#>-=t;Vq{&u&1w@{7*p zRn~o_=~bDERiaUXvf&8&4lzhXoGv3fiOWy;rQ_Ul;hWC)75c>SEp>8MEf?3>Rj?`Y z1=v`HY$9J*sE5WdM_bdD@Bn1*lg-DD47M&@(?jL8Jm;{-yTQ!~ggE2^1NPOm!gUPs zKECa42s?osF~t-${aP?8tdUaI>yHo;k)HSDkT`k@`6BFym_A=7hy@TmR8P;8E)F zK_K`Qe>@quAAkH?@u=x=`}pwqFcXjzJ1h>`nqKA|-LI-tyF-V%4b~=ij1uJRI?k%| zoy5Y}ZPaFO{NlXB=P1n>g_)zI3G)*N=!Zf0F7WxWE7ged}${COrUQV4p7@N8k$6=_X~-#@&0$=YB|u72UF zv7I=(7<=|dYWJ~Oq6FTcUBBJXiPPz+Z#igg=9P~a1Hfl({am8TcOJf5THOABr#eVv zE5$9e0H0Ot)lBYEWuvk;o;1D}&j}JVRt7Pid($z~*OI<57>j>x#PXD1&-ip1mI#4DTAe zQMcC~ICT;5pfWzU>1;v1)gAFfN4t8~WvOCu~fRdH{58mqah-T&*GUMKvoFgQFYB2 zDVzx7-JJ%7bv8}Q1Z(T>sc0T5Wo}nMUC=e3ml2|*_EAGnRSqp6e!lNd^To8Yy6YV; zMBqX3B4^~fZYl7ZKF+p(ruzDt232;mp-aySV07viTAI-d z%M+7tfYvE+4>a12motxs{uz45nhp$(XE>V#t(2Pe zr8~>-AVW7wzWu&@<7gd1uPstgH2?;WRfE_rgw8tBUHo^Vs+#}~!i%JmC|4B>Egk)pZX zu}+6!t{f5(!iysbU35D$brM`C2f~3g3M~~*v0IBy$r9FP>_p^Lmi}WH)|(V-X^pb- zD1d15_mz3Xj}=qUjuVI85vAJxd|sXsMeJ&pd14`XnTbzDz{UfqE=-O3RuLga!1rJl zKGRAD(lMM(S7rOr?bxtg7yaZ5HFExQlrSQ0w!whl6|Fi^rKg8X;$@8K&=)wtbM|94 z9K>Z?y-&vKQg?q_IlD3B**@;UgcGeboW1t_fuV4jB1FJM*t3$muVu`tVr1IopFgc>a z0Igkc+I}|@(M>+VP=5avg^uuH_N&XrO!w89`ULVsEwCR>h|l>U+Q-5_aII*86#kFQ zmlpC^?He8V3^IGFM7^_-fo7TZ?hT3G$F{DR9UP;5?pwS8VYrRt>eYAJf=s8H6O7du z`pnZ#R>o-xq_JsBCc>DM@>sABZ5?ez!4$3TVXa=BoY6~DkM5_Q?$(7vx9=(huJ43L z59LoT4J18Kly7*VTXiQ#)X_mu*GgQ1v)b_!J~^sUcP)*J_fA~8wOMp6A^gzkj20tX z`|f14w@{IDnJMi1mR()lWN*@_z!Khl-YN=-R__Wz=3x`WY8?ecde=i*n6n~-gMYuP z>B{gcD#O(N^oD zfn?9pzP{k{Wvy{(ObpU0pa_NK1%Y2d%bF#~g# zQbZ5i&z;7-8iWp7ileZJwe$3;`>iAvuaKjhvBli);~wZGd|=Ypc|`l9P3 z4ew9@((kye+|S;wh^c;CV`Y_ba$#Z2Fcz8>DuWlf67eoqtu05%0$Px(V10&fp5lIV z&*&1HMD}plly?u8kg^I%M`U0rY)8k#i-0RhCVsdfd-p6v81Nm~Q~;O3Iu0`@5JA!> z;Ow01M#c+E{~1)wOTdlaaO}J~4jFU(&#mP`hl~^`Rd>XYFET=JQY^K*urLhxL1=bm zi}OBxJ(^~sCGJ`(AkYfKPCV;H^_eUP&w(OJv@PV)LL#n}9H;t9 z*uN#wSCflDimf6@VpG=QaQ^E2Z+)1op5r5G@#L?4z!n2Sp_P5Hm7%)9pdL=or#t^~L<5K-J@c7i zYsn+e8PrkpJ|Z~&P{UTWIhk_3Q5rakIu+Kwn_ArtN9fp!3JTJT*s!~Y^r#5O(3rEX z!%MC`n4J0D`BMl$Msj?ASDN26e<5%7hKFJyFORu-PM87A{518bJ;>*T+^e-R?L;>Y ztQ|O16S7N_Nu7pSv7hK`yWCj#THf6-r2wQ8{NR_@=-O?@&$Qv6W0JYjnn)z{3VTqz zkvaj7eNJZj4}sO7X51sjCj_&L8ci4$5x1(Vt>K8u<}rjfAbvw z{^>hhHF@}So6V)^#@}$%Z5Q`1t6ON*W{se<6IR#9&muKj{w~c$H|@v<9u-*x4zTX4 zj)Jqc%Yaw>nxgO4?9Yx&zpb5Jcl#oXgBgR27+zWDk|LVinXH0(46#4z z<3E}X>cLc@!S2r~&sakk=x2f2jCyJlc|M2d=I-L%qbbEFe^!jD%`*zi^d>9K^z?{n z#He$ueCJE>j#;m9l0s@k{CS(0Dm}A{fs`C+oS_Mq31e1NK?SV*%L+n=(spNpneCov zQLJ*VHQeOjRG0c?9B+a^R+UVY62yd*JvbZW6=^%jbJE*E1@WFY5Y7d ze-=r1v4P%@?;#3~%zsFNXoY@})-$^xsM@E_^db9=y1J-Qx-o$$AldHV6eOIta*KrD zNN~E6{5jgo$oR6}FbUTW2lI~J3E9V>lg4;5znCg*Y!j0nn(Ib6D{*U{-5g1Di}3_+ zg&Q{9*=b zU|6xUlpf&-tOlk6j>oGDFVV7QzTXwd{cM~XUs5HY(pM96S!%(G``I=~rahi+m|me_ zQBI%}X)TtJ`~ZZnoy0gt!+#RO)T#kJa1=y8|L|8Omy+Wh_YuZseccO@ zMi#8FJe8wDbqUKitq zPRsBOFdPC&qwcxFzlsW!WS+j>wakxA+b&1(kjqDBOOEebX6s&|E?Ps><|!50Oc1|y z=a)L)x!KqlRSGk_8Wg~kt4HDnh>TZ`2rX9)j(30wjN1%@N|$b~Gz4W!Eu|JFKPrEX z<%11p2f5oys?J4@`?;(2t2ygVGNZP= zk)9eGT}O-aQ+J;+9xu?fyy#`Z_f`$XKR#k^TC8|DJ9eArW~rlpKqDyft{hDLv>r$d z^11%b6|r~Ig+QQWzL;tXd|YK5_@@)>kq^=cgP6cC7u&7kP`N8V++6X-AKi=iEIIympF4ofL35khznqxL1z{0ZyMKt!EXwH+2Bn`Pb_^gIaSQkJD5oQEZSDA3 zQuI^wGa_C@hb7JiO7*@%y+^S6DGWcI$fwh0lS;&-HnXX)=jM_Y9xOQ3y;=?5*-|`=lA4K*+uPK-i`qbM~Ti)3X;H>oty1zbtIvE{OLqy zUX6;4lzWWeE2dY5-cqUcj}{K(;x^>bN>JnuOs5Oe0r!V)NH6rD=UmV42jEaCo$rXB zJ*uwN8fKl%LU$q5Asg~qKfWEZp!gmHzXDIr?PWaS&v-u@^ObK0yv+CEwu!(4E3Fn# zvnbhUM81eeha=SS>>ub2Mn*<&Z@Xp%%zD79s4ctXf_g|$ ztPGW!OPVEx!aVg-#i0=WXOB2LvI5a1AV4ztLe)KKxx67AD)frZcsnNr} z{&r5PhS$&HMFmyMk{EfIHb~{$=AzNKpr7wD$}Kq{^bo2Mx5BOXs0RN|8-F`^{P#{zE?rX32-eU$J0RWrzGG-;gJv%kXwmU|5_14{MQ`4$ zy-0uvKI4A-nTx;#1|%hX0OrP*T?JV0RK1Az;SzN|6=TAJ!4K2(Of9+TU`&FM5}cC? z?nu6anFoQpOT*o(tFamFR@~0cZ-9KdwDirsmDofL!B`|&G8`e8P^N}D89^vye;~ho zgV9R6=&*M#wdqK;sUe%YxVdQbF?gDkU{T1srFh02n#S+W;Dxkp{qPjmgT8!)kxV6x z3o9{L=1^hK4!5^G`ma8HXZvmV<=i!^&V5L8&V+Ko<>2q+E^UPSNilw8XEyVd$3D9= z+uF`qy4>$u!+)Qag2PkUnUR8>6stZ2>A%{oLQLRZXNTgheU*Hwo*s8g&_`nvAQiS6 z^a)(tpA6vfD=u`Xo^A>_T|6I$2NrS zUMklAPdkM^zcFxot2dg{V$FLZV6o#jXqipUZ*46d2GosBPn}wbuv`rHc{w?|RI7}n z5+6KRh;B=S+PI*0;fE5xbSOpR(whG6?)%Xo3%&thh^rIc_=2I0icJUG;sU2(8u)vl zIXyepIi}j>qxcs<88MG!iP;$)F#206F}k@+_<0hQS5Od;RSA7*NS^l$$ZSF(O9H?s zEc&Yj>p8VelF}hmBAzIA`B}3t4i}6QUcBMtiuqI))HcHbX|4%{P!naIYY3A@5~H9s zABT+a)Jhu7A+^Y>j8dO@OE^+QCB%IT3AgO(80&WBx1Pr$u+8+B-MY}Z6iHG=a9qkw zf`~GK$qFP~K!&7fJmtz4pAJfLB0-dah?jKlQ!n8EM#M9rqTZ+0^V92aIRor=OxcKj z;VWWYOF2RdR}i6swED_r26Zj&2cU1JL^&BF1mrEQ@s5H3JC$_D$IMschlJz;-;FNJ zc-PC9CAF%e3{<#V9QGbyqx<0ApM8*{YnBGmb;2cc*^X&aF6C;B!F`(kP1BE@x9UpV zlj5Bb`!jA?r0X|t-fVhDG~OrYjyzacaGC&GISR7^cne|pPQ;8?#n{&=Kz?uqEYIXB zq2;7u2fZE8@28dC)zVs`i4U;9KP`CQNfXHCB5+O<0NtT18ru_Adcg)bSSb|mhGg1rFgS(pXXX(+t9kLUWaqkASJrT4Q;W5jZ(gzn*0eVViDf@;jW5)h%4Dh5cCZ zn>T%^tPmQ207Aq4mc~!kc|Nt1U(GG1!OjPU9Ud891UMVlwd~RhC3+E7=}ea{;7GEj7kjJm+}fS@s3?cd&W&c+)D75hLSyn{ZhpV=^oABDBFU6U=vapXF!jPoBqRlWNOR`To=V z13x>B%&w^t0=^a=pV2sY{AMuy>Kh9M;mt@mR@Amw56@ZXldx)}V_(7;$yGVnK0f-` zJfC8XS5hIg`su1mS~Kp6zeZE#`+wP0xW2#JcX99N&yrj9G+oHxxW4BQ7&H4D2)pz# zyspfa4C+~_e|osLIofnMw>e?3@%F!s?`^3~z8f>%q?QlqR@FDT&kS*!YS2M)`AV=| z;(08@U@nYn98ynho`pcb%hyFPcsJZrICF-L4My%>|fmZ$CI?w99k-&krYz4>NmcuQkR*KOB@&!kbD#{q|Z zM=0=k=BJPp-qz7R1~gmDj6_2}LNV?jH9{hYw+4}hyxjMDqe1Po*WjwT-{Bk>#{8LE zGj9q|Z(ZPgkd{QKH1;;`?CzFr+Mj%UbkKi1+<*M%Dp(91T7aw4gVeRD`oR6IKYswo z##?rDZF^$EXVHD#`Fuwf>s0TMhrj3Hd~b%qo5sV<#{q|b+GJZKa7d15=bA@!gWunJ zI>!x!EuMVeySeGy#GgHslmw*FFJ8PzaXQ=pqqo0f9ZnUWy4o2~w{Wg6^MEh51FbsE z8g3=m`VE$-kH_oXuf)v3-6MX-WfOu-(QKk3x-*i}5Ds>2%kOPaVZvE$uU|b}C-H)z z1S}J;+=uAFh25a0HIZDm2C{n;YC+d8F#ghMC7fY%!C;|Bq0}d@K)INtPsR>sb(m1+ zXl6ch5e;tq7-FWz{`%s*JMBsR3B&r>8tB-oivWvC2N@PC6_5|uPE7fB+ z2c7p(?UDV6fnL^g5^*`t9z2)XjxJY`%E>pSoor&X@ece&<9vUds~c+ln#Lx#S^{1^ zKeXZuNeb03iryG%%U-R`b6QGD+H7mHAJShQwr()z%CY{-l7>WA~Gh|AS5;q5OQTJr&RucCE|6Oy7Td>xFxxFrE-KBt1Fxm0|79Lc#r)W~QdCFxd=~ zHB+rY(oED=_etnTplYRF&o*0oa+A9$6BP902Z@NqwkKxq>!9vjx)DdYysl zpFRaW!hiqI#OOGAc(2u`Y0McifY}D$ zuD0mZ>Ba!}iW){VpLR?c&uJchUKvgA0N1H2DLg?MEUqsnKd}zUC4WrgypOAs1MXXKUc=~7HM|AYYu&>eZh&~|p3Vt-fU!nfm|LtvYT*|X& zkJt;a=(*-(+ppDMTPj+7k?Mh#N2*xLm;2ygU|y?jXBT8hzN9)&$W>w(!+W*NKRBMZ z05{~qa$Tbf)?c>{XXSH>GdBOs9*wmKZD-2MZqlpwAtkiCT&K64hDt~Cjej1zc-k=? z92pqDIa+g3Wd=AP!vw`EWxxhckQZX9r#GTskr916tEBjzWG=MX(CsbcSD()Np1%D# z-(m3-TA>n=)!fn3*K2R5GYPn7hBfaH;4%$FCiTz2C+n_-yu9#rb+y;P;%L5Y6o8Ts zyjEn{KV*+2&q{1n8yEy|Qj zUCw_O|5-2AioHyaO~is4;pa#cQw4L->fY}K#od+sW7{f)J6$*(I=;l$8R?-oO!8SM zjQH{4g!F%WE88ZPQ#@WRZ`bw@r7w}PH#`5#dSLonq8~T-*Vmzaef ziVhz1`feq_9XzEG*V=hqCS<@M1Eg;&M+l51x%yZrJd~v;t=nP&8wauM6C~8v_oL<{ z_YQ~y_ud5yMwi1ByB|s}sHn7kc@<-fufy8^2WgvDkFd6k^EBH&{Jyt0Sfh@!{)poh zKz{G-ohvf9I@J*PdF zbi2zG6^;?&t88aNIq9KH(1gBbmc9jYw!+m3kgjW{K!pCOS?L4 z(HL-O$9+oW%Nngkf(W0EM2*u5M88o&QVA+Nxp2Wp#RZNwt8!j!L^y1}aa$pme{TKZRZxx^O43oOt!cz?pDNLq{48MGMRA+j4$qjla7u}N zVsdM8?kR%{5I6$vPV_F=l9;M?Q$F3~hj{jw0N~tmfMNJY@a1eS<_mT#c zCHu+d(x#nz-Gme1Znb^8$et3wD#Xhxcn%2(xkk&4yEsuBK@he}AkfFyN|4z3ne3R5 z>~9kmJ0|;&dyoID7CjzU!wXhb<+y{`xWY~U^_3qy=JLK?N9+7LRSJKsD3F9)Nc)`i zu$P(Z^6}IjSVOJV9$hC3FOy&KQDNDJc~GR=JUL176k8bFbK+qRUD+e?n0wG>=siBa zC~dPYBZrdMf^=X!z4>J4+sc8TXSsPM#jD8HUW~KEL7nx@a^cD-mWc{?*TRT&MH^pr z$dPzax%EGi&O4s!_kZJuq(jQV`52`*vW}30?9d@`GLKP2HmU58y|>IG;-JjT%FHHv z9ZATRor7cV@w@x}_}jyHc;D~WeZ8*hd4U&4*eSS1x}+>#+P`yC*4^+9W8VJywCBme z&QxF}(Fud1V5`&1rg)Qta5l=%1;Ga-Xr~^8o2k-7QM3{BzMNdV5qb;7z39bi$pIl( zxgW$bvs}^3^`3(2tI#heDQZdP8Hq88t2uO=5{!~785qP9L6LW#--U!|{)DL@uf%op z2L8C9?Y%cMCwG!i7L#6P`{V`h*LP4Bi4aZxD;p9i{+XheQK}#*a=O|MFzBxxw!b_X zre&KdyhWl76}NBj-rRBn<;wBYM5XD8DfZ2l(EU4t>vxh0%K)(_@|cN< zDUXMzXXr(>;ftp^G)DMUErL(FaP8$(P`$^MBl}p z1m}l1&_nm+su72o#Yf9=SA)N&AE(#$696XH0)lIMl(;w=GZzGj-PZb$y!AWg^kW9d zsaVU^n$c=b=+SK`FnnaSfkbuan+ZBDyn8Q zqB}mU2JkDu^{@NB+aL#r1wa)u9A}V31c}67Mdz=K(;k-0z)G=R{bQHdFSV3w<4U-q z;Okinj?qEUV3;BwP{@ zm>Sq9;;<26K{`D{SmiivkK;WftpEr%OiMp70QB6s9oN&!=HlNc4l8mvQ)aiB=~vx_ zsBg2H!O-An32kY}ZjcneofGk*D%o6p@U_G$ZD@-`^myOmP$ARjX|LMJDJudGF|imV zw1~SkPx)&~jQGdP%7DbiR5%1&7`#Sk;Po){`g6H540T08F8Y#uEH+kNU;zYCCL8x5 zWRhP8I`kjXRf8&lKgygJKj1}71YhUlnB$UBtzr05x0dzA!s(M&p4-J*uL@syyIzyn zPl(i?@Z1>CIA3Nnl<~2u$q~{8n12dIPE8EhA6AIr&&Rrsfl32vd3}Vm&UOQMy6Z3) z7Bm#amlNyfZ)>ToJ|~I*`<@tI{&Ko6Iy}6JIW$3(ctztNao2wzzy4 zj2%vXGZVc{l?Ccx<*{wwisO)ypus(;r-SD&jw z2LrvxY2GavDE6QAj3N7VRMYOF)B=bt!RmDQLSRex8Ga2L*gDZjzB}|JmjJOE4hTx< z!Xu;^24zK0PG*%v_T!rFawJ9>J)={iXEmQJN#WohN3EPif5<(wvB{bHH~kZ_-Ora;>09BT(l!Kt%S0V1 z%!AbJ+ArW6FIO9PmCUglD1OZIzYij46*nk;T&N4iior_Tr(c4xV+N^M&P@EMr+9zK zkK!XAUb-Rho#!+^01`A63S91@DgA>PZ+5h3H?Z_SwGy4VY}z? zOMp=s_r5sa?|Ieqq@l6r5=1DMqOVQ!qXb30y>(Le&4>OQ#H zgWXtAHn<6bdKtFQdLT9!3FO3#w6rN-2j2>VCoj7VBg4$1pxL{q!gq>}Cl)3WlKLGp zuAsEnIj~7dMgHvIaPZPT=|Uj;fT*pJIJ&#mvldSMP^g(*n5Ri6JrF0HDIZT0YbLR3 z=bE~I$7i4TwXssKNbiwl@2*wVJ=IF1^NkMQlfSgS1uJ5iu%FM3Zd_PMyNtkR7{MaU zH4bZcCnde`FWAmc9!C>MH-@L#;!bSI89E9M_KW6{8urt0&XgvczYL})CVB^16=X_l z$RHnPNX!AwC9vV|MzKknm}T>nI9PVny8;Q=ht#FB9~yHrfeQS4YVP=lqjEF+-HY z(r+@wP9(zz9L~H(M9~a^v2I{CVh8icA&vKLG28RlQ=hknf4Iab+?&8@4Bsa zT3QL4%(p6oJHv%8~iZpG!zVD5B zQ#RULcDy%Kh|i==z*XB7edWsqbZ#J{2hjG*`S_Gdxd@iqCShx;>(!8tT@skl-3Tjr zQH-M!S2&sV(oq9bfZ(0!M&EtG15N1X+En8H^s|Sch~7cg<8z{6c`-XRf}3zLfs24z zU=|_Q)75?aE^ZMS)ESU0e49fpAlV#>u%Kiow~At6_tzx{779nI_>1H)8gfk`WeQH6 z2plK5GRwj535kY7AX#z!L?iQ~zBV5+$7_Ph=eJn{N-DN$;DY=jN{O5)D^hmpRU%c{ zZP6xrh4=5xBg(etByJpime<;bZ%{S z^vfO2&-Ke5ul^kbcpA^M<;|?JvNE}o7CE6Y!}>;#-L)Rm-(qi#zz|?FHui!muFP$F zt#8Q6nV~KLdoY8reu=A~WOjmNGSR$f^1TQ?Vva za`IJ)&*{QvAK>fG^|^E3p*LlI-Bo0D&j6!8rVV9U0-yUUxm|c$OVGdxC=j*JK7%>1 zOefQBrP8i^IJIwaWh>r!rG~&~M47M0ro#EJFES-Jeu{^B@bR?O;!=M`2eT6a ziQ>3s%SByWj_tk{iEd54dirggP1sM2yS=D0J>}P8nrBy3t`X_OH_EY;kcB5TwM#tLA{c z8L|9jdLE~)p>b2r{bc8FSsUQ*jTA0y?d<5hOv5r_D~(>hx)>(8xq7mCj~wF{YWeCTs3JM6mj%V( zulEz)Ct?=n*f?!uUt%YoWbAX=V{X(LeIq`QZ8Cxzl-986q2Sw?jL7 zJF6|e{M}ulSYQ0{pvQM)<75Nn;|I6QJAY}tv+vNpIWo;5MCKr~b5?BZd(rj3oA0*M zgLoT2LZgzk>WPQuo7L^SWHTBR1>e}0R^-?GsGlie%uY1m1!o5?q$4BKUfa7&fV+9e z_mJqAl87DaWcH@)MD|TB;mT2&**YfCEk07Oe#)@iAMHC%9k*{h^4LBrn7%1is}Lcd ztv$coBBL(ZX3A=BXQv%)@JRkY79E=ZjGI)s?D_vBDaw^y{S;NhXm&D<+vJ} zKO~PH^oShHHr_XBSR{II+YygV-zvpEq0r291GAzJU2&AxkJ}2{sWlM4g%`xdR z-bc%u5BJyQG?k2v!PV?ld&{@_$r{OdezWfiauar7HU|)ozO}wxAyx>WGn>P)HKU*3 z5&L~M6mmr4lb77_xi(Iq_MX++Miu2v4wpnN(XeQD3m)Oz)AN8buwM16c5@yQFBEIlkr#>8M1&Hnon`$ zERc=m82w*Nkk%+khD@QFwXvE~=&B+AJuZp(*9ehsOrJzw?c3%W_+goNNY$48X>heEF7vygY%C1c#@Z_ z4@)e*5gyT4DM|YgBm?rV}bky+wp7WLGaMiv$ja!$bRGK z?A-?|2DhNhpGLFH-f}xRL;kpWTJJ`;Z5*~PRr&kw?ry5My>>)maWVrvJmIRMX7{j* zE%DmFteXgOv|P9SwfEs!U#k7_B;u$E;T&=5BX{){gxQ>+4)}h8j6J%jJ%S{Qxkf*s zCU+OHbJ`sG0bEG*^742v`Hrkpjoxy!=BVFFA(b{OH5{3kZaVFndXt_Vre9Cry@DMM_WjA(}8TLR+AhEvuOF@hYIWvmEQN<|ieZ7Wk zD~&rd?Wx1@+1hQnJ;}oYy(kG!LblvtGuz3Zj1%uce(z3YdKK#UVDsV%eg1dtznxgm zDq8kiI;IQZr1Ybo(1pe=Ti-|048Ge^4YnQ8_r8nv56V1!8C5wby6b)Z$8#Oh`E}^2 z*tOzvxaH16U86X56Lkb(@C!hg{j2U76m7#reeGE=t2X2<#=8+}aoWmsu*i0>;jC^E z+o}Egill0WVpQ%lMZMc=Tojgra!f zY3N$vk&lxs6dfNHwfW@JO-Gxv*b;xuPPY8)QTS6+MT)RE?RlN#m?zN)cByN+iP4f5 z*o+b(VVZpO0l?}W9p1zJj2@c!Q<3^UhcaguX9Db0hLn4_Ish8nPsv`?-sotV7x}>1 zja(PMZuY96ApfbYnme5$?_GWldX!K$JQqCQjwyNepx|`-2$&%bb_O-T19;Zeks<4T zGQT>TNz}uxv^lvrIaNwYO5c~|`WWSj<#z+Rw z@Q7Qhi&p`A;s|JV4Spwl;J$q}c|7u28|tEcUp)fG9y*FdqM=AG4m8{_dZ%{$8@>Tj z#0k5(o8DGe2O}>>adN_h$mx0WFKfN~@D8PGgv8u%w<(S7C%L3D zXVAXxb-41c5<+8eVjmo7r(dRRs~S&+n2gWYiG7Rjpalgb1(k1}0qi*PeX}P|P;Nu`>lSFp3yip zVq)ITzVdkTCX04&bH}K=;)}7p)stTa+89bULpe~`3sq!0^{KkiKE-6LUaTDUktAM~ zYQtQi<6;@(=sgye^;GO~d?tJ>Q%Ec5rw3U4Jubuz?ymiZ5O{q1sqQ~E-N?wP1YBB+ zGtMa;-`G$+`l@oOqs`2;pxeD_a@{OqcVS27Md1&9fm$wlUKlD*!IDP%nUg59$q&- z^=!J1sS}8o#Ds+oHeZflRhGAv&|o*!=^I0B(1m4P+9$8hWBpO>tmaA_Id|`G*}d66 zN^M!>t18+Tv1^e;-*=nQD#=K;#QoKA?MIcxO!C_`}7g*F-E!v)J?+1iSXKTqG z{%M(G`?rKwBYwNVc72})^pe`y5%rLFX<9_D_@3HBIKX9)*+_p-rvjzKmsNrA@5P%% zp|Y9L4)_FErcKI%lac<@y&Ieb#9TQV%jbSjY=KRR&;CNvY2Sa8OMAx>{d|Els#M=a zk8Pe6t9wT&ce}Hh;REkP@o?0fZ=5A8^}p8U`C!9}P>N>p%ZV?vd^$2D(bvSEsEp`y z?mc|&sh13^wxFK8!TDaYHA@NyjYRp-ATL1u(V0KVskE&ml!DMI+aG4x`e`88OdT{d z;FjA}>|(E9#|tb1%4ZSgU=~}+b z>HYh+%?ZSr^GC~h8ni0&Jlv`nsLTgfE;Xwi6t$%uk%97{%y-9H?r1ZnV%T;> zFHsG-)N1f_scvX*o9*;qba1KC1~$MvUOD-qVz_#2Zq(V{#hU zA--SKqE})AOt#SGE1`Y6Ir1|1^gq{lRIl=7#l^%umdruF;x}cWv0RVUHtXa}grkK` zq93?wptzTAi9orOS?4DF-UD|&s@Tt5N5YztU`Q~udXTrK0N-D>$#p;yzdH&n6~ zZR>eFRqYCGhBeXLhj3oh{0PhDd9ZvRF&pzEYl9TV$_^*PLc`&x+24_lBX0Y)Zt85c zMr%$Pk7{>fEBe=1dTA)30olqHBnhp0wb45wk4rMPO;cWNkU^~10$A!}n%$#gu>{@k zIQ9pf6A2SleL?B9ZK%(4Z`?jf7!KNB<8+_L-g-=5t^59VR7;GP1HogdZ_Zw z(;Ll~UgnjMWREslc0JS-%SP*L#tL5GekuXDLpf@+A+sc96ll+>bt+5`R5-zoI$~>n zXXm-QA^d^vyY0ie>rzT|4EB{ziJ7zm9&$7nL=xb+MY!RybmQ`h2poc-X1TC}xh?{Mu?cNt(i8Sc(+Z>f~-HewS*cW*wLW$NS!C3mf!Xm+6nw zn~j$bitZ_d`dRAIn?cE7fO^$_Qu(~NrvU8-8jVu2q#(SlzyBeDK*Ol+J+)zv{nf*5 zTDha;qeZ2cyWm1Qn808jrL%Q%G6f8ZI!>%S<`JIz1R(uJWJUq`*lLac;ScuA3fJ0E zJF#*876jUAy{2TGB%Z1!x6@=(s;!z1CDuquOV|6J7ZpV0A{is~#|gNfxt*2i!sfN$ zZ8_z6-;DX;%e+ip$XB-ZJdK8fW?J8!g(PE4{!Ll0jg3E9HGFHLxh9CiwMCEBDqY+1 zID<$~xBS_55%p!5ivw9qbrI5@Tv|@@Fw#MJr)8NzB}WaxnHYT4^#oY6pBgp9 zE?e7bzZ(*I0BbWoy?%aQt1m||7zxvY3IySmA{EsJah8s5;nvSu8*g);d0r27Rj_)j zme27ty$0ZeW6U|P*Vz}w5Q?-klC8H>TQ8Doj2fR!uGb1W z8nE{Dl=j~50+<2nKME#`nY;?n+P5euEyQm7Y5dnh%CF2Is#E z0r!(#wTy?udHOb@)q;BPra<48VqvC~l(5pr8-5BKD%7G%myzhGDUafzSI_#EbRB#u z_8>ocRSB|kJ6!D2kNqn~2Z&dA?l8gR$%E-3uT>TbP??gNHr8uNb*IC%+lN}?y~G-nC7=ULmXE4*WV{H3)jP!4l! zH?h9Q!((lHek7i1_0Ej%wZ6Em?y#+N0#=euuc~m(jv@2mybWs(Co+e2J;vuCaA>7n zS|hBvHlGwbx3)X95NVC1T#6|#kF*A@c_7-!;*V(!4C%;U)9j8@^<$Rk0#=dBV(z0lOqYX44r3327!LL&j zCa*N=P&<7X>r`<3y!i6X@a&)1f@BkB9yV;4W4T=wvAbYu9e~Ii#@(7PkxqQ3Eg$80 z8GIwk(Q_=ME9UyPGl!S9Ux!F2TzBK`H1%>B0<%0TuQW|(RNO6g6|OR+ne`E$&BvqP zxG2s~M$7Ir9AJsF2lM4Z4;WR1**0Dxb@YdVkxP+Txpr~xVyPMF>DSHojHa(BSWr@8 zBN(0#_l)*;Mz{MsJYBp`fdaz>W{ZYz2E}$AU74|?8MieY5y7xh+myAn#jRP76z+Ho z)MgDQ!5B>Gck0s*$^D^gl%CGYqy&&+xExf$k85O*0e9cpF$rQyZi5@Ch#$<#4?23X zOqUg)WuvN4I<%%i8$8r>24@xp0`*o_OZcC;C8?&&cb*x)Hp&=EoH|S;rsf&@9IosV zeOT+ZBeU8(Np+q;`5a$^E({C^w~9t<50>{VY??Lj78=BM#$_x1aG3;ggwTPpd{Rxr zG#Mw!2!m2;B-Ny*5}EpqSNCfjmtlwVuMcOM>#L?bPQW#7Ztj8Zf0)QpzV4c$f^M9y zzOKtXX8^UUd$YOq09Z7b(Y>LZ#X}E)r5_wbC3;o8UgymKe8ZM#Sv_w1`Sa%^pFB=z zoL$Ksy~0PNVzJrz`Gd{5s%c-+1qu$_1O3UbQ7Ra&;F?+qgr%H#FDnuv&rT+f;v%J$ zX;%S8TpgTJ8}-fP#VPifDFeX)JfIea`sV$FZ(61!n!RJ_1{HiWdX`yrEQ`Zrhq>LinKyp6H-;!U-@fI ze0+zO+d*B#B#J|r=l5>f6*6UustojXbUY>aNTk4Qw3)|0&(*8!r$nt{T2XZxYpe?Yp?gTk&@fFjUBk^3ObI@90{IJV1B)$cLd} zkemEhaJ>u4+za#1FXmjm+8uk3L1^DeSG}1t9`7{Ie95HeL(1avYSD9RvWqFyLG+5K z10u2KE8CHs0|Ks_^HvK(CPGDzCeIvJ;^WE@4$kkvGFg31z5~o{HjCSBW{x`VD&QEX zKqBgafA%eF8sRZm@ovH{v2X9_$ZC4mds_PX()L9v7ayPL;~BiP;r6P(fMeC~#eiFu`8#ZEsM=sMYyH>n(pr=CyWKp7TZhM(=T;VvmNL9br%Be^ zhhAd0;;{v+R_>i)9C6~4tLmv=X(^dQk-6m(Qt?=WrFO?s!N?chgXM&d$%btNrxHEx z)=)NXv|jY-1H?zSKhGzZrqMOQ_Ft6(ao?(|eU5e>ia5okN!^8!%8d)nY&JqGNPJ<-L zx87AXKHgxUu=Bhz31$_cZ=)ykpHC_p-JSM2FGhvuc2OhtjH>kQR|<*?3rdKuj!vxR zju~!{s*Z*yj~m9P<{@+;#itYUMl&-CI^_fuu%H&LH{Q)$(B%MiZEG;czFGd;gQj){KosPzkVhL=IU^#zby=TF0<;l}7(`sH~gG zu8@_Ky$7gMJ$!|8TiCaXXr$wp2Rz6`z-KGW{kMf{eA1ie7==oFplfYm@WKc__NyDN zD2!4HNybLdgw26U%j46Maa%V_{j_xa?VO@*@9FnHS??sp+?3<%;V@q=(=T)}O#>Z1 znkdhAg%iPP`Sz$$2er^Mwnj+bti6)PF=_RMq&bxTeI7K*C9%~=DpG~^s%k0kKNs} zB~<+;;w29HroHzs`_1magm)ZjjqxAOc2!JE$o!3wsBgwyW9>#To6UI+Bgx8i)tgoJG!Fh zl9O|=iX3E5hztt)LsL%?oIL48&cjcwS%gHEyf+B$zF*uH;UF9iR5Yc>X09tIm^=Q? zX>mPo#S8a42ln6~q=@F{xEkKAzPwf(50vAf>jn zv`k_sLgY`JV?bZ!=pvD2zuK=`k%y+BoL6n1@RY9$61x_y>V9!qCv6osA}~x zI&-WXPf1>GI`)33_;A~OoKPXwgtVZMyFu{``k{iLPtnVt_zS}j2g9{RD`r=8t6f%( zf&_FvzZLWgt7qxr>go#G!520iCq=OZtuj$94aB|LG}Hr{uSBW*-B+^W293zAT$`He znmq!Y>HFI{tx<)n%I{i)_D)6Bp+ff7v?Q>DC7t{UJnrD>**;!cD*^=~yXCy9dM)3Z z`L4i%(^f@CnYC4At`3Sux5L|)KN2g)1*jcgm*e}aAYVu|umI<1NhH@w_pcn4X4|UU z(z}ZJ{JpP+Wqfw_Hn%t>*b!I5jfKmkont5b{lgXg-q&6Y>x`mN=42=uNU}>&#{~+!NjA`fEGt?oP!CYCqG{?pDm7py?B==5ApzSa5cz+;5bgnVi(FT)DuA zy@?LmTA}Bd*Us7RjZI@L9d0=kin=Alt&Z)Q@eYflfOsnKCuAIXJ59OP6DhksWy6BS zbmKmYA(xM=E<$?}F46-|b#zN?0LkrXcyHzOv?1yeJ;yjBnS(0-e`G%_<|Lvqm>gZR z^!C^xeMu;?P^$D?wS;s1!*&}h<0RVPna-*IdO1gJ!GGsf=I+w`LOmh|M8zs)b8+mBV&nAhrLUoZyi6S5 zbuIhrdffX#9T`1m5hW=p3FhW05TohI+>+&@EXGhuX547pUca<`=%`y!c8Gp?YNgew zPIcVSXgCRsaxbRcz;4&V zL{@SPvZx|}H%JInHL1%g(o<{Ak0p`O1NwXGa)1VM!3=SM5pSexHjCRbd*4Lgxe1$_|sonIo?D-Pe z*OG!<8!S!Jx5+iR^Aiur{xW)LyPn$$FRQC8>c(a6%U*wQIrG)btwqN8aw5lI@6Jgt71N;Zfl7 zDKoI$mtNF)yz3>#z)7e1Qd>8Xv&#=bL7Whco|9;Yk+C~cEP~B4V%s>)WgrxF!pTL zP}7v$f|5983>oxLS6kf?^LKT%F8{Uw%Kc@nEvqNy<4-58zA0~F{laWe5JBl_)F}1# zdYDJ2cE6&vl`Mrf%G?Z!*gKtBRSd#5fvcA9(IBn(xQ|?r%hFj^<2mik`t4>9aY$t9 zPz^5_JnSF8ME(LI5{mn=fG=xlEm7&FT_Zxp%jI%kZ>F)=qw({m zy`JiP-(3H-P|w~*N4Nb;suI&movt3ec<})lhAE0C^TvWvl8RU97lzMLJv$!>IQNE# zJ02a5`5k-*O|8PP-@7vJ>6a(Z9vv;t z_AE_$2$&TRJ;bljLFmGMxQnX|nxW)m(`^)(l9*0?%qe10Q!#(aLFxHnX-VN+!YxHt z!UczouF%&`W9ey?i1v?Fb3zZ)$sL(X?@K`B89CS(D-11A%1F?QJs~W&s&F`e5y~FR zMQNe*!vG+tmB@847JoY$s#@kb6d)$S1p_K(&nBp#9FF86^YOG$1?8vKsbzz14Tpdp zy5n}$J(m3qTd4vi0t3;gzds23u7h9Tk~;bu)V`8ah=C*QOb${*Vaf9+4X6Jmk1FJ|iQ^61+lW z?nx`ar+6rWpQm`Z*VR3)dgyZRPItVM2f}3Whg!mZ^Pg@^k)wlo8YT9E59Rd5*M?II zc;9VTqX*!Y`Z$_cEMr-I^6w62g{a|6L?;=WFa%R0_GQjx2)?Ldij1AZbIDIqLT*Q4 zIwq?^HoNNxChT+{9RW|Muq&SvRp&%nc_z13GrZqLO@+cGBkz{NZ*QZW10L@+loOs3 z%>!baB<<7se2V;76*zJF60ygOmy)`e#l~$%)}jFDfdb`BaF9~1r0K|GHrs*vDPkYx z=;$(Hx&{;e#lYj>&7LOg2s2fJlytQBh@&bp2=sc>238C6~1Edck_hU1C@vVxR{3lu~-Bl*@$LhPD0Fb!4q}d}vLGhH#U)sCsCwo^)haJN|Z1 z=WgHO;o<0^zAjwND9Mrwn&vVrrAUoX7xb*C1(P!l4-P#kX1{oNre;lk!QekRMnX>7 z^I+!B-!2uSL|t87%lvX`R)vUOd33?VG6qk7OIw{|t)_u3WPJAsq{HOS=Lf+LkK^y* z)8-DOMaS!)dGm3-q+)DA!Aj{TZJOHMzAp_oh6~phujOiGeNsJamY$Z7uC?zrVB(^u z>ykDPFZv9jR~BYtcAB8GIMc*{Rij33(Y_N5Q;fJ-Y|P$J0l(zUOTC zNzaLxy{@`2#0281o_jlg2giqARE^(QjMwu^_9JUL0&5TdPl=Biy4jd` zEifqer8Q9(Pw5?sFEaY;dCixIf#&Ln15?(2-5O4%7ZhaVqy;NjYwE9eOstCpOBx8` zun9LLA8>`=dK4bBF+DIaoqj^sQSre=_BDMVrg1fr{r4iRc!qvMIOP9^%MnvZ)j5IcZq!_lw-9CHomtUVmXK}@sjb`SLR~q3gi&Z~H=_z%!@INqN?yxBvEviag zvy)RbA0gG27=Ipdy+$km0q4!5-3MTEe#N}8!HCY(=GWTp!k~t%)3NQ-PnBX7h;S_` z7)7!~DBdKX?vRQTp-BCQ@Z@NnmuALDHEw&{bGeC2Nj@tPrGzmpe%O0|j@5jJfVdxG z#T=&`lnf!e$bscPMOZQ}nqKG)|9Q!v`Qu)Qv`ZHv;883)nV%t!i+aqZcFonTb`9>& zmN)N}|5jd632AAH;dp;n80oZwJPJc1<4{=&o)j>wYQioEySR3rO@PfpAbU#tS7NA5 z>C{7FR>f5HOkn@x+KR#ZAdWa(X`d;d+hwry776P*7Sb1w4y-64b=Ww`D!%llL551J z4yzCA6Y0(8S<&rHQ4}l$WvbGjzud(~yVM6I^a(I)YS3b(h!Nr>d7o(} zYggv?(bJQ>i3cp2hi9i$2g|h5)2{3O8{=2nbt{G8p=W4RzLA!6;;;le<@Z zma#Z-a+|4t+M9IhHs!OwxY({=_?8hn@5N8g0f0YXqx3+_>hZ&3+M4+9aI6X!XNNLp zcL8tV&*zh(YF3`S`BN~pFy%0X%+QKUWu+%FY0jXB$b9c^5;hiw1;8DVmp!G5kfpS= zqHQ~nr%NuS?R@@_|3nfq&;_X@SS*+zhJ zECkeXl{AuRQYWev1;^q)5RX7@j<>h7i~IKK==KQH=MK}Nm80j5I*%)00g{21;V=={ zvqW9)B+F1*WYg7S9=Y@7-N8E{YsK97ko)l`?RUJ7*W9MriWsmqpzH%L!NfoVfuiSw zj40(1nw_uC0`$jK(G;XLQF&^%v(-F}blImQsgJ$qo98>eXA6xdBi)(tXk(-4=h{Hf z+I7vs$;!$S_Wl?!U79{=vFN+ontEd`X06ruw9$9r=BeDa8TrhQuU(|k=F5Ld-eH=e zR?X!>2zL);E#IP)5S$o}`&ecA`2Y>P2)9tq0T0{EdY6Xl7}zKD<&yS@Lu)IGAdiyd zn&MI)#c?Yx%-?)IS;AB?xPV`#rIO9q_?g@3n{o*|rXHNok;E1AkSAfK zT^E-I%VL3fU)J+%ff)H1K;KSgBm1A-^IgodtA3vJu&h*6SAR;n@qFV?OTwUYRwT~E zN%l^Kdlz>m&QDqSV>vblne?y+Xn%5Gvv_iHX6DElgs*Z&Sm^8S6WGev@XF&0(l<8{;{85Avw_Ytp;?YwJ8*MM`Q{WXk{n!Y!mc-&P(94h`Hg^0FGX?ILHsw~d? zc)XD(=W#kOk~mQ`TxM|nqJbZ}2^WS6RB+I=K#NJxPKCxMO9u63ewbkGOyFyAXK7jr z49}*tk~Tp2OHwYSZ6iXW935qOM0n;^57G3^JWYmV981->%l$H_tA^Ko0@LTEHxVJp z+3ZWFLQz!mEanljD=U^ev$9hD!UAr3{V+Q3D8#P^`Xdzsd`Vv}CCP>` zXKlNSY&BQ2YF+4^^w}7`U_wrfs)hy9A|0c@^=t~F9)#%V>6&$N^A1Zb$%sf0@!P0& zo6-cAQz7+)T~zeoyh1qv%+p}bsUnE{KwQ1a?%3U?xPiz$Xs_gGpHZMeushI@#lA&h zO|BYtb~K+{wdy%kxCBNUImuM)m*M(9q3z66UrUH>U>BZJS+Z32Z@k#t`c{CE|B}G< zJ((jLm%xUL4`T-ez%Pb3tJWrxXLpG`8E3049Wm2~Gl8G$z0SO9M-N~@?1&(~C><$B zzKBfGV3ZPj8?53dCN;3^Dg@FxQ=z4+i$SK;be+hee_|HW&(rd+EyUajnyHIH2{K0Z zT8pL(rzEoop|U9;yo%~J%?;PZh<$Bs3&as7@sUD9 zS*O`HGanBpkJqoWapaULXugHI2a4K&38YLMF&Fy2mO5PXNjIW=O>Zj zt$2yHgAm8Jqk7F!FN^1JUQi?OYmYl#OWQ|K0H_>>i;PO>vvFt`C$h~*w;948Pb5{Bx`r@sc zcBU$E(yEM@qVMeG^osiK({i<^9dL-dJE#%%D1BxxC|FW+YLey&UM1$U#MD&S1qk~` zou9QPo`qzH`!p(iaPma7cEJn1OnR_FbN0Wg{JJT&EUhW+Jq1H9)a@p1a$@Fgkzf1~ zjA3J-wA$?)9;_40mx_I%-?uV&Yz-;}mdv`Zktxl9wc=gLj95Atg_X~RkMiBy6>It zQhLrX&dkmfIW}{sY#Z)Yl)b(9h`9Kv5QnK2quZ#KqGI@<-E^_|b>f9b1G_iS*Z}r# zJOK3Yx8DaW(CgqG+b@P0=@U3Lq0~QM2oYfh@*AB()#_cU@fWnk`g6tKcAjWV`O)c9 zllA(PB01^bEL&$s+1z-p7~7(gZ4#6$LBWmi+j#3b_X8nOy7OQ-Js-{SPfr4B`zJ25Y^?;hWO%&Xsyo*1hC^r_n2<7GIU6oU( zBU`foe5)Lkr5V1+O&0P2E}UTI%q1lGGVK8pi)Nd(FtU0?)547YWpF`jI!3lNlh=H9 zypJ*#fCR@(S+&XK&Dy1PBFRQQLn-`N96IZkn73+L-fy%gR7`nt;DnblIO_^yX}jtC zqS)E3+OfS|pY(V9!|+cY8Kq>Fq}CKgWPU2F5#lDn+#P!y1VA`kzKI!)K|RcQY&lvf z!s%FMaK2;B_9CZoJI($P0)#e%cNKIKEp_9XV7DAzq_#g-gCZ#`ge>!M1V(F`F6oD1 zmb$zG+7VdloC;@fD(o61*`m#&4i8yb;ZCOh4qje{LoWKd7-CBW4NSXyIJ!k5DzFbF zFkEdzZejwRy2M83uzZ|4v@*LgyR|j6vIv6lSvrGa9UTulIv$zh+@fJoC@f!2q8_F| z)yK^>rE=WXjGdl02p56FcJt-{$Z9UAV*(HM4mkTJ?c~%1?_B-|nN>AiDd_rT&!waL z?ty8tq)5YMZD3e={)>z!I^bvFl7{TbCfkjQwm{F0!5=C}oY?fiVpZebu6+#!=YtX} z<<1M&$za0U^r+S*JVzcZo_63E;5`rj6i{R9jEsDb{_=o|293zlqyDo$a$e^z*?s|9 z$tIz4t*8L-I9^(T^7z|5d_kYG1$%@?j*MB(OOg*RN2!VsE>h47D=dn6l8P&)YJ1D4 zNPB~#KozAEZ%x*cSCsiCKieFp(pAeX2BB-m?bWWWtyr=00yt%NRLrt zU|^{fMI9fPIVh3?Rf`2h(Mb;@N4@mKUGy8bmj{kX4ae)_Bv8SXsK&q$6Sylo@dpwc zZXo#W4Yam16Q;|kYjhWrg7ed4k6<2+e#hW8=}=a~mDy&d#b}9%6)7~w`2BJ@^(gxr z;?p?pnStL%a+^ot=>4>J+Lvqi$eKbeyiMf$R}~yw<0-n-Kd1YgZN~VP*XsAdGYCCx zMFrGcC>0ATUOH4R+-$LlVKGEO6@g~-q30mG5$0w5cbZl4qdPr>+##&_cr}|HdhsLf zQcl^2iC6~Si?@{glFeo>B#3GhUYL)|`RMkH7Ne?MbjnYF& zEOJt`!(3}^r+3Zeu1t2yk~>)P6|22dE4H^!bE{5ZeP3LWP*FXhf@BR+zV!P&g_gGX z_92>SLFmZwHBx;1Dn0*ls834!z}SERCksOdb0BRs>29>PGF4d7cIsM*Q7=i(iyhaX zKWU}Aj3c`YiKhqUN9fKv8|Mf~4VhLU{ZwggL{^|XIcneAK2Hl%P_Shp74e?v_35TW z?ulMIvois(ty{2%Zsot)nK>MJn@QO-W$HJDN6hm zemEE7d$u)HNIKoR^}DBf}d6J{6xp z0_keRWWI8Awzub6-_Uo}0#lI5TdJ4CizzOLp=}bS*}@ZI^m&>QA<{LUE`!EmX?^i4 z!=rHRi1(W|YxBcIzycz!x!zN~kf)iLThjfH!G*kRj*CV?5$h*)TvS_AYObsyrg$Yv zTsv=ZFdR#SWmag*MUD6Et*jh@BpZ+f4LV|*6@}V+7t37560i#})(7ZEmJ#F^@2VL+ zPW)*=O$9}T;K2Pq4iTJjzWUGfdhq61{|k{FX(dLq@5Wnu;Lth^3dojmm<*r!a9M`+ zQu2EgnLH-8g>gIX3C1Q$3(KB2)CY32J_qw%Nxr+EPZG~}r_aI0QThT1HBXV!Kg*p3i)7hTJYq)EyVrF>BXfKHOc zlteh3n_G}3)!mg#$$@7yzR4++34WVhIgTNV0hjG!i3LoPO6s?DmTOM}xa^1>-eN361p==y^0teom3j-9pHl z#_`%NdXtZwrZ@^eWi*XBG_EJNz*^VhPL5FSr-FC4q9z?YYxUQpl0NWXE_P9-gDO+! zm+Ki&BZJvF5Ee$_0Q{u%ey(kE)2lkU57Y$nL~_OT>IDxzueIx}HL_4f1}_KF3eJDJ z?9W?D_&<)$J01%EkK;$mkvO_SS!bVwlgu*CzRa^ClASU_$X;i!!`Y;8l=;mpGm$-# z5Hhkex~$CO_vz=K{_7#R&*%MlywzZG5d2xBj?v~V^F$O4>wx9T*hNHd6^3r? z0jEE-WxZ?9w|d4U!m6pE<-*6J%$rwtN-Fqhbb9=55CvmH85;w?Z_1@7GoYj^!&&OH zO?30jTVK>QwqScWrHkNFsLVK-tCyfK*vmNB&}CV}-Qf4mu0<4cgKQpH0DsY%B!-(9^1C;er((T*__PRqGN6Mi$19Y}Zg86e!U z%B*BEy}pXYKVF}NtNr3uYq4-Ww$h5j_Vi0dBYmapOlUZ*ZJ&)@xS%qhVIGCDKfBRL zY6xUoiB%n`N%4>>z5di$1L+}pIha5jjq^8<QeNxa+7W#TOsaXnCDBYi7zSC6NzdatXH5(+U0pF^&EbJ3 z3w~zdx%U>vb@Y)9iijLrLtjL)%(tvJC!$myiJ7H?S!dHpzO8yJO?^4HzlSkOu#}C)O1RBD!L>8GVi6ZgY&JtT2Bkc zP%Os2^X*p+!l>7AVBYNt6rT--z+JSO!^sa6|DCnb(%8Pz0WT?f184{e zpU!|3Zmv%&-9qY2686f#j zxrg><9~Bag9KU-W?;Uy7noYZm9k+OlohR*RN>P)Rcij+FJVz{@rWj zp?Go7`Rtpw=5AQ#^eAjL`Tm(Z*m!Q7_7(n#@b#Mzw=VgcYoyqDg@Z@RpA0!}H+%z$ z$bd#o1XN{ZW4Nip%pgrw{|f4-*hEJTmsbEaWYAa6Op6O7`gHTk0aTHCJ#H9NnjsSa zf=ZbomyJP_bUAXZN=R3CC>-AXjG3G*j6)4qR0yv2%B3Q{>o*_i}{}(BUFkm z^AA#A?-wCbhs#nRc*JS2LY!KtE_Ni+qwy0wLIVeb>f<5O_Z{uKxp1rIF&VH-93Ggr zc=aVsdzSb-DErfdGA)$575(wi%ip;b6%pG^s{wQdj!mu zyN)+bi;Q>_!YF@{_h&{L{u^_Vdv>w)~@=_N5S^fH8r7HJm;Aa@x|?G)!!KUvgUmXCwoV(HWrY@+LNZgx&zh$e81 zAaOA3Kf|}w^X8@Z7Nn8otaF1_BVDlSZEkggG&|JO_3lWfg*oRd3|~jg^N~aiJ*^3M z+FMP$=dY+H#rx)Ze2mke(laumZ-rrn%44fQ&4RGj7?0whLpqjS-0h8E-)m0r)Nb+L zI+>sUq+{^xbVpadc5HBYCtsM@%dDWYP*~W%Y|<_UQKSu#VJ*05Q^=(8s+O0J=~fjC zd(9@R!EsFuX$n_0H8OkpwvZssmjOz?8>RylCTL(pLXqI)M450O!J6L8W6)=PY<+ZT zX=!t9%uk&Py_{uYTdp$w&CYq!r}j>kl;_>N+dFkPORQ)Jl%W_xA)ekUD9*QQw?$V*?4)+GhTDXC1>#I4Blf(MaGY*u!Po& z82GYx;lqHOmFa&}opTEJC&X({~z(bBwR#@sVi2%0}CRq9-h*Q1sdNvB2>v z*^L7#MI3kDYK{jgqDpLi$_Q%Z8L*Q}^52)6J^XF`&b(a8&eXa7n3KFJ0Bq4BG5Nx! zRl?ygZ;>aO7}GR6d-dsfg}R+n)AJpz?qR3ng8cN%N3G#oMUAHdFMpeGqDF>yx@VO- zev}>SXo620Ul-3dL6BST{~Q;XLfD1NDIIC+CwL8X-1ZC!E?A#Z^&UF zA9&^tzIYo*Cce2bGDvHHT&Lv9LU*I}i9^3dNq6tu4u`t1OxKw0YdN-Vc3EBfTZcOO zt15cA<+$yfjA+lBh9@Oeinb2GWkmS2_$=FVoh6)A*0vi>LlPH2=IX+c}zbSe0 z?mjr_;GK&F@nij3yeiIy21%%-4|zr87S71PNmroL_2~u$9)5OM*wbFx#1?*-H!bKz zV{A1TZF-aAoNO;aWiH4T!96ZtrGR?)r@xAO&oO5r``C+e8Pe}$7$c0ACRTWS5KyIh z@vMA~&Z3wqxSuW=53}w*zIqE3c~O0&L6t@^vQn+gm<4|CXA5p`?WgKbVqjXEW6h)z zFEa0X_6Hi$c26l>RK^N z3Kv#JN#Zli0LlSLHCA=hus(IfBpERA7A8|_Vk;^jOzEAE%gfk3*paEcNPpXv0Ii(M zM!5_Hp6J!8C%N&*E{`6;AJeiI%sNS_%;hRm@m}kCJGH+c?M7+K$~J|}ma+Qt+NHFk zZPGD^zwpO}FcyO-8KLt#rvoS?5#bgW0^{p}7r^r0u9cL;i({b$@%j-q*2_-*n&Kq? z$cXG@3?7etf`mP)`dzN>>byVAtlRQTvZ>|$$;Qag!&d)MZ*tGp*8J+5+yNW`#kXQE z886SGMU!+9gV58U_&7Cv^?cS>DALB(d9qi+d8&WvaLe6Ps`jfmQA~T}OCsp$-3KXv z${p+%>vwNrLS^C?zHfTFRE%JFk6nCzUiyX4z6~IPz#c-L;;deK`H6IN@9m7fy@o;Bw{K zz*(TD;&Oe*YSZ-ykhTZFH-KmZr$%3FUtj4zWhySLHqFL10jWBt;;pHQ{?g=3TM$-1 zBC-5sZI0|THs+Zde<5Vyfi_%k!68n=u6(^P94-g%jcELZ!Krf$zXaA*v0 zsNRYtq|`2m5sW}YTR3%c-y-Vt3uQtXK^$xEiytcizTUM@wh^Mx#YgH)zJ@1IRJS6WtzR!WXbeJEb7lLO5oyCWI*IlozH zbRbn%GI%OoLE?VTR>0<)|L|bq)ky*##=7x1*R!KA&i;~!&oXbJbq7nx)|_G{_exkE z1A?d}nw|sdz^L1Qh@mO1?Kw}t?)5qT-ICB%#u#A8jmQL#R_O#gQ}CA=Sx8kIBUJ^% z2|I`8$eXx1!clQ?Z|~p!KK*m68Ee0GE3&ILFUUI7*;xp2#`Thv^^Ii z*TV6-`z}2fr4F9&?T23?g6*_9*tifGj$RguiC{XEgQ2Z&XRf1npa|h9JeVcrVgi-j zH(f9Y#WQxkK{Hco$FMc)BKVobUK8BujGqu|xY0zTQ0WgSm9CHSIQV6zC*`G81T?&; z+atA5f{0v823+a%#C3SJP-g2~#P%m~_nDWhyMQlvGeyHBO%%bSVS|Y?;Aw^YV(jL2HCFur{KEsPZ<;Ytk?@e0HX3 zV1W)GZQ2%6PzaJON(1>U#(7G1CFi=c|#H%pg~e3vZV2a(#^BN?>x1^I4i#cOpl?4Zbqm5oObsbxi5kjllU z$;Bo1GsNXW4sAIB&Q_3Jq_w3D6f;6{C=_uW9=89`(I=Qk#?9J*Wf@plKzh|lYS0f^ zm@Iqa4Zp%aEMv0=J>)!)3dR|tU%O;AIO7a+zWY(rWz2_!ou`q;(5UG<76xZDouemv z<(7rRU~a}keGM;frtfpyk(IyOIPI0EK*nZnpN2*56cjA|+WPg&$JC_Q!C}f}-P&?2 ze2-D1fB9DVXbYzv7t;hBhgG#`WLfFzqjqftAgr-Ldo$LMH#otI<*CB)A{TG+qN={3 zpD0mkGBMdp+k9sj^S%Be1FiMKT^)nzcznJOz5?1QBBaO~x{-36&QjZpLEO7Twm4+*+rcimbBK*7^!twkD?GtXyomrUaAMA01XP3)USvt2Gm7skD(hWlkRQ4%y*o3;@QgZ zw=QP*WbyL?6QNwI_YjM+;*8n4|DT^gyp)KidiLlXE*Oe&)WVy;>ULwR$Wu7mXwM5g zUErL)PTOMKOj50)1?nB5(hdI=IZ_IR-AW(h~^Au5q`Yv-f2;CCko*un%NhVE6muIu^63oKZGi26k{#Qv>|&8Xbu6p1&bsLXW*9 zidEDOhPV88s;9_v|Iju#GmD95iKN%t(a&CtUBS6{MG!aW7YP7uf8(baNuAZtNZNm=QW;X1Xa2|bUezkS|vKRnp19~vA4JWw!+gU{bp^m0Y4 zh@t*tVxh4bUU9IkfeQy7i=>FTfD1QrJ=O<~z}LhGXplYGA-kAd3phJ%UfRY%)*7Cy zHwedUxIC#5ij&86!s@E)z%2E)q=Yx5?E}j~+c^=GVlTz;;Dps`)4sL^Jm6z)7>+Gj3z;am|enp*qt#8=}@r7}C>Ixi7h3@qTW6WUTI+)85K*S?!2W@$t z4}#8igFj${Qf^XDL?$Naa@_Hk&gOIkv~cBJ&3Wse_eJ?h-h&P1?lB& zZ48pv5tIQpTJL~H(W(6?*@^#C)U>X0{!GXbJ_VxCr*;0lg5un zb${D8r>gFOxQD{Y-~ATv)4A8;=Y#*qQ+_>^BcX6nW4B!Q4NTJS`#!v1RfKK;3^)!VF}0 z zA8T7Ykh;|VsJu@#7$z9~+qNp__KhUvdBIfS^(w(Qe?SBOlUp+p#J2mXx^18xe?Uvd3Bw*tW?ncd(y=>ZkD~!7yn> zcr%*R)M~6Ik@yYG-k`%9)g3vPs~{sU(tEVMz5Q=Y>{nD{+IK& zIP-GY2JF>A0DK!nuDd`jy8koM>F_Z6IuCAaQVbM8kyp{UxjTyD*fcwR6C%6=NrV~1 zO*F3q?YG?6ggL$PVapHaI*57tXp?gm+X4V%Tdb`6$mfZs_f=Pq)X)0JHJ0<({Z;&p zB8R5;(j8`ZXEL6jpy%BQ!9Qk;$Q~U?4BQ3Yn`0-oh=z)Pi7j6*`?z-_FIF!(q-J_h zeg9UAofn$|P?SL&gFQ#ruxTut>flW+6wz?pGY;iWz@|->jjwZ_{)s$WQXqrcxLvE= zx@0j?JDb8!yyt%(CunV%oE=rR?95O%?-h82q$DSA7ts@#4q!PugNF^k278nCT=2}w z{Ox6$3D19p85_m>eY3|ijii7_afh{*$6c*^aRr<>l$dDKK4<;B?!k1^!`X)qn|=SD^odGJrL)|L;MI6y$In?|oV`Bq z(r{~Vyk)D_)qm&b1Jc#KvaFjUDZi5bA z8D{N(=cL8;Su(xR(x|;a?%ZanmomI+AzU(rZ{k?hj^{rMxn&L5H;5rR+a`PL z>z-&Nou@(cz?l#}D=HCz{H-mf0N8j1fAtf6yGt{Aabf8lK0<@582eO*29-TriO}@R)tC)c1^tb_!&-7jS3M(fB02HMFWC|WdwVC(Hew~V};&gqh=1zC3r;c zF3BXBM(C@huE6rsG$2qe7=s!cl+ECeCQXR{<9mvjZpg zH}xx4qn|08K{}23hBUZx;|i>2rJkJ962Hv z?Tqe%9$a-wV&~8amB$R+i&ePW5fDi1;T^Y}ffa3|r=YYgL`9H_gUVcmyHG;~`v!iQ zf+l$;+=?aFb828rZs=q7z$Vbwz_2wWnGKo%62YN)FsD>!7A>zhUnLf*N5hm1MFcsP zhg^OpZgzXK|1mpyqtWG>K)L6GaUxQ>s#>z+V>Bo-5_xWvrmWz9GORv(Ha&a#lau`O zzuD`dW;PGrj6r$s)6n5w{&GF(o%KC9V8@#Y%J>Kn36Y_?Vhgs@zSXAF6_a&W(0@Xn zvu;%+_olqOd=Uh4X_H4J$dd}EU1$4eCkhU84DttAW1#xF!3FYNMk?W)NAKe-V~ivD zEFBzLX2{?V!O|TQVv!qdi~-OV&Lf~oISjR&Y*Y`qR#eLHIma=`zyG04hf>jqZ0B}Z zSA_s)5)TAmFL@!468d{|cp&z6K7R)Nm{YDtg2|6QU?sQNVp^e)}K3}>40OO({MxiiG@g7eK<#9=1mwme&i>OvvF#DUSncP z;|vJ?%tS+sAhOfy&kT(%A1s6K9d~f|!r*V$aT8_$7Zh!9DNcP-(olj?`GOS_2wn}f z(V(M&l$4Z}xVL1at5O6b-E^?pbTUe^mO0=}qY@$aTlR^+81Ze%Czf(;Q?QJDTwXgi zp$?@eEwPTM;QV_Ge(e(8N`znE>~k2hln>fE`Blw%_9wFScnaKVt*2+?!^FV%K6^r! zMzp?a^68j;c%%Bj!BG8`BJ4wWZ?_-|m0|^CMuMM$;Z<913Y8VV#f+Wzvhara3)>Fv zVoUK``lrrZI43tG%!BJ47k82s?Ntauh|0)UL&@ z$cuC=ocEtyapK#6zhvop*q_B0A9Cue5B+B(%Vk;6QBo}RAV)3HDM%FWh!Ct2U7l7A z?-woEt(f zK>qnPQd|!}WU|qEkDcy~Ud6`pQqd1yv^Xhm-N~zoUFg7J8(5gcwyl!e+LCVBN%prL z3E~>*=>*^6V01smYK?nkj>9-l{b9R z!>I3dy)U<~QVoBWXrjdy_x3EVjk;-fz(hVx%!3Z~elE9q~t)VF8GR zGc!fqIK!)>AbLI%us>Zra@i+%7YYg6>3=3|Lm_w*$%7m;szuoI2%aaMNKaT*o0hwX zxQ>rEZa%5EXmrz(f3(=}Br88!F|qY@FXfnF{g6`c2$~fB#g2-WPDPyeLLs@Lb$at| z*jKwK79Mz!7zRVB=@dEree-BK(612?pLGJd5LZ9}jF&q3~SHKkTP6(VRCY^9AuT5py|V&z~jnJ&IP0V^VQ<^Jokp zugxzXJz;JHNyK?{AR!Di;dJih@*> zWT$QCo55=a#3`>di>JL+-(;^tO8fh3Q|=)&;l~!z0_D!VUHB~~brL{-$DmR-zZM|DLX#>H)~ zLP5%i&lGYykfcPrs4lh+ZgSz|%z60|XgpqrYCv-yFheQNLpnZ24w5N84Co@Nbtn$? zvVSC@^pL7i)NjH=JpMj^T|12K#epWACUJ(y=EmaK4A@Gvb=G#4BRO z@E|MZYyQ@QE-xoC5X6p;nO1lnTM!CbH|NqBqe14z%Byh(%=1#Q7p9?Y?OmZSVa&0n zBj2ivoU@CBZxFRGPUY7@pYsK^87IkOavC(_YtQ!T?rz89(Qol6epjZ<`Q%$8d^CKv zMb>Oi#UzoYJMKO-&tR`Kk)HZo`ur4j>uP+dgzYa@=j?+U75}oJt%F-gFXaP{P9{9i z;O+*%(OmYMz${n1=>)WNvgre+NA;YQt}YM3R;ot;bmI#|74PM_dOOvjY|@1 z^dxr37^Vmc^e&ZhM(NRJW^CGmWY&=v85pQmhAaW;d~trB8>eTSDhXDO04oM&`Nz)g z!zF|-Am}+tIFI5&6OJ!}`%uQ)OEKSSZ6K!K%K8oPs_mhNOE1;47{3j*v^q`e| zb|S?YaPaR~Z1N?$x2{XSQxt>`3K=nDFJ5K3`|P&miR)?onV%6s@&yboy#%j0v7(5% zgSutYDU*(6LKhK0cv!p>8e%bC%n}*+y-X@-H;gmz@8JrVY+AQ(v~H8m_F6eYMPueS zHVB!`-tq@?%~%YQ2iJ7Nn1MzPa<*{gGU{^^_o5xIjqzcdbfvvF&q0{ggoKW=)J9z+ zKwwNeHMl6ywM+l2QEO-aFpz4uwfZxxGGLSZ57~mU)Ie5!px}lvaVyWWpkp+l$-H>+ zcjW(8mxwWVsA>$dOVf{JO&4twC}q71F^3zC^t-mBuMULVOWkRK1k_Kui zaI-#^0${(xz8EKm#|on381IQw*2-CDiL11OH1AH#FuV>{|tGZQIpP zYa76#v@L`X+WM4_DE|zO+w~xH0`kmjMr^yR0>9P7M(~Pt4f~Rq_~9HAHgrv#{+!8= zZ=kX{TleFahmX}0Th;p1M>jZ1!xKTKfU&qiPuuaMoWk>dj!U6hhP}S>CY`+Nsv09+ z8(!^!Ih{S61E6$j0ln^66)=AJl`M;>rafFkylV%^7X^K`(XctNe6+W;RGMCzJ=(V- zdNeKX3zh&sBv|M}`!Re(9b8oouc?XkkBa zr}Y@HZ9n+_C0bT?e5oh=9x55BGbgy~ubURs+9yThDGQ~=pj4C;mv4zVoGJC=DeRuo z1&8@Ad?`|dgf`ZFn(lz3Ti$i6Mf~Wyt2IqHgrT`;3HXnVFAfGy9)0u~?QD#Ju)2HT zpdNi}5SGg@9u%eE&0ujmiRmRV+oT(Il12&sH|HW>vszK_NfaMqVvrz==KZx)QX>s+u0xR*!b7I;y zSCcTv^@gt)yO-Kp(Tx7kkwq3o&AX=Q(dJlS7$T;jd)fAdQsdg{Jp+9G&98#I8Vm!N z!DEw-RTi__3-<}CF>QXLRF7{aBwlss>id*YA`H}j`_5R{1d2odUTW^4!)94oZ@yqE zmbVZeisM!Cc|GJAVTgHJ9zQtj*3Si{(L@sWe#Q~JlK||klP$P$x?=svq;pJFiTDfAR7%_r`FfpEi^b&U%$ZYk5M&EE$U`;K(QTM zIuuK(-##&Q@Q``b{i7|Xfy4g*JR2=reD{XIk73_$*6%E=63GXqLrGZ^du4?VmWu|q zv5dUQSQ@5hCfrS?5~pQbmBRen7~a!ig(LN#ZGoWQ-9+VwNl-@E9JkS@WhQgDhMn(Wnl@_4kjk1o4sZGbVZy~IvwsW zP1Hoh4Ts`o0B%E26M@D=eus4as7*-n=%wf8vYMCHPPzCHSzd^Vrm@opREu;wM_?h& zeHvs}^A+uJj6;_Lfe8q(O?!QH{`$&LD7n4w0sVKpo!9>0COf z>Zmt+8RL~;)Q63vl2ln=a2cNko|8REejS>kVVS(=!}2dqW~f_tr;lBO^lG}M0{^qp z68rou90XN1U7EEA83HnDm&nH}QYKUOlG&nH2M-^WCv(e+X3$!^SkK8GZD|^<) zLX=aNj;A))=9jtv(5Gj`(j2tTu6^DCBm?(Ih&9&*d;SZyS^Qmb+EW>y1f2`@FmD@# zJg5ak>oav+<0Qj}Cj|?VcE5NwIxAcnyEL-7_xJA;@<~r$ai09_L)RB{!l)l^Y3#6&fU%;si4RbyaiLq^(MLtvCxb;A4orOOyi zw|h;W9jh7A(ya|fQd3AT!|m^MQ&wBj+v4x;e^r7(sSuhPF-WQe^eeq6N}M9B8*fdU z6voxvNx)y^vHfJ8%XTs(?#~0E3hmHJy%NlQnU10==$Veax+>cC9Ny~Bw0y$3@556_ z>Fm(#qvpIED*cRn;a)31PE=OdwOGlm9jTde@fgce6jzIcVPm3|XwijD-NtS>^j^1%2Ww6=4Iw&N5nJ9>`|lh$mv!9t?|NMDH4uTr0SgZs-NEEUypFa z;8%4_``CD^((=1khK0G5c$p@$qN50e$&63%aFnXPU9E(*@wX_aryWQd#AMw7RQaD@wbTGaTrHF21rnxjM7a6=)fi&_h?U~gL62y z6A-YP;!(-4$<-<$92Z1P?IJ>OB$>#IFuXd*L>q#;Z%jndaz$^rUSP{)#k2Zr$rp9Q zm;_+F+MrN~lDG4H13+zX2AnYjE}W5%TepUa$(#N&pab&R_@3y)hl?Vh3lLscTXFF% z)jdAN-r>W4bKEE>Wfw?q=t1e5eha0dbPI*?+*%pvW+^D7(m_!XZ37V>bB?iNlXGE& zC(RRg0{$-fHlH>I?UMolx|zJO z6TWHhG0G4I$G{Y6XXqEcU8x;YV|{%LcDvPnr;GE;4SD{(RFR*XB+L@Xijc0ZzSRW@ zGm>%?4NN~uIKFRwv_woTImsL1<{xC z)2@>B<5IfvXHK5gUojdTqn}6ro1%Gio~?XuBnnv~*UtH@?ZFV@8q)I4;r3zr&`baA zLkG^l6YAC-zt+Rq(<2i3FA3PP6CVa{E$&r|0`uiz2QTJXnR=K zB)!tSzF>}yn0d9&Eca%KU*Gcci9w;8Tu*2w@z^(oUzh;)8`pgz3P~Dj3@wCHuNP~5 z>ZrU5Qw%0l%J6OI#6VX}>(Ssb_s30AzW%@j_BfO0X3GYUmx^OJe`qT`a-_&p@+yDR7a%U?1t-MEvB z?NtDf9E>cWl|m`$-GI`^!oQN^;o@$_${ihy;zPJU)}#X44BNkB^Z`=O{p8|Juile6 z&%^iBf;I#y!!BMLER(HYM9_fR&@yqm#~|HeWK4`TGc9j(vlIZo1We_-B-lpQz>Q2_ z=DtLh7x#cge+8$13>KJZt3_T2L?hH5EyMVd^fA5XIFjTpV`JiskO&;iEK}-0oa5Sm zDmZb@-P)_HEci(O$}kxP#I_d8z$t%pB-P?pbN`7EtjAnSOj)+69Vu5LKo826m6;0?QE|$xrj-%z zDznxABzvg)_7fhOmRMBs09Q?X`RHK3zG;{t1@0>|CGtcQ(=a6sWy~Nm zCt=1~9#4?H&Mh!UprW=N_ikJvFFUsStVQ&hvX1K0KZj(0$lU9-KNW zZQZFKx4hHZ(8Te#d6PeWd-t(s2BmIa^@MHX=w52a``OKi=4saxucc;fMQ#m%uOHc; z@%uAC5}73@WK0*hSH#HthwE4^=d5sf7_hq?n|Cm<&UDn}VDw;HtSsBk^Ld@&PRc;v z`s~>$c!Gwdduh-j_|!fX6ks$$pk1*Ozkc-u-ZHnGt{7{+h(uv*AjpFbMU`YdU*@i1 zaI^!LO1Y}D`MgV2f#=vcP16B;qY-$xOd}Xk&a5aA1dxxMJvb7*>vIH$a47ityZbKZ zRu3M|l@^(@-L%HE2TI?S3tHc-@2ffyI6KJO@M;9&xTs}QL&N)~X46X+#i=4S5pc$Z z_p@lao<8S5tUirkA{0RVj=s(M;Y8Ov@MLO z`nAT(*U<(T*f|0Fw=|5GL5`JD0HTJ8nh{{mPju=P7cYeEP^MeLIQc80v;c>*Aht*K zKMKk)2OYW)1P=#|jE4kOKK%YQkR5ZB=#qY#o&N$*nI&P#;+s)T~a?l>7CTE(U4^2j+9>po)yJvn*SQxV2 zdLYc=Hszf?a3Q#Qk($wl&Zkx8jXPuXNYmTjxp|I=to%D>9OvdXeRt+Z*Vjj%{Ks?d z#nY}94=)0q0Esrgy1en+2T)f0-Mmd0GQklfhXlQ&5jJ_FthJZS)cOU{guy#CqwrP0`3>1qidGh|ds}E+6 z04c6nwB|!o!|Co0sNQ4>T`OYmQbJl><)e{p^$rXq%>eM7oPvQGLpv8NOCg)`X=MN~9h-D37KBf`u9 zklB_-Q)~aWk&la4_G9w(FwEgeGJ@3G>RSSR+QDUsEsbR6Rjm`B&o~be6I9gW@@DX_ z2gy#LMR;hwzPNKxt`1JGQ2$p9Gd^9>k&bamwPQqN#$|5yHxks6b}p?gK1@DuHKR1p zi;sh0cf}UF?!wvq)ysA1`oY~q*LDs=eSW2UXUq?zm^?jtU=BNyl&+1rNih&aC;B>{%70h6C_X)@o^aY1 z5exedfpNyci;Ii*Nz<-tW;e=-=w8j$Lub|gU$i;WB`hkYu#fOfV2j*I*9{b!ulVF# z@B>IP%#|X%5MJrK^728u8tfa(qPurW$g zQ!>p$-)j@*LMoYIO&=p3R~7K$nZkLwyF0f1eLOHZ+_!8mhLoM)2=p>z9T4hV8cJ-P zclX(|h+G*|B;jBnId>Enm4j8|+7|NAo1pm_P$MD>=sO58rd2dF^CmY}sWJ@DdK%P0 zHm$ZbP2-3tul@T>jg!RUVY{ejYHFeEZQ@-(0fT*kSn*#L4C~SIP2Me3|CQ;>czC(P zfi+L_nl?cT7iSQ53HIj6uAYad(Nazlsw>xDcI0Im$Jo~OBv8O|;XHooN5!>_Tn zt6%VWv7EsbBfqTCOiB5l@sg?W@(1geI;9iOt;=GD8AB3VE+Uc#V>Q#pQx5g-$_cK0 z5a++KvHj;&Nhu3fODpDE3!7Wx)LwvS%$sEV%|7(=B27mgDMPp=6E(y~Uxy)09_Kvn zQuly24vEBeK7K2c_N>T*!=Os-irUSU>L2&R2`hFFjgzdVYO;Z}1vreAFxc0%ZMM({ zg91kO2D_d{9Ky`S#ZqaJk^Dn^ClSzmVo~@L#S2|a%vcQi_GPk!O`I`pbXC8Q9g}*J zN;FDbJ=zcvTAOKn4FXewQXz>f^Y&9tc)FD4N zPEJ5-^;gPDe^bU#z#p^Be8KqJ>Rpk5mEG*IGC17xt~L{w3VWRc$2`?{<}CKMx8jK6 z=vn20wHDEg7or>az7C z5Q>`iB_HfW=J_9hRPE8>VPBV8+t2(gJAZev+dj?gk5+!=om7*KKZ>BW9^DqkG!w>P@3n4WU>uX}j=?|9%-4O2rIJ0ez%g6pCL`+1cbtdV|E2l>mT0FrWdRsa21 zG%xjcC#g&nSX3pRk%P|8%+fvwotzycG9=O)#04loD2o@HLACtJNz?iqn_^( zG4Aw}_~Xi|Wp41Kv0@6ie!;>0r=7v1)F{sFgZbb}weS#swWEbmw1NI&=PJxP#%)|O z%p>RiQ;REn@%mD?E4+9J-`i=@Yg^p!Fe)luwFR!hYGmTlm5&@GtOcZrZP#KMICXirou-Q`Y;r?e##67mL?` z2%V1bg&OgC(vQrctLk0qo<@DY@vIb=&PA(Cw=`DzrBW>Y<;+>nC5a9VHF3r?tVYNe z5*%buDx^z}^jq5}{?!kU=jxqTSbKeaU%c>r?w^$o`d_#_)aSdS)$J0fPzgD{!$Z^% zjfes)74k2R{m4Ekv!&XcX6y@N1?%(th1zi})Io#QI-H03Slv@CDTh?xHJKaS2atf{vF z<0GU*VT6oO*l0vxfJjNl=nzn1NDk@l4r!F`P`Xh@Hxkl_2$M#-yYoH&7yYbW!p?J^ zJAQZ8z7Ca$Y2r&%{Vv#8jQgQ=MP0EiwgWT^S)Pt038XYSVwYvn($i;Jea*KPF;Qp9 zRiA;xoJtcDnSY+x!-#1d4dJT8*%TRlcJis zk7a{C3c(K=UV*8xWCQxxKSFvlmj5zt31eQM1I2^H0H{$U z+~YC08!7Wk8qqK zC%wr7$;C%4>1*beP9pkT)uK^wYSY4TU8FWpg=HM=#img=>$K~Fb;AO@PDnxG716~fZbb0lB z#Pb&{1wU-5lpL)qz8%NFBgTJ`EEPNkk+rpcvUw=-D1aQD-=1oW2IlfIa&CJ7UT)6K zKW@LfhZ0TR_c5#g9F6|&rO(-&U*?TsU2Gi0CZ>&|qIx8Cb;hSo4i*j2mC$|(L#T#n>&+}^gSsUZbv(7t#mhdCdv+`Q%rVPNKvQ>rbG z&*fZ4Vrtl#WhTyV?N}{0D)&X0NS_97x_J5c_;|R;L}ohsEqKSj7(O=mmao|zAsr3B zfG|R>E6Q_G^`3Vp{bBSz7Z=B)+@mAe;=VwpksMRs_y{fho-3-UBQN;U%KN<6l3hkKXsl(y>x%+?j7n2x2rPYUFPn1=Q*#cn&iO+OL zWc0RSgJ6wb+wd`nDc>LnF2iIs-Ai-aDt-_681y#_ZC4Xjck=h=_XOZMp6G}{jc#** z#sTjIV*8xjADg&jt?qj}yQ|ie5#hi%y_na@2ed9!DtW4Y!SDKPHv>Oxu$nV^Lgqts zwzA^lN@!b$UxF$3>N=j;sx?{>!j$cXslc zfzY10uE*ESGZHGt%2jWi;=HQ~?Ec-nJzZ!m16H-nOH>T}&!=}E&1v(vx|o_8e7HXz zqwhX{J^jjW`IX-`a9YaCvmS3^BckL%0oY$4P+V2fNbEOPlUn>DgGUt$>>Xa!PTgFTny&Ph_bkZ2v<{VGVWL;B;dx3IIqE=$ZxCoY5Nwdgi85wF;f`U!y zU5Jua^DM>s3G(tb)?}Mp`89TkKFX7$*;GDR>iw$e*0p`SK5^L6=c=dWCN{kF<6RFf z6!XrUWBd!;Qc({}I(&>#?nf~jluts2qWPV1T9DxUb8H&?u??>0V-RL70T~zrO;&`4 zUFCKZn~coZ0vN)r2L7s(j&KVy9u5a2ONb7ldVjLMfFQZ8(E&GLwR`YHDx0$$?Cs zi4>qo*_Qu)0^~A2OpA4=QeIYW8n%cwH#Gdo-!8>n>;Y0NXIc8MRMphf_Ga5I*J$l$ zTYaxrE)WR=<&WmcHR3Gh9|7A7)-$9n4^2cS926(5td$AoA7!1Zf~oUX*CrLgL9l@s z+j?shy#eOjH+<2@s(D0+{>{n!c^AWG7q`qXAj!s^lD{H?cr>*ZR7{wop^fXWVRiM^5w zf80o5+6@WtEbj*|vg>mx%n)A2JSeR`H*6}{Z~jW()JA({Tx(cwyPdUQBLHM`GfoS) zY4&eTgsQfyO9wdlu)juspWIkPE&-y|R+HIUovm9la;Ele3cxu*oB%wGWOH3gkZ40^ zqvZ3c3X_$PVjogD-m6%j=s0S^v;^9#uXBDUcieX?BKJ4V_cu9y2jlcvuYGrBDoj$I zi&yRZ%gvssJ9;~Z2mG^l7+6Z3l#zvClGPC?DZ>ZZq5Hf8lvCj05Lw&RI&mchK- zY|mZ-B1mk4)Ne1BVNy<(8C$$F=%mkXDG?Q%EQ43`0Yf_v?+ z!hZLg>*{DT6S-q3rK3Y0?sv0&6h}sM| zxzv{)1~JRBkppI8KZceW*A}Q7_R?gS%W9Z4YRj=#6pokF3Kt6EVs`3MQq}>p;C3Ye z7~;&M7xg-sva5HLuAi|@pBuri2Vy^!nCU;RuLXe+ff%uBu7CBpLcr~!w2`fHToRBj zvTwUQqdi~fL&HLuGO{uJw;&BHbwy3hYJYT96D^p>Q8|-^~ZHmPnQlo1R;MguN zyGAn#n|-hM>iyTx+sqWh^cr~mz+#Mp_ww%7b1`bZ@&1N4 zWb`nP|8bX5lvABxrYedmr3?*x_ha2MCYwQVJ@KFbVvVGAT%MDsVA_><2-5rR=rS+t zbM9xf`{u_PPjzr8rT>^I$*tzOkC~^v3>9QI)Bj_xIVS7BJsC6Q zb9pm0czP*38kyI%Y^8($>4T9Q|8r+)c3qVa(X2%Fs|oWWO66@E^fqYR+0ocfK|$@1lXOVLm6IKX8 zvY?F0l303T19auSCi;;=cWyf+fBp1emw6)e0N2Pm8s=&EWib3TgaNB4H9X;|6>-%T%2GJUwgmdSchc0nAQHO4+{e{xxt6DMWTQlbWRdNmw0Q z+F0Cp4lK~d*!$jY1JN#knLJ>Be`eo)JE`x!H{0lXytX^zuKMZob}89gwBH7~!^~cb zvrMc43hU>vlnb;cAN;oLc|}Y==hvrn?zi8j%dd^Y+0T3z1e%RMr1_rsqO^3M_+ok% zEykzvvy}_Sn@W#G`Q$jnlZMMbY=lz;u9?7cp_Wi`Ps zVm)LdP%+@do5q=#2PSdw zN#-+^Sw|XIou+nZGIWhWtDbwU=bbNylhs#0QsSy7Gn1Wkb#%CDQvsQEx=eftYd-5* z=V0eR1Tt(n{IA}NLPfGAuxLR|>2}k;cR}JGDqufp7?oFxhij{hs?hx7zUzhFoB6l= zS^TnJ&Ckj0Z0T$m$aVt>B-om)SdLo7ci??}=`w1X5q3LW4N<#`J%kRC!k0J@cKq9R- zpJ4@ZySH?k<8xo+e>SHHyp`rW8!ffJU&E9~ieDdo4y(Lfv-iWvZTGqHj0BjO>D=2* zT$MUygH#qXDtV;U3e>#UP6?0g+t26g?-|6sMAq;#0;v_%)3u{_$naF&QC_wfd>Be^ zn`=7tI?bIy{`l5~Iz8UMOJHrk7~A)|?OeDQX&-C~9BTgS(rowcbY^hZt<@PQUfxb< z*UxyV(qR!Cp3UXCFZdR1hP7YxhmGbKvg3kaT0bIw4bWtXO0XJLO?AZF$};;8IOrFdxQ%GO$9))J>c;GMaTJuLmd#Hj$RI1S4G|~DXEBt z;K{;mI`D^=19SO_sm8<~K#Jw*4^&8bjj@eFx=Y>18aH|_*dt-=tPE0*zL+d^dV(fu z+Mb%ghzWg{NQFQiM!3H~dVyn!t6sbn6}7#3WAP({993JLMX?_sQrl7)9q@JCHiKvL zZJy4&B~_J`0y8o2Lbj;cwRvyV&5??k_rCjO_k;ci`_r7y2j~=bB+d=U9|Z7(G}um; z4PWgn`JksxfF#7OKt{~=^=s$n0L!(pkng{RFz21ZGZq z?3&q+bGe?&E?)mT_gi!g0aJo1&g5rN?bNvXs!2(m}-69|A-rCPTaBH_b>lcvs-AqUaWYva5?bSZoV}^ z5O`78*aMz;c5`B)q8w2i%*qkLYC|7vlg%5olyUdNIzMixZ@q{JHE!@T|M;b5a-ha` z`=&U~;g&_3z;;HdF^?Dp`x zb9&?Msc$zYTd$OUGs&ri;G$LCQy|Jt8=zre_aQf&s}-J zO_d-Ih!^;dGqNT7j|v7BKh}$CtkpgEZYfg0(@n}qTVboyHwa~sA@p-hzdf&C`i@ZnGqXxX8NsYk!Hw+(nWQD3r>@cmR^vj zzjkwI<(nj!D&maHW#bc3WW)i*!wRI7BOHaZ=(94FE%?f69jucye>lvZ|D{SdV(jJb zHTt;^GUi@kZf%~b1U!z-t}yy4Oc`yxJ=xe;XJ^c~KK`Ke?@-C_xP43|sSXAZLmYAt zfifl~$(vY$$i!F;L%=ZQqN;ftHUtT6Vrz<`TDae%_dUoHw*@*wuGcH>{@2!Sx&Ale zH)DHSMl3qbZJb@ZWR^rcih9HlE%$@D`wl;c)Yjovu%GT-RhI~ z&u3X(gD@Wy7J?(88OdKdur_WYEVFO{l`vAJ3p%nrKT0@nzaP!HSqihC&%D{QZxs^x zvZw?6AXV(U15H2ItSD$N)FVf|1f4Q7`b^;1^Q^Y2-PrbQ36O`WfHix_)C0uOhhH?d z3f7J;%5X54-Q<&410?8k=f@QotDJ5>1(=0mBJg&@0t5=Nev+Ch3}yYuwl5xp$;A9FQ9y;%QJF}*1&f53vG^P=)O$@U(V z4k3UrUf@Cg6eR{mRN|2fo*hh7~4? zlN?eD0yBf?6yS4Xo=oYfiU78z7JRmc>jz6^a+%Uq^b(%U>B#lSQ|y#89pHch@-nyY z33#BiDx*M*uhJS*Hk|PDGoZS+AK%}M-UG6~uiNt3Zu9y6T`#8nuC~g*f-MSI66bm{ zn86Bsy(;f-Rf9_a_nH65ZKKC@VDm32vU|bqZRaC|e9{c!*in!Fx}kBpfv)~{47sIZ z|23OT;A@3&a#rhd0vD+9Lj6#5A7bEL^XR@Y=5$2purm^FU}%UmH0X-~I0xFvIzSsD zGPln;Dx^<2l|l+*(_Hze6CYJDVb|(+b6Et)Q$A-G$0YOjQ7E+G5G$*^eDlQGZH})% z$)8S_bcrJQDy8)C+QTA(kF;ADvG1gK2oB`nswV}h=Suw66 zUH)HK4x_Ta(e0P`_j{Q3+j>-(yGtt~QD{AMPIcBWP(v_&l7^k=Y36n_SFg(>>_i=) z*OGMX*E|(M3e42iyp+2pZK``33N7sZuU34%cd)@W>I_SoQqD)*7vYdMqt4g;?|`S8 z#rWpQ&Q8Is4HQ>{Y`4j-*09$0Isf-d6JxZpm@$EIYnxQalufc_vt9*LEKkPpwpTpW zM<#Vr?c~*XOx$%4;)_Kz`=`6*0DwxG2>dqzk@3O7_0b%6+v}xOCHfyc#JYBX+CcL7 zacSvJMs}L?iSNSCjj*q#i@9t?D%UYLcc5daJ*)40d<= z>0xT&g}Wj!$6~Pa7ffe&nQHT%ITraf*OO)Jw0`sPjH|DkO<5$;+9{E2Xj!|5QnV&S zjs}rrtb|-GZc~^}+&!w#@FYBtX)g{4&hpIja44c+>C;#BULI23SKH_QCxD;6eqY12 zvD?g=USEc0<<1cY=&f{J2N?@quX_G1E$ytFEG|0C*Uy~$Ul|jFHID)^I$o^X`|O^# zAHKSWV(Mu|n)9h&z(A+O&tfU9lmyUSKA zd7^AZYX2iirvi2WlnnrE3C6-!fNe(EU?S#7h{;m8;;tut5EBR_uSkN;N6rNL;{-VU z*nE*W4`TF>x8V$zeQ@sB_;UcwrU}C~t%XA}-_leMSrss0gUNA}*ii%J8VH4&$C^#^ z5iBUPh9{Y=p`5%DOwTyzycn2%;3f)wi4(SE(#el{|*Pg>HaP!q3y($nkov>|({J%H9M|86^& zkkGnuF)fYak*~j_&iOPCv8*&a|I^>yGARWRf6d=J?*aaV2oYPG+W_hs{Lm)d)tW>}sj@=^1o>!Fd( zvuB)J97k46rSthowka22+QdH7AX3ewlTxLf2Fvwl4>d)S4 zIp5Im99l&m`ZZma1xEnL%zdAA5rD`wk|h$r9s-aYA^~}3)$JyB;rnXgBpXY7DJA_{Hi{zAg* z;!;}H#mU9zcuj@AD=LMX@H?kcPCR`2LqTG)*f(q{Q4C!wWvl>fK~txt=tC1 zl3#baBWK)py;^Ysrd)V4xF3^z;jw;+r&c0|*Q;|IZ@yq!fzy0?&?(%Qg67B2CEJ)}zofd9--wtTz z73q9!Pvf(GF)--Rw2DUz3}^3 z&N>Uu&Jr`ghP^WKlG}Y$>~_rkZsv3QeU`WUME!hob7uTkvGE#x`}()~3*MM(`r6|ktj~g^@Aj8PL={l+Z`#FK|R503y7j>{yh zK4DYoP3L?it4o;>F+!wON`K?#Fv`t^{jGM&M?geK*zg%0g{*OnPSB$_yoyn)UdCvE z#BDz1*4!%C9+0?(o^lcHKei$8bHE`do|pdwU_6&A#%U9*cyoqX68g<};ffzgH5X^s zqOH)o;+H$dngc7kFViyTg+1?VL+0z;|8 z`t^77^f#>wH@gd19T3xaDNoq|@3V(}9dwc_rzwwHev*3=Lq&xo!!ZqNaxuh^XXMJ? ztlfYOhOrOhr?+;^|NSBEz@zT|MEp{1;ePS9$LVk$Gk-m|aNlZwJ892Fk{qfP-O0vR zvYz%L^E3S0`PgSkK_fhgZ#vcm+*Mp}6hRT;)tt0HZHXchV6cLq&%J-EInkmsc6CQ< z=5X?}Pnt}zBw+U$q{*b>^B9%!ch&`k;P4=lrSYddj*lGBhI|eSr`yAFp!eF^<6f|8 zWH>?QW0Dke6xV1r(oi%*OSiBy%ntqfIx5HS{-^lW@$kguKPSVKiOb6gJG5o`2phjd z+IOAt8qQMQ{h6~Vbkv*xP4IX`skKO!c7p6g7|;7`QLnaVQW0KPS>m^2<5XoWefD#y z3qskmB57-X&oj_-m5o~$8SVG=_q_|(`1K1nP3$SfMO<;`Z3E>#6_}2Cw#Yu43fHc0 zhE>O$8Oki|hl_Zfp)!BmebF;Iz4|P!7SAr4_UBAw67c=1~-ZVDNd3n=l85YB` zHIPh?lPtCFy(!?jvKXj?6x?>r~l-m!&83a1Jk%$w`NyALGQz(e_d+yzIO+! zQB+8bjx0D6-J2+D_~fGwktVNP5rx#j4~B=5Fl|fW45etmiq%vbs2(|@i_=twvaB!v zB7w71r~rTK=FY*!1)v4LQr!m*>Zi}1J*9i9f;w)>Uh@nrHl?_JMq17Guh^C$>BPH+ zK|lEWIPQCcD!FAzNEO43R;OBgM|hr=q+(!dM4%@2R7}vpPTEH(R9lPjVW?*`Uv$;T zb=jbZLayD2Q5X;2s-I8dZ%ARTi{v_Gn5}%gD7L zuBxsE4->tVP(?Ltp>717O+ROtIZMyu{)Lf2-RuBf$L^^qgMd3CB+KPYfu)Wy6De2{ zE!B_B&CLw^wqfx6{U-iraj)OD0tG7lBy)9-f`6t4eU{#*LYK1fD*vsOCbEPCX(X=q zeqb)7Oy>bcvMIj0SMCc}@Sr*H=yMs(^7=o>=J~TchdB;2GUc(qQk?XIspC#^{6i_n^rog}tAhR8PujLVr^^=j!{DPMR)gyY`1ch=C@;*hu`F``D@Dh5@DqfNSeLew_OX_gKNz%cUW6 zLe}odasSxAP8%Jrl;h@l`)4oKLmBE~BUJ2~CbCrhgZwtPJu z&r{T9jgRpb2Qg)sduB()yO=#T{-gYag3^>GRFXoepok?w;dKc~^5B#Ws)j`d(PC)J zz#KDMpW)`bd98vef19G_4|MDNF8bA)b_cuCN;sQQ+cQt5hFMX1sXvySOq3pKtET-! z)x&9ygUW%X(rQikP(&Wg)yGM(P*6}^rX)vCzJl28N zBO>qxS;b`Ac33Cja4v@ufXabZ)FxiG6h;Z->6jN28u>mTKf`bLSRBM(J%9g*Wp>d7 zKq31b9kRZCn}Wpf9@vOAdmgX(w6R4RM4QyUG}nf*n*w&qd#)7ExCi^!ZKkT@n?v68 zttsgj5EJx_5J12IoX}Sp0FHH3-2dcYTut2b=wi$Z?RR){IWZv{{k43cD=$yK-cC1f zFxOyc{kR8)2bfThV25e2#D{Jm%$U)4tjRf#^`(+Ek`q=yFfU)AoV+fpp;~m@)s?WE zF#c-ZWBKCbWaGla)4|O4YfU2;GD%ns${Y>;h-ub*a&nvAc2DG262oAUIW8Z9#rZB< z-3@$1hATlplqy(2!T6b+ou}y5+o(Y<+WQOi`zMT{S_dvK=o_{i$mEG7>Z2&fOGXn# zV+R}@+5!yH{p_ZH?Pk-<6-eFCW@)`;i3AL@Ik#~Ez{0;J{ov(c z>gdF+{_ov`fIhJTF-N0Mz3+^$dpkt)DadIHDmI#(Ov1NO39Ft(pt(^#iGz42dw408Mm!l-$sSi;c=w=b5%f3coN*r&j z$lgmDL;?uork?_06+{^W2-6S)yprUkOpC>Yf#mp~W22wUY~@pO6s%}=w7hLeCL@$F zV;4+_IeACLDUH{umnXaHk!TaUpKObY#o(YB0+>51kzxMjl-qs@9U>f5L;gDZwUxZmlcSI?^1n`|XQ{{# z#vO~&`#!ITRWP9&Y0C(~X@4{+wn$1#@FEoNQ+A$Gr~8b`jLi&c`6@a1vtM|d^e3I? zc@GqODO$Ii|DFRoz_ps7#9YZ@C;inl*&h^BLM9`88P-TDPs3Cv&Dlm@)5g>%X|ILE zTHMdi4#$j3Hw} zc@-*m#^r+KCK@+Uej>GTUAZm19}FBYS95k4{um&`(==ySZ|$Zs4$7Tu+P;p8I!+mV zZ!@{Qi}J43d+l>^uzG9(z2F>u{P{oO1&C!u{l4A^TSVHV1GJEex7%o-bcse!Y+2RM z^wW~wWoqR?@(?X@>cns+>f-RkN!ZFzxEUZOvtUhRhQ|_AOhoc{tOvV~u*(Vz)@XPp zecv!1Ej$Daq#SG5t;p~l}PDP-fK)PjafbN?vfug3<)nh;1YRC0|Nwt3u~9FqY3 z?>r#kdEI`od0tO7%I+G*=gl)ZMKUvJ>+*GI!pEwpK&N9oqBb22(aeaEZ=h$Nm_N$j>ZeQc^z>_+vY91ye)zGVC!bWCrb1gsWna|8+tDZY7|3P^_xBn``6>~ad1LSgfVUcjQ z0_G;h%DwBl_lqk(+lgM?37tSZXqj20;zq zKbn3`;?=R3v?>4vlD3d!dN|;K!6n@#Y|gMm8VKJ2;(0|k@n1w^CQBAo!FS!bhhBnu zoR5?7!+_LTSeX2APj0sIKs8fAcp@|l1VZc?<3V0X7<&7BWo`dk(H_0j8~gFs3v+7Y zSRt=W_cs*pTJK5XKhlFDYHAgO5{?YdSQwXEn*1XUD`M0P#oG?>zeCg%TX7h8IGBPG zeHL6ZiqxLHzPSkYKODWgzF%v<;TF3+C|X|!z=jiO3vR-R;hB1q$lG5p=PE6m+P1f= z-&IVG=DZiE7#x^o=2-tZo;MR183+em{FQeLFAopx^ri|{l3o#WQvN=0tgHR5fT1T< zYNoz-D>VqawDj`d4g*PMXW@uf7B)OeEXN&&%3!E=o_`dP+NwlHooZ_I;7bzOJPzoC z3Ua$vPO5EFqz zofmWa0YYhl6`S~*1`(+B03xjzEP+Ek9kSGCi8ipz3K4L8?Gpfy1l7P`M2(9fwc8hU z9_mzMP6p2h=CbyY(n~yU=iy`W%!SU(R$>qTr53FC7#H}>8t9j5J5%eZAuxGq= zVWuejZb1Nl9PB(#GU957@MhM)`;`t#d&3)^4!wjnV3~AN2zn8;+0$a&`}#SS7JvMb zKAAbSYHr+`oxvax?x`FV+6)XDsA1~zP+_uZxSGWtcj~i zDt!<&3;oMK=hkYQj)IKR0bYPj9TF4eum0ch?}l7&wV$c8 zOh=-vr&+ooQXkxgdoC{l&17yd0N60!*+dtOW?ur@w5XtPIm=6!7u9s(?o6Ad-nuA= zWo=PfQGqsV-4lrcaD{nbBcU9Hq&Ja6?BKWq%5sQP_!$YKGg&=HC`AxZrW_NHfjae8Ib=tgjUDFYqJdnT{$oc*l8?|jnYD^JDbMX*d?qRTApywJ&NL2iw0232V&_lG3RB_)1-I+7 z!y}_Q>vYlt(oYIlMIi)Hm;BsBS^_L|K7Z|i%jr0OF!Wa{Q38+Wr|dYGDOqFAN7lhU`=Ju9$ zfM_gL*P_9G=C)7)@JzQD%?6%84V9i(mtiwyR2HN3ul;YPqAYUkG3$NLz$S_^TFE_5 z-;1|_%OWO0VO&75jB_;RW&Ghpud)TYn$7%&BC)O^$}=Lr;>B_KKsE1ZS!ucoYm~z4 z;Uj?W)dP%nJ^SyD#|fM(B4%hg(;sBREV%)m3E{2q5}gok#OtSyehM@!USZJX!85q7RvRCMtNz z3D90s1!2__#St&@a7tPQz3-;vKZ{*Vsokx-zd303KiL`2*{*37zAm?|3~gJeq?Phr zKB?(@zAm+JmNBumW#!tCDZ8IZJ5ZWFgd(iA@#1;iG=X+f#^NEO45TJ&faZ4uA4~6( z*1pt&a1fQn;AtwFhlRb09MWm5{OWy)7M~Hjxpq zy5M}mfmtrVPD5HsJ=O?3z&G1h0#d`^)Fc8WV<`v@Ww;H6g5g637}MpCH;NJD?CO!J zQ_T=5CRl|+%ac{8hObJZeqIDcf2Dn5{~NvM=7GdtP!i_OI-yB~W>bG8lj3+kPX?bF z;n3hyCYNX|&ssrHxf^#r(4(mjCMCVU4r$IynH3AM|QzX`~Ltv3Al&193!mwDn z5r4zjWO*av^3(&!u#6H-wB=+8l;ba$4~3-HD7x5I*sI^_e4U7_IfUm!B0LgvXG~LZ zNy)EMa}!-1ahFKnfr%Jpzy%O#@sPI9BeLr}%;8YJCa#BN+7Pc#s^r$nGzl7uVRiQI z(&(q@y)TEqO+8Y1C|#5n<%?r%v~WILXg|4Ym*ukv1_(&`8@w|7u7sp-dt$w2Bf%dd1`FY^ENu$r*8Gm#su&>B(S*9z2)4hS0S)H zjPmvKYtus_4Ge)_XGo>+v|7;3#@ISgk0geh$@+PD31L`;`mxvH_#5rnHm^7Im{acQD5$-OHAoG-6(J1f`Z!UzS z0*XGMj_67jYnrTIqv}uRtzUT2dR1AFfcoH(0k}9n6Pqd@&VSaB3ZQt?Jac>E{h#H2 z2Q(y8{BQb4{gXo{zBLXpyo>yauZ`Ry6RjCTJG1Ec1x z`1Tp))pa|efq^k&nzIb&r>W&eI*Jc~GU|wDfi`Nl7FvMN(l^CYu*{-r6lJEaG=}&P zBs4v7Cxd5!@Zz3<5rtHH&!@m=5Ctg{tt8p2|8$Lf#_-G9O046Wsexw!Gy(adV`j$qXo!H_ z5wTOQ9T~5aNlV;SsGH?`ga*h&UHiT_3H#!H_pEc5rnL37PK|p(@0-7_r>!0+^k%KzqI^sf0}=eFFlWG-pxnaN6@v^bVG)DMzdv9&Px$mF#8)uL**3QaPkNO81nR8N{i?QL537EeB=C z?GY_2OUMfj?iu<(nHdEq3ltd8tEgE@B<=W6oi-K{|DFLhW;q@iK<@lUulTAvocF0^ zOlAOiKF~ulp;M5^9p}0#q|rvH7*~Xw!8lm3H3#&vsN!sLGmjLLPFD^Db6!NQO4bRE zknEe`zdG)TG4aeZ$bK?NyV}XVqFwzU32ov>!DdZIQqDfw$uUWxA)5<=fEeRnM8$UW zB!a?716_>V0t*diiK6mFa5CH_2|Dda04kypmWXBErz86~>&KS}c;lj1Pd`nD6x~(t zql%z>Hk#9KEnaTk0(Qq}c8E%3@yLK5`nC57lk2C%vvA>2Ddm|$@T0{# z+UZL7;02qy(VSKfPaw@L20!U?@bsjXatUs3Y4Er_+SxkV0u~#rTA$&)x-f2@$J zLaVor7mUxxp{;T&Z#nPMM69H&sWK8adep)>n9Ig=ZC8=4%%LKvQ$23&9Rjncel)u70L4F$D5+$j%`o)jVxdk(jPV zC!ZhYu}}Kz!;9}-ZTq9yudfrtulD`#Ec}-;TvZ(nzecvz5x`}{Yi{doY4+z9Z+NNk{&*b;ZUO7ea$Q)BH1y>m2w%j7LrXv%76X)_z~jUHFC@g)G;Wk4`B8NFH4SKU+@ zCHkBfD2zDhCD|R=jiwClY@dYB4wX{-)2LOJX{Y>oqLxVt>R8ZJ};H9hw|1Fk+a~Bm94M| zFW9)HtgDINZiM**{>J@?`1R)b-O0|O#qidU`}3ZsVUwq2i!|0Uv>MLJ+&T7>Wy75& zEV40jJo z`!~&-YEn>YoP$~pHq?SmgV2aHKd2*8LI4jzz-9m_{<8F@;T?=6Z-5?^@hn@?Y8spa zE;||M!jM(dll$kiTRFvGbmHiXaI5Y@ljqG^M%4AW8j!0T(|@l!>$|H*XVTjfjm&oAI=2l174$a95QNKK*WAP~Yo-oJ@yhnEzsbB{I^YDnaPju$CP z0M9vR5{Xu+Twjc*_gRp^gnj);K~c?8ozKRM&4PLm$m2jmAj#-V5Sz>LCo+iMU_s(2 z{VzuiQIEEnSjH&H6Ho0}IZ66?5o^w{hNcFCEWkTI;S??^kI`Z6t^^_m%f37K?zMWY z9(PMOJ2yK$Q>&LBouvupA1v?>qtJxVliPzMATbG;a7Y6HRep+keFBpfHK?d0lTX_= zJ+YlR^WDE)oc(nQxa9c=_OF0K|F!S9sWci6JSF~XyC5C3kqeF9=PPTQF2YZ}oPEq)08BPA&Ldvy_dH@G@c>QQP}R9CBP?FCoO zwm5nV=rgb}m`7`y5mJ20=zVK^R5qxD>O1BPS!|(t^C)eTsbevdiJLSvi&lzY{`%{F zmh*Hf=b(&+-lPi|){q9>&Y;oK6^U-jT~gG1`?J*8mBMprifKw#7`D;tfq)gwUxq-# zwz5{I(|bKMF&8#aA*l-bHZPE2TV^Yk!5!uG!%TtNc4&i#Yo)rIJrG{lHz*3^Qp~l7 z3!|2o|I@u!kG^HATA)3VD$%vP|H7@~NS`qGaM16*8IwfOV?=4g!j#6kA<@l|EbN**p+h%Mlr&%NIcZ}eo< zf3}Vv<|f8XLbAQQd~{GODk>(}m^Fbv-lcy&@3%jE-sbAEU(q!~l3c&1`q@q^tf=S6 z#m~#$@z~GTqb!sD$?2cu1RGxN^)LmC(&B^>(PFON0FEz52rO-xB)J6%h_v$%BZn$O zKew?+tU4PhIh26`%utvb9vD(N@MFc)lppG}6e~FBY$VX#sBx_udv3{a*ct~TlK_Po z5hiJp%zGT1-!JY@XrFGf<{**fn%L~E#-U&Lb;>4srXD`X3<{dF~(1N7l(y1dO$8SS}Fj&2`dt=kq^(Rt+ zx7(xQmnZ1YVr`-#+)*ZeF0sQbUy5x3BKCUb!d^Nch74QPPL%^X{(`&j%ws#ql^;YH z^>}{Qt$EmL!nH!Ch55~|=FV%$Grtj`u`;)=SWV4H(BGen!Oqe}F0nIzQRa(CN zTkra&=a@w7=G%6&7jL8Q`dQ3)#$b;LdWy^hi5cJg17Y-(EvV7*Qv|aBGxQCgphn7c zu{>40wv@rCDNE10)q;LSP$&JKekVi8sDwu%r!TLSZ@R>$J3?_~Tt;DOS_=&Q!GIMm z7vUF?K@`0ZfWGnkKSc<9BpJ6V!x0LKxJI2Hj{5uD?Kl$8qeQbdO0|lL(3h}`7v=ES zbq+KKS}?=xSXUq`scz^g1I>*0r0&<_Agw1jD1mK}eJ}3b$i`Y+4(3JNUO@315UnE8 zew;t-y}MEoJ(3C z$vJ3?dJt=w#~f@LT`OQ30BB8$%ti-+SmkgNQ}lu+R$TH$tn$aI){%A<9;^UGOPP(U zO6%#$ZO9jn=LIiex~A2fZxNkgi5?ID=P`I36*cVj!sOa1Q3P5o3csp(t$PE{AZ(_UGfcys_k=XK?b zBT+iT#okz#+Wh_0XTPiEec!vz(MkYedb@JGdx@SHWNj{^f?Ri*zs@mB7=TbtyJRWQoq}R&nMpI?690Y zP?W9EM-WdAVz9O`Trt;RugKc=*^q_^WB^gK7LvDAqxAk)<3H(rM++xp9{IVh)>mMk zi4k)(Ko#rQn6c7L?@9kh(OHHy-8Eo*l!PEH`3RddD2#3pMoJ?nE#2LXbm!=j7$7N( zP#Wp(A&qoOgY^4<`R2tJE|r~g?)cpW+F2O=i8uo`y{y(U+O{BEe6>8ic#ebHGA8IR zTvl_mD5YpU%xLY40Cf_4dIS+nzDRNUQ5yy`JC52Y5m`U)h|nG=huUnhT*f5FDJ?DT)$Igi|%tIE10#2&zlH~3D$1u zr>2-V{}62x6BDgXx#`+lP7xt=Sn@r;7z^20yx!>-7{2N18f{^|UJ?5F*~qCCFwyw)(1wKiOB%)4-t=?Lq+3P{RBE-)Rx^uP1fDpZUSWRHf+6FB^?78uV5psxQETIQ{LdQX$8-^=0v&p0mpZVP0< z)#08++kQ)*2(u%4|EQ>lK&AFa|2YyVt<-bi!j>!F8JCn=xaE>&o>p8)`H8g-1pwg9 zsEFCZXid}R3r7x`HDC+-qR5}40Q5S7&i}_kW$84K;SvBc^;LJ*e~H)3xO2yM+zr?f z4UOCbjC+6EQWoeIY(?cJ}n6iMmh+{5o7s-QIk ztHt&M5BV;Oa4Pal1wI0R_7OQjDV_Yniu$wFopIYragXA+kp)Vr)yA&7WsA#s&Vc)~ zLCr$0-1X7L;i8cJM;hi*;OCj?*{lyQS4&xV`*O=odv9qUlK+PAWj}LcMo^uMkj(c^ zGX140&n~Q@hS@%=qI!?FR}Vz~198IQIeB@sv>YY6dzSzh_wU&F-3})$tMA?8V&IYE zL+;}BO2+t$*s+`)(VF^3YYsyQ4BEuajjfxlW1D+!zxd)IaZ5*?Z0d=-iWLz9P|$#n zc=$R?IyS_xS_%-}-?Y4D^`(um?Gv5;k>N+I)Y^XbkahJDi&Uelto}rtl~MAuX_b5j zTCnSjpg0uB3X|HrgynrvLxv+&k#uZqmb#@3UoPjcO}RUNHV`R(MMq1kw7=KY)%AY@ z`3`d4ggZ0U+&oTeh{gUwUTXU6rxQFNSWHSDU8h!gz@!e~Ey|5cJg^*il7{qje{Wg;O%;vv!iyeX*VVz=$=;-_(>}gL?aIt$@L87fAX~x**bpRxNDH&Kl9-^tVgej| zP5jQX5z{<-#h}VlhVPr@d20^*(v8~)bskcfx6nFLt^n0h+Kw1bS&V4 zcOn3v*yMs=u8JIjmf{Mmsz(KtKmp^6Ka5m_F2_|y{gY`uL;&A@`o+WdpQ2AObocL1 z(jCPF+kJO-H_d_}u$@i(F4nw$4s+xnIG!^k>R>g{|89#X5Gx~*isq9aHta)B zqLjt&zm09Ki$ERPkkEnhS%+;_#jK4JhP64|Wref=*bOpA>Z7j!L4Z;Lhc|@r@$ss_ zLtx7+*<2gN86`3jCQ2F_&ZkcU8l{FPmR& zFVtpq5oB%G%8Psk6r_p#-q68eYeQvwzBeT?E_Ey==RQ9(X#Z15!=Ck1S9;l8mOK_j z_APRNm=)bSAH91Z69;;`)=H>wbbRtna%Br1;l3gRpL|FGbvC>Sv=v_}yCzkb0B3^sq4^FAPQq%wp-)mXvWtLcu>bF$m3aQFmX6j|F-Ljb2zSa> zW99I?TXV*ENlG&dw=J)0In%6}#%v1P_#4pT2oChkFn8@MMs#D5G_8hDW6UY#EH0*Q zTG~2!v*z|ZExI+pCK3R4I0y7a$Wraa8F0G-_1FlpG47P+x6eomOvy6 zR~WG40^|zL00yM6Q0}ND$k58tOp=gIRnSL2v36oYNN`>8L&;KhytPsnGWOic>-kYCB`M{VjD-4gmwx=i zb)qGoQn&2HjYcS9db!+RjigWlENe^37%+00~wDu6VHvh2qG&d+$YT1nzW{y)vUUn&X@yHze2nZfOD+QXS zqL`~5_KL)bsZyI{CWkcFC)3KSmm_MkC~XVp*6+X~G2N=~L7R&Y5fvPzSQPsbyjw~Z z^4xzKb2UY!c-D-YPZ%IS#C8i`aoV<3)CxEVjJqQSeH|9*lf-rCq{tk4e*ZT@gpLse z+cjCbYvS%pG{KbOl9dT3BPC`j?D2J3&3MtB6b37fq_5QujRKcULhY11z9v(O91oNC z31=mJqnT!}2M5!$SnQGvU?kqwC%M&*BM%+tiKp?_iRhqFPhb+FWR0kL(_S5!EwitX zY`XuJ{m%PBJj;s~Yco=@OD&q^OPtJnO2Ay#Um`%izL*tbViuE_n50TF&II+uvJ&%@ z3IEX|AxF+d>;v$ijL z%!H^%7i77J<6NP2iuiDnKFZe-iG}d#-pOzJQp7!XdZfk|kokz*>bv*R^8H%R(IBLS zT8gYBLyUh@KcmruBVW;SF+4-xgu_5&B+PV`Q$6@2D{?COO6Ay&?f%zs*tjPyZ90z4 zCD-6dBJZ{X{+0loPRUng!0vAFb6Qf_lCfTklaS}&cT%IpBDv7~()7;z^a!KpVN@wV4wuYaOQjSD;l0yJ1&B%- zihtbrN9#t+WNGYqG__>3w%5r&Zh9O3w$a$qk*2{HK z<+*I({`kk}{zKU1a*JF<#5700Dxho)76HF5b00tc-TnUQEpy+3vC~*sZ&%l8E_QZ& z;J+fH%9<=lzUbrq7BijLzHY~|+wvF|1?s@dTc~G^3JQA(KIty<)-sR&X9M&b7s7#6 zo8Y02)5Q*;PaK$V2zN($tzJnhRyK^*CBu`Isx@S{gtEnPN-3Oog_%%9ASMmT7KJtwO;6mFSM#!(<&kS?@4E-i~ijU-}I>K5uGb(_@=E=4T3KGHADUZwEN*`GRztmus8ng%T~GNb0n z^uAfsB&>{#6+ynng$bpRMUaFL4l+`@Z7CsQ22b~@?i>TQF1D*on)M0)gp^YJcMjmo zu4o*|kUDfz6PLU_`0~e8xairEyHq11#4zocc}jM(*;D^gdPR5;*JF(aSawG`mbI8g zBtYs-RxZR6hf?!Q!~FQx7-^WFn`@+>BPQZ|xPUt5Z#hqY*vh;bbJYH(W4T7g9G}Bp zMGWO;Bj*i+1N(xRvU_S4tZP_5(iC29(91B$3bBHjNrYaakA4mBx*iko->2=tdGQt7 z!^98|viq*EC@csxl2{#OnS2ikE*}DfHKhVNAG#1oZ|7UD_`#pWscbR&wgg4zQFcLn z3VUqOmpu$i5G!cXanBzJZVbkP!gZ z4>)53cMby2Yj&nH>u%gUB!@0m?#NO}lE(%8BS*>EsGHOv-vVrH+3v* z2p)U;*l)*8_+u=u-I9n%zG&!jZodaD@W*K|6=Md0|25jW06BereCa$2D3gjE59zN& zL8ezGz@6-2;$j)qaDePj5P$qPT{=F#8u&DQKFfsVvk@l{czoUNe>Ya8*K`c9rc%sf zdeMj)M&E|-0$czfB*51))(({RJe*71KdB7n<|(DVSaE0d znPZ+q)J+5)AFl?Uk1i_DIb@?=qR8C2kTIhtH-L{P>isyT=h)^K(Ad0i)wWpW*)!u1 z!8U$Aa%C@Zp~A{CeE82xJUdM%{$N&X^-?jrYjQe$(f2rDBk&T~r|GyG?O5rvYdD%~ zsQ^^nyndpFvEe%IGfdyCF&qe(qh7>d8yr> zO5qUN{U~6D`yLd;f;N;Iu;*j+cxUunDfa7*mfZa~F4JQ)^KjJb;fs%a-iG^FZ#l-y+jonB~^pXnFr=H^$; zvG4fqc&uEm2q986ek|K(d(7E24Msqa=Yu0n7!kag@Jqk)^4qcO<85ThD`qj3&M^#X zHF-Q4s1bY078ZSC0;%cb*_h*>atQnS&7!*CZ9DJO5kG=5A;;&r_NMC&Xn}%klOEG*7&|R z(uLqlWy3&`g#xT5iP1T4IP*zdF`+iMZ`9M5#;S$fz^PWu{P{2Gn+aW(2^`5`Q0C$iK277Af&(^-ZP`t!%m8Osc8}u z34qP0!@rP4{#VT>JbVriHvYqP!}%IV-0=*i`-%=NAqQ?u*|=!2$a}WE6~a?UNe)ry zvcLps3<&|%9qq+Yfa76cXs|xfXEE36m6oOKdQ)d4*6koYdC-GEQGpOR_%B#Nz*9!f zjL4v;&F%-LjvxY)b*L=}T--(AG}feZmF9!F)vz#g=@QOGFCvdQFvI zwu)B`&_Yqm6M3fHw3&>gDIokH{$j>YzN2gNA-K4TI>cU^3>fSP`OcKR;w+VThn$?1 zpP8vLCrd|JK;S)3EI`G?K0eaj126!>$AC6b26KCD#xKgCVxtiM;IdF& zX4y@UpzQYN;`N{zytpF2;$;vRou1krrq3-a@gq&XGn6T+Mn)F!4DO5`=AK3aZxWtP z+wL6i8#=D;j$6;GQ8rDs=dD>Y$hxc%3hX`$XjsW|&u=|@%}wJIXix)S#OA#B)~+{@ zQ=I46frqy*I-tChl$la?LkQcCZ;66O-8MmMq+SrhH6U$szn3ze2jqUb6M%^K4qd>b zSChRCji9)2v+H%2#I4a&5uk3+oNsARjl#UundA)?qXz3eAJ^`j8an4>vqoQ>94^*SrG-1G6x#Xwws1LB@UTjQ>{djqXDN zkM%mPJ(F{D9sTHj9B2QcHdV&|#|;(pL?;;fvjNoWpy!&UIu{d6L6KUHwh z$c$=j|9qT}M#&CQvlz71Z5`4viC~IvByAbF3Im%5T z6}#7+AntG%AZ)bs!&`*2yqZu;Orq_wZ}QJ*xju^~^GL>7YYrgZG!7vPr@W2NlI^}M zptH~kGSSmRa>h#|BF?j$fNvuWR!0d59otVEt9F)&Uhgv`r$Ps0>vELh8ai2Tf>^Jr z4@~JaV8tVwDUe~S-#LK+H|rb5{^~U5sfu4(W1wG9a8M3KjW!6TQACT0p{HLVF??p;(MEj= zRHSn8DYdJz{>+#x`e!`bAHm~<)rwGANn-1`zOT@?#?!w2yDXaL(;>dcE56qUrPnK2 zv`aX`JC)y4_U=z6Hu<5~-4h}drfP~{;@81U6PSv%zd|W9T8u%6L5p5D-O==3xAGVb zbH;i7S6}fdWBLjk)hks7KsJcFx*T9i(3}GlmKZ8qH%FE@TK(Y{8=@YX$?pwIr38Jj zc%Dr@w2d~1m9GIPL&5wo#rwnGy>NO~L}Vhkiv{a#24T__9^J-Ae4L&n>rHhKa~d@| z&^RZKQUI-9UW@!4>*bFPBG;#x1%X*Y+cKDN8-yWtUNZkCn4!qx!%LimEPlx<~tz2wn zr1ZLH`_(M=al43wXrqp?Qb{a7|8NY19S8~6*@Xrv;(vx~E5`6PK$ICeVp!lLr5rN4 z>R^238&*57h+*X5AZ)C({(_5x!)|6_*StWC$N&CY$&&*Rrl2@J|P;CfZvC>)7b_Mc(Y;>Yr!bFAH0|Zs%{# z$AR-^5||M7IXel-zh5(YTvKg7zaQ*}`-I?XP&ZT3{>Ic5@#(7R>2|d`y_8}xV6KIT)QN=Pu1n}t;&oN1w4Z%@FNd)j0|IAI zXzuzyVja`eLZaY*1(D@2pw+t=FOu@maYytos~OAWwNhkpL(=@;2Ag=!nv*~ouG8V8 zxnNvc0nOLUXYV-<);uE$BzfEwsv#V1RtFi6sml{S=Bz;l?QdRa8_s;J0C+Vy zZTh*nHBE80w?FLfR-m@FXBreh9CdMsECrVNoHC=Xj(?#TPJ&?~)hkZW;xTvekYZ^m z&b_-7@+`NM0Y5xcK6=DVSO)Xh-z8q-!un**+{|_+9CY9K6KJaEeVft4ls^>paZcoB zWBiLfp9Q9ul6sb=oJnHOkyIhoRnS?KjK&P);A;K9p;0~mT6}Qz-&hou5l-$qR?Kh) z^S$7NNxCAPOogoVzYY&k}uodIHD`e;ih{=QZfw3}ypIF%Szx1K_p4SCYz< zXG+vIw=cm41VEp2_EpiJcO_M&c0*|77BYsaZh28l4ID%!pG&G{Q7pFglV$Zpob?T} zfZ6%RGDe0kbDl#Eku=j_ril4D963B&B&V7u?%l2@Fv)Bh3t49n|6M-dVq2x1mY67+ zAY)$NL`=U#dYRf7$;K!T>`5uw=58qoJ1N0MgWeOHUytWdN=Z@w)X6Zx+=H!Li-x56 z5%8cVJMnI0=*qO0XoJB?)TL`;7^e6N3bkcYA3%7Y&}=bf=od=n@Ji=?sEsjz;>w7( zl)w=~sHgWw@0$(=Za>`JQ%Fa0{rgQ|FxO-NaA8E`2U(orDUkQOpPfA(gA+S$FKhCb zS_CrR$Xmi>fy!Y6AW&%O4hmAGEWIWORI(r*0#URR4B{5~vF&+x^*mWv zRKa!k7@^)=jea0ictdcW2~EW4)!AO}u$=0vfRle4Mt&DDKz9@v!M%uhI@`DotZ(yM zs5A_6blWdM=#G{5)_-Ta73a5=6NQKQZ#+Jfvk~do9_3)est7CPJP@NM)tJ)NG3_~SF1N`xkA`zJ&Y92xD=3j=^%kFxf$0P|kqm7( z;0@K=PrKXWOcF>h9)jqRvM@Of64!N>3|(!a+C_L)(&_f{FpHnHdEkE{_t|Kq8(MvO zd&7iLQunqE2hWW-5j7p%08H$0zhfN>)c;ctwK^xUY1{G0ogtYxu;)HLSo7o>9A%W3 z3%XK`U0dgT!1KPxiL_rN2$^2^%^}B76+4J$S{D*RirJvUH(H%N3Uo7>VLH?J26VrF zn{eyp(W(-@V8+JY@-v({hfyumWxTcLQ?(-5Ev%%fJ-SwFqLKx?;;($U)Ny>fA_{97rOKjG6G#Z?_<6d<~)J!XUBHfN?2CmN2+U z%u^0@(qK!3VD6frD=1kpy7kqvZ8oTN2Z&2j>%%ovlM8z>x!nVe88AT7m}cfJ1Fy&y z^*^59o?QHU6cJc??7K(N+}OR-*;7k-6TMfMG2@+w9S?UO4LsnIA6A+AX8z)lH1x=C0mV+2;C)jlaH_KGHP1T@lJ7Me|C!emPhnA!vC2zI%F-0cj0oc8#6s}`7m4B#0{D3EUb9J_ zj?99nuTRjsh^(Wu=s*2ZVhz1bGy5>4ZN3n0orKAq-Y7!~)@ThL-iq|A*V6jUtb_00lvH)ZqYQLgMjHf+_y> z-{m)F!0AC`5__0K7fvLVTyB+F7OBQQducz%x467*<6pqFjV0W4+Ffoxwz&L!&fsE^ zq5>H~2+S3g(%tWF7~P-rrX&DM%Q55Pw|glObmBJ`MduW%OAd&sx20-SWAK`~VvUK; zh;!E3Mg5;k6U)8=!)zEqgKo)|=88dO!Mi>$#t2sKh)lTw^0aKcA~CbX#SvG1_T?;) zk~*%=OI{=}SUkKp(RqAa^*RRDw)M_$0PQno{FQh|>%wh@{%5+NOd_=c_)l+Eg7ddg zwFZW1)AJvw%z57I`}CFHnCOm|DhX?NIJsN{{_0&*;M4I+^YyDNY9;G~%r|UIW-8Nz zA9%??KgyZ=D0K>)2r;6}N(;<|6>@^FrD|t%LuS^vo0Km^gPv^ZG33HGH2Y*FsqPTM$CYA>_vQ?N%9e@7zq_pWB*D1JvoiRcb-8mP-C=G@IBwVZZ@CT`_QsYzB~^W z*4=D;MAp`p15AxLYvmdmxGitM6)(xanY5}%1#4vCpcN)a&owO`#W1Vp`CZMc2HtN- z+-*oaj!8UN2A*~UuhG-~kDP{iV*Wl?n+ixBr0ZJ9Z(p_w$(JuEU*pQdiu-5KV(FD_ z?d!JzdW_3OXi(^-pRmEmnY9cmm>(qk>;(qBUPWbaC@q$vyk)#|{=tNliOB>kniq^# z3YBOccfyr$Rq~}r=Vp`yL+KSWbEUx0_^_@xL%lEV@NO z=y4)-jtUV{Mz2N1+_@t!-gd5j}Q#wut$ zhS8xAnMf}WpWC^>2f#)6D5D-}aplsmWS6CEFqh5WgA+vZdS_&v)R7;U{PgyAcXs!e zZ8oY_QBmz^ZTC6boRkBGrtc32nM)HSgn+_y_jthNmSu;}?aB0SBbr^4re+_HSNqzG zEN@hz?YKTgBWv^Gs-9iRl2`xc&>pUEa#EvR5notdeN$0K8^kZ}J^5tcW0fBf)=rsMkV*xQj#Jm6}w-$=~Iukm-i z|A4_-hL#coISVUnK=hRs$sY!p*u$Zr*_pj&!hZx(5>yC8^y-5`|)Ltcqkevmm=rK{6w?4ET$r5?_7BE z>9jVML2tiTG5MY^7ZqmM9GMj`Yk*4-CSEO*Vlj1FVX1{;$ z=H$e+D&i)4eN+MfyOHkHd{Crzv}SnE)NurH5Oy!yJI!b!2OnPgfqfM`gqtRzv-eD) z3xPCEK@KRB*qEg*+0kMkMDg0=7yc=fXi~cM3-e;-pmrk&LHps?!N}CXe+tCGylKO* zvU&)D(H)om0KyQiMOVk|Ao^zeu6NA%r!VhHht|<6vW-lSJTyNYt)lYpOvNBfS!>7K z29(V~C5={5PF>}$cJ@RVSs^+iRSGCpd%9mA4h~{>+|Q~$?big{(mfp~1e|)(J?&HE zKi-Cv8U+|~R%RQxH{s(}D)vAf)pPXK20L&Pz|8cL z)>J?|`c-GFDA#A$G=5W`{9E!EL!3fcjbCSy^k(QNOuQ~4wy^LCA{!~oPHUH}97shc z5jEzJ628ip>0NSN*!x`^f`Zreky&aQz~`jXO9DKiFH@hjb_WMquNGEB99NMq$HzHq z(%lz5hGmu;>~*q2LcSqw+Vr`$_4*^QJ^!u%miDBbisEWLH9h09UigxS`Ug;=OY=93 z`abH4DrmB8;+FB60#2^YCoYCp5hzLoLS}*J981#pdmou*Y@}6XTYK|ucE`+^ApZLK73`RN7kEBKiJussPRJGC(=SvLy=it zm)Lld7H7)F`SRr4$nzs}>R^+@C{Sg%A`HA&QEyh2xVvYTxYQS-M(F%vtP<*Rbn)TurzN&JEY zs3JGV)(kHJ4;>vHR2t{q%f9Mk6P)M)tJhJ`FR3A)XFCgi>Zr9F?|D0m`Q$x3jGfXd z4Qvar{0Rr&h_0Rf+MpAo3@=-V*;u?{jjf~^D;E9iTgi!K8b10i-tV8=4~E5Y?DTUc zt~Zu;EoKARb<^orZ29;`H!onFi^a!|eC?)kE}vH28zYP&K`0?3GL)|5P*m6r1NlQ_ zCGX8tTwf|X2Z`a^>a+?3*Ie#((Ih1Z{M?%;biB6=Ck`4`E2FL)GdX7EA(-_a`9_hA zpXJlPHi4BJ%ak^O^7%GB&yMQ_J&A?ImTY9P^E-Gsi7OpC2~~xRH47S=RhVwb6s@P6 zk6mH(LGKOHr`AQ++MX+XYgWsk3Ce8S0Hr1;B8kDyMvx_?GRb&N>tL8$Q>?uH4ox;? zdTpOzExE4vwWkpxy?qr2nm0zoS--aJb8u_i<`rB6`$EoUigi z2eHn5KdO(zz7LH6|5h+b1`VO@Mu2x~fz*|_-9PWR%g*;ZiRm!X&%3ZENUQ`tfO1si zkhy~^fBtq=J(z69%{B6--26_^PjA-JtU+bBAGC;vCT2B0hoU2ay9^ncl*8hzi*ta# zzlX63f5cKC1MUmB ztI!e~q#H~xi|Itps;mnpj@oR8{wgz<;(ylq8u95Je-E%xLH|UJg$m*^WBdn#!Z7gs{m&vVf*-Nle8i@5)=y8xsbe@h!~ltJZjZ@TOD|o|9JMN z)TpOq{)W-fo~@x`jh&%CKj?!i`E0wx=C1$#M}LL*;ZIedSml~v+`3#VbZV>|uVtL^6t34c3oidqQUJA6;5 zH5$I1Taaoz!#rGg2G+ABLkClv#-Uh-Xc-=w)p)NkIUEQQDA`{W0CTilTpx-nbnxF* z@3_=1+3{=XjO~bIMwrMwdjWQ_*opZ?p_iAkumFC8J}vNu(MTuCFqD|{O~5MOzuAGF z^V#>oaYnxPI|(#ehadX{+C@&n+O1oI8JxbKaoV3XV8~I@X8g&06Z^wk_0jk7)yYW} zh01YL!bifjmOjUoi>=qb-Z%!Z@(*fBm^{XxsiPa|(I93@vGc;_In^z)dOUebz~62w z=R(Oi^z}v=b;Mhi520)_D(WVteRoNxrU#bQOQ*Ac+^*J6P(!)@5e<(Bh# zXLS|Vz7l()l&OJ8q4)0z=n-+qAtJUAGeJ@=ohrrmzNV?!@2hJ}k-CQZZkHDB?rlF> z4c~kO!*t%5{Yik*FffpO4Ua^z(68l~n=`!&VWF4gV3HT7iVDJRdyV!dM^NV3vxWy0 zfnfT4z1GAtp@(iiqOc=29R9S*BX9#Ciwnz zR8*kFYTNxwp9Y)k%d=ZQZ+C6MW>4S%`Lkjto_VC?dF`3t@ZYP|Hut;7BfaZ*=JQiK zM~~w;z~z2gZmC(me4QZQ*_jzvYfrb|yw|KE)gmOf{hR-w;^6$?0J*hq(_m<0TIngf zrmC*H6A5((d%R<*wBJP;{HM9|0TL-+NyZk2hp@ulj3)V-CPS>QQjlZ3_f`@!R%!8g zioQQiw+J<)i{Q2Cl`Xn1V`ayZE#leb)eY(Us*TY&+Y|jsq2IMA>XWhd0H$P+cF`<@ zF+TA4$WJFdTOW*aT5FOvG0*Jl_fruCvUH81X{H8^uTg@hN1{+elqE6)q@jvdEf zIL8%Fd0MFyDX{v~bsEw%;AIc+OIQ_zScv`PAc#Cq@(Ep$oqGQ96mxtWoM1MxD6e}| z01kD_yU*O#gNnL%l0#@NW5x2eGNHh7UEodNQ$JFU(Er(V>FDg%)|R)Ta)-{_w|P}H zs(`7gt1l|#f4fDIAK-Mm88cCtX33mg5wkTvIQY?Mb9DXD*xlB%SZeVN&Fk~)TtPAo-d-VaI)Y+I~f|8DAF?*PX zZh0-kKZb{VSH)14>PWZF!@FuiF_4}qyfDWVAH36p59FeHxl4JoM=#XUWHVhAe|}rc zK{lX#_lOgC>(^=aYhX6#H2pFEjGr^Lw?Av+Zhyw~$R7Lg=c~ojxZ}rd@@vE?jlh!u zxX_VioN!I10LPh?f%(aAG4SvQw2D*Tx=SReZfNjUj^jZok%+7(hu{5Z*oHSVPF9nF z+_bs1xxLvC-u^)s!xRVF7fbJ6qD>W3oWX)YKHGDL*I?j?8otEJ%yIDyc-$Q3lnA)r zL=GQle$b&o)KAHpe`dhK$qZ@0OU%%UX6-M=6*YILdC6=PHac4-iDQ4*JX-Fs&)**! zxuPRww@7ryuyw4<{y~aM(j0ae$yZ42)Rv)t6ZkHm`v&c0YC(Zhrt5YO&ev2fM#PHS z_kp^A0R`>oSZ!8?yK1l$OQLZQ2B(Rr^~>@oobyB>;(TiwEew!k)UM^rVsnV(=fkAn zH_UQPJ59$Q@A_@(OqoQi{Qtavub4HA;i~w}K5NUQ79aps%=-M)=SZvAvS~B4=g+Qo zG*yvWkB44>ah{4CPzAQ8Rzg^7YN^}*{;gdd72W)G<9%DME|eQLT=!jtrXsgV{;(}` zv{Xdoe9-KJ7C?EgDlflSp~xe1_n-58QwrCJtc@wqbJQO0bzkHYvP8J?QK!!SzWep_ z*C*BD46s7T45bjE8;aJ{A&rfBPXs{}kya4AoA|7~lb=mc|0O2F2ieZ7B@OE}HzaVy`6(SktJ$~e%e`L zEQJEQJumUwm&5swv#PHGufhfo z#%%Y$-Pw+Z9Uf0kAIf|h%ID&m>UogJC|4B`%SzA23v9W&{w7DDUy}cLksc%C>(}b) z=k~p$$rrdYz|0~y=B>C_Pq!`xQ!4VG*3X$$7ftMBTh0f^#+H3+j{d$vpRZO`rZG`8 zm}{_4Ct*jRl@UUDFj#l0n6}#u4f237;X0kXjsRO;5B(YegVhLe2n!+=S$$Hpd=p<= zQr%MhT;8fmWuz>XU5r#*#Hg{L#r=A$W%cPD-?DS>ZWoQC-?6WR-@(x_a6&9g_&Hra z-ks0eSNY@k`M23+P4GYXAb$!~v=BHV_O*vWz6NjKrvrz#eimu+b7@NF z1{=MMva!EMqpy@V0=>DMr}f^yT14E=p2j%_OnX@)DLO+%1BP?&yZeF|o{55AZeUUP zR*bNu6qNNz9b10QZF>;!IUjy6$vtKXe$7G<-D6^1L?Wl&Ki@!9r=|wj_-QV@K>0-NMgZCKk9Z~nQ1j0yScc|bTk?-b>-Bp1 zG`sX3v`D^^@7g~4LY7si9B?m(7l^2y$rzo)SV;(*KTU?%kGqjSN*!Tr&?*J4nnLD~zIG#}!2PZk* z1XDXyHme81wUeG|j0NF>ka82VQJZ{_Ww(dl+r~+mK=`R~-zmW2)!6C7l3gbOu-)wL zb9*vMF&H;ISvI2*2hOBihRY%|LJVgATr@#-k=7bEI79uu*9tCgRJGq66IFYBOR2f| zed=cH2!MhWwOs$DTlpy=(fq#8+Vq)|=-S2?Z=SUY2oYZ z8d?ur06A^ryL575kK8PnO?TetVu*Bj?aGco&R6N9G< zM~Q{`%=huZ&D+$7PI_X{VCG^NUba`62yv#0tgAov|*+%mPLd zJ}QBu6q$5?{7ea-tio|i2NHd|`aZ!?`qe6TyZtI>_0R6Yw=rGE9(FbJPT;LkE*a)7GyDc_BsCkpHo_>zgVJt*NDQII-p888)#vM_Ew)vl=PMs>UWQ{~2#_EF^ zPaT4o2q#zu4}%Kkk8O=dx=YS*H_1@GhRudG=Wx;>> zAea762)vx%n?_DE?^vp;0@~6wbwvzojr9lwrR$K3P!B8ivu)8It7ouI&7qO64N3$S zAk#tJ6se&o1w4QqJdLt08l*Po@UHMTj`@`q#u$tG%2!Ozif%qZIYrILp$>m3XdC>+ z`CF&$nJjx)&TC^?6*lHn9X6RaU(^rdxWgNs*^?(O)EE5KpgA|u0+7a1wrjhecSf65 zFIJ9^=~^Gh?#_!^7Sj7DH87=Z)^8+XaI@u?Ee_7;>vM%K&fM-!2~d>uFXf{DPYv8i`IKO&-kwPdQK0%R2RCHd3?uYjvYq3<*)%&nsUX$Z zJ~SL}BF?V@ZwkK2XvXk*LUCanY* z_2vww8=1$)+Wr1HHRvXk4|e_e^Z3~1#$T(FZvLm0)R}%~$&Fh}x1Z=voZcD+m#vKH zEj(z>m?CH-s*$bdKP7tN!hmr9^ z=arFHq{!7OW5(}a!H#-eO^jZgajQTy$=y$ncKzV^zPrD|mni?ANKKDKfS-TUFLd(R z|8aDl(Qv(Q7alcQqBBIa2nNCEgNW!RNQ_RDpI#$+9ldu!5F-*b!4PGLHY9qR1VQxZ zVf5a;=l`zdtF^4XuYI~iv42HT2*3)Og?URzUlPu&Ha{^Mzx{`X!!^=JK6^jn|c8XBZfzX zrqvV7>kbv&kGe|DK1fZzct7q`hh4%}PadzX+Sh!x(L&ME;I)~R1fD<5g^Q?I8bljr zT92xwlXiauGth9abU~ishGs}*g!s&(a#>WgOuR2%9?|EL*SJ3v|F}ol@QWbo;%h#6 zJ)=#^=$)+C9cz_hjk&1wI)4_b2!|vol>f{x3R;42(TDbN8np4{35h>;c6OfnFaI6( zd);<^a`ms_!B6gK1{V&e;`3iy$rpka$z%zpwwu>tK`{BUx-!9z!3qd90Or?}w zbSxiVK%hNc$hf5x@i4@6LIfuwh3f=4iTSk4S<3cM{lD6EbleWj+ee5v6T{x`!eUf~ zoSqO#{%F)Qeo5jED1F4pXEO3B$59EPGL1CEPnc3lTAk9bDARY2lJe3j-0qK@=@S$w z6j4fLStAtT>2;h`a{6h7k0dD2kK8fhRu5R8fAp~;v>W+DCBd2;ogWHtj_1FJEF7z= z_wHWronF~aejAl}@mZ#BC7_|tD(*eBPGSUXwKe<{q%41zJdDwC>$U4{TbBVcA&9TsoX=!xH-)Md(E{LwgjK=Fg>RMVVF#Yj12?_c- z%GGZ+?h8jVb<(BqpN43W6QDl7E)%NI#KDe`I+~_2tVPK_GrUSd7+6ovV^wpM>6M}A zK4$-^Xil1Z=Op`r$B`w+Lc^{*xSeQd4{h`3c%tk&^Vv!CFaQXu~T-;fML z4n))3aeZ(!l?B?RpE*81|5}o@1f`rXqy;DV^jknw5eMs{(W~rv$TLJ7^;K@F#pliL z@FWnbOx|5+zg`Otbo~9zQ*I(D>2W*->3zc0%J`SMQflebcx zO1cF*#B1r3MHq`}YQW!Yjc@z>mghg` zK4QQa_RN5wc693fR-*pd#^V0A-~3$D_4LYLUueF=>a;>5a+!s4QSvzU&6o$!2R~u_xQz)=4e|EKfRLM2BTMAPltXHPg6tER zc{LOMSS;#uy)X97{6l{7E87tEe;Z2hcpG?ObEX~~)<2~VJPd{vrBgyx!cDu5Gw#bU zb{0a_V%w61o{W_!xNhEP0$B-d>I4t@6C1`ds@!C*-O5qo4rk-AXv%(=z3qlQZj{}S zKAkZ6ZIhx4)yPYER{)Chu8(HpzjOy%Lt@h|0S0iiS~#}^EBeuHz0W^No+2>BUh8A# zam(eMjD7Dqr%j)>#zwQ`1njQw>FG}Uv2d1`rWaL!Y}EZ1RykRoo3GQNKF*_?)Po_4 zTxGgSlG3T)g%&^FFV;v$fWnp>UE{&SfyaXdw_A0Vp=34p1D*?{uNA7eFe;&RDk3}c zXBvG|-G_JQ=j3E^-jNupD*fHhnGab%X+Liay}-3pzu;Z<4A}oS(wUejj)OeHew%(} z?zY+7{;HBWalCu=VAFX{>OYLDj*jpL`C#9`z#3EcFby+CYx(wX7DCdHhiPrED%lmV zo_31^{ob`@KHXNDFvS6wnAqFRi>lX~4Q}G1PI~Sabz^m@Pp?)jZ&yRlww9@xv)8}O zWMeL0fWPF##r}Hg|nsg_TW+PPt-%i1TW7wj{&$yWa!0<(^PkZx~7v=Z->+Q zYw3!Sp>t^3c#rsU;Mft;wWWSOD(3)qgKN9=+gS*Gn}o$wU}hA4S)&LAc$_J|3ePlX$8`0Hkz4kZJBM?( zZ9-sO=PhJ0rhtHdqoCl6iN$qS5S?d1@QJG3P zllj9X113+IvzfKWVtXJWX#?=QjHP19V}(kc(IKc@KFZ;r=$QvtnabL+^d&P4GZ zP9VZjQnsQQTUB0InNThS6l-v5esL+GvYS)pXb2&u2dU^Qvg!(Wr;*;>4%bSw!XU^X_Cr?3FT1TISNn*qk`E>XxIvnU zdmUy3h7=gyN83*uBJNQ{IT6HdQPIK)^O6ZvE8qA#+D38tVbFI7v^kyWDZV?`tFc5z z8+{Z7H9$r1!uI~#$&;|sip0UyW?u_~41tH)8U3!izmiYIoI9Q&ZRJv9gZy)pq*XU% zhJJ4!F82G@eV^}_XC{(36Avpqx(ia_S$GB_ReNi3XzV`0adox(^m;EFjQ{b8mp%1& zutGUJ6_xbkJXnH-Ij99FN&0sBcOGrl8&s$1#Lvd@^R~a>>ZWD4wHp?4eD1&zvNyt9 z@T5ZeKR>^S&p`Vsws}X|rxp8Jq}p)3%qS7hD0*z3#O14PTHTEDuW^(zr|ug7yUgyR zXNvZ>0&C7U7fq;(wGA@8+ys{e&}|4=<;?gIpX>2eRdaVlQrftY<&*QJu@|=|e4)qE zPtPlWn;WA>y?`Igvic$;@mReeKlEaCeA&Tga@k)2d;NF*>hD+75MR(`h}goB(_GB? z)!xpvv_;VM1I27(0s+nkUZko>GPg;~R~A0VQ2fOH$jJQS_Ya35m{*h9V?b5dF|@nz z&4kkk=^{!w$!9K&+nxtuD!36U7}fzMisO!h3F!_I@_NF#1D)&N4L#r<*RC^u1vD7e znV7uevPYwTw-cphUb#-T{HF;{`T)c=Zn>?N7H%&?Z#OS*VK#%wXVW&9=g-aBWw84h zyD}HmsqTL|C&N1@=g;z!@3$M=>()R;hqXhgXz9jKAjr134N4n)Ne}IY$iSsRkl0=A0KHBr>iR2hqt^xC?#e zNr)Bi07bg4?gg8r@e@<&ZeXX_ODL2-(2Tx}kw(3Y=wkCq848%u*AifkriHyiwx)v| zI44Mv{&hU3->0zHEeJC(A!MA zz8@T1J>Osym)Wg<2lAH!?vzEI5^z|RvTHSGoGS0MVd+e}25*i5^pKCUoF`F@gdc!YLfIJY*Q zUo0&n1&O(Ex+hJVK4jr3V<0F^199@DKh&M?G`XluO9fQxj|W+>>!W z6jX4zbFiiL<>0FV-`u)JKI8L&Rj|V zdq~=1M|=-BjcL>*4pLf~Owv>8B=(ib!vw1RHY9pmpDzhIf$z?!R@jkpcrP0vT96xb zdXMJY?)yw@y~eUK<`*C2<&Xe!X=!U?ECa~gA7+T#hTOI_`uh1PTW##@V`bk zhI$8IUDyVG^cnGicClF}pf12bCc1XM(k7*6BeJt?F7iRl?1|fq&nTBM#I99v@JEmc z+7A5kenzf{aFxQhrKZRUrpjnul z`Q7CW89TV$PF$A`IkU1gsO0% z=ZEc~M`wfGYpnXL+7uF%R1e{Jl0Fv1K$`M&rD66@!|WG53T9ivFA5~_IGQX~Se`ae zeb(9tD@hy#NUcxJgz=G)PP$+taG&vH{?V$k8ZjJ7PwS*_3RUWBN@bz39suGZwYbrS z-Sj^;_N0r3bnv3Sq>c_wb50BSMCp!5u6z4IQIGTK8!8R$`*KaZuP|u@G-P0zyNAiK z^tmP)#U@TitKPR0^Z9o&+LZNhiTl{cyjZZAC3sx}VxJ6opa2-#QNnPHRF{!0amjBZ@k-N+y5(YMnz$lBwl{o>X<4rqSn zZBEU?zS^Jh)22cA3G^j3I~)6hcLpRXKyi^v*h|Q!o|V1Jb#RDiE)MMhB8y{zJTg?% zd-25yW^-+R`i3d680?F5@-Q%BAQ69Yv~h6d`k&-% zdyxO_e15r5==EZCwXn!!1+O}e#k#;|NDbfCHkIGf=uihEbSz;gch>J#@UY)S8ZZ_9 zv`bQphOMLOxHH5njfPiOHxoq)P^j4MatopNtF=29#>wiJu`L<_0Z1PY-w+QEu8hUS zZ0g%J_nQ-UfTvoG1%w2j6dJS|=pOBRP#)=~0E-Ghnp)}JsPYGVMS8S{7BsSMR`1Acc`MjUI0b( zF{cTyG^5t{H{WN1wdf^nWbqd8Hm@m&k!6|OwN=z5W?W7p+iPtb7HzN1l!wb0?>qp3 z`lulBbu~}wh|n40k$bR3-rN_XauM_zCj5IHL0PXYKQo4px>B7xxB7|7wMtGs8SS=} zc=8MTdz#;-5@ULw$9WUj*Z=kz?wbJf3=P5R#ALHf#lpZ$ugfxg343~C){@vq^WVWeo$kFmG&1kBpAwp;fcufEVJFaI`={!nm ziu_iEKVfUABwbZqQ=6m)U|HQP>%zp`WDe_NGJ*1|xnR5|Skd*xsa{J$*XEM66d5$` zLa48lv2pyIU1=C4hs+5I6K56GP$kZfip0F2A6H6~FTo8AR9ts)v}B3|^x?Yy$S^!I z5>7>8;(X*$cgK{S#7OhU;Ce$-f#%vhSXMiIw>Y1%$JI=qQq8rvy35MSX#eiCT^`OY z_h0?_1}~(vyhBf90sbdX#DedJ8WRw+QNUwMZ3@G%7S%w#kL)@dtsNKaxu3ZQ7^LDA znTsDj7)uTDIQZwaH1F~&XLnXkfT9y3ohRi@n;Txk?`^>1o+T~8-ejhJX+8tA9`3EI zxYjva_w{Vfzc~QP^>mBUOJxta=r0Ss z1!6Tl_44H;Y<-mHW(m%aV*~R*vVj35a%iE_r^8VL27x$sl6F#}i>h|j$ z7XVw_7;2lSi?dCdoaV*(%(zP7fg;QdKs zdcqItLyJ;YQBHnzr5Dw22{)bA#>S@~w8;96A421^w`9C9CF`v4ej}@n@l*p3O9=)gfQ3}?{`ABb{0x3gjb`cT8 z$V9qwIq3VU@x$54IiY;^Vm!9V&pZ-I$K60f13V=LFo@qh-XQe`)QqRvGz5(?guCd+ zh55`0y-O^0BdggXf#_Bft)u8LdMfB-ZYsb`*`~+>U+NK3kvMO z*7!54Hs9EkD==3U{Nx*R(#?b&2DX_9Pr`~ON-KMc_KPdk%|LpWsRJdi@P5Yh^>d~z7^x*67?blRESAG$fGq^wBW!G za7FT5rD0-X#_GA|EAu9{$2?_y_XY2cGZN6!6Qm1`4wxb%saFcAj8uj1f3$t;X-Ta!2lgjFLZ}-$2cd?7*4-l_i zx@rGrWhwGbKR3Kt8_Tx1_eZ%_5%s^OSSMEW@n?Ybr<7@6I><%}(uur%&vJoXsI1}$ zIl*W2T6WoIT{h3Veo#;_du(JrCaukvuf(|Mze0V|tA1y!{|~|Xxi`uN@Ga1A6M`K| z#{j&emDK%Rj;)>DU0~P3`FFM3VBwBpmRN7vWvL%7rKf1b(H5OGT0At1L5@jve0?Q_ zOfrw-E2~%)c#ea{7*FQa9hO;!?DtPiZ4?2?#jC%O)Bxe}@F!r*Edun@5R?)%)iezk zkxE!n)Wny$Hefk%dzN@Rd3$+#`1AJYXX)W}(5Yo8e(n@tA>HY1+)d&0DtVl~O6+$3 zeJM4Ulw0GJ>qK5)ld;Cr%zp1+K!H3DR&Qp~u=Fpw%jNXAwovvF7n&OTd`+mZWTF|o z1eg=Y%3f3e0h?iTo%B&0bF~c)g~(iSBm0DJ$wACWQS`HBz+7ySpi7s1$TY8aGtVH8 ziDyv->$7({Aee2H2~(SG%21DvBI#xO_ikmgx1{v9cY7-Ch@LTtbR=ZYU*+4HMH!qZ zEk0)#R`~J8kfkA;gw{(3KH@Jw0k4+AcQ2W0y&$6nX{5`X4_Tol)t}$ zu2KYwjH=-p8U2oaev>9M_1o4puV<|CCE>@&S3-C^o=GgJS5-Hl|DaT;P~BvQ%!ZN3 z8;OfZjY*+4W4@?wq6O>^xxk)__L%+5Md4CJ_|MryKASfsZXuCa}%dag@0#fPT zZj-KnO>gSdL;eHs!~sbz-mx!-RjfvUtSOdv@#8+wN6^DcngU~ScwePjykUE~_xEJ} z=05`iJ4vyL#4^Ct^$D-qqffiaaEZlV{yIkfyByMr!kq&x&Qjx!t){}b55Yd?N4lZN zMVUatvaE3mSQ$eueW8R#QK4whzh{Ef5RH{*-Iy5!@HrSDCvoe?9JltHQ;5KComvj;UP&X{37&+ zNw<%-bDwI=+vUO%nlb~qN5*p#86_R}xx8FgQmGhBpFRrUGGsgc^fFlEsN#@YUak{H z4rQqd)y&K^aw+?pwUlnm$}3&P-@&z{i9fXXR&8IgmV_O;$_lsYC6s1(m^Amhwzjte zi{2t2%Q4pPFPr(t{yi@Pa4MA z!QtX$ruufO;C7?ny1PB_a_%(Ib0yegcRsS;d*T$@&1UVq>5DOb%v{m1-P}-(FU4P= zoCE!Gd z&KR*Cb`B2hQau;fINfjeI-`|URDkbxrdLni2Mc&K;8MZKaXDehc;omT3==M@=w&Y^ zOM9$V(&FMOF(TP9A>uiIN@=^DL)>B)ByOa0&K{%yCVSXB|JCEkhO6msQ-7uN3F6V6 zl%d4Nn|M%hMxvG;X9P{4ia>(WeIReS>daE;_@Im?5F}y9y>05^mZS@ZQ^d4}6&q>x znRj%+qN|*whV7LVdl;q-rc*SsavwP4(I1-^hzr`Kc~Kziuvqz^dQ*8oy~;S`OZA*A zRcOfT_zM&ox{B?zV4YgP)^if(3)yzi^70=+YGjZqY3;Ena4mF&q6j@|=-u*&E=AEX zUp0cEZuXN*+V2>`U*W5qCIyRB0|HTTZ-~}bmE6Ra{5zAg-D2sK!{le3JI@)*TZIgv zH4KSsTtfsXaS&;YK|xhsnt?9vWc`kxF{7es)P3=lA(*l?4o(kAfOu+A2_Z{k)s`m` z%=hL^io7<{AL{z*0ND$F;KdI9+FmCURbF zU3Esuy>Yf}r*^t2YDN8hFm+Stn@K-yqh5wADVC2ygLCJL`-{L~K6&{AR*gxYE-0NZ zrm{-x_?Y_3YB`%cP6tq*P=|%r(n%34oV_rTj5nMOSWcVCr_OqCzPb(UDgxW zM+%5I0bvKqYX~YT>X>MnF)^BG6jl22zJ$_GZ;2Vm$-T0=Hgmm9^Cj(>NA{```8bQv z!(`wa9UG*6r-6TWwgu3UQVmExr^k80p?0{T071BO?{FWDip`8C&Ryuuel z*%BT&sj@Btr}7))mXJ=6Lqj7`l9-_mR3sf9ADjH=B&pspi+& ziN~Hb)2`EOdT@w?4ob|+!~hon>K!uYP{J)i!xe+STjav(^uGg|B#3cmOK11#x67Lr z_uH}13%=0(>YJ;}h0B}y9bwMjdDA9kjE}3T3!VgwV%#Wd+-JIvmo6@vUF5?n0pT1dRPdsnE&s5Hh{0+GNIad7{8 zRO|8a#_5CQP_*VZv{d0_Ka2J5ABrHjT$5heXH6-1BGc-s;381^ZmY$m0K zdA*Sdxh4d%oIn4uxZ3x+hQ)*8`T{Hijf_cZ%*>z21pri*jiOn%o_Q|48Dehfe66x& zsKe{`CkNL1TT`kt^@r!b15%?jKB5oi(+Ig0NlgDUX)b&-od#knA&*fbCF)f4|Bd3Z z(}~x6_lsz@n4NDddt3x5^}-L8e5wL3Y3xk|N)wMwRPJJVLDv>+OPi3@Ags z{EqidH*%9{vv_33Cl}l6$6;HqwRz4Ad%j#!cmV$b_|_U8i@FqH3=h^d-Y0@=*RXDS zn{Cpni))7)X71SY>BvjJ*K@hMTPbDY>w=biNK+)whiFFb84ZS;pk z-)oiDeGv)P^>PXsLUE$6A}`~hmjqA zwOwJ0EeybQfYrh5(p0z%)0^x|2AEu&eU#U0cBxqE%+CtyFSu>#{;Ox>O zCd_>2NzuW&nk4XCFQrnD3PNZlS>Kv%!9D=CyL+zmfZcG}=@a_3a{H|7G}dTZtmt%g zyXAB~@brP(_SCqwd_D*J0-rePZ&2E(VW%ix&6#E6T4c;wn)?jlLN*o2JyIIQLKRa% zVw#)OO6~(aT4*=_3o%8t1`6B<~x<5`5yf1-&h5Fgyngq=I-zD-Q`s?72TUFD+gD>{iD>%PV2}d2$5$D z*lV)8Vf#X%H1jegUJ;@cQFvr$GLQ8F6iB()*x300noK9%qQ2)p1JSevpQ{>}qyYX} z6!ap$ap8tJ^y25ulE}^0&zmjFo4wel{@dRpYXwS3=j9xd@teFSZ6l@+pW(JkU%zJs zSF(C*qA*4K{$lx@brXdouV|c!?UI#&rUb+^__=bQ)>r;{NB=m~Bl2Ra33%>f^2h75 zr){?U;Now{7R43Rm?DayBUS}J4(}lD1kpr$YZiO19ox_S#?<*z@@fo?9-4%MI-;T$ zI8Bci9_N7BFxebGnPvT-x$WT>?z^52FPA*FnA>fpeuEQS zmXrGS3^WsTJR^0}BkfK~DbO5neQXH@6E@}B9&X3mEmDg|(O}Yj6_yYnP%jvv14!mX z+{O-xg?sZ(Beb<@5Zc?R6R~;cXB0&_UNJ*yGQDZmcV{1piV7^#gI5K%;VRla0!?;F z+#s9Bgxn5^R-X00fFtE#$*J8G<|e8<)71dLPs(U=o3@w6kIUyJu%fHqk|2+n2FC-5 zGP8Jhhiwr8(Nrcb#KeU58dN4rLo70@RGj8*G5sK+dJMW6z-h>sL~&Bm{P#}5oX8)n z7)#s}>rO*R8@D=)q7x@_8a0iVgJk*sKxmpIusowBj2zHnd8mxw6-96M7>&10TIk{I z!+10q5M2Lh^`#N0@}XA!R#0I83X#TI3wnec`<*u&SZA_|LSgJofIPx1;9uJNi@RCe z?!QvZgU{56kvQG4Li|8!n#PH{l%Q%psPs?g>;q%8Hc+VN^^RusB*UWT)6YJ&yz-;5 z^DQgcDW3+O5^-_PlFXSZw-!?Ji(h46hHwmT3B#pAw^s3B;ZfBaEO>$r@1>D9SkYS$ zd;}=z+OAJ{DJvOSpA7lU26`%S_F1Ru#SpWx)P8JoBYRerHY*$!nM@0F3u7MnIQt^1 zn7EOX5-H{YiNc5Lu< zbkbb1Pj=LtMC@#ASN{N(#d_$4h(+kOmLArj3Kck{WuzF0Ll}J;v(^wfy-Frqt%{73ILe zT_TcyIt?xvQY=x^Paq~T#wXRpW%|?9yiuR4@ZMQvA`zren3VX>GPjvF5<65 z9_3Pkv>>zyEl7z(u1*#L$>E8E<8#D_=>B78&E#319rO!<`qCV&adcRZNTWN{=Ue|>zw16*J8iEm z3>_rAok`t2yEsg>xPBt~tDSsbOyq5|-{i}s$r2U|6^pzLncAyfi_i3~c!Ur~esaAHip>kuU6BMmt zd%>4sqHBoVD-P!Z)U70q^4-fnJ~@OjhO4{{*?IV})$Z}Y8mzo!w?a>*QN{7<`KtX~ zPa1)TEXM*iNMYCu zefZ8_x9MQcCuF;4IvBz7KTg7vvdn%BZ{#c{LKW@*)A z-Z=0Xk;Yf;#{H6edjF?G-CTZtWG(8hSKP19nmlc9F+-?X-VRb7p)vFs|2Ey4|!H;tTnhwY|%`g_*|$6{oI(9 z6nWO+yKN%Rcc1WEgQA@S0{>^91L)Lyn3K`3xBd-RELVy<9E^Jt*rOi7#+=dv+Bctz_@4Xt!5p^Br@`+$~WFs zoCG~Ri_E{C`8>!KK&CkQC{U5E+OtAcz{7`!2qXUihYgTfBKdfElaHv?iMEiu^DYpO_iKYWsQZCxuFfB6j({I zncxABLfyHoEFfn`3)Vw>U`nh@iHL$|vJO+1qPyHBC?ztkE~?7R(P_?m5ANuOP*Mmo zfoSfCL|cCJjDJLT#+Ua7&O*xwLEjaBm{ucI`n%yVk(rAPoG!d?2<~Eo?qE>N1;d@X zQL5aAhBVM%y4+vIt1lL=j+v!ezSFfo&Pn@uTMid z=S?G{Af=hbzyHAJ(@p-&F0I71N0`~MS=;xqu#iE@eoFx|*#84UP=Li_Yw`TN|9rLk z{2Z`z>+owk@b_eT0%7K|7=E_KRd z*J%2&&9U`hL4jXQfry>}LAb(JgrLxj2K4xKloGR^R`FLMbCUqHz6qo01~`M?BH09t~;StYhOzCOw@%4^5m< zKjrc^*PC=}OJ6g?$$=p5lBRMFC_^T(wM-JVt{kPL+&aT)6B`umGf@ZEx4|j{#hD_{ zjhIvo94pdA*M7g2aDD9$zt^<@CoCc0%t;gyH4^PXsXyicD^w5_K07JeYrHWQ>@_CbDujQ z9|Ce%d{wBo5S735?)t@~r+WtC!noCBmhS}5<(WC(l5HP$hgq6a(LhV0;t;ih{)1q2 zC5dhH{?^9-e7etEC*^DkI)U~cr^yKo$9h9iGD$j!jq7B01%5oE%z=+DJJGJqSh6sY zkShKe>)dy#pK+hTpI=|#@x#aC%}z@95lg>g8MuvIXvpKNhoGy(U~$LwzCVNb)v>XP zjEvP~KBLJ=C$YR6fERvKa6Q$2F$vIXQ_AS=KC>At_n%E{FGqGp=I1|I-UgBdUbuP2 zx(!$PT+?+8!h2PU9Sz&C8lRL*z`3O0jg&?`S5-AJEb=f&t~}=M;oN}cs+#SojYdCb z+G4QbxIoc~-nWV4?*?0gJMKW}5W=o=@?m+aialPFG@M;vrN2W_-?DhtGQAcOhqSO< zR`B~wYpzLE<>`Cr-R~&{`T{sT2Yj+0a&g-vO-nTg*im`y09;%yT&(;9rfH)ubnW{p zS46$ik@0z*-@Z_X+O_WONF%BC-ctSarH@zCm{5y&e=zd3G5eHf`Z*`g1II;-_BLR` zO`*KZ-KVP(p>Nm|@Wh&Ak6mU0lu#$1PIRolbijK354Kh|muh#H?CY9ZWkWBvMgr@$ zY#e74?0!uXTFv+jj*CTgfQrfmD&X`iHg*v47&1NFwRJ#)sYOf!OMp5`8qfp_dG+DY zmpZPf{9Rl^x`PHxHR{i?+rlZ1#VYBEr8)Y&PX$2|uRR%*1>Lhe;;I0M5RgO98mE>t z>wDpP_Qi|Rnm)&G#3Lox?Ldl(oNq5*zCQc(kl0Fxt$3GIT)emonHE#5l*`70u)R(o zx3+cbdaC%$9@T`e^Kbd6&&x;!SeTq-!&zq5lyl;banlT@H(eGuyGNCsyWR*Bl2 zXd1W%u4%*($nm3m3c3F#85M`8#TVzda6gH|L!SqaftM=<6KePDB;On3H7OM+kL|qz zJZemZ^y1W9)+@oB`f4uf#W_Ivs13svq+i6QQiFuXS|>NHvgU1`1JE7~Wj`+$H5?Qh zkvd-5+Bz(_or`^X{$lb)yO3yL5{Z3T$EczY!&?yoN5tDK5UG;VB2<(*!FVV#{GFUb z%ROq5T$Zl)8Hi%dMZ?8R8X7SILE?BT&C*O3(D$IWI=$^Jz)!XiEnG^|3|1D4S&{mW zRR1sK>T>}#XW7%1prZUaPl?*`KCrgoa{Z_l6)9$NT28IyPjUO@YQ_tW4;KTsf7PGv z&;#Z!>4o!W&}rS$zK<)f)u1N+Hs36o`nkkiFCWKcBuf7W4^dTM(ZJ?6VzeRgm5)Kn zNi}#m)r7QqXwt7}9X$)neB{+&d(g>0%D7?s01w~5T8nYF8H{!T-NW+X(l#uRL)vzp zdu3iFEc^~I20C3fXloJOTc_f(1(r*9WPV@vW#C{F+c5GYttxd}5 z)(kW#n)kVJWO;CPu38_S8>RllNl$3+&W9de?}qMD1FaqlftOE6kN3+8?D{TaFYnyB zb9s3OkZ@$Pb1ti1KxB6T1Bj_A1&tU5rU9mP!2 z@ZS?&hJ3h5s_s(WXnNu^Fbv4_iS>ZIv>-7uU!f)FtC!VswsIC0v|TuAt|*#_Opm+P zh7ml?DPB4d2)b=y69AwaJd-gjVe2tlxK;1?VQ`#3~9q7*Da?b z$Qjm%f85QnA_ToGuB^d1AsCcip$#j>1pwPr4g%Cy7@duPL)U~t3f^F1(ycR-j+cNE zCFHn|x$e7+{(AmInwEwN?hbDJ^E%5dO=78+%pCuJRw zwO@D88eGRnTT;%x+_JhaHB9LjH1u^7aF!B=@GfQ`J*zoM=Ef+Vp#%ii;X5`w`hg!2 z6zKxuv1v9Ux@>)(OXTKG10J91#pW5Zlz;GZg;P?%nFNQNlsvY_yz(|rjGM?QtToWy#R4?~hQ}KISVsrNHQ0muzWY3}o$nKyK zB>WVvi22rJDJZws0L0Gf>pP9~;?EkNYV=dKaW{@)BIwSX&eCl!>)jGj33XDtH>Vvx zPg_s^sY$%w+#k{@jTX@`E0N&8tMf_fqr6?T$(O#sxjjB=AQoqhelil>@#AI2H7cNsQCJjMHzUMZ|4k=+%iqOIZxVc%sZVuVqvl7e0xLGNJ#-o3G6TAe1 zj|N5O-}fCGT1wlkkB?TRQ(?WjLE>n(9|jB6O~2; zBbGls^NNZMMHfylji)3ElQI<~R|?CV5-fBR)vp?UKG-=d{){eyphTqsA4Cqwur_eF zF^U&T5YKtJb=&?y6iL;}5R#1Smy|ZpOTtprFfJ`3TpDHlFjHzEczH=Ccr{c^l#6n6 znC>zdJsdpN2YeSUe#HVCO)@0wpSsSh5T9Nk2QqB+-y3@Dd8bhi<)Kr@z#fKD%Jq;U z5P1w6^vQ(hbmioRKim7KsEfb+YEg}EzV~VUSs^cBA>DuGpeE?igd1ie;dNFVhr3js z2=>CW4cIO`c)-E&Nr`*2xq*7yTXz1bJpTZ~rJ`OH0ac4{J4ISf`j}PgQTa?x{BJi% z1@$5xf-4)yy2l~jz>@{5X)m$MK+totS3%8=f&bp8M>^34&?Depi1vuC9{6FFs5A$M zuvD;o{1RjzzYAHva@04>5}}a(N6zhF&l5(aVTGcA)MkSEAae>T^9i)mQrEl0d$2EVp(=^Zi26^G%p0_b%58^)Bm5mRDllDlSqDfdQLr9gm-Q zY2W`WFl5RFT#HXdZE#^>R5^69nMwmN!1BJxw%+^ z1Ujc6^%v)FLyO46$>Ox$r%myzf`~tNw;%@i)01d=DRqByfi(I&!-`+Z!<%pb8GwRC zbEW*3iI|RDb;W23pQ;JW?DI%hYVQXLpPGjxxb!*!hi7kJrW}9Q^?372+i%OeSKDva zamn>llEDC-lSC9a1JOrH&jrc){z~}r1&2lcD@^yF6#FsWj(wm4DDbqm$AF6vBL2_* zWBo)xNOdIJneVLC-6pR_tXM+gv64B+ehqB%PdQ09K}j>+(DcMF%1jf%eQucp7Xtm0Rgv ze|HneTrAz(Slz!00)0h;<}Ca*^^3dGy+}1Q6yu81!j-qIDWD{zOb1d_!{9rOI*>=9!Xa?~*FTk2ncRm|XmPt4K2-Jsqzbq%zE0(GhOf%DSuH5-Ybn)fZ5dFZM1|?RRBzEiR4g%Z&yo zJy$Z~2S43~7Dc_Tz_CY-@nfTkv?SeOIx z4n%XMfJ1(bj>~-_hn_A}>}>2G_z;jg?a)vh>R=JGT4M0J2P?rQyO~!T8aX&vhFtB7 z++37}UIJ{y3hI#f#9>|4SUqVU`z=h2D}$4&bY(rdhv?&;jto6qwY~W1OL~aXmp;Xn z^=nC$CC%3vRD_2O@4%oi&WB%hiyu1?mV9AtnrquYx2X3vQv3OqE$3GE;ABWL!#|c+ z3hF0lI(&F>wDW1^=|M|uw_~AO{4|$low)5P1_A2m%Dw!|7^cQ+RU)N*@ecs97gPpD zoqz9QGAJ0|mUAEW+l`8v2r9wkTyV8}c;&gHFZM2a6l;S6JMXZ~2YgpnwBG@`JCz&( zfR{7BG$RrilUrK@Xz9#H2-xvgIFHraLErCg;noj>s4ar<`F_Cm znELkLi<^!Ae}QkPLxb_S$fB9kzIPMaJ9D8etUpgqQ&V2gP0c+;;p|oFUkO)LRZHdh z%wXOQrhP8QNOc)Y1B2rHZ%HpHz`PnsmV;3d9O}vLNg1<@t z@i_+3mWdc^_)#RS=1%_Mv&P*;ibAdc>7m&F;BnUoxQRVY=lE zUIVbW4-sEKwE9I_MU9x^QF^#|z<;DVtTxLEGmrQlPZp-U& z7kgUe1(=x{b}y=CTqm^k=p*VTfZw%5Pjac0=&wH4Y%b0$)`()!aB@fc;f!slJgBw< zr>Z8K@Kri53=^}sg(&h6|A5-#q;bVx-B`Tos79FEByG7|ZzEd(*&md2Yc)Or($}j-ygoC*c=>Pt!FUs}U+J0cH!>G9uTm3r&>&9^2O1Ypd z@9S{SVi0-&Vyk-7vi8-8vl`RFD=m)$C5#u8W|leO3+78QR*yCTwA247=V#R#0RV+P zJAf>6(lye{^YY`?%lt7IP78@=6ji3{N(fVtF%Obrg7wodIfXLu5kLGQD^>T)An`RQ z_%DO=j5S5@3e;A{nA1*HJOgrZaezN@8IC*dsdf`^tNSHuD)7kIx6loDRNxisxwi9f z%C->|Pt+qzN1EG>v54w{;ShNkiyUq$DV;QkRo=lMkYw=mb{oAIV0ij8xqD@^>bU!I zXIq$U{HYb?ScNBL0WA?r_G|Kg6hcpLJ#^Y8WsWSM54_x5=e!N-&~euHxiu)pUANcG zWW!m2MZ8^_T3-sR>G$MMKt@u>S6pI`ED&klX~*i5)L!c3j2A0$1LM%_ht-_mf$#r8!poJEyKa^n#nl2s++yI=Qkkf}YH_sE)R1iE=Y@X^KOnW~w) zryuB~J#GfBLt0Tv1FRwAjD>%DA{AH~OjxL1+Ng3!k>ot2BTjhtG$fP_SNfy2bCR}z zpz{6p*NVPU_T4@)Tl8Z;*H1JQjPY9Zwi~&5irzd$`kjm{L=WALO!QQpf09NeK%{0e z;{u+i0h1-&o&Y1>y&Pfjxfh-Awht@9*_0N6cex;|rH|&UZxOBJ49ryOeAw-rcdL%m zRd0{ZUcfG9?m4-%^0u0_+}sX|r0BrNMpg}GLrXwy6dWOzDNwm(N~MVpZt7x^(yE9P zKidq?T00%s?X^7e+Q(1ZND(9zQ+c&1+48cHD13cnzL^|ZM@It&74da@w$7ocm2mD{ zYs{0XB8wd=0Mv!Vm(#N~e!9XQH28RFv>AC~;u7|PTR=?)2vTao^DroUox!==L&ySM z$ACd^T4RMiH)`=YdvPBfeavMAvF!kPNhLjv?bKA)@0x^D=rUYn_o>04nw zsTquaJDi%ue5kcYS+l4jyqFSlTRQD`KX|@#sE3{v5C{b*gSR$(1!cP-eOa_%sje!% z;68Om5+X$DBi>b2Qe{p_k+$a3rDC48%gtzoxK{fNYw<?SurA?kd+J;Zxl#8=A%%`W0+`Rn&#KQ)Fe$#j+c6PWt z60mmygb;Ui;@aGdS{(iz8;&R&LAjdE@5|y_vjZ6og517!5u+eqsTUsy=H;)0qarfTbfM z{u52eNz=5u!%b!HV5s#bY0q&)cU(wv$VYTB;9t+{-H*HByM8w(#z5)7sH5)1sO7pT z-=eUy<6Pg5J=>b%_p6R~R!R;EZD;_jJiMCE9>}@^1rUV6BkN&oEz-j%99-fhrv(MV zxr%*Q#M-BpXj6=QU>U)!FO+An2zv7D>bek0b@tKdciE2g zYYS_ZrJ=76#@HZ4A)Z3mgY6|I9uy9?+HJmfxRKOt{-@-YwL>Xq^Fb^|8Oy)kx=Snh zriexCrP@cNx)DB#cjq`T#DKj>`mTxXB~ychw|%L1<--<6%Cpn6OWHmiuHKt5g++m` zn#*b8hr-KiAHv2jD3{NC2HqV!3DX<8S05$oL^f?9lHR!*uxAs{3p-VaagnFI0s3V+ z3WD+Qt^aN@w#$^D!9-Ag;x9R^PBM$Gu~_rJn~nPA)4FQaxQ5$9V}~!oz!v4TiH=zM zbnN3@tcN;hX-q6UQhNY)Z?ACooa2rsEfXl{q_s$SxA}d8Db5M+yy-DMg|%1|bi&(} z7A8ejt6SSo*TD6qaVp0GpZPkVJ4s+YF(eB7C3 zYX244+qm$M92?O~PnB3?YL3nx#{d{Rx%XZ2aXB$@Ki|o&cURc6W<@Znicw zn!-p@P{eBvNKd`cF0z?gTO|H&!k2V_aTuuB^|8A3fOjgPkCct#$pdQN`DjnK?9X6#9k?6$QUl+AcB{hGsY6AbcyK0CQ4)a}W9z zRF%dfHO4*?tkG-JR z7lO;xl==LOUp^R%{@SZkArBn7ER7~hr@AAsMyR%FJ8#OKh>jjW{+YBaoVYJ<(bOi< z>b3h$Jew(qZ>1#?uC!|R3=E!dk`J9q&vBdbUcQIIe9J0lyHKb&TrI>RgK>2Jeg9}de7q{zUO-|<5JYy0TSeZ#4h?8??Nhkf z{@FEc{IT=*0*g$Y0{H+4NiF)L>+N3!0qkGh9?quAk!R%#KloZbB?5XsxQ;W)!u6up ztu6YjBRhfWTErT3b2!XhAVZ`VNJr{U|4fLGvBlSkONf;U6QJjqoXLz3nhd165{I3$ z?OssGZ?CLNKi5D~*@)=Rs3nX!y7gaD|8K;TU`-@BsIhe(II;s?)0Q8tMFcf+Gl9>l z>`8l;=A}w7YwJB+EfR~mTdJimvm8P#4|k&aBD`&ct#i%a{FSU%=wPSjZnDJ zm|oxT@|FW!+|9qZXU*51`0l~tTfFM>4<+Y&A?~DEv{gKYT90yAWusGKzjEDU06yFIJ(>A)_ z+$;woX-E77T`ghO&P{KGzdFk(_WQb^qW~%up9OmEwsRBseBuPwE!sy-^u&oJkCt|2 zme+k~h!zq*KC5q&97GRiE$yRSzWts=HV@4=6%R|Dr_w!K9FSbL6i-);wqI#EkTYwp#{pd!a)0iz zdvg*GAyp?Q1_z^$y5;ny0n`9M^!a!2K>WjTKRY{v-}|F~uD%WM^!3o$>;@$(`h-!I zO1gw!Ywd0cb2Sl?eIyE@ns++D&IRwMK$^@(a-D6Gl3mIfzAspaOSRq#kP+$AzRPD0 zo<+j>T6vW}Rd)5wCVE1cJStr-$_Pzmgv~~mrjV#oIg^YW%}K@7>!6z0y`bEb#4%io;-9?~cF@2uJ@(wghI^G25L;H)~F;cDNd>1g%$ zMwKS8QP-m3{JK^^eqy`js$~>_-*{WSYcQyHijOTGGwktB;**ue^lvL`tQTEW;lq&ke-66+te*Qv%6)Diqx8;~bRF-=z z4E{Xw4LwQQPxWN}v!m*sA%qf50yO8_d_25hyD^80ymHq!0f7$_CTrqW>5ebbxC4%v z>X@jQia1Rki;6d=K&=0|O*W+*sk|^epe8#-C)fow^}R>=Y$JM3<9AsNg=EOAtpmj$ zcQ|$z^pK|`LU(=m-f{ql_tQRuvujQuNtctTIl+{Y>F%7)=eEOY6V-x`7c-~Zy~4R+ zi_cUYpHf1DhU3E-ID9+=enw!Bi(W?f0(Bs5~0eyTkYRvQVNGGN}4ZZnuvd$RdT$YW9H z>n>8AHXn#GSG=o8ppwRYgIQS|E z$Dx%|z?hXiA1u;Kf8JV(_pEMsg=qMAe!A43G+zGf`g}LwIy(DuShwx^2SQ9qH?=YD zxx#_+Hu~s;Wr>yn6X+o??3Xg7FgW)e16ZoDB(fy0Vgmpu+smvalgmAzj_d0~2B`dS zx>u&>@P@2}eYqcENe?UT88>fz{X%&#UhykjF9yx&kweji*6$a;gJCPJ{8vPmX>VDS zP^;e1@w+2&4B@s|&^ic{`HN~%>UrUWL53t)q(YgfJ!y$iOG_)Fe&_GpE75*rMvZ5q ze|#m*{{X#_BrmEG%lOLKW7Fu$ z3R0Xg`30`ib+hY-Yw;f$IaACR9TE3cDAB7lFV#oy4QqW|2HzFj@3R-VHXJAP+N84>SmN{6H{j|$)Q#YW4t(W{6 zkFfoqArtg%xipSZa?}K(+IPKw6BHCl67+$b zc!y@_nbzD*vCHwg#8!qEPI8WC`t05fV%94+OyYGK2zGJz_p4^*j>06hKlU$Jd!gt4 z!suX(d8sQ-2lq8%1yX1RC;@eukV0q}GDvWxsgYgkSb z@7VNmqt;+E&rIFi|UgrWFl`s+RI`2|eU!PjucD;5!j2|98650B~VnOj1h0dSc+e?aj z7I2zt!*H_#fYXLIENbp8c~**i&$Paq8yNp5ZAoC8JX%qjIDy(6h?K6{x2MQNu&QWl zAK53!Y&GsUw`3NWmU>K8!8c|3#J!WVlh90Kw?_G=`eP|r*E*CNH^ViQqzFIE7 zq!p0m((CE_F7nC0rS;>%=K0Yeo-k+!Wm1WvB2wYj*7n_{q^f3OmVRDw68pq+0Qb{= zNWeWUZHjpkf|QMs%m^L@2}UCMq@|>*aDr;{b9omubFc6v$3zSoJRIEXfJ;^FzeI0-9#A!?xcHmOpQ zOZE$qX~q|`lExK?YQ+vEl?j(MGIJ3M?6FpmiMYFE=e;^K~y-O>QVrW$~FcD)%69z7kF-bTX3X30|jLjqq zyx4y4&cCo=uLr~p?cT0)Jv8elroAf-iHztd`)_~S(mK757NHjlyhHT~ z;$j?dwaRm?*Ws*9YoW|F?$cDt8Q|&~tLU;|?00ljOvuESF?h~Hsw=!Kov5KQb^cnv z=oagWlN3fIE>ABc&f7KoFP4EU+{W!i-|KevxX-|KY~wbKhB22;VHZxPmYkO0H>t|x zBHRSaGfOLgsani!d(M~XMuj#O5eke-V^ao`PaZJ^Ns2?-hBX^R65Y3mOA0&~#Sc5%tR=1`aJJ10FT{ zvrwiY zO5*@>I9Hxc+nz?TGthgC2pSV_tCdIns-`7UT}Aed^A+=s>E1JSpe1bai(SsawB?C; zZoB1<1PV;~P+LFh$Rg{yKAo+t@eQV$$d%C+HZN{Vv9Vj{L~z= zC#_|-21H`rMRgJrzl0*W&J2^Nk4BKk7MM3Unq~S1***XKs5|dta>Wuj(#-JO(Io z7iS}FK&S2L)`RQ+GyolZ;p3i_mpfo(x~<2@rI#Y8{V0b>An^XLKsg~$L`U9ySuJlu zjpnx{3b3D4Af0r3$P_Q`E?9EMV_8bFLW<~L>};sh<0;_@ZllSxqCd;kYfF23X9w)9 z$KXx~FyRi5G5?5Jm`|T&B-d&%J32e=`9Vf4oX~I1<*G& zjcfbW?9)mQQ6=PIfPbHWvq6{E>&?v_XW`JT;?2K@dB$8ZPUzyy?$M+|2EZaDapn-P z>~dWjux)aa)pk4`aQ?dOqBHwCnT8?YroZ|@YOl@KCNafI)i1~a1c@)p@Pxj0~LKlRn!a1X{j8O1B!@j|gJ1(V%ZvE+7Zq{(98!Yf=SczZ{ojG#)YZ%qg8#q$3 ztKzZbg6o*IM)1#3zB6P7y>-gzy1k2a4k9dAmR^jVcynk)a_z7X;LAW zs+@GclE0$Q@B2Dh*Q)-ONVQt}x8=yFgP&hfboD-;fWx_XF)FT+OkMYQc4&t1k4dUNH0se88~ z1f9t-5=EFqcVZ$*0olx>Frot2w1QDyxFSVvpDgB)=UQTI?7d2bqD<>mtYDAzBM7ma zX&M1OD|(-b4KM<2z{hmGkt8pEkm}8t+^P4L74Nj0EXMFBfWLPkCgy%gZoV z%{!kv^Q%3TWLlft&)W?r6caGx;XI#Bu-Vfwad3(&A&REqVZunjwStR@ztFK4YFbT9 zr$C? zr@sXG^oN`Xo3rXDmzVI)v$H)BG~R=zkY$rkx*yRErdS@ecYR-DS;MFpvE8vQ;Itz| z$QJ6<6E41DxY@%MSJZecsaId?%FWg=?;-5fgvlq3*D__s2^@XB zhoTwh?)OxkcsAJ^7xn$K-|lS<@$2i}?Cbyf57xKsyKziUOrP9BA2^Ml4+z$>lTGoG z3X11>^XCnaP~|Cd101NY-}FMI&0Z|f*+jmiqJktK!FMo}-!Vtl2m40^0-j)0Pq-*s z+zxZ{a`*PTI^N$VOcR95J2I!e{hIKO$}gN&X)X0HlEdl92q9vhN@f$98OykpBvz2x}x=`CWf?g(1L`AUL zSiCV}2_e>0#v!9B$+UtGDKeF#pw<>nWK7JK%yqCq=n}M`@jIvPqyBLbV#P%dnMHk} z*8QtrZT?s1YsYn#{}xQJ5{*E2a9yc;vi#FzBr*yf22+K}XEnhJd1J~Kn;-YbF_<)e zxSoJJyErej`ZwsCY)=Va9RusV9ewn#eDBQ0Xj`x-Q1^&HfF(M^-1pbleC4 zfNrgjFLPe#0pn*MR$J|&UyHqETE%vFw#?5ttKg<8m;j5&pr@E;Qw0Ip7r2nII`$bm zWn(kE`NNea~3HW7XO zszn6h+x)6Yv39w@n7%Zlz;j_j&4M%TXLU2Uw%pc-!*&u?n_&Z%;zgS8V zjhSk-|Dq%`9eLI_d^}h?FuB@1-`}2a>Tq^HSQ}p3@$~hrZ)qV+)q6uZ$WVNdyzOoq zB~mVxo|-dDPYqP08CfC}1MfLdg^&s$x zUJHLWE1R%xKa-qTeIB9wsi{faYNN5HH5!(jtL@=hmq8dbrwxN)n)TAUE9+Ct$<5)u zBuD0AZ*Klbd^`xa3HW$?Fj6Q^hwt0(;>K;>%(MZPKNlbaJJ`s&@_3Y~(!SSk4f5@! zrfgbTsaAK2iq5{T_De^IhGah?KTjy~HnU=Te-pFr7ezC3A#@;YJyAuK@fO!0!&P;_ zY1_rgwJ>mU8P|{y4fxnm}WxI?a zES}m})L$nst9Y|uPkTIWnIN2M5z%u29T(_9cIib2GOZM9JbV6KDy;cnN?)EDJpaYv zSLe_@T=Ptc$J=ao+;^x0jS~TjUoIpLG7L&4MtRDV+&Tq`ee7a*YKkg*T zn0bBw<^6-n`%m|b*hK@0cZ)7Bjx*c4d=*;#p6rHd7pv%!1lG=>MrF&eDoVt1CzSAB zWYm{0X4V2-2IJ&kZDFAp6fWZl*(+Uvf43*Z)|z$FnHXUikc?#RRPb-8P{B%$2e~u_ zFT;Ccw$wxx-(3}MCN!+aj{c(T0LM3q9~|UqJ-yrq)1OnY0 zD#=Q{Nm^b$=%_1tB83YaxJ8db!&lQRhRi4sa?~|L5vGxwjZr9UqY*He2bvGAw~I}j zoZHIgC(dR03hbIij7;0H%8}Fsz&k$>97wLl~!R=b-i3n7M+}dq`v<{ zi)=k~y&xzbV}Z+8RP@d$VCvx3q*f^?!Y{9mc6TSy0O-TPqV_s_9Tk)5Z8z8VK2@Ry zw5XSxxj@&7bpx1)BhZ@cA#os?EF;qjGZP!ELpm{s$}&$xy=l0P;5k2UUB9qkyy!Sx zFLARhad{p+Qtu_qrf%m;)2NowBcRU8);AN#8_54x^!2^%G5y;q(Qu^p%F8EKbBQyu z<+5lHCu;rJ#;huRMlt>)L$Hzy%@*ovNIkjJN^nI5&%@xCCRg4=_?hx(WqS;eXY z!MtGEDgEUv=YdWUqt=GjrUgVNYwEDIs zH#3>_Kc3_}-*FQ0sX1-BDQ>$kxpKLlCcv&U4PJB6(EqXHHBcX;Gpu5|0 z`{6)lqBu?f`oNl3#*-eo?K!d#)TY<`##zG}Z*I>mx>S@-08#ZTBg1pTyk4e@PlbEQWP7?8f{F6l95ltwFs;+bszwQ`=| z^#t$PHPTZBoUPKp^V#DVIDY_fR-$BPZU^&5f5N=eHwY0}NZyaW2o7rBOu!O(*L~*& zfI*rM&5vkh$eZRpZ$92ui}QuDfRLmoDUq8Xwr9*i;XjwMZ2U~Ke+NhUX7*m$-LR&e zMh8Z^Fx~l8o`;bPq$&g#0I13Kg<5#^_lFf`mei00wENvk+jNQ15cSgCdY8?YGO~kP zS<@vvq#O;FtA9AXvk&;(`|g1l!PRW9?QT&5e{_jEuo^=hqjY`c8zSY0Jpt7pa#0`Ip0tUMpRc;R{8NT5fOOmM-Qa!Y>fcyp){~qKnD@m zfBBL~+7(x;hB_NCaNr^_?Ps-CG6g%4DH>FZgu>A9yu@m<38uhm+*?9PX1zJUtwssA zo-GZhO8A}~Wq18~nb$-uq!&cO%Sfskkz6kEaqn_#$uMuxux-vsNQR~ZBV|fIZm#_@ zCAKnz>2Mwz-W7pZ0}nz5AZ|l^R#82TNfy4>r>EoDQ|lwKJfBak)AP|X!p^$`@4~-^ zi%4ha)Y?%f(q9~%>$crQ`{PfHBtmV|V&hVIj76RBkY3c7@$68Ti#y@r0 z3(Y{G;%1oIoS~O1$D7|xbf4V0;XNggzxiFNcqvaAI*WAXkcd|OS10$J z^i+DPPUN91GHm)-;pk;gkD7P5s6f}07S4wEg!#$L%*16y5;7m?V?)Zx^tF@gr29UFisuNRL{=3yO(VD4ufeVF84IrZj##0|MvIN zMgEuvkf^OKE%Sj9Cz~RYMDM1ElWKK9CGhCgF{n(K;2Vefc|P|~2!pV9-02DKpH&JiZ#_>@PtYo73kyq#!=hBnQ4B4uF7Mo&;iR=P7`0sBmCtp)Cs&jW1cbK{XuZ>&?P298mw6y*U<@T=jy*%r}+tcZ7*+^x? zh{X$}@)UCab3xTj^0utrVSy6=qKVp}^o`72e< z1}qI9+OEiW_jVL^O>Xdt(n)*B0j3a$1y*|Tq{&%9R(mzwhM^E{$+=!K$OtRMJO}Yo z@46F+mx#aKV;~svl&DnIoqn;`>j0@}KFY%=Z^IlsB8Y z5;vFCBe8KQHif;g@S>{ZdfY3vu|s2P=KnB*7-hx8d)Dp5B4KvbGvJ5(26a<<7F_&K zSlFs?aP#^nn7dVMt_=_7kLHhby;8I1js1WYEm$SzJT6znf@^%V>gr$cgOuKTk@!D5 z+wfa^d1DWFoQ?vu{qb671*NTtx?<&$FVbb&^Bdw)4o=tWJdcR8xufq=> zK0BLrl5o)X#rv6=0?sTk5R!s+MRaFf+uJz8@HW1p~x|*#~`W>u4clm-=8XB77{&W z*`6}0#6MH8j|$Sj+`Gi-yJ~I|FGBBj~>rPh?iU z7-U#mWjqYm`9;Lf$7ubNSg(R$LGJz6JR=Wcu&9Q3JVu^Jtly&?FWeJ(dI z)D>1TDVAq2EkmxD*K>eP%s6z1@g1Z_<%A$aOhysNiaMry3dzLi5-0gC6*lSY=9PPyQ%XBQ# z47ZKuSIGP1|AR4vm%r{yrs9Fu(VnC1$AgwM$`=zK<>bg{ODz<|4Xx3*o8{}|7He57%3|u#VH;~`6z*; zzOe)+z`OqJ9B&>>n_OQKMs8NN2S?&4>9u=a3u(r_y;<7mKHH#j|LeRkXK2*sT}vjl zzBR0t>Tbu0e?xW;ZLwLOBqtEU2zIAUqPTT?e|wy!I8New_D557<2SuDWd^j%snM%i zsPOs5#d+mth5qNuQcf$U?O_vQ@_x~y9(Fuh(0(T?XEm=Zo>N=?59xH z#2C>F4v%GFxjpf&_0Q@7Z*4)e%pHqSF6vq%1|P{^7<2P>O_n@*>H7_Nr1_>)#4J+3 zDa42$5i?n?xkj1Y?RjNmqzubPYF`6u@V48GhS|8+;Bqd7RR$SGn%N9GHC^9Xmc%0e zUvMspGYtvhh+vL)j|}XF)-8a8!?ym0@Plw)>MhB^qhLJ+os*nEeqp?sr?_6AoNRP{ z64N^QmkQ9McVtgS7MAvu=4*~mEj`}*C!%KO0DhqdN>%c|7CSl#HP^eY8B1>%eLr4q z0Yx^J^qm6g%uw^jhJ^*A6T2bxTLEM)c9m6epKB+_1bT6`q=q3xN~zDKf<*HMb(`Yd zGDz=+eW&mn(1$XyDk-76lMZI5xyV6F^yRTHbl-v;inM`lhClX-_zB0J$<*={4gc$& zAIEJM^*6@>rw?u(=4`edEne?tVVil&^yy!gcp22t$ey<{gb^jDPZ$8k#KVPXMb$gx zF>vNYccOMo2QLM}#vEWZ^&#NSyWF zY}~BgTn4y>NB~v6yMBl50)qsuPTfe987jjUDGS_y&5vv!bb`m;L(Q!i(plLT z+H5oAh4awI@Am%yOlFyZktSF8nL3yXNKxmDlocRfu%m;JtgzN{}~ zU+*ZiefMKe`>?wvdtb@s0FP+Ngi;AkN*7NZ`w7QbptYWQ#0kQ@?%bmcnap7r!K%`hdwN`m{8t&zPUe~=|BD4JnGN>{utsUnBnrjXpIezE;p6r`zl&sWBb6#NsZ$t-Qo9ma1_r%4}`@0d4nzva__bobJ?8Vb&lQmO|H z9Y~bE9#*J+y1Z@Hxb6FQP5Q8=;_V}c2cO14sC5>4-L;P!BQ&2Iv(#kN^6Qq=%9^>J z-~|l5-xY}5!v*iz(!Wxu&2P*ZND#Cok705c1t(5T$WAb4Z?N4exP!-?o2$HJ^IHQXx`oihj>7-g^mmYbhtr3x!rHa(h^9 z&KmSahl)u!WcDO5S&TwoXr^g_-MCWxhU~=NXEKosPcCV-{P@v=Z*6Iw-I+?&P2~Yh zu(u^HOAEx8(4 znqraf-RCx0werg(4X+0LiOI`Y zb-($?QV#Ro-Q8{tj+s_Q!m4Cc*rONJZ!GOLW-%yk))3yw5rr z5M#}|>yY?;cI*u~mDckp_xs@5fjUo>85@TeNx?yAK7N_VKs^g|qS)5RM~>er{mTMj zU}aoH7r(NKum6xQQwh(Zg3Uojl|DH~`?uQTwKbo5LTp@ImOG5qI=Akv_0-lbi9kbr z0;7FiA@Nh`ecYb~U%8=yJC>zH?K7luc~(BnCj-!8<5ENGf@S?>g7*V~r~Ka=bRE72 zT#U9}otwR;7Y*?P4LK^E-?V)&U6QQ$cOAJH`Uq_OYBN3Id}MZEyF}(H*X4>TP)s7W zh?$l3-nfYR)vpu3MUQ!*^*nj->c(^F+#M4T2%a(nW(Ey>YCuN>#zW28-V6NlGWnoX zBVd75ni425R1=C&R7J}wid5ecu|Zdsy#QH|qsWmf`wfh_Car*qwzv@>S+f=hsQqznX=rMB(qor_RFw;i|6xzJ{=%X~5NFWaLu^Wp z$PeOuEh-nS`aB{Ybk|&dXeg8eV^|;UGn%-kNPoVwwrLOTEvm99+@6^kGf=El7*PK4 zGpu;_QG8-IwSED;3dIcXE9>5Z<2w6~lLG#=_SqlbUACXhb&rod`($EO!uJD0bytau zRMz6Rwxd|WsCJBH@oY5-p+XXd5K#$Z?9C}8kyO?CQo+PWt{D+3N%6!5P2?7qW%gN) zA!leDRhWz8_-U?Ja%<33kL#AB}}v4@*(n5uBFQ zuZQsGclf^Y_lfSleIKJ;dz4&@6LCQ*-TiTg=p|xAdpRSt^zE{kw+7Bk`=CnD!@|%4 zBt>|}+8-1cvDG)V59Gl+z)}LJtju7qjC)s3wJiqdE-D*BjE0w<>){M$a zy!EB%MV-9lUBwsa6f_AK{wHP4Bng;<=A>*dNQ(D^)Aib@As|c{4Yb)VkZ9ucP1!~m z*O>XjHuixBFe%W`0R70XU%lG*;8gTWs{`7YXMP(^YoJ8L5Wf4T8+-lf?vKC^wTPgF zyrH~muGoTBf}o**owtV3h-_F)V!b^iqOu2}(HG?#55D7le`GS|HJ_{YSnHW!I83MP`=sA;2Q^v}{KJ{)sr7*e#o zrpBHBXClJ8N1$pizgZbsd=^-eo`3pJ=O$|xm8baXH_-L{e#4 zr#>)sI-&*1sH!n=)y(a4Pj}z?)~jwF|Ks6l6X4wWK&EZp5vX3N!wZ_hSe@$$_{`$* z>g9uI6k|h6%YC@G|NhF^!Fu#+$BStu=1RG|#IGxUE_3zzwM;oXYjQQlccc59>m%XJ zAW%NnGPuckZYK<%dF0cQRZyb`6t%my+HX!>WMo+h_2nfWB8TjSG<`Q((UQ`+%WO1r)ugqgOXCS^8Iy=i}8p+)7 zWPEP}QF*$GOps64m0@e;VmOU94C@52Fdf&r@upB86dIO(!v=@4m9u>3hqhDKG zWL!I0)jp64%VR2WnND?ab{l$3L9_-7g()TSt|7Y+&TkbSmr@r!kCLRY+CtUGpt4aR z*nxdp*N-(dQ(qL*s6o6$PrxDZ#BfpAn=?$uP?VW|k)U-VOyD;22nVb8d3w za5Ht*AMTwqZQ`e|Z~XExP@M(Tcd)k_$HS!?hhJ8=N*(%Jhrecd9|80)^t>XFvVJe$l)hc}r1xFTE5vItm(6aja**4Amlwe&$b->fJ0Ro$l4 zv0xLpr@8CC(90Jbk*M?kqkTlug3E>4#TDXQG{DYu>5nzTMF0MOBQofJp9Q7OrY{v5 z>~`vV9}u0Id=qPqxZ8&0<0n##7#E?;#~9T&0i&tLj|bX(*`SSevI^|#=9_&jlR zpDbUopD;W>IK2p{lbgEPH~XuDJYMq|F(Cqu!ovTTe4AT$E}m5Y!;U$R>Ehh;jp*pr zqPvxglny2h2M4{qz3kdXxzhAhREZsoCDnwcR|dM`Pp`w$JLII%^S=s_AQ7^S@ZVlc zthSr08yjbP{rcMuM_$bTqv*WD+5Fom9MQB)PNW3M2H zz4zv4Q+oxqcUvQBRu#4CeO`a$AFeCOl_$Q>eV=naCtY&lS-yRY0JP3RUg^J@PCn!7 z4^+H_MEziKKIDtsG(^kKamAtgTlZVb}_c!=@j6Z}wYkr`Ro&@hRWM;W? zVB(s-@b^eGTY){ z#y8>?<-%3(t61R8=@lsf~ z+?=X2WN_;>668a)YRWzL9q; zTkvoZJv|s6Ox}v9mED}y`}S660nVwUX<*{pobgVJ?qwz8(ccbJ%oNKwBOIFV#^t#YHI?dQDz{>@Jhn)dgXSFWByasJ`>T%+AQ?c5kF_Gb@tWp8xu>7d=+Hc60tF@I&LPt6!VIR{O61FL$cR5uOljvV~$klhwwV z>4K3^gD*jDgN83gM`csoF^q*nbFQfU@-KK%sW+59QSi0P{&_o)^R-*+qGgRl(Qls3 zodFiW=oUAAgNlN=6ZdvQhN+BvjL@GxR5D-2xxJUkWd_oNpDT@NQ&^)cM;q#Y_&{=`e-|6&Cx?+u;WeMb@`mitiTFSI zP~e7^1rMTrWBC2L@3=WQysAp43{G>x`PU14X$GiaMUc>R&A(Ih6evORKG*h#5n3uR z2?=99#`!i>lE<4=|5YexDqE66ZN|Hu2!sQiIZ^j0JRwtuS4;p$0b)Z9wsbla9@yV^ zvKk*5A#H$Y%V9h+=*}LfLh4eQ`0XB0sqhHQn9?Oey$9d>5sydg%F3?ZFpRzY#A3tt zB;P>i=>?wdtxZs*&r18p?~)`KLF{`Y#(Vx^EsXcS#WcSkEZ(Zo+t~X^l07 zQ4iKpv3K}i7aw~=i9sjpFH(W*!Qauch`jP=L{lu%K_pOOt_SYeq$8HbtMH>`bN#IA zYnfQsoQO4&NfYpo7t^Qz_q)p>W7)5`we7=*Z~Ka=nd!Sue?Ko@Uq7Fhl%4Z^X^YpIzL!;(ySZclIyI=$>@W$si$+@{(Fbs{`x%r^UQLa zr6rhP9{kohwfbG#)$qzPdNgBsY2HBf*lB1!9|}`mj$PSbTQkim(bZ`Ge zOCX_4CGLPvv3d_M9~YnN*;K9Rcsa@-jaf7&C{A;XoW~8n&g%&Xe!gk(r`J!8MWoMrr8LiN%b7cWPRmO>U95NCrk1Z=oZb{&hm@}U zdhr;I-oQS&evDpxX@0zNOL`A=;dpT!4|-5N?@h0Zl}5PKXOJK+`HhH`eW{pW>%HPK z$9R?}3W7VcPa{o$h|B68>9QV{KVp11w6aCcK4E7qNwJ>ki=?EiD8oMRZeLnGJEo}P z@(zElwSRb04|^w^vOUNwPwV}JvDai2HA62ieK_ClI`hU#jf@Kk-?oAj7QLcY+AN`& z)qQf^y`-t71B+6a{U{$|kK{|Xum;hy%gNhQKc}G^kCgDE2dV(HNlUjL3lH5Q#+Sx~ zgt~ZEUyWN4>h7w6O3VHO8^2toW^T-m?X&&9L~CRoU%j(kCn;40h53l=0D~=>A5Hp<4{v+sD?{>u|HV_9b?{2X#52gj2?5Lxf_wQ}a?>PIVhBr?tH z?G8)ep1D;%`MM2i5Y@|$0CMaVEg%{PeJ3jG(U#tR=iXP~*(GpLZeu{Jz2izuD2+&R z11kS^B)kf$LQvE~_?{~CIFRTlF%*?QJJ&zDP)f3Pw2BcT(p72BPRsQisJNBxa|^3CnN-JoH~F32rSy{cF@n@8 zCPjN^%kYssNW{3*T|p@K;n}raypIVpgTexgUTDe)A`4k{ zGB#C)HI?!ZAI(If6(F{qkH6^h`G#FW!|8Q4-ek6a|2?76GpoMB&rt25LQP5zO;Z-A z^QkD&&AR{G%91Bv!T>}xy9sYaVd&VI+ZFhk&=g}FqG@(SSxeARe zQ!@6EAI-W~ShlkjiAY%nh3=h}_5&Klgn&75lMIp@y-Pkd(a0-(CbP$ouBA-zVKats z7#Y+2V_R#Ezq2By>SNun;37nBSo!u`omutg72{*(qAk=WilpwhZp)yAWk_&>!tCdJ z2zRyHPm8O6)(-z`Wp10G9|{icOZdX1${Y95NH3*HlQXQ;{EKgO$F%V;Y@JlG$U z9OMf!rAi}CW53{uD!PPvP=GRz6ED<+kfKg#{^e$8#h!Pohu5>MLC`+G%XR(wc0iBm zn~^N3yPw@xo82cZZ2o`S11{^_u)N)T>^I39*AX?DNEHf`I6d$ zvuU5O%nMdrc}sb^MZEa$^|}t)yM0YKtgZT)nZwm$*H-Ab!BD!Mj@K_|TJY@bfXV3E z+M#1>`RB83Mlvp1HeoG0I(39nq& zm&fot$!>>NpDkk0ONHjp+vTbPSsI2Sh2mCcW6$&x`~NW#Mj=ROso5K*xAThRmz%w? z+o(ZzjLt7*b@9?#b46N`c_t3$m1c)MZO(9NOU?T;dEJ!e!As*jWV&5R9AmI^vuk}Q z;oyg08qhnkM zRdpNHmxLrdg--qdujR$UNOSE~MA;o_U=LEjMCYGh64}~qy~3-SOo+l5fmGaC5Xq-gUJC{WF92`g+?atunnC7-q5{Gbc-aH_ zRZeEGXMi;s>7G%1GLZ>vUoHpECQ^{VUQ9CJ&%tE_)#N1G+}xLI$2##(e|CS4{2cIb zpXHB>d<4R&+3>$Dd#SBJTUqLeOar1IiU^4TQFNdL7~l;>c2xG!TEz5U&PkqBip4Wxvy z$gppaWs@~QR@B*ljlT*I2fYR#Hpkd|mX-;}@u6N(y6=9O8e>u$r}ucQ!)%#O%L!qZ z#~X39oN|du;3oU&%4YjESY^p5B_ty@43Bvl{0V%|K9M|$y~$5jBND_~XA?%#BZ0$9 zPxSizL?F-NLuykY>mC`Ojaw4_oZPTd#)$(p1v?!JAzC$$j6;wmx*GU4dwFyjW(j+3 zezvmISQA%=KG{5RXp$(~n+H@X_AsUr!+P1gstt2gm0ZGtn@6kp4$o;i7pyQ|F5@4Q#Q?<-7b@gP>Hls#TFZjK`zU@;as%zsBM zcW_;HJmfG6d8n#n-+316)5U>{tyx@Pb{0!j&p8scSQ$GrT|Dp@SMU70yL%E3vp$veESrzcd-FIptwot?^l@rXh%GMopm5)qXNyFpBpA5#C(U* z2ZryURr$Htnt4X2t;t*dA3}WQinY~kd4m5VMv2~TeE0Db)7L%C_O&>WTXoIdPwDFt z?cez>xKQ;k#jd<&zWY18nDKe0{f?%27_M^xJNs!}rYdN+X}qFCjA*5fo! z-_U(NZa+5J{wI$o;?Nzqd{g6C;FGd+Z4fZE)frE%vT^KMU9$ktc8)>4##YZ?I?a6# zb;Kp%g9~BKj+FZEtCrQDR(~^TsM-BsVcRz-UQtx=vFjV(0hLldoC23fTjFqVmA7A9 z_XgS(aQ3^w?DqFWg@M?@f{zc73pd;W_!M@1mBbGt1StK*C~l{Y`D@m@KAlYfmPTJs zzs<__kAMCyoldU^t9~^)NyGsy zlSHe-AvieKpHkW$OU};Td%`~Kqr8X=>}!8$A)pB+x4 z)CyACR@3vPMf!_5`#{2(2$brux-N5kd*0J5$2xg@sIcM~pZ1?;bLYR?-n!AXZx18` zxt<#X>C2xR68={PDrfe|Hz0M<2MKkA*zYv~ml1iP@m+VD$xqob_n=85zVzu;nNc0l zs7gMoPld?S>S{-;33lC(Bh-6Pfyi z)q$kE*g^~N(EayvGJ3cGptJdTt>{&Mt*SaI*vaA-+#SuS`e z;M9yz?S^Ri<-)&In;*SGH=hLXJUM>#!A>&We47dOC(XJ5>yTILnzIMw>C++gw?fIN zaUQ>yga{H9Jig@+;|SG6Ld4OyZq3X)LPWhW#aYfyu8j*>!^Vwo`IX|@sZ+Kb2YFC$yA`zIT*BPSgC61 zvsLn!Dc4Z*k68`ngCo?Ov)n1k8FRHmi5@+4ifwu)JkwpCRe>gVB=^A-udSV59q#O9 ze!Px7;4eA+wCGw2SJIOElAxAEtAg=}v?=~WX`_3h^p@DBCp(&4GF>#Igz$laIc!DPunn*9N z>!$;2R=me*C^EEOkz5etzq+omW*TEPh(BLz8%J%iKn25LRLNlKkP=K02^N+nv&dgj z?$N5$@~{YL``RWE%4t)_*&`k%5DSR_h*{~>Sz>zoF563bq2K#u<;W(lepm4D_c&>*5el1=s25tP6Ivja_2lqgb0BIhWoK?wW3P*-g>9)h(K zIsJV`1cE0y2)c8)(&Dz!At@<2^S3`<>gIi`$-H`Bc=};wnJ<5kq`{BH6+PQ3>53^M zj`3wxn!bSGGQpL*Y0@?`+|>v0^=;mfy=|)}^}S=2?4@vt2w`wJHMd->Hk`BQc*a_H zb>H;CYy4bc`ePn?^%L}=q_7`_Zq1WIjAe{b=W;7~pLu0j1q(IC(@|kD8GrZ1cu*=8 zQRS9p3?6(f%h+jdPB_hoW;!?Ec_SVeVn_6zjBW#}iU=m1zNc$;?HrD``Zj5Yeeuoz z!9ySa>kN&^xcKD)>Opx4cFwH-oHm(5&n5cTwyo8)_eW!Cwx z0Z|jDhu;Nfnsa76kx?vEg*%%k_awC`J(a(utbAUlWcbgbS|?`!<-m0qI^K6;yq{Z_3A?f7`zG z!=T1yA^EA^w!i7L)J`f|J8I?7yR&P>8Ni)GlPz?713Qefvdn~C{62juHPPT(_Cf0Ear4T=6`!9K3B*CQ5ol0Hx?ZO=c=+!tK*&odL`4gf4_Ga@BSX9b+fs4 z)%v`+tsTV3^i!)O(hG7YmK7RW@~^G3s=9uBgeGVcb^30FZA*lXHaXakkot@+ zWcdY%X{@7b4l8l-;IQvV^P-})RF0Qpk4k@}{w}aNf{~u4HrtcGOo@Rf>Zy!nl6EKs z%gYt7`}ic(PnZS6(_;UhC;FLux?R6^(EOqsSTA-y7}=Wr8-ty;bV#kz5%Stzd|Az! zhO)~L#WORK!RkC7ZI}&%+ChlOEw+_MUKMK=8xGgH zSAGbU2SOR*(QUSKWwv~uCS5km5Gc#%6!MEM1$B)QWep9x6SOzS)wdz>GVsSQ-tIpSRBALbX=swl1o?s+$211?_kKr#8r$ktINJYORW= z;Zj>+A_iGl5{?^hkqX;R@uVg4D=(=+LBnOC)OZ6horSrzwY5*4X*v>8QdQ+-Gzw8) z&v=FLG$%5=umW^Ys=iWQxcnV*_jFP^@NDm_B7PI8s_ z!bn>qy18uM_}TOr9(4Ro#lXJo_sv&2)*3&=8;vx_FI)Tu$M4~ry-pRn$9-YI zbs^q#!KJ49om&eKneAK+IOXo>OmsKUt9Smml+g?gW#-&TihE-)nIkPFEu9s9a&*pJ z64!cQxrbN-Oz9ifT7Lgt{rcKCImJi*)(TU@5@yd(MUTh%)}X5lUe7n?@3RcaWi%4W=ES(aD6dJ_Y2YIXA#u0aNK3gcS5)z0`Xslh#169SwT0- zsW#Trxie`C#B=7uz|Q_<^mjq>`48vq&d%1Q4u3z!k}XM**NbD0!2IIj`88U zUN#+7tiABe^c@lwvbhi1GO<*`A28+)KJ*qNmjq!j*}k~hP*}x#4%^r+Nt5)LEaeM3 zJI*9QqfYW9|QM*&R*!C-J5KEK#CF>w8t_aGAO9VjI>oC14+^A{1E1l<#W8C zoz?HKWdhK-P51`~g7NFv%OBU?FM2MR}Bnp_wfGtU;?KS9SZG-98i(H}DT4a}GegR)AB@CCl&TZ`~*P zHq(}+%E;ZDo7MI!^DT2L@`vgV8|ObATdF__2kd6(%iA)FBdN1a{iX3y1Nkl)-2H~O zqrWa6gFp#XKKU-kXW*)ne3NBAwO@94bh+}dl8i~S&w=P8>8nW!?#Fvc(tbMIzfJFT z7XYcby1Taq^VgnAEAr-f+o4gzJFd5924;d^E`J)CUc0mqa3A~kYHJIYYvP#)rg3oa zT)ty%Xj|3gdxFKgm(il*K|{^;wWeGJF2|$*2fMWZ9^eX;CDzE!`|SdhNc|gLP`M)~ z&VdZ700_(8WEL%l)UD;bR^#67Rr}>GjCwj^>J5hcnQi(}@ac*CT-G1u=KNh8pzZG} zi!H|oo)j5qv*S1OM1j)O$KI!X%*|#u8+hD}Wusr?*WIWlLzvZeEzwUFxtIyP?&R^b zzKHS6)0!{2F0?G90Xw+Wb(8h=HFAF+uQTq#08gK+maH5(=1;>~+I7V74FBwxW}DK# z)EdrD=9qo{JDtptckJ!3$G7PnC1w?A>wa<)|0X*Cd=#2d(h~~>kZGHhRh4J!dPOKS z-CKefBG1%*g$y2BmeKR_z_W&lG3ow)56;tU4@>|h8v#WnafRb6tMqDfZqo`C@|E!< zp`Z6B!Pkh1WFurD%5&@9J?*)!M2GJPWyU?HA~TwBiL!9TjN1>PB&8$c65b?^rsx8c z2$RzDb|s|Z?I%sL@wz;c`J}T0-pwoy2Y%|ii>mZl`ZVstT+xPhAc5_eeqBGKYVPu$ z=NX$%-$-43FJR2!&j|?L0V+fl_G1L=xHhTl9{M>w5==80?26~TRS;I3tYx34hy-&a z#%ywe9ec4br}FPXpYFh<$9D`o3YHnBLMrAdo{jTO(P0hzp#thN7FOk=SZ(1}@^mKB z^I_|EK3B)CEf0rkO{#^5{HFOU8|Do;XPG}5=6!m~I~Bz}!Sa&Mb=?o9Ww-av4oEJV z%f;VGFgK+=*Y@BTJSL=zSlE!@iK_4z?GsR&`Ear;mzdl{oT#F8%8EpAZ~vsj)?rSo zCds3z0(YfaiFYKw3XlVO>d*GWz1`iPGbQDegYF0I{D3dy?BpcUb(-Fo**12ob{=+o z4xD2uGs4dqq6wx4T*W}BZ4a#lFQgXz>jOLr5J^ICNoTL+I$k-!xu)5NcL#xw1x~7M zEML6u5|OyO!=u~ychp(7V;VUAecUaC)GPea{FleS*Tv2Tf0ENfkir_9bK99MHSeIB zrVHvicp#(m*w+9F-~a2W&xcCTXx<(lvLWT&TLOze!cNZ{^pvWzVGy~{%tPDG*8OV@ z=2Gpb@kT?wDEinj3ie?&?vU`R`6q`F@0_l@+S!Zh?N?5tPv;zM77cN;>mR={MnWAW z62R2yMvzzbfl>k|E@Su~EPR#T!$AOsl- z%0gq}C~Sv;P6MVv*WH$d1z;k&`n@w@0Cg>KCvlH)CmgnFiCuZgawQz2BNmp2Qg)00 zj_>G(O^dzq=i1w+ctDwH{7_&yYGwiD4w)k5W;NYeVvbH9Pt~*R#wQ9J!?~`g&uJ)j%NR>Qk~k z51r~?zA35KUiU~2l#GxcJh@2*6Hn(227RrbH#B)2`r9y8C@fq6yoI$xZy!lKfxNoa z=7849DmxBkKhDAO1u z<%coLD=f{G|0E)?;Hl0?Xg!+pbeceJqn>YO2+(e*=QxhXJ{whuf zl1@S6t|JB#(AX4K$4VSaa-?t+*~8ZZ%2B8}fjFgptgnm`(3FQ)>%dY4vt6vUkiqP~ z-F046O>t+kR0&0fuKVqzYbZWZ!4qcL!vm(J_2`p(siXs44TBjA|GFH0@Pm~``iK2e z)A~rMv=T=ZCG#0$pp>_W(3A^otBD7R)^oZDPdK<_$tGEcmWB&$pQ*So@crp}a-D+J z0SIK?zS8ySQn3H$!T*2M%tiel)vitN8B#nhpN!n4W^k;U`~5@3ght+;@qS+=&0}`X zpn8)=?6o^9u6-Ixgt%ue2N#xryXjek{)p@*7pNNwyFSnI8}eDc9lm8=aT7Nqn(r$U z=$;}a{Pk0$I)0+{5o5?kFT{ z4!dwbU(w|4dC4Xf#Bl*yj=2^a)L%TZEaW};^PBk@2Sl+jpn7&_=b6dN8uorA-EKy*za+!%SwXJ5E4oZg7iaDO3MU24LGpg zvw}0UPAM*MKCU-2r6rL_4+os~RhQTxlPGi`$zy~Wq$^P79Rn>VwzRc*jpd3`T4`31 zO7vtN0&EZ%c@V|u%bNsRONVq1E;Tsku_TDvokXjFm?1ih_c@qQx8UNP2^haeSRKLz z(&{2r*VYukYf#IJIE#O5tA#_CGUEmKrIBuTHr;*!_R5R8|v(A z*A%S}t1+kIaqE6KXT3SV8tSBqRVr8he*^hf3o;!|c^aV?X=5;MxSw11+JnR;le%v8 zM8UYt!?h}(^S^(^EA+_Oi%~jI#WBc8SOpA-2gl0tPtX_&M}U znVse`c*^f)OYukPN}jyTeCQPexHz^mg8aYTyBz~aG39~4#Vqt!2tle4*4C8K{adER zK@1NOzAESmx!n7GI9AhjbD8t+gnqEug`b~af9SQna?35&7x4P4WO>e`-7`qMqCuLd zQl_T1R~!-4M@L6()v6HaDJuV>3#IL$FK&sB-lCQx$wPe=p2+@|r45nDvr=QpR#sX! zSYMDh?5J4e$x5d!=(2k7u|~4r`qTvUvBs^tVNEqcngA{Sx!m!n7v|X>co|psz3bMu z2M&SIf`kMKip42zYY)FxKRlWT*gc2mz!QIJZ;f_;|G0_`q$ndx>*l-LQUniyP__q1 zqM$lZi?p^gfjD>nti5pl$1S*c1{@=WM`N6$l_#QReKp|UrhrxY`_1{PHVP)h1q)=qoT!SeI z6=gjYMB5vKjw&<(W-nCwg}0nGX9`EKv5HsqD-wa^*oxObryQtEo>?QjY#Mm`xLHB#lhttBCOK6!IBxruw3bTvV`(^ZUAAUSq&9 z6Kx|ph_Ih(b4nZXn%lu#xvDB&N`!f&QV#}@v8(o;t-beq8JY)@ArrJE4aVbnl5VRE z+~3T^KkoedpD}Be)Tb^9KLFGQ6R8N6!l&q;0@m-pXHP~bN&>lao{ew&8Wo(FqaF~by5RKh)4l;zRpQRc^K^<=@AH|UmzwfB9 zz*Sb~!&3I^n{6&iTV)mv$IP@QE{WqnV8!PqWShd2eYxc%k$bilXsVgb+G}ZNgC zbaWc?5Jrxy_Ct4;MVa>6)=HwMbBfrn^u+nvM!}e3*I-UQ??tuD zOw*09%$61R81=CdyTb-54YVo*Qo?H4x)e4xf!Z$sqOJyke`;Q46MZp21d7U$cYi65Jw z&e2K_$!8{RP~-vUuc(;LNAe?} zj_2><&HWLC(`Lmmzn9awhqb$TetU_uZ= znGGJ*WBEOE@Ok`RTh+2nEFqXH91=<@tV5_Er0$WlCZV2Os0q}xMk95b>L}&ZjPDw% zJD?_lYC7*4|Ihq}h65~jRI)ice75Rcur_!A7!>!kta`Hc)$PW0r+bFfxj}9cv zd-UsorKRAP;c;Vm`AR!rJCA{?&-61{VmuhQJ_&@AD*FMgY4(k{vxxd&Qc#$Q<0UZy z*auZN^ke-*6+`5g#=(MVmv8&|iei9S69zXvUTT`iVN~07TD!>4NWWm5jqj?ehqC_K z>?^M0>F$awt^TWixMDAV9_h02Z`b0w8SD4=!Qn+j&Z`)VxUhnO-vN0MJvVW}gzf41 zgjh>U&1NG3XdhFDg&Dk9E_a}KdmB{!klK8@@&BI$%9RLS?A`(F2HV<}o#&NmjjK8? zHU$_))Mu*oDrCuW)CXU^!4|;dZagj=3%E zgvZBj$&Uvfi}%-B(vN>EoL$Q1l>P|x2^crGe8U6E&G`A}Lo82t>ja7SQs4S!mEg>_hwERWkqvYk9uLuihy#HO~Nj!f6L9jx$Qsu?PVz8SD5e zjz9?&zu;R*d#?nrTC#qvaN`%-A7ObVc@9tTgeaNR8KyZ~88F6oUCb~_{~h@`LnWp| zTb}``X0OxJGm4I3R{gI1Dl$=yEA>Ql^|Sl!0Nc=7MccvqmY_9wYm61M4jvwliivtc z5vSHrDzWMgM=Nqi+}=x8?;Xoff@(TlvX*=Rdr49flVV>C32YL48<3LsI|d&NenJB( zAA+Aw$`XL7r(tsNuQ4xaL?YWW_QTUE+8hq2NAPn=%vD;Chfq=U<~yT)G>gtxXRgaG zC8zG<^D{Le+o-wrB`_{s}ro-F7FgSnKWX2jz*3s;;(5spNp_3g3i zAF0XYvj^#QxM@Xcf!e)vC{8f$E!C{d-R0wE8rasX(EC^%+x0!ZfcN6B3}%M z3$nH*9@k1QOAQu1$eIBoF!w>UPr#`30`uYl`B0Ah#3=UuuH$9zAd;0s*9M~qcL|uJ zq=bZ}m9_?0APiFEJZ|DFfy3zVC#Ago0&}XwYrP=aB?IhO1~=U+wvNPImT=32PphaLLQ2GZFgQk6`f2WzN{r($MPgl4IMPn+^f-XPsLwXh@d#DpvE&bj}2&L zF>c~v5*&glMX`ve5GIu z%V+yMCQf)daHRYc4@44u)OPOUQOon$2~1gYA+(1lrCG4#>~)6)$SAE^gBAedPs1u6 zX4>iB)YZv+^?WG1*oCzP7N@qP+017wn_u;oo01)bD%dP2_byV?IZ)6xT`E6^Mg+7! z3eQ_Pck2cSJFys9S|vQ3v!`xm(ZyK7)t^YoPi>!W-2Ki0<79QScPx|r7QM-^H zmJt4hJXH3n0H~0IE4uCZP6&tNjQ;XBrWyZ@XfXam!SK-Y08>H(cN*p)TC2La^6*G% zLf+$qI#*sR@%}~NALYPYodbidukJ#ulOv<2a_g2Z;9OBv?s2vp-uLQW)5vs@;j}_9 zr}rC}%+0@aeA{B8$2BGp?x4hBDfuFv#Q=!C1J}zfq{tx(YD);lH>*3-RY~`j{q)Mg zVE&5MI^*lq8-M9SRssn(i)^*I#SC=FZH$H?>V2N++lTPrDO^YI|UhnFmQ@EN|9 zu-(P1nHCrbT_`&D2$Z2k%BAkQQ%-uUtdR(bN?TK7SG z1W%ncgd;bV)Q%N8Bs`?@tdnO;P<=*N1NL<87G^h*r<+zu~GF-?*^ zuU=1*ylmFDyjuZ2ObCJ%b`EAi;^Bme9wRft1JrQcT2iQpmp}R}%JuAXl~zwU4YM>zKCEANVO9>{q71%<}S`|qTJ6CFnuBSJt;Dz!+9%&V~ zHvYU3xJn%NxnJvZG`Z+r19~hhIUIPA^LB3P;zM7}j3iLI$gtsb%pU2JDTS+Pk1OR+ zH#AT$O z6`NFdV3nBxH22``ve&&=w=Pcz%VTCuk3-}?$$y$Y7L5Je?mxtI_<*ygJ%{b+)MBPo z@AhSAB87fa4KJ?JeV!WMq7GFhkD~$OD+XIv1$`k2PsDgd4@@sD70k?d;>t~cQ`xL_ zFp;aVCoYkMq`Vxs>Sp-k?oSzUjFZxz|8=ruy$Xn{){qNJSfr-Oop-VZ z11NqHW&wgo0Zv}6ulyg}tOB!&vrvg#1(t*|qTv(;GAdjHNpje-SF3cZbhk8)MqtEJ z6p?sew_AJ*!$aM^dP~LWY&`~5;;(>1))`5`E7@V;oZ4*qU%B9Vy7%|bHp^i(5A7&8 z2$&rVij96-Zto3(7z!=Pg_uD*D#$XqlvlkXj9Ko&&gw%~674+QoPA#>bGo-ll zDKz#Y&Q|#yId}m4y(tiECb1e<_88p+9QOdVKBjde>`2s5Sd%1_aH=(GaX0&Mq)IPJ z7IFVQ^6S~mj<-@Px$IR!d%_T(PLM0A`h_fdpXe`OIF$CinZA&^Jq$c7*tmQ<#P+Wg z7HGM=X_<-i#;3HecklOh3rOGyPJ#>O*+;Dh8JJt5~xLuu z##SKDYfQFLc)?+}wZ94{?QWvTUAoG!l&Nw+O1=Y4Q{yn^qbal713U`t%lH|fCZ zpawB}_ij*pVNKsGBns1KGv^wFbdISvvM&u9RKUL5#FRMfT}$CATdLo_HkH5Ud-;t7 zjNf3&&oDMu?~rl3^ZJ|V*unRd!O|U6L|#0*z0Ypv9x1$%OBW$cPz28b^fUD&wfw;cPXj}yCs8qB+}Zt)X~g0 z0=eE^T%9G9+M8fFO7@LtSR5#+pTmpZVqK|(Mxx%d*yGLnZlGtv;-?$G6@}4;dCSye3q zYjNn9DC>Krg+<-B{*~ggTwY!Y#b|5fZRsLW#vi+@o8n0m6D}GZsP4UO;Z{1uBGXgu z={(0N=k@2w1HT~|;dsj_U#W1!94ou;&|02)-^`%8T&?|=-e&69GK^o7P^I^Pw^77E z#ORHJAWLI*Wy>J5)sjTAWj1gdHE6Q@sd`o+rpppHvT(p^kW$4GK~jXm{}O|3XkwM$ zYp+|O&_QPOBzZE23s5?+dXT{eXsz)gu?7#=DWK<82PKVbYP?^0GehTtbuDdKc?mow<=IU{aM?#S!89rz47= zGV;`{CfB7;eHFi6FlAmUS{2)U?MVDfk|0ws?ccJDO;UybH_6sL{HkP6{{=`kG6~xD z-d!VmczD=wRr2#?YvBPE0b4S9<7SuY?jPH2L10(g&EMb2Y;IDwAzw|@el!rCxtzA6EzW=mjdkv^{T%qVwO z+Z52&b9WhM^rl>i`)_s-H~0iFMF^`~6C22V0DV>b9{>eG`o79}nkFDfdgl=Wy}Vv^RjD=}qnci;Tdme@ z+aRY&t@sq_Vy464m{NLo{qFVa*Wl~H1EQ@K5l$(WQjo9Q6p9nSWD>`!c-Sm9Jajfh z#CR9{iebcfE|LTSZE(b*`N(Hgi&3einO5QeTEZll@R_6&G4V-TgPwe|Fi{uvJooPv zY>D4cm;hh@8t(ozzkb#AZ&5HMr@!Tu&ptm{>M{biR#SKjscOolZMzU6gz*56bLJ33 zY$A*l-uqk%!h4FE!Y{1)y!f{1SiBFR>sIT{X1&JWw(HhiyJ_35i7m1{i#SH^MhJ-{ zW)&kH3?60fa!uhm3m5eR31Np;8RTq9Lkf7*nuyH81mQcDMNQWOiQ%+_Fp|sXc?)o* z8|QoCe8hR~kRYUv1TS6>s8A0=w47m1^*QWfoXs)2zB~EBS#l2K za4t_Jr<^AvBJby6qdE1b6LBy!GvG|&r;Zg&NYn{7r6bS5OwUM zG_7-iy=Nc9HPWp@Y<$!Cb``sI;~Vio)XJ2ntc4tfjzc4{aV{dGD5;q;Iq%Grn2d~t zgv|x%Rvt1$h!P^lMnWSoNQ};TDO!w7oH#Gei>gj3_ro+zIW!JEO}UIy1{8uRX)#S? zMnj)d)?73fO1X?fI`q@sZg_ipcy~MA?Wg-=+7J2unC|y^P#HN4<__xaC)#D&jdXjU z>wA5Bm*3n^|MK7b-+%PS|I__JQ@o`0%ZWoFrySTv35}1fxPY+SqB?7GuxJI_hv#j{ zENX1T-a7zF!flpjiLmYgVpWAwfsv6|ge%N*nWkyCyPvafoMlsCE~SjqlylB0#Tb1E zBJjehD`0sB)}+IssAd;jc2cb%;)3_yAvI;)g&=qHigr#s4je|rEFr|afbbfVAxYRt z7O87@9*>-JnQbn$Uj)4{FD8}hS|PGpue-KunkeEb>Mh7vB{r6Gwi>zW@9*zw+^nC~ zDuDAWh0MJ7P18VPv--}USwvW-mFGadbKVDGG1BV%NH*&ysxtu?23$~&hhr&veRJLS z{j=xKSKSJFCJ{lnO`4OtR*}U_9K!{KiJkYn=oK*`v)3x7k64In$LY)fjT$g^c<)n6 z&|_6Jj_M6pWhI(HeU{m&%9w?e%mu0oS(p$m&LdWzI+OW%qUSCVz4z1U^KU3jK#=bOdv7Omm7(SifN+uk*dkdVRq; z%^nCE(r(POfqDLgm-8(ug80ofYBqJ|x>0c53lLN4%B$@WpL2S`d55sG@H_rHt*2AX zMaDx;?Deybt$zQxX2_)O`4$Rf@KLo!RHqU>X{T5rW9 zNMI2oQKM3581rGu#f8P5gJBtjN;A_A|inxuIhiDP4Op2f2`iJi1-9~E?ESb91~u zjJLb-?vN(sq&y_+Cp~69W_O?EF3I&kU*3;j-VL9>>p%OVfAem7b2t3_)!|?MoB#E@ zKl!^~zTI(q#qFk$C-%%@1cka65d;FLYECsGE30PJQY;r$V`C{wMfGqvq?(A5mY7T< zTfEp{jW4+j!@$h2bF&Dkq5UaM<2bZ!+cXVS+|XDI<9Ik8b4t*wcWoQI7v?2R7Pbor z26#N|DJLt&ELUPJ!QFv*!CkK+1jsVh7wD3jm0U~>P}4XJ!^e=QA`71=>e)8N0Ue0l zXdNlXDsHW+sxpxWCL`jDMBrL6(_4ltQPDY7F_K775TkeEjRQUuaysx=s-D*p_e7lWU220Fzs49sGthr=;8@#Bv_4k5sT1LwqH7=Qw> zP(r*x&bjaV3Zpp($}N<8Mt+;8(J-!TI7MRUm|>^DEyv?ABVo;a`z+*Pr&PfL6cmPH z5m_{3!n~|WoP_Xz+Uu67!fhf;=CE< zTp&a^f#I!=UQPve$`~S|YeZbvwO3cqudbeNHrsBsYTH%t(YfHA2k0`BFd>^G&XPDt z;?xNUOUyCkj5GOBs6x=r+(pEoP^eo^+_DGH$}C5m{vbM6E!SejK&dQiUQBbrNY;w@ z0zE3$Slub}5TD<6_WAS?DUa*NZz{DOB1D;rmXuO12?s5Yf4z6&or}&z=UeAuE<8=e zxn{lEM2EwjcNJcciQPn0Lb&?i<@1*xUp)J;?Jj+|aDE%YW!GJ9x6jrW8y|(e`am&C z2+oCABot|~g+$E05$}yzNUUN6V^%E$4&ua$v(k8KyahKjatJ&KrC`~W?1`J;LvW?& zIHa74Wi6`06oWUlvz5yWWjCrRIUqO87B3-&Y@wwt466fGteqHH!X1Sd|2IVDZ0jAO~gO3`6V zQz}`N*u0kzU5Mf%`&Oc7AH+A}f*2!5pG~DC=!+bQa0rg9Vyb#4N;L(y(PCSm>b9#g zB^7o#TYpTu-LOB5`@^{F(|*WfQWaNB?he!aZrV@u`Ca<*K7W2Y{PMd0`P;*1?}pFc zrMK64e=Pe^???T^KmJF5`|tn5cl$oBFWJSCa!$!|@$>#%XtSF3{Q$V2tR)xCYS~E1 z8T&Dnew?mv?uuI5G-M3SY|Lg&6L@xf0?HvM0r*DI0)7@_=-SqYlfyqT=bXoJWTMSx z)3t5ewm>yuo&`q1DrB4q@Gmb1)A_&(F#!|;5}T1>KhD8!rq!*dvZRs=-sRlKaHfav z6|mwtni0NE;8<1YnW-!|cO_MLi|Ufa=t=cFnEe}Y-UsSWHM&6lSh`(`!V4$(B^cGr zrg227Pb5x5H$h!0*CkqniP-@YT%Qj6{q61TG)>MqxMHkU>tPs<$Kz(be)jzNOcWVz z9IEDE8^=r4ht*L9?bTA|pjm`eorZ2+9;S%kP(3Hq)%}wh&?6Nb3_zAlSX~I_uo{9@ zhzyU%8)0cI(n)0m^VMbWA8RH~1=p5pGjFKh9+dxago!FP)xWxdAN&ffEHe?u*r*xY z-@Fg?6p~NLb%2(GyTEtbwq32(tJV7A;_}6d53a7BtyXLJTM#p|cP@DEp`>OKq8eR| z-2?tJPa=fz%JFA9a4t+N^a5h(*$mc#ntYNSDj7Mia1t_>RdZS`Gc|d5k#Or$dA2=5 za>f_K+WTt76xT_plku%2iAM#tKnN2^r6$Z?yof_;4Ci8Ox~A!TY?4|k#_U$Bj=d-G z1RvuI)n8`MCCR)2^ONSZ^<0ZZ4l)J^$e1>RG#L3z;#CNQkX()|tXs zM9G_obD?cJHfCdFb7b+(d+`#y1QF5VZESsN-O$k8D(nLvybZo&mrF2iy%&*TN<%-D zRD{`#oZ}dMnlf?an^1O|k)Emjis8skW|Xs)89EclS2#4PnJ~xJh2UKfNDM^8Y(7Y6 zrD`}EsnVFr@mLPWJdTCfLS*3g$HuKz!8=x?QWPGenpF$VWYr9>M#R!I zp<6d5Btam}AS9!zw>`5HB~~K#5?deJ>f=(>tXR$^jU|mGO{#@FyQYoKc>t~u@z5s` zUyS-ukJ*Myec@fAyU7ljNAid4UfmpD-%WRkfA;$L`Stku+woV| zM60XIm!JO5zxcoW$&j>|d2uD@G>j!B?-k zz4v~-S`qO$jbv2C_j8^>L=5N}uoGq$_(lS5sBN1NW59#BGQ75JbIwMzS+BdU3n5gM z_DsZx7~V`+AQcPP2#%bK5Q7Z~5`-s0hJ(a}Je*a*RnNGVa)MHQ5pEVLfo2&BcC+Ov zScxcT-_?|-vMBYDN_*jIOM#cbIF5ban;G&FIOkv(A~T%M(RO_!W`=|$f)7ZJ#Vj#K zHFd70HG##dzQTh8r)kL`_{%^I!|?9<`t|GAL=-}J_wL>Cc-(F;cDr3s{ov)xwyp7Z zh~N{Ewr$RtDtVFN!9eT-R8@6BXp!ZIIInNQ*@D)GEHA4GeegT#&N&T(;!+>-&0YtLS1M-xOnmLCm+82PPe*Z z7n!2rv}ER3S<~@wcX$1+Kip0IZGXHQhM}KwAy2M}UAKMqvRyqh*P8dqoU&Jr5`&Kx zT#A%JKCH@ZYwudUjpeo28{J>$-Lb#zhug6niO)eJeB#dsXcG-*8< z5)&=SIEaYyRNx^Gz$FNK5I7*FA(NGNa z8;}+Xp1amvJ!`s^cb?&@EW#p)gPNxXRD*?ybGE6NlEkiSyT%6}yc>pN>XQ(qWQMGu zMB+KNK~?vMp%mS2yH(pv!!RDF<9^6PcI=|}&LmG-62+zoZF3yP!(kZ46r8_)yPHyV zrM&CQWV|2r-J$FTPKAo{p-=bs``sapi4R4mYzYA5Oa%f-p*A+gq-6i(pZ>G|=l}cv zH4MY&UwrZG`3HcYC9~Cb)3u%V4s%dc$7vLCC1>YCXc}nIODXW40D4VI$vf9HfCH*| zBU#uHtQBTRI1Hj|1|>nAWmNzod2z%9m6vLnrYWW5omW+znd{7`;6GEh_d?LHYpQ6{ zwJ8_XA_B^T%q#*?q^KhM%Uop9CDth>IDZq=2F|;go7e&?S3QDFRTW_E^SV_4PkZOO zt}CUO5gSAqQlz;@3r0j0=A;xYB~N3T(&$4Bu|a2Y%ES}`Y)_n0o~DV&ysyy{h`5Q{8K=ob@0^>aq^3wM%+Lwtd`8CcZip#BYyo_1D{O&t&LJXnb`q%! ztZs0?ozxK`f+47ubMS?QL8GqwfBf5jyZrXot$dX*@f#O3$1@*8272#(2mr8eVr*h; zLyTR!TCLVy*R58orfFhq09y;S6*CkMOOa(sJrHTIJs(u7yXlc&cwWve6lic!RY3+P zc$cGXj1nF+J4o^aVd7yq2@}iH>(WCx+ZR+<<%6&FXtI1=6b}zS<8L1C(-Z3G)uC9P zdCsxsUg7ny38b#^`4$mzPEE6xl#`OV5M0yx&`NB&&Bb>0XfB#=8@kS1Bo5BS7~`sK+NQbMya=(4O&4QZjERGB z2%!nid$NYdj_#w~1bgl5EsgJN*yp~V_S1Ms<00okQ_`tu&Z-6Bc^tfWFFptnA@{;^ z?m{FMPNJe*r8a}Uix2}6goEec#W{|Vo5qRb*gzS^Or)gFkvMiiLgSogBTmVt!Hz>7 z`joQfY%$7q+dR8$E-u?{9erRQ*!${h2#^xw7DL_+Et*Ellc_R$AKNxG9kUm9T5w@i ziWBzYBC&HJu2$=&T@gtsT2#qo7^dT4Jnp99SadYX?9Gw7VqQYyVlyT?jCnF53CBrq z_xa|S?D!y`O9VzJ=@I?@c})tmNMgB%rXkxS4D_)7{=rAFbq>li3o@O2r~%URx>z%;58Qt1Np9L zn`(Ly!K@t*hy8w^awapNPah74l%}?6_WMKA#O?MXM#Qhy7nliGmF@6|;doqk;rZi0$x*EqJT<0CgM;<9 zZXq)*L`tR5G*n-PQfwNPm}A?lwwrFf2{D$Urj({^g}e(?NH}=$jww3!PAupC{y6N8 zQ$Ia{nEcjtUp7^;gprC8JR z`Zs1aKukb0tyVQprm%kl$z*A5*?mhf%tYnLRg;HRVr03LoD;TK(K2TnsF)K_IV_tG z+wpuyKYHBq+3cj5sC_W-=?C>8{nsRIMpVPUYlWre@?lETG)|=y_=k!hiw6-=jExB6 z6(C>K^npw{rzxeJa#8i-Vr(!c&;~8qh}zHt@`dxdUoIk7_ z`DFYzDd*k&t0-U9J_Ohb0#b@_MG=8daxL?mo!@o-l}>By{n4)?B+4u%p5&4<{lNKt zIDM?Q-~r3!v*&-MX5!)X+JVz5{0+-jEtU71onLx+;)4y3c9wNqr3DPjjKf)qV*7dT z+qQ|p0|`5&e0R6kqHXL}>-BoOZMrTrO}pJ*zIfTKFPv|aaw=8|6|Lt?46G14k)~~9 z^u%oJh+I)tm6X-kuhv^}K6o$Q2Oor)OdIbS=K>ecBb5VFZ`>)OyZ5umH8LjXSFnG&X$J4#zifsqS=}t7u)9Q0%=fP3_?WXl#rK56`B%c0HK@}%g2;hWW8=T z7n{}PMOd$$52~hF$HRCy^uuwS#uS{7A$Va&n)>PfdbhhijE6}_Wwl|KkB8jva(^h} zu?#~w^m#Xxec|5ZShy#@SGOxNQuou(?tlJe|BKhhU%pF!{;T}Ob^67-d^1=g9*Yf$ zra}eD)|iS>AyOujnn%Wn#5)$rS!0Z5_Ip46y+8TafAad(>u$9QF^UtwEW$~!riviS zIq!D6oO6sZgrM1+2p}l5W;dO8xCn?h#DZl>FFbxRCJg5v(>6=nx=_Ow_0tt+x2?AUT?atTQEQ7 z*F2LQMT7+!0>?6Il&kOLGA!Wg{m?^SfTu&GNNtpedRuo<`b%vQpZOX~WeDDxb z%*@D20XTPsvORm*DnXnJ6X=o%4r%l1J$o-+go$OL(6<&Q{_Vf}_h@1+^fkQU$@1{_ zQ~8>o-Y>u1%1>5!|KfT7&t7QWCi5yF5rl9exTo3+2@ZMnI-;bPKRbgAdusF_Co!Y^$QUe{kfUrRNi~U($0BVetN&c`wQm0okwjxtURkFs>shq z2qY6TGPncGZ-ZqnEaIH1P186{2`*a90&8*;+jh0tY%iLobusv^YgU`kZk%t~M`On> zxEOs5DJc=qJ{Zw52=oybSUi)9ab@IE(J|%y;phSmDvpV~uwxCP(HBpXr{tx0Pu>R~ z+;Mk2?ECw>aX4gWY=t#xnqdFt;KT|LM2M;vWDPq+WCz0T;U{NGaLB@tX|5<_&T)w1 zoq##nJSkdz^q81^aNfC+HI2mzX|^;fAUwU}=s7livySVoX&PU0$|(=SIE+&%iX`c! zSSgy5m15pY*M$%qv&87Tu8nOYF>q{*s6X_(cX#*icKe%szaNKV5*9K}L%O@!zj}3Z ze{&p%Gz~?wG5Nz?8V)v&HjUa3dK`6k)P3eDw4=n^i9f#?fA;15pM81%AAkD#KmF;O zpZ)UqvsdL;d%MrHFEkpBMt!D9sSp{&2qK)pu^*L)O%U@*Oe`*h;JhEFv|exif7NK zw1*a!5Q!QjX*O>?s*(`l^^B=HS5}>-*|{*W9FS&>j36fwl=Zcd^ZqlJk|9jwoZF^_ z8raPNuHN~Src$zqjMFrZ!!RDrv}roD4CAyD5$DKEwGi>_t$89-W~Qa2l+4VD18xvr z4kLIt9`9~%yRQ4_!;i!{w2ZOp+P3Su!{Ja$Zkl!h-$aZF;6$DCrx=zq3OUog`WYG# zEoJEY{@6nY<-Lb16BH!C88KC6frNy!f|>0P`(Ye0EXYY%#ZWcCkuf<;>GH%XK|n<* z0$n(Glv{!Wq|VyubW4OxQD+l%`fyIw&nhr96JHt4QCHR3-}_wTYs!24<<~C1*5kgh zd{t{tUB{J~hdro(?X^_+nu2>z)!rZd_dma1&Zc;l10LS;J|lln=8BJ=@}L7>(ZKTP zCm-?k-F{T+Krlb*@Y!c3Vlq|`t67);u2=mPvPD(Nu&Jh;bIw+b#d#N*ypPRxd)ciw zq3v93+x6OowkVSe#-7BJIAb9QA5{}D6jxSq{6Xh5H-TFyqy)0A^6S=AJLkC6$Y z6oV=Pwqzpm6&0JsF`~@iiHW6wT*RuTN(i)MVJ&ccs~9z=CPZGud5K<{#z*g*7bX*d z6?}1+#|+goP!oOI1n*(^7f^hpy&9+K{${s(w;S(=G-WpSE;J#M$@qiK)S$ zhF4x3`UEIOz;-O9lni?Wa9S}twpcZ6@x0ViL$mL3rK__!!-&A=a?UwrXt}E-G5bR- zc*)CodY+&YVaX}0DvW`HpiP(9x{JmW;;WG_Rcp=pznW%HY43VNAhQncBN@?46MkD1@h>ck_bc+nbfXEh|$pIw4QgSW|{tr|Sak4~& zR%Hp^#Nm#48P5grgpeVY>&tXAPSJB&mcVZ=Oe_!n`tta;xje;yzOp=S6s5lJgMwB5 z`07`5<1{p9A0Cy*_Ylvn2~SoyzxCHHPu~Bq{Zo0b+Dt?qPUO>-&uk`->emYA_r5n% z4;!o9e*fR|Uzc*eaNi&NC*_j4O$O^Cf{~T0FafJ8j(Eh&38=0yBUQ^OtCDlU``EN? zY&#PPP1~$CA++LR2%Yz>bHT(FwXA9;#3!6l5vfNN5&^13Xv78Qqw`)(Sp)=7n7okV zEN(Au$DElQaSUPOo9EnI25xen_jmW{cofaviicYmBqAl}5V1zZjG0p^Q`S;2!3=-Q zjD+PgQLl<9VPErWRL~JJ_`5lBVnlg{^ed*Nz&uZ;2FDUoGb6|3orK_mmzsLe6FXx^ zWLC5e3C0?JUPJ`&L1Q)|=S9RBb1^PThr@7veV_JI88R6~ADlSnLQx)ue776#chfNF zFxlOHy4_8?ecm1T{@!j5`L5Udz8oews(X7VpS?Z){Ppht`0V=6KEMC$&Gf4qeRr@i zQzpv9g}JcP+Sl2O{#-3LuMw1bv=#_w2Ho;@)%Azt|NO81)sKJtyNAO8X7b>@sil-$ z@W`6M49Yn>>N$Z2B?N@}+gz%3qw?a)j!)lk>A@DTMIdwD3*fhfvG~yS<;EFWzOIJz z=gx*s77^j<_J|EOd+^tE8>%(8#kqd|tW|;pM2jea{di6~W-m@7D9WpG=A5)tzOAKX z0BXZzT>o44J~QLHDlp(AHW3kz2yazYI9-(8+rJbn*0IseAr*`23_W@n{fE<;fqOyodtn?Jx27M9cH2KK`4huTJ6l zhxx`QT6@1dy6fAQ<%wTan3rSJuTka`*TRf|u>7!-7_8;>pX|o`VvnysB}_ajUnK#2 zeR*;uA2nsmKg2{b>mCXEpDI_J2HkLTo~8jKuj6W7jmRwp}&t z+J~0em7*z?qRJvUWnhhncQX(*tXGblR}m!`xi|)wQZ8DE)H(4^*cFx?^MQzsf?A`p zcK$-7GnK>j-QC-_>9BJpxl&l6ttKM&-ZjySz-ms;aZxzM6A^)1!(_uu3^780f6C5@ z_X1c+5vV8xkw$RC?}wa~iorA7U>7gd1*5J%VRl}eV=@xY&Ix-K&&H%|%BDgptTmIB z7~s-~3HY!?&IMypVEBSey~5F%ucJO*0O|Pk!=~AO7%1MfKw1Vzt>Y(KwD-3(v$Fd;*dLASP=T zY0zL1W}(^J2rLDtPb=zMkO}2-IN}ymAgbr78oR9b{487PSMk z3MoMdpei|4`2_EchN_Ci3@Uo(ou552PAVL@?clx6bqPyZ3^x!aFknFSUh<60N`7E> zGJJ0eRID)y!epG)veKbXW48OzK6}^y>ZX5lpN=`aJJ6T6)9W35{%-o^_4N7m z@mIIw=eOz0o9UO={pWYXt9^cVv_5k-1loXaS5bk%+#v6<$+^+1DkWxPf88|oCk8WA zQ`O-(Fmr6qnx=jjkO{h!qNYVl(E^N<#i3_8@q;VCki^7j8Mp#< zX`e0dWx=2Es#1!koN_KXW#q<$4aGUDIZ{ju-+-g$=v zU@7OSW3L`Y70{{nmboh9u(hz0%*aTD9il|VLu3Q)eAgw^i2) zsuTt=5A&5%gY#47Vg|T$W=<*f$Kz_fcFvWQttjLaaC(qmnPu1NqXyOB{IW#kf=?+y zD7?A3i7~Fa4w4P@VKGGKW{Fl6;01( z%gij~oWT37o^Z_&m|E>4!rRN{;%asIY~8Gz!b*;*DkRK=O++L(g) z%@I3Q8i&M8rO+{HKiOpNFzL-9eQ`T|elxwQPO^0kS7J;P>e%@jm0B5NRo!~AaHyzlw(EcT zPyeT;X^wrr*=|H6=d5PA6p&!Fg7z@Ec zh@_PIzSlW@_G0Z`PR3_4ETab|XRclYM)n{fno zmS3$_rr5r}uILh$0mRJEMkbkHvF z%gbyZ1tB*DR-7RS)&aY{vcI|xMYx_$Amg3W-&$c-lGR@!ot&;LYx2C>)565re0_6y zeCuyi9yj{ym&Yv!Yt1w03XcId*%F=uPNU~n3%UZJ*fM* zU$s2m`b0~^k9N_cad`5Lo_N4FjqQ0k*OY*05E+rqaMDJE*!GhZzdBCTjX9UELwma1c?Rz5*bhgL@1Y3 zN-{F<>cLb*)MT1?7>Wp|+)vZpba?x#pa19a@YbfC_5GS%ON|a?f9QuPEtm%-Yf8Dy zUR2_kakk?+GMLXAxr0STRI;+nYG|TdG$CSBkO&>|DNxhY@KNI$7*LAktTij8FgxB{ zwcV!a)~yRJlM*{-DMr}{jNFGVga)B^rc{cKDW_yck_+WRg`K!qOpeEC%(ff#W}mK) z`L5SP=Idkm{CfD+&Gc?xUfuMsZiiQQ>D^B6r*bpcUhQZ!G9{r=Xktnv#-1QUu;`qi z9+NRIlGCE9WSXFssK3s-0j`QYhDcVg0WegFavJ~7|KeZ#=tn=gzPY}*xCk+VF5?(_ z4zaxK3pM!X;IWG(q#FL0`b2mVc;r7 zX_<(KDu-JFA5L@wH^YsTEa!|!lSP<-0t5P3+y`yJdyl9M&RWU25SN^D&Q;DMCOcWI z&Kue7cGEOD5kze~X!@+o?Fuu{#rW?2?q@&yb0WIBx`K|c>$*kvzzbMerN^^pZk0g^ z5D@@Y$9e#bA|e>7P|RpfLrOdck-{ApgJPIMKvq;oS0KS&OXqQbGS zqQ(5Cr&ktGm(%qbIPG!GWi#U9R|ylpMtM^8f%YF?{WgVoUQ3IB`Wu#Wx-)mR_6i@* zE+3MKQr)gZaGKYmnwco)$+U>$ z;N5z?Uai+Yc+)Z*kGtJ{O36D8!87smXIJah+KJCOr!+y+$W-Iw=09aZ&sD9M=DL2k zT6o84+V96eZ2C;#}L{NwxmZoOU;Q_3kJ(<8Hp%x3k<0nMzg zPUOLw5J;3uKG`EmDf|6iRlBxjUbOj-X+bHP!E3$GIj3m~K6G6-2NA$9@j#e>bU0`6 z&O|j~5O@!R*UkC-YG;WMr39Z1tXtEnDX&As(1wA&%?f!kgC8_V(5$6^|1WF`m7k&I z2Sg9X5QXwa*x?bC?#x43MF)lxpfFWo;tXOK4Wa|=yr18w(#5JEIzMgAD+4hdFy=wl zgdYYxRL~E=hj{PXu3Nk@X3AfmzPwZwCB(5vDY`#kio4Br6WgX}LDbIN4FKp>VbpNa znFkY=mn9pV^9W9xgQD$;j>l2L}VvQLkQ@@9a=Z2DI1QaCoGyd{vOj@-QBfl$xK>Gc1&Hc?W?c}4iHJEi5*l$xLEf-< zf$D?2NQmr0RyGpx(fP*tHf1UROi<2~_Wg7?OygKoITtD_Q|9B4cZX>|aKrvH{9&?n8Tz#5u5YooH7?O=PP^*rd*kb$<7Vmnk!Yv}9(a!!pG%g$o8frAKm8B|VSqcu{i4S8#CVpYbuLTy&WngF8YWeJcYS?*bJMN5moHy>?^4Qe^*D>tbTyb$ zwWwymww(0`+9WdqPFg7?rv#4{IEo@<7P&ukPMvzrQgxQvh-i5nlBS|3CnUR*HsT3k zV&RGPRcG<^{PpYBIek9O;Aw3zKM7j(TPw@z`4;6Q3eB^|PtNPFU6>v%;(Gb)VPDbB z)78f}eM70WK@A>U`c2AASMm8_nfLQdF3*3OE8t62OfJ7ZBvtR-{kS|PZQr_7f?J8s zqecwSH_X)+Y_1NigBj~AYE-El0!BTvgIq#|55UMiUL?A;>mJmwVRg_tk)U1#eHO*;csi#UICNd+-+7HvcY9SNHUd(CI z)KAkf-@U!Qd;7+Q-j0X<_I5n(av5{UDd#k)DQU5+R@8E~5F|z)qGPInKbncOdfj7o z02YiDg%HP_OHmWYNbuo<^FhRm_Y$M?UW`m3l+7dV1B(}N#Ev=cFu z4yrB{&c&uFn*oPA4P%~`Wme|`J&FK*xM^KK}w@6zod zA4Z$9BMHXL;>0`g;=OO2kKP66qL6bEz4#!`5ea4(+9`$3Vu|u0nuB>C%Ifb46U$}j zH$e`un0R(o5hMGPfBk>mZa2fwhZuYeMawvjHCMQZ6IU(nYE}=Il~RERFLVp_uWzpV zzHgg$v)w>xQA$xQMm2s?L~>3kB^*YlaqRnEwQSZK=UmA(_XL>M+54R+IC@pXMvTCQ zA(0r|WdQjGHv$L~SO%&&=W!hRet;GPv5qywXdc3aZi9o)#DnVlGB4C%{`Ub{T;v00 zt}cV6)KC`H#U3;>dmI*!y3J5+TThEy`d1+ zJQpTvc|w?2emfh4`9h^UkA7NM2d=w+`|tk!^7CIosayG*{!X(v%ir{nF8qe&!P0oI zETi*C2{8*9k1Btwzoq=9{P#h5pp1A=GjU?`k2`xdbPE1_W-`TH3xBWP2wz#=^I!Tk z%9$|npi}c2U4)2*be?*4(ma?!5MKb4X5?vNsxJDb#Z*;`X^Am(U3c~DS&YqiJX~MD zI~?{?nzWQT1rZaIlRy>7m}=M+;x`Do$wFGJWGb1pq+xWzj?`2uZ8J@|pGr^0CEKc9 z2iFJ*C0aM@w_kku>hoWu{chav?ys-Mu`ilRQ8E^RFGMAh(_}G9+Xmo*gLRbx=t5#7 z_c9Wq`3gH>E0(6h#6j526@*R6#B7GmtzKPJ@xIJ^XKa;4Ga+fX3nDC#hloUrm8|2C zr!nEAJ`Piwa?WL(@{~0dP9}Zg<7CIt?t48XOVWMz?)cNsu3x?FMeV$zS< zn6lJ0%D<=mbMd5|-^| zyWMUPa8YupiU~u=31(cTY05cyA4)0xFpT3sL>HS2A_8Walj=iodc6nak#Wv0r6A8W zj@LQo1!n>f2t)))pn^P*0Z1dIsc9Ob%J6bZ3OKBp!JM9mXCdfuhQU~N@%cEPQ*Y?_ zh~QJS;2W?Ot=L>8V`>4k#lqhE7-B`sn2j}{1V<0F_ZH?#(3^I zh;U5^6Q#Ps$U;xfiROd1J}al55HV3H<@WAQoczI0e)8h^i=5JG)v0R9#XAp|QbcM% za$4vcz_h({-g|hHh)9}}6IYYO=9&!MJ7+{W=NkP*l%dC(g*nW~OwM_>%#x`dk9`$K z7V#D{@a=?&S^lUOQR-yO!o+fY{`z3t+`s>K|MmwK)AET?BY*qo=&4+q+2Ham0FDh$*Q zIC+6?EH-Df28Vbi2K+KC4hT^L6Fo0W-$1sO{?x}lRnEPfjEYq!N}TDG@Zi~qJRj+* z6$^FDbTMEMk=5wG<>jk4gBiXP&qfn9HA6C9Ev9Pff@|6)=X`g6d%wFIry-|=EI}?f z7l02WM6AV_SO{pFYHGoICzR7jR;*0@{kwj5BYDinL+<-DjAgYD#2E)2Jz_bL^Z$upnR$ zeRP{m7h{o(F79{W7?ntP&TIp`LiA8kL;yT05fvS!Qc52(8; z@oJ#WfBB2IuiqT^$80A1W7+RBku+^%L{l2slk>i4fv;;yqYt65s+MlmrJR_p>*A_w z+vvN-2Tw7OcP32Y$T@N{M`#eu!~wG>BtnkaIfKKh6J8Q8gPID9gDydWxZs0xqIvqk z_kZU*pM0`A?Axy0Y_`O%6dlGX=Pbm+(zFe@5mJo{krPI2yeDEQL1?jnNKBFou zL(5}?6o%N?QX>_d5yjBN7>E?1(0Cn!KZKbGWRI#df~RoZsSFwK)L~EzCUQ)e3K52& zgIpWP9uh-59*@qs;OA`2(2mSb9C#2W8S0@bj)|MynoJ2hUj^uxGao(g4?Z9j_hLU= z#&)4~%ZDcmGsD2ycI~t0&%3T8B0!Qr#v~TRg2fQcjG)&+_bV^2fvGiw*bLa`fcUDJ z=)EUqAfm!DG6#Q2F1p=pQp$6zFMzWMr>&H8PKiYXI9(3e#+|Fn16n8#M{;IbOi2O< zS%y3LG8C1cEIJ-Y&GSes0>|Uwa{un%J>fI)HN*N;d7|C-%Xyo%(+_@sqCCyGemmu_ zvhBZI`6`C}sL%G^2);j_%azlnSzMr(&x`irB>U51#av{F<(5ZlWBK*0!uij*G~Z=s z^pT7fhdMK}YFh>!IW=Ha*rDoa2rGx7!wM-~%`}^8O(fq$=iHQraqP!wETu5jG4KJg z-y~8kuf#;eRS~R($h4HPKMuq3`pYlA`0VGezxeFt-J3l0!{N{$j?*-;6UaSkLhOjd zv2Q{XLui_&joyom$GgM*o7C^LB&fS9k8_TltNcKLb|=mOMXII%h0qneG~Pw;y@=+b zxv~>P*&&P$Zef0Qg8q7q^$I&BZE4FNJcSreWIO z54Z0Q_qT_`VeE%#NYio5_lI$R$j8YFHPUST_C?sf9H~8IpJd%!e01^h`_Df7!S{af zw?6sKkG}uIAOF$c`3HaS2Y+j|>Pk@~^4^gnBQB=n)K4in=X?lbPQ%z|RbwMoVZ_Q4 znTn}razc*HIrfer1O_j`O9(CmN5o~pIH-b|&MGA(_y{0xddZ;I_#-W**>cIny2kzR zcYnZS;@susGa^bkr3t5e$4pa7h+y;{v>4tM!~~~2sgg8;CQS)$bc-0{9Gnbik%QsH zKt{+&+%`>Y8t;KzQgtT```>$I){WGygrhvv?=0+{KLJdgZRDjeu@j(C_!uMf{IKq! zw~K_f6zpsGVa!gx46B6BP7Dt#tEtwvIHNlCQ}u{6@JKD%bschS;z3ZN%#LoxELih3 z2e*R{Wd(0w=2CLX308npiqDmvD(>I^`zL%R9@m=7<9f_>j_}XJzem;4!kK=s zo->~OL&0i2@4#=XJm}dsmETzMV9eNG;uX%E7GXt(M1GPu>RutLlmD=s%O%SeGP1=* ztMdAX%=^jDOF4g?N&+5Md+@sT0rOpU+TOFeuIg+Qopo4~Zy&`;Nr5p*k?!vP(Iq8a z(lI(lBi%zn=^CIQAYIZW-2>^6?k?$ipO^j1wQ*fMyYFwD^EqR=f{j1*%pAGjp$uid zWVZ9Z{u~d?497mbTeO1!M#I9Nge+L*n5Fkous>>amOsL0QDDD; z#4PB!Ec+1Hi<7<|Ze}LpCDxzD2Cd!p`BPa;~U_?_*@slqY#&%0t_U`15`*gYyv@|_l*Ia(vaI54b}!BUOR zD$~b@0bQwAD;Q>YTT7m4G}Lds(d5|kiD=H`ZFpn;R7yhh`F%s@!t0x8PYRt>oQI*- ztpa|>&W?cRKR1=8K{tIqK{w$af=~TBZ+wDZTwi*=bX;yiowraCct3diRVUd>aldGpA02ZnhPvD!3Y+xD&K_Y0sbMsiucN)h!r1(I}Oa z8bL?(unj>J4w{+U29mj&Kn%m5$IHdnAKz#r$c9g>jFDIt3drfY3Bd>TPtzmoRz}3~| zmF2cTvFibXM{oZ>zntwXry4kWyUSHI{A;T(IbV_F<97`ZEcVBwK83%#apz(^+i-l-H!}oQ zPFX3FW%@#;Ln4=zuV%mtsvK&t$T1#_^)+EkvC}psaNwMvbDZ;Lflu!HCb)AV|A>)_nXX?=d8g^BAr1qRK10>ky0kVWx1d6o*gP>p$QYg6u8y(w!%zCgvWCOzP-g4Cna_R#3$hz;} z1zrIo(QYZeVy@sD+*TQMKxm$H(=QeC5>xvk zH=LLxE6hVKd&NItKQ(2NawNRDwg3KZwaHFH-TEYv-fb4&Sn{D!REzyo3vrKSHhe(f z5F!5g8$h~rI3nk-(~C=iDaG1b(1F~$9!Nca1gk(v3Xom2Ip5ZWv@#PhB#o3#=G8PV z7Ouzp?rz4-3H(4Vx%8#6x{;BY($I+JRAmsct`vTHmG^pF7Q#QEgCd4Qzw3CwVGa(gHl$bHLVr)9pMFNGM)&qLT6pZw z=^q1UbI>V%Zty9-S-_2J;O%l};Q2-L@yyM}wN>Zy&)Zmuhd|exf$lNL!()$&hwk7L z!l!d!V{mUfn(FCHvGZZbN5Xkgcd8<{^VYn6!KE=hU4LBS{x%t3^4`uL>gVSLg*FG? ztw)cWiJMgci~V||`i=R~e&CK&6;)$UQ?M-E>T8pwH_;XJWm@6+NHb={IHqlGlQ) z03uVkKS53Ax~0O)Q@ioN)fx_PVQ52CY=^GR+YC$HP%yGuY7vjfX=ZPEzUF`PA$#{EhI)r&t@Vwy z)qmzq6_yN8-p-<3OHlccCX|&NHT?%5Hh~hWg->N*G=kj;hQHUKVmcX0#IAK}o~_Hj z)XFzhmfzIvH;{)~?=R6=2wY2q`*Bnz{bo{z~8P-7kew54- zoEb?P%7mQwPc@0TMHPD?y~^|*-arbY6*i6Vsjfh8NTa$419gs)t_Za{Q$OHlWB1s| zc(>x;zai!^RF2c!@!-z)=Y^mf%|P|(W@-AljP*;}K=7FR^WM~MGVmRc>U4?7P`5@O z*>o%mez*uKA22*)?BMj=`TJu3oVu0}7!;~5sKbx;2^;6jOx?gFb0${o z$?uTM&&2wE3doyWUTqg!G1=YJj85dO(PCvNffT~WaO$N6553zH)W8OVigOJe_A*OR zMUKX9a&VQ*B5^gpu$ahZYxMqigUF1a-+CG(U}=20!uk31^$d?mIGdZiVD_{^p=LeR zh{fpBkN19-s~*3+r%XG5s-*o(#{)**^Vye5iM#f(fzCOJhoHKrc^@kGOZM|m8x2Y- zK{l1^6E%!NTf2Q1S7VG|U!)t0j z3Li#E=M9b!_$KjAWvO*7+=o&$Ns$v?To7C@1DIV^aCb{ws|jfE+h@M^+#AcF^D7zo ztcJJ8`5;FKCQRcvm%iYi!$$pfw^A4=IydAa%4~4RS=o0AsaphgomADPemTDtH{YLG z;Y&i;p4U~6^X**j?c=NDRBab$exDS<>KhytnjXrz>No}2LR7ni6SS2L$V3Xs1y}=6 zs96j|qA*thRqW2#TkY30rNn^t>Gd>L;ZFy$0Z^=k`nwR-UlLKm5Ar%RsBF$Bc*tQ# zng&OxE?RRO9q`HkH9v~*e{WOjnnE$QYa$dp4=6x7cxJk8Rk`D|3HcMOyVJaXKXJ8Xb5gj5vkC1K# zfSem4I|HLdx}l1rMaIf5*$s~RrW^cQOWD~=0IA>Y%(#sY#3sr@#K5XhV#mYFyAf({ z&dW2I67FH*WJGlW#7&*9ysPR|^%2@XkvP4#2yR?kXoF!R5K<_(tczWEp*aU6@=bM09gN^zkLL&=}s=k&f`>QPy(GA3-bFC z`|O**d-G~v`q;IfSmTs*vIyec9SzKU2M0q{*kzhoP*_Uc(y<_b%&RXgRi>pKX5h)Z z%#9gCkbO8t@)f&~UK_SFqo&|5mm;oO?1pZ>zO zlD-Vkfkk#>XM0O|dRZlTvVpzUwvIa_jo|Uw_xAB}oQsoF@^&q}XML^BacNd3w9!PF zGD=#vubHu*^yBUt-sVz6&(UvZuUS?2id}-U==++lJ22MEzFozt>VTlyN8$*qr_X#R z-Molk)BEcP`mSHXgX=4ug5AAUGoehZ*)wYA&sVPZ0oS0RV)gX$ERi(X(Qu|wv+{%; z;1)U+)y%B&>v9MQP&#rD^YA+@PTsOsp{h_OwEe)xr_I3ZG={rl4NrurR(vHRWZj4( zg!4%$rE0lD)(HZp8q}O*z?PW({J1^b2`p+NO!IXng-083I!ImIZkExX?p`;<#|pir ztJziv#l`X%@RPmyoWR~kT?2(Q=la#-ZW@%P_a~NP2(@>Vawl1MsQ?Z~+ndxtkm zRrFvYaXkh7O9iOUw)pLp)t#4HMsy9lo)2nyMmFX#@H7QU#`Vzp?fxE(t;eVy zlsF|=AR^WU*dV$$rJfB6x)2|jc3@`#rd%Uyro}@`vzsE!#=u9EMlkQc`s;9{%)8yh zOu{j*-8lI6-PPf|>3vhGo3x974a-I^x_81F^{^7kdjN2<0Gp5TwUsmC{b0ZBSrfy( zehN6A*QvXg9ZY0x+*yn=uXW+~{@+h=VCy-Z0yEG#b{L+WgHdV(b5lYO3_|DRI6 z)3kbe6RmZ@uMR-22G-r?cT-AB(=s#Nm3xFs9dMzYt6gro?)zV~l^N7B<9=n3M@n_Y zX4X5yoF6u}V^0HaT3_w~BA&$kzt)$#mz!ek27*@GaY@V?76-K@z#zK{l%KTuR;&8^ zziEPJ%Bj*0@G@2OerR)}3Ky)|7DY0LXLnnL#1+}2`1|(GRKGJ17q&gvK>LJl?yLV^ ze%>G78b^tg9j+zgd!Y3u4MazK@Brj@h&OiAWE8@GSyPD<215Vy)mO*ot(0RRG1xZ{ zzFli8Hk7d>c3VO0oT*aKmydUsPcC_r zI!{_d=HN`mAKCac5e>(3Uu|bFsN}yjXXWtP8X{L69mH`gvdDY`%-;vqqg8&-cWfiB zvKiG(XsG|Hf_}PpZ)$BvHD`fl(Q9-Imd(Hx8*{85N_j?0ot^}?;R7APiLkg-J3V5~ z&h9s7rrU+T8L;xwu`~YN79 z@qfSqWp}@6=K@TUBS7m76xtjWJjXOe?elWR2T|2j^ zchq^RQvXo5(WpX?)`DX4_;~F2YU!c%Fr~lfJo}jSRdH6Vdf^W!c|TMmM_Iz)B(jz+ zCn`6VH&ugwdF7_jM>O7s;u^qIQA`PMr)Upvau?Z8Ysswb{WyQj*)>_J_J#1A|1ye> zbp{|oqG=D=J)RUCWJKV4W7ua<@+Es$OwTJz-YlBVF`teMn;GjA*o_qnJ4Jzr**wv; zN!^O6_(wC73a%nQmjqv3Y%JUEV>S@OcDoVF$Un}R*Xaw@ zRleK*@DjHW^?h~q^u)#G^wg!^x?F=%d2^l$AIS4<{0O?a%zN25xxSvK3cmz)1d`VP zBHPky~9J^~Flw3B8PL$ELrmzg%_}=2NvjZf#sFe5xbb zEwXpgFB^kc$$^YRVFc4i3iTRu;q6T<`|kO+R4Q2sd0NK*?;eZ|3zV?(T$RWof4<{UnfDg0G2Zl>@(x#b8{2@v?9{j-ei~c%FRII z&aO+5XxB1MeuQ65j>3|=4ob?+tAvw0Y2DA)8}+e5kd{(vUtJu@W=#f}nRw@*4@DF7 zsbc#|p5O|b?X^1-hxSW^`bOZwMpX`X=n%h$x-_wl-<&F0&%AiKGhn)AmC!g!_*; zgDQK&I-D;SsrHq1nH@{>;;$(k*w4cjTYY^sV4q;&-NU`|*L2miv$eIEa$rT|pym3) z{g6V$ws6bhXy81fD7*-@cx6~g1gqpLuOYMO$_h}&1pYm~6#h{&XZ(v9Y+qvm?}sYc zyPLM9_y4&}b<82k8U5@r-7u-(^XHeAuc*3q9y1XuWZ~CWQW35rHcs$$dueL^`}#LH zCd_i$f8>m1NIz$~HrWGcOriAS`-_FTFOBJ3v-;!0{F9!Q`!cPy6L_qdR_os=V$o86 z_jXMu)`ECM!h%+L$h0^JEDE{7bpFJ31UL!JNMfD}PdD|xrKx%%?7>ezY>Xd>&zAkL)^4<^dVUqK7}uVtnMYfhtkTyB8F zamE2iioNM0F$=g};Bs|w3A-t)TspmRHSK&q^+qP6Xg{bChbMwS;_lxR)zh9LK+btu z0KD5w!MBYsU6PNIeyhyyrz(q5fXc-z=wFiI^#Cdls?qS>@YQ*iutgrujjD^LB>P+G zkn}zjPo-PR?tgsoVEA?3-{z+YzH`Fw*r>=l>YCoG;0fpyr0NS6E&9KX!7^9Q+-NjW1vylZDanhfEt+HR6<5xsM(N{D=Il z&aD=}G4%GV(yLB~@w0sy4#w|BlcxSp*WbPP$w!yq>GmU-QC)wO6=mz<>gggK%t*{P zU}luT-K1=>TXqlt%W?glY&-DRf?*Q)bIc0_cu}Y$N=4Heob}4Qrs@%5yY0UE)GR-N zz@VBGlqm@j1qIZZB#%^v43S+KYv&~s6O&KTZpdct&CTr{%|SkaPu_bs)<9Cs^P?d+ z5JsDztUfjUrDtV(Wn1FQfcWdKOgbxV7VoF+!^1|`FVTUy0G!2%9(T!x`rKMUbt4Cd zaKY$3{Ju3?sI~Q@;+-X!Q*TUnuBja8ZNJcwOugsGHi$IiXSC5PCH)>LOr};U&%xHr z2*ZE#(M8O@^=c;ejU$-Z&VQ-e=PduJy>eBCcC!s;)DtjM;a z1FBF|a)%l3>ssKA%gLcf&acfE$QLIOH-#D|ggljTe$k0x%uG!hc9>cIYy5JN-YHJu zy(!#JnkVVMle6R^RBEFV`fKJ;8TVFYZw2-Ocm!YHM4|;?2P3xe~-=u1|z=9A=-eU$uiuOG|h?Z@k-z)Qy(G zKq$oin{~6i8F@~UYl1u4SA?8eBi)HJNxPHAq(s<&k-z>!GxV){ z9Ec5@dT;bdR_gl9!y*jU=G(_ooU;7Xj{n`69Dn`l1dpuWV~m$7#%~X(UmfaMODE1F z2r_(?fq){_UfMzQMg0Gq3|JU2>!(rx>RJ)jtAxsr-}BUs8yA0L4vb1IAnkD^Xp&y^ zg)1U4-vc<3%-;han8%+LGHzY9o|Pl9#0>Rv+s^0SFdmrT`z+rfO8)iX%3Vp%ESTgs zczE|pX|!gQ5|=F;$H8D-ABWDUvgGAC6iP*U&JpF9$)(#V?kwFv3Gu1jWpUOI|DSkvaDv5^$-xp5hyS4mwhxV=V5>;8z6?~mh9)Db7ai#X^WK|v5 zsY1^Dd(0#8=81~N<(=9k)AHQF>Y(cYuRB_o%7E5H?=fiMG%>W_>FC7ApI8urN8`;# zCy3XJOnRfb^92`xUO_iMg`TInmGZb&`GRWU=S2qV^q;^e;W>58Kl{buB#dQecQ7!DaP)c zZY7z(0Xus*?dq%lJ!bgOAw-MB%)x}sf&J8#StT_#*m5g`^qHq06CDdw zq3_t%r%L%oEyuJ%iwMS^!5=Q|NhS&D|D->ovtc@kR5K^7VN?Uh-W>`pV(-O5yuoDoFsVruW!Bycy)rh$eD3NLNm)2xvaNeR0Yb;uuPRX0^x~mtsb}KX^^ft8jVhJ9G7`pvrW{?< z$Nz%gS!_JT-roFa$!u)rEbTG!(_@`gSi9!VBOO((_(?pX?0NE`bOvm#5co&y*OsNc zil7#+nqRF}5ftTBMd>|(-ZB78&3FC?;)GEX6_*<7jx82>RH8i6l&&N+$lH7QEjfLCh-A8D(v`QgZ#G@MZ&qvr>C z|CZu>SGO&Y*?cIf1LErAPnGt2dUq{*< z6l_qT&(oVw}lfsmQ-kdkjyvUkgtQX3R<6XcSQvCis$dhR&& z-!-1%r;&@O6;K0P>HHV^x%)o|-p{lw%ot2JF}Yp=ti_n>*ssE*e?shnPMFSDOUBWj z;<=%vH*1%!A2JNKVs0cQ7vgVld?n2bh$TYxq_km_IAFOSfSoaIJ7bH_pW#`waY8aXf0$qmab?ftTDT5jGO%0CL?L{PcQ6nD&^||y(^wY;BK97m^ z*5k8nd>yoLj|^)8SloESC_+TEHrke8-h%F#VEG*athG#@Y#11&h6l`~s`Ea1q1>OB zc1R>9g7odKTnusG1MkCCu)>5D4vwXFgm0FD+@0vD73S!_sl4ZZ!7ne*r%&8%ftNdZ zPnW^Z=ROjKRdbtwc=0c7eNky)ip<&J)nfF#7aOqzWdcj#d~fA3++zxmwOT{E{6Rc3 z`Q*L3aQSk>dVn?>nQ3BT{9o|%q*B7e=JL}M;9gi{?C?Ej@BgZMsF`~A{7lKhVL5eA zI#$XVA33BXr&G3X0b)#>5;vHG>q=XI_8usyq*l|z-X4A%LPY|IC}~K{FF^f^q$q7B04+r5>#+ja^ z%;`|L)j>6?)Z53ca#+uos#Uflf12(gdi`|n+t$(Xe3YIS_8N*O;v~=cPJq z>A+B|shh(M79-{gRjoB*75pJX7;qG@)N#9KQ`c_nT(xnXlznw@aksO8q2{x_(J#Pe zKT9m?6`w>xVr5)&*~=+dR?>;Z%sWPQH^Z+CUY`@hanyGje^LnK|hB0_?pp zxPost(>oucsh*!DeXqkipN^)efPS^TI%r>rYVd$eV2RdbN7#^^@H2m8!Dk_2bK|Zo z9ck%NgR%=$G7zg9G7gRyh(ME$RE%IzNRb7Tx#921kvl?_enSQ(j3&F-_no+0L$0@( zzmOm&F*T{RL7p4{%j4|Amt0JgMJTSvb4>zo{8yj;`EW#5=AFY+7umT4-dAB}na#zlhZ1kK=6dSk9 zux|gmKK@AC`pLU~(dnD>t4`OYSrLq`hBuKu^m|-RulX2dY(z%1Q0I(q$#6pPk!?}% zGVsS?8YnZw-@Zy|D@}*xpi^OjLZP9VeIj%68D)!iEClIee3#t*5Sp!Ik{{z#@*hod zr4XlV4 z6y%G&f0V1o(N~`gDHZ7geVNXPG0_sG{DQ&O7o#Hb4)5XIS5-vuw6)<%LUn3yzN%%$ zp`Bp^N;=l$+*;(E)sRfO;13q0@h9CXxD^A%8ba5Yb-}Pg?^FZ{?&nljtdMNYsuLYi2)E{JsY{LcO zfhqA97F$r~fgTA7iGpA}ScXHn;o-p_1l(u44}~d7mnrU+5INJWl=SZgxA&?Ph`|vu zHw}RjxHLKpR?W_e+@^%c{Ap}v_OcH&K^C1aV!{7>I5|0go6&e@I4F}TnaRPmIGeYU z)?Z5jF&d$;h9&2vUo6E%F*B_f|K;n{lN+6LM>sk-ohL-rGn;?+3ql7JQ3EkN)Jrhp zcl{s>7Nt|X^~*Rk7S$g(kzLH0JP{emY)EyP$2a~z5ZE-ov#P~)bn8>bgYHxqTbkPD zof>G+=$S?Ay~zxB&h6M3#CBsG(uVUL6x7iq*jD^c>G-~E`ifJ`W~(`GS+Ix{V`s|p zEgBymZ+yTu1n4B+=9O4b+kQ~s4LmFdvH%*@x7LbyJpGIfD}Lr?-ITjU-&gXmuT z2c36%Nd8>!G9(EuY5#O1U;c>q<;~i(D6xE4#RRWv1hsbe8oH!v-%%N6gkTi_gWRfL zKgx~x9Ru+x`vX>~ZVKO6AVlJ2CF2Wh^%-2xAC_0*vWkG<2HHyND~a;CrH12genpHM z$h5Raa&3T=F5VYjWDj89#W`+O5v}mz=lRozO<;j|C{%?%u$iL0N~Nt#6BRqQ0|@iP zTU+K$`ODFtDHzx?u`Vym%EmrvyB(kr*VuZ~B0wxXwI;>76!HzQs!{fhQ3OT=ye!R# z(V2O>XZhr0=VZs3ZZsjxig-w&(mwErzJarW@Z)v-dwpiTEu?RXDF&QHHINR;D; za;gYDyc*D#-{g~Srhxe$P3B^R`JyV?1^Hd~?6b7gSMC}P;l3JvzF#@kUrFf#QcWVb z-FSsLA_l*HyXX0YhL)f?xyGMD0#Mlu zxQ-Z(=j!S*z;9w|YHBQTiRki=CU(XK5s)Yk(RO!lLJg|sc%o9=?Zh9CW9D1Ut*JLc zcyT2%psP2de;bZ@+uZ1s?6ugGB)cA|kC{T)rT1xu7LF{NV0gb3#D}P^*7hOa6S)Bx z;p?8Y|H=-IkC)HgjO!~rTeu&wccSA6xscMbor8#P-=VV za;9Z`4!z8%rDmJ_J7x3kwI2I;iyFx@lizK!5R)^h#6MPyTwZnT9Fq4=3M@9d@^4rx zvoq7WW7Vx@VZzo&I%6VK_!zVfSw+XJT3ha?e{aFP1gxTV#sn5T@m8=ut!wZPBJc1A z6gz&692cb_M}5$-VSq$smZV%>N%c0{Ay{@TAtJ@gE}cuqMesHc$GOzyLm_2)@)Ix5)TIs+;+Z>~h2jN2E^kmFL`$^?H z|12wA2!u0X+%?3J(Gi4iYsgTOglW<_$#`OYczn%X|CAG9Fkb*Avc@Dge5`kVi(2a- zhn1VN2J{jf>~9?)MFP`r-J@VIW=+jys_RC8yR%75jI{0~+5PWI!7KsJka zdjvsN(fNu97xra137tbDfNnmSJ%rTTHv+jchpk?AdL4%Ek9vg|5e^Ekddvwo|Nbl* zR%NG8IP4_y_xBDkZ}QXc0r%X=x#<<N`Ov(I zK$+DU;hX!tkx@ULu%3%-JFa|W4xynf3yNIXJ=m9#tGlFD!3~X> z{hHOBS8P71@dvondYlH#kg?1Q4(v*AD6w}5P{b)>?6IoWL^4tO!!lIkzYc40q{oc| zan#|jXf@pRrnLAAV_+?n%Px)CS6Lw$hS=a9+OI`u-}?CrQ+QEGy7s;chgwqo&g#O5 z+o@gn@XmlALluTsq0!7|)I+xzR=FWI&DxZpAV;dF@l|GUmzpGXQruWxWz*}-RzIYr zYj<3DmJ1vTw3yCQy`<~AzUmVQax)1n78}x6dy+6rZyIeimiVcN9~|b3keQE{G48|m z?pfBA2|o$uu=}}5DkRbixi5o)n>stG1~lPlKc%yZ4qJeR5{&$B{l7GBIc$8#SDfaB z>;$H}UHt@KxJeA|@QG&)?}$~G{y#uX+lDH3T-C9rS3FoZ8$B_028tEe!tU&Lj_$)9 z0CEshmpbe6o{5(IUZE76R-6AjDP8{Gp6Z8$V7YYTT|v3-fqKVgq;4r$u`JI3Dv z)PM!z!}1gGsyUU8v?Wh@un?vMmb+P5H$gLAzy?g_4YZUv&~B;Hd2#JOLV;>nmQ8PN z($^YdEgL>TD@JMaPGS7hiUkqeaxZU50vbz8!c!JscUp;F?-|dsA`=g%;6!<##a8o}HJgmvu0dW=JurGhayz2xC zl)(n$DCtFh=(ERsu?-_GMiSs1Og>M+I1j&S_B_^Wq3+&B_ER5gi%fiLgM7t;nu)MF zM_Ut@moaXO8fx>}K|0*IO3-gJFjh50+-tP5$_Tov?z$(w!u2Wm$D0A0MGc zp@&V)`j8yG0cJko_tMFk9@mJ9MO|3U&mxvGt+~pU1`mWk)%;zYY7(sznwELt&cPcH zkXc3{2360{9TM52=_bVI+GxXPw?r@qxF^8J9kyhg^tS@FHYaW&?^-LqI9_TluwfsOL4h2=EcrOx~z%C5ABA_fBrN(w1g>{1^X;8`r0G`J{T43Xest`3GF3vc=NZnmnuu zAWvh85i8Ob70Iu!t{Ee}54Ts4gBi}-%!ufsH%XnXi0sn5Uu)WKvrYW0GKO2_e%el6 zm|x&!13KJ`>IUnwT_D^)&&*;ISrNVsc60nPulOd$}=YkY)#)Or>P&YdQ3wKa&K}&EETLF zva7}LsT4wuz>LMptCcbq`blh?&;pUi%Q0n5X7`z2_Sr7=G8Er1F-`-|iuB${h45_? zh3*st5uUHiBtHogzBRtj@o0KS@ymg3i^sW4Hh}mf3fz|X=~TB~^164r;WgQ~2Slz8 z1?yzQx)S0l3SL7{qGA6Yt)pTf^qn2pP8s{xWU_D-Lzn!ph(j{%1$O ztJ+Jz7gO4TGi{#ep7yJdn#*8QiviUFVm`2kn;I%w9f9S6i9FlWEFGGHq|GjxrVg(AmmAcyd@_qvFyu2Dbb3KPx)K5q4-T?bP!?;FyvCK# zQLBsY6Fm~9*#|2k)40q-L-h7C7XbqfuPF|d!q2a5j|#{asV)mJ4(}Xef!X;v$4J$m z#6l9B|4clg9+8S*Z&rK(g46WkU`0CoU=ehCnO7N|aMs+p7h+T&2jmkOhb#~B0jTN} zAd8BzVc*~SV^N4*$1cgQ{}Vb5t);>mnWh>n`oA~XMfLz>bOTG&t>#K`wCNhxrtsDjwdq|zMHNy=Ix$f zv!jM8`*p4s!prp9lnFKHa6oV0b7s{cSYQt946!iOs2W>hI^^L5;Q@Bca@6(+aZS|$ zs3=~KwK5Iti`cde5vSI{eEi~RsxP&Fl94-?put-vG>kbiXt&r z%sG12?>u=@{`LR!imu*CfDC6vU5*0e&PLBP>FtcpZYkZgcBJ%W>~31U^xLji-cHik zw11wq1O+~=%S;8f6tk^GY|QsiE~5~0&A0uO-Q&9-LMYN|le)a4;=hbV!#{-VzX4$) zZwjkV>3r^=pgy;6j~pFkq@Tm|>X$tu0)v$a>avbx=_8QZKC|*7G_jB_Av@$THNKiK z9Sam>(^5n;DXru`--sSGn(ENZjDBbw4Xu}0xgaeqg07g^((sVY+)$dF*s$B|!Gc+& zXX*WqSO2oeVz=NvtvTFPLfM9VU2dBhMJ4_GCF)c2y{{4yFewChcg25_2uj6C>^fPq z|9GXj3Wp^E=RF=OjK}Hi2zU1<6ecDl2oN3w2%+JQi$#ZvMfO%srOGIZVEo{iWVNxF z=q3@aJysiYg=z$eWQ@)B1VxjW>rEuN?#QGp<&|z>Cr=m8GMA5V*FX^q0#s zoZ3}fd6bC3TK;rjRy4)Xf-N9>6F!O7c@CxMhmuA~S76q8s0!;5>b^!(lC}{XEVPYd zfgqc{=EI3)QP+e(n(cnQv&ZDailZU+oZP#Bn@2Bn#PcF25P+cyaJq4C`_;;G26^Zcfj*dj6hoMDb+ z#5~u7-lJk9k>PqMQ0CyqJX(evL8=i)9e&yJUxgg$4;f5^|LsTI9=D?}fHZ=qf5rj5 z`?VI9ib%q(fHP4dD0HyfzSBOd(m4iG;*5x)M+Eb=kwb%1n;78;XATIIe^4xFyUfp> zn&K{?Irl@kIDo7;F0|QAA3{IDdrudGk_( zc6*^$jMTc3b=8?&g1@Z)fBu!*FX0*em!H}4__FX&=Q5N?{~y7dKd)mmO?>dbj4DB9 z&fXltcT{hxha`%3G5$UJOL#<4)Mgl_rq)Dr`P86?aME6$m2|t2d|{{?WaUf}`p-NB zMPrYam34$k6?0z;zPd&{bV&4oJIRF)3vdfsjIJhvl@g3PR)QB zJextf>Df%c&!$_ihfbYhR;NRK)@!JUn`{ZvJq;9a7RM`*-!xxPU~C3Vxu50CMTeS= zi-!CTcn^?(@|y{WQ1 zHh;?enQHpJyTtg^n{;7ZlhvC*k~W-K!(C%tB^}ap(ai%SL4@A2EfEv zFN-h#r;`@p`p}z8%K=v-)U*(7dM7W=Yz_xqCYK||MM}~Yo%n>*wgy{ ziXbt=U0I|*Kr}}p;P&?TW;O6>tZ_Bq!8z`|Zm5<#QlTb?0D^TFp6-{xvy-weUNI40 zkf%(-#jZ(3OrdM6g-%YAwAb6uSuIn6p#z0HOkWU z4QahfN=16w;KLPi78L|RBU-0!#UC^FIX;qq6=|>CH zGwo9KlzCY?S&WVIdczJ)k=r1>V|OcIVbcasGU&=(WD4HRBzB4P#ze=Bp%?v%8h75ua7dKma_W*j-7 za*gwE>VGU`i23XJ;N~i|my>!&w<6^Rf~r z^Y{5a9>4$b@W<=(dcR)J*K>41<_perrX59?9*A|5H__)6G&f=`Xe0}T^%2{Ktm+7r16~W@A|HAX_LnCzJoC;ySit>(pD;d?#T2*l+!MGZGvVkM%h@ z&LxWQCmN!rY#+~CKhj{@&k%;M3n4Y>V&ZS(HAd zc-~6Vta{Qp5y>~EreBTOVJZ$q z$rA*}LX>tecU@h7Po>d$zhL#*OQf=Zvp+3YZKU%W-I>oW)-k@5Kxy?=YMf_-uTRs{ zvO#YRXT7-_X}cOz&iIT)(_4C{Sk!~s>Sz9i2rHTI8yn_=biX_C0kGMrb!ks#*PF)VIgiN?u|meR^(C!jlT zdiQMKTiUc7AnBiZs`99k5wU~l0Df+`koKZRoG7i{d&;V(N~M)vETo`RU4o7$=w3#C z;fFlf?u6GF4()6UX6i&sI%kc)(sylQyoKKn{BUpkBK6z1W33IX5PPeqK}H&mQ`y6T ze{~OgZ}_E?*YnfBazYM&eO)4@fK--4ZpA*%x$>w@ZpGQZJgmyjnfPSib5)ONus^$mE=iW~p`3 zBoFw5*A#=INp*t0F?x)PnMRb%bR%4Q2$U5-WGdvmDWU>-v`#jeOn(3QJQL~j#rnj` z+SnjTEg{Z2gP(%4T5`eBDhWK3RkNEUCbbP*SyutR+ebx0>|A~!Z)Z#T#OviCXI;+t zA*S?J1r|!i&nWf^-P@FQ`D|YH7S4JpZ<(DUbx3nAqb{th#x?kDh$E8{eD8;3H|u}}KvLH3_1#p(X)w~(%Cn6L4_1w!r;F)~|IE@aiRvXGw+ zq9Zr$T?@)ERxe_D>J!h+w|ChGm+~5@XGQ{a?09V{0~$rg(pDNg8MfdFsbNsK;X}JB z275KUPHB5goP9jy1|EKr3J>R}0IV(SXq1d**7(=@zA5gCAesClSGVa3YWFrp!r%=? zcqjRk;V;kXli(>u5$tFOX1*awoof=Z1~saW4iPzj{BN9B9p@Z1m6yF%9`*hxWLKA` z#1A>6>N5Cv?-~`4SR63A**gv#zwp0Zwql5*Wxql%9BkJMkVYsx0vt15J(EW`KL-cUNxFoPM zK1hsbH$5vr6&!ec5qm3{2mx-#R# zAWCZ7*Lpb=O_2LyZ(#H)R(Q1Klssp7Ml>eO9!`sk8F`6>V0xGuI2g0$=V5qp9qa<; z*hNcI%KRqBcHk++LPTWKpC+J;Af}lnN32JF9n3@SJopZkn~JTxyr>*#Yj`$2nc84B z!;!XUJkPF)RsjEs6Sd{j+R@Q;)f{QokrOKT*#2VSeLE|`C9(fTc#^qI)i8fu%hY4# zt~ZWFQ_W5j&TQ&hNwvMgT7}mWRTxnZR5yJ3smBw~E6T(7%8|8UpC9JG@bpG0 zj&d#R#&pwjryIh@FP zhv&Q>j-A`z>*Q7#(!uV&Y~<%{R7gS|0_gbj!C9D)AmMD^yE-kixyo<-HG!k45N zBhJ?SiXTV@`KVE0U$~#oIkV4m?nXR)n&Bwxif1#FD?zV;dlQy!r3T*S=TL~46#e{c zM!t4h3lMmuLb1t)XP>hwxTEOdszjH|9){3Sr53iyLgFEtj~*?u6HiV$@P=O|S0b<^ zKKUPO7daZ!$h;8_s)vQQQ*U{GF|kSvUW~4de8!1v zzZPs~qhH!h7LOm}RAe$Bn%=y&O1uv!nBIN;W;uW^C~Ot%>^9jxpsxFAA|4^s@W-{b z&Zy!7!Pk$3ky#<*zOSt@v$BwSEn?1>W8i8)e94~TUae8yg`oEf>6Ub1O%Y!~z`I_N zvdOC(Ee)R_ZAIqA&l?qb1^WB9b#&!ds3!OycXX4O?p^0TY(`5zup`>&8w_uVjdw{J z_yrC-b6%e}R<$~h319+yl{t-0zIc|j@v2!MY~Vg7I-afqJzYxMQRT?II7eZ;x?wxk z_wf%R++SfeZ93HIXWc6_T-@bvv&`NPvK4 zG+V;YbP`Dv#DVCh)o4L)!iv52%=y*q1gBC+*!>*JWF-4jwQ>}wc5y1u-W};xE6qXZ zZp{`nNQ3<`u1+Y^vLF_!b#D?_fD^0nX-1D?ay}3Xo1F&JlFGZBmx1 z^E(5_LK=0vaQI@a-Z_U+LY#dJW2j(6fjT%fjiy(f*g6%odlt}cA_%tIRq*T{vDNsa8MHqmFs9|<#}L>L&l1KWY23f;GItfm&n5C`rKy>~6BSae(e?fcx$ zWy5d%pX0En>)r$L8U!IZ0mIWq1p_C)t@mWl#yNPmgs!x(5p~@@CDr&9j;lh3{$y~4 zR{f5*rYE}kL&W%^o-nLfEd0&94r1y!J!pyLp5Fl0CsOSN9|_eYeI#xm zKJ_vpED86)$yE5WWo1qxbd1l#i}wjz_!Wy4X?Wu5F3bKLPDteG<=*!8+t;f&k~gfn z+5TU6Lepg%YVNH9|2CqlLzm|yOsCM5vVIc zc~oJYegl%f$sahE7iWoof5hlKlh-okV``W5WyebXm$YxcMT@_=DM|IJml_s_8n~?e zagB30{rZ)pYuKA&5)Pk#;f1z@Ed4~_-MlR-cp~6ifi-K@FPMpPxl&dlg*CCmQi&WrH!F8u5C9X3PzC zd5>U;6aTWb{{e@_q$W$Me-gRyD(sHK){!pH%STC@l83jXw3YSPA`U$C{rmUIgO3t! zA=j%L{biByn|e-(VkpTCi>mBYah&IT?(3FJo4L3^Rso|^To5f+`booLsyUth(B(^w zTATWZY0_v40vvftD}^ZTg7}fqc7y&BGqsKXqPs>O5`P`aGqHgK(GFcyA)9K(G zq+=l_n?lv;LgD)1^~>LskP9E;`6S^}1`tdD+EQ_n1HI*DQu{wYC*-=DM zMJbQ>uRKqAc8Qp{H}i}ko2uxnc06HuYZ?hdlP6;tgTi+ixf!(~P)*%o{-Uqb25eg5 zy=68T7d}@J22jhykBDkc481LU9YYZlOz9T!rq8ae-IrKi1njSEdrS9Ycuq76s<1b- zcC@pzbGX_%WoRp0&ILPVw@+;w^f77)dBS0h9^oJ^*w1U4LZD>YrR-e#xPW$&W2aIL z@xFJzIr(vWd;5Zi`Qo}8-9g|%l#llw*)k+4wEE}{S|MdCDnhMuUf^%F)|>V716m=h z8r`-=IyEV@M!J;cU|i(8ab;Op3ZuIxy3%!>4mChLzMLy;%UO6vy>l|xR9G}tT)z%7 zOD>$dTHmF$aLyJNIT_`4{^)znG_k^+<(OG)7nOuxP>v`q9}PR{HO+8vNe$qUF#8-z;)8QsR z@oP|b?fY|OTRaYqb5>s#$A&d~xoYcgG9X7W@2@g?3kMDg6mAC>)ehP5ah{1NBld_n zTt+TM4jV(;kw;3LS!v(Wp#4kX3fyIl{3LlzP?KzjR&>&=Nm?;gM9X{gu8`ojeiEeD zq33n?g*BwgYSFUyHzFJnRUCq|QV$66tmpAM*sQ^n@vliu zpCX`YbP5~i2!<`_z^Y)@v{~>DFHMmVJl+s*h(B7N&P9AsJq4faQJ6z+SjBvs)?vCv zjH*#|nvLO3z~^;CG~R(ThqZ*f`k+y_t-HlK*{7z@Q#IxCLQBaabwdo^tTi%72@zd< z10%dyNoc+HxKy2Cy6(cVh0E8%em;4$Xv5GW9)Fy>E~)RoFFI)EIw!PDn)jbc(GJo} z?LO>aAF@wuKn-v$BtC|vYOC-mP|L8I|J0XvRJb;P6IQkVFmObs3r_?4Ht-Jh{Ik0! zHEd%6KhSn$;0fY-^v8qAYl^2LZCr@-By3a)6MUcN;<}vLGLljNPdp)HiTQDRjWG}T zx4qix#;)4g9?-ISocJ=63DMM%?g0DuFVqj=(YJN^^8%CYw}OD<3p6 z%SrhSJgEuQ*Zt0h06gQa8c7rJ7WQPwCbt~)Nd-L8_x-aq1X91L=oL0?&Bal)S4XCc z$@lpPb&8H`;h|X5%6b{5Ai^jvl=8D7@m^S@>DTWdw(@VH6GCM2KZO>aypN$%c-qp4 zz-g)e)juedTCa`f_pszed89r~J4xBRt!4d|{+bsh3Be1ri(h)n+Uas&MXQY@9Ihct zRc&$YgeWQXs`VD>0QxYhPw7_T;Z`2;U#x>NbZ{TgHuY!fC@7M_^!$ zrFtz|(j3co;V0OTsD*^^7l9dX*oO7ra>R^$QeSp2t3i@u;?fhr?EX$<;w>j`N{>}| zz+715MK}v`SZTJ`_q^&dIlosfb}sSiFZntohJ@fk6d%C8AcC4K&7pv6EhO?)6lewE zkkyzwgfauBMc9`=QRR&T!4-4+cXuH@8*xI)j*$hr|zbp(Ts zk(D}6MqX-=T|w5?sePgp)59_v>o|N4lXoA8JJxF1Gs-y1crO@|zsAaIX8~={u&=|@ zEOXmib~u}~$?J_$g@ZHztOEbr(cSH}AFFJT3J*OT0I&X|lhnSUV)tgpJMP3hO#6VD zG9<5yJKvz2pr2U4uc53lMW^2r1$wm2+++0*PT%y??T>Q&z4_J7+qy;9{fDQ*Kgivs zjn37@JNSH#uZUYcDz`u}mr&b>s$_!nQmCkc|BPnWLE3!hUz*N*TK3o8Qho&v`cp=! z^1L9rL@=s-Gnj7k=`Mx;p!Mcq;;55=@h;`C1BC>UH_^@`2aPisc%K$+NnkI*>T|qv zFbyq)b|U-B+IJO*8l^mmURgxK7%baho5&l_iaJ-g&2!&rbN#?uv-#(49L=!|J%Lps zIEGTblGmt-Ql(0ohwUdgm6vbn8KWX?h`Aw5P3^U+s_L$dEQ{vU1Gw{OBN_vJ@^!*F zBg$~uohMoaDYk_5(!zel`7wvZQ{bKe&k)y5iP{hPqCPjMCUi704vnO&5ip#}@|s$f zsw?5Zcct7N_m(Y;#0*GU?M_a_2zY30vvHIX*Db}&;%hmQwmU8Mo-3<7t6+fg6&nO*wh!KS@=I`CGWLmVb#=hC~{QV5CPq6w{=TqzqWGM z-EZRRi5dEYrH}X}{ES4I#+9vvhVJ*vA9nQwUc!%c@~Ia8#gFNRstaKS;Z8;Nd~#Jw zfveJ*;SGT#(S5c(;tJOk79~RUk5Kqx6^RDygaHPCZ~<(tmZV>U^Qe|%@kKkiX9<6 zd4OS_m-~mPGs+N-QW9!wq|{*OUKrn;J%_{j7r_NQqPbs<5XiFTnde(S%*jcL*9AKO zyA~hEddU37R1ZX9ilr3iT_P}Ibb{T%j4d7F5n$NnhWP8-Qz*qS$={$}%9g(CxxX7J zLfY8ZsEudAKav->XJMpMhl(p^oh;5{KM&?aiZc8*7k8c%K<;Xkg@P6PK@$$(8g*zai+=(jcw-aO;z1d3M&mK3FfV`c>FnRF z&QYjdFCp#_Yd4B-X6w~fORNfcOev8b(T(o)u>ZtTbPySQ2wSV6N2pOGrAL7Tmyj^5 z{P=m+n9-V|DI{n8#m9D2GrKI*S5lIAuQxdmJTIE_l%(NMG(E><#cLn$Yjq|U92D4LF(zw8{j@*c$(RXS^qaYXZ$0f{z%V9 z1V4dB(um>RQRPk3nY zPeGv2HMwaIV}U1u{B|>V@7lF>!_Rc%3DM${z}-$SK?B@mZ}FuIsaU!!Qtc}4-Fc~)cak<;_A-fauu@*wfb#)=q+m_H2E8>qARtV!8A`+2^7GLbsGS0|B{ZjL1nDRVyv$YkBz>~qFLk3c- z+GIgM^!BW&o%~*-gcxCH`iLaDIH?(h^B!6%c}($hy9QG`*N?%x;?NK zeE9<=qyfx}kzTbV*az6V!E%2GT%(d!K=7r%#jh78eqaGQ&p}voSabTM7G1whRddky z>}M^qCyxdvBK@OMQKG&rFVHx3jN;JS8pKZ{CsjDvja;04&+6lIRi)tGxt05DdY$U7 zG6G#BhiFuf2WYuI!Qx*OU251{(G1c?LnGsJQLWF&x3crpzKZ@!mG(+4X+{z!53z*u zG1OB>jOL3KWQ1H{4u#bTePQ_#3jGh;-DRCFUVZe*wR$i2u2CAQXLLu zW?GT^CK5h-72;FH2FM{{I0bGy_Jzx1#NGXzcYa~=-geXUUSYG)X|`SrY=1fSJ|ZE= zao=q5FQED4Ceqhe{i*%KcM0_youOtCfFzx2c_16eFKCjiFFPK^(r-@5!0KHKaAor zN(nv>wI1-X>VG3Fx&nVf_7U z_eN%#@I+CI9u*@Pbztgdpp;~}D4n1(KhUS?NZd9elnN2aFmq>phR#<{l2h7GfDveQuh^@d(??>xl>P171eFt(HoD*qdUy_zv4Nu}xYCDN#39v#zj&uj@ihs!q|=iQzpE|M%>` z*^$V>iH25t3jaMJ1RO7q7!zU#V|NZsPXIT8>9M_DLzzU0A{**6Rb z!xC6yEJ4cp`Cc+VWvjnq1@Ss*G{I}t-EJ{Nu#jeY`j5qbbl&}Y2Y)DWM|yQEpM8mc z9O_WKF_WxDrYY!Ju{0*%TH$~8z5;FX={!%i>id{^>)+plYJ6U6PhgDoOJQwhhu~MdPmG0_r94W8IcL>&9;Lcaps@n+ zw~a(5N;>7JDiIfb$ga;Y`G`-6K>X^`fx+`J*!Gb_2DH|wsV_9>%{IXNEuFe)QVBkx z?z;DCSLR~D57R1lb8_S<+xKchDpWQ<76_SRp*8Pn3B3dY0eWu!cuV`3VoBG5NjGXj z_8OR{JR~D_AXMx3}IPvvs4F9ri0e z$%8ST?}L@&I}_&L8bA!-ckv=Mwa)%zR7OGiK?t)4a>4Q5y1nJiOYYnSN#{-aEGWTd zHpa5cO<+PlyH<_t>$k^D7|$G{f*c2L9aRE}Gp#Yv)?+EbmkZm1J)=lb#Zsv62kOeckvNbS;F)(YgP(e^x?S^T_C z-lX1lJe*6Mb=yC1KVi+*v6VW#0)Xr9-|dVuz1H{QM|F_H!K7MGM(aUeQeB6F#s#E3qW%UC$a>UTs@jU2i$j7{4 zD$iH3i)fc3-mg0^Q&MxTti)g^Y7#<%-KvEDt_uvfh_`QIKc4+PSZ|>F>pA<&&Amo| zx6=$^gZ#=%8EQSK&dKSs;SY*+WOA4+V3cuB?^tJ7?hSCN2`7>AdQD@Ck|(v*X<=N7 zDC!qVanp;Zm8qQK;}@HG(j@GVZykevLx8R(Rt7_fbfrGIx`K*b>#O{o8gLj07<9LV zIq>&eJV)1!;iMLbEY6G)k5RDgz~|%P?&JI>wOnA;KEK8CoMM*_8&w%7$vo@f1=NNM}(ca zaTkzc=K8LYsSlJOF1}XY4+8P*?bQ+psbSxoF8DbY#IzlPxu|^$7g}6C-B=7r^*uD@ zW@>LU`ks;Jb7Jq1yX%3YS*oeK3#B!S7q ztjycTi3!u^H3+Me6AUQ`aAt&i;w0rD1nVca+m%6k8wc~|c0E7$(Lp`D3&undt5FR@ zpzEWxj&z+xd?%Nr(-;Z$w`7;m;=`1Z{zBmLSC0Pzgmf}(uzLi`DxoCqR^y)=MLA(e zti%b(lSJYVR2g}!EG&X^Wh85Dj9uhvqSI$<1Gh5M_Zy-2$8ziIA*WyI?lGbNo`qi1 z^#G12WG7pe@&Ks3x9_b$>^2erD;)flkLgp~duiKN2YYzFy+)*2H#<-x@XKUAj;wiCkjAwlOnwIUAB1sxwZ zM@|w3rxJEjR_(Vj%LT3^&rDNrnLSB-T2jHct~vW5`X+1UorD=@Bx~p&Js_fUKhXAt ztIm<5&1C~)_`6Cx^q)YJ>6-1FzaD}gTwLFiA;s1XKGgA_j#^;9E_-BWq81+z&m-s| zRlxFQS0_;fDl2`=Tx!1C=clJ{$trVUJfY0^c)Uzy>LkZJ#l)##cRxauB@FW_kt)hg z{d~s9-_>VHG?U#sHjH>4r0kT`vVIw3i)Jt|&v>Bs@?&)uUQ_uB)ndzoMky4Ax99oX z=6ia>4z`s=-|7#gycbRfcD4h~>_gd^AL?u84)WygaA(lZEu#DN9RM5_>IuAmqXrW1O?y0t^h2o;XmS_BE`u0rea zg7<36WLtU-Z;D(ty+tHP+Uq0^p0vz>?v5VQow6N{b|ZQg0sUkUwPnQoFH6)?I~&Zz zt`8^jA$|%2#r%)Uh@|_mBja6$-;h2^FcE|^OC7SpB#8jU$4GQ4goL-kg%sv1r-LTQ zGOE%!5JS1?O>sK_PhdnN;k-Mf{M+dzmR4q3Q`18SXOcW;AtgTQr4xt0WX{;SxDqD@ zgpiV4&lrp5_a|fH=uamnyybPe#x(-?izJW|&m6&%o)FAkzNHB1rv`$M_Y{X7;|v5b zp|5!;i0TEQO*9~QSJQ-yW|L2*q1P0|+3CWS!x8%M=LqRzenPtC`lfnz$HdwC+V?Z(f0&)nxeM1(&aXWu5NB}L6@6dDt~2WPY(P2+@U$CR7AV+11ypFy+-~y zQ5fbS96+bD%)G<>J=#2O?qPs>JNVtt% z_b4|_Hnk5~*GY@7$}~}N=w2gZ+{knK7H;|3TWCCMnH(&;GLiv)OxJU+Swe?e8}{t| z^jdRICv6bk?)qS*`PTX$@~-5c%8N2vF4ItI|K;+1vm#iUzcd$1M#;HjetszkS!?Ghyyw4V7ZZf&XGLDsO4{qB6!2g9bOZ+s|duUu^r{$1)rf) z68mr66<(VOJ!bnAS%M1pQBSdalido0aFx&JPLZDI$|V>sSU`fSFM9h-vZ!p-7gGYw^UW%!pce5y-& zC(~Xg1$pJf2twRwI#r(+eJS?O4NoApHOmtKMUxioyok9K(iJEJx}_y3^t{@<>-NUw zq@Z~$Voz-58gtxpdt|H)6uhF`(|sT|!vyE^i@`aWz7sr!mcqX(8G%(+X$oU6H+h%n zf+F=^lcoEPH)7eHjUtK>V6I=c5s}D*d6@{Fuj!;-JpZw z7@^rcR_*MiZ<-@S$@@xGKXZDu$=wMEI?j)^M~4~XG8{WhAQF0e(m9qXDQV*g6k|8E8B7v|j26!=BFLZ8dtA`*W zjUCsm#wZ~tn^b+$rCZF2;tA1&guH@z2JuAZGJ^0s*a^GSa$wwXOGFBd<*yEbD5H|{ ziK(URQi5Zv^fr1kbzw9{kOaqxkt4+!d`lvMGL!PA%HBx!U1!qAeix_yIC=h`OvHWU-IfI)LLqp&`f~aAD)c z1LhcMkRhYj;rdFcN%)K|qd^32%rJu?G3&%RLEG)tVYN{BlF=?xiBX(=yZZX`N{(9N z03DGib~--y1zjJ*%$X9bnfs^=JTJPprJ&P56?vZxb;pc)sa|WoFZ>>(Qn*iwjOReTG+ZB^GkkZdFye1ALM&k=@`$ zpAiuj1;Rda!8xIakj@DaoTqp=4S^UHvMRpOB&?S$AlG@)9IgTQlfe$ zPj!rv=n8r3%QBwJJim_+z|9XYlp`ulqWDu-x)bdZ43@#gPnw*UIr(be^5e&wvhTicu!g5N zAV;A!r}fEygEue(GZ?^9^nq|ONjAffs3^OYK!*8ePCS>Xor4W?a?~{4-k0b&U65v# z`S+zNwMhYl(ISKOLfQqzWlJweJNDa(N!Iw67jGa@@$prM+UapL6D0t6m)KOfqpLQH zgO(SRs^F;F`J)90B22)!sf{#h#SR59+8yTPF#KJlSn=7EAsbE7z-B~j$Sml2{xokp zBOt{ENQ@aX(VGKptA)?(gqh$8QZEHGm5@GLOG#TVGu{thL!bB;dWy$v3G;zXmVCEr zS^e~rRoLqV_{nAco%nBdNIzPFYPyal5F`CN2c9Ep7PB$1wm1$o@m=Q{4;0Z{J1*Tq zp68o*-F$$>5xX*vcv#K{&+yL4f+jR@4H4?JBFdXPL(Ul7w`4EVNWj>v5!pKdF^Xkz zc~jiKN<@ZGveDJtEzk6-ctn%16=E7SW8?Dr_~y}<$)YZKhV|8s)!6F?9D%nx=V<*p7%j^?9!?lhpI`8>`p9g@&*cG0 zoR8LG3oQs&DQ+vKycU!c?3}$G0pL^LfjRj((?k1(&D(8H9;LWal6BD8xxV@R5Ax9a zf4e+R`7SyioQPfP5arl?}NlSP{wzz9EVkLZ-j!qLp1u- z=LklvOnXiyVejDW^p?3Qj@J-Q#OQ!{3+8G+qEB>q?fGI($QPju(Os%fDb3pjO`qAQ zdc=b>XuOEopH@HpQ!bb_zI}K1iC4-=>51TLbrNv&X1>>#bQ?p@sww_WVIHoUK9n%! zu+6>#D29EA@JBBy%2_SrH#R3u4C-+J`D)8GqTb3G*X|Ih;Sbd%>&_QGPvk`^B z<`&{HbV`Y)9knWg^@nN0#D^ZZ_4i zc$!}OEvsOaY>R_%UQjh4-y`z&Jog|rIYF>SsF5|An3781F;NVT{Um1Sx+?m0AVp}- z$=XR%OrR*CF?YBoAbWdp^ax~KfYc`Z0Ls^{8|QB8 zol@VKfT0ATImWZah+Pv=jMGEx#803a&HKtP>6YY0@NpO8Fmq5x zN9`*!9H$>;W<*`2eZdQ`d02+s9aON&~ky?{=c=wSvct0%ZV)VgX1VC zPkh5fsq?(iyHaynUwv%AAF!WSXbZtx-B1cq;Eka%YO@4kI&LiiW0wnwI`d=Kht~su zAvMTXaqsPMWW&0&TfPKJYAdJVssxq6n5z-!WXmsd66yc9^@|y%FUE31sPpH&OTxl{ ztzHqY^5X6m7n9q)(cdf|6eC=Tco3`Pib_afPpQTWw%Mj8K4=Z-Y79D*iE53;jAFKf-9ZXRq-=P3JiwomHiI4ZS6=*=AE29S5sy(nM8j)b9AN{8%r} zO&qjEHSXzwLGOe*f#VeI(<)zLkqNMvQCbetV;#4|@aAmhxaj}VLLpQxwOYlO))ubEpJz@IQgSxLQi zhgR3kEF9r_WX3PnRDi;i)DkJ>vH*JizfG?xQ#v85>tb@*&cO2oNYB-u@vQ;H1fB|S z+5D-BE#c`pS2M6UHbSeGfdgJ$R+X+WHYKG@A>7bX%h~3j5U^e9j1=JfWN9gPm3)7C zkGaLj{Vl%!-85a)rNzVH>G#$zH1z)BY`O@ zXLCr>PP~|tsd{=6WVu{b%c2$rC=Io2V9J{8wiPrDLou6*dr-AGQGwTx8s|6hIjJ)I zLveNQ#yz`DT;1eCE>G@&#T7$N4w?7)FW}0x^%bgl&2@uZk*=LWVG(1xSdD0@MN31% zjf^Q{^=++?tJ2%ez0DPAgP%ByZr}Ag4agZn^i~S$V(%k?$kgF!$XB14%6HrJZbKbrD#ig<>dbSNjrfUnwunCYCQH9$cCKocw8KgDZ5d=lH^vS^JzWPR_YM z@WbP{AJ*DL&-be#T9L0?KX{c5jgy5P$U}U}oF8Tr%)A(hCe-xle_Q+ZK~w*?7X>F1 z*7Xpu)jhV}ydqE2R>go`t&SBm-jXW@yB>6jMb#NJz7l9WkduiTM8XbUQ_nVA-9aCnNP6tKvYBIb3DpQYS=9Cgu)815w(!+aE^6*P+jLLx85Ccc6GQq z?K#%!*DAHUSZ5CR!RDY~qO;&=81fCqoDRH#Cs~dUN%~{gbvMk&wBVWUl{@k(so;pv zh@60-shf&Z|F#Z?ff?9L6J3lv6ta%C`Z)t0ivU`47Kb^Ix&Gz>z9?U%e>dCM}7TxC#w3!ID~(Pg9DlUJgj_ zLe&Ty5j&wLbUn9+J(uX7^h7PXJ~9qyG4sMQYM-Ys$zi@ep9r z1UfO(_yjMCcxA95NU>W67bLM&OIYMSJVAk->m3kZYi$Z>d%pSnspT6l6i_z_=CZ&K z4!i{;o3@N1+Z6+T3<1VobUp--WF|Us?z(7mZ6Vq zx#fwV*j`hl$?QNo$?N5*PbJ@*F6x)j&}^wGlii%ms;TgZMLlFD)sp-Bth9OMx#Qhh z&$S;<#r@XC%|{PV@y$qFE1wcXfe^cB&3O}w)vsTX4gh*5x0sFR$9F$lLmM`ZDf20H zZhpQq*T_=URXibl_GkS8>r9jUOG^%PqSwX7ZAa(^=2q^0_dclg`NSMfi&`p2#P@7{ z0#mnV{Szu(TpZVHvfB)zgkPCUU=YEi=k zN}jrc9S)L*O{*w8cYPyAa-v&-A5wQb( zAU~J>(>2mCzds&ehOfi--c|QcUjK)tbLTI!(6|hWS1X!z7Y+K z+h`_gL-Zzh^_bINWgR;!tKzkjCL-!-2(F3igJj|wKNliHb5`*DtK=GVk1*`WXf(U9 zmE*;%x(xD&yD~;X?rxSR9@8GT=cv>N$2b2xyL%mq(xHv@ypU{@KU7<3nV>8a=+yq@f2{oh8Bqdwf~5U2ftXq5;1K&Kc(AB)SX} zcx((KqX@@*_<+#p%g4#1*!G;_C+n_f4;c4hI2^T5|4O-ywot{ zn8~*>ynpp{MEkQ|rWnarr3c9r>;zn0o^G+;UvBH02md>9|0~-Wa?6l57{b)ieH<8O z^su=2FaAbfAuboG3RS&pAC}|Cc)I+z+i(pU<7qkelP)es(|274pb59P+uBvRS3n|Tn30vKP)OSUSUT@OD!l*yTgl!+6mHhFG9qNfC97oby|Q;kcCtrgXGgO4 z-Y!?dMKZGYy12=v%lEuLzu!OAUn=)F=QWx<3*YO0)-`)qO zh`Ji*9o4(wnXqdi?CKhULBNE7)fW|tSvrT$CSn8*$w3=??XoktTGPFI6|@lFjtP2t zIOxvgBTvxle^*cCE4~WhJ8TQe7j3V&Fws%Gdn_0GZ(qz)RGs#F;IzZP%I_UFH<*5r z5M}mWemh+dT>Vte*S^|hOc)*%djF|1PIJR*A~Tl_JvL$S5iI|^K5h^$6IbEaUFVVq z0RtpdXDiWDa)%_0)Y+a+1r!Ep#kR&Tp^rX!y;@1;5k=PVvTquz{Ak^v@@yNKtQ%2) zl`28gk1x;G2ko;IiqP%Z!osJ4i7v8a@*B~O(=0z9e|?i<#nCZiq+R8P4lhdpB zF1q5GG!v!bya&86lCpCo#J<;8722yo*^tVq8-IuYxfn{$u9Dqq1>yeSPedj?E2M>I zd&DWbp2D+vp~Hb$Cz|IKO%Qh)ikn>H7+03Ws&+b@VnsGagUEslIlLQ?wavito3?Sp zK!cXg?Nk8qk(C|itAq2KZHKiJjH45qkh_@M=KUJ z`A|%fVFmG`SR5cqftjBal_!fBdkK@3wH0EKKRkqdL>#va-vE`NgFRyC@x0}Qq4|uG zV3mM>c?6a-k=?wF!AgU>be>GmzYCE29dLR&bAIjvWoPay*Q;I%IJ0H)0fM}9V6kf( zCxwrDKQPD1@nrQvO3W^hNl6$$zqR9p6 zq*^&R=7P!W>(8^=`u3qZK|gVK*KYdLbWE;~#i4U5X)g<_H4IW^~o^&6TDxzQ<}8yfY@oA+~{NsmSbKNvXuq|F>0^iJb= z5Fz4KUbbaia~ZiGQ)b4fb9I~cnU87K?zp%_QN);-IoX+x3P%6V=erV(t z`VCrBM5Cin^PKdv-b-s1Vp8LOhp%X< z^hUTh3-gCpJ#y4k?)&LofWlDp2|bnxIG2Yy#AAkU=gs`l*Dl~tHhNcOvB5l(jERJv zZD(({d`$Lv(A0|jU4Q})rSPD*3KZs40ViUEkPm(mw4FT-T#lp=sL339{UM_wB%T|2 zS%9*DNBnH!>PyqRpok#98x?)%g6_Jxazrhd-JW*S4<4=FU`rJhEnR;8oD;Pm18^UU zMs{FCLMx}=K1&Y|8LD%N6VIW5d{28&|9r<}6k6P0{$n;^2M~LCj`*#!!A~PQeLL z%2?uFc5w9etYOJ0&Z@s-|De-*sH!bc$2#e>SJ*wyy_qqZUQG2r(oDFT-ncReyk~@c z8)BdXPMfbNTQSSZz1l_~Om{{a6#sZi@tNhV#;I7j^CNEY)D$XZTllnI4FjAbHO10n zy6^$mo2=IhS7_v80sw!ip*)Qa?lRrl=u8UM8F{W^{QA zk<@8nU%}OfSG`A{)T?HHea2bQx*)s>bC9j-dsX?jWi2q{C6I1x zY25PCwTPDQdmg@do?+-&z)!#20%QE10d9j0O-&VOvF6WRudJ>5DBfeLbeqg=8Y_On z_Q*@2O&V2b#3+cfsSuHWdUzf=o(LDK6Zt^&tO+S*7v>pp>FYz21ip;}u0iYB^JsG5 z)oN}F= zmuyG)4*?QHhGzdaR>+1XH+T8{Rx;SnmFqb=ZY*!<9CaY`gBE}O{25dzrrkkOFDGr< ze3@Nb-a?D7udji@CjNoX7f&6%I4p{)X#12*RgIl@9w{sGGpEugh>x`qB*io(_Ebp} zR~GcJzY-5Uki&Jn?ng`KCf!@c1N-`E?1(rUEY73`kKC;kD*U(0iQX;3@3v!Ud}k@C zYdGc)3}HnQsEUje(ez|3C%;{K2doB$a;;I@}t=4yy9vR65C)H*F&z<@a@g=InpY6Bc|I_NOKmKOtnZNmImq`&9i^vtxKs) z$xVJk5+sY%5`{^x)`5BohSMIX!^QGho zAnXHpUCkq&KM2R~vxeJeQM9ubbJbcTK>6HRxA^gxaW)98n{O{x4{ug)7RhD6IQ1}~ zmEP(M7>N$$ck-dX4$j4LrprCczJUqf?P|OEe}%fnV%~Tn|Cie$LMH2H zEV;&k{(FKL>(JCcR9+;es(4SIDz)^a!`QxxC@E@S7aiR9hmpL5VQ_z>{nfb)*N;$f zK4~hg&8@7*Ru?|qIL%cwuht>PSn^0+|D!|n(ymzv56+?XRA#*PU#^orU#h6CMq>J{ z&F5Gkkc@dFT}NLn+?6I#RgrhqaB(aEl zm6S!YFlVihs96Kz3lZz5HPiQoMyzw5w?$4~TF)Myze~dL-S@tm*eUks31xezDQyzT z2(8$-w)Ts=4bc<q<)>>tR(j{VdnE$tygFGKisolI$WX;1n-?UUo)& zjJeAH`jDsi+cytq3pX_@Kr@_LT5qDK?tg|d-uaj|_{bHR<%eqoqsy+w4?@IMy6RS5 zMUadd>!|V`gRH~KqWsSx*yM0hHm9UQ{UOH`S772bn|p`u3=TYQQyPM{$4DH^y1fDy zH){)A0@WeUaUZn+Kf3Xfz)89DXK%P}BYVrQt-bpZmF+L_>MAzzZ5pju8+N=F!OZNR zgY${YLDvW5K+HPWefu|(xvRT7*nA5-Rg8my#qiNli*6Y&lbQ2H0Wxf86t^F_8~wJU zbO8~!hH$iAX4hY`su6s+hn(@jUG_QW(7B zl~WvGhFRH$<(W@O9O-80n-o>aw^q%S>%VS}K=r&4ZSw{}@ig&ec%Ak&CF~C;6UnKZ z6U*!}j+9R?=g%rQGs<4q=IW#Es;-s(_0zaMFYv{`vG3AaA@^QwZK8TuuA-tAGsEW& zEf%wDqfi-AQJFJuj-t@d(EL$+66n*?imh^0XU!^=`)aZ-D(2%xvgfPxV}qhMl#b4E zrR5zJ<)LiD*_wED1k?j9DVq7uBJ=R-3Zhc%+d}9NH0d_TRxeh1I6(+!M0DF%7Yq13 zgZBFdjtT>Yi~%ji9L$n(rw)%;zMSkaDZwg~j<7bo(U@|*r`JxpL9}eGqZF>)C?`xH$VzYzJ#a(+HZ=7`d07p+2~LZ4a(1^TDN#S!cG0A)4t?G&w{I}yrJjHL5hP5U4-ac#iMZq1%|uKbFb`S@`$Qngva^X|Go2bTmy^UDbNy zoJ(ERUbY%2a7$gbiu-k*?`~f8lyJ%@}GPTU&xr3Qdiw$`Z6< z`s8ff-l{fT<#gNhb>&Cqo|W6blhn#x!$0`dkBW*fR_8th*n}m1i=mk}HJv#usjOZ6 z?h;%`(;+?mzD@0ubi$YN+%&^Ud(%5;3D9)4nyx}n=o44BOT9gA6*0)_HN5$ zWU@7lgn!xPGgo-V(eqek4Eb#bx=n9FX5TUz)dv^c^zUaA2X+?~sg$L7yaM69)Q}71 zI%~=y@t6PcwPJ>u3+7h&^znc4r+W9!5YNx>2#F8(}!Uob}QS3%;n@s z1RuGm>uT=9Bd{$yc|B*momw`+$@kj?UZ!Uho+o5@3_-wObs1prDUn6)1q_sIYlhL6 z^-uGPX_y}-Fv~0fp9#GqXj#S!wfpsr>WVV7X*1ui&~q1p?KbG{UAr-7=iS$fGiJfZ zZnv*hcIB3R7J-lMz$b79ebx>y*8@XBdIV@VtH^u3v7s@>+wZ<{uHZOTZgTL*A6T%q zOldfAQ!gmd#^YA@;k>Gryl;XR_M;`&;m*TUGgYd_g4cF7m~u|P;q1J3{E|1Pg#JaD zvyyM&UA=Wr)!|3}YeVOiC()C6h0N3(b14CD-`4*OD7&9%kLjl~o!Pn_yShF)!+6;= zy~35z+*dDXk`WpiL0Gazv;|d)P>;~*T!&EVJ)^O5B}I-)6lLiXB4^=-9HMu$*Q~1w8!d_qt>K{!< z?Dmh)N*qhPE5DYQ(5drSYTPgyQH#RUSkq)HQ7a1R5k~Y3s42|qGs~$YRi+j~Q%QCN zQ&T+ER44i>5?&(3OSt5g-swaSdq_NZyghv68y<`$xSbMT%MLu{+A$|^H-E8*%n!fr zYN~*D@fHpm8DB{WbRs!9pyJ&HYa#H7TFNj|OgDk}$5t~Adi|m3s(t@k;#*UU&!;v&ZB@{oxAF{J9 zWb*KkIln4W;sqh=0zRd@j>HGrFRyrgx$0tgRZ~((0pQS0XQ(LU>oEH!6Id_4>2U?f zur=H{=42lx^}+SsU+0~kxuhg{`1Nm|?dE^9fJ{-P?_@s$?V-I+P>%>>2mT{woc{ae z27#TKNyVR9zVfltZs*kM!m^LuCaIEAETL3#k-pSQ53R*Et>bqGv4>RB8j4ahe}D|2 zFY;c5f^6v)^yHE6eL&nAWI$16!tfbcdlw43|6zJ@)JLGcNliKN>iQ49dkMyYdS*eV z=fVH3tGoXF1uufonA6DkDZt9W1wgi?J3UZBt!~wHi<9szD!#;;yMyj*tk~$m>X$RIgxuoQGipVULo|R*I8ObKCB#B_+}?QIij)a!l_D-QdmXewE6e zw)tC}d*ey?*giP^d1)2Lr6~OjYh$T0kNbo9nSsW%fx>p~MuyKjFXUTAxt=fBkW7l) zB~lz2D^w?@&iiWD^#v7WLRWLp-6C%U{d4qUF;VJ?*88Qh+z1q(H)*?rs2jDOR9RVa zAZtZhG2rQdBt7!aSgDU_;-h13$RqRhNM0edN_qiOk`f6@{Ecr@U} z`$}B=f=aBx{=zPoFzh!M9mG-k3R**DKt9pRp9N#}aw{8jxEuRSlH~pz3$Anc&fals z!uuXPSaoA8_ODRyluY+6ZadkBqwK}MJ|O+P1dWK}MRgv>D2`7TWup%dRiJ7i{#I7M zuUE2PuqY0R^Qj_#H~w;esb1p@f05!Lk)wVNQdXWmts�Ou75!(EE=S*{6HZ57A-g zh>!P@AY^Z@=RWf5=+HDV>hm{6Te?>x?fh};JOber3ZoE=`+~c_`YlBC2mk(7Xyf!y)C!;d30HN|Ej=$7NlN) zuWm|)d8Y|3`MJ99v#902b??=5lz=vMUbI-{d91wHHv8%y{h@3hBZS!wE?MQ^J0ITIpASUmnS{j;X%t^z*tVF6YOlcQNWe zOTwd1C1(%UW7Y5UZuj;37Y9uUTdW!4yc2=2+`c*O3D=A)m}qsu6Qk-dOqT4&GqS+G-Czyvv-bD_Q-rA^ zM{ErWzd_hvsMs5%`DIZy)b)!ceDS$CEeGrOM~83_cnyGkD6`r|6FPwRcUcHL`)vn4 z@Aa1UU@@SdSkj+A4@B;Q(e%|7%GEONj~LH?>_G5AL4*$9j?)MVJ1!>2(4eJ654mF$ z+WML_r@V!dK!obMITd$`eCsql|`n8zlH*n5{P#%V@m;Cw3s)@4I#R9tE8jU!Us z)<*P~qOdlN?}G?+esO-ve7eS`WQ!do`>@b2SSKT^`mvxEv{b7`m%J}+^Kvq(_I zi=F-J$n{9UL6;aUrH6T5CP$xSflI=r!Kzr+HuvHHH@kpQYHE7Q8zl6mD`t2;SqrZo%EW!#8d_k-3>3P;t)f{hOLGC@qwEsr&kD-u38lk(+cie~~e%{YrEPE{~ReY^d-UFIKV`S!;3_6&Y~4z)uYlj9-;03$2_ zu*NNzB7(rRiwTXT%#dN4Bf44J4!7!!2a)K|>3=U+P3Ps@5?lp|6JEhyc- zge02`2pDZw)JDAgAc4$`&Z&G($^D~0EnXN)$OqZBg0*4C&C%i^Lz088@T}nFRv@ZP zUQJn}vPv+htMgF#5T%k<=m17P>5$&LmOr3Y3KmU8fSCef7IM&W-b>>9_kAMeXMDbA z{!WBH87=*?bY>=R5b`E5RtdAU2dx)8{kIs=alX1vpnOUWO|p|8e^*>lG1 z_#EOh0fR%L1c)2yIwI9N$Z(Mnr6tTSITKb`g1%gLy9-O0v3xx9J7?HCsVRm6@qE~BJdAoXMu@1ToIdwMtEUh zKzC}gEs;{E;~ng~Wj{@irvhQA(L#cbq|rvH2p(LA>rWgvCM9E^ z*jKI=27mGExG1Z)p2P;r#8!z>8_m_Z{_fA1ZtWGTLVvqjwmaGIY~txV-dt74j#k(B zT=-aW`^C->)#;Am7rN_}fxa>Ipf&1?OW|4(Twg``_d%dt^P9aBG znbTsn{+Ta zH7Xuk+j9swLGLg=kKKv8V-Tgw=sD$)o~+ucMz}_yk-t~u3D(6@l56oSGtq7NhEljH&`5W?9Bh`n;~@G-?c|iTj&45; z_x3`hY0L)u0~azm+stiDIha#3_Ae$SH%f<-(IW^NJdpFJ*@Q8 z0z5^st%>_vSWtR1($4yGpvTaVdXTt%%oIkBq)v{e5Q){d>Kpg$dH#)b-_`)KBLLf2 zUt9#WLi;@WzXj42(vY|W@X5FV08%0cd;=Djo^cw2ZNRdY372)&R?`C^eSGcI-#tl? zl5AB3Dr=H3I_eusHfu3kv8B?Ayxa^et(f9B&A6j>bXRL9hQ95v{;4Y%;*%!XQHl;vAXh;8{ILWQJrdbwYin(I3^w zj>8yC9U7``$Mq(x=6Qwp4Zis?-l|U&dU=vRDFKU0L*HkCJ@}v9E_bN57RS^&k3OAD zW<^ht-l$amJ(bC$;0R*v{PWy7ND87)QQiHJ`t4tt)^KN^e@6a>32!#t$99K`)oBB+ z#2{~MbbuQmY@Ye_S3P5|tgh$KBOzLzHiU55>-u8G*n$qSUS~#A!obUu4XX*SXEe=v zP0TfE{iTg0J4upWQ?|ynKGN(0&PZXJ-TBzhLRS~PV_?~OaK6>OVkTE+o&QtA@{7vL zqZ-N$Wu0hNVio6bl{Wz#SRUn7Tb_<_jjy8bd^GibAQ(Yfry#&!l|w~Y>)9)27tg1l zf`rC;_WBb`QLo&pOeA|MYZ9&9(6&lj#r)vi&AA@3yf5S6M$gmq3Iy;14vD(?}C3o=wC(7cb7R1Z~~6e9iQk ziCx8SBr&@4JRv1x>Yb~GyeUT2T(Z({LOFI(+lO2gF zED~hRM4MpwoCzFZ&^~`4Patlm5lZ|}n5u_LcbsQjgc5OZyd{b_2{dc`i_m3=6E7xd zQFi1xxwE%kG3bEKK9+7!!V^LySxoHLN{SJGjPuI{ogN78p|HYnXlcZMy&$O2Vk!se zcQ64-aJU4dWeLwN0J5oIi#A&4&ZTtRV#aW)Ii)^nQpQ(7jtd^(OeS9!5YUJtL`IX5 zW$Q8W#D4SmWT3F}8%qp|H-5iq8ib5o29(mrPoD*nThJ*Rxq;ji29L%ek5M)<%DX!K zN~Wim<8`u}6NhVG_qDm4JXF}zQ?%kJUsbej*yp|~v4Rd63Li#*eaQTQ`Of9v;m5a_ z?pyNZ0L&>+gCDuxoOTCY|F(nLZ5zvwL^w}!a#M~@sujUvSRSx67Nz8ef_UERMfA-v zbN9dXNOFJ(co-4HG*}DllZyc7d47%gk2eU`zV4DtZ=WLHZ3pbg(c#1KO|u0^dQEU@ zOHFp#C|Fbrgc)utZs9@nl7$}**OyWH)q%)Smkyyn+kJQxk<5Aa#~VY(0tvaEznp8& zvV!UTNlF4AEYECz5gNt8;7DQG6xDSr)E93!CsMVl6ZF*iWyFuetCSgn@G+pPypu~8 zRO_Et6FvTkQ?lC!v$6enF1c4#yZTuH!Y20~`%j**K2DydE*BBc9`BWCow4k2lBiF@#9=aySO6keHp}+ld|*|34w}sP5p}>*a4xx z1OjwJ%|kz62OkiEm3VR{!*B8FA6SwaA7ThnuJb{nk-4;D=iD6L*0 z4O?{X_OPTnv>2kPVz?$`!p{a#cs#igucImS!%4udy$Z}fm4+;G>PJjwfJ=+ti)~JP z#>WDXPw5j%zPNv7R(zu!Q4oB+CA?#$108VUGxrT3kWNolISL7ESkkAK>&cCe=BsMRp!pU>$MG9G_5Nw> zM>uBtA)0%RI66y05WK@e+Klq8i9dYOmBTW@uSkHUJ=EgOB zq?sS`!4-xSS1$eifahcVHwVg>t^MqX77F*!^YD~xkrHh-R%>&EEt}l*mW^x{_kJ5N zF!-_S#SM*(sS{wd;1)O9ZmU8^Rw3BycH0C<)&)qki_W{q3s4g1z>(Nm+l7O`83xBr zZ~4*BPVw$)I=#ey%vq^INa?qoK3GJ!^gNR}!$p`J(C7dabgiJtj2~J$=t6+RY9}lT z=pT^pZezmwab-^lc@r>4-@V9AjQ4nl+hy7ks{c4 zr%LA%A}yi>zox{C1j;N0b$|u{uKz`DPv|Qirz1(XNMW5d?5Bhs#?X$kRJr!!-}$UG zWBHXl4adSFZbKmWNm5>*B3_7`C~!N*iU{+0;6zl2fLF|H+^Y zwi+CBbOQ=s+SI4j%O`=iKuCHs8hkVMpIvEj@c=0CZl-Q;s&6)L|8}RyA?OLHSJd5( z;@qR5X>n1GNa*6Cl%(VW9h6xnsH40688A(6QfVb?UKOCO_`_E^(S0>U)Lot+Z|=XN zi}Kf^PBhx#=r~67_@os?*c-CFZG!k!cfNo*;CRZRU>;@Z-uI2XAqK2HR;o zahLgJ#_Mk*($Dj#IBpy@oM#X2-o7z11vj#4HO6V{P|>oR8dIlioayt!;jF5Wj)-Pl^Aym~*O$$Lc?!j;Jlx zl;u~?PB$Kb2(?Pn!`Zn>^k=&)0@7o;wwRy1KCdd-NL^4{p zI7SRD9rRL`m#$S9psgRE-kY z7QtG{ObkB|K2e269WV{{-hU^N7n^3ml=Oart90C}3sf=82!QOJiVum7gBH`HBP_lT z|2utZMy)~DHs5Xp-#XZKUGBKy4JWf_DXS#*jC7DY=EOxu3uq)Mq%_Ij$0yTJ791VU zwyaCTHg&0ZzV$Qpa^0JNQP8PEIQ{tV(fSLWz~kSH8MI|Da3Y>)4T&R^`j^^|H|ypP zGPn>UQzh_xvQnCs9SAlfer3vg_;y<8GX$8=?qGM0@7IAyrn_!B z8($2RS8L>A@Fu5naNjsW>nFNUfQk~mbIsh9vwb=B`RTgYeMev_I2fEC-rSdOQ9GvV zzFhmy^`o%iCBX~`oSitzrYcZ&#iG&ojud&1)6u}P3Fr~s#>jLKf2Y<;!?AbO1+H8` zs zz960=){{~A*qob-VK`Ycd7S(2N$2bAONT9A_xY0s+N#TZGXYO?zO-^l!fl=mF$YGI z`ASg}p4o(_q}OjaoW^7>&y_>Lu=#lXbk&%aNI<)J5`5^DVG51VG)TphQ*Xb0doz(zuOy0pZ=1UZ>rnyCcg_&CkJ;1^SkZT?^tQ`K@q(;P zxH^wTWRjJVAmW?)LcB=mrm@h;JwF56CrAKgRG{SJ{_gc~9cLvbrM`CIG;nC({=AO~ zU0W^cy=UMIYyCH3q!?pFQ1kMK@#qxR6O)}m3lKcn>*^-iFkLGs>-d_T*LB*^kx7P!8h+w2$OkHg>$Z;yCo#)*KdETW+K9_6LpEzk3ekXpR}?kJa!zhGber1M@a zUFuc4R5T7A59zmei+>bE8p?YGh}|5@V8H7A?+n1_1Y^q0_ypwyy@LY;5KN}sb<;uT z2md*$7Qw0hk0>?yp7)d3~fL)uTr{KN*be>(_a!=MeJhj)%MoG~J0$ zZ&GcvtG7pYI;$?ED8+*5x@$~4_r9P_wfu4;Va*xB;;tkv`y{-pm6@k=egZGn}*-(m@ch#xVFi+H(ka z_7~CQOV8N(T9r;^lWYt^yu|-wiSDkhu7bP$`p+tEhrufOy!Ya`Jhh%eOc%3``OUl! zD@D?A7jcgF5(|E-Mdr+l*&gHce-4Q&WnFJ<$r_YW?@cGYZufYkX54Hszu8JeZB&%) zf2vh}k%o5O85)v#p3x$0^$xzC(Wm~?3eA)V?IZzR^jL(*^A@wcHB_ZQ!(%Ol8ZO88(El>Qy`9H z#OBn>&~JXo){T)V_nb_1;Ccf(pdXP zof=xE!)y)YtSw^}mxC@((~+5D%UvJd^|k<_#ebs=|ig3u=F;2h(N z8G1NOJe}SOtayg|r?DJb4;>v%`L}hIoZdf+j}`=xZ|&_MZsWQjQqmy~+ao$Ef4QdR zzWmZVh+@nu$$Nf0Nj@}x(cD)(9Gf|g7BEylD;^y~)mK8waMeeeUl6<6mAP+DpU$bt zCJDV1rb1K6cOXIr)h4p*ERHw9%)$4XGK2J(N{8@*q0FmwmGzS&!BKObC|NBRN%#R3=_gW1ELTMK{$t&2h6+b+$_ zg9WGvcfj|Fv|!3PEs)0`uNTc?x4J)O;?umhQ7UpVh{|`DEKCUZ#^l!1u z@FAxnOWE?c;)`~|xHo|W)nCKj+77$tKD{_w&NIL#54h1s^szzsNMXl0-#G9gLJ=tb z$o$lA|K6q^r*Ns>;|qVlCSsSv5hSbqnv!qjs~k-2Pc9z9Bh>I=Kwbumhc8 zF_Q9tceeX7cKK#n90;Pv)Y=z)B_C+1s%H{JEyO zcHoyx@Mw&-V)^3w(kjF>E+l)&a@&;kWTo<4tXRdBOe(`39wuVO;Y?>+qjuxC*d2J+ zhT1>HC(i?o|6<@$lm~C0iN%UJs!oIlRI^7?u$)s*h@yGEy~4H>om2cqf$Ktq{lvSZ zjB9Db(HWvJ^@)$t0%5JBd>nLzb<(GEK39H0W1Eq)ZIV6z;Z9XIE7UdDajC%aDZ zG`?5d=k#AjsET+oJs1=pq7Q+^#Vr%rh6AOE7$kXhqed&51J%k&)%RJY85QloR)bWRXji}^We{0b=*ejqj!N`}IoK)&X zAel+=--82`+N|l-u1Zkhh^KNP|GZn^o1bc(bh#NbZ|&SXJCQ|YGAuQUn*E0}Z%g^< zNImNVIVdX)NvCXob15h^+(~_NDxv|g;ShpV5a2t$^T)*vO;KZ;J#J`s=$nA}Ra%r6 zQzg|mq5H4z}>iKg7{* z+q0=7nvT2BcL_`t%qgigu$3YN_p`MM!TV8^AxAf-Sm@s;r)?ktQAa7KF0aGOu!t?v zb(B5tt?ebS(e}uFeimNl;5}9qSMiGf&1V`*cglf|*9vu2PhFSjtqva^da6XcTqXzc z>TS}SOyH%+Dgo-}&fweCdDrgCEg-+Rx+(|%$t_S8KYPfW@&s?$+d`onFLx>^Sbq$d zy%K;rpKLuUI5KFb4S6?lgh5u_1^yS zMK#e)d$0JR|A{%LC!yp`1CaI9GK%V(qnxKEW0)e_LOyEsUBfdic4??A=2P*HtXrn5 z;#JX# zH4oRFFRmJJc6 zaDur5oXy%8?tu&~l^!mc9Q8MO*~e6mXdc3}WBObAZIa}Y>s6lTZEDVDj(Z~vmVKUH zcXG;H)i5F``c~b{tt#quTHKqMuiTm98w+a|$FnL~@HQTYc+5snWP8uv0q-@qUC7}z z%Lh?@nV$p!o@vHpSsVqk&$QcK2x@*orVRN@Mp*R(q3toC|71jeKTc4b)6wba8D2NO zqt>hAOQF2S>?O(I=k~?+Kh)TgWVX7(aCOkJLfYS}Q%ATcB15YV@sRAU-QwO=j8Y6{ zRe+vLxY^mYRImdZ;Zz z?5%6exng@oL2WZsri1&KO^vNsrS`%p&OS;vL%RG@UWby{q-Y~K_1ClQxX$cXynB`I z$i?MlKjsdApC5iASnv5<`|)v#mLP%%zyq6`!9&wLxQ>Azt$Im7hVBagd1y>ffO@vQ zAaJr2S%nHCZ|ajJF~RaKAPz|n(;R#^W=#3DqEXH1V@FPip1;nza3+OB!#%??mo~%U z3e5pe1VNuS;!*3(`M^L1LBPtV8D0M)6C+b1|JvEaiQ%nS<`3T&_(^4;YX8`zuETkx zZaaeK!fjT^3e8T!>DUv&uj;fnmmt0*_2ppocJrNw#MJ7W+EXw3@Cb%INY7_V5<3&x z27N#kqPNcZA-Ym&BH;dOSl$9bconmSXC@=yxE(Ku$V&Ev-nkc!X(49a$Ua1)bxyb31j9{rm=A%*m;67D z%;y=`m1iC~ul4;hLOwU}5)12cM4WRu9XJM+mjCNjgDFwH&E(&n{B3B&+L~R9@I|Mw z$82?>69lw3F#4vGOfaSrufxh-8~~yjdDnHwodSCk+!BB_eIA@ zF(5TBc!S#!F~`nMOF3a|ZJIW@>(!-}ZZGjL@jv7_z* zdVz6SJ{K{ING9w;x3RL2nh*$#Wa9sQ5cc%tX2=9FvdKZyh*413NNciw>Uc!Jgp$%S zf82k}k2fl_AjEk2Z$tm%61wHn@bsXv*~IaZnA;g@4$~sh<=~=ww|L684Mf87qQOu2 zm{TwCFqeJ(B~fN7owdaWMmNvHqdA)cR5E54{_d<~KKUbuouO1!HgmRdz;{5E=9W$8 z%tVcn$jbSx`@E<%;yK&vQZcWnUtBPv3|iYANZCDEZRS$1GFLo9+&(-_Kh`IB=P@)F z*3;p!jae;2TpF)HRC95@q%dP4Z?YCQgZ|4Rl|M1zQ%nvd@Q92LTEgcG;)1}DO_rtcQb&+gWzN?jeNWGpP>G>;)hgc) zqOBhzW~E7%p83w04Z?LZYD7;$K_aT>L=`%trKn$po2moV&i~anxT714TwN~4g3qsS z$H30&zv2Du^6kv+hkLeLO+RY{@#8dNxF#+Gt^fl^rX%>a`xX^kPejdUAnv?9m18Z%kfz>$pyJkH+$un69zco9tqtFZ*(ij-WQVEVaNv<> z7SpgImJ-U>IW&;aVr{l`L>H;&=_s#e2u8nKyWpc4|EF*M+xZMgak`;eHY^hPXT%>A z`3p5M%pj`1;ITLzIz%Zc#5I~Pz<&8yF!|d`=e$D9HoMB8+N2Te;Q}XcsxMK8h@9hI zgK{}lwVvBEeiD=I?7_8(w!d>%(}v4;Y;&!QJs2W-8F@7Ixk}!UGK%&W@j^ic?lLF> z0A%rasXOR2hID@GjaeSAuNZZbx9GsdA?A91et!Ap>@h3WW_G#O&-J0r>{vm$3@lO6 zFf;8b!+CF3M2cq>iui=tUimxbJ}BBu=u+@PABv~W&l}ld_7Chd=h!qYzs|R}PwqY; zv05g-#*hiQ&3LQWnA%zaF`bB2iy%=T6Bd`F6rUHgP{nvqlD}6SnX`3al3Q=rJ9<_#KRQKy4?XG49+Ea}g>RYT6i0bX}|37oV z8g2X*>TPFqfqx%UahNj6=JEbh4UZNP++SxmUVZX9_KD!y4^QUq`@~IUmai-aj6=m_ zbjA)C_55|I{r@iMh=-PsB}O}(H0k=SX36cBak|Pl`nBkNTPf$!Z}C7XB$a0oRS9>! zU9@LWGo~32ntMAEXBd-DpUte2B!W(gp->$vj&fqijM)ftN;62Ez5gvqbqJzIKN&#@ zHB^bAw6FWWs=hKRsz2(Q?(UKpx^(CcVL)PNhHeA|0qKyC?odD&VL(7~=x(GzT1n|1 zq)U*}=lK8QkVvG7<^ z$r#hboW9lVfcjiH0CquR6l&PGlLi|!kvX~PSS9H`|3llFeZN|L3WynnaEzQ4MSd4x z5|Ig~nArg_=Tk$9BxrdMTBU{GnQpvWl_K*lS0 zsb+4yR3jvS*(_z_uc)oBnR^)p~);-7COK3BdFL zOzq#9hx8MjteOAp&f_)k3Qhq~KLl?cw_g9Idi~O+OHWwI;QQ z>>#VvH?zMdtMry~qVZkB1~hQ<#txVwK`a7{QM^R`9*Zo&ctTm37YQ)@f00;duMNaN zhD2Ip<7?86C7`%Y{$d|X-7i8a&Emy7fNTbiqF*AJp|MN4)PI?WasV>=0BW`$u9=rP z>l+>igCr`#O$1NSdT4lgvk>VCeLM!aq26pDED{rYbS(hr6;c(S6RsZ!%;U~i=`HTT zRnWQgF$Me--Y1Mp#VWF)l*ny=jQP+Hue#XjmcZ=7f;dFIFhpCQ=_6ZDm4D?P(9 zY{1Sm!u+7Fb&aAj@@@nDn@w3x~5Tdd!Oga(H9mOJNVP)krf0-h#h!K|Q*zrpef^0EQz zGPIL`>#~iNBWwIt?&1BWhwPQ*>G(lYe^|DPF)k~5QHwz28up5d*nJ2#<@igMrmj^? z$^h)7`d!u8SG$|I@IOzYqEFUnE)+gzuD%v)WO2C&>VZ7o!o0}^L!N=d6%GEprG$!J zQG-2eI*e{;m+|-`c((Y|<796CgKcXn zPjSlu)(j35v~X_0P?Jl8*Cef~`K%TF{9AjHp_|M%spow1oaAgK2d+m3;1BlE^6mhC zkL84+rc@vG6nr^0b||aG7WMQ>e{mKgadd>xVK+mRTU{?q@TInMb_tdJ!j06ffcGeU zU;K>hrZ6M_Zwp&_Zs)@aW)hh4JZ1a%10xvW+SeKtecqX!)XyRvdRnri0okpGP7 zNR{lnt>l&RXS+UH;>h{4PkrMH=fWvjWSut;S62}-+eZYg>}- zauY1+2Yy`^HIe#}>W31NuVl6}`0e<(hOQJB2o~|lh1_D`LpFyV7l>0!sx;$_x7Uin zaT2gKUKkszKq}7G)lPFbO_Yc0xd#tPrXAfcWVEPCdhm{J z#>YGV++tPrU`eJs3|3Soir32-x({VDIBZ-$G7_2Z0tU&hx|1Hd%jpLJ(>5hM{jV>YWi^I{GA56l5_YPZ2Q=>)BKdgFc8OW zCy02UB7xiewRS64GqHJX5#J8_2dp_Bn?9`7Dho`?=6nXH2w9QmmTP}DUV>Gq{qm=u zAdzRWQN-OQvG7s|(jROpGvFv_qk*h8bw;m@KTYQ?n_BPPWE`gHQc~i0%8}ub(FR(jlL2_yX z*d6zz85kvbI=C4i`B{4dip4@UFdl*zvi>;*Q1(eOrJAH~CiT~)1LRKkq0ROAl}BC) zZ}CoKP(Z*@tbCM5R}u&iQz`9lFsi5o@85-bY-CBE=1QPGLfE1N0JU(3dmd_LyB}aU z-b#P&5nu)J%J{ESe}QRa9dZ`q;iipF24>mOe9N=U{=$9|%Y26z7+>Rmej@JlZS6M0 z0Kpz*sD`g06x$D&F1MI$X#Nf%{lc>Shr!^eeIt^4>p$~>-@8qx_Zb6HHy0OPZ5Ds8 zN)KC~UaC8w{M@sLEM3%7lEf@MwC!smYv-U!s?FWa+_ zeT09Bs_d0qk_R7vTS|XUas0F@wH`fldtN&AxuaS~D2OF^AK?v^Ws2$d*l#ab3_v3Q zZ^nh<`R4NOu`Mbc#d>-w?yB}zey8Z2kx1JAip|9*U0y@u(u0+N)>W5J?c%+h3b0={ z`Kw8cJ=0iA|1$jv;jh$PsX3i7@}3J96K+{J#E0WjQ>} zd?ck`;(qI|EY2}1Na3MkmTN$RqwtRnc`J3#$}#9D+Hv)l)xE@T0m5~PcfV^VhDA9f zu*IhM%zidRx727HEP9@kx~M}$82CXP<3s=6^I1mwg>yg0(1VhPTOzY{`ULBN%(0x; zr07W-)4${dJbA!6<9fm?I%>@g94Sd9R0)|hG$~}wB@W`!l43aQSxH2Z5!z)1h+G_wn6u8!+H*Oa*Zt%0 zvWi01e?Ly&JWl)PlKwkC{g(sjpU#~EumoiVqJmS|AYdPG4-t$9erB0#wu?|cOZ}|y zBo)B^fMRlYcLCg@sX!X}t;G{grc_kYB)2?sDo0@&5GcM7$g_%>ba(Z8_ zPY(ufVHoYDtfq$L{-VqZ|MN?j3g>eZGQol4{)Dd3^$w+uFuG<(VhTbdo+;O6F=0ZW^LmVBV?B6>Q-qWWD?)T&-pXryd(*DuO~(Og+JzCvd8?!k=s`RJ3@ZuPrr9Bt}Uc z|2@eyImqc68ef$GJK%Sc z%rUlj|6MrX7G)wCbjeW2O$m{Rs`gJ&2K#%CA3Z^Q`%}OYOg`dUt?{b|%euoc8wgcU z$hFt2vTsRPkv)CZNu6Sn-*&ucO81ZXmA}FLW8=hcT==VBxbRl>KMEMoo<#p3Z@ujd zMGIW}uT#k1eF*Cf0t5~G@p{Hcz?q-B&n5-@3bQT zV*9i0LD&9w=5_}mBZp83xf5lY>OY?*eZ2Jvl~s_Q0;Jbo@;;VlYrBZt%YHEM$o|@l zvftkI`h;?(BZ=MIfGgwmZ%)Ua1W1=63Njcw0R;+bQC2e0kEB&Ns%Km=qt&#fnd15t za4@&O;xhme`}Um8$2P@|C4$GnHr$iDh|QrriTzK9)Gn$NH9V}NylzhzJFhrq5%rSu zN(q4VoE+ONtWbe(10-2U9%!rYw{6t94-w&}oA3^EM9sR5Oz7z~YEsc0%`II6Rpgj>}^2|StgPatj@S&fH` z3%-uwgoi5dk%w@*t9N1eg)BB(nSYmT>}n*J4_%C41oe+WltHN{(eFMkMd@Nj{_ENM zvUKa%Z26MWYBl(D)`{Ak(Tfr&O*vBwa7r@>tC}b!@BEcyj>^cvjV25xe8hyxfXxNQ zx{s_F8ZWbrUzTl7g=)P#wkzu6tq6YuZuBeANdV0bBjRkw^UI{K%n z%x^S1I&OoQ$PqWu;pr7V?z$9;0&2}e&T&Qe7KHCdWS}9rHY}=hNrx)uNdl86Z^K2H z@=7!G@#HnNd8dT>xZ9B>RGYE*_`~PYQ{Sa<$&&-~RO;FN20XLX93-ExOp>m8NHUQ= z+6G7}1cyFg1rf>noH4EXu8O8iw$0o={Q0wZ)0F^3*-z@(Qt!YQJ@MH7oXxQOlQV{upO*ww9GT*jzmH$n2;lPAYi2yBmn8hDc9s*L;1vczAdyRd{@T_9RI* z^zI7Z22?!0M*82e_b}0WyzhTqTy{oKfy(sJGbevuk^-G9AVADVL^@KB(8bL3|MNArh6yT zQyhBpF%x*&+GY)olSCAYxus9l_pFt5Rg#3dV9-DmdLa0>=v)kUuOs6v`!1{-?ieHR zK@&fVcE?_{KFjJn24UYD7Q2n`P4bZ~?}&Rb*5|16OX*#fPtC>^6y!;k0*+j1<@+y8 zu)giv)Q*PWrO+RRTs_c0doskU6*ZDwekm!XsdFgfVanmVCnU5Pvc81AG!@E9mo+Oa z(Mne3NlghASAzNu?(@_{b|fJgR4L_)fhOi@g+E49Yzl??$D1jRu%e#E6$N%@ zi{k%KBR(#zY@&!GqH-GqP7XG&+z<3gxpsp~3OA8-Es zA%)_gnBs@1IGtF6X)$CK3CKs4@MKPcJ=WMMTMZ<<^?7~Qt}uevpO2;g{7_bMq}7-n zr}l)9R)P;Q?ix`ogz9em|Ggns+!GT?Li`l9>!IDf}mxc7*;+@_=r?NcF|MUx3_a+;95(B*M z#1tqnr_@R;`2&hcwy44i{5QY$oo0H&^mu0!*&O!{YP&5H%@om)TT~{CV|}K^dX(|C z(?d?vCw3h;lmla-qm2m<{wn{psF(NdFrkfC3pkYb1hzLDUyQ?j3L+xU6rdoy0Pc z9+hDTbP?21B5}yLU@;u3QuhfD0TK4Kl238vxM{CUTrD%lfQm@0jpou!=CLH z&$13xU_i5+64K@^v8B`Xe&wdvz~!@g?$MLs=oj1nJqS0Em8kQFFVHXZv|~4?Z$cJ; zFzyJ_S~oK)kIqYU)o(|jT6A|%=Sf*djL^O@Bx!iRy2a27GY zVj5^A&1O)=);j*NyUW+l&21-<`2B>$>UAt;)_>6`JAhex0>@wZW^L|luE^T1ll}O# z;GHbEZlu|MO7-_r5GVC;RAhPFAF>URw>R05Wvz-Lmk}caUVX+&cEiSHR!D;206R>a z?cpG6j;HwX6X(ToWwSyO^4Osj365NL4mw9ai@?K@>QZ=NQ{PD=g`LPxgEjD>)-Si1 z_?@+tkVi}}+2c5NdD7a~XwBcJ#0TTq36o6S4AYILb^S8hf zl2oa4_K@cfgbYi>_PKNkqRV?hbV6u|$sWP!pxEe~4HLsUUBu^o&K8S@dk(7fhonA^ zp*};=n+{pa{iSm!QQrFz{v`739X9jTc9R2Cow1I4z;K=B6)O3eMZ5H^ENpJtmlS0{ z`*uQDlLF)y-enKs$=&M4Nmqnte8YB9=F#ZOTO{w_3H)ujru|*|(Qa}^Gi3Qhv%7TmeYbb-F($vPd)51z6>gUgK!wwv8Y?-|bPe!pR&up#@`wvH5V?ux) zz`8p)Ff=rtx4W~GjFRfP^4ajVXI?3A?h3Ms`A(8dz+b#@gVaE>U7aA0 z>1lS|PXnEGD(uSjVl>=eL;mqsdNccQGcCTrVpCZBl^7ntPR+aqzv{qOVCY_UfviQu zySz9RcU-l8gXdWIy6t#fyi@)wx$QktADdDvHj@utmPR}@SL4fX_8T&QHEcy?kL7O$ zv)8D$&{+w?7hl!x`y0NZt7C5nf1?kg7{o>w#fGbGqRe1D##4cw+FUjeMefL-7_jM6 z8l^%|S~RR{Rp)-;oZ!WK6MdDU!yvoK!n0!hULhjsO1|BUc*&?RA+5j^=a(h@1Zm$;l-z=s_Ar zE-$@DO;x-mF9XiyUw-q3LWl@yP&!VhU2z-2prHUsCT12EHWeTf2KWYPYBnrC`9J?v z6JG#cP@eph(8SYv9b>0WE6oxd<~BMlb-KmW<-dk2{>y}Poztdn*0&s+vch3FG;5d8 zqyPvPK}1bl!}`Q)6WmTz@A)3lC~1B~#P2?}$K>L3n?E>JUY6VV`q@uorE2KJ#zxE} zcCDaGZnDq+vpI6JV=jPwGjolFvS>G8B`m&}WZZ9GZ%!s)3=6D@*bR*LG%s!+X|6cF zeq)|&re3tW*Mc3V^g zjo?blB}$0I8E96n)aM#K8j+zP=XAJ+4%8kxw37dBoG(~zh#!7E>cQE@B(X8@9H!!x zonAyWd?-7$Em{oNbBdL}?EM~?Cct6JK`yEX`#30-wNWj=g;s-TNPBzQMfmJl&9-D3 z5^#e%-6?X z>+MemGOD*F5!#a8L8usaNoJC@TTiA2f}qogob(-p-DE~|{8TJulE7AsLyCy3ZxbUZ z-FTNnsWQzV>5Kg$J$nOIHr9_;DOK0E3+EWUFYK@}7;CnfoW5av{~$TR`@9bbF!2fO z+C$t=OZll&c?q7S9l%SSWtmg|Yd|_G^>r+7@dBeZ*fKq30llVfVfSgw<}|5XB_xUr zFba@TKaB(goExa0d*ejdL_F33xSqIEDKNUp`S``QFek2b@;)xhr()B_iCFx?L$O9w zqBf-i((pDs%Ok;@iXL-tIO0v_2e&lyx7%~sYvWE@%Pzr~A!P%WZ=G;h#La%onYAdd z7cYcLRJDMnpKP?T1ZLG$!r$=8s_}aiHzEc!mBZeQ`w%0;8Rjy#ic*M4Euxk%iu(?G!pckN4h;p^w|*V;z3+IOrV2!FwAvpom0IXP+!~kdu+f!Icn?DLSRV8?q04 zD6i)~lAeIACxwJ8@*F;GGj03imheca=WUB7+iMp}$xs&~?8c>1J*gyf^&RvVPetcH zkgnZ2XAd8WIh_OHq6O|kLkn5PC`9D;sn;jY?E7k&Jneq)4$uiF1M}4b=zq17ROXVk zD+K?g1s&W2USq1?Y;>hgV^2KfnU4vQMsTNkW4os`Od;NmTbG-0Pg(BJaaam2BTgb8 zUx1z!3IWwsfhmYHe#U{R=2DdUxh3_tnco<4;{s_MlipCFA;cb4sVAaD3ahne4$&}x z6>f8Cx$evBfC^@jb_D)|-RjeVPd|ZWA$34YM;hJ(!efqL_i*==WQsVwv)xw;(_HL6 zjCf>BD&FY2K~MPPky;mq4~qUlxDkJun90@OB=M4SqP59BCM#p>F_=80%n<%X{QN*f z;12UR+u*%Sx;t6kaO-K8NMs1O?zQOm%(m0%_9u5wyRJK& zyBNbypkE$GI-;n3pP1qOxm%Xrd{kd@2>E@WjrkRW%caR5AA2+V%SrwO{}&@U^v2|w znAzwGIWkMND`l88lJXhNsuUk2A_;2+pw?fd_Y^4hh_fj(tKT|joPjY9-b~Y~tqI-4^DvQP?^eP2D4IWO^|qTJ&N>WR1j}4m2uq z*n6K1(=^g#OL?^$c8a7hJ&I(9;d@NplX@UZVoP|5C!*Rj&)aClLOt_bx>%q$HZZTE zq7A|7SGa#HHIzZ=>g^kX>Uwu~!AQnL*T}%d%tYJ^Bi3DAf^bsg8px|~%y|LA&HsN1FLrQ1xpX8*;E6AlIUHTw#my%Nk zlj?O{(%s!wL(WXY>gpXE6Z!Ps`*+UB-pN&ODfaQtWz!*2cfEHzZ8o@oy{bfNXT-Kp$O9d85 z9~Q$BQht*0DLz3NoTEQ$!+w!m?$V2;;h)0j zo-oh&D7Z;x`Y~b&x+HxX0fY%PGq5Eu4Ql;P%h&klrl8j(aCWM`z#XiRp< zO0nX^i)%y*V0ZEdOeyt@Mv-mpAa;=cN<`&U9AuG!NhHw{RzY#3l91^h6RlPBF@wV) zevq=o;6gr~Bc8q%TE91dDl1x(qQ$_yxw_bjFkQ0q>WvOWSXo=EU?a)i-$90RS(qzv2aB;H)3PK}CociX zQn2*n^==D-lc>vI7nTf}{STqkhs)TbfZ$2n{re0G<2Or6DS(~A*<9$|!wi@Rl>No@ z?r%TKUoerfKiyq-mTT;v(EZd{b~LOL+|HXdUtKI1C+eYeSVz(6Xc0FK`o|Li@y3f$ ziX*D&$DqNqvwLm4T+rq3$UJ}T8{_iolNHyEhs=~8?PiFQxNo&P*D)#hTnOka0Oq18 z!}#Mdu=Bru@=&A9=+X<3b6NNt*C4~)ZH60zCQ1JE47Lu?7*)WpHpdIMh`nJq1nV^` z@V7XyRUWL12Wx(O)cxX?zFm+UBUdbzLk#}Dh!obb{8I<@>>+g0w=}D=7YtCM#m88| zrsA-bD(gcSYMRv&=579a4|SZO>CNs(+H0o6K6c)K^*C#16rqsX^Kq5yah!a+b`UL0 zk}@T3L`Gl7jT176 zBo;xkVNt@=s*wia64Z@wwKy^U&FX=NO7TpUyu7>;XMzG5W}QoiQ9E}%@5yanhEiVC z3N#zxJ){yt)>$`<@J_+UQDJpNf3Y0m;Q_&jfp} z;3g0iF9iF5&3!edbktfz`Q60HSqB=!-)g7JG zFa~KF^ypY~3I*W0F{U4Ko^MF+5*g8arj?kl`NW`(D}vLMttlZ8Ysq)JKH&PU>sf5g zz^(Y5%Xh&h&3TELSdEopf5$TbE17l0Bz|=39dHq^bR051JYxpeO%!G7_YN#KGUAd5 z9xgMWnBlL!96Op|v%8=w3#$@%6ximbU44noBlazAFwk|obw^&?eGr&YoQ3cBbv8eV z_Gt0)meTKmoMTPARKp1IYrrckcKFuq{49ypft-!gst1ca(9y`zDT1kLj!rgXh0W(z z98&;pNrK|mN`1<94fl3vg$p*NA_ZQ}*7AN+7rAK5N00oIIJkvl-9${{djj5yc9-%c zv#uS|inZe~D=TXhoig6=cDPF7+80Nm$lOGFFPNT%1R1%*M2RE4K{hJGYZ70Hg6$98 z%}&_PZFMjGHf{E|%TlPHiDWLLu69DTG7L8KGjzr&akdkq zLUjg?V&GnAjF!~iPG@YLHcFPV4$ylCEtXvacuR&GfWHfik6!!KOA7v;=0?PSw+z%=*z9MP zgK9x|SvGCOv)bajgPX8;K9RaYOK=_k)wF&hhlX-y;|(b5b9u6T35RA64b+D1IkVW@ zsJjHYY{;B6cq3L6=~;BvVG<=lKph_?oNYu#M=;iMikQFxdAtDU{jRb<)n&7b*mXqw zv9$CcbSf-~ymLP1J;IZq+i|6L;-UZvc_#LiJAz8PC%cwf$lwi#WiiZq2&LjKW|)&m z7&FwjSCgMScU{`UpD%BAvji&*SrHy5w2M&MPZ_py7?p~+v6*>d8TDEUCZeFR1D|sq z#kU%yekwPfQDpG_Q1b1IY|c^vK3E=UHm?T)M`wLoc9;r#+?%UIV=RNS0&bF829`Rt z&G{DOL>KW*hK_*Ewsc&H185(YYaJUuu~{&(S%PCV@ldi2H&3GgONqznWfI~bIyyR( z63W*4hiws)eI7ZvK(cU9PxRb~G^+Eo^G0P9oqRN*7mGO^`P^k}hE0%CPwXcCIbS3; zT`vTOt7p7|Tpo)nTai8gdbHEDYgMaWb6lZkK}UAhp&uH5whw^qCY37^!ic$7Gef zZlB92X6zaXqI3+KsBvn!$(M~>Jl%MGHF@3`2Ub=DH0-vRgoB3`U!JKU-%E3F`50hR zQrntv_g!42QIl9^@jN{1CBho!))iOjknZiZyfdZlo0U-A8@ zA79jO%Pw*BN--5eGa&?vEp~vO+gZ!8AtFx~>l{pmCc3e6_{Lr~CwEM?=5)1=BQ9LO z7I?X0$X;`PWK1>7I=~J7RyA3146L=j1kSEUa8*h%6!)zYwqix}@$$Yh=gE(I;b|G0 z!f@(|ZDRASdxokzvXHE&p$e-)g|#{?$Yl+&M$YB%?DDfYggN#%QEJ~i4WCL;Xr^vMYEnZt^&<1&}X1ED$>lV!MVXQDxeI<1BQffh# zS`9Y2|AP8e?YkODeoD}i?mb?XynyMI z_1htlYm`S`*8q3kg&e<33ZcRv86WrSd}h-JCpMw~neu+|h5Njtj#(HseTMpQp~>4szioIow29?5CL9iM7e_2!Uqh=>g=pphW0YGFrX7t z{zg}Dfs)hU3Wv5+^QA=;BT|qPmwa+};<)qGx3`H|gZ6TX8mxTHZ#!)5r?0sgS_y7( zOWZCMG&<;4p5iF^OHl%|jq*Ewz(V3Zbr&tPtS2ty=U}aT^-LzV4>lLrVCi$f;)3kr zL3C(iK@5(&JxFc#&yE9TD>~(GOoRQ3m%YXwGR4%_`D*w|zWm_u zdG=@|jCpFj)f5DhkyuC?+cuupfbnHA2w-3x*(i$mkVxp#v>|Z$;jikOEr(_y6=-`C zljuLYq>aubzkZFV{G|o96-ZW!>8?bM??31J5_j2v?8`58QdS`XKmW+x!f@VRL-mtt z+2)LL*uNg%s1_=Mt|2~lw)xtoN#u{PU$I!_cpum7risd?Q{^d%-;19S`23pmyo*N& z@nsL&svYP+iq;nPE(5Y&59<;lumY@yiD4jLQN!*@H}^{^7%d1u(Q@uGW;|BPEn9xW zD#$`v%}T?bsEPfY2CVNtihJr?YEJa44%|lm=GSaB8Z!#w`p*fvJ-oxYdrV%P*zi*X z-XCth`=e8K^xl9X53GKunpc%dSkK}>T`!G)7`EOd=9MCI+l)N@F=){mJ9b-q8Ym=u zxM7FO-rP>nq}9tY6)vz*p1Q_}c#5ByZLnrAIUB}jQ-{rlM;to>{6M!}EYLGrW(e}< zkJHeu{k@B?j;OUn=+Gy{5OVaVa4p-EaBM-g6OOnz*x1~F7WcAC3bS|7?46NgOb=ue zf(FgdHs|XREG=v-E>h7huJoF>JZ0T2)5(di^WZXs&C00J^A%}CAIT;U5@=OS4D*NK zlY2I)4jNK0xz0yF{iDkmfzZY7gke*bh)y4c>hlkbY6w)4**L_gXoul18gql{x|V7U zo>OS-rj)V@+S4d%VQYLa>?u3=;Sgq*0@T3)Vkx-^xz@` zxw)&jx4z~QMd|S+MPXU5--k*zev1nlp_*Q-S52(52Oqy`{z0%JVIw~f}R1bm*!+y&ke=E;n+R%0-8+*W6OnE?_pwo zznI~z>1V)sY%Bi72p(RlwSxQ=pdKf==&hSycKO-{mi-S_H7a4&I|}Q z@B_6xcXs)@tOMK;V;IABT=M3tN=xF!Tlq4cPTOeRe8o-bO0HCDe9yM#OO4y1F-K$C z*z3_Rj~xdO?dF&|jZfC*dpQ(e18P^O5%X(3wK_HqmocPD|DY5>`=_;>)WIks&464f zadn0{(%BWiw=W4@XJZFqL5{o zd}*sN<$ac-3Qt{hl!Z-}{>7Tq6bRqyaOtmJ)dP`{H&5axWi(2hh_xegUE-Uy0&BsR zAN_||uj}z62{VqbtiHQX`r55PROVleA4nf-53U)6zf)T}PA2{Cj?;p9feGzQ?IwgT z#(aGTUvBgr9GJ?fIUxq?4e902`_V!L@Z(3j&E-$Oa={l>gD|19lGM<~%bCnmVS?o! zp0>mg+s^Zec6K{Hw!(UkNayF2gDT?W)DlHW?)NlcJ?|m8l*q24dgR5mfYE&c-gHsu00?Jn&zG{E>DWlziXJ{OJCzIUKf+fpK6qbM*sh1d5B5 zi;%-=3Mw3Ct7Q|MkKFz(NH1E!s$=={*)SCPTq5w<{n9P9Q5`daEo04Ori z_~}SXk(odF7xC&|20wnclvVj>_fK1tzuLrIWF6x~xM0@hWLwy<6XV`fcTm50Q`kxa zb$x+Uf63-Xyex$L9jiSo2;XRzX%@!%=pqj(a=3AD&tEIyQXSND@%>fbX_v#+VN>{W zKVSKaYv%`q2*fl*Fc+UjHrKm1P?ZS;v#ivfqt0K^o{L~G{WMS1-=1^K-+{l{JK%qB zn<`IrD`zP306ecHt80JAjvYNZ96L#&!PZNaX6s7JO{dJ8Ojaa9)^4-)alx2P&g;4} zXpeajC!Ejt|JHL>xK(N~QBt(#;^n01!C<{+4-+Gbr&)6X)zk=koh}I-zq zj{m-N;P7ON56s`^x~+d`ll~sBLLhHrwtE~4O*ZT$VO=H9>sttH(|@8{3nlwqc&=iC zRQaqp23tX>PZy7z7b3xTC#siz@p|3uD6THo>-vI`98Rx_ zzD$1`zNF-H-c=;X=uF6EI5Af=_%zjI3Sc|7jdK?vTubV^7`cqHFk{B>&-n5~!g(?~A?!cA5Zywi$-KClSXyFeYVT=<8de-T z3Y%Mza_BCkO&{U9))nTvbiMKeF1SCi=T>xO9*t%yt5D68O_+L9ek-TR_G5*MJAwXR zExbfF@i%ttMjG754@Nr&Gwj7pv1iu3gt^8EjZV^W8U&?TB1QW7phY=p5I`#ZPP z7R&49R~_|VpS$hkIEmbK2yDGc7l*lDns&Dk!+FZ{Z}aJnRR>(zMrwL33%r}J-M*|A z6T@wQ#ExSsW0l*z_Hr7%cMJw*v_FS{*ZdRcU;=b}FLis(ziF(tO?e1aJFH*0yR!eR zOr${OVaJcZ>!WKeSdYRULnvzv*|N?V=Ya(qTJ=*QF-rcyNVDiirD4p~@S;(l(J z)*5}p$}2B{6;5ruRm+i2e{slWwI|1WtNXzTDzn4nt#2~36n6uZks5}sveQ)ruN+?% zaadzhYVwIVtVMO=vo^E6nT`dW>c4(@TG0lOrh*|n={GaYt?xX*=n;|&>om}#y-s3* zu?=&Z!qq>BjaI%R|F6&pJ{UUzXu@#9#6oOi@!%2ZSz3n9EJD2uB?={bFF4L}`SAG7(I zh$~l5VpsgBVik8?o#$A5IhN5H&I<)AG)a5W#LJD&FHKLvq4#cephZF!5d znW^q~t~%AlkoerrbH$ehH6rC{cgYtJeoqW9yB{dw^4qGob^Rh%?5gvAqQPK^vh!8y zh#wC`=b&(MEBiyObmX8Va??YwmRigD<9x9DzHsSelnCoaoHsYx))R1D*IwA|NIlsC zv&l)!nzr`tULWY^2@t+oUt!97Brk>PS{LsF5#Xl>mC9`nLzj*&y@$cOG zV3|AC1_`}(Bo;;gd(NJn_J*&RkAIU3FzFzx+>&{)Je*GyLg@I!v1I^KG$r7HQWC&ramJNh~{MG_bg%p-u z8Xd&W{pSZ9$Co~}c^EXenR5CcnXHIBYbL3bTF0a`Hw(vqi0&sRd{)^z`stNdw=;=e zP#M};Q(FVk^Y{*IN*vZB;giheb4=*N|eWkyMCu`pT5=Se$`dC`}E!X-8w+7sj8t0U|?VXHunc`w*i=|1USD2 z0BvpHF#rJg01g%gfOGF*+)EP+>p%K`KA=bbpZ>oSJqiH(zPooxd-N#($Nv`xU_|Eu zKn>(>33vuzVqpAh|7BP>SpN(c8ygD;4;K&bpYREY2=MU<@$v8oNeBsvi0=)LfRv1c znDn3j?6z6^>{!PYz z83ra6HV*E6N`yrB0Z{V$^s%ro?~}#BzQ@G~y}u4%Q{Ygti9Er5p!W)o-HS>zA}JrA z<7rJdwf+QxQ_R*ol7Ntg_8}cT*CTEo-pAq+l2Xz#vd^BYsH&-JXc`zA8Jn1zncLYr zymoYQcJX=Z>*pU37!>vXLv&1R95^}Ub81@pm#-NGg+;|BrDfl~*VffT8ycIMTYmPy zdi(kZ28Sl6re|j7<`)(>;G0|9JG*=P2gtMEf6g!dqAsugabW;h|B3bAWd8>j#XT41 z{WHME`^SZW>3=UQ3TzxU5nReAdU&tA9;8Q(K%CG4r;1JVCP}_P>5YljpZ*U?1 zq5TKh{~cK5{}&{Z2g@u}e3)R~1#Y@kMQ+x*l8|va=~0iz z@;`Qhzo<5fU+V3pDba{C?8Cy{P3f}wN_<85K6$;jO1wVu zr>Gn$_1#Q%>#|j5M6_Qy9$J08W(l!mp_Jzhd@UHZLX$S&R#mIs6xXLZ8B`{N)gdfr zWRyS5Y)^IQqi7t=MU~y}V!k6q$Wye80|-#*DdYT?Fr-UT(x@s#d7FB4@wz%0+5|kl zNr5FuBzJa}ET>LRIKc;IMDgs=`b!k*>wHYjCu+rR;oTgdK6;wEihV`S*=h+l$xvp7 zb^&)#NDYPU6hn=5WWRl`96E38_TFZqBoReQ_6RjC21(MV;*B9k9seL41utTVPERIv*jxB|(b z5!T&5N)YJdNx!ow_gK)&uIugy`rU2HdUDd