From 8693ee1d290f02eb9604f0bf4d1c3d97a84f6579 Mon Sep 17 00:00:00 2001 From: Rdzleo Date: Thu, 5 Mar 2026 17:12:48 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E6=B4=9B=E5=A4=A9=E4=BE=9D=E9=A1=B9?= =?UTF-8?q?=E7=9B=AEESP32=E9=83=A8=E5=88=86=E4=B8=9A=E5=8A=A1-=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 0 -> 6148 bytes .../01_原版代码备份/HOLOMAIN - 副本.ino | 696 + Code_Backup/01_原版代码备份/HOLOMAIN.ino | 668 + .../01_原版代码备份/多任务需求描述_应用版.txt | 55 + Code_Backup/01_原版代码备份/源代码.txt | 668 + Code_Backup/02_当前最新烧录版本_V6/源码.ino | 784 + HOLOMAIN.ino | 784 + build/esp32.esp32.esp32s3/HOLOMAIN.ino.bin | Bin 0 -> 390048 bytes .../HOLOMAIN.ino.bootloader.bin | Bin 0 -> 20384 bytes build/esp32.esp32.esp32s3/HOLOMAIN.ino.elf | Bin 0 -> 11347000 bytes build/esp32.esp32.esp32s3/HOLOMAIN.ino.map | 83033 ++++++++++++++++ .../HOLOMAIN.ino.merged.bin | Bin 0 -> 4194304 bytes .../HOLOMAIN.ino.partitions.bin | Bin 0 -> 3072 bytes build/esp32.esp32.esp32s3/烧录说明1.jpg | Bin 0 -> 114544 bytes build/esp32.esp32.esp32s3/烧录说明2.png | Bin 0 -> 81553 bytes 洛天依串口指令.xlsx | Bin 0 -> 12918 bytes 环境配置指南.txt | 1 + 项目配置.png | Bin 0 -> 115664 bytes 18 files changed, 86689 insertions(+) create mode 100644 .DS_Store create mode 100644 Code_Backup/01_原版代码备份/HOLOMAIN - 副本.ino create mode 100644 Code_Backup/01_原版代码备份/HOLOMAIN.ino create mode 100644 Code_Backup/01_原版代码备份/多任务需求描述_应用版.txt create mode 100644 Code_Backup/01_原版代码备份/源代码.txt create mode 100644 Code_Backup/02_当前最新烧录版本_V6/源码.ino create mode 100644 HOLOMAIN.ino create mode 100644 build/esp32.esp32.esp32s3/HOLOMAIN.ino.bin create mode 100644 build/esp32.esp32.esp32s3/HOLOMAIN.ino.bootloader.bin create mode 100644 build/esp32.esp32.esp32s3/HOLOMAIN.ino.elf create mode 100644 build/esp32.esp32.esp32s3/HOLOMAIN.ino.map create mode 100644 build/esp32.esp32.esp32s3/HOLOMAIN.ino.merged.bin create mode 100644 build/esp32.esp32.esp32s3/HOLOMAIN.ino.partitions.bin create mode 100644 build/esp32.esp32.esp32s3/烧录说明1.jpg create mode 100644 build/esp32.esp32.esp32s3/烧录说明2.png create mode 100644 洛天依串口指令.xlsx create mode 100644 环境配置指南.txt create mode 100644 项目配置.png diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..4904dc86fdf69067cf77394fe01ca528b0588b7a GIT binary patch literal 6148 zcmeHKJ8HvF5S&e17~Hr_`L2)~2*o);4v>%K$_533dsRMHj+WUE0U@UeqzSXIJMXP_ z^mtQfwE(O?5BIPX|Mc0K^s3 zVO+;7L2RBNc7;G6NdIB}pOdtc0#e{#DPXJJ)2`>0s<$pK=e@SkU+7-*Nq6HqC=Ah#iP4U^ g@pgO{MOoK;&F5X=lo)j8gHF`Xfa@ZY0)MT*7dLYiU;qFB literal 0 HcmV?d00001 diff --git a/Code_Backup/01_原版代码备份/HOLOMAIN - 副本.ino b/Code_Backup/01_原版代码备份/HOLOMAIN - 副本.ino new file mode 100644 index 0000000..728f843 --- /dev/null +++ b/Code_Backup/01_原版代码备份/HOLOMAIN - 副本.ino @@ -0,0 +1,696 @@ +#include +#include +#include +#include +#include + +// RFID引脚定义 +#define RFID_RST_PIN 14 // RC522 复位引脚 +#define RFID_SS_PIN 10 // RC522 片选引脚 +#define RFID_MISO_PIN 13 // MISO 引脚 +#define RFID_MOSI_PIN 12 // MOSI 引脚 +#define RFID_SCK_PIN 11 // SCK 引脚 + +// LED定义 +#define LED_PIN_1 4 // 1颗WS2812灯珠引脚 +#define LED_PIN_2 5 // 160颗WS2812灯带引脚 +#define LED_PIN_3 48 // 1颗WS2812灯珠引脚(新增) +#define LED_COUNT_1 1 // 1颗灯珠 +#define LED_COUNT_2 186 // 160颗灯带 +#define LED_COUNT_3 1 // 1颗灯珠(新增) + +// PWM定义 +#define PWM_PIN 6 // PWM输出引脚 +#define PWM_CHANNEL 0 // PWM通道 +#define PWM_FREQ 1000 // PWM频率(Hz) +#define PWM_RESOLUTION 10 // PWM分辨率(位) +#define DEFAULT_DUTY 819 // 默认占空比(80%) + +// 按钮和输入引脚定义 +#define BTN0_PIN 15 // 按钮0引脚 +#define WAKEUP1_PIN 16 // 唤醒引脚1 +#define BTN1_PIN 17 // 按钮1引脚 +#define BTN2_PIN 18 // 按钮2引脚 + +// 任务句柄 +TaskHandle_t TaskRFID, TaskLED1, TaskLED2, TaskLED3, TaskPWM, TaskBTN0, TaskWAKEUP1, TaskBTN1, TaskBTN2; + +// 全局变量 +MFRC522 rfid(RFID_SS_PIN, RFID_RST_PIN); // 创建RFID实例 +CRGB leds1[LED_COUNT_1]; // 1颗灯珠数组 +CRGB leds2[LED_COUNT_2]; // 160颗灯带数组 +CRGB leds3[LED_COUNT_3]; // 1颗灯珠数组(新增) +String lastCardData = ""; // 上次读取的RFID卡数据 +int ledMode = 1; // 灯带模式,默认为1(白色) +int pwmDuty = DEFAULT_DUTY; // PWM占空比 +bool btn0State = HIGH; // 按钮0状态 +bool btn0LongPress = false; // 按钮0长按标志 +bool wakeup1State = LOW; // 唤醒引脚1状态 +bool btn1State = LOW; // 按钮1状态 +bool btn2State = LOW; // 按钮2状态 +int singleLedMode = 7; // 单颗LED模式,默认为7(白色) + +// 灯带动画全局变量 +static uint8_t rainbowHue = 0; +static int trainPos = 0; +static unsigned long lastUpdate = 0; +static const int TRAIN_LENGTH = 16; // 火车灯长度 +static int trainPhase = 0; // 火车阶段:0-正向出站,1-正向前进,2-正向进站,3-反向出站,4-反向前进,5-反向进站 +static const int VIRTUAL_LED_COUNT = LED_COUNT_2 + TRAIN_LENGTH; // 虚拟灯带长度 + +// 单颗LED颜色数组 +CRGB singleLedColors[8] = { + CRGB::Black, // 0: 熄灭 + CRGB::Blue, // 1: 蓝色 + CRGB::Green, // 2: 绿色 + CRGB::Orange, // 3: 橙色 + CRGB::Red, // 4: 红色 + CRGB::Purple, // 5: 紫色 + CRGB::Yellow, // 6: 黄色 + CRGB::White // 7: 白色 +}; + +// RFID读取任务 +void TaskRFIDcode( void * pvParameters ) { + for(;;) { + // 寻找新卡片 + if ( ! rfid.PICC_IsNewCardPresent()) { + delay(10); + continue; + } + + // 验证NUID是否可读 + if ( ! rfid.PICC_ReadCardSerial()) { + delay(10); + continue; + } + + // 读取卡片数据(用户数据区) + String cardData = ""; + MFRC522::MIFARE_Key key; + + // 准备认证密钥 + for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; + + // 选择卡片 + MFRC522::StatusCode status; + status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(rfid.uid)); + if (status != MFRC522::STATUS_OK) { + Serial.print(F("Authentication failed: ")); + Serial.println(rfid.GetStatusCodeName(status)); + rfid.PICC_HaltA(); + rfid.PCD_StopCrypto1(); + delay(100); + continue; + } + + // 读取数据块 + byte buffer[18]; + byte size = sizeof(buffer); + status = rfid.MIFARE_Read(4, buffer, &size); + if (status != MFRC522::STATUS_OK) { + Serial.print(F("Reading failed: ")); + Serial.println(rfid.GetStatusCodeName(status)); + } else { + // 转换为ASCII字符串 + for (byte i = 0; i < 16; i++) { + if (buffer[i] >= 32 && buffer[i] <= 126) { // 可打印ASCII字符 + cardData += (char)buffer[i]; + } + } + + // 移除空白字符 + cardData.trim(); + + // 卡片数据处理 + if (cardData != lastCardData && !cardData.isEmpty()) { + lastCardData = cardData; + Serial.println("SORC_" + cardData); + } + } + + // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡 + rfid.PICC_HaltA(); + + // 停止加密PCD + rfid.PCD_StopCrypto1(); + + delay(100); + } +} + +// LED1控制任务 +void TaskLED1code( void * pvParameters ) { + for(;;) { + // 根据模式设置LED1颜色 + if (singleLedMode >= 0 && singleLedMode <= 7) { + leds1[0] = singleLedColors[singleLedMode]; + } else { + leds1[0] = CRGB::Blue; // 默认白色 + } + + // 更新LED + FastLED.show(); + + delay(20); + } +} + +// LED3控制任务(新增) +void TaskLED3code( void * pvParameters ) { + for(;;) { + // 强制设置GPIO48的灯珠为熄灭状态 + leds3[0] = CRGB::Black; + + // 更新LED + FastLED.show(); + + delay(20); + } +} + +// LED2控制任务 +void TaskLED2code( void * pvParameters ) { + for(;;) { + // 根据不同模式控制灯带 + switch(ledMode) { + case 0: // 全部熄灭 + fill_solid(leds2, LED_COUNT_2, CRGB::Black); + break; + + case 1: // 纯白色 + fill_solid(leds2, LED_COUNT_2, CRGB::White); + break; + + case 2: // 彩虹流水灯 + for(int i = 0; i < LED_COUNT_2; i++) { + leds2[i] = CHSV(rainbowHue + i * 256 / LED_COUNT_2, 255, 255); + } + rainbowHue++; + break; + + case 3: // 彩虹呼吸灯 + { + static unsigned long lastHueUpdate = 0; + static unsigned long lastBreathUpdate = 0; + static uint8_t breathingHue = 0; + static uint8_t breathValue = 128; + static int8_t breathDirection = 1; + + unsigned long currentTime = millis(); + + // 每300ms更新一次色相,非常缓慢的变化 + if (currentTime - lastHueUpdate > 300) { + breathingHue += 1; + lastHueUpdate = currentTime; + } + + // 每20ms更新一次呼吸亮度 + if (currentTime - lastBreathUpdate > 20) { + breathValue += breathDirection * 2; + if (breathValue >= 200) { + breathValue = 200; + breathDirection = -1; + } else if (breathValue <= 80) { + breathValue = 80; + breathDirection = 1; + } + lastBreathUpdate = currentTime; + } + + for(int i = 0; i < LED_COUNT_2; i++) { + leds2[i] = CHSV(breathingHue, 200, breathValue); + } + } + break; + + case 4: // 彩虹火车灯 + if (millis() - lastUpdate > 30) { // 30ms更新一次 + lastUpdate = millis(); + + // 清除所有灯珠 + fill_solid(leds2, LED_COUNT_2, CRGB::Black); + + switch (trainPhase) { + case 0: // 正向出站(从起点开始出现) + for (int i = 0; i < TRAIN_LENGTH; i++) { + int pos = trainPos + i; + if (pos >= 0 && pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否完全出站 + if (trainPos >= 0) { + trainPhase = 1; // 开始正向前进 + trainPos = 0; + } + break; + + case 1: // 正向前进 + for (int i = 0; i < TRAIN_LENGTH; i++) { + int pos = trainPos + i; + if (pos >= 0 && pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否到达终点 + if (trainPos >= LED_COUNT_2 - TRAIN_LENGTH) { + trainPhase = 2; // 开始正向进站 + trainPos = LED_COUNT_2 - TRAIN_LENGTH; + } + break; + + case 2: // 正向进站(从尾部开始消失) + for (int i = 0; i < TRAIN_LENGTH; i++) { + int displayPos = LED_COUNT_2 - 1 - i; + if (displayPos >= trainPos) { + uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH); + leds2[displayPos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否完全进站 + if (trainPos >= LED_COUNT_2) { + trainPhase = 3; // 开始反向出站 + trainPos = 0; + rainbowHue += 64; // 改变彩虹颜色 + } + break; + + case 3: // 反向出站(从终点开始出现) + for (int i = 0; i < trainPos + 1; i++) { + int pos = LED_COUNT_2 - 1 - i; + if (pos >= 0) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否完全出站 + if (trainPos >= TRAIN_LENGTH) { + trainPhase = 4; // 开始反向前进 + trainPos = TRAIN_LENGTH; + } + break; + + case 4: // 反向前进 + for (int i = 0; i < TRAIN_LENGTH; i++) { + int pos = LED_COUNT_2 - trainPos + i; + if (pos >= 0 && pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否到达起点 + if (trainPos >= LED_COUNT_2) { + trainPhase = 5; // 开始反向进站 + trainPos = 0; + } + break; + + case 5: // 反向进站(从头部开始消失) + for (int i = 0; i < TRAIN_LENGTH - trainPos; i++) { + int pos = i; + if (pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否完全进站 + if (trainPos >= TRAIN_LENGTH) { + trainPhase = 0; // 重新开始正向出站 + trainPos = -TRAIN_LENGTH; + rainbowHue += 64; // 改变彩虹颜色 + } + break; + } + } + break; + + case 5: // 马卡龙火车灯(保留原功能,未修改) + // 代码保持不变... + break; + } + + // 更新LED + FastLED.show(); + + // 根据模式调整延时 + if (ledMode == 4 || ledMode == 5) { + delay(10); // 火车灯模式需要更快的更新速度 + } else { + delay(30); + } + } +} + +// PWM控制任务 +void TaskPWMcode( void * pvParameters ) { + for(;;) { + // 设置PWM占空比 + ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL, pwmDuty); + ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL); + + delay(100); + } +} + +// 按钮0检测任务 +void TaskBTN0code( void * pvParameters ) { + static unsigned long pressStartTime = 0; + static bool lastState = HIGH; + + for(;;) { + bool currentState = digitalRead(BTN0_PIN); + + // 检测下降沿(按下) + if (lastState == HIGH && currentState == LOW) { + pressStartTime = millis(); + btn0State = LOW; + Serial.println("SO_BT0_HIGH"); + btn0LongPress = false; + } + // 检测上升沿(释放) + else if (lastState == LOW && currentState == HIGH) { + btn0State = HIGH; + Serial.println("SO_BT0_LOW"); + btn0LongPress = false; + } + // 检测长按 + else if (currentState == LOW && millis() - pressStartTime >= 2000 && !btn0LongPress) { + btn0LongPress = true; + Serial.println("SO_BT0_HIGHL"); + } + + lastState = currentState; + delay(10); + } +} + +// WAKEUP1检测任务 +void TaskWAKEUP1code( void * pvParameters ) { + static bool lastState = LOW; + + for(;;) { + bool currentState = digitalRead(WAKEUP1_PIN); + + // 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + wakeup1State = HIGH; + Serial.println("SO_WAKEUP1"); + } + // 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + wakeup1State = LOW; + Serial.println("SO_WAKEUP0"); + } + + lastState = currentState; + delay(10); + } +} + +// 按钮1检测任务 +void TaskBTN1code( void * pvParameters ) { + static bool lastState = LOW; + + for(;;) { + bool currentState = digitalRead(BTN1_PIN); + + // 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + btn1State = HIGH; + Serial.println("SO_BT1_HIGH"); + } + // 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + btn1State = LOW; + Serial.println("SO_BT1_LOW"); + } + + lastState = currentState; + delay(10); + } +} + +// 按钮2检测任务 +void TaskBTN2code( void * pvParameters ) { + static bool lastState = LOW; + + for(;;) { + bool currentState = digitalRead(BTN2_PIN); + + // 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + btn2State = HIGH; + Serial.println("SO_BT2_HIGH"); + } + // 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + btn2State = LOW; + Serial.println("SO_BT2_LOW"); + } + + lastState = currentState; + delay(10); + } +} + +// 串口命令处理 +void handleSerialCommand() { + static String command = ""; + + while (Serial.available()) { + char c = Serial.read(); + if (c == '\n') { + // 处理命令 + if (command.startsWith("MO_LED_")) { + String modeStr = command.substring(7); + int newMode = modeStr.toInt(); + + // 控制单颗LED + if (newMode >= 0 && newMode <= 7) { + singleLedMode = newMode; + Serial.print("Single LED set to mode: "); + Serial.println(newMode); + } else { + Serial.println("Invalid single LED mode command"); + } + } + else if (command.startsWith("MO_LEDN_")) { + String modeStr = command.substring(8); + int newMode = modeStr.toInt(); + + // 控制灯带 + if (newMode >= 0 && newMode <= 5) { + ledMode = newMode; + + // 重置火车灯状态 + if (newMode == 4) { + trainPos = -TRAIN_LENGTH; + trainPhase = 0; + rainbowHue = random8(); + } + + Serial.print("LED strip set to mode: "); + Serial.println(newMode); + } else { + Serial.println("Invalid LED strip mode command"); + } + } + else if (command.startsWith("MO_PWM_")) { + String dutyStr = command.substring(7); + int newDuty = dutyStr.toInt(); + + // 检查PWM百分比 + if (newDuty == 1) { + pwmDuty = 1023; // 100% + } else if (newDuty == 0 || newDuty == 20 || newDuty == 40 || newDuty == 60 || newDuty == 80) { + pwmDuty = (newDuty * 1023) / 100; // 转换为实际占空比 + } else { + Serial.println("Invalid PWM command"); + } + + Serial.print("PWM set to: "); + Serial.print((pwmDuty * 100) / 1023); + Serial.println("%"); + } + + // 清空命令 + command = ""; + } else { + command += c; + } + } +} + +void setup() { + // 初始化串口 + Serial.begin(115200); + Serial.println("System starting..."); + + // 初始化SPI总线 + SPI.begin(RFID_SCK_PIN, RFID_MISO_PIN, RFID_MOSI_PIN, RFID_SS_PIN); + + // 初始化RFID + rfid.PCD_Init(); + Serial.println("RFID initialized."); + + // 初始化LED + FastLED.addLeds(leds1, LED_COUNT_1); + FastLED.addLeds(leds2, LED_COUNT_2); + FastLED.addLeds(leds3, LED_COUNT_3); // 新增LED3 + + // 初始化LED状态 + fill_solid(leds1, LED_COUNT_1, singleLedColors[singleLedMode]); + fill_solid(leds2, LED_COUNT_2, CRGB::White); + fill_solid(leds3, LED_COUNT_3, CRGB::Black); // 强制GPIO48的灯珠熄灭 + FastLED.show(); + Serial.println("LED initialized."); + + // 初始化PWM + // 创建LED控制器配置 + ledc_timer_config_t ledc_timer = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .duty_resolution = (ledc_timer_bit_t)PWM_RESOLUTION, + .timer_num = (ledc_timer_t)PWM_CHANNEL, + .freq_hz = PWM_FREQ, + .clk_cfg = LEDC_AUTO_CLK + }; + ledc_timer_config(&ledc_timer); + + // 创建LED通道配置 + ledc_channel_config_t ledc_channel = { + .gpio_num = PWM_PIN, + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = (ledc_channel_t)PWM_CHANNEL, + .intr_type = LEDC_INTR_DISABLE, + .timer_sel = (ledc_timer_t)PWM_CHANNEL, + .duty = 0, + .hpoint = 0 + }; + ledc_channel_config(&ledc_channel); + + // 设置初始占空比 + ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL, pwmDuty); + ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL); + + Serial.println("PWM initialized."); + + // 初始化输入引脚 + pinMode(BTN0_PIN, INPUT_PULLUP); + pinMode(WAKEUP1_PIN, INPUT); + pinMode(BTN1_PIN, INPUT); + pinMode(BTN2_PIN, INPUT); + Serial.println("Inputs initialized."); + + // 创建任务 + xTaskCreatePinnedToCore( + TaskRFIDcode, /* 任务函数 */ + "TaskRFID", /* 任务名称 */ + 4096, /* 任务栈大小 */ + NULL, /* 传递给任务的参数 */ + 1, /* 任务优先级 */ + &TaskRFID, /* 任务句柄 */ + 1); /* 运行在核心1上 */ + + xTaskCreatePinnedToCore( + TaskLED1code, + "TaskLED1", + 2048, + NULL, + 1, + &TaskLED1, + 1); + + xTaskCreatePinnedToCore( + TaskLED2code, + "TaskLED2", + 4096, + NULL, + 1, + &TaskLED2, + 1); + + xTaskCreatePinnedToCore( + TaskLED3code, + "TaskLED3", + 2048, + NULL, + 1, + &TaskLED3, + 1); // 新增LED3任务 + + xTaskCreatePinnedToCore( + TaskPWMcode, + "TaskPWM", + 1024, + NULL, + 1, + &TaskPWM, + 1); + + xTaskCreatePinnedToCore( + TaskBTN0code, + "TaskBTN0", + 2048, + NULL, + 1, + &TaskBTN0, + 0); + + xTaskCreatePinnedToCore( + TaskWAKEUP1code, + "TaskWAKEUP1", + 2048, + NULL, + 1, + &TaskWAKEUP1, + 0); + + xTaskCreatePinnedToCore( + TaskBTN1code, + "TaskBTN1", + 2048, + NULL, + 1, + &TaskBTN1, + 0); + + xTaskCreatePinnedToCore( + TaskBTN2code, + "TaskBTN2", + 2048, + NULL, + 1, + &TaskBTN2, + 0); + + Serial.println("Tasks created. System ready."); +} + +void loop() { + // 处理串口命令 + handleSerialCommand(); + + // 让出CPU时间 + delay(1); +} \ No newline at end of file diff --git a/Code_Backup/01_原版代码备份/HOLOMAIN.ino b/Code_Backup/01_原版代码备份/HOLOMAIN.ino new file mode 100644 index 0000000..0d703ee --- /dev/null +++ b/Code_Backup/01_原版代码备份/HOLOMAIN.ino @@ -0,0 +1,668 @@ +#include +#include +#include +#include +#include + +// RFID引脚定义 +#define RFID_RST_PIN 14 // RC522 复位引脚 +#define RFID_SS_PIN 10 // RC522 片选引脚 +#define RFID_MISO_PIN 13 // MISO 引脚 +#define RFID_MOSI_PIN 12 // MOSI 引脚 +#define RFID_SCK_PIN 11 // SCK 引脚 + +// LED定义 +#define LED_PIN_1 4 // 1颗WS2812灯珠引脚 +#define LED_PIN_2 5 // 160颗WS2812灯带引脚 +#define LED_PIN_3 48 // 1颗WS2812灯珠引脚(新增) +#define LED_COUNT_1 1 // 1颗灯珠 +#define LED_COUNT_2 186 // 160颗灯带 +#define LED_COUNT_3 1 // 1颗灯珠(新增) + +// PWM定义 +#define PWM_PIN 6 // PWM输出引脚 +#define PWM_CHANNEL 0 // PWM通道 +#define PWM_FREQ 1000 // PWM频率(Hz) +#define PWM_RESOLUTION 10 // PWM分辨率(位) +#define DEFAULT_DUTY 819 // 默认占空比(80%) + +// 按钮和输入引脚定义 +#define BTN0_PIN 15 // 按钮0引脚 +#define WAKEUP1_PIN 16 // 唤醒引脚1 +#define BTN1_PIN 17 // 按钮1引脚 +#define BTN2_PIN 18 // 按钮2引脚 + +// 任务句柄 +TaskHandle_t TaskRFID, TaskLED1, TaskLED2, TaskLED3, TaskPWM, TaskBTN0, TaskWAKEUP1, TaskBTN1, TaskBTN2; + +// 全局变量 +MFRC522 rfid(RFID_SS_PIN, RFID_RST_PIN); // 创建RFID实例 +CRGB leds1[LED_COUNT_1]; // 1颗灯珠数组 +CRGB leds2[LED_COUNT_2]; // 160颗灯带数组 +CRGB leds3[LED_COUNT_3]; // 1颗灯珠数组(新增) +String lastCardData = ""; // 上次读取的RFID卡数据 +int ledMode = 1; // 灯带模式,默认为1(白色) +int pwmDuty = DEFAULT_DUTY; // PWM占空比 +bool btn0State = HIGH; // 按钮0状态 +bool btn0LongPress = false; // 按钮0长按标志 +bool wakeup1State = LOW; // 唤醒引脚1状态 +bool btn1State = LOW; // 按钮1状态 +bool btn2State = LOW; // 按钮2状态 +int singleLedMode = 7; // 单颗LED模式,默认为7(白色) + +// 灯带动画全局变量 +static uint8_t rainbowHue = 0; +static int trainPos = 0; +static unsigned long lastUpdate = 0; +static const int TRAIN_LENGTH = 16; // 火车灯长度 +static int trainPhase = 0; // 火车阶段:0-正向出站,1-正向前进,2-正向进站,3-反向出站,4-反向前进,5-反向进站 +static const int VIRTUAL_LED_COUNT = LED_COUNT_2 + TRAIN_LENGTH; // 虚拟灯带长度 + +// 单颗LED颜色数组 +CRGB singleLedColors[8] = { + CRGB::Black, // 0: 熄灭 + CRGB::Blue, // 1: 蓝色 + CRGB::Green, // 2: 绿色 + CRGB::Orange, // 3: 橙色 + CRGB::Red, // 4: 红色 + CRGB::Purple, // 5: 紫色 + CRGB::Yellow, // 6: 黄色 + CRGB::White // 7: 白色 +}; + +// RFID读取任务 +void TaskRFIDcode( void * pvParameters ) { + for(;;) { + // 寻找新卡片 + if ( ! rfid.PICC_IsNewCardPresent()) { + delay(10); + continue; + } + + // 验证NUID是否可读 + if ( ! rfid.PICC_ReadCardSerial()) { + delay(10); + continue; + } + + // 读取卡片数据(用户数据区) + String cardData = ""; + MFRC522::MIFARE_Key key; + + // 准备认证密钥 + for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; + + // 选择卡片 + MFRC522::StatusCode status; + status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(rfid.uid)); + if (status != MFRC522::STATUS_OK) { + Serial.print(F("Authentication failed: ")); + Serial.println(rfid.GetStatusCodeName(status)); + rfid.PICC_HaltA(); + rfid.PCD_StopCrypto1(); + delay(100); + continue; + } + + // 读取数据块 + byte buffer[18]; + byte size = sizeof(buffer); + status = rfid.MIFARE_Read(4, buffer, &size); + if (status != MFRC522::STATUS_OK) { + Serial.print(F("Reading failed: ")); + Serial.println(rfid.GetStatusCodeName(status)); + } else { + // 转换为ASCII字符串 + for (byte i = 0; i < 16; i++) { + if (buffer[i] >= 32 && buffer[i] <= 126) { // 可打印ASCII字符 + cardData += (char)buffer[i]; + } + } + + // 移除空白字符 + cardData.trim(); + + // 卡片数据处理 + if (cardData != lastCardData && !cardData.isEmpty()) { + lastCardData = cardData; + Serial.println("SORC_" + cardData); + } + } + + // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡 + rfid.PICC_HaltA(); + + // 停止加密PCD + rfid.PCD_StopCrypto1(); + + delay(100); + } +} + +// LED1控制任务 +void TaskLED1code( void * pvParameters ) { + for(;;) { + // 根据模式设置LED1颜色 + if (singleLedMode >= 0 && singleLedMode <= 7) { + leds1[0] = singleLedColors[singleLedMode]; + } else { + leds1[0] = CRGB::Blue; // 默认白色 + } + + // 更新LED + FastLED.show(); + + delay(20); + } +} + +// LED3控制任务(新增) +void TaskLED3code( void * pvParameters ) { + for(;;) { + // 强制设置GPIO48的灯珠为熄灭状态 + leds3[0] = CRGB::Black; + + // 更新LED + FastLED.show(); + + delay(20); + } +} + +// LED2控制任务 +void TaskLED2code( void * pvParameters ) { + for(;;) { + // 根据不同模式控制灯带 + switch(ledMode) { + case 0: // 全部熄灭 + fill_solid(leds2, LED_COUNT_2, CRGB::Black); + break; + + case 1: // 纯白色 + fill_solid(leds2, LED_COUNT_2, CRGB::White); + break; + + case 2: // 彩虹流水灯 + for(int i = 0; i < LED_COUNT_2; i++) { + leds2[i] = CHSV(rainbowHue + i * 256 / LED_COUNT_2, 255, 255); + } + rainbowHue++; + break; + + case 3: // 彩虹呼吸灯 + for(int i = 0; i < LED_COUNT_2; i++) { + leds2[i] = CHSV(rainbowHue, 255, beatsin8(1, 64, 255)); + } + rainbowHue++; + break; + + case 4: // 彩虹火车灯 + if (millis() - lastUpdate > 30) { // 30ms更新一次 + lastUpdate = millis(); + + // 清除所有灯珠 + fill_solid(leds2, LED_COUNT_2, CRGB::Black); + + switch (trainPhase) { + case 0: // 正向出站(从起点开始出现) + for (int i = 0; i < TRAIN_LENGTH; i++) { + int pos = trainPos + i; + if (pos >= 0 && pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否完全出站 + if (trainPos >= 0) { + trainPhase = 1; // 开始正向前进 + trainPos = 0; + } + break; + + case 1: // 正向前进 + for (int i = 0; i < TRAIN_LENGTH; i++) { + int pos = trainPos + i; + if (pos >= 0 && pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否到达终点 + if (trainPos >= LED_COUNT_2 - TRAIN_LENGTH) { + trainPhase = 2; // 开始正向进站 + trainPos = LED_COUNT_2 - TRAIN_LENGTH; + } + break; + + case 2: // 正向进站(从尾部开始消失) + for (int i = 0; i < TRAIN_LENGTH; i++) { + int displayPos = LED_COUNT_2 - 1 - i; + if (displayPos >= trainPos) { + uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH); + leds2[displayPos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否完全进站 + if (trainPos >= LED_COUNT_2) { + trainPhase = 3; // 开始反向出站 + trainPos = 0; + rainbowHue += 64; // 改变彩虹颜色 + } + break; + + case 3: // 反向出站(从终点开始出现) + for (int i = 0; i < trainPos + 1; i++) { + int pos = LED_COUNT_2 - 1 - i; + if (pos >= 0) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否完全出站 + if (trainPos >= TRAIN_LENGTH) { + trainPhase = 4; // 开始反向前进 + trainPos = TRAIN_LENGTH; + } + break; + + case 4: // 反向前进 + for (int i = 0; i < TRAIN_LENGTH; i++) { + int pos = LED_COUNT_2 - trainPos + i; + if (pos >= 0 && pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否到达起点 + if (trainPos >= LED_COUNT_2) { + trainPhase = 5; // 开始反向进站 + trainPos = 0; + } + break; + + case 5: // 反向进站(从头部开始消失) + for (int i = 0; i < TRAIN_LENGTH - trainPos; i++) { + int pos = i; + if (pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否完全进站 + if (trainPos >= TRAIN_LENGTH) { + trainPhase = 0; // 重新开始正向出站 + trainPos = -TRAIN_LENGTH; + rainbowHue += 64; // 改变彩虹颜色 + } + break; + } + } + break; + + case 5: // 马卡龙火车灯(保留原功能,未修改) + // 代码保持不变... + break; + } + + // 更新LED + FastLED.show(); + + // 根据模式调整延时 + if (ledMode == 4 || ledMode == 5) { + delay(10); // 火车灯模式需要更快的更新速度 + } else { + delay(30); + } + } +} + +// PWM控制任务 +void TaskPWMcode( void * pvParameters ) { + for(;;) { + // 设置PWM占空比 + ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL, pwmDuty); + ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL); + + delay(100); + } +} + +// 按钮0检测任务 +void TaskBTN0code( void * pvParameters ) { + static unsigned long pressStartTime = 0; + static bool lastState = HIGH; + + for(;;) { + bool currentState = digitalRead(BTN0_PIN); + + // 检测下降沿(按下) + if (lastState == HIGH && currentState == LOW) { + pressStartTime = millis(); + btn0State = LOW; + Serial.println("SO_BT0_HIGH"); + btn0LongPress = false; + } + // 检测上升沿(释放) + else if (lastState == LOW && currentState == HIGH) { + btn0State = HIGH; + Serial.println("SO_BT0_LOW"); + btn0LongPress = false; + } + // 检测长按 + else if (currentState == LOW && millis() - pressStartTime >= 2000 && !btn0LongPress) { + btn0LongPress = true; + Serial.println("SO_BT0_HIGHL"); + } + + lastState = currentState; + delay(10); + } +} + +// WAKEUP1检测任务 +void TaskWAKEUP1code( void * pvParameters ) { + static bool lastState = LOW; + + for(;;) { + bool currentState = digitalRead(WAKEUP1_PIN); + + // 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + wakeup1State = HIGH; + Serial.println("SO_WAKEUP1"); + } + // 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + wakeup1State = LOW; + Serial.println("SO_WAKEUP0"); + } + + lastState = currentState; + delay(10); + } +} + +// 按钮1检测任务 +void TaskBTN1code( void * pvParameters ) { + static bool lastState = LOW; + + for(;;) { + bool currentState = digitalRead(BTN1_PIN); + + // 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + btn1State = HIGH; + Serial.println("SO_BT1_HIGH"); + } + // 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + btn1State = LOW; + Serial.println("SO_BT1_LOW"); + } + + lastState = currentState; + delay(10); + } +} + +// 按钮2检测任务 +void TaskBTN2code( void * pvParameters ) { + static bool lastState = LOW; + + for(;;) { + bool currentState = digitalRead(BTN2_PIN); + + // 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + btn2State = HIGH; + Serial.println("SO_BT2_HIGH"); + } + // 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + btn2State = LOW; + Serial.println("SO_BT2_LOW"); + } + + lastState = currentState; + delay(10); + } +} + +// 串口命令处理 +void handleSerialCommand() { + static String command = ""; + + while (Serial.available()) { + char c = Serial.read(); + if (c == '\n') { + // 处理命令 + if (command.startsWith("MO_LED_")) { + String modeStr = command.substring(7); + int newMode = modeStr.toInt(); + + // 控制单颗LED + if (newMode >= 0 && newMode <= 7) { + singleLedMode = newMode; + Serial.print("Single LED set to mode: "); + Serial.println(newMode); + } else { + Serial.println("Invalid single LED mode command"); + } + } + else if (command.startsWith("MO_LEDN_")) { + String modeStr = command.substring(8); + int newMode = modeStr.toInt(); + + // 控制灯带 + if (newMode >= 0 && newMode <= 5) { + ledMode = newMode; + + // 重置火车灯状态 + if (newMode == 4) { + trainPos = -TRAIN_LENGTH; + trainPhase = 0; + rainbowHue = random8(); + } + + Serial.print("LED strip set to mode: "); + Serial.println(newMode); + } else { + Serial.println("Invalid LED strip mode command"); + } + } + else if (command.startsWith("MO_PWM_")) { + String dutyStr = command.substring(7); + int newDuty = dutyStr.toInt(); + + // 检查PWM百分比 + if (newDuty == 1) { + pwmDuty = 1023; // 100% + } else if (newDuty == 0 || newDuty == 20 || newDuty == 40 || newDuty == 60 || newDuty == 80) { + pwmDuty = (newDuty * 1023) / 100; // 转换为实际占空比 + } else { + Serial.println("Invalid PWM command"); + } + + Serial.print("PWM set to: "); + Serial.print((pwmDuty * 100) / 1023); + Serial.println("%"); + } + + // 清空命令 + command = ""; + } else { + command += c; + } + } +} + +void setup() { + // 初始化串口 + Serial.begin(115200); + Serial.println("System starting..."); + + // 初始化SPI总线 + SPI.begin(RFID_SCK_PIN, RFID_MISO_PIN, RFID_MOSI_PIN, RFID_SS_PIN); + + // 初始化RFID + rfid.PCD_Init(); + Serial.println("RFID initialized."); + + // 初始化LED + FastLED.addLeds(leds1, LED_COUNT_1); + FastLED.addLeds(leds2, LED_COUNT_2); + FastLED.addLeds(leds3, LED_COUNT_3); // 新增LED3 + + // 初始化LED状态 + fill_solid(leds1, LED_COUNT_1, singleLedColors[singleLedMode]); + fill_solid(leds2, LED_COUNT_2, CRGB::White); + fill_solid(leds3, LED_COUNT_3, CRGB::Black); // 强制GPIO48的灯珠熄灭 + FastLED.show(); + Serial.println("LED initialized."); + + // 初始化PWM + // 创建LED控制器配置 + ledc_timer_config_t ledc_timer = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .duty_resolution = (ledc_timer_bit_t)PWM_RESOLUTION, + .timer_num = (ledc_timer_t)PWM_CHANNEL, + .freq_hz = PWM_FREQ, + .clk_cfg = LEDC_AUTO_CLK + }; + ledc_timer_config(&ledc_timer); + + // 创建LED通道配置 + ledc_channel_config_t ledc_channel = { + .gpio_num = PWM_PIN, + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = (ledc_channel_t)PWM_CHANNEL, + .intr_type = LEDC_INTR_DISABLE, + .timer_sel = (ledc_timer_t)PWM_CHANNEL, + .duty = 0, + .hpoint = 0 + }; + ledc_channel_config(&ledc_channel); + + // 设置初始占空比 + ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL, pwmDuty); + ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL); + + Serial.println("PWM initialized."); + + // 初始化输入引脚 + pinMode(BTN0_PIN, INPUT_PULLUP); + pinMode(WAKEUP1_PIN, INPUT); + pinMode(BTN1_PIN, INPUT); + pinMode(BTN2_PIN, INPUT); + Serial.println("Inputs initialized."); + + // 创建任务 + xTaskCreatePinnedToCore( + TaskRFIDcode, /* 任务函数 */ + "TaskRFID", /* 任务名称 */ + 4096, /* 任务栈大小 */ + NULL, /* 传递给任务的参数 */ + 1, /* 任务优先级 */ + &TaskRFID, /* 任务句柄 */ + 1); /* 运行在核心1上 */ + + xTaskCreatePinnedToCore( + TaskLED1code, + "TaskLED1", + 2048, + NULL, + 1, + &TaskLED1, + 1); + + xTaskCreatePinnedToCore( + TaskLED2code, + "TaskLED2", + 4096, + NULL, + 1, + &TaskLED2, + 1); + + xTaskCreatePinnedToCore( + TaskLED3code, + "TaskLED3", + 2048, + NULL, + 1, + &TaskLED3, + 1); // 新增LED3任务 + + xTaskCreatePinnedToCore( + TaskPWMcode, + "TaskPWM", + 1024, + NULL, + 1, + &TaskPWM, + 1); + + xTaskCreatePinnedToCore( + TaskBTN0code, + "TaskBTN0", + 2048, + NULL, + 1, + &TaskBTN0, + 0); + + xTaskCreatePinnedToCore( + TaskWAKEUP1code, + "TaskWAKEUP1", + 2048, + NULL, + 1, + &TaskWAKEUP1, + 0); + + xTaskCreatePinnedToCore( + TaskBTN1code, + "TaskBTN1", + 2048, + NULL, + 1, + &TaskBTN1, + 0); + + xTaskCreatePinnedToCore( + TaskBTN2code, + "TaskBTN2", + 2048, + NULL, + 1, + &TaskBTN2, + 0); + + Serial.println("Tasks created. System ready."); +} + +void loop() { + // 处理串口命令 + handleSerialCommand(); + + // 让出CPU时间 + delay(1); +} \ No newline at end of file diff --git a/Code_Backup/01_原版代码备份/多任务需求描述_应用版.txt b/Code_Backup/01_原版代码备份/多任务需求描述_应用版.txt new file mode 100644 index 0000000..88341b6 --- /dev/null +++ b/Code_Backup/01_原版代码备份/多任务需求描述_应用版.txt @@ -0,0 +1,55 @@ +RTOS多任务模式实现如下功能: + +1.RFID卡片读取,基于RC522模块 + 模块引脚定义: + #define RFID_RST_PIN 14 //RC522 复位引脚 + #define RFID_SS_PIN 10 //RC522 片选引脚 + #define RFID_MISO_PIN 13 // MISO 引脚 + #define RFID_MOSI_PIN 12 // MOSI 引脚 + #define RFID_SCK_PIN 11 // SCK 引脚 + + 将读取到的卡片中用户数据区的字符信息发送给串口,发送格式为“SORC_XXXXX”,比如,如果读取到HA001就发送"SORC_HA001",卡片在读取状态下不要持续发送,只需要发送1次,如果卡片离开读卡器,再次放入读卡器又读取到相同的信息,则需要发送。注意,这里要把读取到的数据转换为ASCII字符 + + +2.基于FASTLED库,控制位于GPIO4 引脚上的1颗WS2812灯珠,并接受如下来自串口的指令。 + 串口指令“MO_LED_0”,灯珠熄灭 + 串口指令“MO_LED_1”,灯珠亮蓝色 + 串口指令“MO_LED_2”,灯珠亮绿色 + 串口指令“MO_LED_3”,灯珠亮橙色 + 串口指令“MO_LED_4”,灯珠亮红色 + 串口指令“MO_LED_5”,灯珠亮紫色 + 串口指令“MO_LED_6”,灯珠亮黄色 + 串口指令“MO_LED_7”,灯珠亮白色,为默认色 + + +3.基于FASTLED库,控制位于GPIO5 引脚上的160颗ws2812灯带,灯带有5个状态。可被串口指令控制。 + 串口指令“MO_LEDN_0”,灯珠全灭 + 串口指令“MO_LEDN_1”,灯珠全部亮白色 + 串口指令“MO_LEDN_2”,彩虹流水灯效果 + 串口指令“MO_LEDN_3”,彩虹呼吸灯效果 串口指令“MO_LEDN_4”,彩虹火车灯效果,灯珠从第1颗开始出来,往灯带尾部前进,火车灯长度为16颗,当走到尾部时,所有灯珠要全部要进站,也就是一颗颗减少,直到灯带上没有灯珠亮起,再一颗颗倒回来,一直走到所有灯珠倒进第一颗灯珠进站。每次从一头出来就变换一种彩虹色。 + + 状态0 全部熄灭状态,串口指令“MO_LEDN_0”; + 状态1 纯白色,串口指令“MO_LEDN_1”; + 状态2 彩虹流水灯,串口指令“MO_LEDN_2”,次 + 状态3 彩虹呼吸灯,串口指令“MO_LEDN_3” + 状态4 马卡龙火车灯,串口指令“MO_LEDN_4”,效果为每次从5种马卡龙色中选择一种,以16颗灯珠为一列,从灯带头跑到灯带尾,变色后又从灯带尾跑到灯带头,以此循环。 + +4.在GPIO6上输出1000hz的pwm控制信号,默认信号强度为80%,根据串口的指令,来控制输出信号强度。 + 串口指令“MO_PWM_0”,输出为0; + 串口指令“MO_PWM_20”,输出为20%; + 串口指令“MO_PWM_40”,输出为40%; + 串口指令“MO_PWM_60”,输出为60%; + 串口指令“MO_PWM_80”,输出为80%; + 串口指令“MO_PWM_1”,输出为100%; + +5.检测GPIO15的电平变化,GPIO15接入一个触点按钮,按钮另一端接入GND。按钮或引脚按照下述行为,进行响应。 + GPIO15默认为高电平,当按钮按下后,出发导通GND低电平,向串口发送1次“SO_BT0_HIGH”,如果按键持续按下超过2秒,则向串口发送一次“SO_BT0_HIGHL”,如果按钮松开,则向串口发送“SO_BT0_LOW”。 + + +6.检测GPIO16的电平状态,默认为低电平,如果检测到高电平信号,则向串口发送1次“SO_WAKEUP1”,如果恢复为低则向串口发送1次“SO_WAKEUP0”。 + +7.检测GPIO17的电平状态,默认为低电平,如果检测到高电平信号,则向串口发送1次“SO_BT1_HIGH”,如果恢复为低,则向串口发送1次“SO_BT1_LOW”, + +8.检测GPIO18的电平状态,默认为低电平,如果检测到高电平信号,则向串口发送1次“SO_BT2_HIGH”,如果恢复为低,则向串口发送1次“SO_BT2_LOW”,9 + +9.位于gpio48的引脚设置为一颗ws2812灯珠,默认关闭状态。 \ No newline at end of file diff --git a/Code_Backup/01_原版代码备份/源代码.txt b/Code_Backup/01_原版代码备份/源代码.txt new file mode 100644 index 0000000..f2bd77e --- /dev/null +++ b/Code_Backup/01_原版代码备份/源代码.txt @@ -0,0 +1,668 @@ +#include +#include +#include +#include +#include + +// RFID引脚定义 +#define RFID_RST_PIN 14 // RC522 复位引脚 +#define RFID_SS_PIN 10 // RC522 片选引脚 +#define RFID_MISO_PIN 13 // MISO 引脚 +#define RFID_MOSI_PIN 12 // MOSI 引脚 +#define RFID_SCK_PIN 11 // SCK 引脚 + +// LED定义 +#define LED_PIN_1 4 // 1颗WS2812灯珠引脚 +#define LED_PIN_2 5 // 160颗WS2812灯带引脚 +#define LED_PIN_3 48 // 1颗WS2812灯珠引脚(新增) +#define LED_COUNT_1 1 // 1颗灯珠 +#define LED_COUNT_2 186 // 160颗灯带 +#define LED_COUNT_3 1 // 1颗灯珠(新增) + +// PWM定义 +#define PWM_PIN 6 // PWM输出引脚 +#define PWM_CHANNEL 0 // PWM通道 +#define PWM_FREQ 1000 // PWM频率(Hz) +#define PWM_RESOLUTION 10 // PWM分辨率(位) +#define DEFAULT_DUTY 819 // 默认占空比(80%) + +// 按钮和输入引脚定义 +#define BTN0_PIN 15 // 按钮0引脚 +#define WAKEUP1_PIN 16 // 唤醒引脚1 +#define BTN1_PIN 17 // 按钮1引脚 +#define BTN2_PIN 18 // 按钮2引脚 + +// 任务句柄 +TaskHandle_t TaskRFID, TaskLED1, TaskLED2, TaskLED3, TaskPWM, TaskBTN0, TaskWAKEUP1, TaskBTN1, TaskBTN2; + +// 全局变量 +MFRC522 rfid(RFID_SS_PIN, RFID_RST_PIN); // 创建RFID实例 +CRGB leds1[LED_COUNT_1]; // 1颗灯珠数组 +CRGB leds2[LED_COUNT_2]; // 160颗灯带数组 +CRGB leds3[LED_COUNT_3]; // 1颗灯珠数组(新增) +String lastCardData = ""; // 上次读取的RFID卡数据 +int ledMode = 1; // 灯带模式,默认为1(白色) +int pwmDuty = DEFAULT_DUTY; // PWM占空比 +bool btn0State = HIGH; // 按钮0状态 +bool btn0LongPress = false; // 按钮0长按标志 +bool wakeup1State = LOW; // 唤醒引脚1状态 +bool btn1State = LOW; // 按钮1状态 +bool btn2State = LOW; // 按钮2状态 +int singleLedMode = 7; // 单颗LED模式,默认为7(白色) + +// 灯带动画全局变量 +static uint8_t rainbowHue = 0; +static int trainPos = 0; +static unsigned long lastUpdate = 0; +static const int TRAIN_LENGTH = 16; // 火车灯长度 +static int trainPhase = 0; // 火车阶段:0-正向出站,1-正向前进,2-正向进站,3-反向出站,4-反向前进,5-反向进站 +static const int VIRTUAL_LED_COUNT = LED_COUNT_2 + TRAIN_LENGTH; // 虚拟灯带长度 + +// 单颗LED颜色数组 +CRGB singleLedColors[8] = { + CRGB::Black, // 0: 熄灭 + CRGB::Blue, // 1: 蓝色 + CRGB::Green, // 2: 绿色 + CRGB::Orange, // 3: 橙色 + CRGB::Red, // 4: 红色 + CRGB::Purple, // 5: 紫色 + CRGB::Yellow, // 6: 黄色 + CRGB::White // 7: 白色 +}; + +// RFID读取任务 +void TaskRFIDcode( void * pvParameters ) { + for(;;) { + // 寻找新卡片 + if ( ! rfid.PICC_IsNewCardPresent()) { + delay(10); + continue; + } + + // 验证NUID是否可读 + if ( ! rfid.PICC_ReadCardSerial()) { + delay(10); + continue; + } + + // 读取卡片数据(用户数据区) + String cardData = ""; + MFRC522::MIFARE_Key key; + + // 准备认证密钥 + for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; + + // 选择卡片 + MFRC522::StatusCode status; + status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(rfid.uid)); + if (status != MFRC522::STATUS_OK) { + Serial.print(F("Authentication failed: ")); + Serial.println(rfid.GetStatusCodeName(status)); + rfid.PICC_HaltA(); + rfid.PCD_StopCrypto1(); + delay(100); + continue; + } + + // 读取数据块 + byte buffer[18]; + byte size = sizeof(buffer); + status = rfid.MIFARE_Read(4, buffer, &size); + if (status != MFRC522::STATUS_OK) { + Serial.print(F("Reading failed: ")); + Serial.println(rfid.GetStatusCodeName(status)); + } else { + // 转换为ASCII字符串 + for (byte i = 0; i < 16; i++) { + if (buffer[i] >= 32 && buffer[i] <= 126) { // 可打印ASCII字符 + cardData += (char)buffer[i]; + } + } + + // 移除空白字符 + cardData.trim(); + + // 卡片数据处理 + if (cardData != lastCardData && !cardData.isEmpty()) { + lastCardData = cardData; + Serial.println("SORC_" + cardData); + } + } + + // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡 + rfid.PICC_HaltA(); + + // 停止加密PCD + rfid.PCD_StopCrypto1(); + + delay(100); + } +} + +// LED1控制任务 +void TaskLED1code( void * pvParameters ) { + for(;;) { + // 根据模式设置LED1颜色 + if (singleLedMode >= 0 && singleLedMode <= 7) { + leds1[0] = singleLedColors[singleLedMode]; + } else { + leds1[0] = CRGB::Blue; // 默认白色 + } + + // 更新LED + FastLED.show(); + + delay(20); + } +} + +// LED3控制任务(新增) +void TaskLED3code( void * pvParameters ) { + for(;;) { + // 强制设置GPIO48的灯珠为熄灭状态 + leds3[0] = CRGB::Black; + + // 更新LED + FastLED.show(); + + delay(20); + } +} + +// LED2控制任务 +void TaskLED2code( void * pvParameters ) { + for(;;) { + // 根据不同模式控制灯带 + switch(ledMode) { + case 0: // 全部熄灭 + fill_solid(leds2, LED_COUNT_2, CRGB::Black); + break; + + case 1: // 纯白色 + fill_solid(leds2, LED_COUNT_2, CRGB::White); + break; + + case 2: // 彩虹流水灯 + for(int i = 0; i < LED_COUNT_2; i++) { + leds2[i] = CHSV(rainbowHue + i * 256 / LED_COUNT_2, 255, 255); + } + rainbowHue++; + break; + + case 3: // 彩虹呼吸灯 + for(int i = 0; i < LED_COUNT_2; i++) { + leds2[i] = CHSV(rainbowHue, 255, beatsin8(1, 64, 255)); + } + rainbowHue++; + break; + + case 4: // 彩虹火车灯 + if (millis() - lastUpdate > 30) { // 30ms更新一次 + lastUpdate = millis(); + + // 清除所有灯珠 + fill_solid(leds2, LED_COUNT_2, CRGB::Black); + + switch (trainPhase) { + case 0: // 正向出站(从起点开始出现) + for (int i = 0; i < TRAIN_LENGTH; i++) { + int pos = trainPos + i; + if (pos >= 0 && pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否完全出站 + if (trainPos >= 0) { + trainPhase = 1; // 开始正向前进 + trainPos = 0; + } + break; + + case 1: // 正向前进 + for (int i = 0; i < TRAIN_LENGTH; i++) { + int pos = trainPos + i; + if (pos >= 0 && pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否到达终点 + if (trainPos >= LED_COUNT_2 - TRAIN_LENGTH) { + trainPhase = 2; // 开始正向进站 + trainPos = LED_COUNT_2 - TRAIN_LENGTH; + } + break; + + case 2: // 正向进站(从尾部开始消失) + for (int i = 0; i < TRAIN_LENGTH; i++) { + int displayPos = LED_COUNT_2 - 1 - i; + if (displayPos >= trainPos) { + uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH); + leds2[displayPos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否完全进站 + if (trainPos >= LED_COUNT_2) { + trainPhase = 3; // 开始反向出站 + trainPos = 0; + rainbowHue += 64; // 改变彩虹颜色 + } + break; + + case 3: // 反向出站(从终点开始出现) + for (int i = 0; i < trainPos + 1; i++) { + int pos = LED_COUNT_2 - 1 - i; + if (pos >= 0) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否完全出站 + if (trainPos >= TRAIN_LENGTH) { + trainPhase = 4; // 开始反向前进 + trainPos = TRAIN_LENGTH; + } + break; + + case 4: // 反向前进 + for (int i = 0; i < TRAIN_LENGTH; i++) { + int pos = LED_COUNT_2 - trainPos + i; + if (pos >= 0 && pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否到达起点 + if (trainPos >= LED_COUNT_2) { + trainPhase = 5; // 开始反向进站 + trainPos = 0; + } + break; + + case 5: // 反向进站(从头部开始消失) + for (int i = 0; i < TRAIN_LENGTH - trainPos; i++) { + int pos = i; + if (pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, 255); + } + } + + trainPos += 1; + + // 检查是否完全进站 + if (trainPos >= TRAIN_LENGTH) { + trainPhase = 0; // 重新开始正向出站 + trainPos = -TRAIN_LENGTH; + rainbowHue += 64; // 改变彩虹颜色 + } + break; + } + } + break; + + case 5: // 马卡龙火车灯(保留原功能,未修改) + // 代码保持不变... + break; + } + + // 更新LED + FastLED.show(); + + // 根据模式调整延时 + if (ledMode == 4 || ledMode == 5) { + delay(10); // 火车灯模式需要更快的更新速度 + } else { + delay(30); + } + } +} + +// PWM控制任务 +void TaskPWMcode( void * pvParameters ) { + for(;;) { + // 设置PWM占空比 + ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL, pwmDuty); + ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL); + + delay(100); + } +} + +// 按钮0检测任务 +void TaskBTN0code( void * pvParameters ) { + static unsigned long pressStartTime = 0; + static bool lastState = HIGH; + + for(;;) { + bool currentState = digitalRead(BTN0_PIN); + + // 检测下降沿(按下) + if (lastState == HIGH && currentState == LOW) { + pressStartTime = millis(); + btn0State = LOW; + Serial.println("SO_BT0_HIGH"); + btn0LongPress = false; + } + // 检测上升沿(释放) + else if (lastState == LOW && currentState == HIGH) { + btn0State = HIGH; + Serial.println("SO_BT0_LOW"); + btn0LongPress = false; + } + // 检测长按 + else if (currentState == LOW && millis() - pressStartTime >= 2000 && !btn0LongPress) { + btn0LongPress = true; + Serial.println("SO_BT0_HIGHL"); + } + + lastState = currentState; + delay(10); + } +} + +// WAKEUP1检测任务 +void TaskWAKEUP1code( void * pvParameters ) { + static bool lastState = LOW; + + for(;;) { + bool currentState = digitalRead(WAKEUP1_PIN); + + // 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + wakeup1State = HIGH; + Serial.println("SO_WAKEUP1"); + } + // 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + wakeup1State = LOW; + Serial.println("SO_WAKEUP0"); + } + + lastState = currentState; + delay(10); + } +} + +// 按钮1检测任务 +void TaskBTN1code( void * pvParameters ) { + static bool lastState = LOW; + + for(;;) { + bool currentState = digitalRead(BTN1_PIN); + + // 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + btn1State = HIGH; + Serial.println("SO_BT1_HIGH"); + } + // 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + btn1State = LOW; + Serial.println("SO_BT1_LOW"); + } + + lastState = currentState; + delay(10); + } +} + +// 按钮2检测任务 +void TaskBTN2code( void * pvParameters ) { + static bool lastState = LOW; + + for(;;) { + bool currentState = digitalRead(BTN2_PIN); + + // 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + btn2State = HIGH; + Serial.println("SO_BT2_HIGH"); + } + // 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + btn2State = LOW; + Serial.println("SO_BT2_LOW"); + } + + lastState = currentState; + delay(10); + } +} + +// 串口命令处理 +void handleSerialCommand() { + static String command = ""; + + while (Serial.available()) { + char c = Serial.read(); + if (c == '\n') { + // 处理命令 + if (command.startsWith("MO_LED_")) { + String modeStr = command.substring(7); + int newMode = modeStr.toInt(); + + // 控制单颗LED + if (newMode >= 0 && newMode <= 7) { + singleLedMode = newMode; + Serial.print("Single LED set to mode: "); + Serial.println(newMode); + } else { + Serial.println("Invalid single LED mode command"); + } + } + else if (command.startsWith("MO_LEDN_")) { + String modeStr = command.substring(8); + int newMode = modeStr.toInt(); + + // 控制灯带 + if (newMode >= 0 && newMode <= 5) { + ledMode = newMode; + + // 重置火车灯状态 + if (newMode == 4) { + trainPos = -TRAIN_LENGTH; + trainPhase = 0; + rainbowHue = random8(); + } + + Serial.print("LED strip set to mode: "); + Serial.println(newMode); + } else { + Serial.println("Invalid LED strip mode command"); + } + } + else if (command.startsWith("MO_PWM_")) { + String dutyStr = command.substring(7); + int newDuty = dutyStr.toInt(); + + // 检查PWM百分比 + if (newDuty == 1) { + pwmDuty = 1023; // 100% + } else if (newDuty == 0 || newDuty == 20 || newDuty == 40 || newDuty == 60 || newDuty == 80) { + pwmDuty = (newDuty * 1023) / 100; // 转换为实际占空比 + } else { + Serial.println("Invalid PWM command"); + } + + Serial.print("PWM set to: "); + Serial.print((pwmDuty * 100) / 1023); + Serial.println("%"); + } + + // 清空命令 + command = ""; + } else { + command += c; + } + } +} + +void setup() { + // 初始化串口 + Serial.begin(115200); + Serial.println("System starting..."); + + // 初始化SPI总线 + SPI.begin(RFID_SCK_PIN, RFID_MISO_PIN, RFID_MOSI_PIN, RFID_SS_PIN); + + // 初始化RFID + rfid.PCD_Init(); + Serial.println("RFID initialized."); + + // 初始化LED + FastLED.addLeds(leds1, LED_COUNT_1); + FastLED.addLeds(leds2, LED_COUNT_2); + FastLED.addLeds(leds3, LED_COUNT_3); // 新增LED3 + + // 初始化LED状态 + fill_solid(leds1, LED_COUNT_1, singleLedColors[singleLedMode]); + fill_solid(leds2, LED_COUNT_2, CRGB::White); + fill_solid(leds3, LED_COUNT_3, CRGB::Black); // 强制GPIO48的灯珠熄灭 + FastLED.show(); + Serial.println("LED initialized."); + + // 初始化PWM + // 创建LED控制器配置 + ledc_timer_config_t ledc_timer = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .duty_resolution = (ledc_timer_bit_t)PWM_RESOLUTION, + .timer_num = (ledc_timer_t)PWM_CHANNEL, + .freq_hz = PWM_FREQ, + .clk_cfg = LEDC_AUTO_CLK + }; + ledc_timer_config(&ledc_timer); + + // 创建LED通道配置 + ledc_channel_config_t ledc_channel = { + .gpio_num = PWM_PIN, + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = (ledc_channel_t)PWM_CHANNEL, + .intr_type = LEDC_INTR_DISABLE, + .timer_sel = (ledc_timer_t)PWM_CHANNEL, + .duty = 0, + .hpoint = 0 + }; + ledc_channel_config(&ledc_channel); + + // 设置初始占空比 + ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL, pwmDuty); + ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL); + + Serial.println("PWM initialized."); + + // 初始化输入引脚 + pinMode(BTN0_PIN, INPUT_PULLUP); + pinMode(WAKEUP1_PIN, INPUT); + pinMode(BTN1_PIN, INPUT); + pinMode(BTN2_PIN, INPUT); + Serial.println("Inputs initialized."); + + // 创建任务 + xTaskCreatePinnedToCore( + TaskRFIDcode, /* 任务函数 */ + "TaskRFID", /* 任务名称 */ + 4096, /* 任务栈大小 */ + NULL, /* 传递给任务的参数 */ + 1, /* 任务优先级 */ + &TaskRFID, /* 任务句柄 */ + 1); /* 运行在核心1上 */ + + xTaskCreatePinnedToCore( + TaskLED1code, + "TaskLED1", + 2048, + NULL, + 1, + &TaskLED1, + 1); + + xTaskCreatePinnedToCore( + TaskLED2code, + "TaskLED2", + 4096, + NULL, + 1, + &TaskLED2, + 1); + + xTaskCreatePinnedToCore( + TaskLED3code, + "TaskLED3", + 2048, + NULL, + 1, + &TaskLED3, + 1); // 新增LED3任务 + + xTaskCreatePinnedToCore( + TaskPWMcode, + "TaskPWM", + 1024, + NULL, + 1, + &TaskPWM, + 1); + + xTaskCreatePinnedToCore( + TaskBTN0code, + "TaskBTN0", + 2048, + NULL, + 1, + &TaskBTN0, + 0); + + xTaskCreatePinnedToCore( + TaskWAKEUP1code, + "TaskWAKEUP1", + 2048, + NULL, + 1, + &TaskWAKEUP1, + 0); + + xTaskCreatePinnedToCore( + TaskBTN1code, + "TaskBTN1", + 2048, + NULL, + 1, + &TaskBTN1, + 0); + + xTaskCreatePinnedToCore( + TaskBTN2code, + "TaskBTN2", + 2048, + NULL, + 1, + &TaskBTN2, + 0); + + Serial.println("Tasks created. System ready."); +} + +void loop() { + // 处理串口命令 + handleSerialCommand(); + + // 让出CPU时间 + delay(1); +} \ No newline at end of file diff --git a/Code_Backup/02_当前最新烧录版本_V6/源码.ino b/Code_Backup/02_当前最新烧录版本_V6/源码.ino new file mode 100644 index 0000000..7508ad6 --- /dev/null +++ b/Code_Backup/02_当前最新烧录版本_V6/源码.ino @@ -0,0 +1,784 @@ +#include SPI.h +#include MFRC522.h +#include FastLED.h +#include Arduino.h +#include driverledc.h + + RFID引脚定义 +#define RFID_RST_PIN 14 RC522 复位引脚 +#define RFID_SS_PIN 10 RC522 片选引脚 +#define RFID_MISO_PIN 13 MISO 引脚 +#define RFID_MOSI_PIN 12 MOSI 引脚 +#define RFID_SCK_PIN 11 SCK 引脚 + + LED定义 +#define LED_PIN_1 4 1颗WS2812灯珠引脚 +#define LED_PIN_2 5 160颗WS2812灯带引脚 +#define LED_PIN_3 48 1颗WS2812灯珠引脚(新增) +#define LED_COUNT_1 1 1颗灯珠 +#define LED_COUNT_2 186 160颗灯带 +#define LED_COUNT_3 1 1颗灯珠(新增) + + PWM定义 +#define PWM_PIN 6 PWM输出引脚 +#define PWM_CHANNEL 0 PWM通道 +#define PWM_FREQ 1000 PWM频率(Hz) +#define PWM_RESOLUTION 10 PWM分辨率(位) +#define DEFAULT_DUTY 819 默认占空比(80%) + + 按钮和输入引脚定义 +#define BTN0_PIN 15 按钮0引脚 +#define WAKEUP1_PIN 16 唤醒引脚1 +#define BTN1_PIN 17 按钮1引脚 +#define BTN2_PIN 18 按钮2引脚 + + 任务句柄 +TaskHandle_t TaskRFID, TaskLED1, TaskLED2, TaskLED3, TaskPWM, TaskBTN0, TaskWAKEUP1, TaskBTN1, TaskBTN2; + + 全局变量 +MFRC522 rfid(RFID_SS_PIN, RFID_RST_PIN); 创建RFID实例 +CRGB leds1[LED_COUNT_1]; 1颗灯珠数组 +CRGB leds2[LED_COUNT_2]; 160颗灯带数组 +CRGB leds3[LED_COUNT_3]; 1颗灯珠数组(新增) +CRGB frozenLeds2[LED_COUNT_2]; 保存冻结时的颜色数据(模式5专用) +uint8_t frozenBrightness = 255; 保存冻结时的亮度值,用于计算相对亮度比例 + +String lastCardData = ; 上次读取的RFID卡数据 +int ledMode = 1; 灯带模式,默认为1(白色) +int pwmDuty = DEFAULT_DUTY; PWM占空比 +bool btn0State = HIGH; 按钮0状态 +bool btn0LongPress = false; 按钮0长按标志 +bool wakeup1State = LOW; 唤醒引脚1状态 +bool btn1State = LOW; 按钮1状态 +bool btn2State = LOW; 按钮2状态 +int singleLedMode = 7; 单颗LED模式,默认为7(白色) + + 灯带动画全局变量 +static uint8_t rainbowHue = 0; +static int trainPos = 0; +static unsigned long lastUpdate = 0; +static const int TRAIN_LENGTH = 16; 火车灯长度 +static int trainPhase = 0; 火车阶段:0-正向出站,1-正向前进,2-正向进站,3-反向出站,4-反向前进,5-反向进站 +static const int VIRTUAL_LED_COUNT = LED_COUNT_2 + TRAIN_LENGTH; 虚拟灯带长度 + + + LED亮度线性映射表 (0~100 → 26~255) - 最小阈值10% + 用于将用户输入的0-100%亮度值映射到实际的PWM值 + 避免过低亮度导致LED完全不可见的问题 +const uint8_t brightnessMapLinear[101] = { + 0, 28, 31, 33, 36, 38, 41, 43, 46, 48, 0-9 + 51, 54, 56, 59, 61, 64, 66, 69, 71, 74, 10-19 + 77, 79, 82, 84, 87, 89, 92, 94, 97, 99, 20-29 + 102, 105, 107, 110, 112, 115, 117, 120, 122, 125, 30-39 + 128, 130, 133, 135, 138, 140, 143, 145, 148, 150, 40-49 + 153, 156, 158, 161, 163, 166, 168, 171, 173, 176, 50-59 + 179, 181, 184, 186, 189, 191, 194, 196, 199, 201, 60-69 + 204, 207, 209, 212, 214, 217, 219, 222, 224, 227, 70-79 + 230, 232, 235, 237, 240, 242, 245, 247, 250, 252, 80-89 + 253, 254, 254, 254, 255, 255, 255, 255, 255, 255, 90-99 + 255 100% +}; + + + + + + + + 全局选择映射表 +const uint8_t brightnessMap = brightnessMapLinear; + + LED2亮度控制(0-255) + 用于控制LED灯带的整体亮度,影响模式1、2、4和5 + 模式3使用独立的呼吸算法,基于此值计算动态亮度范围 +uint8_t led2Brightness = 102; 默认40%左右(102255≈40%) + + + + 单颗LED颜色数组 +CRGB singleLedColors[8] = { + CRGBBlack, 0 熄灭 + CRGBBlue, 1 蓝色 + CRGBGreen, 2 绿色 + CRGBOrange, 3 橙色 + CRGBRed, 4 红色 + CRGBPurple, 5 紫色 + CRGBYellow, 6 黄色 + CRGBWhite 7 白色 +}; + + RFID读取任务 +void TaskRFIDcode(void pvParameters) { + for (;;) { + 寻找新卡片 + if (!rfid.PICC_IsNewCardPresent()) { + delay(10); + continue; + } + + 验证NUID是否可读 + if (!rfid.PICC_ReadCardSerial()) { + delay(10); + continue; + } + + 读取卡片数据(用户数据区) + String cardData = ; + MFRC522MIFARE_Key key; + + 准备认证密钥 + for (byte i = 0; i 6; i++) key.keyByte[i] = 0xFF; + + 选择卡片 + MFRC522StatusCode status; + status = rfid.PCD_Authenticate(MFRC522PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(rfid.uid)); + if (status != MFRC522STATUS_OK) { + Serial.print(F(Authentication failed )); + Serial.println(rfid.GetStatusCodeName(status)); + rfid.PICC_HaltA(); + rfid.PCD_StopCrypto1(); + delay(100); + continue; + } + + 读取数据块 + byte buffer[18]; + byte size = sizeof(buffer); + status = rfid.MIFARE_Read(4, buffer, &size); + if (status != MFRC522STATUS_OK) { + Serial.print(F(Reading failed )); + Serial.println(rfid.GetStatusCodeName(status)); + } else { + 转换为ASCII字符串 + for (byte i = 0; i 16; i++) { + if (buffer[i] = 32 && buffer[i] = 126) { 可打印ASCII字符 + cardData += (char)buffer[i]; + } + } + + 移除空白字符 + cardData.trim(); + + 卡片数据处理 + if (cardData != lastCardData && !cardData.isEmpty()) { + lastCardData = cardData; + Serial.println(SORC_ + cardData); + } + } + + 使放置在读卡区的IC卡进入休眠状态,不再重复读卡 + rfid.PICC_HaltA(); + + 停止加密PCD + rfid.PCD_StopCrypto1(); + + delay(100); + } +} + + 注意:以下两个函数已被TaskLEDUnifiedCode替代,保留仅供参考 + 实际运行中不会被调用,因为setup()中没有创建对应的任务 + + LED1控制任务(已废弃,由TaskLEDUnifiedCode统一处理) +void TaskLED1code(void pvParameters) { + 此函数已被废弃,不再使用 + LED1的控制已集成到TaskLEDUnifiedCode中 + vTaskDelete(NULL); 如果意外创建了此任务,立即删除 +} + + LED3控制任务(已废弃,由TaskLEDUnifiedCode统一处理) +void TaskLED3code(void pvParameters) { + 此函数已被废弃,不再使用 + LED3的控制已集成到TaskLEDUnifiedCode中 + vTaskDelete(NULL); 如果意外创建了此任务,立即删除 +} + + PWM控制任务 +void TaskPWMcode(void pvParameters) { + for (;;) { + 设置PWM占空比 + ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL, pwmDuty); + ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL); + + delay(100); + } +} + + 按钮0检测任务 +void TaskBTN0code(void pvParameters) { + static unsigned long pressStartTime = 0; + static bool lastState = HIGH; + + for (;;) { + bool currentState = digitalRead(BTN0_PIN); + + 检测下降沿(按下) + if (lastState == HIGH && currentState == LOW) { + pressStartTime = millis(); + btn0State = LOW; + Serial.println(SO_BT0_HIGH); + btn0LongPress = false; + } + 检测上升沿(释放) + else if (lastState == LOW && currentState == HIGH) { + btn0State = HIGH; + Serial.println(SO_BT0_LOW); + btn0LongPress = false; + } + 检测长按 + else if (currentState == LOW && millis() - pressStartTime = 2000 && !btn0LongPress) { + btn0LongPress = true; + Serial.println(SO_BT0_HIGHL); + } + + lastState = currentState; + delay(10); + } +} + + WAKEUP1检测任务 +void TaskWAKEUP1code(void pvParameters) { + static bool lastState = LOW; + + for (;;) { + bool currentState = digitalRead(WAKEUP1_PIN); + + 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + wakeup1State = HIGH; + Serial.println(SO_WAKEUP1); + } + 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + wakeup1State = LOW; + Serial.println(SO_WAKEUP0); + } + + lastState = currentState; + delay(10); + } +} + + 按钮1检测任务 +void TaskBTN1code(void pvParameters) { + static bool lastState = LOW; + + for (;;) { + bool currentState = digitalRead(BTN1_PIN); + + 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + btn1State = HIGH; + Serial.println(SO_BT1_HIGH); + } + 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + btn1State = LOW; + Serial.println(SO_BT1_LOW); + } + + lastState = currentState; + delay(10); + } +} + + 按钮2检测任务 +void TaskBTN2code(void pvParameters) { + static bool lastState = LOW; + + for (;;) { + bool currentState = digitalRead(BTN2_PIN); + + 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + btn2State = HIGH; + Serial.println(SO_BT2_HIGH); + } + 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + btn2State = LOW; + Serial.println(SO_BT2_LOW); + } + + lastState = currentState; + delay(10); + } +} + + 串口命令处理 +void handleSerialCommand() { + static String command = ; + + while (Serial.available()) { + 先检查命令长度(新增的防护代码) + if (command.length() 64) { + Serial.println(错误 命令过长(最大64字符)); + command = ; 清空当前命令 + while (Serial.available()) Serial.read(); 清空串口缓冲区 + continue; + } + + char c = Serial.read(); + if (c == 'n') { + 处理命令 + if (command.startsWith(MO_LED_)) { + String modeStr = command.substring(7); + int newMode = modeStr.toInt(); + + 控制单颗LED + if (newMode = 0 && newMode = 7) { + singleLedMode = newMode; + Serial.print(Single LED set to mode ); + Serial.println(newMode); + } else { + Serial.println(Invalid single LED mode command); + } + } else if (command.startsWith(MO_LEDN_)) { + String modeStr = command.substring(8); + int newMode = modeStr.toInt(); + + 控制灯带(只有亮度不为0时才允许) + if (newMode = 0 && newMode = 5) { + if (led2Brightness == 0) { + Serial.println(当前亮度为0,请先将亮度调整至0以上再切换显示模式!); + } else { + ledMode = newMode; + 重置火车灯状态 + if (newMode == 4) { + trainPos = -TRAIN_LENGTH; + trainPhase = 0; + rainbowHue = random8(); + } + + 新增:切换到模式5时,复制当前LED2状态和亮度 + if (newMode == 5) { + memcpy(frozenLeds2, leds2, sizeof(leds2)); + frozenBrightness = led2Brightness; 保存冻结时的亮度 + } + + Serial.print(LED strip set to mode ); + Serial.println(newMode); + } + } else { + Serial.println(Invalid LED strip mode command); + } + } else if (command.startsWith(MO_PWM_)) { + String dutyStr = command.substring(7); + int newDuty = dutyStr.toInt(); + + 检查PWM百分比 + if (newDuty == 1) { + pwmDuty = 1023; 100% + } else if (newDuty == 0 newDuty == 20 newDuty == 40 newDuty == 60 newDuty == 80) { + pwmDuty = (newDuty 1023) 100; 转换为实际占空比 + } else { + Serial.println(Invalid PWM command); + } + + Serial.print(PWM set to ); + Serial.print((pwmDuty 100) 1023); + Serial.println(%); + } + + else if (command.startsWith(MO_BRI_)) { + 提取亮度参数(跳过MO_BRI_前缀) + String levelStr = command.substring(7); + levelStr.trim(); + command = ; 清空命令缓冲区 + + 空参数检查 + if (levelStr.length() == 0) { + Serial.println(错误 缺少亮度值); + return; 终止处理 + } + + 严格数字验证(拒绝非数字字符) + bool isNumeric = true; + for (char c levelStr) { + if (!isdigit(c)) { + isNumeric = false; + break; 发现非数字立即退出 + } + } + + 非数字错误处理 + if (!isNumeric) { + Serial.println(错误 亮度值必须为整数); + return; + } + + 转换为整数并验证范围 + int level = levelStr.toInt(); + if (level = 0 && level = 100) { + 更新亮度值(映射到PWM范围) + led2Brightness = brightnessMap[level]; 使用预定义映射表 + Serial.print(LED亮度 ); + Serial.print(level); + Serial.println(%); + + 亮度为0时输出警告 + if (level == 0) { + Serial.println(亮度已设置为0,所有灯光将熄灭!); + } + } else { + Serial.println(错误 亮度值需在0-100之间); + } + command = ; 清空命令 + } + + command = ; 清空命令 + } else { + 累积非换行符字符 + command += c; + } + } +} + + + + + 统一LED控制任务(防闪烁优化版本) + 集中管理LED1(单颗)、LED2(灯带)、LED3(强制关闭)的显示逻辑 + 优化特性: + 1. 30FPS稳定更新频率,防止闪烁 + 2. 修复模式5的双重亮度衰减问题 + 3. 统一亮度处理机制 + 4. 内存优化,减少不必要的数据拷贝 + 5. 防闪烁机制,确保LED显示稳定 +void TaskLEDUnifiedCode(void pvParameters) { + static unsigned long lastLEDUpdate = 0; + const unsigned long LED_UPDATE_INTERVAL = 33; ~30FPS,降低更新频率减少闪烁 + + for (;;) { + unsigned long currentTime = millis(); + + 控制更新频率,避免过度占用CPU和闪烁问题 + if (currentTime - lastLEDUpdate LED_UPDATE_INTERVAL) { + delay(5); 增加延时,确保任务调度稳定 + continue; + } + lastLEDUpdate = currentTime; + + ---- LED1 控制(单颗 LED)---- + if (singleLedMode = 0 && singleLedMode = 7) { + leds1[0] = singleLedColors[singleLedMode]; + } else { + leds1[0] = CRGBBlue; + } + + ---- LED3 控制(熄灭)---- + leds3[0] = CRGBBlack; + + ---- LED2 控制(灯带)---- + switch (ledMode) { + case 0 模式0:全部熄灭,关闭所有LED灯珠 + fill_solid(leds2, LED_COUNT_2, CRGBBlack); + break; + + case 1 模式1:纯白色静态光,亮度可通过led2Brightness调节 + fill_solid(leds2, LED_COUNT_2, CHSV(0, 0, led2Brightness)); + break; + + case 2 模式2:彩虹流水灯,颜色沿灯带流动,速度和亮度可调 + for (int i = 0; i LED_COUNT_2; i++) { + leds2[i] = CHSV(rainbowHue + i 256 LED_COUNT_2, 255, led2Brightness); + } + rainbowHue++; + break; + case 3 模式3:彩虹呼吸灯(优化版本),缓慢变色配合呼吸效果 + { + static unsigned long lastHueUpdate = 0; + static unsigned long lastBreathUpdate = 0; + static uint8_t breathingHue = 0; + static uint8_t breathPhase = 0; + + unsigned long currentTime = millis(); + + 每300ms更新一次色相,实现非常缓慢的颜色变化 + if (currentTime - lastHueUpdate 300) { + breathingHue += 1; + lastHueUpdate = currentTime; + } + + 每30ms更新一次呼吸相位,控制亮度变化节奏 + if (currentTime - lastBreathUpdate 30) { + breathPhase += 2; + lastBreathUpdate = currentTime; + } + + 计算呼吸亮度:基于led2Brightness的60%-100%范围,避免过暗 + uint8_t minBrightness = led2Brightness 60 100; + uint8_t maxBrightness = led2Brightness; + uint8_t breathValue = map(sin8(breathPhase), 0, 255, minBrightness, maxBrightness); + + for(int i = 0; i LED_COUNT_2; i++) { + leds2[i] = CHSV(breathingHue, 200, breathValue); + } + } + break; + + + case 4 模式4:彩虹火车灯,模拟火车往返运行的动态效果 + if (millis() - lastUpdate 30) { 30ms更新间隔,控制火车移动速度 + lastUpdate = millis(); + fill_solid(leds2, LED_COUNT_2, CRGBBlack); + + switch (trainPhase) { + case 0 阶段0:正向出站,火车从起点逐渐显现 + for (int i = 0; i TRAIN_LENGTH; i++) { + int pos = trainPos + i; + if (pos = 0 && pos LED_COUNT_2) { + uint8_t hue = rainbowHue + (i 256 TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, led2Brightness); + } + } + trainPos++; + if (trainPos = 0) { + trainPhase = 1; 切换到正向前进阶段 + trainPos = 0; + } + break; + + case 1 阶段1:正向前进,火车完整显示并向终点移动 + for (int i = 0; i TRAIN_LENGTH; i++) { + int pos = trainPos + i; + if (pos = 0 && pos LED_COUNT_2) { + uint8_t hue = rainbowHue + (i 256 TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, led2Brightness); + } + } + trainPos++; + if (trainPos = LED_COUNT_2 - TRAIN_LENGTH) { + trainPhase = 2; 切换到正向进站阶段 + trainPos = LED_COUNT_2 - TRAIN_LENGTH; + } + break; + + case 2 阶段2:正向进站,火车从尾部开始消失 + for (int i = 0; i TRAIN_LENGTH; i++) { + int displayPos = LED_COUNT_2 - 1 - i; + if (displayPos = trainPos) { + uint8_t hue = rainbowHue + (i 256 TRAIN_LENGTH); + leds2[displayPos] = CHSV(hue, 255, led2Brightness); + } + } + trainPos++; + if (trainPos = LED_COUNT_2) { + trainPhase = 3; 切换到反向出站阶段 + trainPos = 0; + rainbowHue += 64; 改变彩虹颜色,增加视觉变化 + } + break; + + case 3 阶段3:反向出站,火车从终点逐渐显现 + for (int i = 0; i trainPos + 1; i++) { + int pos = LED_COUNT_2 - 1 - i; + if (pos = 0) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) 256 TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, led2Brightness); + } + } + trainPos++; + if (trainPos = TRAIN_LENGTH) { + trainPhase = 4; 切换到反向前进阶段 + trainPos = TRAIN_LENGTH; + } + break; + + case 4 阶段4:反向前进,火车完整显示并向起点移动 + for (int i = 0; i TRAIN_LENGTH; i++) { + int pos = LED_COUNT_2 - trainPos + i; + if (pos = 0 && pos LED_COUNT_2) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) 256 TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, led2Brightness); + } + } + trainPos++; + if (trainPos = LED_COUNT_2) { + trainPhase = 5; 切换到反向进站阶段 + trainPos = 0; + } + break; + + case 5 阶段5:反向进站,火车从头部开始消失 + for (int i = 0; i TRAIN_LENGTH - trainPos; i++) { + int pos = i; + if (pos LED_COUNT_2) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) 256 TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, led2Brightness); + } + } + trainPos++; + if (trainPos = TRAIN_LENGTH) { + trainPhase = 0; 重新开始正向出站,形成循环 + trainPos = -TRAIN_LENGTH; + rainbowHue += 64; 再次改变彩虹颜色 + } + break; + } + } + break; + + case 5 模式5:冻结当前灯效,保持切换时的图像但允许调节亮度(内存优化版本) + if (led2Brightness == 0) { + fill_solid(leds2, LED_COUNT_2, CRGBBlack); 亮度为0时完全熄灭 + } else { + 计算相对亮度比例,避免双重衰减问题 + uint16_t brightnessRatio = (uint16_t)led2Brightness 255 frozenBrightness; + if (brightnessRatio 255) brightnessRatio = 255; + + 直接计算并设置像素颜色,内存优化,避免使用memcpy + for (int i = 0; i LED_COUNT_2; i++) { + leds2[i].r = (frozenLeds2[i].r brightnessRatio) 8; + leds2[i].g = (frozenLeds2[i].g brightnessRatio) 8; + leds2[i].b = (frozenLeds2[i].b brightnessRatio) 8; + } + } + break; + } + + ---- 最终统一刷新LED ---- + 添加FastLED刷新保护,确保数据稳定后再显示 + FastLED.show(); + + ---- 稳定的延时机制 ---- + 使用固定延时确保LED显示稳定,避免闪烁 + delay(10); 10ms延时,确保LED数据传输完成 + } +} + + +void setup() { + 初始化串口 + Serial.begin(115200); + Serial.println(System starting...); + + 初始化SPI总线 + SPI.begin(RFID_SCK_PIN, RFID_MISO_PIN, RFID_MOSI_PIN, RFID_SS_PIN); + + 初始化RFID + rfid.PCD_Init(); + Serial.println(RFID initialized.); + + 初始化LED + FastLED.addLedsWS2812, LED_PIN_1, GRB(leds1, LED_COUNT_1); + FastLED.addLedsWS2812, LED_PIN_2, GRB(leds2, LED_COUNT_2); + FastLED.addLedsWS2812, LED_PIN_3, GRB(leds3, LED_COUNT_3); 新增LED3 + + 初始化LED状态 + fill_solid(leds1, LED_COUNT_1, singleLedColors[singleLedMode]); + fill_solid(leds2, LED_COUNT_2, CHSV(0, 0, led2Brightness)); 初始化白色 + fill_solid(leds3, LED_COUNT_3, CRGBBlack); 强制GPIO48的灯珠熄灭 + FastLED.show(); + Serial.println(LED initialized.); + + 初始化PWM + 创建LED控制器配置 + ledc_timer_config_t ledc_timer = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .duty_resolution = (ledc_timer_bit_t)PWM_RESOLUTION, + .timer_num = (ledc_timer_t)PWM_CHANNEL, + .freq_hz = PWM_FREQ, + .clk_cfg = LEDC_AUTO_CLK + }; + ledc_timer_config(&ledc_timer); + + 创建LED通道配置 + ledc_channel_config_t ledc_channel = { + .gpio_num = PWM_PIN, + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = (ledc_channel_t)PWM_CHANNEL, + .intr_type = LEDC_INTR_DISABLE, + .timer_sel = (ledc_timer_t)PWM_CHANNEL, + .duty = 0, + .hpoint = 0 + }; + ledc_channel_config(&ledc_channel); + + 设置初始占空比 + ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL, pwmDuty); + ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL); + + Serial.println(PWM initialized.); + + 初始化输入引脚 + pinMode(BTN0_PIN, INPUT_PULLUP); + pinMode(WAKEUP1_PIN, INPUT); + pinMode(BTN1_PIN, INPUT); + pinMode(BTN2_PIN, INPUT); + Serial.println(Inputs initialized.); + + 创建任务 + xTaskCreatePinnedToCore( + TaskRFIDcode, 任务函数 + TaskRFID, 任务名称 + 4096, 任务栈大小 + NULL, 传递给任务的参数 + 1, 任务优先级 + &TaskRFID, 任务句柄 + 1); 运行在核心1上 + + xTaskCreatePinnedToCore( + TaskLEDUnifiedCode, + TaskLEDUnified, + 8192, 建议栈大一点 + NULL, + 3, 提高优先级,确保LED更新不被其他任务干扰 + NULL, + 1); + + xTaskCreatePinnedToCore( + TaskPWMcode, + TaskPWM, + 1024, + NULL, + 1, + &TaskPWM, + 1); + + xTaskCreatePinnedToCore( + TaskBTN0code, + TaskBTN0, + 2048, + NULL, + 1, + &TaskBTN0, + 0); + + xTaskCreatePinnedToCore( + TaskWAKEUP1code, + TaskWAKEUP1, + 2048, + NULL, + 1, + &TaskWAKEUP1, + 0); + + xTaskCreatePinnedToCore( + TaskBTN1code, + TaskBTN1, + 2048, + NULL, + 1, + &TaskBTN1, + 0); + + xTaskCreatePinnedToCore( + TaskBTN2code, + TaskBTN2, + 2048, + NULL, + 1, + &TaskBTN2, + 0); + + Serial.println(Tasks created. System ready.); +} + +void loop() { + 处理串口命令 + handleSerialCommand(); + + 让出CPU时间 + delay(1); +} \ No newline at end of file diff --git a/HOLOMAIN.ino b/HOLOMAIN.ino new file mode 100644 index 0000000..449aecc --- /dev/null +++ b/HOLOMAIN.ino @@ -0,0 +1,784 @@ +#include +#include +#include +#include +#include + +// RFID引脚定义 +#define RFID_RST_PIN 14 // RC522 复位引脚 +#define RFID_SS_PIN 10 // RC522 片选引脚 +#define RFID_MISO_PIN 13 // MISO 引脚 +#define RFID_MOSI_PIN 12 // MOSI 引脚 +#define RFID_SCK_PIN 11 // SCK 引脚 + +// LED定义 +#define LED_PIN_1 4 // 1颗WS2812灯珠引脚 +#define LED_PIN_2 5 // 160颗WS2812灯带引脚 +#define LED_PIN_3 48 // 1颗WS2812灯珠引脚(新增) +#define LED_COUNT_1 1 // 1颗灯珠 +#define LED_COUNT_2 186 // 160颗灯带 +#define LED_COUNT_3 1 // 1颗灯珠(新增) + +// PWM定义 +#define PWM_PIN 6 // PWM输出引脚 +#define PWM_CHANNEL 0 // PWM通道 +#define PWM_FREQ 1000 // PWM频率(Hz) +#define PWM_RESOLUTION 10 // PWM分辨率(位) +#define DEFAULT_DUTY 819 // 默认占空比(80%) + +// 按钮和输入引脚定义 +#define BTN0_PIN 15 // 按钮0引脚 +#define WAKEUP1_PIN 16 // 唤醒引脚1 +#define BTN1_PIN 17 // 按钮1引脚 +#define BTN2_PIN 18 // 按钮2引脚 + +// 任务句柄 +TaskHandle_t TaskRFID, TaskLED1, TaskLED2, TaskLED3, TaskPWM, TaskBTN0, TaskWAKEUP1, TaskBTN1, TaskBTN2; + +// 全局变量 +MFRC522 rfid(RFID_SS_PIN, RFID_RST_PIN); // 创建RFID实例 +CRGB leds1[LED_COUNT_1]; // 1颗灯珠数组 +CRGB leds2[LED_COUNT_2]; // 160颗灯带数组 +CRGB leds3[LED_COUNT_3]; // 1颗灯珠数组(新增) +CRGB frozenLeds2[LED_COUNT_2]; // 保存冻结时的颜色数据(模式5专用) +uint8_t frozenBrightness = 255; // 保存冻结时的亮度值,用于计算相对亮度比例 + +String lastCardData = ""; // 上次读取的RFID卡数据 +int ledMode = 1; // 灯带模式,默认为1(白色) +int pwmDuty = DEFAULT_DUTY; // PWM占空比 +bool btn0State = HIGH; // 按钮0状态 +bool btn0LongPress = false; // 按钮0长按标志 +bool wakeup1State = LOW; // 唤醒引脚1状态 +bool btn1State = LOW; // 按钮1状态 +bool btn2State = LOW; // 按钮2状态 +int singleLedMode = 7; // 单颗LED模式,默认为7(白色) + +// 灯带动画全局变量 +static uint8_t rainbowHue = 0; +static int trainPos = 0; +static unsigned long lastUpdate = 0; +static const int TRAIN_LENGTH = 16; // 火车灯长度 +static int trainPhase = 0; // 火车阶段:0-正向出站,1-正向前进,2-正向进站,3-反向出站,4-反向前进,5-反向进站 +static const int VIRTUAL_LED_COUNT = LED_COUNT_2 + TRAIN_LENGTH; // 虚拟灯带长度 + + +// LED亮度线性映射表 (0~100 → 26~255) - 最小阈值10% +// 用于将用户输入的0-100%亮度值映射到实际的PWM值 +// 避免过低亮度导致LED完全不可见的问题 +const uint8_t brightnessMapLinear[101] = { + 0, 28, 31, 33, 36, 38, 41, 43, 46, 48, // 0-9 + 51, 54, 56, 59, 61, 64, 66, 69, 71, 74, // 10-19 + 77, 79, 82, 84, 87, 89, 92, 94, 97, 99, // 20-29 + 102, 105, 107, 110, 112, 115, 117, 120, 122, 125, // 30-39 + 128, 130, 133, 135, 138, 140, 143, 145, 148, 150, // 40-49 + 153, 156, 158, 161, 163, 166, 168, 171, 173, 176, // 50-59 + 179, 181, 184, 186, 189, 191, 194, 196, 199, 201, // 60-69 + 204, 207, 209, 212, 214, 217, 219, 222, 224, 227, // 70-79 + 230, 232, 235, 237, 240, 242, 245, 247, 250, 252, // 80-89 + 253, 254, 254, 254, 255, 255, 255, 255, 255, 255, // 90-99 + 255 // 100% +}; + + + + + + + +// 全局选择映射表 +const uint8_t* brightnessMap = brightnessMapLinear; + +// LED2亮度控制(0-255) +// 用于控制LED灯带的整体亮度,影响模式1、2、4和5 +// 模式3使用独立的呼吸算法,基于此值计算动态亮度范围 +uint8_t led2Brightness = 102; // 默认40%左右(102/255≈40%) + + + +// 单颗LED颜色数组 +CRGB singleLedColors[8] = { + CRGB::Black, // 0: 熄灭 + CRGB::Blue, // 1: 蓝色 + CRGB::Green, // 2: 绿色 + CRGB::Orange, // 3: 橙色 + CRGB::Red, // 4: 红色 + CRGB::Purple, // 5: 紫色 + CRGB::Yellow, // 6: 黄色 + CRGB::White // 7: 白色 +}; + +// RFID读取任务 +void TaskRFIDcode(void* pvParameters) { + for (;;) { + // 寻找新卡片 + if (!rfid.PICC_IsNewCardPresent()) { + delay(10); + continue; + } + + // 验证NUID是否可读 + if (!rfid.PICC_ReadCardSerial()) { + delay(10); + continue; + } + + // 读取卡片数据(用户数据区) + String cardData = ""; + MFRC522::MIFARE_Key key; + + // 准备认证密钥 + for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; + + // 选择卡片 + MFRC522::StatusCode status; + status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(rfid.uid)); + if (status != MFRC522::STATUS_OK) { + Serial.print(F("Authentication failed: ")); + Serial.println(rfid.GetStatusCodeName(status)); + rfid.PICC_HaltA(); + rfid.PCD_StopCrypto1(); + delay(100); + continue; + } + + // 读取数据块 + byte buffer[18]; + byte size = sizeof(buffer); + status = rfid.MIFARE_Read(4, buffer, &size); + if (status != MFRC522::STATUS_OK) { + Serial.print(F("Reading failed: ")); + Serial.println(rfid.GetStatusCodeName(status)); + } else { + // 转换为ASCII字符串 + for (byte i = 0; i < 16; i++) { + if (buffer[i] >= 32 && buffer[i] <= 126) { // 可打印ASCII字符 + cardData += (char)buffer[i]; + } + } + + // 移除空白字符 + cardData.trim(); + + // 卡片数据处理 + if (cardData != lastCardData && !cardData.isEmpty()) { + lastCardData = cardData; + Serial.println("SORC_" + cardData); + } + } + + // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡 + rfid.PICC_HaltA(); + + // 停止加密PCD + rfid.PCD_StopCrypto1(); + + delay(100); + } +} + +// 注意:以下两个函数已被TaskLEDUnifiedCode替代,保留仅供参考 +// 实际运行中不会被调用,因为setup()中没有创建对应的任务 + +// LED1控制任务(已废弃,由TaskLEDUnifiedCode统一处理) +void TaskLED1code(void* pvParameters) { + // 此函数已被废弃,不再使用 + // LED1的控制已集成到TaskLEDUnifiedCode中 + vTaskDelete(NULL); // 如果意外创建了此任务,立即删除 +} + +// LED3控制任务(已废弃,由TaskLEDUnifiedCode统一处理) +void TaskLED3code(void* pvParameters) { + // 此函数已被废弃,不再使用 + // LED3的控制已集成到TaskLEDUnifiedCode中 + vTaskDelete(NULL); // 如果意外创建了此任务,立即删除 +} + +// PWM控制任务 +void TaskPWMcode(void* pvParameters) { + for (;;) { + // 设置PWM占空比 + ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL, pwmDuty); + ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL); + + delay(100); + } +} + +// 按钮0检测任务 +void TaskBTN0code(void* pvParameters) { + static unsigned long pressStartTime = 0; + static bool lastState = HIGH; + + for (;;) { + bool currentState = digitalRead(BTN0_PIN); + + // 检测下降沿(按下) + if (lastState == HIGH && currentState == LOW) { + pressStartTime = millis(); + btn0State = LOW; + Serial.println("SO_BT0_HIGH"); + btn0LongPress = false; + } + // 检测上升沿(释放) + else if (lastState == LOW && currentState == HIGH) { + btn0State = HIGH; + Serial.println("SO_BT0_LOW"); + btn0LongPress = false; + } + // 检测长按 + else if (currentState == LOW && millis() - pressStartTime >= 2000 && !btn0LongPress) { + btn0LongPress = true; + Serial.println("SO_BT0_HIGHL"); + } + + lastState = currentState; + delay(10); + } +} + +// WAKEUP1检测任务 +void TaskWAKEUP1code(void* pvParameters) { + static bool lastState = LOW; + + for (;;) { + bool currentState = digitalRead(WAKEUP1_PIN); + + // 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + wakeup1State = HIGH; + Serial.println("SO_WAKEUP1"); + } + // 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + wakeup1State = LOW; + Serial.println("SO_WAKEUP0"); + } + + lastState = currentState; + delay(10); + } +} + +// 按钮1检测任务 +void TaskBTN1code(void* pvParameters) { + static bool lastState = LOW; + + for (;;) { + bool currentState = digitalRead(BTN1_PIN); + + // 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + btn1State = HIGH; + Serial.println("SO_BT1_HIGH"); + } + // 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + btn1State = LOW; + Serial.println("SO_BT1_LOW"); + } + + lastState = currentState; + delay(10); + } +} + +// 按钮2检测任务 +void TaskBTN2code(void* pvParameters) { + static bool lastState = LOW; + + for (;;) { + bool currentState = digitalRead(BTN2_PIN); + + // 检测上升沿 + if (lastState == LOW && currentState == HIGH) { + btn2State = HIGH; + Serial.println("SO_BT2_HIGH"); + } + // 检测下降沿 + else if (lastState == HIGH && currentState == LOW) { + btn2State = LOW; + Serial.println("SO_BT2_LOW"); + } + + lastState = currentState; + delay(10); + } +} + +// 串口命令处理 +void handleSerialCommand() { + static String command = ""; + + while (Serial.available()) { + // 先检查命令长度(新增的防护代码) + if (command.length() > 64) { + Serial.println("错误: 命令过长(最大64字符)"); + command = ""; // 清空当前命令 + while (Serial.available()) Serial.read(); // 清空串口缓冲区 + continue; + } + + char c = Serial.read(); + if (c == '\n') { + // 处理命令 + if (command.startsWith("MO_LED_")) { + String modeStr = command.substring(7); + int newMode = modeStr.toInt(); + + // 控制单颗LED + if (newMode >= 0 && newMode <= 7) { + singleLedMode = newMode; + Serial.print("Single LED set to mode: "); + Serial.println(newMode); + } else { + Serial.println("Invalid single LED mode command"); + } + } else if (command.startsWith("MO_LEDN_")) { + String modeStr = command.substring(8); + int newMode = modeStr.toInt(); + + // 控制灯带(只有亮度不为0时才允许) + if (newMode >= 0 && newMode <= 5) { + if (led2Brightness == 0) { + Serial.println("当前亮度为0,请先将亮度调整至0以上再切换显示模式!"); + } else { + ledMode = newMode; + // 重置火车灯状态 + if (newMode == 4) { + trainPos = -TRAIN_LENGTH; + trainPhase = 0; + rainbowHue = random8(); + } + + // 新增:切换到模式5时,复制当前LED2状态和亮度 + if (newMode == 5) { + memcpy(frozenLeds2, leds2, sizeof(leds2)); + frozenBrightness = led2Brightness; // 保存冻结时的亮度 + } + + Serial.print("LED strip set to mode: "); + Serial.println(newMode); + } + } else { + Serial.println("Invalid LED strip mode command"); + } + } else if (command.startsWith("MO_PWM_")) { + String dutyStr = command.substring(7); + int newDuty = dutyStr.toInt(); + + // 检查PWM百分比 + if (newDuty == 1) { + pwmDuty = 1023; // 100% + } else if (newDuty == 0 || newDuty == 20 || newDuty == 40 || newDuty == 60 || newDuty == 80) { + pwmDuty = (newDuty * 1023) / 100; // 转换为实际占空比 + } else { + Serial.println("Invalid PWM command"); + } + + Serial.print("PWM set to: "); + Serial.print((pwmDuty * 100) / 1023); + Serial.println("%"); + } + + else if (command.startsWith("MO_BRI_")) { + // 提取亮度参数(跳过"MO_BRI_"前缀) + String levelStr = command.substring(7); + levelStr.trim(); + command = ""; // 清空命令缓冲区 + + // 空参数检查 + if (levelStr.length() == 0) { + Serial.println("错误: 缺少亮度值"); + return; // 终止处理 + } + + // 严格数字验证(拒绝非数字字符) + bool isNumeric = true; + for (char c : levelStr) { + if (!isdigit(c)) { + isNumeric = false; + break; // 发现非数字立即退出 + } + } + + // 非数字错误处理 + if (!isNumeric) { + Serial.println("错误: 亮度值必须为整数"); + return; + } + + // 转换为整数并验证范围 + int level = levelStr.toInt(); + if (level >= 0 && level <= 100) { + // 更新亮度值(映射到PWM范围) + led2Brightness = brightnessMap[level]; // 使用预定义映射表 + Serial.print("LED亮度: "); + Serial.print(level); + Serial.println("%"); + + // // 亮度为0时输出警告 + // if (level == 0) { + // Serial.println("亮度已设置为0,所有灯光将熄灭!"); + // } + } else { + Serial.println("错误: 亮度值需在0-100之间"); + } + command = ""; // 清空命令 + } + + command = ""; // 清空命令 + } else { + // 累积非换行符字符 + command += c; + } + } +} + + + + +// 统一LED控制任务(防闪烁优化版本) +// 集中管理LED1(单颗)、LED2(灯带)、LED3(强制关闭)的显示逻辑 +// 优化特性: +// 1. 30FPS稳定更新频率,防止闪烁 +// 2. 修复模式5的双重亮度衰减问题 +// 3. 统一亮度处理机制 +// 4. 内存优化,减少不必要的数据拷贝 +// 5. 防闪烁机制,确保LED显示稳定 +void TaskLEDUnifiedCode(void* pvParameters) { + static unsigned long lastLEDUpdate = 0; + const unsigned long LED_UPDATE_INTERVAL = 33; // ~30FPS,降低更新频率减少闪烁 + + for (;;) { + unsigned long currentTime = millis(); + + // 控制更新频率,避免过度占用CPU和闪烁问题 + if (currentTime - lastLEDUpdate < LED_UPDATE_INTERVAL) { + delay(5); // 增加延时,确保任务调度稳定 + continue; + } + lastLEDUpdate = currentTime; + + // ---- LED1 控制(单颗 LED)---- + if (singleLedMode >= 0 && singleLedMode <= 7) { + leds1[0] = singleLedColors[singleLedMode]; + } else { + leds1[0] = CRGB::Blue; + } + + // ---- LED3 控制(熄灭)---- + leds3[0] = CRGB::Black; + + // ---- LED2 控制(灯带)---- + switch (ledMode) { + case 0: // 模式0:全部熄灭,关闭所有LED灯珠 + fill_solid(leds2, LED_COUNT_2, CRGB::Black); + break; + + case 1: // 模式1:纯白色静态光,亮度可通过led2Brightness调节 + fill_solid(leds2, LED_COUNT_2, CHSV(0, 0, led2Brightness)); + break; + + case 2: // 模式2:彩虹流水灯,颜色沿灯带流动,速度和亮度可调 + for (int i = 0; i < LED_COUNT_2; i++) { + leds2[i] = CHSV(rainbowHue + i * 256 / LED_COUNT_2, 255, led2Brightness); + } + rainbowHue++; + break; + case 3: // 模式3:彩虹呼吸灯(优化版本),缓慢变色配合呼吸效果 + { + static unsigned long lastHueUpdate = 0; + static unsigned long lastBreathUpdate = 0; + static uint8_t breathingHue = 0; + static uint8_t breathPhase = 0; + + unsigned long currentTime = millis(); + + // 每300ms更新一次色相,实现非常缓慢的颜色变化 + if (currentTime - lastHueUpdate > 300) { + breathingHue += 1; + lastHueUpdate = currentTime; + } + + // 每30ms更新一次呼吸相位,控制亮度变化节奏 + if (currentTime - lastBreathUpdate > 30) { + breathPhase += 2; + lastBreathUpdate = currentTime; + } + + // 计算呼吸亮度:基于led2Brightness的60%-100%范围,避免过暗 + uint8_t minBrightness = led2Brightness * 60 / 100; + uint8_t maxBrightness = led2Brightness; + uint8_t breathValue = map(sin8(breathPhase), 0, 255, minBrightness, maxBrightness); + + for(int i = 0; i < LED_COUNT_2; i++) { + leds2[i] = CHSV(breathingHue, 200, breathValue); + } + } + break; + + + case 4: // 模式4:彩虹火车灯,模拟火车往返运行的动态效果 + if (millis() - lastUpdate > 30) { // 30ms更新间隔,控制火车移动速度 + lastUpdate = millis(); + fill_solid(leds2, LED_COUNT_2, CRGB::Black); + + switch (trainPhase) { + case 0: // 阶段0:正向出站,火车从起点逐渐显现 + for (int i = 0; i < TRAIN_LENGTH; i++) { + int pos = trainPos + i; + if (pos >= 0 && pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, led2Brightness); + } + } + trainPos++; + if (trainPos >= 0) { + trainPhase = 1; // 切换到正向前进阶段 + trainPos = 0; + } + break; + + case 1: // 阶段1:正向前进,火车完整显示并向终点移动 + for (int i = 0; i < TRAIN_LENGTH; i++) { + int pos = trainPos + i; + if (pos >= 0 && pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, led2Brightness); + } + } + trainPos++; + if (trainPos >= LED_COUNT_2 - TRAIN_LENGTH) { + trainPhase = 2; // 切换到正向进站阶段 + trainPos = LED_COUNT_2 - TRAIN_LENGTH; + } + break; + + case 2: // 阶段2:正向进站,火车从尾部开始消失 + for (int i = 0; i < TRAIN_LENGTH; i++) { + int displayPos = LED_COUNT_2 - 1 - i; + if (displayPos >= trainPos) { + uint8_t hue = rainbowHue + (i * 256 / TRAIN_LENGTH); + leds2[displayPos] = CHSV(hue, 255, led2Brightness); + } + } + trainPos++; + if (trainPos >= LED_COUNT_2) { + trainPhase = 3; // 切换到反向出站阶段 + trainPos = 0; + rainbowHue += 64; // 改变彩虹颜色,增加视觉变化 + } + break; + + case 3: // 阶段3:反向出站,火车从终点逐渐显现 + for (int i = 0; i < trainPos + 1; i++) { + int pos = LED_COUNT_2 - 1 - i; + if (pos >= 0) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, led2Brightness); + } + } + trainPos++; + if (trainPos >= TRAIN_LENGTH) { + trainPhase = 4; // 切换到反向前进阶段 + trainPos = TRAIN_LENGTH; + } + break; + + case 4: // 阶段4:反向前进,火车完整显示并向起点移动 + for (int i = 0; i < TRAIN_LENGTH; i++) { + int pos = LED_COUNT_2 - trainPos + i; + if (pos >= 0 && pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, led2Brightness); + } + } + trainPos++; + if (trainPos >= LED_COUNT_2) { + trainPhase = 5; // 切换到反向进站阶段 + trainPos = 0; + } + break; + + case 5: // 阶段5:反向进站,火车从头部开始消失 + for (int i = 0; i < TRAIN_LENGTH - trainPos; i++) { + int pos = i; + if (pos < LED_COUNT_2) { + uint8_t hue = rainbowHue + ((TRAIN_LENGTH - 1 - i) * 256 / TRAIN_LENGTH); + leds2[pos] = CHSV(hue, 255, led2Brightness); + } + } + trainPos++; + if (trainPos >= TRAIN_LENGTH) { + trainPhase = 0; // 重新开始正向出站,形成循环 + trainPos = -TRAIN_LENGTH; + rainbowHue += 64; // 再次改变彩虹颜色 + } + break; + } + } + break; + + case 5: // 模式5:冻结当前灯效,保持切换时的图像但允许调节亮度(内存优化版本) + if (led2Brightness == 0) { + fill_solid(leds2, LED_COUNT_2, CRGB::Black); // 亮度为0时完全熄灭 + } else { + // 计算相对亮度比例,避免双重衰减问题 + uint16_t brightnessRatio = (uint16_t)led2Brightness * 255 / frozenBrightness; + if (brightnessRatio > 255) brightnessRatio = 255; + + // 直接计算并设置像素颜色,内存优化,避免使用memcpy + for (int i = 0; i < LED_COUNT_2; i++) { + leds2[i].r = (frozenLeds2[i].r * brightnessRatio) >> 8; + leds2[i].g = (frozenLeds2[i].g * brightnessRatio) >> 8; + leds2[i].b = (frozenLeds2[i].b * brightnessRatio) >> 8; + } + } + break; + } + + // ---- 最终统一刷新LED ---- + // 添加FastLED刷新保护,确保数据稳定后再显示 + FastLED.show(); + + // ---- 稳定的延时机制 ---- + // 使用固定延时确保LED显示稳定,避免闪烁 + delay(10); // 10ms延时,确保LED数据传输完成 + } +} + + +void setup() { + // 初始化串口 + Serial.begin(115200); + Serial.println("System starting..."); + + // 初始化SPI总线 + SPI.begin(RFID_SCK_PIN, RFID_MISO_PIN, RFID_MOSI_PIN, RFID_SS_PIN); + + // 初始化RFID + rfid.PCD_Init(); + Serial.println("RFID initialized."); + + // 初始化LED + FastLED.addLeds(leds1, LED_COUNT_1); + FastLED.addLeds(leds2, LED_COUNT_2); + FastLED.addLeds(leds3, LED_COUNT_3); // 新增LED3 + + // 初始化LED状态 + fill_solid(leds1, LED_COUNT_1, singleLedColors[singleLedMode]); + fill_solid(leds2, LED_COUNT_2, CHSV(0, 0, led2Brightness)); // 初始化白色 + fill_solid(leds3, LED_COUNT_3, CRGB::Black); // 强制GPIO48的灯珠熄灭 + FastLED.show(); + Serial.println("LED initialized."); + + // 初始化PWM + // 创建LED控制器配置 + ledc_timer_config_t ledc_timer = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .duty_resolution = (ledc_timer_bit_t)PWM_RESOLUTION, + .timer_num = (ledc_timer_t)PWM_CHANNEL, + .freq_hz = PWM_FREQ, + .clk_cfg = LEDC_AUTO_CLK + }; + ledc_timer_config(&ledc_timer); + + // 创建LED通道配置 + ledc_channel_config_t ledc_channel = { + .gpio_num = PWM_PIN, + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = (ledc_channel_t)PWM_CHANNEL, + .intr_type = LEDC_INTR_DISABLE, + .timer_sel = (ledc_timer_t)PWM_CHANNEL, + .duty = 0, + .hpoint = 0 + }; + ledc_channel_config(&ledc_channel); + + // 设置初始占空比 + ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL, pwmDuty); + ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)PWM_CHANNEL); + + Serial.println("PWM initialized."); + + // 初始化输入引脚 + pinMode(BTN0_PIN, INPUT_PULLUP); + pinMode(WAKEUP1_PIN, INPUT); + pinMode(BTN1_PIN, INPUT); + pinMode(BTN2_PIN, INPUT); + Serial.println("Inputs initialized."); + + // 创建任务 + xTaskCreatePinnedToCore( + TaskRFIDcode, /* 任务函数 */ + "TaskRFID", /* 任务名称 */ + 4096, /* 任务栈大小 */ + NULL, /* 传递给任务的参数 */ + 1, /* 任务优先级 */ + &TaskRFID, /* 任务句柄 */ + 1); /* 运行在核心1上 */ + + xTaskCreatePinnedToCore( + TaskLEDUnifiedCode, + "TaskLEDUnified", + 8192, // 建议栈大一点 + NULL, + 3, // 提高优先级,确保LED更新不被其他任务干扰 + NULL, + 1); + + xTaskCreatePinnedToCore( + TaskPWMcode, + "TaskPWM", + 1024, + NULL, + 1, + &TaskPWM, + 1); + + xTaskCreatePinnedToCore( + TaskBTN0code, + "TaskBTN0", + 2048, + NULL, + 1, + &TaskBTN0, + 0); + + xTaskCreatePinnedToCore( + TaskWAKEUP1code, + "TaskWAKEUP1", + 2048, + NULL, + 1, + &TaskWAKEUP1, + 0); + + xTaskCreatePinnedToCore( + TaskBTN1code, + "TaskBTN1", + 2048, + NULL, + 1, + &TaskBTN1, + 0); + + xTaskCreatePinnedToCore( + TaskBTN2code, + "TaskBTN2", + 2048, + NULL, + 1, + &TaskBTN2, + 0); + + Serial.println("Tasks created. System ready."); +} + +void loop() { + // 处理串口命令 + handleSerialCommand(); + + // 让出CPU时间 + delay(1); +} \ No newline at end of file diff --git a/build/esp32.esp32.esp32s3/HOLOMAIN.ino.bin b/build/esp32.esp32.esp32s3/HOLOMAIN.ino.bin new file mode 100644 index 0000000000000000000000000000000000000000..2dbdcd136330c84b5874b2c453ebd3dba17a7819 GIT binary patch literal 390048 zcmeFa3z+1`RoMHVncdZD_3+x3ZP}LXzt&!PR@%qR>{H9Ew9`E^J7dku(>>aiCEwnj z>7Jdodb->F*qs%ED2Wop{R9Xw$bfw=>E>Bs{gAWI}%F5{l44t)trBwdRLvQI#qS*)E{r_Kd|MlqbI-VdEVt1@1>XI zf1mFSj6U(1K5r!ZTb~ky`xOq}eCWvP&Cc2e^YucjRH^POmzMV}w@T$gu^#g?JaT;a z(DC76ha9Wb{o!N&$k51PMV&vq|M0#-@%+An!y`BEJ6E{*;86bHu_J~2zCx+qyy)F= z+B>}axt(wS*xv7Z`={TO`q+2f^3VOB{E4FnKk&r&{NO+RjfaOk?>D@iF7j6aX6AFL z>`-oM`qY$Xzh~x8yH7#Sh~@OyZ4*li!{O(U@iH6FX1?Am zRnG0-zu#M&oF4Z}l~S{mFPH8q7WR8H6A8q^>DjoC=}N8DY{YTdeB*A3%aaeH7WP_j_Zl=324REUo05rE0}r z&6mo>!g1eQ#F?Unh|K(AI_J&K=g3sf%ivZn`clS5vFSIf{(7}gB;0i6JQYyz8=(hr z@mH$r>-kE-MlhGt>S;9VrCOH=G-`EEhNtMcARVbx7q@(y+>nvoUZ%COQfxH#dlU6~ zwN5pw$5zFbb-$OcmdmAv6uVGt7FVQpyliQ`SZy^s_#X3@TdS)@B5L@RYSUjXo%4&8 zYU|wEesa?+)+_n4Uvx=Pt0Y$_Qr~OUR=J=-*7CJlu_E40CFSeqTIKdt1&{fK zYSF~Mo^P%Y^_V|9Jvp{G;V(?5(|*0!s8uV4V!^*qYOeWnW4G=1mMV8wsuwCIZEt<1 zSjb4d?YpJYT3;w_6w8glJ^rA#$G`rBUsL=31|+J;ck=Tm^Nl9e?M?WDyUVRT{_e(c z%nlDq$Y~QLTn2X+_8g~%;)RI#&(+tPUBVQK8@|+Ub=6pt0Brdq*}36hOx z!z4ylv}P*rZu)Ea^F{xVG$vI+?R5!KtmKy=(Z$)Uzp|FERElLw%$-wc*7KFddZ}rv z$X~vwK~0C~9HdYzLpPgF!Fo4DU#tjq)O%*>LZ0lbLb_6h0%h&#yHIMptOD1It5DOL zpKn~Otn`dI$j2q~;Ao;+m$EtX?p%A$Z`k}R)iQ+*+Z8G-bPii#ykP*Ax`EUfh@tn+ zKFzSFHJClKDMGLz!tp2BRMIU-HD~c1={1r;A>CM;_sr<>#U}kfnPjIfVe`3CtzF!d ze^=j<9~n~1JG>V2SFU)TK9p-RZFo0&rxvE?y`{0mY;N(4fmsXF*^G7IBQt$!c5HlN zCOhVhji+<-a}$}V`K*4Y=jXCAxTig+Hb-ayL^eH=$z`(Rx!Ls0ZGj~fwVcib`0@Fr zY-pLD)9>u~Y#3TBL1?kq(DE6CR*Mb2fJ637&LwEA;&n)4k06Ev#9}-E*70fPTPch9 zH};r!+(#1b2eGGfvtya;#9}TpJ{Gg4XVjXR8M}QVaI`kuG7Hl|$n+E!9K4zcK zOh@e*T4{WCHmxPLU$f&DHx9?6j_?=uW5j*HU(7G1r@W<1DmOlBz=AiCotjvjo5<$K zk+-n0kei(!pO6}jSZL+YWf3w7Z9+Y}8(z6utqFs|w?A84uhuX6)0Nfg@g3g2P5*Xy zzMri&nQSx6V!r(`Rvc^jDQ2)E`-fNk+fsYP-(L)Q~Ky!09j zldUq}pOtRxYCs{3&qQY7;0R-kfPI

!8D>16(@99dWKxf$PE{hf5z0zK#sLhU z9q%CnweK(FSMJWA3)+Mnksse*ES@)PmS$1@Q5*Y5RwYQ9;x+=jb<@bw3rkXeA8aug zUQ{21D!2UEse2^gne5n1+#TnFbDf0QZAr|jQggLbg#W_zokPPz8xnQ`hNB=%)MPo& z49E{x*ocVBLS}JnHtI66|In$ad;HU-$&#S?xiD!WX_Qv{RMy}_7ceu`3;slBsO{%>3Y7OYSBYzUKgcA>b)1|9iGW_Km(XJpFJ4QuG zXV^cq>d%_KkPoeA0w9{l@g_&3*QAQ$+dR&mUj(F38yOg6Ir7)RVkqUP|VsuUU z-s$-r-h!;8WChX)seAYE(FSG77Yg;`{?Nwmp<`$EvaYy?WybEKrjvVn{pQ6Q2!Cv0 z0ZXH`Z0wU`>FoUC9Z}SLb}UDtQB-y!la1OXk&!cCOeEuD%x{rMJ)-ayrta|4^NSPX zOS22!-0hj%Z4-B7yot%B%tUU2;c{+#Vsd&;xarKoR5rUX?oEzmWniA1%y=`?+3d^& zADQZE^Fp4UZkus<==caL?Ze)CTIFDgExlvC#)8ZrXKXqkOA{qJrPT|iN}+n80jW4o zQ&mQs`3zM|1sQ72EbN;epY(4p)^(ZVTn_F(xPOR{V`lx|=ANqN>jjrJ9Y`_q-LoKrJ-MPE<{%EF7#B!C)KbbmLD^)vk*FxQzN4s{=Rky*EWF=m2)!36@V6baq z^~Es*78`Y94lY(02~z zBv-99Vqs**V71z!k#H^Kn|Y?u$a0&_k(zVyS7i@ozdup0pI}5f#*|fCyV%H8S63Ud zhG#6vP0oyErgG`A^wh)%BT^8Y|kl$VQmoC|8r~`NdYHqB~Kg`nnF8 z?7yt$Ws15;#kg$6GB8*5XU7lQ`X<)Em#?YCt3K%R#!*AAmm0eL689-%RW69D!Db9R zMul08R-%zIGt-$YbHGCOj=>ump~oDXOwB#*jUz1*#C9O~($=BkWe#?26gUQ$wx;e9 z8w)#F(I$~DGm6s4>+7+qS`mh_?ie%%J(|tzdF+R8`(Ue7r+l}Z@Xzlq?B8A3YwOh5 z_Q$JdQ&Ej>Dyr#qVJ(FDBYl>`t1ZZIxqP?e)a0hz+RtRZmp!>At9r@+Rh$PS*m$;j z#--WWd|Zw$Op?>%d;Q`@O?M9AJzeDpFD#WUj+d8Jj>rIqv&8ZhtrOLY9xnEZTGx>9+A zEj}3y%>E*2z+6k>{vf01nvMlhB~;>Cv0l8Dm0pji8pU(6#mcsl3~##&wAc!qXhXIi zvBtw1TA@nMvAGH*1$&OG44AQjB=i%HAz8sWEwHH#TfU)VWg0J*Ww&W=^J*j4x`_MC zSRa%_$V-`H_P7muT;7low%CwOQXRg0nP{9_JR*k3RaqR*&Mq-LvRGxejxqT>`~NZ^ z$2~_1CDc5q8QW{xYL9K|cnH&;GGlQ%Agy_!E_>gJ>JEoBVe4(%+jigUmu2LtGyCK# zOiHsUR=*)J5$9U04o%Yu+Gfb#=bKzGGOSdUCm@fmyJ~o1F2G&8QMPSNjg;GUphSOZ ztmWw~Oa$;={*YHGUdZL^_58&gMhlWReEWPq0Gl|JlzE&bj$*}Z| zSj~^y!xLSb!5Q7X$7l8|mtETl`=ISh;_|&*s^r=DF^#iEX^M3XwclT;SC`!;cVcpJ zJlDaIWxArQ35D!e%`%^ohV#}APv!#-F4zHRm}Y5f*s$`0uUxf}TWwWVgcqXFSajH} z)^h8uCWjVXi6n^Oz)GHc5mO_hKXWOVLr#pm`^fT~?<4ZH_J~6!;Gup4S{wvk!uuWFNjs5=E zGU+jT1%8NzASY(JxsE0 zu^?UixH`?A9?y1bgA!Ae8A!|&5DqLfZH|#}FzI8DdZ`!BvF>0Lk$Jw}WO!45Yt`!A zIX0PPa4{hjv$DKbX;EgYJ+Y#@JWeOhds%}=Ysh)iqPVucBr%mL4Gz^yDEYr&>tIsOCV=PVa%Ekrs*YFDrq(U$Z zHq4AN4F$9>(-H&9@mO)-9(FfmpJ4}IF&9GwW;=#DWITpvlIdYcMnW0w>+v4v7O=<} zSg8o@^ylsV80X%3ovO`ZhUrJvG9r%CG>7~;?CsMqmJ3PDjmmTjp9F=@&rMFB%1tg# zOe|*SGr6U?Y1yol7|nTjLD*Or;?_#FvRXP9Z^NL8B@em;Gt+ah&+lDI;>RB9$f#!r zPL@b26Je)pS-Y^OYH-38C?YL0CvBuB*afqw6BJ{vji&nxD=r(#@F9Hk!v7@Fy11!)9}jTH*9z zAw3ee9*kS{s6cCMAuTSx?=8rNuY8ORxetv}FdCVBXf*O+&KmeQ>^vWFA4lECG52w^ z`xrJ+dt<{UYCcTVe3+>DFj4biqV_UliyGdWIFn9~u{|yyw~vjFFM2bniBsanIq}@M z`AE+%&1J!aGo?&Pt%@1*5X^BWO{S%>S{Gz@*qRMV!5go(MD9bDc}g1*uXiJ)!+}}o zl&;q5RS^<`!49!BCG;tKh>Wm0HmJl(MaF*)e|xwNvqTX}R`T|y;epTP%hN(LtreO6 zJ%q1TV2z0+z)cn*xC!Ya-i&O9v+q;1R@rYJ4$||?DWztB@ov0yzEmitF21i=uX+pV z+w-G zso7G)L@nRKrcITanv|9<$dyUm;;L&Uc=>2fT|`0FU2JQ_79hje1jU-c#iLahv8QW8 zS7V!%NI4jFLRfFlMR6>wZSBWqk1>Sy>?=v}qrsvRje)6=o<9o@&sy129e zH*IZm+3C5ZiHv&XVAr3^ug7;sf;m#=utp_cYpgLPK@Zj50yxw3b|IT!sXd-Lm0NIwyyuG8w!#cW7v~C-11cLyhW+@a1xlbAVXk zfyUYTXYEci$%d7#T^Qm%pj%$vw6UxF5KDPVOTUrfjfthj2BwVIMI~(OvsN#bW!Iv& z=kZNPYkh7m+S6JJ-Ivx(`PCKW;}E4=lQXu0Nmh2}8d6wOYW0szdGV`u#2Ji$t7E(6 zqOunp%87WP*)tajFEcH#pdcb9COs0FYiIAMq=ayzu zEav7Xb277Mdba9Hovn8h6;g(*N$d3(FC+Y!FRNZ{tKBu-sGI;;)3@W zN6KpEju=*AnV6ejIyHq<&R9AuxCC)kJU2Gm*;H{g>5UzER3BZfSe;m^Xn3iw|X>N%>1Xa@j^mP!nbOaoTxh*BN51IX`);D$f|X& z&bf)xIor%hx+2aq*$kDJUhGs_aT}lL?v|c}#cr=82_{aRv!jWLQ#(aV#fTU|Pnxl_ zjd-Mr7DM`%&?0p=F_%R=ZE_OIj@91jMH)@ZddEUGO7lxI3vsd)gmg)*>eO`D(&FIS zbY>n}R5s2vk+_a8EzC@(>EpSXvD8FJ4dNEaM09XVEso8lr*iaX8PTwu3Q1BVHe%gM z5K?qH)%={4d6G24iV)|_#LPrmI^N{G%W+T{;;tisD`I(v2 zSo*e3p#nEoL2;s2$q>FO@PbQ<2(ZJJ!j@Pq6nKS0tfNvaZL4z`!o}QeJ zN1zzVl?;G!f7%1gCS)gv`GtkZ(4+B8PsTlpytt3Do2_J5PUY$4k^?d_J7X)H~9zS>pGiK(I!rT0FV2mHgQLYyoS|$%5uE3c>MbVC zj2-wIM+8@@eQ7c53xcDOJE7g!G?vYVRVe<)ma=j$!_wSsbcK+LG|(C5Qc^rUJvYu}xmYlzSY#TSsjN{mPvUwGCL^7)ReHh@hBI<@j(48PNZ*VCYzava@~@3MAWAz9IM97v5lghDEBhL~L!F@Rz0oQbBM*w@rlg z={!Z-R9a|0J8?dC(%xIWw^+-Cfr897n^ACR1SFXk0VF*^sWIX6}$9WeG34Ie~L_F*m-L zIz>^K`w|0#^OVWRN+}yOLoa`3=wL-XIkq&z8o5W5;+4U3LHR&!m9E~;93Hwkmo_Cq z_Wn|lGVSHkQt%!g4L{q%gXwf#JS^NMl}c7*h2F)FR9o0UJv?beEM(eNoYDHvP77^Y zE<6#}>G_#SZKF%HQ`FxkD&Kk6nuOY>C-3N;zSPBL{PnDuAXTP-j&0;TSgK^r(xW;$ zHlmDMnVjqb#HN!F-DzoptoW(8f5o_gHo<17TVg(!_*ouCxfp{oyK{?)J%N~8PS*_~ z8)F<@;%xc{J=?f2a?<^BNZHJVE5pEPAveXzoEr-w=nQ9c3A`}Y+-Qt!{Tlz-u}nCe zOr558vg3qKhFI|e^mryW#Ts0jDoh~i?8*WW_4Y76eM+wK1i9}N$pU*;(aDYM%g7(k zokN->g4vO^xd>u+elqNMvC!r~(=C>IdFi;r)gh`S7KqcQ>;)pbJ~0{PEPwVCmuYn~ zp=*+CSFqvGEzhhf#=1Ikyvgpp3u>f~*7D`pi9uGy$whY5Ud-EF;6k3iRyv2knjCf@ z+>2b~hu^WNI9I^~G&Oih>X+9OU6!{pA%#5JCuSfqzVu@4V z21l$&8508W*nDGGdp5-Jfc&FuwMK543lnnCBC`F>dahK-p$a9xo-6QgaPWK;F_atk z6jVrLk5o&|U}e<#5Wj7bjsGBA|$Hk~U+*#4A|nE5ydG zU^r0>uIo!K8hbQQ!wBd)3h?ZmWrbr8&?nH&*pu&IEF&c#ZvQ zp16r*SguyBmX9O+s5h>xf`#KN5(;dQs#e63P_u zl7)bD!}bhg%vF&6vH3Sy5`+;I_iYkVYe6!m+|m#xR6GJ5UZvWju}J3&b9)a0BD*{e z$n{eZrj@ilNKl$+7eegh$3@xGr_zkkL(!GWI6IFJO4uCIcD9-K-J;|W#v>_c-9+2LA+OeM&uH^n1jbEZy`jj%^Alh^)$Z{qkg!)!Y$E#rs7S| zu2kg$7@9JkEe#uieU9FBi0(q@p{I6Y58Nzy30-v~d&zyITbZC{9KXqk@84u%k zHC2%omQUMlG<=Yt)=yYzxpidUq>dEjH)>_%4pf7Y6NZrByS#JMITZ_#5UOfHLJ3-H zw^^;4y9K*C_N{0acOt0k`TE@qb_kQ18jke?UoKW6ut9_C?RfeEcV~j0U<%-xPC}X# zG!7F&D1=&-xZ!?88x*o2F2zP`Wi6Uh9o6H}l&T2WBoY^IiEem_jK(Li6e2d#GBRoH zu5ppnU3yVjrVU?&X3Zy8YK#n%o&F?bQ^Z*}5mHm=dMg6g+JSH;WG3Q9nTpPu4o@djnc77#*CF9Vy3DOAretJ7nIkX4p#}FX!U+7E{9zaKEwP9-H7^!E#@(`q zBO6Szkz!8?u%2R@i&#_u6(vzzOtkg5&wWT&D8peGl1{kp@Ww@@1DAybIJq9ET(9~# z`=~Ez!-2C!L=M=(?;@|Yb|L5PA|Y-plMJk4Vc#vV>*pGbh__Fq$0stZs@R{Ig54ii zlI`YY4uKits{@}QylEskM$CFnc|cNaoG%0{ROk?^On1dhM_Lu9EE$D&qP7XQd>Lm{rt{3+d~v4XIQF z*F~Cd<>E@Y*x}AtGAnYU(?uey2N7c@8p&d{@N!5^#%8VMLb0*JMX~U9_{%DYNEz zE96$VSl|drIwGeGi-Wt2tRF)L`u7rdCT&2U8~nR2-6N8hFsI%L-*g~ z@9{P=!qCF@2@gg`TWLG?E@|wY=cXB(Wa>bLOg)BK_pBp$Cqe_ zAl^&me={xH(z}(&n^%z?z6ebZ`Xh%aL))O(wb$qsB<*|Ibc%AU7!qX`y*L)=9JADd zD&FQXC3{H4Yi+crTiYNOFL}*Unu`4!GADnvjqxI!QL!L2G$YIKJyL&jEm5*Lzbf>s z*DVMA1TjN?w`vSAsuij{-i|gzN7s~8+|5%%GGXR z^^6&^VGMmr&)}V=_xkTQV?!dhOI-qLI0hg|s%LQOlG$>;B^ioz8=_@IX|H;z+Fmzp z#XVMRQ$sJeMlC5MWAgqNCJzNj6{S-`XSI#Ax%-H{ai`x#itjgGh2nJ3DK@6qW3b`r zx|a^mkSnWwJBXoNrca}%BEQ5TF7=KCxN&sS{Cs-6T=M3Q)5_i4I4W^ni90cDFb>w} z$ntH5b?Yx3_@nC8m-eB+PjX_%mrm=`BAFgz4fY8cnp#VAG?(-L`SnJAHm13qD`TKx zG3XJNSj?yuQW3eggW#!pwN*1U(1V(i>=(OIm1gdogcU}!jV03YRioAlG(@g;a@pEI z4Wi`>CRu#lz`}KPbx40pGlt@a=x1?X!azgejRFtWpFD|OHJi6+b z~ibsxR0>M0!J8Vsg|o)a)V5-GqJg&JF0S*T~d&nPGrUGUdYBJS0P(QFPA&& z*On0nHIF0=3Yar$W=I*|0V2#uCAvm$~4Fs7nIh$3X+Yl$x9E` z`AFh}?7POBT}Nr(dAhq)=*^#vA_sxZRDT3!CYp!sSNi~5Kr$_-D>$%|bQ zJqN1=UoRU3(h7klG#iTZ8jV_RWUj2q-FexLx8;D2+fvKRFx@4s>q$&#C z4aD2fMnW5#>zt};UN&`gYKq6@{HV6FWwtJQ_<`zcayr+`PjIGG*UQnJ6I;%=Q0OC9 zbz2p#<(7))+x4Egj5)m+NVdpr>&_9@H@GCsR4pSEO2~SYfqh`{DOxpaUSY%+8 zR+2H^9PFY3xk9m#H#oP(pewtrh*1o3WLIw-I(Aq$R;B+JoN5uil@wtB9?l6auR{|UioO7CyWl+WwQ$= zr_7zpEMd*zXOHGrPuhLDN2DsPLe00GQ$xBdD&8afUEE`RBWJRVR1J#ZdeN9>ie6!h zh;PxVc&Sn}HxWSE!F3AJG>7_x4$($^g(Dw>F={yy>%pQHZ4cD_Vr zi%z7TJHIL%B}`v)`(;ioa;mk)`VkJ1Gsg*UMcEzsQl3^yp;H+_IS6r@s~Us5 z0_R=Azf08GuMF>h`y>Lg!urcC$mz6W=_}_sJQG&g$aJ7>&}3$Rdp_DY_h_LS%Q+6E zdC@EP0b~nJSB~RsQG-k#U?GTrSiQ2cUK^C@qLy#2?e)numB43?)Bn{HdODLB=}g^L zlK4GEhnv{H(v+EUc@F&(N0Q;-ok!$)P0~ZHqBa3A}jck%F`lw-Sww?HJJs zBc7~_TH_qA8Od~S!e3FgR_MQ6T4|y^!s@Gp`+(p?TW_AVCbN}{;X-X4qhb@mMAWFZ z>J)-C*#|8*(j|m!jQCWpsMjgF7p6qbm!8;n4&Jcnt-CJlXQysc2G4xF-EvU&K ztAxZNk{P4(StaiV=`m%;VrwBNL$!<&Nm;RXtVYz*ChIY&^Vp3@qU%f^NHT2`l+*Ba zohzjhKCL7=cZ0WxF6le^5YY}#1cKpTSzF3U=CI7c5ft(sM-Cr8sG7#%gc2S@Ow`{l zMlTWMG9nlf8N$7=Tardx3#u!$&CO|??yxw7zmtAn~tG(I~9 zyHrBfij_?#f^+fM99dqTIS!3wy|U&Q>~LbM*)uX^W;@rF3lde^-_0-bIZhVv;`(xx zrLhx|lU-1iJ!K0^)|sNvxpR6EG7c;7Wq9?a@+wu1^*aYL0tA>MLr zW$P)@-d&P*(_Rn&OlSdDG`42Lr36P@fGK!LZ zSv__xtm9N@8wu3gD`H2EzJej~lF^2=*(-7xAk9n@8FqUGaCGeI5$S%EVKG>D&JgsY zofxjxg>bPud%P1z9;thooj8zP4AwdfGCIC=?Idp7Wix|agp$L;bS`w<>m@o;#PbJ5 z#H1_H%TA8^Q2w}U%G!s*9CnG$(H|Z+M<_u*qJcKsk0M1Q9SLQYLY?#8KI*|U1p=>| z4P&T4bQ!{@?7k=Q7J{2wBE`RS_cLn>9SKYW^zPb`QtR-@v#)GZ)>&61nWPA-4U?km zwY;m?6j8WN<5Dy_x53)*BRxi@!Oj(BJDVzYL%i4IiFX-|NIx^Z43Tok0>{`uk)7d~ zdd8*8M1t5^v&T$MjVM*d@^2H!U22%~%;UgG_2B$v}? z=DAj{dOCB6O>%FJi{{FG$g6&&At9nX+AeN?$rYep?al5BIuaqJMbE!#UnFUo*qDqk>iCLLLMgdto znMd?kfyu?4LW{k^$b1KyVMFPezF{^)i=3{BPD0cww^oE+B$nLTJ@OQRglCcNmMQz$ zT{|x?+2q$xw7tF(E3?WicCOz}{oS;RY#OsIr4J=0+ z22KIlVzGL8gKnaG%XrX>2||fx1D>LBjMiyG#ny?GI$0^*Yr@U@n=VrzW4!4QR)6uP z{cBmJqBdXACWu}2Y&s$4+ImhO=Gt_SP{4NcnF|^>fF_qUPOyTvm-v!Lo}EUj z6@-68owbfqV#$duJk^d8uE>6<;%BQo)UbMno^*rqL~^+jhS2M_mRcphBqdvp93aZW z;PMcduqr5YM>dmHu-M~c*|gQqZX%*Png488K~RpHViArmXSPat8@!B%|qh6M!>wK zJ|K-StE$5tP4z6oRALKhcXOkQeU(lRM!}Ft;11-j&6Z%x68Y6!uGXvTkqm62l)-~h zmkgN>>Qa-^5?M}w2ZUi1+(T2YtlqThun(-!4j}VVi&yMVt5#rn$AbYvuX+ogv`Y72 z%FtGdcbqQaD#9~fI+W|9S^y_oBZmt1m8#BZxksNghnf=OgRBh7RVHR0X6qa*Q8d#& zFSlUPP04be_Qs{`4=wz-kW7QI=j!PEIJ?Tr272I+8P8+_rk6axR(mO=nqX(|VQ!g%{JgWOE6sl-q6&92R(c zoI{eOOeEXF6B&s&EqRwbhar^!UBy|=`N|s_s&bJP3ql@UVv`KXH5e|dIcZtjiCyqc zdC_7FB7b%qoz(2}tJ3~R(!M#m>eR!78X)wh%N|Q_FG5WsjwfmJ9I#5}b;&}HLi^GR zCU8hNn`?n-cK}JxYf4{wWzh&FWn}Vs1$1PWPx1FS;v<0TDr{uP!|pN+upEt+RUT)u zPiFR@kXU%5eZCjbBLXN_CQ(K>E5d-2?QgZpIDfl+0=dL<^Jb{ue8$3|4Y7cF9yV;X zDkGWb%{qfNweG1-1pZ%cnyxbC1q$=R6>>y!!-{=x&JG&BTrRhnSQz7#7u0KI(cyOa(|`a;dAj555|9 zJAASx+;S#vIp^iwzuh7!n%p7nc8sixBXf|9Fq!Neo6)u*SL)5DVf1(VR{0*UOrV_( zMc<;|y^F-U?8mOJ%egh6C7LoIh(Y-*mraw2c9pWU-Qb|yRy#O?bngu+c48m6k!>Np z#-D>s_n_tJ6^7PcWJK#rEDS_CLejReZzfaqs*tJ+QP_Nbk^v)GDRjt6@MNlO0##MS znT~A*cCTWzCL?lz`ACE~oTOE}pE)0H#uc?voqd=d=FUbD9^m3s!DqVz0+x;J3Kupw ze+u7CWO3Mu96HBt_VGKrnUn(!7*_uQ&ykwF4mJ~=+y_J?=tuzMp(UpsYbD}M<~SSJ z#)Z&~ke+#Ajc!?kor0TjuOUarDp!Y;L3D7KfW1UP*7ZGAm@9cK+qH{ifemfd0mjU4 z)WyWPlg`!CEjIHouU5##V%IHwcA!P(3r%4`qUTFI?8vahINuY=x9dOVj#1IYA9hDXFkGDJ4Em?bj)n{Pah^YZGH=onr&Jv$`- zhP~|Rv1xB9lM)Rg%ISKX$?)J8y2>SsFjo?tewgHP9O+5A2la!OB|W`KLrij^X2i>$ z8p?5@W@h4c-sw=waKwWDz&0H9hb8nkoD2P>$9Q2jH%*#}J3C1P*^B$onh`}SP^P>R zK>ZMvH*R8FK)*L{jZnIT-MVM)n4?*&qp^%Fq)^D1_NW1v@?3gqDEu4_KS#pPgW=~P z{S-ZoE}Z!`0nN7wX}(QR^L@x$%#3+sJjaAO6>ky|Jk{kQL@^Y%4#%w{aqB^kha1qi z4>zA$I;9z+OroVEw}8fSS?F*TihE8&5xc0hh}wC!E#hizI`L}+!-)un(e@jSU^o|z zAh4MTF<<)V92v;7aVP3odo~ZX6^V#gm{%+M(4XTcdj@x; zfJAvtIqzkz?lpB4LaDn6sB$IHNFAWpMK%Z6Tk&Oh>s(NLt8_z-4bV&bru6z6pmO|3WFMIVj6EN}E+WUJ$HvAEdt_NxrT@T^uR zLaCryNsWzhj9aa8aZzuLaVWU1xJGzGb{pa}AvfS6+e$cQGg-Oc8)hbFq8PlvKorrQYp}O0m1IO6 z%)Qtg7b}Hj=k;2>9&Ft3yl0PRz9Sj8zPemQQtx_lUE~6m2`q2Yu3WTpq(SKtH&?B! z6bEHfQ~5*}F=8NOBiBNGZkSOMK!%Gd?_Kr`G+5hMWNI*yZ`^fO1vE}e6cal|rK|~G zwbsg_oPpA;@!&X|mJ>VGS&<0TiX=2?wc*Ky<+$dUL)_T!Qd_+7F8MrQAyw3txaJCh z_BMwp$u1>nbI=f?4J%p;6eG*H(j|U&58Av>GC8$-A2U~cMZ~@>MAsa-K;1HBv~0v{ zjoa$26{|0W=0f)YdZW#K6$Sw3#<6l+Hf%Xj8zULg>+TZI47=EE-Zy6Rfm$Yy){O)* znz*_*E9y|}^_iC!j&a6@Ys8JebN@Snj{?#fEjy` z67M5s_!J(a6!Dv!_B(f^Xl^>SYqWEtDNuC)w#6LvBpR&33Q*x?wNr+2pkj5LL_k}5%%5d&NccELCymici+3J5Kp+yN@G@RzBV>8OM=aeso zxfFI`Ut=vFW5L)R@nvnpG^^K#kvkPW)yk{0b}%9&A_J1=vvQ8he7eoN12xlkYY>R0 zgG@2n?FuN-uzQwkd9$(sP_CKq|4KyRM zF`P$M5Wyw)miKz$@LscuVYR~o3`P_7TRwJp$-t%I!-srTFr{VOTqG;qQij1+wLo1x za8p_KQj8SK^})%!$TxD^(CVt*t9KlYw5~`xc8v`Yuadp~eZ4=cmP^MZ!o2Gj#65hL*kIW5tzYhlac(Hy=4vJi6)~J$iKY;PBCXs5eJQ%vqO*gItO1nk$yn z@U6FQdRts5z-);x=L^Au2Pm=Sl5e9~IDTBvN~;lTy`I0wI{+7?LvX3yL#<1tC2C$o z!wZW!qr+x}y>{*}%4)e<@9xK_qOrb~xgD?qG1uvPx$~vsh2zIjP>Y?D;p3>6sZ|^P zpi$34YjME@wQHbdvP|H;Q!~@4^qDicEKl07$DTn}zO+mp_ZPVa&BGKPs$?{ve(3!H zFPc1M$=D@R2fSznlS4;yk|u+Qo|$+&pF4fV;~nw2Eayk68-ODqxeilAsrYiMR4z0Q z&=n4>)T<3n^sD84bEgjMR|k8zEa$cRise;ZI9XLm7Dx#W&@7@oXZtg_v&V{(5%W3 z82(-y@=|3?i1EDV-{qyAd9*+E^vC;C-Y5D~&jP=Wc|q)vp9}l!jb7?SjE~<=VLwZJ zgSc(q9j4>LUU?JY#JqyAhX^NCePc+^CvsxdCOkPgLx%k_Y&^pX2T8-?|I)_xo2j7SDqm3NiTKH z&%|lRxjPsw&q@4tqPYiuwmcMx#Ubun-UBURI=MgcUN7|oW)Snt zf|q*all`gt`7R5d?~}k6!GE4__P%u3L#0KrEccMCjbjLoJ=b!1xxE#^%SmXhv{5YQ z>gSd(L>ycI)teFpU|i{yHj z(bsSFuG4f}l{KhR6%G734*P2;1lAx1qc0X%ggjm#Aw&a_jR+dh_hO8-DpDq)E7q8A z6MNi?CK&goNydD!Q(RB_0TWG22uQsNlWKBPL&8MVBT2{vrdSCPEeJm90Xxp3Q(vp0 zP?U*DxBjY#(}>C>du>W?e3{D@F<0b0LKk=u4)D}H@GWs9F!JJ10=16pM*^i6F>pE8bhund;Op!-bwI244qmgzUo;UQPtKm%d3sJDH%IcIPEME$|Xj~qUd zlj*y`8&zQh);A@v<)K6i%qf4g-t6;6!9jFKo?!jvtN!Pol-4~ zGyLM{6E`&T<}S+1P7wz~DncRfg4`;?AJ_bfyoE-g^lV7pZHNT0g!?i=Xby$l)LgGi zk%d@FRqyTZ@Za{<>vmti>z(f^)wol~*17r-ixQW|kl}eR^qpmR;n#mQm(!J%N};Hi z+-k)_sYMMf(d6VU1Qkm0IAwrtxv>~`1nmj`%8l6NBFCik+#q17VfW@;Oq!X%S+>3D zvbntI81%d=ZWtK72J<$|4VVL%W0*0_doUTyU6>-Kg1LaX5A*$)AHn<-=26T)$NVDZ zbC@SFzl-?~nD1b&c=y2QZp;zPdokxQ{|NI5%+F!|4dyp7&tm=z^Acv;;K1lxFuO4O zFej}U2QFdm#(WRvM=>A6{2WI7{2L3M|3AR~b z9sACkLjMxqiHP0D{?&+G^CN7&N{d4M%mI~xQiyW@0orExzJKSXzFs_fQuXi>*Gv5V z-d>a5ciu5D+DC>Tz}^ph7&rj@6mSdhSAkoBzYp97{5tS5;C}~h2VT8zVDxg}yMa4^ z-vzt^m;qi1JO{iAcrVa--i>;wKZupjs8sKFI21a)RcL84uJPCXq@Gju%fg8YU zfIkX+1Mug8Zv;LCd=v1$0bC^r+{05 zzX9~#;CcTA*av(O*bjWuF#dr@fm?tX;8x%|a2xRZf!-TE?=fH>@Rx!8z<&!I0RAW7 z7GU29;eb1V+kl6G9)vRs>;s+!_5&{peu(@D9{AIO2mTUp0QeMe3-FJDTY=vOZUbI% zkahsR9k?Ah1iTzL2HXK$1YQ9w0Ivkz1H20OL%^$nKMQ;f@N>Y|0iOoG9{4A~Yk>WS zsCVF7fNum21K$LE5Aa&xS>T(2e-HQ;;75UP1^z4Gb-<^92Z7%Jvc=(TIXp0W82A=o z0k|Jn1g3zi!1n>q0oQ?Rz<&rV0Uri_0QflYZs3zZ)|K8L0oQ?l27DMeaAaWg!@xHI ze*(B4_>;g>z@Gx11%3p05$K)tydMGf0UrhS13wQO0RBF33-Fu3t-!5Esc+!hftLY~ z0=EO_fR_Ucz#YJQfmZ;374R{&wuYucvZ#z!8faAa&z-8bS!0!WI3H%x0Rlwf>UJZO6=$-Yv?cYVZ zz_$YXfy2N7;Cp~ufNQ|5!0!WY1O6<~t9jnP2KE7;0`>#{1ULYE3AhFLrcuHHhk@IG z3&6{OYryTmdx4h&e+sw*_zOVqKIj?P2mA)GANYn7#0xwQ+yYz$ZUz1Ta2xQ`z{`MN z1#Soa8Srx8)wj@Iz@xy|0&fSt4*1=`*8@KRyaxE&z&8N@2KYwcJ8z}EfHS~rf$P9G z1Ah?s7T~9WZw3AV@H*iC0~`jv^W?zj2=F%GLEt^WL%>e}4+H-#@Cfh);8Eaf$KVfu zBS7yV#w%bS@B?Chgn2~lz@G&61AkHQk9*#43Lf}Jf(L#ZH~@TOiuwT#0k;Bg18xH@ z11|&K1KbY$5uo>Z=mFRV{4B5^_=mtP!0!OJ0{t}pp7Oj2U?1>(z<%KO0tbLU4cr3! z5^yWknN?97FKZNoUkjc~hC`PvI(;_T)5njE zogH$0HdzFo_1RwH=5=Ke(TZ3Rv6GiWGWkG<3{% zn?nSlT!Xv%p%4CgkrxkL3Zk$%ji3urq2T-FRBCq>BHI z{x$27Od$DUf?7!-*r zUXhMhooU!e04)!4mFBXRE(YWkNxOn-c;1yBzmrE#%G}Z~-|lzclefxvq`&)c*PrmE zedg0UW^un6!QE_e|2Bd7aGpC)|8DM@1yI8Ki*5IDIiaw9MUl?kB z{}H>3VB5}}-e<-Ced^?0b}ex~pkhc#`|4wr}yu@x038@z5fbp`fcy^USHoe-sOGQfqUtt zclW*Y(gDm-%&mQI19$)ZlGp9RmNRh5KP<42N-OvAbrQo*>QvfB!pQG|O@=#!fbN9DV4mlN)>&4!~AT{zi5e|)py$easz1>ruk*>E(V3n$~^ z6Ppd^hvBXw+-El%?qnG5YQlYfv*GRw!@Y)ZU)*ds8qk$bX!XfWhwBf*Ngx06ro(Ls z!m)Jqp4xP{?LoNL6YeXU4!1K1cMaj5-gG!W2=@lU$xp@^H||JZmVPOHO!|w^zRjZSF$#;_=& zYn6*`vtC}l<)8s?D_mbTX9>A7k8V`iIFrp&{jqP<*XJJeB@wy$YTpLdoq4_M!i~6C z)`fLa-F+bkBke0cY3t~3v-V!$#ZBUICTYJ^deJ;cpM5#ug+`;lWO$+FmlL1(js7lW zm-LePkA|22BtMBqOwum-i~c0O=uiAh{4RX5e9qm4NyaC1k$7Afew`Ny2=IV(Sbh?} zJRcnH$E#2`$3F^loa1=s-zyqfjhw%I4{EWvQsk|HNhDs7c(=&l$){}oZl2rKP}ZY+ zMyf5$sUq(WmsT=t$hydC_47#H^TeY@kcqxi>>i^E!q|AzES;Lgw45?=gc#(bw`)d4 z46Pr@vc7OdhRtJBkt}z1h&_qre4FB!{KRpm%*Bb)ijkOX#9d8@Se9(na65vNGWX~x zve0rnD$8NT6sI=j;$*d+M#e4h5Pyj<<{C|7p~S78Lbj@5sqtw}mU!Wy)F{psFG%br zLK7tBS#yHAF&2E15%jLl%dH}bsNtQLpf=;C5l=;%yv@~XmD_MiJsOdFe|4N&cNNko zHOE#ty2_d(8I!|yKQ`xb0!H!0^E{`y8X;o6EK-HgmMYacC(p%#zL+S_3YuV{kI=#7 zrHr1t`AUGLSy)N0us$_WFBta@@pcUEQRf*|G&+R}d*X8Ckm|_HE|}cJs@bb?TR$Pf_Xi9UYD6z z;*y(4M9I8JnBk!zuL8+1)ajjASAKRoRMD?@eu1;fiH%Y-Et|or*2;tdvL|m;-I8m>f@2iq<1-B3EP%nRQMu zNc$37fHd-ta8?a2&zPqJ%~OJ~jS^*mL=Jfc@et={h3c#@71|(Z-d!oJA{VI_8)bJ< z6pO;|+j7f%+mtG^ue0eUmU#)z)AxB8$aB1$Bz`zjj^X67ANwc|kNp@Y`>0MqFWALU z_Qs*XsiI73Nn}#~6;3`tNu(5bQ5tjG&xy*M462D^a>(%WI@UG?dZLr;jI@8x7WD4El#C}2>@iTj*9QAi^Wa~^Z25G5kjI^T--}x-@nBQ5KA$~h^85UBnD1*QDD%JQ zPd$L!m!}N=QS0x4KR|{9^9cU;g8K^QTI=TW`eDMmZwKE6Ztradf7U{A+d0#hn!?P0 z+pzeDfP+sDjDCxBb^b|(A??oz)`Cc@~IY%~=V=?X}f zd*37wn?({9B0-72hz^G~BaCZw z#~YVc4L(8C>^ZMC7B_hZ!431nGXPS0+n z*<1$HEt!}y799EMev9l|3XSO=nXuxjwp}J>(F=i8DDU*5$CCqW&iOEId|}gNL5-ZN zVdCMQJGGUt0bZYL8TQ{mnW2`3N_WmFjcw~&@5`MBuLUh^R4ov zE<&qFQ=<_r>~=4QuvR^-B9z&SBxOU%fi(+Zb#UIfMpJ}3&dCBl5<<}t?UFX~93d{J8{16j4= z84(Qzj`Fa^f_531^sG07cd`3{VD)ya?lq8m;J7|}fE z$xbzi$zHZ>U~7^x&k7!$ZtRt>-P2^9Tdsk7Irn^Lv>8g86Tl%YF>GCCv4hJ(xq7TQTp!EMd-K%9stz{g{U^ zAHh6=c@*HBfyq%hZG4q#H4Ma(j$hWUq>AIJPG<`*%)j`=;z zG-VpZycZ*9JBt=(EX-OcZoT~AO~>WvIg`;hq|{L;AwE>T``CIgd1+UNOjHw~Jf$kV zR!Ia3(OZ*Ba^_RCOu{iJTGnFji(N7EX&27ItU#AW3f{N`GraII2_{S9b3vI!y9JeL zxl>TGRlX<}iI_&uT{P)QF;qfE23hUFI1@3KG~_C%nG+3P!7AP$nb5(DHm1N+Xpsml zA8Qy~*~!wlgc)%Yzas2Dk@aqlw2W8hqUyw~1H&);l@b0id9w_3R|j@B8Mf9KlFfeL zX|DIA5!{NMBm~G%CynftFc5_ZIF!|jcRsvLo`^4U8~#*$dp#NmCvH|&Q8dJknc4dQ z#ZLMpJ05cHKH(BoKhlHg0e|PFkw;-d7lhDe~X_C zL~_gDO6PHJEr;e)y9KCYnw*=p?eVzz1h_9m z+$A0NyY3hJQbU;SPjE*V^TZQo+l4d4j117;R={3 zjKe+3_Y;_pL~u{@{XFKW2yP2$UyDiR0-{!|la>67wQB>Sq|4TQ;T5^?phF%0F@KJ3L}E z16W6!#vtz3VF)`SSDUJ<_Bx$)pR(>Qz5D)kU+NJ|mO5~_C$N7xfqM@7ix&6Dzv)XA zG2erc?_a|lOPDJ52QkjQ{+oTNBba%NeE%5ciG&%${=Z?IyUUN~yWgPvoF#-0?2P}m z1V4)((_h$~!Y|_?r9V1X+fUs6AS3_lK4h%u_51(2`xpO|z3Q)-esIm7a*w2MVDwYm zIlGjJkG~@GFqTPA%V^r|cPV!hZY$u;nD4RCeD?dFe)!YB_mRPYW^pT;D10Q<(7eD*^z(Y6u z<=t1NT|T`>p8iLt51mhYPtKiN|J6^Wy%Rrt_PH}(OP_r37dGDZb8i@5__P1``_H}Q zw(%eN>g=}PdEvhCzk1KtexrZiFN}ZYqyPS5dgD*VU--nAZq5E#UuyOFzElnKTbR2s zyTJYKH~Uh5iK)EMmzwxSU+M>dAI6B?8Nqim;y3Dc(b}Wi29^j~Ljvp@+yY@z?xeX0Jx zp&noAOF1`5|F8eNFZJ_Stsea_QSi(eFPXMUxf^(^SpJN zbWuWWb*z~SwO#P?3qFk1>+8Q_%N1L<^<5EsTyez!m@D)bd>HH2?RdW8GAx%%C_(NJ zjQP2b0f*RbK5R;)eTm;?+qYlVkJ-L`+hyA?+qyku_H4i{+jSBX+rakiTL56phx)MY zFoL+_m45^3j_;N8Z$*`q@nwmqsV}+t-Hiy~<#0cL zL-;MY){Vw~@um=8*dKnoa7h?V|LuwN|D5y$w~xF@xYt_vm3Q{1ev$M)z9)2(^naW> z``$?UU$Av3_{5MflpGVTOZBJr-^v(<`7z8v%%6<)r+xzSE0`nc{?t_`p)257jM$wK zd^aP0qi$o?9>sr)w2lzRD(2gmJ)~EZwE6xT`Fao|@E5I-??0NLOa)`U8Tl66M`-!5DdM$`ZEMEbu@dV=f2NVxxG(|;`6pZa0a|K9h7Zj$~7sHfAB^dGi$DELd! z&Q}`!ssCI(sY+w1+QpT~R+^EOEv_!Iaa#|W%gBj4YDp+EJ7A28-8Bj19Xj@UoO_s?$_e~$q_ zXTNvcgWSX>j7y^z{0ZX8e|MOlUVg>x;@^+^J@Su?{muV4#Bcfj@cUBnN&2ga^s^TC z!$1k&uyE~rp&Qcw!2QsW#Yy^aq@La$Nk47tQ1F+cotIwfyYgDNiFa)~<>i3b_r3E7 z@`Bs`e5?0;ecK-D^FG)21sIU~w{82)ZQjSWZTsXl?{~Is`_N_HpKROq7uzJjTT#g6 z6@IVpBLm*Q>VNIG`n~_q{~EqOK49Xz>85R8+~Uo#%kz_cNB*xZ-XDtogFo*p|LGR* zzlaKi|K9(xzHe^v{@Ip!OlU9(e?Yp0FT@lKW}{P5BG7msc+k__j#Z0 zyMe3U{jYnpUt$Veel6)TIQ35n^Mn1b`GKw8XZx>vq2K$@{iA$;Vc>1w9`L?7u$S-8 zZMh@J*K2l?*2nv{eX7s5n4@qL|l1DO$7SosayvoPcJ-OD|i$A6yHs;Ko) zHy`+w>(NsNR2Fs10AE-85>7U;zJ=TW-ofn*xchc_DcKK9hLiKSC%d>kgxk({b`JL# zZf9`&-gultl9wkjPviD~$KB3~+jAJv>nC@Bl6jH3{&E+$>u?j@dY!@@!|i$8-qIn? ztb}`%`8MHp9rhY-qFZn-?sgw&Pu%H?p6K!G=KeVDqBF0PyOi}Q++W09?n`XB_uE{A z*Y-LoZqMU(_69F?y|`h#NLy})0`JF7?n))y-i6zTaFY$cq}xf{p6L?jUATGg_EKLW z3z2ZzUK_Y&(bM;^xIGx;vnKic5N@L9F+o=g;`TUhqL1-Dz9Vs}+m~^BWEh=llyl3k z1aT@2d>yx`gI?+)aLY4+o7Rg|!xs;GDY+jOiPM+#gTK{X{%7;2#73=>)z2-uw<5id0YR_wE4de z-2q1LWvBdHnWPaLkIV;WzspPAPkg3b7PP%a!9O>O&QcO#B}KKX}qh!C2XNOgnxC{7LY~1N@N2FY|%>MeF%F@b}_hc@u5N zlj{FF;J*m|LJ*I^UxS~~G0O);+I=tIGvJeSJ1&0g&!lVeb5|SQ#NTYgn{qwa1^;Ll z{Ab(nCf%>J;Z3^Fx8Y4aZ_!Mf0z~WWx;DIt|4weU`=8D2~A7+gLOy*KMwxu#QS|f6Yoh+Xh43w_*vt_=Ft{R!i{1U-~m`x zn*7_$irX2C`)QC!xHj62xCuY&e#vl;;ZPg5bNOrHylxkM_N3(HITs-?8D|%MR{0^B z+ubi2u8nrpgW;`(pLM@TI9-njKkI%Gx0Bu4H|DqN81l;LyHorRIwa5*>u*gbF3L!m zm51*_C)#cj=9SWAhx9bgF6n98bfHUiyA)k^NKebxi!NW~^7X1u|9=#HN&osERgR#q zO9GLxrAs@Vybf<&+DVsnlGn#2F8hnn;*hv~**O3sZd$Kj@8KqE1NV!B(>UAaKJ{St z$~uSB^d!Dlk@f@HcopmP5y`&Pd6znU%DF!!g|WX#{V1RDO6f<^)%j#t z_`FN^F7S^!_jk0r-;4W;&i$r#_mAK{bIMDdk@%0cyMGqE`$fv7>A%u)Nw`rLDKHXm z(1y-A>DHxRXt*x@!oQBl9&-`K)6@2q{JhHjLi6MIp#9MvZf82Xos@hwd$=jF*>Wc9 zt!>S$9iZ;!l=CxP!it;x{tmRIFL~)U_J~`Tu}8yo;hog&IVqt1 zMQB;wyw3HaZm%*=uW{Bor>FD(gSd5~V=24rQM+HV3~l>$rtLMoXFG?}^uE*CO~bu{ zJ!*}!%O175we8nM^4VpNTEjisc`Q09_3{e#sB04L#m;f+SS|Z??iZ=+&r5a5m~yDI z`%}(6+u2?F;*~byJB^#tSBEUZQ<1CcH!^8WlS0vOjoI++M-hr0xC+#wJbg z74Q-o?o}R}wEw-zyoAzxH(o-4c3TS_kx>o*5>buJxo7S7(W6mD!>~>P( z?6NlNx>qXibsmtsNZYd)FLB84??Ag~J^XFj#gwFdjO)@an%<@OwoYv=b@mFzMoq5^ z-&T`2U%}X@adsIS&q|!n_Mn|EW21)avd%gwblyc4=n*#_iCl#HMf!m$e-F0@ySPc3 zpX}`Rh>)?A^U2Qcx^5D=i2s+p_koM5%K!iG%%Fl!g-K;eHJT(96_o|m6vK#$Wk!ZY zhDH#4+<6{n)mGL_D5ceeDtMx}FQXnzig&&JTQErI@RM`*cA;wn$Lw!iN2 z(Dyd%_#4jek6#GY^GE{G*N<740#8u>sWeL4&%@sZ(60V|sO^X9`y>sr|J#nv^BGJc zMs%FNsr=r7Ebs)yrAYEk<|RYNYR<60=v%5Q`ITjlo;m0=*rpzu`M4fgPr zY)8OT=Xk386w!Yo?SUYJ;;Hi5AnmTh+uJ>I_s*og$nzu9uJTOUZs6&fJ}LLW(^Y1W zc9kzZD0k)0pxl+rpxl*A+HT+pj_2W(gGb#%?7qjY-biyp$GFP<n6YC{7@5J|pNfmY-k*|%+xu$|6J9i9q0zc3L5-8r zTXbKKrH7GqdnZb{)z^5QF#eW?k=2KhZ4D!93nT0HPLy)1$1}d``%*!&v@kMP7+HB3 z+2YVL)z7aBEmP&bC5&uW7+GX*y<9_;?a(kXM;O_}FtV~RvPEHJwP9qN!^m30$Rhd} zr`;AtW)CCF3L`5GBdZQ0TOCH$6h^iqj4b$rYpO~I)$7o`N%99pjWjMmUHmFE$C1F7%cuiHY)GNc^sp=Bz(tk5#$uQaqw`Kt~iTOCHmS3EnO zpfXh9?FcPX;c4>HrT+=?r)05VWXYjrD!k0lGNrR9jBG&|*~-u|72d|sG8JA+7}>!v zvVqn>u5_vsD!k#LWh%Uk&@$z(Ahb;Rs|qbs{+5T9DSr*2Wy;_7&@$z3e`uNV7b72v z@jt{@>RFV04d))NMMd#cVK#kHHN*Z+T6yXmFgz1{X;?WW412WvNnv_E-{Qop3) zY0xhz*-=0HIeKaTkM_w%?RJMMUHxCz{>5N_vgkk1C#$kGxUZt>U=QxAsQm1~ewvDl z!G4;Gi@|w|%9kGW$tpZ4fuq#MTvC1pZA|5vK^s%?T&-6X^*^Y-C|Oe&nbb3*I%rVO zR9t#6_N#j;2K%-hb322(5h@)$y&KUK<_uD@<|vh~%C{bruS4pEl&?`a8I-RIuLu1| zMwos?#pQp=zI>6yQ=TJPezN|^Qd;$YL2XG@KarP(mbV4=Iz)T~f@H<&{xojvUjdeB}}ct^3lsPGKhi;@}K4N@|L_M&74?M2CsaC=cYk8pcY zIt|*3l1Y0pns@YI|G**bp$BKbDlSKO|3Jm%2%r6`_V+_)zp6vvU(nn_rLPD32g;wp z{((BrFgW}5NH;HY8Lx_j9;2Z6D7lnXLuk28{C4{urgD3%nkOCQeoy6tLBFTU#Gv0( zb>Im1dn!CF%s48!eU!$7aQUKS2Kl07M>t=UPJ?_=vY*BSsTtk-1%vsM%Cm6ef#~|F zo^{X9{}=VlXbkPayhHUbEus4tRVNJQ9m?PTl6ks{=MT+0r2fhiG%hKBJ(zc>v>VJj zl+57HnF`Nn-XUY4!JV^ODIOUE4ZahSA+qIR?ua#nmZ`WN;qQc~G#Y#-M1^PYoe(86 z`cBAUt*5MgTruQB0th^+tl>-kqy?BzKfhyM;xdpOR=9@WSE^O-cytTb|1I5#UBmRh z6Vh$o;dj5Fn|uA6&C9#-UFsX!>$~yw_2$-Y{32DigdMJbPg`mH-d+>$ycxZ>HxYlK zezQi>S#2Pbd4y3Pw;I_&!c*_&{jBr5d9u%xFiz|CU1(`rJ3tz;#jHUhW_9@U1m0;x z95(%4;(8KpRNaY?26gD2x9u64b5ICb7QFq))VCWj2R`5+^-e@*Ld8YWKL=T;xJdfF$kaEpAL~fJYOgYn+KlXV3GayxS&_t3o^bU-cM*uE z*be23kxcR>@aX9io9?e${Z|fj*%6*!s(wN8CGd2O%m0@7<>B>14%O}x0*Qh8vrh5T zLhz0BE*h^nlf}QP=8nVa9|G#T=Ak_x5Pf3yM@s6}|B`y3+Q1ItW7Ovu)B|+}WibEi z7+dTHb1UhSvO>!`{Fa55tN1PoBU2Lw^vlyV&o_th*BV;pkg}5J|EK*xNBQfi?38C} zUh;o5?J8dk>b{a0)O{uUp>sW>wq|ffp>!U_Jy(a+d4si&ic1gHK57rmV2#}(P495p z*{)S){WsU7Qg)e#cyH013x$11rqUt(?C^=2Q~LWLnM#L@w+;iDjJIQvh59YC)yN8v z4e6{?wHKL(R3lTrjf6Qkp3={*L?%~!yT(Q8+B#&%hmc8KYeE(sLZ<54Q~d6)$X@E0 zzo_)ddDu4mrHAk*blHsbj?@eRsr6_+1+w`*gz=A0<;e4}%|$U58R^8c>ZyPajSzaMyl z(x=Ly2kUI*&tRRcWIb7DOTNfDdm?E#8FNs+D4la;&f|Z&rlBYM`$luDPGR`hcnL7q z6ED@K)Z9y7v!w+bLsgvE7LUO!xzW!TL-R988>ih*bj-j2L1@(6wYHqk3dkf+A z@4{b?-GO@vE7<*3?14uQSC8ke028Y7iR&thRr?G|m$d1~9RC_9h(8>@Ed+lo z{J;|&Zmt2p+<-50r)2a`k$9?b_54{4-wXeo4!)i)Y15nGtG*{Fp4;JXhu`%#{@URO zp5S;|yS5L1xeqnq+YR`c2K;Vq+OL0(f%~Q1_&DmfVY2~$hXMbf0l!w z-uj>5d`k<#Kb*0$lP;VrRbIKBQj^Ji2?GfB5}kVn@H&S&u{UyOrOuI$!$5z@vw& z^Sk$pI=_3rsPnt`i#lKW#lRD+U;4$s6U>)>G4SYon~J~mi-9MY|KHFr8r93?3;e&4 z9Mu0OkjNeI)&8F1Cu-7G38O1l|SDN#q4i$R&N_^Yk-%gBO2s*jQW)s9T+t1AC4=_uN(Id7A&{?@q5XPUu`J?jJt*;1* zr@^{N`8yaUJcBj3@@H_)tz-ska3$+DhYE^k4}Mof=`>guDVf2#NXhnhoj(P|rP~}T zNM^7uQaTOJAC=7D{87o~be)6g;ixC|M7_d0{w58&2Q1iG0z!b(b3RWo$VJ z|5e(n&aXDdz)J(`&owzmb>ScW98F*AEh8C9)1$j@@5Xni@(s6kEjZugoQyxc+z;!)7NrM@^q@TH$|!4KZkF^XRU z?uK;Hn}9v==tJQ7vAlK3sY(Bz!mh2O0{`}asBeu2lIwVI4k@`PJ+ z#9m|yc@IP8#|Z)1_Z{g45M~T+zor8CM$6BjM}u(c>xoLwhpypE;_|FH-T}-c7$gez$ky>w3D6E4q8x z6CHSYaC&w9vL{*!{{qTT4_9|Dd!j3^G&z4B6wkwH7oGCLpCRH;wF`&IITEvC>w$%B z7vfLqSt3*R3PqwvI=Ji33qPIZs3UI)X4r)vr5v1x}Fo=w%U?&0Zt2`~K_ zlk-%GpFbUkQwKJ`VD5T-=LC=0GCEpX?o^Bg+#u@XJ(Oc3`bV_Lj88frsjxN_*FKr#$Ot zj-n>qnBiIH9|wnb=v48Pd|8i7$}A`@9c^P9vg5kQjLNqaw<+SbOZ}htT=#a7hP%L{ zC&Rejti*q?Uc>Nl7md+k_Ya4Y?yMJ0`q>!%0~sd%q(00skYypO zMW)8B%tQGl{-m8)Uott1pb=S}WztTzBfCUoAUM3$SYuu`IlmY7#14NMqEp&Q;L-hw z?O4M(=JNH78Myc{WHv|;+Z9O|I;NttXWJXKzKozrJjCX&7# z0fo@6I%ORd@rqw(X=j}>PqGJOp3X8^N0lOzHlgd(I~NHrGjxBb%E(~fQ^|U|j*{g4 z$nxtLd&I9iUGwEXRepMCox)Rb`FF}Mgie*8!vAl{m*`hb&hvo{d^_+FW=8sX)xH&S2BbBd{vhWzG1Co2JbN|ogP)7dg*p8+aB!a ztMHESH>{P;BfOul(td=$VXfkMguh{}bQ*laTFH*^H>{OTgKt)VEj8>%j&Z7t zWIi2uy4KI5IQFZ!{5xa+I>s@HubzfOb1)g>0#DcU8H{l%E=PEbbI7>zzhw_R%owNA zZg6I;WJhs~Q{fq$Su2^rnYEG~;W19>G&r+XvN=-a{7=_<)`K%^rPJWdTFDH~td*<> zW1RAL6vsFfp23;5>IV(RI3+VUvsSYICBM_4;$rYS4Jz$N@pl?jTnxrI6_*~2aZ2ZZ z!S6JvcpCgpgOVNL-)T@f4SuIV$qas{LCKEr?=&c#J^7sm86OOOr$N=1qR2o`7Z`8F zuI~jc2qRk=Mz%4uOr@bEjO<`&nTqE?e%Bzqf%_oDuIs#Dc$nWj$OtV{aVZEbQ{h#G zmMMSBL(7!EhA^`2VPyNm$YMhOu7L_KF^p_%XqiewUTB%pIVX(F8%DN1v`mG!4Ouni zHzY*)wTJen;u0PDw+oa^YU+=iC#$#^&68u%C-ct06EyaFWa=qxsVpFb2FaD)MPX#M zp=Bx^n?uW#&eqT}hs34ZS+I)G;hoV0)CQ$N#l;|RR9p=5M)?c3|0`kr$Z`r77bWXy zTnzT2Rr+KvI`DMOm!^OK+EunAv`p!gz39Nx)t|w7#vx^Eu%1ymkMMd%<>&v=^^D5T z9_-nvJo`Voo>6&rgx51lr@@|`%4>u5jFKJUJv*h-U_GN`Jy_2ue?3^wsC?lvr}>D!Fopd>%n?PrLU)Zc0KsrITfD4dPb$;2(M?9PJ{J~k{PUL zlF6=&rOxi z9?VS*@56LTFZToG4uw2j?`G><{~Y=#x;yxq$@yF6;`()##E$!b+cuh#FA{mYwER<6>V zQl_!!6S~W*(~LD{Wv|+<+ZQY|VK-?7`*i!dFLYY;jJPvt@#}Q=34T4ve!7+SNkwmB zx=u51(&^H%I&JXlS>Sg+e7f*WT9!ZjG{rY*8GgEpJG&y!_1h&at1r^v$m7#Inr{UJ z>hbwBAJ8FOp5pDlhl4JeQ zWXDpl5;TEzLy{dab!KOLrpdYfOU=0*6nq7}p8K94K``Fr9N4Bg#hpNcU3wku{#ujM zn_+UcgLLeRi<2CyK?B$VT0mq;k|PmJ1XaKb0?|%CLk~Zh@QmUtZdI{#`lr{ufS-Uq zXh$6g@bqjlb>pkDXfb!<2kC>anqfeVqM~c~Y1|11v4ECzcm&JsLUyZ%D19~$~T>a z4)9YM%f&9=eiM44pUU@Y#V&Jvq4Mo5p)wZ{D*c*J>Dz?Ly=9?tms;rQerog6!G1c# zPtWkvp?(_Yr)T=~sm!Uwy}Vy0G}%ut^;3EGNBEcfsZ3DBeubaP+)nH=sEy4|a{PqK^Ixk*is-h8#Ipg;MS3RL7%|~ann)iBS4j^NWZJ9o&l0IrE z=7GBi^Cq1q_64Bb@1`dq{Mqg)HcZt zEhx<|DsbBhr`RsIB)r$0++5;Q(&6`lOKg*FFLjsLatiXNPCpcI$VeC6(wvfUezGGG zY>7*Dw4RsjC@IR%R>`1XRwI}4iJ7QV8JGT@r~bwy$7YamRkEXP3~M;32P^heD;D%r8vlI(CKCOb;|GA9Pn{gNHEYiMxn&`}8_h2nEr{vZW+vJ(W#qQ~)1-ILZXHK7vLmB4P6XARGL#cWp=7THRRbEcO}%P%R(FPyI42zl-#iyUi&d~S)G`7_&yYcI3qPtPy4O)hko z*-9qoO|!X+iwlbf_tiS&lZ)Ls>~og5r{xso$=+$e#j$;@)?-aPeIqPpi0sDoRsZ_- zm5sSbi^X!>v608hNtXX1t@0?{;|c@GC@o~ilcY#65|MniQVUD+ZBu4WpIj0mCKAo= z(a}|F(_|C0G=CZym_500`jq^s*(L7M?4pw5oN3vUCBuxIsGU>46V4T@HCHL{fH|NF zECAJD5m*e0ODE(0*6hheGqa}@yJuvV7G@_;(}Yz}pturrZvJigx$fcsTRfE%6wb^r?H2nm1Ix8a9Va@QAv=CX(hK$5B8zkb>9RjDhu+byR%F3 zf9ckAc3zIo_d5z9ojIMzyE}R4#$XS6=CojyB{NHk+|zS|0&!2znN$$$BsafAaSGhI zld~lnk{eTUa^2ZQIh2MrZQ4x5E|QIK$-CRc(7{$VVJmqDd**a1Vs^26Dz&_W8N}+? z1kd(w)k|3v73AbkFLjrZ<2kpvwUXOQs3PuS5lN(S3UZ34Wf!@N^9yq|8kgwED=eYf z6cn_n&7@@}Cp$KZy~|T}F=1T7-4Q!7+UDvc!oysPo=hOlW3cbSO%`qwkuN8# zR>GQ8csnOnw3AXj4h8Te4#_~`kT!}v^^rduhs9}n9BiXI$Dx&QHUkMG5Qo*+B@ROg zL*g(sm$RGrxPqBysly$;xw9K=ld`kr)4>$x>Zd$(o9EhQPA{2RR8&~Z;f);39P&t4 zMEx!*oL++K;=*aRT=#AHlijvidG6`-s<%sLOeaN(N3r0O+Ih3 z7N1|3t)hIz6}Ia$#$=Bgn|ghE_O+O<&m4c2t-Rc3>>>>pKO)d+W%-loTk;7tI47nb z%85{EbLaX~S5nI0lpQ$0vfC2NE=W{QxF`fStlZ-K+uX&39?)@4;3Um{MUb{@Czs|F z*hb0GT&H-Zxh1P9)oZfGjL_u?wn;NfZT^w5^!6gREx*Jzy|C1#baX55+<*q9+$JTF zVB_G9W{t(oSwkr&gmlC+^=c&*pu~;RDM}#jC4itB6<6XvFucqrT{^>Lb}31TE7PcI zC1>%=TFRQ3T-H~cl3(Dy%r+#hWQa}rYg=4yUm5K#qaOElmleseAl;j?Y9p`D$R0U< z{I%n=N2HG&akc96WO$KC(q$Ip=juJAzfX*pZZ$ub#7NdA*e;-2bg7E;#pnAwUrIpr zv$iBnEI2PuJ2d_kPMK0-JI5vy1RF8E{@M}#Zf4}T5#w*l$Q+rLot1fgcIwFMvz=qF z9dUK`HK|#L9b!ix7Z`ipxl|3p4^;z0MwzKoDU%W1mw$fMspSWC;`G&S`r+x5Z)e&l zGrgI`Ii+gu>z{JjuB7@VN&yWSn|7@&cT#>1U4qP^Y0PxA`BU=UxkI{lS<-y-W@Y=^ z_W3eooF9m-KTedFgib&zkZ!$w7Zt&?($bl7Fxgpauv|}zbd8e;IQ}f#EMh&G88Y#v z3&|Kkr=r;kr;})gI?b+%IoIZ&ZRK96MQS-ECGKMVaMYc9nN7QlE=aFmo$@lSBt9

~KLp+R@b!nIhY?oKhMu)AQirBj9{iaUnyd)UgDzTDovm z-wNsSr!e&m?P*dW_b5hOc#SP*I{o^EBS=v(oje6vl3-(vqvW|cr8&w${`8X4;+aZp zQ@wo-nNi{{P{Trk?e@Z%wvxQUnFYDz6vx531he~)T2U$t@g6!#`O{VZYLlK+T>o%J zsew_srwhMKy8nVQ6?+*?Boq8R#*TPme3lxa{P#Uw zo$|?+Tj(y4m7*-CX4z!m(0ih5uD@xVYUiV~CyYxSJ7)B_k!gMD_!&Dw*ZyhKq{8dV z5^7?okfo$LN~j}bed+joxwlaS`TJ!0);r_X-J`2=>BPny= zE&e#QTyccsguabH!U)W-19SX{EA=?ZR)WYgx!CD)-fTa36l{)+(L7PD(WH09Gu zm}ApfdjokFX^vcuetk^zpT^jBj!E1zMw3g#KlXV&D*8`Rww+Old!jVCe4K7+^EhmO zv)Gb{J1$CeykqfP)IV`ZqU~=3qHWr~(mx{ods#aF=gO64O=}*by%QDv;TYTJV-mj^ zty#cS^|L^$UI^gwv)QuiLe;P3IH~&uf z?++ODhkxhZ*#`q&zwh4(|D6H%obzw`KkMJ|-{XweJvve~t4(ViFmj1SlXn7s>~qOr zO*?L&#qN66V!sjk3qZ#r?*YBK!}rG&=*M6m_%aKAdw z_x`Fm^VWy0?RRTVMejO`{ddrajOLU-LH_~bxl0=Jg67P7QF9)^em-sn zoCY6WH98jYPTWJ-8{uz;E{C@gECmgq9@K&+u(?Td?t-?0i9aWN`n7E>R@ZiL`mdW) zP6e^R^@7E2>!Uer_nVvzyd&4PNprg1)|?vVT!+;a0pwlGTE+s+tYrvnn&#ZLF2Zip zEcOM&-+P9|z6$gkD(4DTm+cnbYq?+DFDAc^t)xjJS~>* zXgFHQx7brOM?7d4s5xRz#!Os>Zq}R&pzBEcx_@d;zK`L^K$ZnR_bqrIYtE&_F)fZf zN51`!nsewMG-m>7`Y6s~pL&+Xek&+?Npmg+ZFeU%w2=Sh@Td!p`=Cp}6M!=OZVUe6 zv+8Wc-v6SX`uFbi@hHB+V=Z0Q#Dr>m&vPvHM9SoX1dBbLIAwsXAQt}- z?Di5{auSa6FL#ZzGty-f6`*_1D%Hb0_a5>qhC&Y zkT$?Q{}!R39n`oj_QlA*g(i=0PKgJa$KpzSs5vD8)Pi;3m0wxxLn$+!hHW=Ar6^sB^fXgqw z#bO`PVzGaM{^}a;t81rm_xKw``+OHJByPw&&?fR?DB*0u%~o(ckNLM2``bG#_RFE; zz^UMF@S6`U_9r7O_S*sR^=NHAkMB6`Zs9o!n^UrXX|aF#k;VRL8GRY%5B_YiKT=3t zHtqLqg-qaypK3lCoG2tk{{5yz2AyCZ4^t6F#%p-+e+4t1sqrz-3Fx z3+OKTzkmI*Ipv9>=9J6spuS>{v2j+0Jp=Q>i!|3}%!{ij-#MCVBXALh&v!TJ|H|h( z9pd}m=cv|P+u)aiSdepjbINHmno~|ew{4f^bPOBKImIbCxnKGp% zqd8>-HLIb{R*5@g@moDxBKKLgFe-CNKP!8pv902g&^9c6vo-|63eXR*%!?*Pq9 zUHY5FJ_Y(b)Ulj8g!x7A1&FJ$*nb9=f#t|wh8_Sp%PjVV;6rfwV;1|bkxhcmf>uIb z0@;|$p5#5>r#OFlg0rf}lN@Q!@?InMa%kHM&ahS`Ib6{Ar+F6yp4_QFh`%?1MqCc; zwAf>yP0)*>gNc6*bO9KRo2Af~LBtB`5lDjf0+iXZ{bT4c&~Kri?6lbHz@?8{?2kgz z;oSu-0OLV2hyyc__l3Sqoow4df0}A_Ev3I*2X=siAo4`bG5jRHH~@7(6C74oBFMmP zJaiy+H5RZ_=xPC8#$K0|ew+Fu?~=dB9H1VwGA@088}CrfqJDz2!N9GWbNTa0jvFvv znMoQpTkPe~Ip9t3$y*ltd(hJ+SnPkmybts7n4iRaD)d2U0@MRdf}Rbvf^X52g8d=z z8Mx#I>H+*s@YjJWvEK;l!QO6!2YL(H#<)f zGwut3HkC0il5cv@#|;N}AE_U_Ti-j&V&C~T`3&8PpKYK8)Pi+j1w2by%4gOKqoYJe9cFI`NKBGD1Q}7O0iHzRb5yQ z(7oVn;-SS@2L24*eV9i<$7;+m8>}t|NC%G)#y#*qglgEwf-H~$GJ%hJPCvWf=WF!+ zj?r6Ym-lZd{N88c`xF+R@4ag#MdP4COEkMqC4Nt$D-oJG+G2keEPItc0{W|QlvyKf z1o}aP#l8m&KmMhs%5GTm(#i0y2i9vCbKpNYhPe-ZHe>FePFsfmJ$iOvF2ZcTioOfk z6zKEVzd}a0pnZY41@jWz)gk{58gVu42XiX)7U(abGoTMb)1l8nlcAqN6QDPYrQZWj zVEzPpGW0!kR%JA&Y~-E2q12HW$~*di**Op@@48;g_7WixUB6&*LdRab71GYD{1h`s#(`E#${r6fqKS3&Ii=D zS?uKdV$#!!JQDLF%>RR5?IYG;e7C0z3}X#@;yUUORNgnWF(1ApRf|hDo!j@+Hch*P zxmg3Z(=3%<+a!}C@iE(m2wO{OMn>r$>W_WLcCc~q!L^TBYHSBr9I#HUx4v`w!NyoP z5p%!wX){heXpL&HX;s7cmpqk!>9hD3KaYP)gtvH@_0-zGn6@mjb#SJZe;3`s5ig6C z>l`uVR9ElOmh^AYo$D;?UE)>TES~51mq{!$#4@8{N&o6aseZRQtNgFZ?ZP)&pxgFU zf8(frFtz0`(T^;t{vQ>Ced2RgzmL32`n&#Os(vVym|0I1PqVxq%@*NQ+Zxk5tp~O& ziT3KTkSM-*(ut324}5lDan!=7ldC6ql*77~1J+YAR?JRZWvV^odZ}B4v-(X~_Dn-Y zMy7X3bcU`+GG_7Ax~+I>SUo$VlP7E61@?Zcz1~IQ=Ha!gHNV2&r@~nB@a0RZ7p6`* zIo2Ar4#Gl{w~$*AKKrYKyO{8jPETQ%}^@Z$Q24@!5{9>M!Z{xL^Gfht#9{ z3Gvp)dP>VGlRv$E6z7K9ebD*C_;;z~z!-`CS@T@8W0s_jZ;Y;6e!%tn)CDVHRt`IH zZDUO3t=gJi6<&!_e6KS%9aFwvJJF$4)!3?{ZSje!p5SXM%tk$(&ZJGCXao_nWel5zhbcgrs3eS-Kw)j-#W`^g$vS%c2RimR< zneMIfR7f7pA6+r~fb|$mi_@)Eiu(bTbLqkuZSChz+Gr&&|JrZ$OKsYUW;|zG)5pEv zcSYX?t5#mH;1_kN2hO#)S4CB%9JqJZ+^>DaX^nYBn>B|SXWy#cYs^)VcbduJbNk+K zcEp02RVV$d&ye_mo1IyGs(Qu8Z?LTC)ne8*^xbY_pDFF2SsO}UtiGi+n?3}y%rhIR z=p(TwU`_(7Fuw}YFkcIv#QX}l8S@md67vQy1M{6=+ZlYX>@l-53+jbVTyAz&0WVky z)&rS)#;}(aOPIapHm8`NrSq5*q9-2n2T)7DgxdAcMNcyaht`66khYrnJ6I3)gW+o! zBf)CW3Wnm|1!6TVvWoaP&>smN#hi}+3{VO-Kgif{4*PMKBS8YF#a>VU+yHifgapmG z27j-Bw}Bl!vS0HVX72@>Gg<6Z=v~+sovAs8W8Z^W8%7>r{vPvo_z9T%n3)3()|~N} zkHg%Kc_`+Am_0)@rw#K^%uSeMF`tV$nmoJ&Dtmd>UCf1vlkA5+bry3s;=6p3=CtDW zdfeO!%0V^!#h?=Nz2GtMdyqiBZiemvToksSe$PLz>n9XgB5j@oXzR;-JK)tMhwT;K z`G1MM#w6BTv1nPOfyfwW=HfR>S-dJo@c zLdRU(ik^p{b5@z1yRtNAP6-l{5tHE-RwIRu| z@smT}MJT1cYCQ4Kh&u8H_ugBmPcF^*B=tn& zVCu^}8Vm;KgG<2(FcwSzKL=C6G*Ale09D{Yung3K)MWN*Nq6!B`UCQYHNiodpDtn@ z9?6_65o&Mb`y36FYoX>Gd-(z1*e_p=(B63D^2OMTKql_WZe@Q5H&wWm{cqL|ACt#6 zC>xV^e_wwm{RZ_{yIpfmETi7cqW;{bIc1+*)*|dT-p#VhhaVSbA14v<=RiA_ z^)iriqyf;&K`!_ekhRD2&_98Xz%Fn+;hhdH1S7!&Fcp*n510e4xQMy|eE>WH9s_H@ z^WY`W2wdO|@Dcb7d$x|>UUYc=u!-ZS8jpa@>VGR^r7=3nB+ z9z)#$@}0v8(8cf`g?&9)Ldr5AIGr znL0&0CqN$to55a?ateF0;J08Su-cf63}Va#PLKg=h~GTuVo-(oGiW{ZeW;wFE@1t< z@&>-K1GTPWj=(i% z1m+4WnKRsc8hak13;H~CIeNC?b_=Kna&{``sB(T<&DhoYF@0zY``VzaHOa99e@lPH zoJ-cSHzzsX$NmO-{+(Ia_VTEaw#4 z@ZTcvpApJgVLEQ*4AD*-ku${oAoJ(U133efbHL9DuZlBGIp4kbbmkl2=Rn5MNzgmM z{h$T;V?u%VPWI}tuiMIA{-h+wF8ce(Oo@-?`Vx67aX8&ZUq$|v@h-|r`eS31~WhnIC(I8>mV1|WT+Ll)1fsW;!D2G#26fh>~-vWz$KV_521cw=9^~D zvoM$Pty0-5ACD{_do_3k4ByCn1KvA?^LOlR;2RKehCa8-hL(a1%E^U}a`NYP>>AGl z(2@9E4nH}Eymu!#hJ%5`FK`YMjk#$$eGrHyPvwkK&cla_o3tdyFNadcIYamS8vUe0 z@>b54Tc#yBvcN&^0W8DK5c>Y1XEOK4+yp)Z;Cv1ZSXUE%Y7mSMUWm2-X!59&SHFF7b+P)|>}1Z-=)Ib1q19B{`PT9@@M~j?9Pn zhUSCVpO^Wp@6~9^Th7{#Kbv|0uK?%a|U+Iak|& zomF!7{r2w;Xz|blfWEdJ4y$VmdKy3)dD4dcAh2VO;QYh^-Gw~{^L}Ux*bZ8OhTe8) zR&J6b4-WU{(L)(v{e0qI@w5j0tvX2bVz&;`o1EKZ>Qw)?dm^_gO9w=wVVrq(O?3o zBHr>XZ7+HcRF8khh4DvO| z=RgDJ{Bp)$h7JdD9Se5R=H#qj&iLi*zlr#i^R2oxun>Q*;r|2Z7UAPhtKtj}f7?JS zG6(J9yz#VyH>l6hc<4a(ZRNY-Z(WalGw0z@IUin*{|xfRg{2h#rb*OU*3^$cTi(_0 z56Jz1ChT%wU_0y9TI4H%7sxs84*E>_rg8)J`Vz(*XcoFA0y%To$~>-!@E2j;f?2+E zT#b1V>m+S5W8jPQZ|^a8!u&9>j%OVRy#n5^pfT8+(D@PO9C$ux8U5P2-K@6=cPp}O zU^|G#?Mb=Jc|Z=>0~%sO}>v=L}-i~U?M3CKMhx%*Jhcb%)zEq5Sdtn}^2Bs*-! za^De}2F(NeMK*;qY_OGdPJqgNiMyeixS0C>nGBwF@{Z{6a1Y?WqGZgM!OMjXg&qUiiO-j|0~E zS^{&}Mr50@&&SWRU>D|Ec)tb1^6?L?hu#5w6?!YQ*Dq-2q@^AtV;=;@!Rrg11>Hva zJ|nO9f=95w2@ZlGx3YFKMQYUtH0L##?*rxJV-xP)#B3oS*I~X0y5oKNKJsB8c^wO^ z;2?d*Hk-*Q-$3-novFD#J5lq@IZbPsda>59>0E8uH0Iy<%?AadgZy|5n$G;P3fRzj z0_Y2#hW{mU4fC6r&w(a`KVkkD{1MsR(0Fw2hi@bNgb&DPXgpZoO8px+*VNzDpH2Ke zTHx+XK`HfuacJQ6^wD5AZj-_CQN$a2209YZdF}5t?Q-aF?6aY<$n3b=MtQ9SV=eJ{q*JminT+XSz_hx}yjd?oZY@C4WbA}gr#;9U?|NnV5b_$h)`f_m^Z zh@H)R6O^HI`d{f!KV~k8eHK{H-GJY~TZ4HH^fTxwbEpfT8kiTM8~#SjcIa;CdG|1$ zVx9`Ud*s+re5`=0-ZpJByrIfBJo+ZE0-T9`2lSjO z?sF3VsnCVsT@W*$c^$lA&|AT;!T$iqOq25k_#a~)a4&lj;OF2m@HM#TKK3-guffaU zOK{2p^pW=Kp_9Q>U^Yc*@$hC~-r?mw5#L8I=g!y`#@E2zQ{U-)?N)vlYc^;M{p(r(L%je)z5G4^{E3*Wf!q&V1AQK}>>xjW%eeP<>M!}Y z2t55bGVmR^4gLjB5H_fac1BKuvUHNV(J%+Ii#c~2^QLXYe>+(8ciIm84}cf5)@E_F zKR`cUYjJr1d(f_E5Cg0r7TAD8@Hu7ug2`FlN?1Vq)7JItSJl;5kwf6(_p?a&?2iO?c22P_7W z;)e


m&vn7@UtY&1ESBa`1P8vZ5U@0Z^p0$20#0BKr-13cX`98P&21mvg;`JEg>U$<9 zU;6gR?|$TBUJB}ghsl-v21pudls(Jkgz3WlV(ujDg4X_v@`QKxQ|u)J`K^$LpqKvo zv*fBT=;r}n33oJoMI8lgZOl>dGdS{iZ7X#6m(0t+6ZokIxtLpUvjsGLjen57oB9Nr zk-r7r0e=GGUi_6IYi}oyf%G4m){;VVx_be0?|SyKd6UPnfVtXMFdXwi_Hzq>7jwiO z+5wmYmI9+N)*(yW$CwEu3zrUEF`j!^8^36FwnEtxueH?KpL@sGt`)56E@~TBT=B{b`9Xv_fZ*l(?urgN}3{1DlJjnN* z9h!(eR9fDJ1}bT}2VD)A{|*W;OPY?ErKd^aUVCqn;}YyQBAW`8^x5X=>3bA= zGx!d04wAyX>xPTV^mMXa;wx%0JGD(_XTy7DXB%c0vUv1JI(tJux}EU_+C<)6Vxx^= zmV4SU_whR%n7>0FLmO>)m~z`e7>ilkf*UYzY-er{4cx~*75+8gPOu7m1qLl)t_mtZ zA#QWGah~^q*?A7;{vZO}kL(Y?@(6A5GwKcWV`vq$0lFF-Yt^*-ps&E&1>}z9DUVWb z7!QUs7R*4FfxR581sT{shFX`Rhk3>&*yY_AxnI2q3>ccLMuLE7@y^bXZ+^pq2gNRvY^`xR-m|a*uuvG={O8dhj+~G{m=i zj*P*-q5ZJm<*i{IihV($n#26Aawuu6X72HY*_pPPe7m0bLr=;ik3bWA+3&p>ULtml zr|1jLKYqjd|FtBC+%?I6hkDw~P7ig#cltq}X{a`E?r6e&Rlm!Z$62#u zAM)dPSM>zGpL0BS#xOVF=5_D}SdTpT4qtpaeFzBL&6B%)azC&7D)wQ(>;~dIhQ0#b zG0f*1pmL5n_D1#!uS$08XeKSP?=JV^hC_v??aw*-#+WNZg<3my*29zclNc$cyFG)`ZqVcVT!vmqT-%?b#wPU8CfxB zU(G%Hiqo|fUs^C@7(Yt0u3AwZF{;hC^pT44eRX&5tGRQZ6Bl1tD(={KVY)VVFFRh^ z&a#M#(tTBto>dK%PrUs^{U&S+BefeoJWyAMRex`lO?$cjGLzNwvh6kVX_Y5w+N%DZm;1jq zPAmGrR$HIyS!HuyXRhpHsvMz_Yn5sIH&>3-DovKkQTkn?M(uyhRZ*8dur^YAEz-!Dq%Loq2IyWn)Su7X=%yza~?~M|+nI=~J0=T*ZfbUmMc9GAFv?gT0F@D|7l+yuWvC zW5WD9D*m+h$#>@82O-e;k5+8mduhMiQb}`Wke7uj=|<(e>Tip>J(KUtK`oGk$$f`}M8S^{w&iTdnJRO4qka z*LRPuuR@#g#NJ7bu?^g*>$Ab~W(|hQDOz-YoBLA>cMZuV%yFiObNjwogK5PdEVx+Q zTe+Wi@);G2_mXwX8m-87z8)-F^4S`*c#S!QjG&AvEyt1Vj*Wb~%lhsamMz=dYs_)q zTTX4;cE+ZI(p}(Yt(j|TJ6|+O)``8Ma__=;t)gP@-udy>PgXzR+3Q{6SsSG-i!v>Y zGOtb7mZh6&%J(izH^&|H#a`vUD1y6g)+l<4h3Tg9Z$|C+>zz@$x6-TC%-Bo&s~l~r z9Bq#K#<$EH<4%m|{f%;yqvaIrt?E4`-aI!&`&;rEC#GAc3^b3rSgXn1>)z|D>TO+B z*>v#vcvI{@b|yq@Y8OvalFhwGYE#nx>^?hUM$X=rQzWJg0cI&|T7HeehT;llW#>%l;oW0gQ*PXpLao)0py)@6f)IZleQdN1CgnX3>`6}~< z2>0j1CT=VKz*JP#|MIkX55Ha6OB+;0_cLm(@48d=&KR`U8gXGCZNG>^xHp|Z)d@EIS5 zg{jAS7T0>_dp%WyE1MjDuG!G5@+$L%S7~vd3>%bI>3!+)3G)^`Kp#j1Mr*wn`pUoc zK9%V8lzP3x2d$d>nNRw%@!FXa%)RgPUAKRa)m+tUVN+Xmwd>(!=1r6FHouqkn|WuM zN6q$GBj;PnBj@)Tm7r;Z|Fy^3t5ad@+!MYq;@wpTvmqnIi5LnZBgcUZp( zmEI@kJ=joXUg&)>p#KJ+HCc*$zWIR-dl+oUqRKJas0`mj_n0eQ421Apb!C%FSFh{V z71yrwtm(62Gn&y@WhNpIuiPY>RfhCV@mbU7TVf+eZK2K&UL{fQy~j8B2{MKxP@_CA zH)Oo*p}M}1oKW%GKwy%bwvObe8rvx;D_&Rm^m3#Qv}_KtPjeBIeFY|xO)(|X^l+A{q{#U47Y%1PSJ$A?wZ3RGWm=N`IicyS*NL%8BQ zpWZKFj{DxX)@v7obD+9sTv6ip?>^`Y_($vxxLc9pclQgwyA`3`#a-cdm*WrH{f>ma zb5Dq{-Iw{@-WWdYok@Ooq(AHx%@TIpze0q);zGaM%fp8qm*{tQVfe6D zoGb1=p%}{s?`@yoKOwSm+qlLv_pJ4PGT&r9uKfG*?}}dTuf~U+Cs^uidz5j-7)#CR zd#q1e-?DDEzAOXELt4$CJz{9l>Q2!exkp=O4BWG(4_tSZHRq%~C%zQ1rZ=_~1*VFK zJv9UN%yaTWJh-`oeaii7QqefQM##q9>=_o7pj z#uX1)>;Bfx9q(A>*geTK!@Q^H2^j)cR9JJgJvXcxQukT=yI$=z?@O-7)zIiN&G@ce zcjLa>nscE2hEw8ZY(vS0K7KVje`c!K(q6Nry(tpfu(`US$+OmLlGw~2R=&UH?e@yl zgv!)&D^t&VtucWXg~UB?m^Ct(Z5^bCvGbl`HLtc8EAKlO`074wr%>^*^I}Wv0&b}{ z##H#)8Ir9lD|32dt9-1rGAB|T)C@>aSJxX8EA}cEdGqU*H6|ch@!o)ndF|GIuf=oy zUK6)_2FQhXF|Mc|Q1?c=UOwkrthZRd75M`e>!8@anBtV_6meJ$j~TOw@3+*wqWf_t zSiaiO-ngN?ZbN&`hW6V{*3+!VRD2-efAw;EjKlPfVY?f;kuZqOl=c{Mh8<(}$J>6dO zwDNW#wqPJ zzrc-NAN%_2<2382$v&<3=RUnYUTLbhuDvF=vnqQ($^Cmp)u>UvimTfjuWzrJ7*Msd zm#%7Oo^|d`zPazK`7%{z#Txp&q0$+BeUiV=YiDt`u-Q~yJCvDKwI`z5TUuS!|D^n0 z3%!o&D%-GML?lE(E1RO8#algdS*m$qYD8sf zZ_naV@5-4T&&+e`mR)VJmM^@zSLM~cAFU~Fj2>@3-jU;~7$aG4Ex)u+{z>`6);2~h zYmBc*6W){)7!BfhO(SytjSIcsamqgbvC7fMSD82TscQ1i@{uJ~-WWMb)~FqEai902 z<1)#7e8sRpM8=#nX4s=Nr}&B?Djp}2>nr|2JP2JP6DkHQSefJ2e75^F@3CvWeODA} zbusNVG3_hPwlsdWyYBe*n&aDdetxoAM>J{`8+MOxw9C9Za`5}Rq4RsGdggA`Hm|a- zlIk?uBJX7>Zrt!;C*J#goz{Ne485<6vwWhpm+wF49qZV&Ue_9PWh#G`O3CnE($~_`mPmU;db>Y7u>bG z?w`ARs|oR%2;sN$;)wFQ0>AR3xYme?f4gcnE6~a}Tc{=ToRJ`I+Et|}m zziT_wvT47sZtHHn9bI7Ad~ao+<7TxUTh(V*q@LElXmgL(s**fa?h~87uW8=BL1Mk) zWXoKW#(QYJNqt@O?q!VwCFUnuHuTYrJBL^{^sUL<4R_}!W}O#zz&z?7KBaZ%XLNhH z;-%1{XVy37Q7e7AyA}J*dPMh|D<(>|FYd*^%6M(w$x#(I?WWF+V&6fJ-N=)9pKiwW zyRUmv999m~GFHfoXO%g9SYe6&Q?0A7N_}j1-6OkIR&o2eF>iOxlHE*V5XZfFG9JWm zp7px;-D`SbTruCg{S*l`u;Mb$Eti$561wj*GsR84fA^V-&6}oab-&u}ST6oo4Dp?K zZ^WB5*76NfB60CPwRYQiq2-Fcd+$BHB4KykoZU}G>N@^twyu^JesJjii@Em=npStG zKkO|sXU6_Zzuvf0eJ8%r2fYiFUV>42-RFwlUreYNgwiQjT~uM)T^_Y0vS#}3ic@#< z+FInoQ?#P_{U52SuJXn%S@_{4kI-4Pdlsiw-mKj_|AGFynXA@K*28qa9u%Fe=1~`F zbwAf7JO5zbbe>jsi$5;z7~hFk_3KFE&Xe`HtQcy!;7?yyKIS{~lq)^oI;3E zL8T3~c*U{S`}zOYIpNZo_xql|k54#f@3q%jd+)W^UVH7e_xYHG`%H-N&-$lLaN+-1 zLD$&a#BJZx+_>9h`{OiN#BzJ?XZ;WTQ|{ByURGW}|AY09le^z~l~q+h3Aq}}BykAc zU{!X=lGGKWx#7J&hX3dqL``02TmR0gZi=eAV(y)=0FNIl+qjmKSk)>*IT2*ELbo{I zXX?yrZ#i=~=iBFN>g=2*J%@3`Idbaq?KugKl>p{PkPO$al;!}tS&^1jmX$>ZKnn}Y z3YyhTW@W*8#+M&ju58iP=Xh8Kr`9;{3}tDfdKRiCDESPy;w$IyG4m>d(Nt>z_c2=W*Sy6BRAWbgD5~&1eFd{uiLpqYt=ZPM( zB6K!_em{%I#mXLSfEWEd)_QU8BJNze4<1kl!Iwl===Z zD4W(;rWY9Nf(fokMijR^s+621G;jRm8rr~nP7Ex*=3jKp{pV|z%CS@!k}%+Rt%` zbbNERyXMu{8X+yKAr_8EEbBS_vZvotJsDY^`H=fziT1Z*;pXD#I;^5=YRb6i>bZsG ztt%SK8fV))vl$SBk!!ufx+h%=UB#lqoq7!pAZJm8<(lX;MR=ZI5>d1)@#*$Hng{t6 z*V1!h9c)gHPHJ;*taFj7H1Qg$abOxMg7b}E%QdjvU?CCES!(Yk5yA@Xi3uchk#a%O zavd7m`wcB~81$WtCu$H6f%eFVy#0g-7zkJByg2WPIdABwkrG2!fWsP+a4=1g46=L0 z#HUHs58=GtKg63iC{t%JVFG89%htFPrik@Rk&BioE@!7|Ju2X~^bvn&Wd5>o*8$l= z3qLoas|(MT>8CKEF9-5~Np@ADXQ-lwjIFJd0w>v}e}jRW3NWtOv98%^K#DrC-V1<2 z+v5D{WW2#1S-`yqw_Bgs=CTt}#fC!S0+hF05z&teCIjL!o)mN*)$%QCy~UQ#Z0FM3aVm-Aox6)7 zDCq4GxfuqP$CZw06-hvFK`d;DowH0GUA|&PS-}hpdcZfiQUML-xQxnqoK33sl=UFe zE!T(o=uzuIR_ZIu=lH9$yTr;ZYz6$eiI^#nU^&Sa98%+fdo0!z*7p%w0G}B<`KkW-UwBUt)U4;%hd!4w z&p-d3m7W%GQ{D@GhKE^QQzl#J0izA;0oHO=RDCVmnXg4)vT;ny!p|bRVsW}@v?JTD zcs>}3by~hD9_lv7#prR4GlCJaIj$9_ebKB{vrm;;{*LbYZ;tB!KLZ^XIwGDdJ)$yD z%O9gYL=V14ZPpgC>pW46Q}IJ#+U6~6`*^0p0CO<4A`!obA$^C% z2)m?j;3Iq|f5G!`_g57CnHwCCad9=FeXBm^7G%;e(z?cMR0^Kd<3l z+SbhG{ss;Jn*mh_?H9Sx@Z7eW7GkZFxvt1`}+bswA@VQi=-8{Y&aT9Uo+lZXt1NMEJDU6bH)PrmaZ!5T zO(MR!{fvn8&BW2qxhPdoEO_#E$K2w;^!A6C^)&Kw?~0!6X)7v?+@t0|CRf*bM0evdb++>_FD_`9mt8XF7kxr*c2(=bUO_cgVuQ)IA7IToGna%^1jc6Ni1C`50o zsz3rWE{myido&D=_rv|q>`F4++~xbT-L=B0!e*Glu3|kVHKsGCN_jjmQ+kMOb5V*t zS5^2St%rkJ{gx|SCja79^tG=aKY|82C3h0T|DUUv^kI^~&N1AcqTbx#ZBs#k3EWIB zbC*HMO>(-FTeg7Fnk}ts?=;q>;c?#MSWN%MF{(w|_@S*Sn(-V`G|g6^mva85aE@e3 zGUqrI(+b8aeWk|(593Mz*6I}t`o8n1SSPF4yyb@;RfLmeH*ZO?!|0k@QyW{oI`L^3 zW)<)VEPT2q@oD?x(fN-vx&IKkv8v-Ddb#4LI5kQ#g|MzoTW7Rq8;mQB=>Y?mqgN{7 zp8qg)rYyH=>sFClWzYU$ao~rrd~^=QJ=LYipb~6gDzqNKKqFK&pZ!TmjOjI#{&;=Qd-izm>*6bzGA}~f>ftlwMsg#tbPX6V zn_52+Q)a5U1Y5()E@RpFt6aJYM=WUVb^S^UEzbls_e)P84o{BK^z7K2Y#l#~deDh| zZjJNcy)7jk6;!7=?6D9MF2<8R&H;@;tpQ&C=XfC2z;PFx*@>2S=qdZUC(g|^$LfMi;)_Cft2wY`|Op~vsq>eOAx|))q zF{ND9r!pqXRcb#AsX)~i!b80;+E)iiFnwY5HuxUZU2_+D@z(M`vi)m2WlDzbV^ z$%zT8A~{vc3ASKKssFGV-o%V~L$rJ=S}cqu8_e3(qd4tWjiBD4&Z`wx z0S|l&>a$8_!#}SS+OC7wdW}6!;dH&2SW=m(l-w<=Cgk>tC|G?`P#<_kNN64tgiNF8 zstJiD?dPPdo3-jR+x0?JwZ2({%qYs7-X5fR5AB2bG%f9V_4VqV8#=EDacOnOYlN3+ zeNerQKXD~ZIF7{^lNqOy=1IUWS90oiN2^{@a;k+-7zNlALf(q<8qgHjHPeOW%(%Jv zlJ^O2h=o@;L+F-h8N(b=wXl}Qs7r{Zd)^i6xD>g6_>Zovy@d^!497||yd5hxvm+n6 z%zkoAUAjG=+py~j-*lxer&iMuHBrO=^-8U#I%?v?iPAaRNOaf$ZqcxUz~>*y3$bJ@y3oaC4r z-IT5O1jeq|WrWIfW{*kFPT-dk#wM-eHLVj9zLrH`0>Tp->x|IA9!;cK6Opb_+BGU$ zgN{Kg!*rv~tT0YA+NK-jI(p2EzK^kvNYPg@K332QdB7KL3r|~K=$`0ln{AbLY2@}< zd&L?RZTjsM{WvVv+-t7bb7&IgqWQ;(6HXJ*UvdBDioMumFE-nYlkCOGEo|t61owYk zv5bwDX?pJrjV&LGCEhQF#<0gFGx%XsvJX3mLRE3qx=Q_+rljPR zN#>(_b&Ydu*w4Up9QsZye?2lkhq?m&jYOoZ+^=cBC9eELS+4(T#ftcq`xQG>IZ39p z87}KB3#TrR{~t^ns?aS%WIaB@D_Yp~Qoz6s(W%fJF4a$DR+^HfBp3@*wdGFE z?y9LG5X;x7rB5wr?Wq)pvA!JMje$I@!6e_BHzr{Sr?vmzaE8A6KF-j&L7Wl)iqmpd z#%a|K!)dwrZ#c0=`yQX(u0fp2f5jQlYHvBT7Nr5@An` zl<|HyRDW7tkl`+lLH`oY?x$*?O`;QL10tnu_Xz;Svy~@+558or^>bWu-9|+_~&gdh?$sqWG&WubG>XaQ75z?k)9*X(nwsn2!kOb-IGQW=Dim;*mZ z4@_AZm}ERomQ9QL)}n8+>!yW{S#B=E`k{8(`RvLEb)2U9&xpWE6t4;an{eI!3^q5# z$_FU@Pxetv;^nh)`cqQ+SW2(6$B~OePS0oB;+UpUjAsl}c*D3bL>3hM5V>76H`9y} zEmUVXC@66QU{36%O{ncj@Ji9S}}$yoPWs@DuEaZeKCDQ1uy`g9;ULncWyv2MF5 z^192M+QF{QS)K3sM8Ru`T77zT!_0=voR#yK%zSExh+MihLDIGPGcqDFbH-myeA$=Y zqUKqGukNc)&&?k zl7yFMR zxTrM(RvBP2aq|N0=9y^-^7CwIIHGKc;5`Jl#=aU_-O6Cq zmPkyog!D_%H*GcBB5gSIh>`<3^m{RPzx-(Vy{I}5ovu)n8ZH$Fo|nwvS$DZ;JUFn& zJf1Hmw5K;5d+Uqlo( zIVY8K9Wpir#=}a4x&%gN3L_Dy9Qy-aLHS3kJhm^h&;G%M``)S$Rgz|(%j_7LSf}b0 zndr+{Nuehag^E5BRLIwWOj>pg2p<_1gEHy;U?6!=CjXyuF!x{OU=s24|3eOp1UFm` z7zhIQ=%5^UkAF`NEZhGtauBi&$$_O~Kn_CH-@XACM_r?@-kwaDpxxA-o*=SiZ?sdM8+RyH)t}3eMx#;IP z7+Y>i;u8Gb7wx$V?^-+ehzLbm3S(31T^X&gQzlnf-r8!F`<}8`i6v#py zEQrdRFtI5xyE>sMHKJ`of*d_?0{f7Z?fp;Df8e5&2Hz|~Zm}686?;;S4e%}y`G+o| zp{4yvI4$d-;Z-kvbM4KS5;LvUUy9>jr zJ(g9qK^#?k!uHrN$!_vsBW0&?#Z_{!FFaZX?>H8iHS*ko)evk1dBclS3+a_J5PnLQ zuQW>sl}AXz?}&-zxrinm#5IIyEFnVrAfDk!&BT>uETo9B zOB-0>^u^M&dk>pap$8yOgL(XqFJk7!+ze*0_hh8mhj1ZLieHPRhZCbQkDp_D6l)FI zZ*;4tJ*#-hM8Y#m|BBX)8$lM9Au1JyqGygKe@+zFkvYQ?NGmoyFwvdq=ld_9L4TQN z&wfZa_UO}a0i->xu&v8pC>R~b1O@K-boARzhUgM|QJmd0o*Q8=8pY)m-pF!9^Aj%? zTC-2_=XJHyZkloesi!tL5{u_^g%!HuK&)eO&-~cJb|W^Yokg+NigYw$vzc5awp9#L z@XDdl@&@{%F@kEU+JS%+>KmSMn&Rz>th#KcX_P}zH_d5^<6|yT?6?knS*H^;gWZ75 z6QhepE$Uwc8>0nV8o|g*s*5?iNY(O3Tr@21S6mFR7lT@dqVa-}_C9Y>me~!fOOS8F zY{%kGDvxqfbNIi#@Vut~#)ZK33&YA?7%G2&hlp^(xD5_FYWKW z5co<$Aq|VuLkQvq5Dd`$hg9f`3y99_@4OH=5iUji9vLc@K2U6s-%q7-2T^WC|B(xU z1H;OFJXEfDc)41q(6o8Fh5t}0+IHdjy#9|b1OgWvic8T!Erzduupq=bqzamC(R!&dmH%k~j7Zzyx-?;BW$p097T@OkS~^eirZ)MYb2V# zM`OLzFI)%+Lsc%L97zC=t5fY0qM9aXY(cwcg1RS=(6&F#duPH_t-kXf|B{5^*TAr> zzx+aARTx9XWy!WI0?k)g>z`slZ4&=833eG^9sR$$5ct&)wPy#Yc_wHqnJL)i)i)^k zdI-|rCzGdNNrqwBM=kvC@?82J(LQgy`hJ9{kY!*}N2A75JNGXCF>vAl0 zQ&z3x&q(+$^x0j1?!VO+xYH*Ou8Mz%H5&@QTb=j+!sC;0zWY6#+^x;EY{emwKPVyo z42a)uhk4HMpGpZw`wEv^>@IJAcVFOKUr_rJ+}V=O`G~UHcVQzaNl`G7*|4uqNSdW> zj<8j&;}+lsT`2kKyZy~i*lbE}_VC*zsyo3(Yk#0G&@R=_)oG;3pR#=A)#F0TV||s?<1EoBkl#O0Dog>i zs9-THX!lW4#)DMEzXde*_xt(+e+joC{Jg^G zmv%We^Y8VU=cGE+d_&)ArDF_V-{+V>KQriO4)5!8JVQTARI5Q1b0!wKRyM_BR)!QQ z5Ig=QqDgz#avuL@iSZo%Eh$~&$d~fmOwF~dQZ(i|JN=kZGk!v6+1Ti?I2 zFYr1VJlx#Hlq1b8jNvdE!$I#Pb6Z&cIjNL@Qh(_GeP5tbDixNwpUCADDmwDS+xz^L zeGVj;&oNG58BM2<9+9mYrBLB9mYJ00y3PNN3JUoPwYMobs}DK;Rei{; zFNM2^Abu@D3!B?JU7F069`d67T>z|{2B z7jffa8+1Y`{6Ua^goipd*cDS;vyI%?EHk|y-h}`ta}f@hOtJJ^rfT;!@Z+ewKM&P^ zr~iq*z=CjhqLD^Zj&DZwIO}`H{{plkJcEZ_ePvH3vX^R@k{eSz^|E@>XVKsi$1u8R9`##p{rf{gEb z-q%0AFYrJZvf{dE=x9N_VLbm90SM-ctAw138A5v3O(DOlSt#yW6wWdHU)GR}l?pN4j)XH_2bTsxE@~xGaPo;6=%eSl_ zc$QJxQ&rL><7=-~Kj(WUR4e65bBo6uxiSy~%NKikxC`B$9pinCU3;x$9BWp@gmE7? z!#NWPv;BxNBqNsR4$!H`NDYtUNEm*hI@at`)F7M2wlAM7FzZ%!D&55npH}NP)i>Rr zpC?heF2d)(kD8a?`;A_saPR#F$<}{T@-8X4nSgguDx#E-`d3Po@Yvrz?=bUC-*D<2 zH&fhZgyXD(i(VavprzIMbBkB6#2U~@(D`j?tD7hfa?cwmg&ViBI3_3GxH2baWwCB$ zaU7pU$)4i4?NSVV9;;F@;kdsqlI1ntiDcQIH z9~O4#EFTZ71K>ldZs1=f#I&R+Midpw@f3$OwmUeVqQLD)bmz zzX%ZCAF;wB=8dG9#cwkeNw#Hgd(3f&b<+^Gl5zd$=PdT(G5{8S5R1L|-KEx}y)2*Dh)UWzs@@r{Xo$!Z(bz`q=Vii-8Ay%wad=#(Cf(o+$8d?>%OB(v(Au zTi#}xlcwxxta_Uy6B(25B7?gvXBf27f{Ea7BiS%BoIDSP1XT;c8_d!qVda7kYM#a{ z$J8aIJ+<*>@qwaCs$f)0WZfd`ldR-2y(|)}u=3<0hl28{BE3djns0Hk_4)d$Zwp4L zEN7BKJD3-=-W}LRd1jAd?ahS^t(!CoE~;`YTVY}Brr1if9DJMR$WT{uK^5bDmuZ(Q z8cz}Y*gvN!PKs1ukENLp8D4z-K+e+S!}} z%_TbQ2-=%hIgW5Y&03e1-6$sihfFIj>E5M0zvt_AdPDPBqg zVx~8V`88n5olU&9a#9TbaF&X)$y`}@AeQV}r-xApFSoaYj)2Sop| z^G8$&>%XOUA3M)Yw(J-Ef0t8k(%=9N`oO~0r{I+k7(gKkT-q9_N25q~qz&i~01@Y|WX#p*qI+V)1gQ?;^jo5oZn-P2nS^vVQ~Jf%#epgC zKp^OVb{p_yFJYY7lY!+%vVwc3DKMG)Q`RRvtu=_|nSsb77=~HX+xGt`(s?kg##R=+ z*FK+_)6xYsM1Bl8&|3~M2z-s|NaHx0DS7?D6Q3xWTvLg=I^r%Z4c{t~zKMWv{1VP}fO^+`57gC2$E`x^lDW9{NNii<2m!NJlm1DpZF;Qq z(T*9oXMr8+#>%lp{K7ER(C-M9>p6HH7>OJ<3yxCWlZZRIOPnvA%H3^Y`3I@i+|3!y zob8iVF1qR+zKXyA5j|aQH^dXLxhF&+4u0=}vxLZg1_ce1r@w(FJ&E!DS8_Oi zaIKe(eSAj0lOXv&5CZH7kYCw*V?cg8lE?tpzaBxvmL<y^5*5nUW-PM9ii~F!;A8F!m(4A8I4?s}(!c zCki54A~q#3%@O=|q6s^01c;iGHl;H{MD;4*550g{L~$Yo;lP#`lA*ztZPGKV)MhoK zq9L^@j>(8HM=(ZXA^cNnjxAVx4}K<}8ppxpb`L$9jQyb<5!PpuNds=%G=dmaTW*NP z+j4Xj;K2AZ$es%Sb*LcOWp711B|9f0!>NwJgt=)hom1IfiyAXR(x$}>{HpBMhD~F^ z$h>Vpw<#6-#|*!g>M(#+8mBZ47KQ0AlIcGZ&2cRewCOmkZ|6K5`C8-)$|p7cUw)0& z>k`55e>>*T}vi>@Jq%euF)wa=KMwKo^ntM3cECqOke#YplB9E}# zIM_y$2{EVHFyU)Qwquc_$lhk4&?XbMKQON(tS_}yCOe)nKqcgoqva3LsVdyfn-H1Ch$F24zHJt~)Gi=XqN5@Cf{ zuuVv_D;+aty!bZm4VWW^D@)^gs163O%tw5kwsW0puP!~0X*_LgJPb8fWLb&XDO{gL z47^G$G(tmc0XM|if@>|0sK*RuBajdi89 z#Z`RW1}>_3=Bjzl#jgtER%bh=?Ox<5Qk`gKHuUtK6?8UxHmU9d_Z$KKOfNTX! ztkh5h^16fNKb3GN*w&=^SXkIZy?Kaw@u7QI8|)#Nu6fZ<7kqxZV9Xt1kv`!Lp`1u_ zNUh%Rk2ym!6$Z=^;$6g*4W zB%I)$&u+gh#Sgd#5@mVj-=g=nx6k7Y?wbQyz>QAhYw0~a2lE^0W$U$u;#Z<4e5gqL z?XDRKbBxCoVO7LpU{PS*%i30{*b zGk<1!p*LmexEre`m=^b@Waw_>#hIS!O-azuZz^m0aW5e;<@cuKeQR3O+kQthJ>8p9 z`wdrLnHg_d*qb7Bb9I2)oN&T4zZb4?hTCm=60iI5i(8Yhd-)XJc2{OjF^rWm{!*Da zio0dXL+ac3O=*71G`klIf5SvmF4F#p-`pP2uv&uPD>Gva&zc_Zg(DE7*_6|pds;L& z@RvM;Cq+|Muj&htnX=lnfKpVSiIthFr;L>gAV#<{^HIY$rdd+n5xgZD4w`02WeKUMvAtb1P3z75R5aW&O_%c8C_xnf-nnv$>LZkmoifq%11W!xXqwWi+AU6b7Jq>u z_e0S%xwrkV;*@Vtkoaf<{LCr4k&3s9zYygqbta3H_ntVV-jpPj^NFShd)wa?ryMky zq`Y@Tld-qLBjRfZW=d%Pvqboo$soaR6-|k~?OViI6Y-bm)QYn*O=G3JH$+oHZ~I1R zzBHE2(#VV83C)<~#$TP4F(cy!cYE!fBdn`IadoePk0nWVxs(Nc_qc=^&5>DE8w)b- zb&M+b>TapJx7Dnhv{{JqO|0C=Zj0A-&6~8J(`0gUr{pi-iWiJ<7+_;S@HX5JL3s-r zeeEq^E2z4s`bwg|0`xhyJR^1O9rt&kBkIPFv-uk#fT)*^j$SuwVrAw?{&J|bT(?H3 z)y$|K_8W<%V=}mwKP-crHQW&HA^7$I_)iDmKOTS|A;CvG@dbOhxKg>X zX^wRr&3tpnW_D$=WOUL7&_HaDu@&_*yO{kMI=4RrR)~p4Lh3TYgM+bZQpoe^;5Kcg z6AquWV_b+caEX}LFvPX$XLWN;FHM`zrzDl$m>!J<{anqn3GE6D_LS*MQXc;$_aMi` ziaJBZc@5&kUi-~!lX4E<%E~I-vz_}rH+N2V1os5z$O){-YH-0jc=c&a8ZLaj(YcIi zI;?2x(99Q>Z2e^IJwr8|X`uNabmdE+FgKN)?|4dWM?A`0%}WUt*mHU*0jnTc&n!G! zmUXl&t+kB%snJztp>si~6WN}QX|zHM01uO|$c4ZZZ&rwV&+1bQ2g0kZB+i1tG_;9}s|8>zG~ zKQ7zNJf=cyIh(Bau*mF~L_-WU4*f$c*>VjlJ^1LH@U5n9%)-%Iv#~l||KYunOuzQdS_3#+ekLizW5FNSsR;kL9#v6{26= zOi@J0p2Fxg5k_0t4#cxWcs~(W9=g$@y)j`Ln#20BC{#UDo5CeVA#qdAeT?m|zdFLwIO!#L^|E99 zg|9YT_^Rsnm6`2i43fPETHZ!c|J)r(HuQ2EUgHc|9l9xp`4GLsq}Imq-CsRhwNPlo zk?h!7oz2lYca38v5{Z#HdMysx@u%q}Yj#cRt2)dwf%ueBYr6?L4&=3uPLQ|o4!+x?mmJW5~52+vA8F}H;t-zMD6v6`f)1W z|COMr&fvy*Uls=?_B0jEZ4eOzgtcV?(C-=KGOBL2QyIUu>U$i<6NjPw$z9qFTZb{2 zYH3IOO$u|I(4fNnr-TO4lm|p<+kj-D^o_3|4zSaUClEQWBgs`luP>?bLnk6)Z4GI7 ztcOE{;Ay2+z1gge!g8@h6G0u1@)COZ#pt4>sKG9Tf&aP)gKBs=tyE4WsZj`Bp=#L_PXbQJCZk1a1z%jv^w^r|)I6C&cufA1pd=lc&FpK!L2qb) z61il*z#?9lO6GARu-k;EI_W#Ec?+}yuQ*jr-sYdmSkT`4j>|Zn9>Vede-Gk_9m3&x z|6|Ck^iD|7j{MwVyy)XtsTPmRcu)&p9Dp-3!hHW|7%b|nFUH|?;(f*--ISymDbp7a zX~7-!RhX7Q?|CJo=6XDIc5Q&X>@%M@fKx7X_scMZTnHU1r{DN~x@U(76W`Ku+x9``o?k*}OOmqpc+_)9^ zZm>WsJ0?nr?h{{1=`};?xtGZH*PEQ ze)=UQ{Z_lKsD7VC|+zBMQ8ty|~n@!m>1>IBSkF zOEA8|7NlZ+F*?@W^)V?)Q+|rI>x*L79t8Db;93+oP^7_jAs1beFlE7Sx4*n#eTABq z-N)a@VO=NK(P>xE(Jc&I4X!zx7h;3@z zcfxcf70lKW; zGJTsWtunh{sftNTlCS@<7KjCFlyY6H*YBe)O|B*SrQn+s%6xD~au7PE7~m;=4)jA} z2TFVAfvK)T5>J-zL>2D)9MAx8^yC5WZK`va&qc%e)DGvfiQ50{_xZF-e5T5LCV`94 ze6e7rlFYr(H!_!`^&}=AMK)U6duSMs(0#;Xk~M3HM>z1l&!hK8IJZ2U$JF6G%EBhg zi1i&>Jf8SIkKb!cGnnvZiv`QVZRtHDb7>uHOWF{iwzRYi;}g1`_%w$e9^zAO%Ymju zDa%8HZCS*;ri2_jObcygnL1+@PLzL`97)X#pUwkmQ{s`oF_NvIP$} zdZs+*%@s?p_OvGJ*5DLT>qENb?Do1vS9^*=J^SJf%d8tk!!nGtyhw{7$@QuL#Ej6OyIjKx2;a|%j8;J`WVi(HOpK9h3pB{t% zpXY$%1ug8krEDQi7mY~*0(;6#Ztg-!m)J{Yh7+P;($V8!!o=YTLOVCMwN4=?Iobh8 zDM$Y$Wy9{C8i6#L43W!?T{sAlOJ$If^{**WGAE8)gXT8^=Q)^M*x&-}?n#MtGs}Hr zs1s>+Xrr1mn;?-cv3VNCTD{n;qwac3^uN&qnXXXe)`jO>j6E})+?zGNF=&G(DoHb; znp*?JwX15JpP#K8_z3%||2-*vX$ob)G$Q>fPZg4C)Rf=)E}UZ<$Z;-Zq@+qI%bc1r z$Trj}zme#N=U91FrEgM8s=0cAGup(+%t%RIn)1*qgh_Be-}C(`D}IeUWpU$>UzZ1_ zN=C0B&{Y3ZJ@|$_rOMNaf8p?VoTit#AK($}6E8BA$3ca9y-uL_JcRhj>5qLsU7q7| z&x!>f+$Mlj|06^Lx8&_r;0z)m2-BWM>A;zbBk-g%t6>ie^x&ewb|_+&vsSxe?X@Sh zv1Y}#4_|gwWt%4VR6eq7{WL71A~J<9p72p*SnV9uZ=YEk_d{sR&wIvMXUlMXRg5b$@dVw*WaYl(R$4-8$?~G?%1TNhiQlJ}18qHo>Vr z1v}+Qb$qzzYN_XhsLGpCqvD7Qz0ROEnqjj)T(k8jiFJv%iRqZ_oi^;CAiaLZ;1oQ9 zaO5KJ2zWPKK1VY!3a_@=-bgur9gh>~bUEdn|9|B5{NM75=w5|aSjRLB2H6pVA@Si1 zHupamW?j+=Ukn!~Ov4HLO{Xt6m_pumaH+wP%`z820y@W5am${~=$a!$^Z`rM(zY~?T&4)#9BQn&w*S+w|E z;}RY7c+ztvCuT>Z`*loS(x&(b^v}`z)rSUJ9)aVbPwrC}KJ1B5QYwhx)*tJBjeZNq zY2m&QOjJ^dlA(_K)q4g?0#WN=!Am&kxb`kF{)tAvN9%DhC}=lD$TUI3a`1aaz5Ar1 zPkSOkGpLjs#L|kgxKJNONog@C=Kb_OcAbVuT6W)WoPYo#+hCgggztLf#j_a4jqqIxk}HqKFMoSj8r*f1 z=D&TGn`HglegCbq+)OmL|K?ebOKHW!cW1fhLTz*%7r`0rMw-c1F&>T5`)-u%_`rTV z#OR{zM>o%cjp+kE79GG}I|FG&U=hCmu`$VE;^H># zR?PD@X*r0_uCcMymTT`~IPDX;gsEDGNx(h&xHH8uZPP8lwP{B{0{4%Nm*DQe+TSB$ zyko1t2zy8! ze(fC^qkkQOUL=^drpl}#h(+>y$yx?7v^7sCqAcb>5)rW;rD9-5$lkh2D4q9)Ckise zoJ=CLxWy-&xoGRsc_dz!RFX)OXm*72Hf%Uc%B9X1Roy_!4r|(XsnMjdXvAefisXDn zDth9^Bh$!?dMyh3{M*;?>&`Zo=#~l21g^X;!I?0^$8W2Pb!rTA>a=#vcrI?C&?;T! z!No~;X5j7uS{HEazFb6WqcdtU-WF8)lkomgKMCP}@~E(@Ze33_I>x2vj`yiLmJPTm z!`%IjKvlG#2N^Mz-AG?tT6ngxShwsMA(HS#627u9zQRgdk0$20W@MXYM3aU?qob41 zr|5pz*>6GLg=|q2x)sWcT2}5;54M3d+y+IGA7$SzK~1>Tg!_d7Ue!u7F0OCFb&FAU zbtHCwU78fjjuquxwb8M$;Jiv; z2l<~Grb|5ERN4_5GbhrnR^jS4`{U$1-TrFgbWY#+xo%;wl^=C>VbFCnsIvt<9<}o5 ziEIjcu-?&d8r!6&mYIiflOS`$smOQ9vE-e`I1abpGlJTj9doB>pzd6l2eUeIYY&Lq zbJ4ifhqw`Kl4FUFqtP8Fcl|Gt||MXVBF!%4^;z zc7Q)X08++ySF+i!R1@JIuJ4H!0s0 zomH^&ZffC@Y_uCfE$?p1nv31dtcrCPZ?;5OLwrhIyqh z7KX1RZYw2je}9I1bJy5ZZtt$KGfL*p_P<8lJ5wK!%;DAnbJ)4`f&4iSv?Dga|NG$p zje8aCH$?7HxeUP3fx!O?bu`DS&Z7SU3{BsQFnuF3LGkm|*_kE`aL2TK#nKPc*@{f2 zwB$^qUD~#C=rH0R)99bY9mw9o2#N5}LEQn7*$KPr_c(MP0;kN+Wd0uQbcGUCV@N`tyl!Re&3f2J^$xb(oe4 zZX|LlKJyHr7krxPPIzI$^8F;SSa1S&5qWoth{C~|_X$d>k0>~F4fBt#ViL1#iBr!B z*_CyAr+$Rplu%hW!l^O{(<!12Am4bkmZT3Y$enwLoR^2L!Ct!$=^4e#z zn&NAm@w;$n@&Tsw+wQE!_+?9K3u;%7l^9;4w`FZ1=i#dE%#<_R|oxG29=BaAWIrAQ9e-+o{hQeSfi!3Ffo^wOx1dQ$7~u|dr=+UgA9d>!DB}HNYB~JUrb&e%6w1|6+uO5g52sXDK}nQ}mZFl91CZp6F)+>N^r{!CoV zx;dd4cOvn7sSxk%uGOSOrSN>W-hm?{-6dmL{=d61qCKfLa8Ke5bF{5& z?KPwE+Z!2+HoV-8_+tFx*uaLBR8Vl>$45U095#Er>m7VOYRoT3;Jw-5bg?)aRI}Ik z3xON^;Uon&ksH_e-ns^13tdcSep|GekB4bM-*%YEIRyn9x+%_>39mWLcaq*NCEn#Z z08^JP>JVv)G@K{+1=iev5cyd&cftT zcO1*@<~V*1Js#1zf7Bg}Zc%x;*rmEK(0@okj}g#gVW5X4Ad5D3sVNNfhy*m9fF241 zO_hK`>e!{(VW6oJ&?Ewy90sz;@5jw3xT~E25XbCodZ~29;1}#Zj`__ z1WA52gyD7*oYHb8hHnlUUh`=X>KV!RP$ur^w7b5ktV22vRq>87sUN9>G6{Gz{Bp^;JxUkPZPYK#|Wbf6146&f}zi11dIFi zpgu#cy zq`HfPkmB|qi>kRIV^~$0_=us_T_~l^6IHWC#{E<^~*3>_jCtcPNnEh#_!>5X4Zz+1^=iru>LXtaBI zu;9&a-OGaQpNV)*d6cacmg#La^f1eNLw$NT#TMQmUff$T>Yak}@T+shq z(EVJ{+ZrQ3SXyI3%@$l+w>W71IL5y?h=_=LR`-=))LyUeNm?F&)}_Pk#v4DOz{jgUn1)x^sfGn)oZR z^_P244f=UX_m6_!oy2nEJ!Vf*N_3?A(V(}9N_(3IQf36b{uuX#E{i_~x0~5r(<(Q+ z-049}V~k;5XgL_)q4KW1*P_M78~87s8iX#hs~JpqUCmqqy&#-^9KYu@#F9@5)@wTE zA<;vZZ~;DaS6pNYuD#>2F#JvlK&zq(wFuqg3*F_iP3iK$o8HLLDbC{2GGr_jdWBx9$;U){dJ| z8zW4bP^%TRtJGc1bMso$~%ru_rs2$OgCkk z{?bLJ4#~89uZVOHMH&AdWs(h%&B(!DO>PDOIlOmRI&Si&ODoD`Op=_yUYd1aRuxY5 z7#qvrE8w>bz!xzT{dd~fCdKHTr?yb{rSf_7z`x$*cXl~+{eSGTyV?RZU4v(kvniVx z!|{CoQ>8=(Et0PTYk?a^KSQAB$@XjcYwL$uq5 z(GJ-e_ei20BhilPa=!oH1H$0e4Aol`t~adj;q{(BKzrT*?FNbVjnn??r*WN+YfC?_ z_q}#{Q10Fyr2XNG@%*19;O|cR&r85>w!_2V?mG>3E)c#&*G@az3_@g@D_PJqZU1is z!IQw??pa-M~}aF69z?pPcpwz+V5~PupFMfscpkvSP31km`Nru{XA;R_=4o|puo#uB_M%#o4C_s1zExRpnpHM>%(Z1Cg9=|sUr@C(< zzgVLE&S}4gX!}8XZ@@J~d(j|m-gg>Eabcku;a$5e6dO2%_sapiJp*`iB)oq(?XM=h zTY>jrplS&3qeFNrPCGp`PN~VE7^KF=kcDa(!hd)G|Dgf=lO+7VIqfea{J#hOqk)w} z_>+e4uQ_eFC1?cAgv=jtW0|-t+|o^h&*$_mgcGU8?3yHP^d_vm?diN3-e9Krv^D`2 zKzQUPfS-%BRp~o9fTOTZ=X&=IW?oj!7M}2(l&|O*;`vVlJij%-^Sx7ObpH9%{yD_+ zv*7t;;E5rgZ&0>0R{1ASLv_?@`25qgQ8qg@O})l&b3%rWOQ0GER0BsH^uu+Dse=Q_ zg}CQdV#-!UOgRqb(quKn)9L}9Rt@lUQsOE3wBJlT%>Ykl1I8hqjt%jYdfJRZqFK8e z-&2-*D=w_A;vi=b@nLlS&j6jD4bb^WqN6?S*ASftKg&znv88*vi++dUf$&p}BjYS{Xs~7d)E1=6EcC#acKUxseJ^y{-_8syAL{!D z2HVX2i%#0F`6aa&zp_)-Ye5{?wUk=iKkwvNzJ#*c>3r#+ZPGA6uYQ1Dltl08PXALx zZ#n4A4=fs@#}3i^aVPZlLW$fnoh__SgOG5`N{f3g(V8#OlFuuJ?Vvvn(E7swt;;8g z*O{IE45IZEXnh@cWQf++lr8BF_d`VMVTsoC&b6Hwt6>YsK9NCpxTkcI9KyPtD$%8w z+`&4Q4$xgOK=-Ib*U;%7M|2Rln=BfmH;nx^(I9FgI-zX`)O^-- z-P&7evyz>sYVZg(f=ju<70zamp2awNjhz+6;mft$hQv-pMWkwsKb)3mCVRFBJ~5oZ zzW5wpPqh7`J7+cb$8`qchnRY2kSWNId!*FY{Ze14J2!BhP^dVQWfQK}2#p8@5=hzm zU>#znPm|;r?%+Qw-3;~3S5%B{YXwgm?w{hgdr{n5+)sbAK8?R~s#UO2Q)(ESs|?#S zJqOY%TiBih&$w(4^~_~F(yQmdGoHDM#E!{z*tPp{_}d6re_l9c*D7#txefQ+3r44w zr3+!|jCO5=O`wpnf>Z|nO3bx2ka?ah?f$~b-ZkB>%n_!K{VCgA87r~}#HXgk`*<;I16j?GI%PB!q1r8YctDsbpjShGA$ zDYR07Zw`yMwn@tM*$&k`>=0w26dhWP$hobD_<2&feWwB~D0eSX(n-0LMtgisDcH>* zmoYCA>1LIXKZUE>>)CJQ?@)qIX<5hMunO9=@l~B|r7aVlWa}2@z|%MlQ(xZt*VrAA zq2)MA*m1l0=_w;{Q0cF+aJ^Z6CLevJzF6csl^R)49O?e^sZctcH6>czvA0eI-a6If z>2SYwivJV!TN`Z|Voge)9l(OLW6!b8rvh&P(^M<8T{dH2SGr8VN$LW@o(q|dW#+c4kZPRUHJ3ZTI%Yo= zu%B|j0s?0Kcf$rp)(?H$j_QId@1j))WYT3l~xt!6ygBXI*_X#M|3*t>v5 zab$htJ;U4>S_Q-b0nISVHM%cgvVxoJf-!hYc8!U6NwO?l-iC_@+9Q9y_B&$nsu0{3R@{jBv+ zFt5*>#~Es2hdXlGZ*QH2P(O03IifHNaTzz{;~dm5?`qjM*w2p2`vgnK?AqHjqJlPw zYf{wz!~3XmE%v!gqI$=5Ja0q8V(`;zxU5<5t*wq@oCX|}&BnH*{+Q6hRInPcM2r#ysDhixq(`603Ww7M^_ zHG#wQ1xKDZ*e9K0_JNEh_Jou&+9R7OrSx(cSryZJfEDIuZ<@Bj?m!sI`1%3g*OrMxXhlc=ft0;)sg*;q6}7sC8Q#zqB!Wpj>s zTMctCkfH|&ie<4u!s3G$R|=n%Pkx--@yoL{$Elm|tieU>G$4%qO zc!jCxJz2uIszbvtg3Ll?j>hT}i)w5eFdFPrQ8nFE%>xUuPnA!=*jzoS7UvANs+2B$ zhbo{!?F!pHq2Yel)SlRehsFM54NF`Ipss=+K1!R$}0~3Z<>s+k< zpPXU#Ii`@I|2!;}0s5BGSM@DoxTe34qA=Vl&SQmCm5}OoVN>W| z1WQAPSTvmL@Uj;uuOzi@m7rV|p|XY7*ph`%x{I%|#kowUR*0*H*&lrf48u39vxRPJ zD!%*Ht_XH75o74RC3IO+vuMK%eX-~%#3!j3w!EjS4VeQkbpSbB6=T!=Qm$Yv193A5$>rZ?7^P0;|I12fi+~J%SPC5$#{kX$VHc?;e_I>;Xr}ncnVTM& zQTf5C`N@?ZfJ%2y8))0}K2!e(&abpDEBmNzSB^{G%5TZJ zr6tj#Pu-*&p`jdeZd(kVRP5qWV0NW|3@8N4eGKlg{C!BCb{2ZvV5apvL>bFp!)zIe}kc9UAg4jpZ=A2(ldn#-IQzt6+~b8SoQ?&?MN2Xl^XtX$I$t7@!8oBdh%9%y z~$IAx6YPd$Qb`3Ga8HW8ST=q zj{ESX`y7?NN|5Ao3OfPtjRD#%$}!bS-Y2Z{_KnJ#h$;HkCBom0g@_D$sV`%knd89aXe4V# z`xWW%#aiT12<6U(9~Z{fonwaMSjyBTuzad%pI#b&TpWL#O`sN2CplDPT=|{R@%?Ft zjk9**o3?6Wi-5zBq-0tuYACtImio)8j*IH!rDCxpt05G!74eZ*a~$^MY^6H;glfY(L5&@H zF8S*7$&T+G-sEKb&SjqQCSSbx+?D7RhV|+T>T5+kIm|?@>dt8yI@Y7OS|kk~^RI6v zQ97UGJZbDyVI{&(BELM1@7Z%;7?046C$F(hL$aVW4*%d#`9vc#6CnmCM|&+habA=tFp0<4A)Kg{b64l!B_A#j*v||B=g`1BhyvZ~m z3xI}yaqP`wixaqvCGCs8&%oyd1;FMHlbZrYhP*f7YfBxiF8?q-yYnXd2O(P?(o%U0 zsZupCBI2G8=P+ey(9fd<%c`01Tw)RxW&ftx9sUI5z8|$wS$EE*w3ueLI?n8AxkYST=Y zGF`0QY?Z1Vb+wi>X?e?hX06KYi00MRN_9{x_z1^ zU0xbD&yZ0W=3b3OmykKPEkzJ3O8CU;6Gn<>$X=0AWgauW)O=Nt<^rGJSFTmAUtZi` zH_#qZqN&c!tbXs)Lc5~$dTotkduClOa>^&jQBPI|f6kG;;EF{wG)?E4f#Rn(Gnoz1XNsGVW0 z+LEtnf$xAKKG5v=4%&vct%9d~_v}hrJGVZh^m=9G_d-kMhOLFqJ!5E7yNck&aW8^S z-u!}P%XJ1G!dNmj zV8HfTrs3_dW-1=1@KdDJ&Pr*xCtIyt}FHyIp3`k*pSRvK- zQ_|)@w(sbff{fvmw#Uw#QT0(M#=lX02+SN+U zJy>W#6%lTq*gJ!$z6mZ2qDRJYQsdES&~S}j=QtDFaLKtle+z#KBsRbW zh~bOdS(qB`t|K77mK>EzjiX}(cz0{DAZ^u@g^gMr5T8HG_q)x|?Fo-z_V<#=6 z{%}}>w zYf)lIZjO>YNH2Ju6ulPvA_~I_m6S5bFC@;*q>Pub)uw9DL{HBTQ}C}lV-$r~jGsAZ z_a?xa65BOKNWtz}l1&S@DiZ~*-C$JR5b|4r3n`MHL!U>>yv z0c1qA5b9Ev$A_@r%K%E2OIH$n9oro)ef_O5t7=0$_aBw+KPujjMqOe5B$}d%HQ0T? zcpaUTAFAMM$z3z)X^;bu56757$oqplM>Q$4Q)TJKg8eZ`*CFxN7;8$NZfy4E+X*q? zEa+gyqb7$#o&kS>5DJLw59Pm^O&wWGwGxRsC*Tm*3%ioX$6VMi^q6Qgz3R_lCv zFA}$~h|L>%z)k&TnT}l_03a#m^YDQ3l+N14#!*ooG3XtZO-MsWyzb2jINGLe(!_4O zhv{U@wWhgA=*t>!;}2l#=vX0wo?)jG}SK2^Pf6Hg7X zQv@LP4aNRuD)zY0-H2~6Y+^@#ntQUH@U3YNHC$9xcYc_rjUx_8H@3H-jO>K*thebG~t- zD*x@CCN&~A$5N~W^xKz}SfKup5PT*fg#C3WsQ^xFvP-Zy^@UPkb#g0`zD6F9`2L}> zt6?^JF5VO9(x5-cWaLzUYf1UYE0K9Dpr<6+T!Ho!-%QS48nUIx$G-D*5cgbx^8Ioh zV?+GdB!Qm}bw`{=z)cf!sj^bS2TgsP2>hNf-qBjhp(pZn23_5j^+TyrREI-NZbUOF zgIDufOINbxp#V(keB_EYRxG2-8!BA+9o9UaKMrj!YtZq(Tmg+j+L&jBa(>Rxr6=Va zan;az#cAytZ}cl2Z^Hp9OC+?9YOzBb8RE$ql5&Q`9K7S_*k{Dq#Rs3t4||!q4!s); zaTpr0$G}gQ1741%ZI5tN6|6&DTl1;BN9qnSNM#FSqC z=nMA95I=DR9g~A!3x-zYZ=ic9Fthmt@-p5+UAJr@mPOAv*;8^XnQrm+;*#D)&Cy%f ze^CNBHWP1Lf4Aj*Sf++Y6lP@L%m6(c$@ynbZwlI;<3%(Ijx zFO(}9Gi3ZrO5wWJ!gVp`?d^^YjzV|_S=XK&shFn69=WqC*#ZAsmt_B2&R%*blczDX zpLqwH6gC86wIdiayG<{%Nx^RUuQ%z+t_*G|B9JDnJ%)U7eJAH?*|+}dWx7&ZKugZW zL7!e5hQ+Vt((*rCFKgK6^7C5*#x4v0sM+mA7`@KS(R5r#WPBR-k30BsIA8au`gBls zEVnaFS!U$ez>jG@Nzip`K=om{yn-F`U)^+N-9MpThN{~@r$ikxpqBOeukCa#`gjoI z{sFoLRxR7@&y@VvU38UYi^?wpDqmNzwn3acs+jB;}P>X+%*$&5UFIJ_U61hhy#k) z(+EnYf*PKy7}a8eI^|^x2h9-7&MC`GP{cGE(zLF4Lz2P?;bEf(KwDB8QcR-ZOeQDR z4aQb1EbFM3+A@5NtsQjf;)zpuwe%gz+#^w_C)_vFO+gC>Zwe;XV7{#crJsSn@<$FMnrTSSDWoJuISh-`}g zY8tHq^~L_#JMt{Ndnr7#2Blep;;g||$2w-E(U+wYoH&z^vzc^H$ce`L>481l-+&Q_ zo>K=Ah8r!nMZis<&fP#R;xHM=9di4`;MPFCeQ$EJV1!DAEielzC$yjE$2H|Y%UbW2 zZJW3~>VKD=9(bp0QP?0h>#?;9=eW4x1BD280`Uq4`GPL%Cha>#%LgH9>Zfa!8)X^y zX3Z3Flty zAU#61^87F${V*V28Tibxo2?^QbdFSM9Ofd!4@y@!!de*gYE}T8bpmUnQV^-m4@l<+ z#4k|j?<|iBK^Exzr+iAA_odfxUBR9lp#7?X+w5I`ky8WGsR8j*6p^wndu8AQK<-zm<9_WG4-a4l|Atz<9x@^Lu&{{YWS}vN32Dyk0n9?M zK2B4xYF{nVfdR2=fMpO#{2KNiUD=ED4`HL5t~3*WJRr3Xi0uQdVhQsSdR9A767HPG zv5yAuFKBkmMq4-fQ1*Wr(0^JbH4TV62UrrJK>a)E3J>E6UUVSb?$i6h-X0K}27Je- zkTKZn1N)TVLw1RhttPmZx&e#RerfxFw0(f~bo~1g&rqIEbaLmi-^ldpJ8-fWDR0~O zmQU!Tyw;7+NSnKm#^E;z46~JI+kmufK&(J>Qka{XlXulyr$1Xg;Hezw5K~*K2H2|v zEB<9*pSJ!ASFz{pD+3-Y@@8nTjxok$Vle_A;pEe#B2@_8Id3ZarA%$%fJMB0scb+h zlc|;W5z>6Lf{w@X1}w4IlT@-)85)nG_tJ&|>BS$nZJNJr*m#R3ndxzQ-l)HDlEuoU zmVzVdOKS(DKl$sRW!pWzLhy^u#?meN7GfZ_tQxQ^;31$wRvJmc+9CVoEf@9>8{!cw z>T55EsZLNBPT(7I>Cl(zGr7*Av`)Z1!e`O@NJlrmu#9Qsn$uD92bUfnkmmfDUd~rF z#8`HLn2A+@IBkHwvPbA~opcWj2B5y&PD(9KkNjC&K7t&478wK5lmRhg;4|kw_9j8& z*ir+l&0XB>Bpi;q&eC!=vOT!Dh&qp8LbI!PdjY>gNdKtR)B^Sz> zfNBf{I6n5*bMJr@I3V6Tz{&`bpecxOe=ZNOEwKYl0cW)2vEHKLv%A$U1I}#O6ngzn z>+zu1vKV^!A!!w~5F<0NS6A_bO$A*RyDBDhAPzo@@t>fK2^qLh!`67vdFu+;9$&rE z1&=s(;49^6j0aS4frgw-FN;IxX$c&F9F3aysbvBXu7v0y?R!2g`@l7*TcUqup7el` za96>u5toaOdKOE(poRQ4mBxCtpzTwW4>pU@5b z#|c0Cho@p5J54#u)Th**Qy%G*N8IIU6@Oq?2q5FjfQ&~~h2LcqKA&lLOU0*^AN(1} zna7^>^QPV-HhE5~SPbDHA@(rcpab{ORpa$?#Y<@D>KT26Vo$4A)8n1H#3Uoi@gv&m z5&uev#*HHSh;E9HDm8ycye8DR)DLL&h}E9cS|-m6!2AKhb$;NVlMs8XFMu}A;F~Za z1I`0%L1%Y(z}+zqET~s0`9{`6@cZ=HjViX?BYS1C6(mFX&*u)Q05ZBw@ITN3!X}W8 z;F(dUPE~*P$U23V#LzoRg_hN!z-uGCMX!1~oJIU3hdTsL*t9H-5^+tXYd1F8dwnDM zeg5YM&-ek8{eVey<&`w@%kqajVdC4M^-w@vIZzq>kO}_lWM2utoKcsHL-}wyOUa(| zUnkHN0Hb(zK$VG&l{2+$y#E^Jzv}6FM{Zg4Wx%4RRoL-yJOkIN|J|gHDrUbUh*dRT zQAt7fhppGRjVKsO{_+%uD6iBu`?obtz=dr0Y1F)3Zq8R=z>0`G*${$f1M~`{d;9JKxNL z5A2b9-$7@(59pDvNIfm!tH6=*4jaXZ*0exovCg zO>a?v2iu;Lyz#GTT?RhNU5hQeINBmLEbzu&hk00Dlsw>~yiYLky|=oaSB+cBbt3poNQ7?yIVURV`u3hx|e-HS6_b;LQA{M#lh_J{?cpa za&zUj%<}Y^;=lUWb=`~&qnZs~@oazIcv%Hpn>WELe%fCjDnEtShk3X?9qa~9_3e{gi+l4zm)wcX4~ zWE%EpviGYkrm(nW%Fb|3wDuRa1dQCcEmrmC-MHNp5X*VRt^Fg{Z;RFadDm})uKJs| z#mfG|)_}Zgx3Rwu&{z5k-w&w2iYJ2G(qH&NK>ZbZx^^2AI+s6Q2mJX3%FciL-WBu` zOkva3i+}DfPoGf5`Wt3c+8nk(`;@u_A=LT|4G`@AAk{iW)>~qw{nm$k`YnWK*))7l z0SKotp1sh|>#b9e*f8UBVSLqd{eC?85tCU_f5Uj|Lz6D%7ia(*Q1-1izoZYrF&YB0 zu%OE?`4?LQv>GT*pzjEw`xJD0^fzK3hA!Vm z9i77a#=~Dz23yb%pmhlxTS$*i#3G&B@9SOoV2p4-2Q7XdxdUgG-duwIfbt)bXzcoK8jMK8D;`- zO2Mpw2!}Tjcnv5iVjs|xyU`QcFOBPOb!^le_F@biFLOXLvJkp4e-Qv+^B$+U(SptY zF|32=a(ppf<^_#A9J@{Ep)})!SbT%-EnVO9iDv5^oe{{LL5C&p5s~Y^5V5Z78-8-( zE1OQ0SPp&vBOrH4>!EL&&uumQot!dQrqhny<+6eBxm%@m+#<=^J!nBi#vLu*^Jt=SA3|jFyZ=)TH!GM|7RfQo|Zp^{QMCSxuroYhdfTyazB@g zSdT>eii`qOS^u*Dy0a_-u0MzJ)d``-M#Me+9%tk}39z~#R8Al7{2S*>r^kZva$?wz zQo`hv2|r4a_1j%|bxy}8esR);Wd??=uB{ z=vEvNR~%t0eCT}n;<6*KsyIU*lTTLN6k`eX(+=Lj^tHy6{niUOXP z7M#&@E7t@^Em>Hc|I*h`QDzU05{5Es<-PnVsYU6akLJT&L`2JsBh8ya_6YD?WqrXK z)vY@<%`v07d4^*(LK3p~2!y22sK$i?p5LWs+L!b1$KAm>)sNFDuPj$8 zjjmB*x5r=wA!vcN^BcHfy8~OT^_PIyfI>dQK_8lGEeXaxWOve88xe^3L*PNx*2BDR zANG_-Uf4XYJ21XZ(=0S6Acjnou*Dv;<*>Y;3^=x#XiLyBn;Ta_XN1)EN@nn!3}XVr z+LeMj4U}HTqQv1$hHi{?YlXZkjc+f9D;Oy0D1K)OdzCoVvi`8N{xEcgptpocGB<}~ zf1z}?jQF)7F37Y`3lXN!G{6e)yx$zIWK+RbKEY59Q6nHfTxoG=%Hx!pCERBwE-pOy zv4X>K@nas#J6uuBvIx&(&m0~I;Hv|4!ut>4IIKxIZ~ys}6ESwgxaQc;sJ`JCTZo`I zmohMWZ1wDM*2R{9r1Q$ugIvLS34W z%co<8u;y9<(k!#5Spw26v!`1E5-UoOBgb6JwY?t=&tb~WME{DkDWK$;yl=eB?rz;N z(c$WFxCWxip^Mrsgz$m862?{;+?BRg^IuXbx5Yr;#$g|*M$Ma=0&Yf(eCc&mKF3lH z!|xN;VmR0eYIOWX-6(LiA!Zg+S^2yfj#Z(&DHt(Z$l*@v&&frmQjsi=uSjK8W{^E& zGbV@-bH#I&+n&o1=pIE7%wE&&6{_VRE7t1H0kWy+^!U~wEckFjsM*xcM;H_C=p_XG z?=)-(M}k8(;mn;`p1vSBmi8PP9Ti5$mpiZ*e+ql8@29ZrLwBNl=7>H>N57Y->js$| zrd(h{TF%#fC7PStv3YQ%7dcPs|Io<3rn`-Li>RpEkh(w>b#R~Z$wu}8r3#w$8p|ql zBF=b~lxNAW5puV)S=1-oD^lmGXj`vDD+|Tc?~nDB=-hL0>I%pwccGqS8FGU~3rH*W z9RW+a&wwpD)aTOrPCNxY!qp$58q0j=m+WAl=U^WWxdUrzaq`wj#~56HPe|`RAu7sl zHcxFwhl;`mFTR(my?y-GTcr5E0XxSfS)zt3o0{(x+9E4m&92Di_cI-DWp3ZAczFz- zD^1N;BTMwd%C^w;%4?w~_}$Sb^t&Uc>qv=!=-=L#v%PPbj@K4X_|1;;pmHxS#xmxH#~jj5{aUjP+M6!)gBOi zttJ{w@BG5s@@!xAyocZi(bj9^X$ir5R@QiS)*EZ=$zAAx-SjWI624=av9 zT=2IBf5cXzIk&IncYQXUD=2FHdR_Dd_H-W_*KZHm{=g*ES~z0jaH$0fNNw;YLLGqcJ<+#TS%PuT4RxTEJ856De%U0$W=@!En^`HeZ#I>b zXOUA5>}^M5KMnIX3nJdKtiFXs1v)nrys&YC(Jyw%B!gb%dI282PQ?gHo3>W4DsACH zD6XNlc)?UDJZm-CW(uiDNVUxsU|wgPZCffV#&xl6m5^I2SaLN5W&X7t!&waWc(pic zNJx>_lYQ!p$1NE%oKT=uo_ZWk=vW+mS=03un`u**jr8Ej&nH)E+iZ;Kd)o^I#jdts zPjsIY-6u}!d*ns-SNa(0`(ql`jq-FneJ^OgC0?7Ipa2WtI?q*Hv7xmqjD=7Y;DP+T zFpimff{RE1#!O11YjJ%t=h*BxBZS-#%zw^o#}vcbgClTQKavbT=4^u4>);mSg+R$X_*xn;ed9Dif- zxsu_8<8Oq2rkgsT3qJnF*xk$83QBMF?mdyPyCApI8`Ws(4$B(xa&1!=9c@lN?Z^)r zPn&^FW7wO-mnhTh17T$&-l&(X;pIC+Jg3~!DO6G|4!hY>;s`t8Zr>ZSaPOYBrZFe9 z9S)woO6A&AuCQV4p2mhp#R2#32OFMlRl(4(VQpPd!^TA~H75%WUcW57LD0a`uxU)* zIkFVW{MbD`Kv41O9Xd~!Tk1ePI9*03YIUeuKhep%Y?HEAD592_I;O6A?VRUhx3n8T zfA7Sm9oH7`G(lmSJ}kqYTix;d0vcwrBBF&4ST?hBEa!S2ujXJFYa|et%DtxHrRAzJ zEyoG>cRvhGS9kl%`nGw)Y5jZKyMA%6;o2?1YJF+BHEPDw?IjU~BeOz2Sg9W7E1( z>x%4ifsg%B9Lp)td)zKLVl-}fhA(|&Idtp6^l@7lDeF!m)q>r|+Tz6Hjdsqi` zRbBb(8ah@Aep`brkI4lC{vPr)=YZ-E!`VQw6p0T@Zf5{lBP>sl{~|7W=6=3O+Ws6 zT7Koum4f>M(8zDQ(SVj;x}^u*&F=R0DKSwNYq7;0{$p^KhB$4(f^JK_5b>xQJJjqx zwWFT<5ku1+M4@Rd>A}s z*(TRC{^sh~UGH7Ik`%Zr@mG8puY(ZaIMTkW;g<-c274H*!LH#|d_;6$*KR{yTEm#0 zNlnVsjxba)hS>=J^Z>)FU*~p)b+&mc54AT1M$OsswdQm0zHyMN<#D*`^FtW2mLU)c zT*DfZ+FgMQ?G972oX2{Ic<~>H=r}V%Zpf)aDW?yCkGTnmOn=DG$>9XPE-hhc-VN{e zP(HfCcVO`XRSlE)hoDA8{ac7no0_R&lAT6blkD3C}4cbCd648zo>CYageed~oTN5Ip19Akf>md7K$m#rf1!s4fw zJixkH1o541IFzPbSvdzW<1emOu#!V7XBZ3nRfUD9HJB?7Is3;$g)@xl%C@o1Ta4NB z6pkAdqp{*i#IC8`x+BqQN*p`sqD$v!S9d-5S+}yiH(7gA?GPWX*)#OCPDmiby2Mzk zNrQ0+v{mIC5_1lbW3-w*_f&1`hG9gtzp- z6D#Id#{^*x*!~P(VRIEh?_=Z&)JJZ*!?WveCbQqW1wO$YZgGr-#|i%Tamx78bNqMZ zp~lkTXjOUW#L{m5x$@A^(zfWK^3Wj5d)H?>f)ER1_Iuuz)IYPw{n4Z8@$8uep zmz-$`akx^pSC>>e)Z1&;#i?|aRS(yMDa#(<+SqATpO)Mv40#Q+#?FrAGC<5OBZYQ2 z<#ntuX0HepZ}+lk)B+5=JwzNPk+KG_j4akQ;gsHUrB}MrD}LSE>gZzg39?OJ35VWo zDZ4_eTr0A#-(D80>GvY~31oI_6%QvDpt4D~PisGG^&l9U;IW zxL48M7~G72*m>Nd5#v5+pFaV8#!J?-=RNfsLA1+54yIuOA)K{c+M#!`%hD6&YYNVJ zoRhiuHBYxq=JnY(RNYmrF%!Cyo~*fdS(K39{c@a2nbnOWs$O=L`Zt>M8a0PGp_p|@PU>8 zQ>jVkT3UN)(`G9TDTW0X5PPzsfw4J+!^Q-$bs}7Z2`#P()HLn1!j zi!bhfXP+luXV|6_Pj zYk!iBBU-RpiKx6r8$vGK%rBG%yULjWS(U>G234SuWid8oX_93k2bVCG<#2H%X7u9L z>3AJY!)63lXb<#ao~UeeV4f&F4~MyxR%XMFe6Uq7CiSwVeiFayL}i!&>=AHzzE5vh zezhqOu8m-%be8tDa2kJk^sGn2E*L-ND zNf9@1!Vk;BrYYkR#+aO3T$+}j4V#LXlFmsNqm^+bSNYIp00|fQ&@(1Q{xYZ-nae0R zA%CLXq^OA)E>E9`huy)ZkeY}?eCS00yY^$QGKFBS;zOe+W>8K`bRw|VL^PPXFZ!&2 z&8CpD&%JzV^m&c|D$CQC1KQe8NH>+I$Khc$<-n)JDMT7awG>PHB!ZPc0()C!*>Nv# z$~xvntnh#KAO{Lqh!wuDli>TkrtW|HY5`fAKEw!5=Pk&|>P4jP$Y~R&DG67XcUodJ z-IX0cSaE)K*?9yD2Xer*gYsmPq8x5|_j#wS_Ep}w2Y65T@Mf44nqBgI_Odc2ttT#R znx*?n^vRgauJTzi{KS^_9&(&)7h_U-c3FcfE0@G1_qf-`q<3w%DPwl^kQ^Yto0w^L z%f|c5wv3jI9WDDeDtnJywsExVG$9@<+lC&gp+{`!dEgT^LYA|c~Cp6+)41K|IApdqbiZum`EvuhoB4yFM~KX}*5>Eb&>Y zX%m696!*A-9IqmVTCz4znNe%B2UR`W;|g3I*pMZz>0vMW$dhL;QlJH&#sBW1lQRf>jV|@pnBW z-mawkqNjWKz@&0)yZih>vZv`I7gm`YDavlcstcQo)^+)gVxA!Qs>MA`TJXb?n7LWN zBuTfcGuf|Yyz_h5BXon#K{U_nk$%?&0D(>{ZTgku0pK-D?` zV+?Ld?tzhtQwn0XgQ$G3m^UV<$lI0cq#X`R{CF|3XQj_w+p6*Wqz)${aps+&-eQRl z9?kIiaEJaVmhl+Kn1wL$Hmi~qP=ojc%WQpgf^)ITimght4STb9eG*jY+~0XZdZdsZ zF{B4OG&5vIVVS-uWHS^rj58eA_M73bh6z&|RMx5V=@5UQ4fMmh#cYSnIyLo%OjBmJzAdPx2#^SWi0Gs_} zD1Xr&2k2^2#_a2ki&VoB#hgU(Ieclm2`79FAHNzp^0wac);Y6aF(+A!F`0xj?beiLGzCEk1QP_~P-HMCaZAPjjXaoB~_*8Jj&U3O*ptbgIm!7%T3UbLLroS(^MWtdN} z%FpS>fg|0r_TwKbf`tAf?Vm@evt2h3A#`_m3+rysx}t1B$5yC%mzy`6yFOIHu4G%9 zqP7}`DvfV7rt!MzfmCUynzKeN4@!D@)*JC{iYWWa^!6)lSj1jTXm3(tt2EERX-;@K z^U3zE-HM>o?dRJ+pQO%Sd&BU{8@<)WhTP4Y&Ig@{njW}$Ru&!9qkTEgbVF)-kr;$m zgppgbF^HAWBaD4ltl9A5(w&N^Vrl3AKc-1T%$rXipVWV#LAe`&C7Z|$?s4K*gGv7O za(>f|{aThUb9_NJOaiLo$;Dhn34BfXIEVUHQg-!Q=PKDX}!)3b{>9 z0Ttu(F5lf(Yf@H(=0QIhi#RzShQ%_iES~VtE>(SuhI%vj!8TC)d}9EMq5P`J-9n&k z;^w5PoBwWDa4jls$Cg>~N9cEjrR|N|_p}x7QAF*9fszkrCfDJ( z2z*L5?EqDMuFDo-549!OO|~?9s?8-7*qzqgQP`q0U2UO4czG1GJ?k%yX*DUKyH_5i z#=dL)H+T%N#0U5vzot-o#4F@s;D%XXrJt|;T~+;EVt*Gbma$r8W952#yQ=!S_yrJn z-CcGU)JzIkhMdvUMgHYk7`+&agR`vRM%ramgu7*b7hE*{YHZP-t`@1QAsoWSug11~ z+|@veoq4|;+ZNt{K$Ur~j%|yF`rFpAZFs8RiX8=%-KdPt{b;EW9+wc65bo0Ehfagh zV+g$ycuCVa5;nD)LbB9QSu{DOvv-NbYxOLg^0#m6n{*MtH~0I1Nj&cSmd0Ur57FEr zc3pCGNn)4Zf#*9>S2ux6djlA<;XyeBBiBr7jX49wSx>+I(H0y#Iwx zFa$&PCQVs zHGUo(BRt!;r3=Khh-h|@p5e4FGTxKlCFOUCtGZg>N?^+U*0Y_gz5vM@mo_9~JR^u9g4 z@^Dpx33g8jp|aX4@fv*+L#vWE)%8N2(z93}8!sgB3-NwGmMPK0VPgl;$9X1qLA8(I zCJ~&V*{D19?;USpcde8l4Qp=MG|TnrkuL|{wB5X7PioL)1#mWP%>-3RJen(evaeo;X@i4`%7GkAR1hof ze{@R!=xlYAi>Eu8M7b8N!qBbB9O@KLb_yz+9tW(d7*D6!`mFVCw1@Fj8oG>!J0(x& zBZr_Yf|yL`dAvWpyHh&U`P9NrY;(%BY2@@;Pe-S8u=A;R$$Cet$Ub*nPz3=!EMah> zSwP+e6!<9OCQOEWafek`JA8G$-zmKhO5ZLU^6hIg9r27zsbg4UC*npVaO?uXqE)U= zsR^*nqN|f_kz1uyxLuxxPRWJj_rZ1=_GT+A4uxel)H|l+jX-mvbHD+oM)LdlM6Ps? zXIrQASCrUG=fwWL&b}aozIrSC^&a-uySY=U0(hsmxs$E+)yq}5JTG@j6-e$uz11M3 z#{;->B=l;?^$h5U3y;k^?S+&83eXOG-RL8G{4_k@DU|}apSbC#VMN8%!w5olFH7G; z-lp4CFLc6swmMN!`69OAmFv2^<~8jsg&5BYJDZE;IltJE-!A^KGq-?SSD+YKd6T9O zngbE!olPfp?$g85R>DEQI#%)>?TG?Rvp+HZ5DWH?s#4(G>>eu3mUR{_>l`(5wx(>! zVcFCp;iE^(o}fGET?Mhn{dYWnFMI4q_rLMqPm*83BlN^ig6$<)$;_9ZFjC0hR8dyv zTBV@fk-)MJ_8;{j!t4_bUvVt)K8t$1g^XBA7AU zLC!=;L&;56?k|{5WDd#aQ6bjM}Ihs~uwU{tP?R)*KypJC1R|_7E&Alr@h`ExlG*HB$3Pbm5LE z=Ef;AYsdePHa7XAkmiq4W|juEANVlu(d$0@ulmQY`*fsoIOC%47A>i)8rR9|`j>=Q zQw}{}Tg;Xb!4x!>ZI|D6VCSJ6Y?lhUDs`ujmLKsmIDUW0NrCnctBsXwj3E@VJsL;WLBK8b-;6RQY$0u%_)-<+msT9rI`kJB^> zH?edx*=KW|w*vQ3e*5d?xR3PRk1WG|xc~l9+(+P^eM;TNX_{EEfSsaSmxX;oSIAB$ z=qkVO9ByZ-iA^FNw;VfY5r-}f9+ZX--th__K{wIc;I(7tcwX6=HHZCLhGJNZ3W6rLF8H>F^UZAzXp0ERjqMFVZ6|iYep`1;f7{yANh>O% zi&aq>LFsC18;+{om8jqY+q!F_bZzIF8y)F-dz;KNiOW@zKo5spE6XayO$YmhkS(@D zLZe`fSyN_BStB5!(QYlWXTn9Bwsx~6M=d-iB!Cxb35F@_`Jig)KE9Tpy8Gj>k$*+6Y*qq^|?@;yP1TC*xwCJ_P2hEEXtxS~?ZoX!idP7Lzr>lxji%#D_VAc3=hp@=aKF+hw3_HH8AR zHODvH3OTN-*LBdrAl>hjR05awgl-yyWHfS z`K332qK=x|s$AmA9MMGyInuw{Z3%vsw2!jnRf3s4JDXRDHxAId{|hBpOoqB;paWZv z8a)2TI}tA(@QtWtZ%~u6yDtg>PBbYuj1TMl*vmck#eqeS2OB<|DxN=3b^ZW+0p>@m zq3qPUfO9INlNYPcEKy`{m{c`hR`*W<52G=$fA04!p4{Wa6R9S4yPU2lL9kZi} z9}9^e?A-$^w^c&-%$3;sx7$Ezo8_}@s9qD`j8U?O2*~EiU;nTx213#=jH1god>KJTng2F7qv_U)4}0th+f ziAo&h1Y@fjQFVs< z6*vUTX#+h=h@QRe=#sk;IHFoP6>yb;*^;YfAq2Y2ll|I3vE%>=d-P0wK>(q$RS=$S zP*(WS_bmSLfF=ErRLwjfe=|ZtbfB-!bh{^O_%;VY$?SMPcy~_4 zyE0j@x(du1xXr&reR@RoSSo!a6lU_^Xnh4u8o5TfI#*7Ro#Kma#o*PXX8ZiLMUU3T zTYa_7rx(O=@z2c5ob02&Wfb2$8Jqmw-6bE`RII^|O?L+yO>p4XaysJe`lm9>#K~NG zg8*Hb*cR@IL_pi?LW1+;MS$AU{PJ8{HO7vKWV2&S%kUZhrh%bV{t7Pc_cN#JILQ6d{Ydu4ypx};T$@|&^!_d7yl(S&`Z3$px>U}Cid$nNimGfhKrTY>YvPkk@9x{Q9ja&+hk$p2vY^7?D3VGsV_YN^5LioY7_EVded zH8rH!N$aYesj=)&AEN;+3HvQ#?4_CerMUf8C@`ERi^VmRLw<@mZs$XjSe^_x34n2z zrtg=g`vI{7f$s$}d`{^8epAT04t`~^8N&=D%6Hp=V2df~9k{2x7KsEGC19_@XK$GU zmt#9qr?TJ3h_yicUzaBCmo)qDNY3-`P#})qk18C_=K3EZp^8q5Q-1n?C6~V1VG)0R zDQLg+L&qKZXWc0+(|^AV_!R(WUQ+Cr6#t9<&pLiW|BH9&A30C-m;8kOovCr`9vSU0 z&}LlvszW-~afkZIyYHR7GXMTi#gz&HQ0r_qHGC$BHkRkcn^ z=);mcc3t3f{SG}lAYyTc%OY6s!gEe+h$D#bq`Iu8RjF*WCGK@!1&eB`` zLm!sj2&(DdZ|NU&?%J*3gL)fI?yaGXaTZLB465yLz<+kl1MArDIuwW z?aB7ykmTYH79>BCWwlbjXL7$_ zGRQ1|yl`o0hm>}g7p0VQ_q}CK>*!w>vSrnR{8lLfn$x=?T{(-PzYZn$`lpDm3)mlJ zT=BqFdTCCFG)KnO{G}1*NvweKXg#>Di_aMSvOgqJyWvU`9uGdCH{VJLWuMVdAb*!} zY`Kgx6gbN+rF6ie{?2#t#DCJ4qxxyTdYzE@#*KO}`Ma*A1dJO${w^|Q{MRLmc=l3c zhjdlCga3gaDgX%OP%aGtib${8f< zrKhnM30z(e=ivNcXX+F-MXvc1$>RLYrCXA8@@~zOMr(eoUs|--A*e4Duy7f=AJB^~ zU6Q0rGPIw!A(ThH%5ZiSm9aPE%v&KWlx7>hU)US$faF`b`v%mdM2n#21DBmkA6|XV z-feFKcOIuy%u^Tl;R-JK{OHpejHrNH@KJ+Etj#ISp(J~%BqI&$qhsjTRI+6|XtZDI zm85#<&KP>0a(sQs;`pDru1NMz8MY3vwU<7Yq>ufun2B?$B#hA*Lz8|kOgXfUk6lv? z7A}W80wNQL$Sux&s>XNn&gg7YWVHn$omVazUChN0MCZR`zei?iqjGh~nN=avRcq!6 zD%w4bTCQMqR5wfkuwxNyyZW^9^NGsN|H6*sMD`|eO$cd-aVhxK)*Kw>Shrdq6R<)F zLw4yc-fjAWk`)mYye+9t<*`)~KW2>}U_TYOvFlexxS^vP<4l@pmNK#Kt$n}rR!@js z!JeUF-61wb`;zwBIzEcu(WI@;;b3ZGQ&7*q#wOm6Ga=d@!=5EHwwV0L^9_hIu@4rp z_LRKCw}lv6%A@+Fd&bxT`5l(|8D!2Gd(I2b>I-I6yvF88Yi$1?W$zysb(Q^(53l*j z@UlQ~1_29DU?gq*RRY=uYKTAD#BxNdT?Yff-CA)ge=PRqjs>qlYH=)?G1~Xc=)??y zGGpq9qP(b(6nE3MLf1BPqpY=7G|Nn#&-1)yP}|4%^Zvd+{vq?a_uO;Oz4zR6&pr3t zbE^>-RVEW6bQ)FOgW`&X^|=e$V7U>}_*n1&9x{7>6)A_=1xIUU3#}S#k|Wp$#6W?V z4NcA4+`0r$8uD#9<3c)djwgckQa&3aR{pd^sDj>UxQopp0+}J)dYE!SH?~JCpVF)M z!M4O?iz{+n4!;&GIpC{g`&B70ma7mISo z2699(XOKg1cD4C$oby75FIzl@I7uP+B=(2|uLk^I2JRKbUkt*Nk|I=W?&F;Q?C^~d zk7?N1!6MV7B3C=juD=eXh~mg_k^DXs+58db{J6uHEFM#_j|L0eFBSL}1>PSRCW`Tc zb@ZYDujZ9+#^QnipFkZ^MWE}nPvSs^k9spM@|Xg;&>tyLsBo-GZd;HnWyD8S^+*Ep zS<1RCL#I8aBEk90t@O>)xCHlt5x2A$B!F7=twp@5bQFbAt%JPw|3*e>V1O$ zXhsy89N_pd@Qmd8-8W8O^;GbQ?x-I(b`O>@ASG0ay-j5{8x{Oi*s!^N*A3$q`7xCg z4EI-*1wWm6`=eK^9oMRw_xQMy-(P7}xtp)BT^-4AK}&T6CWIo@9VcRo4#jO0`o}uOOU^G;1#@;GML{Vw8ie3mBbuUei8DY8mR6R%Leo5 z0W{km>g(fL7O@5i<`KY@4Xo=Ft2#pq6}53AW#PRVT*`o#+{9qfQr&JjzoqFlF0Bu~ z%LW`RC`-<2utslTFG*;A2{fAqe%mP;B{bo6PtWCEfM!_r|b$JE!&X zRWqu{!0=uL>!JSasbGfA4VAU4I#gH+-G9=6A(j1)C$N#7Jr(?xBSM)0m3PmQ@$K|? zt}Oi_PW6b)Ij#ee#hOk#6P&#a9=lje@3P7HA-b<3i=2ZRR{#6&ncqL@+Ix^RtR1KJ zf7#CYk49KcYPOe%jA|z>YslWIzqM6#F2Ma;vzXplzkn1an{nQ@x9S`7pe8v&63i&2 zI!AQQn>VR*K?EwFcPj(bw6&4(%ucG5&4=Z)(;kgWkhhZXY6Ct%WdO^~$%?c|2?&6% zE*X~)mLz#$Jai5JO}o}tVSM24EM4mRPY;>5 z?i}Dd#jA%x+*Z9b==|ycRT1u)w&sZHK#{WbJO&RBxOQE7FHRh2rb(z{P$8lG`AwiJq=>s#bWSJ(jG`F-3 z?|jLDhF0aUikl5|Q>aJq?itpF?7}A{jsEO@B>7%HWOnBc{N<2nztx6MC?}*ZusN@ZR_nY;mL4LieSR2PFRmsWn8+-nLHx<)6mtpwRSJJqSiJcJD) z13DPAilfD~rC4T{z}aXRk;I-qRCzVi5J=^dKy=>}e(3vuR=|nVBd@Plcyf|cV_M9wz?S%BdE)VHhs14%oZAlh-Gyu{VW}&xn~U7k-zuCNyaa()@{?Ciq%CKcQVNUL~MD$b+$g@K0-iP~GV{A!REp%668lHfSN z4Gc^A!;eNKfWzu|cOpggiW}hfv4jf6Gc)lI;W7dtjTK12Fq#@$A zE<1e?+G3fY>LPtfQWLJW161`lXn!fnt~8wMdMh$L?C+H7$%6^*cQlqBc|d7f+-C2z zF9y!pH#~W48Kv8lfr>4u^)otca@Xj1rlM*|-rT4@MLx7NW|306x(=G(96k^{D0Uva zxxy(ZCp2aidk(Hx=@8WDuj^E^Zx7%T1}+^GKMupgbBOs5LNBjMrQ<)2)JdRVewzGc9lkP^bhJ(-_Y}{!(`&25>fC8fi zJ~}AwyHzomrBBMNM`qf_i@ghpxJMhjy z(Ht%T`PfZ4VP0K*kYtO1$BB&Y2zF2^vkGN?F|hZbXd5KqV$hYA0GYvFA%NuKdRBfA z7KWqG*W&z@_JVS1JX?Cu1zUgUjOLbsl=81pSG&^UG3(ElH`zEHAyrYBM+LJ)B~jl#S~CZ+=nqJp`6ed zn6R^*5HrqLWmD>YRCz`xudFXQc@3^l@la;chT|aiAl9g(Gizs{P6hKwbt;R_)s-L? z)j4~>-b3C(lCZ}rlS_zm@TfwX;s(xzRh9~NqoY_%!q&#qp(<$^j$>dO&RzTGLN89+ zas$3_I0}Vqc|%=pvRBZ~JdI72=)T-xezScb`=EHK1e2Z?gqiQk)!gvYxYryUw zxc8uV?;y{77t9rI-oV!NMd-FguyhIbQ@|b=7=x;>a|i8e#SInjX~ zD@hDv*R1q!c`6{^l^Q+bA=>qZ7C8{R;mM;vd&XJYvCp%KSz z_)OrZQf?YPU&ZHL;m;W(j@RRJMEG<12y1G*t2jyb-uG7cLzLtHL|r8Qzf0%6Y)u`} z_G50_?mXRB-|@p8uWvGzf5&VceAMzR|1_f?=Zw>GVQ8>Vu+G<5i({9H1F8IeuzF2UoV$-dilYO!VT7w#Z_NBk zWebWkF@$t6m+hpr-&H)^cc%WJ|pnWE+ zf4WnBtU&^p2LgT?c(p@({T2aM%Bj4VPkb!-^K;*44cVC2fooKP!)%aM8PFd~1O6_wUSzO!Qa$%~n46v$c(FsAB=LS&Zm*&|Np8!c)?2q; zui2NtDkS(!z&|;#xA$|RuV4sj*O4&7^fDuhc;OGe1~6dL8*GJ{h7;r&c=k9r#{E--Y^)lwlnnWf}LfmXBOES_Q*lKB6l0XyybC zH~c!P^vs@^_ARh4B_Ui~E;fKeh-qR0((%#^#iTuSzuA_cS z=v|8-qVN^Kv9G@`SaK@J9w2Cp*Qo&hBF>HdF@_@ z2A}OpiLOtb&PU=g&+)iKq~>)Q89Lvpz?dWKA0+q@nv$KriVMJ?*dv$eb7h;IO_n=7 ziYB;iDw`~bP7EU`>MQwc(3pU56H??K1b4ujC0a{@O)kXR7h9Iw6hfSRt)p zSv1?e#nPOe3F(PT0hTz6!ZOUFEcpu-ImQ$Dc}EZ6ksMt{S~32_Ww_}v4b$5PupX(H zLh4iTK%RIYODR4a@F)@|p4k<{4v|U#LhIUXN-y>kjx~|lN}fZBABoF!E7f@3m3>dY z(L0-{ckkhqtDCq+PofuNYA*`MM-iv-=xd)`VD3lrdhL~e1MuL!RepGf8uNJ}- zbN>zF@@v*uuCfO)7(8n8qg-hwmp@6iCx@&41tRntYw;*KD04q}!+7dPL7g5SosL&) zM$62xoOGIu5`@S-3;90?>QVz;A}-D1^2f-G8Vy}fwy5zw;!^l}8joB?P3EmKgdsz* zx$S~_MRN@9b#_hQgU|fm(`R=YtYgnm?(bwZInPYZq@3T%=CUd` zkhz*R8QK!)16?e!A4>LL8Bl73cC$4>`-g5+aCzNh*xpwPAToTJ$c z6!{MT?-G~evw5L%Q}8(&pP}BW&H^o;Es?Ui@2B5{6ZP#6CTa4q2X}2N2|;#`quksO zl3&Q2@9wAie8HrGYC2zYcI_v6Gl6}ivy*0Caun|1N&xm*9Mc~t1ZDKL%x9TqVDP-X30yz zq(J_Q__lSMgGruh7EJ2Pufq4a?iXmdAtR)%H{aiM+Z^hBwf{|;V-#r{;h{OzL|N%b zPBlqpeDnrev)>vggUEolxn}ZLk@XwlHO1dkzhS*)xjByG?~&f@&Duv{y1)eL*C{`k+$`lIyA^AQQk0Ky+S3UW|pa|UQz(Vu1!=T<_2c5G3N*5 zRoUX8c?KS{J=Ks%u>qRSjpeV@yw2t4%k~Dy5vKHyT>e9{?>EdXox)YmkbOUAd}$)r zJzZ9M4+p*>TV8+s4PDMfxRRksknvpq-)t-_M*A_>yf?_e?e`2E2VEe z*S6nW-3*kU;RbcSN5b(LDyw!=8qu~@!c#(N4ob^K+Mki;yVwrC$KQeW{4MnNLVLcA z{{Fi?e>492o8BkfoA8r(a~`iP~E)3uG$ zl383`R&uhU&egvb>^uZZha~CK)<$7M5jSHUc$&){mAvQvnByO}iyyZ;KW_IsK4;@; zsm6A!s@kzyQ?RgT)lt$R*>TbX%^u#>8a^T4Nl6CS8{=@ zp3;SiaDV2six0Isr=a@H>{Y2{>FsFOYR%DA82J0CD)2`KF(bYw(s#&rALUcB+NCk~ z-QVuKza3lWx{`?;f;vxXKR&75cVBzgwg=e5A$?q$J0;f#@3@-i-g3!v@x*e*s}Vmr z>C;S!Y2}FfLtksK(U8*n8PviM1OqL|>pzTr1nPH=Xh$5a@HOxIMO>KKJwH`}eT>y0 zn1tn+1#(Q^zO6l2PTVz9mlHEh~ zjzt76vATCO0YK1~kp z-2BcH^U+SzqL@Vy7sWAWaVj@t?igyTs{cJ%-QqG`H|>NyCOnM%&Qyb(EvAwIe7fGL zWDDt|Lu(ch;H8n?HD~iF#q2m>?ukxV?RPXHt7?B$mxH*8%?V}Jb*KUBWHZB`wLX*v zpoCzWlqg1{Y%9P}m_0yAC)Bc)YWc~E11F@~-r=up@T0zWDX*{MbdHOQ|9HzCelB6} zWDU$vZSGA?84ANtu(QYPkIO_*MzhD7*zC1>J~u0ViHjJY=i@}tR)g?%cC}eO+}2Pt z+#nQg__(Y<_l4YcKd*gR>who0?WOhg?)5k?>McsdMTzxwo-!S-V3z6EsZ^feMRkH- z9e>sloLkqbI$=`v_sRN9#`f!ix=i1jRW8q$$;#s!(=93iM|AL=AIW}6^s2CXx5PrA zlH5t*%#PF4T?Oo|w^oP7F`LE_SM$V4sp18T>GUer`W8}b#H@(JXy>Y@$(Z*opyDIV zT~FB0PQV!EWyfUy#~7;Jt+KkD)p}fv6be0g7{jiqMH==Ml?>q1)m6#9ppT!8;b)W* z9>cQR#}KOlI~B^T>rhE!_)+-tXJdF=N(_x5z-SD6Dd~htR;M~t$vkJR+%I9>JzFhG zJ0Z+(57&!J?}FBr(3oY9Z=7X`6jIUYsZ456^$$Vt{*OV+Q0%-UdEn~GLV%>=RIM(b zOYOe4nu8!%y+r8vEp;nZ;uAwdc$kF;YBc z^Rk%AAI%x@(RPX|U|tr#NViC}D4p)?_3x(L;#KYZWy7oQmQf`4eBAUjJ7nfkh^sLW zPY4AC`K0&;!D6I~dP?^zkb)$hy1xkGJ)CVs^aI)hr$%d2mq(CznndDhGOc}9MMUa! zefn^+x7rB~dIpOlF0-b@Qfmydn&B&1G-bJ#4Ts499q3oYyHeEt={PZna7V`*6Rvqo zh@BT3Z&R5SB(qf2Cxc6*$hakYg4Bp2RsZo|ZwcIumkmc4E88$Z`EX>N!H(FIbzfN` zVH#gcH9V=Hm=zYC>L+PVG$=+8=LA_e`LGSS2q=N#F%6 zs%$A?mc}ekHm`nCvN`;u?Kqg*6~`#u=D~)f+f?EW0`G%vB$F3yj)}1G8(aTL9bz2 z<4RAepcM=#f%{IcP|3R4hM}a~NcG?i8F{Nbl#hT!;M}LN7AjqiGL}ie>nI?$u314V zQTgoh#pTP(*Ou3oZz*ps|GNBY@$%^6<-@ZxpVq={3x~n(4}vdi8xI?`3fp|$aM_yS zb~Vl|^tNeh=J!UfnPw|awA+hmg%MUZ8frETb9Lc)_Wr9_s6azJs^isI7;xqK2OQ+k z?Y;gZ(pip*ND;>49SzcdVgKBk%rumiq>;jOHDx_s;?+N?m28z4f_Uw$@}llJ#Zi-2 z1$L3UheV9kUfbePnKQwGkti2X%{$e_^Oz3*#&kISH6*sGF48jE9uImAwpEsz-bk#c z4OllDNYn7BbhSbBBhg6PKU()k2H5krjhFN80Q8<4$Vz>hds5qY$u>0Uh%mY) zN1y2N!g%1QS`d?4|LnX)$&0c=iVU4`{ACxg;}sap3f-0)CEw`H=@Ghk*_!z9YOY$N z!+NfwvQ^K{L)5d$LPp}mL?Jufk^x6J(A26ZQAS`3FK`Y|-ie(NEk!*BKC)UVgT*Q} zil00oDlnxjkk|CO{FJ|Uf18!1S?g2? zI3~$ASbDAx%Er}*o2+Y4p3A_2iHeV`yxz5wjFtGeV!OkvAPfp8-Fn$Gf3K6T%P*rtQRd4<}1>K9Lo3c2ux*?4@VhN}#uUH*7 z)^KZvu1Q@p!7|N0-*VPmeCNvIXjj*al9T$C#c{;aG&XbmNp&tro{&aEF-x2>(?vgy ztx3MB){&USON0|DFP3ViR-Us=wu;F|S>@G4p~n6ozQ+qQk2)=RW_6r7FAfnCyiQj} zTp&Zxju|2p9VO33Ouu%_yvaahQ%Xo{hTqLj`H|%+(5Su%dcQOuj<5W2<>9Ov{Yg8C zS?V>==1Ps*_}X4U8%Pya_e8GaBxH572^r#F!zFTAw0YSb=4E$UCeu>!MUWO2@OW_&8c^+bi7ctYU%7bM@_5Vian<4P`J9{OFq^cYp)BcQiFQdMVyFU3d#~^ zY9HwlSjD*f#<)q}AsTQ_s=!HYMqgkuHO@?uSP5=ylRF*X#+wUv(<(iW(~_5Ug3%o9^TYH18^3$-8ixaIkc20E{-T<_v+ajeAu~$&%CfgQS#%J#5AMO&9(80oZbY}ZcQ8UJBCU4t=+a7p} z6MK>S{L{p#p?-i@FJ?9MqN2Y|zmA(P#$)g$cUvy)EvY~9?}no^9tMR?r5Mica8!p< zv|Vppt{T_&Y^y4*3-8Kz$ibD@iqa6BkC(*lsi0Y(93_|+CY$vsiTImxZ8@(KewYj! z;3%2!Wlrg`09T!ksL$1EnfpMnSj8>bR28*v^7iyn-8`NL`w=&M1as3h7AcKfSRoz$ zJEo#hJBHwR_VN2t++OhZWkDH$UoiOlwrZpHOBGYx`V$DC@E$G6*xDkNKT^6RH%wYg z{u(43>XL5C#<%-OP!vN?z6pRP~&UY>&`{+qpc@n*vG_sE=l8oV!egy zULj*2_|Oz<3Re~ho?Vvxq3xpI@j`v+A8cpqUtel3wC;@9@^*)&vwf599#v0F=+_3N z|DA(vwVQg&w!DTbhB`qJfMN%|?3zoQbRzHGljH5j?Vs5PtfpwIDF&fvC*+NpmN#~O z-Y?h(Bue|ncc{9=F_4cZ@}~E{fe0Dvp4K*DI6j2tUUNSMY&3UAz-bap-W87*>`OM` z95=@1Odm})d#~x38qCb4ZO{v*H=qJqCLpG(%cO!b)~Zf(%50|7v%Mw>3HeGvLHTDXC zvSl>j1bywQ>z#wZg zfIoCPq3+6Dp=QLCxrUlI?k*eO{Vrq_5?-BvqAo|U$@aA;uO zVGgK1p#{Kiik(l+r~91V2zyK`hi&gS%G}OpF>^*&xK9OFigPJ`P{8S_DCve&KoOf7 z|KaFqxRT8!<^XcMrN|0=Pm-{+Y0O=8m)UAcv`w(&ZLoj8Cg+KShQ;?`0STnquoT&{ zt9p_l2_*T7s5z1L`&c${o;4+rFiTsyJrDwf96mNB(RkTZO!nkqW~=+3)k9)5XWCR4 z>--Fv?J|V$n#N{k`q^19WOLAoUq+j`E}E9uKEvHe|XVX)Ht!*shk-1an+ z{sDBI&Zg>J#K%=$>b_f6Iy?qPSIT}*P}hDV`@U)|=|Gry=qWm(T!_xPf!{81O#joe zhqb2>gb&bev`;nbKKT5>141_K-5JN!@R({ri?u?R0g2u1Ebtxhy zD7ds4djH{woQB>bQ4@1k;n4G+q?IJ@Z`l7W)o3^ED|FA%pU(8C0);kHdgkYZ+r24B zItF0EQsI!khjs3cZS$pdZctIc1J&4#>9(pTEQ=eTv)d|;6XccG zs@^i=b}aNOF==1M!-$YjV_zxhbXms~m?C4bmol!sQ&6O9==8uhb~jWom#qI8^}`4+ zeh05QdkWr?a={gXmVCz>^QyaHeZjM+Ft>W3c$t{JE+4BTn@pz9x)P!xN|f zSHY%OwRz_Sivnc@h1GE#JBK*SOtV5$vo8*}h3RT~CG=0+NxW z9pdwUpkwFWl3pK@biM%Bi{Py|EXvX&h!+Ne^uYNrQp`uOma?+RsLggiG-7{-{Ag3j z{dz1B>i&uPKm!bb_vi)esc2^f6e>^$g>vzA7(@sU>>!#pN!gS9N?`ra#g1*|rWLE_ z7i-8ednI_(+^R8~RAioolj%EeEzHWB=dO1&UpUho<2s^XmDI=B#jaHtmX$Bl`Bmnw zYh{`xrS(fnFC>>bmJOX>+}+~po?$5@EA9lWg!xy4?CYJ9;3Ojj1SdrDmpg%mYW!R^ zXL;01i?o))u_~c3UE>LvfA2@Z)UL;13Mzz#-l}0wQoX`5^kCz;#VWqF+HB7+QZJ0l!$Kp}NLSNf2LCB2+%ZkX)y{ZXf%8P$BxKnY1#u8yXI1hp zRfJz9gT)TZ2H2aLTOBlByLZ!Tm&d8oP79rz?=k7Oh!3 zI?0Nec)Bb}%L2s5>yQyqx3)v&?t>TT8p%I`>g1e_*69)l^P1;tx}TQx`xeA(#e`^jq~`fnp2-P#7`P=VXmdYb_Ggf zY5Ya2T2A_y{VQQv%8^}Fsl_OryabM7)t7?}HcdEt_z~;d>+9>6Kocb0DW-Vw1V&?y8rbMaW!w^sqDeN-msY(HAVR3(aA>c7>h=M-&p~!*970 z|Ch=7d#{B1f$iLdW^dT(%&sAyvlUdaSFuLfI~i`Lg*e)BHtb@}gbE&1Gim%nzGV55`ylr5 zFRQUF7t2$4RkX^I`#-@&`)YNY^2*D6ztW5xU62KeHfgeW4#OP zB_4$>&ikDGB^%;Wu6fAr_P&;#HtW9f*m8M!T)D!zdRMu=98oTrg$OV`w~IZ$Yqd%| zzQdzQB+A(gBKHkqsK%=vRd22H_q*&d?uTTy7>|nmcGnsex~qPRV?H9s!-wvvU2HWW zs&m0A8%J${F;`|=p#JJEUTu3$UH%IcZP|htGYPN_*%cmTV3_+0S+z=5l1Iic-P-H8 z3HX`M57vBi{x>+Siw!meBg;?su? zOHZ9}-fAmSm#29QHhA^n@>8`OXLV|Ic`Q7%teLW8RHT)hv*hlxvcy&0*hAWE>hkYA z1ynt)b?)j&vqLv{j2>G5j33C-Ub;Ow>^kMx0Ww(XE}_V{nuAA?)uE{;Cn3r0iC%<+ zzmRz=g?7f(0(c*h6Q-;*{*2^&R878udD8JR**sq+TzGTk_VZB`1wWHNqr!V^}J5TW5rhR**6zLE|LKL#DQaz;;V_2u3 zPX75@C;z3>hp_#Aocm9s`K)@&u8(-O1v;IqSoXq*6 ze{xwYOpA-*JWOMRcV@`+FO%UpBYrqsie6uDU#ya1qdQ;nKh3eni5Ci=_hahL9Qpv% zvwy;!XPvfYOOddkG(MVd%3Qy)08iPKHhh||1|DPIjnL}&S+G=_4(pLdT2;>nSC+_} zEBvg0@EKjQl1D*gRM=-Reajv}S*rQatAxQ#R;q0#HmCNa{Ms+sNZC@qK{NPxDAL() z{DP(~K2>t!hWtZ|#Yn{$V&b|^V_5EUny;XfXA6c@M*75di@}O>Tbi~xJ4(6 z4yX6q2t3r^QGO6svh8Q(RfBMzn{X9!zo4!Yp!~soglKi%@PTxydrG9~s_&S>t8)J2 zqwkzZLG9Ir<=4i`KHT>=24wvczy^^ae-XscGndPH11aZy9~;3J&s8SFBN@Igea;AR?* z&Y1w`O6A$}tr#hfpFJ!6J;7GeU!1?LpuZ9h6COSDEs6~B7DgFlJPn(RI+CmVC6#{T|VGYp^_JgtI2q16!>fa3>!ym}-4 zQyz=tYoD)GpNp(}1}@BY^5i}9TFjP~b6S^EZv6F+3t!i;T|U>l5ooCt&%$+hm>rJ} zhqe>CgdfCKpKZJlv!&4+S@~mf!=^xreReiZ{1)ZR(k32u9f@O6L|dI|kqTyT?A_4j z)zkc4ad?$R&NfkAqxSfped3>e&OiJ7TT?=^26orTQnG#4U&>uHo+1o? z5REy6*A>_c_z*`#d9N4-AJQm^RwgZH>+z4tTEChve}tIHHU zwU*sU7$4BKteski&@Jp8!q_*Snm`RG`3w!vwO@jP{vW~a-XL7u>HVc|2@2;==cT_& z_BH*5f|LIaAXHfMNM9F2GU{dMdz-JwHs<@_H4{*8e8`9MJbI}f{f@(6cz;87)?^Re zIMr7r)Yn>Enh06*$dYSP&p~!UX0wxopWW{>-S4w$p5z|TF0nfhZ-e9SYS;{wtw43) zoz*i|tS`P+l-T5WW&QbcFbusD*Q&ISKVjn7Z)knMOVs1}yT$}hXRa_OHx^Cat6A|9 zxL)>yjaxNVIj58yY(7zsRY=P$@kFZ}d*^kC2$WkDSEjAYN;;SEg&s4N4CAMR=8OoT zsQ26xLN&M--gR8%<*~{U7xblzI<&3~Zr+DPPBjyn_6EU<;m!vV3d3h!Wc;5@z9w5Z#9Az{?L+aZ^RYdgLxub8Jtn5T2tfra`F z=PMz4-uxfwS$!KlcMv_{k?6)e3o*ns=`350!~YOI=l_ULxDDU`&)8z_x!(<9*GnAJ zh#ARNkU|&coSH&hvIxHJG67- zp`Cre^l^MrPh?|bPg2k6#;ILnX3yY=gO8*UzZ0`b-Vx%^YKkt6?v}VT=J5deGqoIbLtZSF0)o4O~=hb@I#$WABigJyXJ-;C?x$3(r zp-QI7byRJvs*2OuIQTr5ya*=+)px-v^T^r&Z%B_#>D?6i9iI<-SBY7ZR0ea-xN&i% zBTt1gvSf+5GQkP2(3@|~^H(ymV%emfnW@;o$hh1psRm=8tmFj^^yonY1kdf6bfsh+ zP*U44x6O__GjJ_7ZD+E%$~qc5@tTvGl0Rw&rJ6MV2_|qy|C%r&NyNzdS8F6;2ON?v zb0>B+HQ9G=jNMr)*do!!`l^lka~k*aKgZ?MN`3WxbGWaXWhKvs`)b66uy6dYDbwuO zWA00Vb9}sIWa^`;(bH*+>uuCGg{JC+@vMko`D^=x96Fk(;&5n@BiIxIG%ue zwd5=I;D6SQW1vS>*hNmqzBs&>Mj(H)Lzb~G(p^RvX7|Yenp-9UFWe zjV)d<*b^=Hu;Lxws2=I_y+XUmQsENgpwg?C4N1F1*btSZMLD>ik)ro##s`;cbV3mGRy4BEB58)<;z0tyxc$6@nBYm>xZrg1w~ z;}&kwG&Yw~m()0H23{Ryw;QhQvrSk-?gi%2~s{&Yp%GH}rwUZkLZop8J@nD#U`XH?}+Btn0n4iIMW z3F8ol+`Hae*lWnf=^IK6NI8Wq0ronT%}xRz97SYdq5}Fafz!6=Svd*5xQzHI?vPY&AP<1D9IGORYD< z7*tUXdqK+oy4CEI51eZiFW<^vO*sgwC|mugho2|r85?jj?*xvroDleTRITkgf=J6< zQD1)95s@fF_27i-@cv0`xrFZ{)YmfbajV$ZdNY#7QMv29X+J=$mLsWA3L3lkSTiotOi z#_=>r-i`Rrvk?*QFMfKVvp42Kb985Oa$x$cEOB=$!IzDr{|)2tQt|Dd;?7p2@JVNS z@gOv@9{>?oE%6z|HA`HVK8Nd0LA*-|gJGQX-bfYRogRb?q2v>n+?LilgslmUur8ot zsnp0tDZ-<^ms>H!ub{Pu#D-g)o=EvP=J&mFdmStGN2u^bE!{H#$*55Zn0marRjh7x zRzu8rm_T(@z0@h)Mza@Ie-^a8>6s*`4y=LrPyc~~FM~sn&fHv(s=CVE0~ zG;Z&!StKRVIy6q`WA@#}qPdOXe3Nsh2DgP}In%pWTgG4Dx&g+zdeFm+6&ZJg$H`Q%QY&ECLbUkz? zrf+45A$la)I%Wf8YZmbg%u8QiXY(bS%D2rSue~zdcmA0Wt-R_wbp)NW zU9wGHdBu{!XIU2Ft+=7xh@Xl2E3UWjc0t|2A&$NSZy~F#j;ID(6u;Qrc12L97U1nr zscjXPT44C_sQDxz!KSSe9PoUt+Tf_AnEy5nKPMDf59eVW9Q%r@^Z;kbMiwgn&lW+Q zX>&y;CpNogC0iq-8~51^>5+P~X4L6;J^>C6boR%!<1h@~VY?;P>C3WFn zTkwkdz~5TLzqN$K4e?e1Wl6lXXL=%=ApyP%z#j*Ww1`K;fZZ^<7rxzsfV(y}g+N$$ zi|;@Sre-HVuZmqQH|6D|5I%}Ir8w zky;A)@S@XFVRE)qvAk>_yg#y3yuBfI4kkE+J#D?;mitqp1XI=anA+yHz;iVeq`If# z1R`seN^RTJVm*Z|YD1PGT~5y?9ItN?>s$P;9nSg|wuz!l`1=+!(NmM{FfB)qVnH2CMCARt1x}uZ(kQMv7e0IZ?8&&VeUB{D z#wWODMQ7Tqk;#ptCum0XegN+HFj%)-P$Uag6AF^yH_S#523R*>twRKGEuJ5f5bG&f zP-GgcT(a)RJHT5;+a1Rjw21T2{ts1n!9`Z`E-p=c*ZmIlIkaH(sTon=@Q$$D-6{|G z{;zGhQ)dF}$76Y>3tJ`&)$JZG7zWzIxNT!HyW19FX?Ad3y}yzpr*pCHXm zXfD{+md2@}s7hxl?8^2zyQ*9cTm{oqo(mUD%&ijGpmH=p72Zp1Jhy$ExeazJ{L~#VNyCA<+NhOrC@SHj_Zm!wvb?bC%2oOj}CmhUHoJ_ zP3>@8qC(0G&FvWp>|qJ=FMxb(;PdU`-y}#x^7$@U(Yswx8$BGGK_Kj}+kNkD$J{;z z&;{br?Kk`Ufe=2L+ccNQEpD|tA>>0w|jW`71KF~=mvw_^-5A4`3Hs0O`(IJ{4gh{^f66DK(Trse1ySV9AAIK^; zpcBpqn4Cb^E8Bf9QXgyqXoXmNs}HWdiEQjS&<8SEN;Sp^%IPd3NKo?$)GhVR5kD7k z;l(8+#GJdE!%GW-l(4B(5W6WDsnM2}3GAPQ-dBQJs|PB#i_60VV*UC@sA8!h3GAc< z_c-8c23BqtO<_22RmCD|M-Mwr5bTNVzWLOSazF}V(XDnI389ncQ#)kNN4FE>=|k;s z{$_iQEp--8t>L-R;=SQUz>9Ow%p~TNa#N8zbYSXs@qxi6l4lFvI?)wG zn(o?;$1!_2wwXX#%66Zg+B$K&+4ZG3;#OP#6slTIu9UL8;WTCncACanQ1Pm@tLLku z8`Fx_eBDP7c&Rg^>#`sb&A}&C0Q-Qz>K4@9j~g(ij5wuk8Ag2Eh5T?Qma zcBL79OS2373KAJZj>#AAXG4kpusmy-&wgwYG>rnAO(iS7k2E{qZ$7*A@9YPH zl%$1h&-!HcZ$RqK-Cz%fLC-dehnk(A0rYe}ox!t1&4LE=r5|v;1vDcDf^1Rzlz&Zvr+(v^0mrAn8m$xutsLa4PSR^IG@T zpmRN%#AZs=-_75}kH86{a&!dFKWwCjIxCwYwsI*O@(v47+9SbkI)7z|rEz{G`+^Yq zmVvAC23~F!U%tJOXDH9=Qvj%Jv9mJlm!1c;Aao8X3;#@h)cmnFZ)2sd<>a$ z2G%xI%$ovk^Qef*pPb9yJf>(nl*dY`q3W-bShrMWCd$kmc)D5q{a_iqbs)={ zwr6?*>yRKG1jNGwPc@4(!VuLT1q~DSq$aT4QvPJ*|7zfgX7M+J`F{!8p5K$5z*?pJ zUm*XHfybJ~qQU&`VCnEQ_NJ7Zf!xA@hnvOu;m(HGb5M@esY3h}!Dy?tR0yS(!ul$O z#gvvCEWE4P*sS&_t35uQ&sEZ`%% zw;(u?lHlKy;FY$~rIE>azF@Ql31{!&m#|?CtrLr+4*R>;ye(}& z-7KE*-ZUUQMmgb0k-#32;En?>ec-xRycmYVI>G+x#r(CgnFPU3czr!yF#C6a%n<+L zy}9P+hS1SELA>7oY|z=`MVsr0CO*vTl|M z%j;7+Ne6=Mncm@8(my2vJI9;;EZah2r0x`()09f4B23>i;bbO8~3S2Yl=@~3#ltQwC5&^Mz7OI zioOU$~IKKX?H9r5`WX?}S)dM9z) zlZw1NFRy8Dwxk5&=9n$xlZ%u0B1Bw@j6FoN!lfD|q^vx0X2psn^HwdL(|k-_wX3T6 zO*Wp!2${`Icz)8AKdSV|oIVAvs*E4QH@8Z+$Qzfl(P4r{d!1vvpKwf1G{BQ6UFJ`b zyN)EgN@ZhsSGU1^RpuF=nm=j`IjzMLW+7$8g3cB2TQYG*_YY7W2j~pEWK5hOud1J+ zTO_l-cLt8l6+^wv;JYeoMnuiN;cQ5_z9C*`j2GHQXb}VRS>#iJ8Z#k6LN2fB&8w<< zt4@>HE9l{Jd^n(Fk&=j*?GC6t8rDZ2;QGvK>gV2djr=XDR-AT49$qXBwcT?Y5a zI8r>Y`l3(C4=*h>&diNEnpgNQ&pHmAbw!SMY?X5+jKS`vwi$j8ID1&j{u##lPml8} z!g`!41R8>J9X6DF1x-73<|uPdvPDf-hYlOk?us)z?p~HPbxuY=aZE*qJ;Jmn zuTOrGJ8FVpZGrzMKLva0xtDOXY;2BTd%_g&@i;p?aI0tA!X(Rt+20o=vK`_49UkW% z4|{_$Q=JMGnZ-^x=%yG%QCjIGsr6gKuvL; zM|<*#beU-PIJbIO4Z&68E_|JGjZznT1yR304bmOK2e$GkfhX;d4F3b(eNcuAXp)=;A4_BJ9&_oumSu%W%knrM^so#n z*?%tByZESYgVTK)B`U^ygdD!tq84U%s4aS2w&1nqnHm;Npx(*sD`Ga1IeE0&7pKbD zlhg`xYQ#!TgAhSDcjk(_+GL|vN(cvj`7gcVB?6I#AaMH z@~UU)7iI9hxB$nc?LwH2#;@6s5Us~kJz}cIInr}ob=L72yGjI9o<*d944E&%WA2f6 z?L>_6&Yoy&w$VegZ?GUOYS=2odBix6bC~Bkch=Dl&vWRm9r6bh4=dMkON_~<-(i=- zfOmRCt;czX=d3f4ot5yPz}a1t-y~=0L~r8qF`B^mWq}9Sxo`=EN4(zTR7f;^$3CPo zkjkHhbAM_Qzi)EhXhOx#yV)_yrOmf_=e6Q@eJ) z8vcj4w|^GFE+!m)Y~H(c$&hS+E*R2IU!7Ol`KB(LJd|AG2-f8S%3~_OI0Bmy2LKvR zF)>{ECr#qVP0oKbU00t)sI?tbdG}YrH-~bF9SGewB-^B@rt*@vW#4E|*RoxqqJ46) zr^$J|sqzGKP_YpgPN0wf(nL(|h`{4ka45qOJnaEmBM=w~>zacInX;hry>*B|T%Q(g z{96S3?=T@^llWGXQ*1hmQ;a&oSBYM=>PPi{W!4)~yATh-ywE^r`ZCvHJm0$9uHnn= zW!8+?Y(sX|=z`Hj_ILzB3M8jl5yb7l5oRI06^^Fktxe$l)~4&qvku!aHG7V5Gc)BL z-_}(5@3W4*xY@0Bx|=G`vS%nW|1)^}#AXWSWwB$VDDlTQbgsJ&cpEd>AEc6-n?#F* zQp~?_6I%6w)L)_Y@=@zJ_7pW3jTkF`Sz9{1oS%i*#^v_qpt?hAPslFFF2Wjk_%U4C zdYWjK^skCPfZ*f*)#R*dA|5813nZEsgnO#8$yrH+J1v;*EKlkyiNir|4pFVT7VLeG zdhP8{ufabH4U)3*FJmr7u#3+5Lq|ct*h0Z1tfsru5h8xPtXM3VIu|ofHEpPY-ABZ; z;wH0csPsRa=goQZ_yTj`nEu_dQ)gLC!#6(J#A{rIW38s74%HY-mt&Hv>#=EtIrB|= zvk8~z6Ci}Gg;UI?yWIbWxAzZd>N@|&Z*D>o!d3a9;ioM`fq=RpIt6T3KnDS|Rjl}9 zx_qnYf62o8 z85w(60Q^Vt0L4D9Oy9w%VKqm=xa?v?9IKF^4b3~1+UkvL6(+Y{a9m`skx8qcSB*K> z&0`O7cvIM~2^8lnpP%vFPAX*J-YI33W-!kOE2mp9Pfh_J{Aaj)7(Yo<7V+~l$Cd0A z!sOghCdn=cq!XiBy}lM9s+AoeRj{9sRD2F^_1hM=zTjfPq z?4?uiMuWwaG|EF7RUuS##7{>PDgr9TRKy#-kL*@D=aQnZEx#B_!%qjmDjCIYb(hjo zGC0-8m7LR@x%H5AXaoA!TfE0xgljDq91BX zNHL1F-v4ws$LUL+g~Kz&ZjnehRC(%fi&tn7x>_y>-Rwq!gTAuo4PUl5#g)(v2M>zD zN$`zwwNr6gDDEeIU;p51E4di;3$}_tsNB{9X1ioSA?#_v+^ZnvSyA}Km2_z=vLVH( z_74q=F;0@*_?aGDNg;m#k-_Mr~+~) z*;JAR*Gs5-N=q1>^N|nU2HJJiFJQ`O+tr;gRqhYMAb1lwmI0OL*(rWhR=0TbT7=3L zEUS*iY%GB@Ct&-NA90l(XC29l7&$j@_QZ5=L2K;-Hj9*T&VT@@W%jN%)$Fa{md?U! z#-PQQzhDx;PGleQgDr0HPH7Q-*+QmC7!4F z%dth5X?B!U)*Ig<6t=K;$f|`sDbNpbdW-j=7NJOl_;pXRZ@}A;*V659qI#D20KXU& z$=)UG3Px{ci#M!Am?`G{F+-}^_X$2CgJxb4XHJZ(Iz~>*!Qk#q`q+yRbkBRf z+F5M;o8@Zl^Nd+ZX(O0oToZ+nx!N(l=6;mnxXdra za$>)7*s39i!+wd{OJ5-bZi!MXNzQroF6;E?{?zF`=oGFxNguzjtR{@-G(k3R4i9CK z+AOk`2dwdu%TtS@o976>esnF{z=Iw!by&!bE@iihFWBm|rHl_O^i~P7_bsPz)>(C( zts-p!0PA@2-yBaIAN4#2?;oU`5eiTXe*qdx=xtwe$DF9$+|f?JIlLQ6BSGipCU&DA z<||I2*9o?Kh1ic|FF~fkheh}C88Y@+k`3FL_hqN>-^d5S6Tq2QggY5{^^4HKvEPa) z-HK>7kCb<;i0S4d++K!Mq#`hyqu5{iYg*?N_5uRDLqncpUib@hxN)}d490JbPBHntmwf2e0UdK6ec@mb9!w~ z!RB=Hk?eP5sMW0zwmaD$5hOe1!mCbp0(lhA1h7SGaEh|4E_w457u~O5BS<0_+D7Mt zhesy%NB+trfy2vh$g5iPgiNKf>g}x@Wf)whw#$W;MvG@L6p&1U^$s zf*xtCh9HMQVKoE@8=Y2z(rQrI)~#ZIw}w$Db?_5O4>TB;Weva zd#VAh6U2H}IpO9+vOTH)TwcFJ5pCx!Ax&IdxwD?D_uvXoN18+OZU|-Vd_xmoTT_!h zVYO-Ml|>tL=!S-0I`QQ|Dh?htGE%O*z*>3JdK0_ExxO=o9QBbR4#c7lZnMyBSkFF* zlFw4&p;i0J^;km_ujk~}3vFWH6@RStp!r*nn!w&lG3IfxhQ6c9uvJH5$H zA=&8`e!*@ehy*=g;A*NZFU){>_k?-VspoC znz-ZrKObm7#LWUE=p1JHWFpfRlMniznpfnm(ZbPWiFv4gUX*7&-7)Bcn zV~hr^(Gbpe%f-?WZbRg7>1fBEBW^>K!w_RMj5Qh_G8!J{k4V{K-G;c~Y~vhz-fL?6Fd7p1ccg53w;^db+XTm+Ke-Lb4#PyFVUp4CBctKR{GX(3DQ?5$;cQbJ zdwSf4REJ@z(eM+aVVcn}o$rydrMV61!`Wsy_H?)n84klEM#G~mQuy{Dz&mDXI;5ICA7?v6h%Z!F! z7!AMV{~%>6b{k5Dvn_Y*+2=MG9fqfjhEk)U%xGA_?~}5XyA2gmHn(A=!|=2@P;ugY zbFRT07{H7)=jNFMl`$A;`Q|{CIk$jIGP%||a_5-%b&lM}O|Et3+}V!YC!Vj1?Hu9w zbLQ%He(%s)cfR3ze%{`z>!4Y4JwM-_Ul9F|f^&{Q|MZK6kz&Dcqe~XibU`lb&?vF7P)ccVWG2tu=R%BX@BgThHIUX zdpTsx+iOBI^7nFpWf*Rw*e=pclt*DS)|F@etBmhm+l{{Ttm`)9^C#Exz3WaJ4Bdu; z-o>6vNSS@XFvoL#ou_x*1;gXrh9`O}#Lsgt80JZzyAAU%7z%A0>wDK)4NrC(7Swx4 zBf1SmR>Q(G(XzcZG%jy%JxI5}nw#&=EjV-hPdq-N(t6Co1*pzSMo)nb&Z>FOI)syC&Z-@pVx*1|qRKw0CaCdus$);PG0unX3>Y2aO~D;_RgNwtkT zFeQfRQaHSsEK4}q*=i=xm^d~&@gZH}!;3eWXFg@kU11HNv`IgixP*A0a>4k|!3X1$ zDB@n*m=VDCz1cXRU|z45A+2Y~hYUzPeiFKujfbvH{H(EwRwANIATz?vKhw>ZU*K2H z{vTv%KEA(+uAWA<9-@_#sH1pJp+0S*d!|y~;CU(({+K%GfkTXlpyL^&At>bLpR&ab zOh!p%E-6|47`620c*{9W-g-ztidh8gv*a}gQOo(P{ZX`X0+o=iF0;_eFj>+2V}I?a z;!N$qo0DTU?@%QER@FLz*75os%4ECs*pMr*GxCBr!m%RCy&{^~!d$7gqFqdr*krL$ zxPLf-R`%Qi7qqq}>PKe&1$dspT_Urw8i5Ov#=};BZ1jR0+^eQP%;Yg!Anl--#Y(uc zxAc7HV=9JAQ9KQ{RyVergydnziXXY>y-QIAA z_sPNceEPWR`M?2nK1V7)L$%I$+;O}CcPsmn=^k97qOMj_SI-MlT}msdtJ+Q#9f{ZyY=1sJg{P)O9v|?Eo=)lXlCI#QtapIV;3XAhTX{ zlA2?o*yJ5Zx>x&u9?MIWP`>$3bbY3W_5G(jbC|<98^EtoAbxd?55z~nmjsM7{ys4z zbd;?aU*>-~v-+wJ|L0z+%K62==>e&i>T(wRn>^BB-jy@^LDa-<`Zu^8M#!T7NU5_q z)Bpd#yj^V)2@4a;`}6LHqjIcr@xP|NUc-#QF|F=8m~6~Zb}H$6TO9U4d)yav43je& z{bA-`Huna{Fi|dcgahe4Py79(%48Mn#)kBHc_oW0*LWX+=Y4R$-eUNLFjx}VWsdX3 zA*P*UsO-$*3iiwZ1${y$qS%-f%gIb-vACCvB(?3UO*LbSU+nI=(`cLSQrW_}MDG(0 zM@guoWK0_zh=!R}cjeC$2U&6j@VJXtHxJq^dr?+8GT=(S_03E5b~7hS3#r$e>!+COIY;djF3$AEXJuz>3-oj(Ki&d65%L@DY%-9>v^eL6YtHOjo zEvOvqV+2rx(jh1v{QI8zgCX_ykov}~z5BEF+C7b9nNu={SBA_DJzx2#hF|XFi*I~T z)>Kwpe3L2*feTsOyIuD+EZ*4~5CTEDJa?b6cXILXJu7z|SlE`^aYGPp2>geh`r{$> zhe80}CzZAS*3T}RP&p96jpeM^r^<^drZ1KKWT<3J=+7`A3j9}Ec`xFPK z6sXaokH`?F2liacDBh6^7F6A|HqolE)w62IqT6gWx>^rAoyY?4u~B)r74Q~B95wZBNbC#j<)-&3ddofb z=c3!qy?WdMPZOw(EXU@Rd_iBaRlY5ht5~B1`Y=GhEnHH0_Yz!`z-8GzTo4-6bi-1q zRnwKNf)Nt01yUIg%CwL&EhwV|Iutb*%2Exx(tvuv!-l^4dvW@eW+D z3!e$>2{PlLF=x72JB8gWq^!Q_QeP6N^&t$sL!H<(v9eacEjIwANq~9*$U*?s0}wjP z0Ufzil9UrpQJotWo*3E5^_Cnxq3SGOKZEYs1E)Y}dk+L*-q~+VJi$a+I#BCLQsR=p zbv&xM9aUM0DrBhQVX2CfsA4s#V$CouqDX?UN?-+oZS_H)Ymv>?CT|PNo4I(teVgOR zcx{rhtxfp35Nqa7LcGyr?j4_QZ|A%}e#7!6sr5ohkhMg^x(OhgaH(UC=Jv|U`Tlxk zQoSFb-a=CElf(7iejVAN*ms5e;*Pz|1(_@5N?-hBo1$$rqiLJf_NuF`?X5hGh@>KNhH`N}Wt(q&Tv8N3^?<(`WVGOcE=>u$U-7$XWy_cfMkh4$Y z-P3M_)^X9sp{u_$B5!?DaM6Kp%C|!=%X?+#1GIQ{m=>!vS86MR{j~U_gx5&mHHzRB zGE9pDBq8U0-(*@i?+8h*P2u)(Hij9B=u}@lCV}}Q?%fv1>rL9b|kSn(udrxW7{n)6>4+Oc+0NjcCIp|eXnI@r;=+p*m$}1 z@W8}~)z}jb#oDz9AZK4z$xljUGtwfEa06|sYSIo{&b0yF9%oDNp5yHyR!4wcc1d+k z1Gk!_2Yy4cK+ClU;Ra#w%tI5+VAH<$E~8-N5Ymc!#T7^85#HaIl_bB}u@2*>j|a{E zoA=M*XGj8BsZ0LI!`|R3p*ZX2ZE9_vtX>yl)d$2TW;Ld&t$KN*n^x+n%HQ#N6}wD= z_cGvh5_p{i9(Fl)5lH}`j|d=4%N*Q&xf<6;=5)H?lOSk)^rM}s{noV3R))4k_XgTD zy)g&cJ$6rTd1o$`A$vL33P+!bYzrYA1bEZ@@JTnSu=;qrlf zffT%Qu+oTL2te6jscaa^K1<53Mp^&*q#;R47+G?NK5LP4N{gZzTF26UT)|7ct||5t zQ~h9~o!%ZXtV11t7Zd@G&1A%O6!T@Zbk8`7;abz;%9hZu7W#T6lMppBA)^3Z>}7yg z_QFkOWm{0uU*RJM5f`IYwWh@;v`=DsThoH8228cVFi+7m+RidBkOSF3P1H@a4o)yS zzc3&FoH@8p-;IURdh|8|(B0<>`UV_FzkyRY-m(csE!s=pZVX}{;TfWEYF8@*{VKh%+Q$PK7qplULSiemUcqu$OPS#qU$oa zF_Kg=*%^Ev~!~=Xsr=p{Go>qZ1+m25}z!st#Icv7(e=oKvLN`=s)Jz_<~uB(0)dwpIU-IODD54^@3jN|Zk=mYZA!YLK>C z%O{IA`O=ne@OKq%r)e&{4dk1cqw zU2NgXhw#z7@?rn@tvvR6)%)a2Vqw)Sh<3^2ibC;2M#Jbg93OawKW0cDnQyH)vv9!^ z1O4q=kzu8Y)Y6=oQD3i!wUb%$KoW@_f+TS;AU*i|>3*1zxUsocM*7x})Z}>6_k+qQ z%w8_mN|U}cukd3ee7FOEi|w)pD;@?s_W{7yY0ANuz&+(8W-07@*mI)rlqS;+7z%e^ z7xDid7_o1K_ja-$k=4piGvVY;_Ur@iY&hAdSoiBte+MkvhFD%vbqM~??~P^qhQn5p zVq@}$N3!_(%q?WWlQd&&4^AJOW6wv!?<_?s04^-m;occD+u>!{Yc_m3QOPJBi4faS z(PgEtgcPhVEBX@F5mC;qWP2g=pt5zR-=KUW!MNnDow(pHGSKW>r14C0{Iwe_zq3t^ znCI;%r<>1V#g#sY!%5qmNA=knUfO91WM3wg3IDZ|eUg+z+u)m|8?lTb)o$#J zXK#__b(nX?EV}kzJH71Ad$t!hNrK4BP}IIDk?d75qkc&GQNo%d`t{z4L}u0u0J2yaR#q=kh$+i?1<{?M0TUBt8{rUxaM7dk(@q5KCS zRE_nkc(adn+f40dC=Nq0P;|9Nu_-$p-`}s>HnA>}ix;w>c^Uui4RS^=9k@ZvI$#jo zd!y%lALZ=3p&YDSDiE>&Hv)O?(WB{@e4RdpL98@$sDLSCZCFACNfCHs?|kclYm z__|Eg)zRE<(wxTY{wZ3hmYrS35ki65C+t@S$yiGOL1XIa67zF@IDW zx$yzKVSWvl&;)vT0NX)Yx(xj4D)>7U&sY$Cp?<7qS6rY^)n!a$YwjpZA~(I^y&bsk zGI26H#6uO~mg%C3@o7>D?j|+tDgQh#p|17r;708-uovwx{aXZZWUjG4A$7qT;Mfk~ z*besZ1n-<7A65CM9WgP&pKxf1`4ux_bswUiu%9*}u`DV@@a~9TeiQl_$G>CWwS%K- zPGiRrFwhtg4(}lPW2Xol1jQkTY*ccL@A(!`^r>W!gX_U#DV@$|uA58F*Xv5p-lD&5_|yH)9v^Ri%FHt4In z_3_Rfr*`h>*tz48U2Lwj6o~7~_8qp+8oS1o9se282FxZ(9;nx>i|Ok`q)B6x*%(7; z0_WV{Kmk-2jZd51@effw-;!~#o9^ZjIf{LYRP0};#4o__4e||lIQkUJHnTC>fB!~o zmb5PgakIVw)NQ_?CnRPueii!AwzB;t+ z^ie(BUCK)%pekRKp+fTJ{ez*Db2L@=3Bb>N$Ft<^mF?{FBEmEb@v+k2>`7^@vhKtv zGcWV>ZgU^iJ43O7MQII~EVy%-B+qymkP;*IAddy^myro>2ug$D_A`o`T$c`A7bpaE zXW}pf^Vkt0d59c#-iXF*FN5s}>Pogy{8|(oT~HD{C)0F*t^d=y`W-i{Ik-a2vgXjH z*VdhMg;;YGCh{@BWO|afWp(FJ)*NMbFXzsYJ91QyY((e~PcigIx_f)^(2=kMg!l}~ zL02>kg3Cfj^b%gqW|&F4WBL*z&}p%d`(%*zk_}P}Jr*Fw|JZ)NA8{B3;o}>rdUQYf zT6!;S7=9mo3BiqIrPZRN0Hnhd@nv7>OQJZ^pMNka1ZN1oJ1g@&0t;T)tEK%lDa)0$ z+O&3YoMo~zB4m>MMa_zXW7&lSp^k5xz27$bPcQSy7s*Q-5WY(eSIgv+pKWe$b4y2tGeK<>eS_C@8xFU^JX_+%XX3ZwR%>!_9E3C2ZtH7D=YqM zGT0|G%G?B;nGySgq#%+IBqSI?j5@mPg$0($nyj6n-9w&(iM!!@7wmQvfJWKOt0R2R3zvN|#mmuar# zvk_v;4>f!LyO~&2Ll`nfYB}NuD9BUwAARt|3~iTw(nE{m;7hKg8MZ?IWgZyS@OE?U zOQxDENbxNtXxBV$o~?v4v@DhjdB4o~Z7XwIw-*}E@Rc)58m7u&J5*%r5#3+{v>JoEuf;$h69sr!9Ll^vfg z8ur)CmgGS>MeOs=h{$bd_L@cHdT_Z#N!_M$Wu?sWl$KGYB~bFt&|$ThCv{@Z5pk`A zq4-iJD1HPcxwwX{qM7}0?51=EhmlB(LF@Z+r5GR%{welhk*JVadxurQgW2cAriv=m zG3;vcGH-b^5&;s`ZDsWcirQQmqlWQJTy_@YTpQ*>JhG&?!RNx*+08Cxn%WStK`(k@R}B`1 zxv*SegIARnhKW2|WmYrVD&thE=-_#=TD8ih8eATh@FcB_p&A}*9!Tm8?2UA(-k*FR z3MObUFAQR#C^%*2Z6WMWn!A)u;%QUO(0&$KO;!N4xP9Wujz~G| zBylvub2OVwo^ojPff&I@yK+d{pUY-_-SAK|gfioY{`^>-Oa91i{O$SU?!SG9U#tZU zw=j!bfi+DjHP%33$QQ4W=fKZiFP$(kSb%V7Lg`{$QP4^SAXDACu#Rg!;hJxM^QTFH zlK;Vpi;q3_vo;YHd&ei-@wxR>d=V8tT5`)yMXWyd7}nCPyU=e>QzXd zYR$0dMTIG7D`-|VqzwyzOP$c<#58q6_UME)k<}xqi5qG{<0f)7q57O4fRDTB)6>cT zD()*pFH*{>xNAPWPAQ|}zJ&F9lAKY4%yEcplnrGGhE9T?CyAbY&mMbh7yeLBT!$|e z>V4UF=SDlBT=$hP{xM3aM%Twv&6nd|_NCFTx22>n ze5H?4dfKJXr=qRk>Be4-|J0}3*rMF(so() zVf^mJUmgB7;Jp{WiltQM5Pq-VF9y$g{FURG)OnXUbtXL77d{_LZqEALmpYzG z+-96S+xLhD0iMW)(WXdj8bgSI)=7=N;EVr}h{xoQed(IX=Y8o>ELt*R-hN+Nz?=Z>bDAsJ z&{{GED8L2PBt)9W$P0UYbLZaJ7awHq^%TMaJbsh*x{3*%7w0Sa!p8+*D>3Uw01l(x zt*o)CtO{tv*5epBOQDlfLApfS22tZU~cFXiZn$^DqkppsTIW+x1XRl?>QQ=O=Jv;(0A`)E?+yZtwwY&>F}&{6{<^PJ3)<`H$r$g~JFfbKJ-&1WFsA*oO~7iPh%l22 zEZTsY@IH9g$KGz5J9ll$EIx(v*zimQ}BsDwK)HeqIm`HKOBYi@-+cdDN6VgjgwWbdo{K@ z7N5+CRLZ-tUnuSb%>E7=7Wq;V?d%pMbW*TPmC^gmBn@HwDqaO%AO!AkVVh&+6{#h% z>=JtMj#cm|M*Br6>)$wJKvPTuv`f(ZDnM5K$w~%pOLOE#g zWWJiHv3&jbgru=wrz;sl^ZPwA=*?*vE+H?Btso#6wGw*;qZi{27)(>ly{VnLbF!2^ z4+sQfWIg&7G-9a@skppekg|%-%UZG?4JT3CoX-Sz%3#|0Tg-d%Is|*8;4V2H2UiE< z1iJE04q!_%Ss=4pUK5&c=2x4{!H)zsM#R^oYZ7`#PYgt4vK)p=7#O=W5VtlFN!2Qf zfS4!CQK5gx<6K#_f;_}OE)!V*HbcZ+uMSQ-jP2on@@V@9HHPNFA-rFt4a{JELuOT#O8*OEp`MSa^izyHy(3*n2&H@8q8gYcHmIrTHT%c4 zuOdQl%>gC%F=T5cBe{>6$Ua284c@1hF@fBv`q;JR-dhN%3yB5fpXQQ~x=ZGslZ$Lc zHy;wC`#5pR7Ng`nDr@s+x(QN0ne$8obEJNl*{OA7H80q!04`Dn= z9dppsWf~WhPD9(dnyGphi=W?*TU1#W4?TbdTuB`l#MS0qiLXw>admJ6#2X4mubfUT z3$$f5{^Vu62jEKt!l6=>RY{q9VpSCiG!tGwI?TO$Ib3I3u9@RTm^LZuxfF~M1fPW6 z8nmlWeW@WBM&r;g!m~3sSkG!5O5{z@SG0sC;;b7i_-Rpk5<#Uyxog@X1-$5Wi7_h; z!P+QA&(A3CTC>d@7uIa(?dZIAj@~Vk$QOUwcO^>sQ@Dh{2sfvg+D%fEoj(ocO8Pcb zPsbRBU1^BEQfnPyjtfmT;C7xdLp7D6Y^PKex&-}I?&GtI(4k-JgE_CU=cJ{Y>qsig zd*0HrcspavnSgxLKMS;d+?QuXuO|hUMJRG&QT&XNEKGwVA=99%U-DsM>&rRL;yrVL zcE>U3=6ikYeAkyv`dD0j;!nUCkDoBd5kmT8o2_5TOprP}LIw|3GsNf8aG5{iqBBy) ztjP(am{h_>;Ven$_!}~%N);57mecQpGGYj$FFJM|I;i3{gmn~q8v9GK9839s4cBMn zO+16MMRqLXdcw1dYcK(L*GB;2R!=HRUhWdv3_JUO%X>%6Yd+%Hr&GB$5Ew(`I?|>N zYU>K@*VHp%-Iu5x%>L$ooK5Byr5=f`OB3}crGdU!+$XZIi}5&<(COKEg#a-);(KDzQ-fT{f6SA`V~07ML{IsUmu{(8?okirUh1#$P%xS zR=UBb39X#Nb~Q2IZx7D=Yo1dEifa|_vd_N2=+wu^-0{?{oep;3RTF z?6K0V68{0UbU70`J?derhMMRCH&qik8anH+P;(!Vu@wZH*jt&g@mc=0-WJ+9W_RGm zENcmgCI$!LYvMv|^LA+}-~(a%-zg0AjEhXzBt{)7DE zY_coy3nhm&o#PMy=fS-2e<7A88N(pSgJf2 zM+S>+9i}yUO&a5bw-d`qJVWV^DYn(-ZMAi@A|wf^OBBxoR@_^Dm`%eloq_)ZlPM6P z4z82>Aaex$P2d z>Xoo4HpCiU}R7qZ@;oAD3ijUNf+ z4V!n8tz(juH~x@6Z{-A=j!3&fDzG99^eCSD&J4G^T(Ca8VVtdpf(o)ebXT@Mu#>Kt zaozNxr#E!pmJzj%V^R9R_cgF)kYR0R4$y6Z!*B+_8HPO?uwe{Hy5TDXTB%!Pqnq3{ zhZL4jtP!VzZ2N7Yt_V)u779x^Iw`y-h$M>lWNb7>}vspcTldLU3j87l?F-XNL9aXmnH1x)W6(eY8E@KIww z;n(8RsFZV_%sI<5dzRPrxk5AA*_Wh+vM;K5yhnsDP$j1uiL(ggcdq-22@p;-F4iti zSUimY$dNHamJ+tV@kNcL5~Eqh_BBGV8-l6mE*97Syj{{t{S^6 zdOdR&zUpv|M*PJPFkd5RdH^nRCSIzs7p*xOyi8^YIH&qT(GMxsZn7fA-|+R-=GQ=G z@W?<-r0T?i>0^EbPmIxTfnRBFWf*oZk?Cz<-73m_qNjdH42)GS1vfHK+oPzq_}wZu zpTV}0d{71p{{~P8i$=9ggTIe__P2yeZ3%t(8>bPfwP_b?Hb(jByUQv~MVe@Ji9)K_WzTU5sG`jASu2ceVleis=dURRhRzC{sq_+%F(@vE&+QN??G9Nvu z*L+|py+3lj0a%w}q<2cDTcnBM4(XG1}cqRA7 z62$d!3mRcEU)RenXmscaQt_+d7|9QVeWEdL4oN?(uAI~85;yi=A^A!aQ_IdJVEn_n z^f??L#Pq>meN}Y)ZX4Y;%rA6gHVQv&B!J7lVrMk+w=#KWmO~N;5jyzyi#{K#ZS-mz zJG70`ezB2=jm31ri^3fuxK+5gB25XUyb~KcCN@fQ>v^B_dqUcY2JH`)8|=AXt`y~B z8#`j9azI%uSK2F;E8YHJxzZ!|%f$y%-qDR6qy6#y$}e|=V|oPTY^`MrcvA^=CX0{5{5B`rlHw;~0c4WlI32r+`D-vd z!kN~4>eny-uoVNGqCRXrvqT)ZACh_NTmrfEB+PqDvbbJKG=WDTe?4pq=+=c3HIb%p zx*h7EUK6S?^9G1(MzJZaq!gn>-O#CckTD=C>gaCUKU6`9{D2u`b*Toalf{2fBJ6B zca1YftXQe3xJ$|D%(Apbpq3xm8-dJ;Q zid|<(RfdA&%;v(xR9m6RoMk; zg+Q{K$aW}dAh5vxzPf`5VJZ>FV?ov}SV8wFsHV_5@f3SD~L zmuDm-B=RUCxCxuKhF`t5(Qbxkner_SAwh@a!`D*ATs@vD64LuY`<)kf|@dJC3hwas?J}BP34kct-8~+MbTYd-i7(B|qq(SpC8hOsm&b_6WHRmXzXF|Au%)1p`xt(3rs*`(~{ll%^eUsz)4@^7R{0+)|nav zEf1!0?P@Rx$cm0xn%rvFh;Qm>t~!WXs%f>4cEfF3?>Y4S;CY`-2FP+S)=M*5?GNFe zVP+6kAw)l){SHKE(d&a6t$|cg+pWG*ylx55maD9CH5n$6W9$Dn`CcU%2j7?P6}#%q za?R#;XbyDA;$c`S4<=1bO7{Wf!{(z zSZ@BJ+@d84o2;**=CxEfE~F^aA3S>_a2PBBmV-f;4SR=Kq}#dhdDN( z_H>SdV$(<)F?8jnFjFpr+bt%!8s#e#{=MHzaoLMfU!*NwM(g$lBi{$UiII~ut&3-I zUIyOJdsQ*6fpETan^eL10O|^~ye4v4eVt-{7+wMHRUbh^%<@|%3RO7VJwudB zSgA~?JqP_Pid&d8&5|QQWseb<-A7krM^O%b>>F6Y=omFKGT{Y^q?Cfv^_MX4Jczrrsrks9F8}tEun@ z_x9J}WQrZyf^5<4e2d9QcpqRjok{q%(Eh5B$?h{`MLsL)WlzawR+!vPUlLsgtWX~lGSL`oFZC>Xisg5g0huU%H>7MZ^ZQ) z`>yHrtfI((MX8K3{8BWo9k3qV@Rey8bL)^L8=@UcD%|X~mlZ7N3@D1e3mmXJ(Kvjp z(j;g;sQR}4^(-!XMS9TOvJjK$tzulLf-f+=Wy!|vd{E7l30!u0YWSsKh!*#8~0~Yh1+LjlVG{wAJp?#SW zjN7o&Iu~7MOSak6>1zA@x^==b@~w37b^jbD2QCs|4U&2h9!G13upURSkCCz5r9o}? z&WEIy%Guk@t+(>R7LQAsVwqXDUdR*S6<%iz!*#3|W|434^M6=}C>h3jM!+XZ;L*y# zd+?#V8ma^Wy#Xbu+qBh`kSgLo`#L)rurYS@YFlb!BMti43eDZ4i{8J>PS~bbgU6Io zRJKC9x*AM65_P(OqBVE5EtC)|Vwiuuubcgt)C$c#iYh9*E4CLsID{R=-}c>f-3I8a zu)aFv!#C)Y25(zM6IzZUPzGmS&lyTgeTvY;!kx zZYSLCIFJghEE>E8x5h;;-^%$y>RUEXWG(%t<3SlXFtLs7OzAr==g8Qgr0>JBkoYk& zHn+ZCUasytBMBqMAP{TM7%IBY%uw1zl%w}ZQIzkI4^ozTT5ahN8p1;mwA%s+tsgme zC4Yl*$$G40f3-!kKdIjh#rEh#Q?PliaUb)t6s`IPL0i&7`F5JHvwjSd0^*EaA2>J zGM(=>2bqt|s)<(N%PS%jwdGy+xX`*o_^?^}U|vq{bfNwPRp$B1`?Z=$GO1pCAT9Z^ zDApnTvvkPoqQRU?jl(w}J-wXn$$*~sTzFTo#aibpZDAK9)z)#r7b9t9Hf4KTn;y() zOm&J4bS4+lM%Nj-$Bn5DraCvl0r^Y42uoOO(>01z&54UaMy~_@mWygC2<&xCG|sE z1VwCYFynBD8Xh@fvX&(K*U7WA*ZfL{)++qw71FnhM`Fyf>j*>BMLVSxL_GH}s*Uu< z(2cq^#>kD?8w)oYQwx>Zg@_r24cpPZlVwz>_D?nUfvNlZ+}jd$5A9p5$xiwIVOPmC1j zN@pm0t)V7bEj8WQ@9WgDSMULXG30Xg`8reC%lF?;NW22Z+x?j%w*N1r8bVnz7JrcT zKM$m_A2c+4&>+0m0B7P1QvhB~IN8t*6Q0e3{~(Xd#Fz=tyAk0C55L0xw;z3izYzTj zd-#EO>;`O4!!jCLKSfYVz2z&3e?_0bX>-t_)EcYub}Q>?01YgupfG!olyu^LyAD*> zf$k#7;oTIJUPvgt@$|+EYmA|5jA3L%P`d8&Anr{0cN>(q6Wzit=zsr?K!B*cy-f+V zGN#uO069Km*r>5YooH{eh~J_&7LqB*J{)Bi1{(dd2eVAFR_x zuA(7OKiuT+K@vb=*YRH2X<;8u3gn_F-u2Bg&6&&Orqc-t0c=OK=0XHqA+5o;QhcL( zw6HW0*TPV&g(Qn~zrdC@nAVTO=zFT6uuuiOmp7~_RATrU8_4jhSuu*4)XigDV?zO~ zLHeJ-i1!NwZ>(FtC#*49ok0lyS}m^KigTj4_7~!2LU=snZIkkzQ;3&igG=wFl~A_v zNwP`uzI0rxw@}tF<@Aa$>o|q>eadQ8Zcv1O7Ml|WAe2i6Q7LeGoI=b2cPetz{s^<-MwyAy68)~#xH5*G^&5(r*8**A+OfMz1Ul({jU(` z!JXNAYdx+)O9}GJ*=azSVaJee>5IaS-kIGU zCv(6zlDih49HC10Z~qH{kKMcpVUI7xISQ3v^u>0vBS@hyG-p3>$vU&y8)S>NhAJI< z{)?Dm6)HIya}3PRLW&FdEZcO(Q~Qt4=!(KG{amPZ~@nrnE zbeH0KL(aE*+H@}ZczYY!!huig3`J+*{bp*GzC`pPXo z)#KZJyE2qB#3*TOmg(K)d%LdhJ?FV3lDj|P{78r{$+DbExyG+tfbwnQi>G*sG@tia zV0EWj6wYWiuh;&}cQ&IxfcY)XOMfAaivCGmMs#~|hG(F#7npTs&)v5Ccz^4mgvMRt ziuc6={TqZG}ifrKUHb>7FSbCaUl6q+Q2C$b4xAw6n>!@yE;H^1?pev%pi7cT>3(7hRzF zY+^MIl8dG?ko6G{Rm4|Sr|yC`__Q~Lfn1_r&b;zj$on#LiFiHJrWEIbKuP|rj3w%g z4eV!xBkD}{7cxMn=?PNA5=Ss-5le_?A;=KfQi3;q%q;(7U)9Zoe=BIe1`;`B{e_&4YqEG^fV(Ls0<7> z6PXFF2$nJPmEbM>?GVe7RzK$lh_y9cmKRcpIcFhF9FScK8H(#n?ibgQtx`XgP@Ou` zhvyVu1l%F(Yv~q$cTmvzeUa`DIP)sRB%3WXc%xD9*8)f0%5+(J7Nf3H1if@RZv2I~ z`0H^AmN?72E?L#kZk2hSsMhe39FEyF3Q|;6_Y{Xs9ZonUnzPj6tcrPSN|fw!f)|(7 zMMH^b-Z_OOge&QnBTCM2SBPup5|XK|mTT`b5TZ2tK$Pj1ewup;VT zqQR$p8{Uo?&@NObj2Q_xC#AtLW45AhH)|a(1N4oO5?aOJ&>e>0Ub+*)Oi(_ zn=(z*59?_o^&sN!7R=pk%EXEgTUdRW$M$aXVzAA4!pNCkp|Q#97Q1F*M`$WzB38~q zm<`x+(UgTo06VblB@woneHK3kgT|nkcEECcpl%JMv01c!Hm70xD~;iyKuqGz#Zf5w zpTq#fWnVw89?(tB`QH>Z-LZu*QT5GJFc7Y5f z@38>!bH6Fl1lzKjUNy%>+>Ve4-~a)jbudf-Ye@uXV2z6?L%fQq5Sf@(dR*_;PrD+$W{7E@iN#Kf&lkxv=YWzajR$d! zW^+l~?ytA(OsTD8z&`xII?O(Lp9W;jnebrRG$~EGX^*F_`S&|B+&1DqIK?8%D`7Zk zpTwTXCX?)3T+HSITjK;J7b3E3HN>$i2S4ZL-rEB(j2GF$(pz7Pu+Rr%zgNFA_`&+M z-%Bf1Jdjp-WGn3K#2XXVyOqc-O1idIsM-JCiZFj_bD56Q#(Z1T79j3nly*&kBSCki zi8Vvl2(hTIvo=Dqp3xNL5Y+68WUOeH+{LAVd1a<~WtM}KXCnDtKKmJXCdnl3O6)@Y zp;-6I%))14%XDgYa#sE8vDTGY(KfrbnB!flbUnL?0F{oZWIY$oZDwC2pZxol@cw4@ zg$Lf**R~Q-NtfKLPbXXO7fR$6=~6;%k*Bbm7`je`B(VjjQLNaKc1F+)g#wqYu?24M9eF z2{JfTGjXesBv$h-yIv%6geAXX31iE3jazdhaFr@^is>{wMC>}cx^DVB7qY#VGHnfr)pMK&-m7D7-unN+Fg&CKOUh+;ihemlKQ|ha1@WGeG_rWL{ge1P5xhiOVwa zQ^jY6=_Ndm7N2PpQ(aO5Oth}fU6>Me?tnX#s{SZ@5vb)BQvyJYCzQ@%DC=>F#| z!ig;y+=7vfBtURD3Uv35-kZp82?Aa1Ptyu-TW(?d3 zn!_;4XnX6UbP>G1MLv41u`pfM zr-w#*+@etcSG>RrIQa`cSU~+ngf%kz;s3+l+s8#!rvKw-Mwl69js}Q?47Ci3;RA*b zm747$+6ZcW6qB^AT@D7Jo4aN1`jGC<9Bnu=V8K)}gPOxpo<^;a+62^HAe)eIKVrKr zwz?m)#qDYRlu>D!{NC3&GsB>mSnanyzt{FhGUwqw*L~gBecey*_jM^cZp@z1bi~!= z-Z6LXrw+q?ZddB3v%6=X(K)l0T%hmN44pk;_CCkB(ifGg)^02jbt@~cS0^-Iz@B>& zHjY=P%XC(}8s6(b5SBvH-(4>eJfn8=V+AcNC5d9DJ!c8AO0Y@{D z`cKWK2dG8!H;6_ z&P@80)tH`{--4N;i+?4`sW_54!_?-Aeo3|VOHW-&!+!DLNl)#xQ?JC_e!&H_Fkn{y z{E4ECW%X$P!q|5;UxhJIsmz)3BWL2@yRJhs+sSBCj~pqPE%2`lF%|hjDip84y5SIA zF=fMn@zc;R9SWQESj>mJ!Dyir1l1|-T`qB2Ek1Ny@7{X{eIpj%u&G;M%!h#ELN>)k zX;6eF<_wEnF{1`f7 zswTf9^?wd0YP$#Ed&k^!|E5ldrQXvOQg3V|wZu1;v_u2=NQQ<9TEp z=7(zp(<9?N9&-Bc=OEH&y=wLu{@@Ukt(Sh~zU-Fz@`ec8v$l=1>t;Kb>5lxR5obiz zs=L&#lU-}hoIE+s^~k4d&dhS3d}JK;&NJ8~iJzTU6Z%%xYq$Otp#%NRW?I2&iyXJN zdDOSuqFH$yCtep&@U6jIw)t-(?K|7nC85cLHG-)6k zb3{-uVW}q59xo**_%QBW1o|jV0xmGzO*dSw5>|5uaFWs(xG*iPIVyF5Yx%1e^2zjF z-F)jw6o+~C_HMSi(W$6PN~~@D)Z@u!bg9{%P4V{0ZmWKr6d zVf@a+wh8VDnXRu+Rw4F>N(~d{cm4@vMb+9C(-STeZxWM2JqseR{B$j7Ttoq-Aopy_ zjq?E}0uShxY1bjz^Z^AnNDphb>Z;RD=<24wtMIrR>moevh?Dyo8{Cz#>PENXzBNV# zgMSg-dN+ben14)lOh(u#dHk*2-W|7!)glVwO-ZbIT#;$Hr&?WiJpf$oV@WLu&E4kX z7QB*m6ls2>x1@1aH^DI@le+kW5hj1^70KdS z(heffOLm!L$U7q303l&avx3rl+xTh$us25)j2c!|osg0;W6LYW)vh`% z8_5hv^|(rC+U72=+H8>eJ%hZVf=il%!+5JTZEFf9V=iGqS!|?acjiwE{qxUB*oR4N z?2@W4-P@>4O~piD%LKctduDx@-DPuXB!`kVU3#6)^FfPR9kEI?((tY!DHIzWiboz> zuX+ctKb!!f>%g_2uqx{~Six>}$^R4*%3+PI-Z8FO$Lu*? zSbW~|#lF^kcKmp&&^eC&uGKNReICz>mkX8NR;KAMg^l}MbvhSqo+6ZKGm0_p0_k<> z-k1pmw`=FTzBgt>tt%fruGaPF-k2ZNx*jRmH>}pRVlS3*4Y;@le^}}m3$~R6NHIoZ z%8R$WgwkrY3f}c_!Dg*=Y4jT73yAlkv3!nX5L`U+cmR0O$rRjvJKyq0gj9-qykOsO zOEkPCqo*#k$5Xghm@ww2+4}&4P#RA#CiC#D^jlSfm_0iSJwAX7KEHTx%uv2%i^;Ph zE`4uZqe{hOF9^AB!OXmHRR_KoIyWmk>(z;>BM@lB0G$w#ti`;1kw#U-=zcE@*N=Mn z7Zd`xsg%^vqH}q=Tr4I*b+}`4duA6}hsPBaj0vfWLX+KZ&>yw6iLCPbiD3h;_e2&oy4t-qFY4p4HOdaKU+@HKrR z*PDG!&xd;Nxu)lD@uuT>slvkWwS|uh9wEH2t{yenJ0?_!GUAMY>QN|!)DLg)*MlnW zjAidcg3rFHAM{=y^&f-rN6_SHqN*dBT_#p{jC*gMxqbsWN(cAuJl!2BXXYd3Zy(Qi z{Lcsxx)Y|2E<^*@962-J5+hgmtSR9tZH9@HGWj}6>Bt;yIl`8~gB&^GGMy-v`q!3f zzU4?k!-qgAz(0bp({co+SuiC;zY=*|9OKx!0-PQvc8hAJ=zYNuFD$3PhS_)~>)fk? z!S(LbMiLu>wP^GwbZx@$&mO)%yUo?Y!m1t@K7w9b4h?^8l+QSj0H#O?IW)Z0uT(M) z)%C$o`t{i7qZpfJUsB#2e|d=7fU>Z{QE+eDOtqd9$~fEFr_ezQ_x*LOQuSuH{>dQm zS?&G~9ae|g?^k2#%HBC*fYLaz+q=4(y#;?-#&xTH(M{KG?)Ki_&F0dzG2N=WyV)W5 z(>t;o(Z3zjM%k=kMCw$m)(D2;B#%6X(D~E@1Bxc+hrodXoN+rNs3t{QBMS4Pr+0TG zt{eE*7b$7%*=JS!4wGqHxXC#z+N!BuPiVZj;if@juss%7a zIwKk{oe>q$hClM**4=qnU1KnhA`=mZ^g18vFo+9O(x8WPF!K}i!U=6#Yu%mr^)UTX zg)_{tJ0Gz(t~qfmbmW2)1DuIa)rkS?2Gm7VhaOfRGnmV%Tt{Mu;Rwz-5*?vyoX$|k zaD=;X4$rDT>ute+OXo`VA-+?O1u9J6hp#=0|3}GVjX5-pE5oi@0=IQMw2qiYY$3_R8@AMFYSP=>cEeU2t%ex~W5l)_w#?C37xCr)ux((& z_y?^#=KynpE4FhbcCOUUIeAXxITz2B^W1ix+h%VH$HQyCuvx_iQ&| zf}IbHB{AK+q0Dq|V{|S!^bWhBY*CC;!y8KPLvVsp-r%Gl1t&phV|B)f8SZDhgl> zjEja6{U&^7?}+h6Y!fjj-}eZEEC_-irr4f5Do$(`Q>}`#e^)zz?`oA6JN}BT{<2JsQ94aP7Sd>gvvSQ2}(eO+& zx2aW5$b=$9!*k(1a&7J$;H1$0>#~w2$5~rn(>sHqUOcOqcYvnb#=9mLpZSPZkYjqh}!( zQZHpSw;Xv5%9_0w%Gw|+%W`j!vIb))XGG}A3%ROBP*jks=_>JI=xS@oVU_61z+vA?vdvhqCRDx;pKW|oynT<=(BPvZJ8)_VmlnAq=Z`DG_ z8)xqnr3b2#1G?G^-OdW=O5`@t*p4@`_7vvx+~#F0Y}Gig+a$Qs!WfTGtasunI;@RL1mj^QE3N{;EhzF7%xe0*bl;*I$=#wN@H3#Fv2xT<8>d?Q%Xj->MA7u$M(>H!p!;J!mJqKRiH0jV z)fB$#je-iz$xe@b5JT_vX@t8&bF;d^ep#nd{fN>3rl3+QzW^vPy6ISZ+?S{RuAE&{ zF#1+~9TYA864q5UI@CTk0wYi+3h34Nnc3BcEJ%AE_j^j*gi7iXo}tts*=?F zSlJ#+llsyzRk$f!>`>Tend}|1>rfSi#8G|Z%G`TOX}Ou%^+`cR7$jUcXwr?AUUk|X z8q~ECGrAXQC&jK)8No$Gr2?;1P@OQVaRM+PRjm+JyFIvSDpbvgjze{`U0Szu3&SQ2 z#YJSWSfrU8<1OjCezr?(=-fihq!^=xnVB;{^;3p<2z437?0QA6OXhQoF&oaWr+s?W zC3k9fW*OtXSE>j#C!Y5%@6|T91Xti|+h!rP&7ySEf?=v0f767bX{a&#Y?w?313X3P zDN6O{x2McY?WwoC+;%o{h7! zfb|1^NESoFIR^EvOOWNGKM(D8Xm_i;ahMHM7F5d5V_>1mT%gWeUod98zNMKfsYTbM zg@CU!V<9j*VDPovriP%-j2$?7TG*QuWG%A;W=>C&t8`#~vCSH0dTN|?sF%z=#Bv|} z2-!QNe@C`=#~}3FUiRKw{(+MGXp12EE#FdpOF(`VtX=BgF!w7|fM4XZd84dy>U54l zMhG3$M|;VfsPxO+qjI19d}EcvetatLWj|MvIfEgW0{2J`+%d>YD!#J3pI`jGZDg6& zlKIs)_U|8Dl>NJ^x|e@9?)XmqyQTPA{JZK2$-l$kVedZEp@Ap!M#hK`bV0V$+h6|u zVrDGk&Fb;*h;{vFFW=Muu{Yo=yHs4?vR^*G$&6vV3&_O>%M2Hf2wqo`Iq{8)@bTV} zJu(ksyfeP7%qvtA12U7FK{qW;Qi`tO0YBrPlEJ-8zTM{!7hd8Id+WCawj%lVAm{G$ zC;rLJH9L3s6W_!p*q>ak+l3meb9Qzk+#pCiA1Hj@-0#P~R_@OI->=+BH1(2}OjE<` z>67fPRrd7BX0HVm;zVPe0*h8@lKD!hG$y5A(gwZ#qvv9Jpbbi;F)4iz+JN^@Fsn;P zkJr}+O)%v-34tLlS8BQ@-08{4@U?-pYNWpn3P$$*xIC(1nPS+CCF!Po1(K>EK7x4- zZAP=IR9j=#nl;8xK%_IzF-c3x&8*7!zci`-hV##Izkm8|Z~wIByY)|bf&S8KjOcs* ziJ525{4=<(!#`zTxv%FwBl)MG`6v9-%x~M*yAU$a--UX~etC0~e;O_Mr!hTqX80!@ zLtoK9Stb88s+WI?{kAf%z>%L{=BxTAY;_DZ{x9aA{qa$Wzm@y?+3sK;b*B4UO+b;8 zt)D(h_2+KJ{NGQYU!OvUHbGOx?(+es)DWs(4Vc{RKUC1lxb4mmOX6+6#e|RoTI2 zbmg^I3}cZ7W)* zXa2^+GUm+v+i#$8IpvA?E$Ql<$e=+kEqyX8jeGKtJrX1m>`J_)#Y4#aR%J1W|Zog6+&hWHvUeylUrou( zc*kD;j^)R2cja9y%*!!e@yy82y>((;?Ua zwZEVcHB4DqbXdqg%kF4f%sTHycK0!uhLqPDwwq=&9@Zefs5yZKJ$hWDD4I+6>a!ocMMxry-(#Jc}6I*qB`8!l(MUG)} zs?dmsh|U_l;ci(&X&EMjx$RJ5WM2p5F}9oSoo;%ePj@|CLj>gtMogTW-2>PGF@$tqDNAneD^YM2n z--2gLD+?#q{?dl+W^9ok{kxL?W#LiUop&Vu>f%vDsc@ifHy+9wHB&7Ahg9H1yTRdp zKDNz%=%ZTBDbh~4Gj5>1j<(#ZOOwl*R%~#_9HLG6VnAM`UHQsYsiL72TCC-s6uGDH zA$cR7Kc;LvM9<{rU&Ql{YN1X#7AVb{l8Vpa1vi}<;M5EI(DJwZ``yutRCa?Cn%39Y z#VKW*YYh%3(0We2-B3#Vk)^nMdbPH&5buke6Gs8KQB&=#!`J9609`;n3urM_WMA^} zrIYOC|G*Pvuo_47dhGH#?cyYTHC;k&9iYFBbjCp7(RhGP9Zs);y6H28^aj3#C&y!( z76%U8lhzl5zt`GQvFM_J;|{0rB3{mNj|=)1Z`d*7UCLjN#+xfNo{mwf#*y)j7l%)& z5xE`2jXG*@ynVxlLpL-VO5YpU+=kt6v|w`W5?k|a3{>1d_uW(Ku^ex|f|2a`dzzrVgF z<`|ia-yBl{+9Pw3zQ`}uHKRVpp8DJq#O<6e8H|O3rC^`wK={X%jXoP9*obOc#%&i ztWB_??3|;@tXV9I2TErAD<5suK_m6Ije4>C$@Ptqpy%;~DSL zi=cTLw)xH~ap#-kQ0`dY3x_ggeGm?1()vDeD0i&?f#OgGt-lfuC35|Dk3+f0{|AQx z;LZ1mL%Dt}CM{RNp$zgr^B)`vAS*a7?GFwmo&WxDDAQDF+_v4yOm0gKw{A5uXCB1CTRdo+M!)V7ZElpXsvzvP`2L?>WwnJFyhJ@5OB_TDC?m$9n z7}K%ySL#D*L=xT+^WG|`V((420CgCQJxC{<#++s`yJ!0{w6jRUX;AIKVdbigH!#JU zJeF9dd1P7KS5W8dqP@wt5mcj;UlJR)u^?GxA32oHm|g>(AYE3uePj$U7B)Ik6T-sx z!A5pjXM15@^h#mDXfuw>$GnsotE$#yMWhN>r)!xH8PEM9Q(_y zh9<-E4yX;igxbJv9jP&Z+L$RCsu6WdGIt8Pm1_Qr7ZrN`V=&?8#vuo_?&#$@qewNEIHTTUgF5sIUfP#k51 z;!yEPPRwBZFpe?_#u3vH1mm#inA)T=8N@-itCI1Kr1M@Fju?@9&fN>c;aUd_N40S# zVK@Nbs3k;3t)wnou6-Ryj!qwv!^InRsnQ6^p-KQ61AtV_^taalP)4%5F=gAWCVWR#X_Z!fK{}7G9a|bF#HYoOl1t(9%I9|HCxJ%Ihli18wjHoYd461K%x zcbq9((H~@crT1Waz<#917z>!0?ZGX8JEa>OR%#0BQxPtCi%t2mb+w>Q1azM6HX|b8jY`imzW3Nd3Z(Qwi4dt=B5E52w3!fEx`a$tWq z;75T~fvjPhhBL;M8W1p|6PdJw$Q3BzRgB4@a(~@FqoDFS*nlv|aU;)F+PNxka&Ucu z23PdgXbcOESQU~M>-Wm-K<^n5hfI|EtGn3k>#t=6V}26c94b-nuT|7vMQNv292G!JE!vJ)Sbj5Cd6cU zN6c>a$bopXjV?#urB#pr=C34?)^(v`sxBT=ub(;A1VbLTN6$oqyqfOc~*GVhWyl0M*94 za;g>smY6YDbaD4vt2RR)t3+&U%$f)ME>|O#o7@6Bk_t4qiYLU|U5g89=3_>uuQLxP zc|~s9hh>;c&k4h{8oVe>m-$61%LjlJyGCfDKaAlI)*o+?JUtER5Pq8%gc8a3=R+>+ z7RkT(a`37#Z+wBOCn%tHyP=BbYJEZ2Q+V#hF&!9`B%Kl8!p>n=u$D@yM|Gl<(m76x ztj}igp4KLsj^3j_N;ymz*9nFBz-md}9kpBq%YwOS9z_*sn?hsIvn4nDj(2f(ZYOk9 z;0!g#K#4n1haAH;oq*{t!g2Fl11}cKA2_;W0LwO_&}u3aC1T6bd_9%-fYuyM|4NS{ z;I>Y(l1S;2VJ9BDuUbU%KSP6Pr1$iBBQ!tKEesS4SxGdt{Cq>!(sP(CNq5`N|5i2? zvx07(jvXpr{=|RzGuo5S(uSyW@8AtPbGTw&bKO)OWUtLY%NOe~ODPt^n1a|ddfU{^ z7{B+Hp~LRvHCjG{p}A;t24+KEq@y)V}m=8IY>zoL90!Sy=eqs7* zcOIJ2WNF0qd5+;(v9h6gVwS?OU=%mX3Jy8l97p^2s;gSF%|zr z*u@!Or7L(5O-20zwj_m@shF>ZEzMa~@XRpvJJ>PC3~L(-2elku!R4qm#^JL4EM17+ z0|AyUoReSh3>I?RF!{$k_IQU>sMG^xExt?|DO#$_LwpWE@_ECvwgrJ_q&`ZUGDX10!xld=Pxu;^XTYT@N54=()sI?shBd|B>dMHT=N{zG*x`|9I+A+oD*f&H_cls^$zW-5m0z8=1H<{b@d?6zAMFrs2(eMrXk!e#~3al}T(_ zf%_3ryzT8Vt6WagQP<*=b>iVL&x_MMJ6&$KtGW?~Iy$GA!R*#-)Kw*)x7q?91ed=4Qi+CT(^%mNhmwF}{f6 zHd+IN+ikO8r5PPV zf8wTIpxtv9IYi#|5R{t3(FZoF)bHHr#qoe)N8oeP?bFf2bQZh^1=_6M5C)I)t~|Vl zLghcCIc4S!xRtr{acZ+OdPpc6dOA88vBrSSsvd{kbu2%DVJ~XIzxo9<19!u-;9EQC z@12-#!&ib4GRj#k{T8$7lriUl5Dmg{b)Z_6KVc!3S^el`F`jyc~L^4La1)(y;B zRX{8pl*e=*W-~CR_ZkB$5TFgYmn6(1rmQrm10@+Ws9)2B&p{JDXFBjPzQGRo7X^{>lHB^$ZQx-54U&im72H>wGoVKp`&|BY+0Ig| z%V;_3o5BXK%WS>ousbo&qf+4vT~5!Uu#BNHW)o}Ds@`kT0G3~x%VHl!TF((?6ZTG+ zP1$Y^%5@1~HUswFYmHg)3qNKP6`>_Ko(E>LXAbUPPxo^U4$(6R7s3(7MUow$Z0fRm zM-u)KV+XdGu!Tg^cG^P99LlJ&z)|QevmdkBx6HZOer$+eW(l+TEoJs$HZRwAfEUsu zbeMzLY>0hlcQIzqVV2JoIB%3TTMkxTUGBtLL2_61A@}Ag$lcnr;}9fwp9}XgS#ENK zw$f4l_0C>!Ml)dYK&JGpcP=c{vLk7RE*T5Pbehty5;NwN4c04&C>pLr;l(yg8(o;w;R*9!e=XgV z_L*uhU~6cjTiRdx27at_w9k(jf$fBG2KJZMe5ZcQn-}l}z4q4n_G3n1JA1}$jDJCX zEE^M>E9@mC{>YE*^!o(B;nI7W7TrwV7rZt@9AH?Z}@ufFn)*}Hn#y0Q8@wROug0ek6(t*flC^{ApKtoNbN zo0Q(A3`SsVsPZ(36ISvid0!lZvg+qowEf)w{mRF?@Y~UMJ%;zH%jM$?265tDT+0}q z_>ZrAybHg~Kin}q_ZVy^cnr_;EL44WWBAuQ78=7-pN-$LTD^Ek@PJ4=UGwB&QXb() zuES}rJe2aYq(P-cv3r1T^Gu%_z<9c3jAz}D5ku!<6e5f#*8IS3VZDgmxotYEVYgwd znQI!3MKnP^?=h!NpN6G$YDIij>sQ#Gh)x=!hJDV*@^IT!txgcJk#Oju@ot7Weh(o& z5hAh|;?p=&+8Emb$R~iGzK;S64`}bwS^h#XqJ6rNzEvj)KG!r6OMM(F z8@3TD6bhO#4O8@HC{sb`MwhzN3P^b%I{g#EnpitLV2^2~?=MDQ% zUK%zhX`@IU;*snD@^42y{(u?6c3H1thM!rSi3tQwo`y>2-`Me!&z*o8l^Rn;yOg*D zS$5K920m`u0QUC_D25JpG?_)Kc*6^Pi-NX1lCS}S4alN=TpA7azd*QBy3~+G3%p%+ z!wW}=FARXSGxY-0Oi%*%&Kjj&U}I|{t$-C&_5mr#Z6cW-qoV9GWT8GfKg3s{ z;VDs^JNlBsMqRnEiv1*4c2HprKyeyzz#351xyI8!x(%wTeLeiW$ohK1IRq=}ELTtU ztD|!6R*F*n&Km07yU+gjN6Ffz=U4Mk)SyF3I}{}pigop$kA11(kLOVmzeJm?trTty zXsYqB2}R|;NcFqDM^$L=8I6@uj|2Mx8IJj6xEyQI`2xw1Ofo6cmB$IuAwiX1PQK=Nun(MHO*|HY^OhmsGd z24hbTVphf|EwdPN;w4ojmCB}p2K4nw2~Shp+@^mI^r`*9ed>}j5`P2x zoQKNdgEl%LSejpjiPn534fcfXZNtvW7!3_dJF#nwpKjd(`UP+jfXE)QTo254xNNo$ z7V^VwXwe5@wLwZf2w5wB1^bvyN*xYm;yYzRwxdxRMj6ww>6JI!hC-GoZ5w&1kYi*R z58C{;<}!X@?^3j{5oH}UxNO5w2F7q!W7;_1^j>4-jlWX$az{T3=&bRe3B8%# z&%^s^q&I`hz2nrMs4pyC1<|Fx@MoXi{+V3&USz}Akv?B^X?=1~pC3#0kt=~C9L-!| zc~;$rcEirnYNf@4U2)7Fc9aRGyv6>0uT(FFpV|W(4(jxYvi5Qd(H&9kTxc)0M{23> zR{ZqKtXa3=bEZTS3@uY~BXbu*fuu;G(X?QC<&cSld{f#$PkRcW^F^dW?n$&GY4K9= zvryi6pZGh_yR!2ep~408=jIWh9w>}{_>)Zdld({v-=7R!)rUV>64{WqMA9KVvGLKM zE>2xF@ow1vNRlJbxRhap=b0ugGm#da6aiiLYN(ncsPx8GlWezC{7)dC zKBv5EDF=8F`q7Tcq+g?HjIzs)mWS_48Yy=w`uFvu;2oK-ezZ*6)U;AIQk7jY(#pE} zdz1gTD7s+*zP1QDUZ!n5cv`R`kP?&z&jXz~BdyO@3R*nCH-)#hc;D(yzhx_yf;N54d)N!@4PnvFy8GdGkVo;dvque9JhN$t!#D2S%+7;twRP?2|uWT=@g# z4_y4smG}etmES#oKuv1+PaMndlRuz-1Rd)t{DF(V@;&n({y_iv1M`0K1LF_Sd@Av} z&>;SRm)ey#l!HGI-NEol+O}2jo-}-fpT`6j=wtP}QS?U)l1>3M<`R>l&8_mL3SGP{ zpLP<2^a~4XaZh@)^Re^0*7)AdS4)1^(n}-;UFe_^TfP zr$OvDr$NLF7Muq3e8i_TV0B6HDZde?Vb}M{X{fmOht6pbrTybzPQ!CpdGzKq7!l91 zf1HMjbU&v7F;;>(4OP-P+;_%lK#Y~%_~^ZTpSGQ%)eI%`H8 z%S$;8EAe>X81$MjVt!6To?qTx9E{6x_TV(!FJpXg&fGsvLoVW2N}L8@DWP%+jN3WlSrK_9UIMkw(|`h;`%V{c9l==myggVq4(Je?7O*5H>L(KOXp)^lg#50BU2 z!$A7to%MaLpBwAvH3ShGdYu=317d>@^8;c-Fb4ALcnvD^weT8LSLQY34(yZHKxrKN z;5AGQHl$GS8h}UbC#?ZoxJz)JRls>#vGS+msw9aIK|CbF%m{;eh{gBVGRfcnx9?uR;6^!)w5e%Xkf9zjzIGIK1iMHTY=_kk^p7_4~)HOTnlm zUV{=S$%jB|#S{?JZmmRX@M0#_YcACb`{JMmAn}8 zXeRibSZ`v3u}@;dlq=A0uEx*$f5L0181nDtHC)|?f%{4OHvQ%`K>&e#4&chI3g$K7h~g9i@?kP8h4&dxTiAAkc*?Ln>-~Y|Y0G4CgWlTnxk`b6)TpM6 zkdg5wZ!uX@)dXD|F{h#vBYht@G@Cz@~NVh{%{+l z_awmdD@@iG!Q6(wJlqd%L(l7fgnl{t>=RfYC0vc$a0_u8rbtTLVKPpyjJgG*O-7_u zS+?PdrXhoEE9y|c`()d&Aw7g?Mu62Yo;dNu7lIp2QG?h|UW4!bQ}X-ecz?QxIvYekui>tT``|S+{6Qv+ z5ywi#ocB~{E9~pv&1;aPmiletCg^Vxs{HME4L#zQpu7nvkMy_WT6hgTGIbU)S*^jm zh6}&w!tgCrAmn$F*#f5(VDyoMdWxCUNB&3DCXkmMm=L+3Kc za~(C-6?qN$YGXVde@NuZ9$tf%=|yS?>Put7-5fDe@E zC=W8xvpzQt?agT*R!Q%nDKUp3PQ!JO&BtjtzZ6YMoCeS_mN$jBRb$5fkZt*2l`4u` zM?6}o-mj5-KSR#=udv$2vjL97d-T2^Dtj4D_ig`O%AgQsiTjk^6@Byv@16_ZHb4D= zxs_uw6pJEqIHh?CEfG2t??#+698ew}kbC=A$yzzb!ZhVZ^*UvO>!VQyYXb7ZuRT^Q zg!A)^{IH=*B6)5yKUkgPGV$|f3hQ&Y1fEM05cMo^DYpozNJfd?g|r+Q5y{0za>LDD zlC4AeZsfUy!yyM$yVac&@tsZYGxRq#v*EL~=Uhoo^AW~5VWk=kK1bo$<^#NXt9ci_ z{9WXI_~X)Eyp8=!gLoSaOZ(()oL>3^j#TaEt% zI5CaEGJk{TN?DCRB}K8FE8)3v0?TnOf^=|Ov6RKbYrn8rDIod-Q2t`6LunU};B{3M6<=hi;<_XF>aasTduC!3VQIdb)Ch1yRI!||Fk-ifV z+@+>-yPLwp~N5*Y@Em