From 8a418c9c98bfc1cd1afeaf96c24d93a465efd71c Mon Sep 17 00:00:00 2001 From: wyf <494641114@qq.com> Date: Thu, 22 May 2025 08:56:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/img/icon/ai.svg | 1 + assets/img/icon/score_down.svg | 1 + assets/img/icon/score_equal.svg | 1 + assets/img/icon/score_up.svg | 1 + assets/img/服务协议.pdf | 1078 +++++++++++++++++ assets/img/隐私协议.pdf | 1078 +++++++++++++++++ assets/langs/zh_CN.json | 4 +- .../home_page/DynamicReportDetailWidget.dart | 3 + .../setting/pdf/PrivacyPdfController.dart | 40 + .../setting/pdf/UserPdfController.dart | 40 + .../weather/weather_controller.dart | 367 ++++++ .../weather/weather_controller.g.dart | 31 + .../device_bind/bind_device_success.dart | 1 - lib/pages/main_bottom/home_page.dart | 66 +- lib/pages/main_bottom/message_page.dart | 368 ++++-- lib/pages/repair/apply_repair_page.dart | 2 + .../chart/AdviceComponnetWidget.dart | 119 ++ .../sleep_report/chart/DataShowWidget.dart | 108 ++ .../chart/HorizontalBarChart.dart | 2 +- lib/pages/sleep_report/chart/LineChart.dart | 158 +++ .../sleep_report/chart/LineChartByRange.dart | 24 +- lib/pages/sleep_report/chart/RadarChart.dart | 109 ++ .../sleep_report/chart/ScatterPlotChart.dart | 118 ++ .../chart/SegmentedCirclePainter.dart | 2 +- .../sleep_report/chart/SleepRadarChart.dart | 100 ++ .../sleep_report/chart/TimeLineChart.dart | 273 +++++ .../sleep_report/chart/TimeSeriesChart.dart | 281 +++++ .../component/AIAdviceWidget.dart | 140 +++ .../component/BreatheStandardWidget.dart | 315 +++++ .../component/CompareSleepWidget.dart | 197 +++ .../component/HeartChangeWidget.dart | 316 +++++ .../component/HeartPointWidget.dart | 47 +- .../component/HeartRateStandardWidget.dart | 316 +++++ .../component/SnoreViewWidget.dart | 4 +- .../sleep_report/new_sleep_report_page.dart | 46 + lib/pages/user/about_us_page copy.dart | 113 ++ lib/pages/user/privacy_scheme_page.dart | 118 ++ lib/pages/user/user_scheme_page.dart | 119 ++ pubspec.yaml | 1 + 39 files changed, 5964 insertions(+), 144 deletions(-) create mode 100644 assets/img/icon/ai.svg create mode 100644 assets/img/icon/score_down.svg create mode 100644 assets/img/icon/score_equal.svg create mode 100644 assets/img/icon/score_up.svg create mode 100644 assets/img/服务协议.pdf create mode 100644 assets/img/隐私协议.pdf create mode 100644 lib/controller/setting/pdf/PrivacyPdfController.dart create mode 100644 lib/controller/setting/pdf/UserPdfController.dart create mode 100644 lib/controller/weather/weather_controller.dart create mode 100644 lib/controller/weather/weather_controller.g.dart create mode 100644 lib/pages/sleep_report/chart/AdviceComponnetWidget.dart create mode 100644 lib/pages/sleep_report/chart/DataShowWidget.dart create mode 100644 lib/pages/sleep_report/chart/LineChart.dart create mode 100644 lib/pages/sleep_report/chart/RadarChart.dart create mode 100644 lib/pages/sleep_report/chart/ScatterPlotChart.dart create mode 100644 lib/pages/sleep_report/chart/SleepRadarChart.dart create mode 100644 lib/pages/sleep_report/chart/TimeLineChart.dart create mode 100644 lib/pages/sleep_report/chart/TimeSeriesChart.dart create mode 100644 lib/pages/sleep_report/component/AIAdviceWidget.dart create mode 100644 lib/pages/sleep_report/component/BreatheStandardWidget.dart create mode 100644 lib/pages/sleep_report/component/CompareSleepWidget.dart create mode 100644 lib/pages/sleep_report/component/HeartChangeWidget.dart create mode 100644 lib/pages/sleep_report/component/HeartRateStandardWidget.dart create mode 100644 lib/pages/user/about_us_page copy.dart create mode 100644 lib/pages/user/privacy_scheme_page.dart create mode 100644 lib/pages/user/user_scheme_page.dart diff --git a/assets/img/icon/ai.svg b/assets/img/icon/ai.svg new file mode 100644 index 0000000..adc3af5 --- /dev/null +++ b/assets/img/icon/ai.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/score_down.svg b/assets/img/icon/score_down.svg new file mode 100644 index 0000000..6e64b9b --- /dev/null +++ b/assets/img/icon/score_down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/score_equal.svg b/assets/img/icon/score_equal.svg new file mode 100644 index 0000000..5f67582 --- /dev/null +++ b/assets/img/icon/score_equal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/score_up.svg b/assets/img/icon/score_up.svg new file mode 100644 index 0000000..c4c0bab --- /dev/null +++ b/assets/img/icon/score_up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/服务协议.pdf b/assets/img/服务协议.pdf new file mode 100644 index 0000000..2819243 --- /dev/null +++ b/assets/img/服务协议.pdf @@ -0,0 +1,1078 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[7 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + 服务协议和隐私协议 + + + Adobe Illustrator 24.0 (Windows) + 2025-05-20T17:00:37+09:00 + 2025-05-20T17:00:37+08:00 + 2025-05-20T17:00:37+08:00 + + + + 60 + 256 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAA8AwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A7pepr7erLFc60ixPKRDD HpJLjlzVU9VDtxHBCT3+I13CrIdOkneziM6SxzBQsgn9P1CwAqW9EtHUn+U08MVRGKoqL+7XFWP+ YLXVf39xZ318p4USzs0sWaqitUN0lOTU4/E9Pl1xVaNG1Vltz+nb5DGv71THYkyE0Px0tyBSlPgp 39iFUytIJYLdIprh7qRa1nlCK7VJIqI1jTYbbKMVRP8Aur/ZfwxV5LqhsLPUdVeG20uKd3nkk9e8 SFY6mUepMi3IIc1aUuqqeLL+0uyqBgXVraIxfofTIkupEkmtZNRAjPNwojBFxRHUxpIVCMpPdmJY Kp3c+v8A7kTaxWctrUOJYbtgeUb0USL9ZjULIyoSOQBVgDvtir1CxcvZwOSCWRWJWnHcV2oWFPpO KvOPzF+sDVTJa6RbajPBH6zeveixYRpxpx4yVcPIVX4wo2471qFUp1GINJcQ2NlYnmPR9CO/dvTu I1RzE7C4gNPVmYURP2d+oxVZDY2NwJHm0+xa/UemFs7kPzKoPSQxi66s6qByb4S/Ku7MVWVfXdY/ 5Vx6/p2v1nnx9DlH6X1b16ejX1/T9T6v8H99Tniqv5g0OC5F1aSWE95bSQXM37qCxZQ8lSY4/W4V ldiSOYZD+344qh7W0lMcd6dG1GORZuD2Ekekh3UqFLsY5PT4EOa/vOWx26YqncXlvy7Lbxc9It41 qswt3ij+CQkOSVXknPkBUjqR1OKsgi/u1xVivmXSluLue8ks7m9EMXFLWGLT39RiylTG1zR+UdCR yYLueu2KqVp5G0+K2SNpAaQpEB9VslC8ECBuKw8a7cjT4a9ABQBVME8saMYkS6tYbuVNhcSwwiTi AVQfu0jA4IeC0HQYqmX1O0+p/V/RT0K/3XEcKeHHpirzTVtVW0167db2ykuIbkMzC2NxNAAJnSPl b27u7UAIFa1ZlqSvxKpQnnrzKJ7hR5ptLkOZ1trdLaVLnlE49MqgsZTR1nT9lgQlVLAsVVZPpHmK S4trZn83LcSJCn1oLYenI0peVQxjZOaB3QgKVBKJUd2xV6HYyiayglV1kEkauJEBVWDCvIAkkA/P FWOaxout3uqTMtxbJYFo2hR4FkkVkALMxbY8mVaUpSlfkqhoPLXmG005LDT9ZjsooiBD6FnAiRxr X4EioVHInr28N9lVS+0fzrLJMbTzFFbRtEUhU2KSMknEqJCxko1DRivGlfbbFU0+p65/h76p+kU/ S/p+n+k/q44+pxp6noc+Ne9K09qbYqxLWdQ8vW91ctJcTmeIszJHf6jy3nAYcIEk4rV2OwpRR+yt VVTKw82eRoLi9a31Qu0aCW4klkuJYwsbND+6eTkh+JDyEZ/yj1riqNTzl5WdyVuaOWSOpgmUsX48 KVQcgTIoBG1TTrirJoCDChUEAgEAgg0+R3GKsH86aZJc6n6kA0xiEBlW/nmiqVrxRhG1OLsU3Kn5 HbFVCz8reYLOKWGzhtrWGIq9jBHeXqJVKCNXZW+wATVQnE06Yqjl8u65NGFluxbrE1YlS51CRiOS uxkk+sxs1StAp6DatKgqpp+itQ/QX1T6yPrXq+r6vO5pXn6nHn63rca7fbpTalNsVY82n3n18tLP rMsby3DOsLJHCT6vCIUmkMooi/DxorfaoKjFUuW0aa4e3tdS8zS3Ts3r3AhjiUr8Qr/pUSQhSYm4 qijrWm4OKp5Z+X7t71JZb3V0iaJC0M8ttxEjDlVnirLWNV9NlVuFTyFSWbFWZwLxhRak8QBUmpNP E4qwzzZFqc17cRWf6Rjr6TpdWkixrG0YZn4LJFLG1V4g8gQTttQ4qk1xovm+8VLv/ctZXEqs/wBV j1OApCPVLBDSJlLtGoXowFftcuTYq6+s/N81vd/V7LVUMEYiitf0nGjTmvJpllCuVYrHxpzUDlsA fiCrI/qmp/4N9H0b79Iep6no/XF+tc/W50+sV4cf8n7PD4adsVW3t1qbSyw251VHUyoHjhsylQeQ YNKApFHVV3+e4chVSg/TzQSMZdYWSZqokselcoVNKU4jgRsaVLEd+2KpwdSuUhLnTrpuIHwj0Cx2 32EuKpzF/drirGPMuoXNpcyCI6m5dOKJYQW8qq7/AAKwaVCAV+18R47b7dVVVPM9qLaKa5sr+2Mp fhG1nNM9EbgGb6ss6pz6qGIJHbFURFrtjKsTKlyBMquga0ukNG6cg0YKn2ahGKo363F+j/rdH9Lj 6lPTf1OPGv8Ad8fUr/k8a4q8nvwL7Wby99PSLq9E91bCaRdRjeOOKVlhhkuviUH1VkDxBabqVGwq qnWhJZenGumCxbTIwJrZRpN+ZPTlb1I29Z3/AHz19RmPHdiK8e6q5ILG304G1tbSK1VQlvGNA1A8 FLAUESsG48jU0A618SVXotioWzgUBQAigBF4KKD9lT9ke2KsL816X5Zl8xW815LHBduUWRQtwJJg 1YVQtDIimochQynx7Yq7SdF/LuK1hOnejBA1I7ZBM8RU82kCxqzKynlGxWm9AabYqvj8ueQjyijl iL2rAyEXbGRHKNOGdvU5BjG5ep3K79AMVTb6j5e/w59U9WP9E8+Pq+qKcvUp/fVrz9Tbny58t68t 8VYq9j5rn1m9e7tdUjtEZvq3oahbGKQl2RSIxGjRjgwfqabf5WKo86R5iubma4ZLpBHGhs7V9TeC EMU4cT9XhZyVFS3qchybatBxVRtppuri8M09o6BAnpcdWu5Vbhy+3EyIg6r48t6/ZFVWWQcvRTkA Gp8QBqAfY0GKsJ88291K8vp6iLEKvNWGpfUCFKNE7f3E32RKWWv7VDsQCFUJYWl1rE7TWeo8ow4S 8+p6t64jDpUNwEBUMyMrcAVG/wAOKpy/lJnBDazqRBXitJwhUfGTQxqhr+861qOIA2rVVGfoF/8A Dv6J/SV5z6fpHmv1mteXLlx41/2NPbFWNz6x5WvNXuNJvtKsJYiJoCxuLGR3kDO08RgZw4NKu3f4 t+9FVU6t5CnUmazsxZcTK148lgYOc7tyjLLMSXZk32oajfrRVcnmjy1YpJe2mlhbgUiKwyackzFi OaVa5QfC4o1W6iu4ocVZxbtzgRqFeSg8TSor2NK4qwvzTokl7q10z3cZSe3EMdvPpi3kSciUJMnC rBuXxKz0+W9VUBH5KvLqzE2n39tFZyxUsLefSoUVYZijMJoisMnLiZBQcN23G2Kpho3kRbdPW1S6 jvtQqQLhLS2jCxrHJDEqgpI/wRzP9pj9ph9mihVN/wDDtt/hb9A1T6v6X1bl6EPHhSlfQ4+hWnbh wr+zTbFUsj8x3Daj9Xj026FtFLMZJDZMFdk5ikchlFGLpXkUowYU8cVaPnOxqlNE1NmmnS1oLM/a NWRmJNPTDbc60Unem+KppPqk8buo0e7m4iM8k+rUYyOFYDlMv2PtN7dKnbFU+i/u1xVinmPSLC8v LiS50i9vmC0EsE6RghQDwjBuISK1odhU4qpaD5T8sLEJx5eFlPEhtU+urDNMYKA8Q6yXH7s/ylut dt91U2/w7oHP1Dp1sX5K/IxITyQMqncdVEjU+ZxVG/U7T6vw9FOHretx4inqcufP/W5/FXxxVi8u u6lbS6lZ2yA3Kh57R7mHUGjH2x8bmIoV5JsI36bgbgYq7TtR8+X3pSxppyWzQwu/rQ3kMpdgfU+C TjxB2IG5XcEnriqLhbz6ILYTrphnPAXbR+vxBJ+MorN0UHYFt6dq0CrKLb1Pq8fq09TiOfGvHl3p XtirD/MuhW+oX9/9ZntEt3hUSF3mjljCqT8ZjmiopUOwYcStPpxVVTy3q8crRpqX+hKo9BXe+ecO R8fOU3Xxry3X4dsVTJ9OuleM285QRtv6sk8vJeXLp6ijqzDeu1Owpiqj+g7z9A/UPrr+t9Z9f6x6 l1Xj6/renz+setTj8H95xptx4/DirDr7zHqllr91HYXVvccHlNrbt+lbp5WSrTIUi9WNGj50VUDH 4SAor8Kqb22sefVJ+uQ2Do/p/V5IYL9eXInkXRlfh0oFqf5iaEYqnOmaxdGCU6pGY7lGZhHb290y CIGi/E8al2P2jRdq07VKrIYGDQow6MKiu3X2OKsO80y6Ompsl55hutLuX4CKCJ1QUNaFUaNw/wBl uR399sVQ48u2V3LdQQ+bdR+ss4imSC9jLQtRmEaIVfgePPrV6dSeIOKpja3Hlb1mMOsiVyFUodRe QCv2aKZTQmv0/diqZctM/QtPrv8Aof2Prn1g8q1pX1+Va8tuvtiqS3d+GuZUBtPrEfJUjXVpY2Mg lkqrKI/hopDHr3WlFFVWvK+sWDRevc3lpHNcxIwji1Z9RjKqzENGZRGACrrVlXfYdgcVTey8yeXr +drex1S0up0Zo2hgnikcOn2lKqxNR3GKp3F/drirE9eF0+sTC1sJbyaGESAJqDW6bq5VXiVqrzeL ip40O/gcVVvSWG+W9jsdRll4RoR64aP92roAY5JwtfjPIgUY0ap2OKplFdSEkmymiY8a8vS/aam5 V2Hw1qfbpiqr68v1D1fqsnOv+81YufhT7fp/8NirAVv4G82Trc6sHs7h2VbabUZLVoXgkEDiKJba F2B5A/FOQxNBt1VZXb695UUukerWjshHJWuo5CtR6dPickV4fSa964qmyJEByjVQG+Kqgb7ddsVR kX92uKsW8w3c9veXLJf3ULCLlHawnT/i4qWJj+s0atFP2244qt0y9jivP9M12VpJnPoWN21gpZdk /di3RXK8zTdq8tsVTGTzDoEUZkl1O0SMKXLtPGFCitTUt0FMVRv1u0+p/WPWj+r8v77kOHh9qtOu 2Ksav73T0eS3bXbiG4kkltjIlvA5jlP70Bybd1X00mQDnsRStSSSq6Kew+otdHzQ6Q3QMsMk4sYj GqpzYcWgjIKIrE8xVd+XTFU8k1jSYbVLqa+gS2fgEuHljVGMh4pRqhTzbYU6nFU0tpI5II5I2Dxu oZHUggg7ggjqDirE/Md1oqavLa6ppl3qX1m3cIqWX1qERBGEqB40YguGIKud+ijFUPZP5akt1RfL U9vbqys6NYikckkIJ+FORbiihGKBh0WuKo8nyvNK5fTmZ0YszvYT/aqzGjNFvuGO3j77qppXT/0Z /dH6p6lPT9J/tc6V4ceX29609+m+KsbefVLS/uDNqkEUN1OY7S2kvLcqnFakqXtPVL78ijO/Hah4 4qjrKC91IPcJq5EKOUQWrWlwjrxrWRjb/C37zdQewPcjFUdHpd6rTGTVJ5llULGrx21IyDXkvGJa n/WqMVTuIARqB0pirG9fsxdXT28SWvrTq0fK5s5ZgXC8k5SI8YoONach8wcVdp3liwh5SXtnp8ty eIWW3tBCOKgUBDvMSQ5Yg17/AElVMrLTrCxQpZ28dujU5LEoQGmw2GKov/dX+y/hirAL/TkstYMj 6pcpzd5pIYtGWfmjNOeHrR2z19NS3HfluOXLmOSqNtfJFzbvNJBcWaetGyf8c+FT8XL4jTi3+7W2 O2/TrVVCW35c6lBam3/S0EjTTx3Nxctptl6haNl+yojEdfTQKrFSVIBxV6FbII4I0X7KKFGwGw26 CgxV595ytvJV5r5h1q3iuZwViZLie4A4yRl/ghVHRj6cbnb/ACqkVOKoTTf+VRRRvfWl4skTTpBM 5nuZEaYRrEiSKzEN8AC/EO9Duxqqm9rfflrIrywJYlWETPOYBRqr+6/eMlC3Fdt6imKpx+mvLn+G P0h9ZT9CcOHrfFx9OnCnTliqBl0jzjPcSONdFlA5nURRW8MzKpkb6u6PIgowjI5hgwJ6dCWVXWuj +cYbdY5PMKXMtayTzWUY2p0RImjA+LxJ2/FVbJovnFoeEfmIJKTX1fqkLUo3KnHwIHE96HYg0OKs sg5einKhanxEbCvtirF/MWrzWOpBrb6g1x8K+ne6nJZrwNasYlinUkEgA8a79cVTexFwbaNruCK3 uiKyxQuZUU1/ZkZIi3/AjFVb0ouXLgvKlK0FadP4YqqcV9KlBTlWnv1r9+KvPqa7d6lfm20zS47h VuLbTnuLS9+MtJM0nqylI1VHohbj9olqV+GqqZaPp3nXTLWO0tbTRLSxhkJisbRJ4kETNIzhSDxR mZlavA/tbGuyqMWXz+8ij0NNhjBi5szzSMenrcVASg2bgSe4qNjVVlNt6n1eP1aepxHPjXjy70r2 xVh3nN4lnmZ9RSypHu76m1hwHU/CEdRWn2yK/diqUaNZ6ze6dOulaob22jkaFLqHWfrZ+Bt+crWj lZURxRNweI5nkScVTuz8r6nExjuNZv519JIxctcAP+7DBf3SRRpU+o3J6ljRa1oKKpz+i3/RH1H6 7c8ufL65zHr/AG/UpypT/J6dNsVYvc6gbnXptMjtpZpkLRzi21gpJHGTI8bvbrKjJz3pQcqU7Lsq mMnmHzMkjqvlmd444VdX+s29XkINY1FezACrEbGuKqdpr/nSWZVm8riGFkB9T69Gx5EA04+mvw1J 3NDt9nfFWYxf3a4qxHzQ3mh9Tji0qG5W2Uo0skUtkkcnxUZWE8M79G7U6dupVTGxl15bZxc2Nukq CkQjuS/qNQDlIfQhCb1rxU7dB2xVbp115mkIOpabaWyErX6tePcMKk1qHtrcbfD0bx8N1Uz5XH1e vprz9SnHmacOVOVePXh8VKddq98Vea65FDY3uo3013ptpdSTSCQ3kGnI/pDj6PrM08bSVMtF5OpK n9k7lVFaHB5eh1e8W/vrG2NxdRwwWDxaZBI90FjDx/unmkdmrGeB4vybwK0VZVZab5SVxaWNtYqw iUi2gWIUhR+KkIv7AeOnSlRirIov7tcVYb5ys0ubsqZjHVYkKnTGvlKs7I1WEcgoyyFf8ncnYnFV 1r5c160s4LXT9UhsbeKIqY4LOJFMhqfUCNXjUmrL39q7Kpt+jtRIctqswdypHCO3CoQwYhA0bnia FfiYmh61ocVV/qV1+jPq31+b1+X+9vGH1etfs+n6XTb7H44qx6412Wzlubyaz1W9hD+hBZi1tyHk 9VyrxU4P29Mc2AAAY9eRVRkPmn1bw2/6F1JHXgRK8CCMmQuuzhyPh9L4vCq4qp3nnWxt3j9PTdSu xIyqZYLOQqqvK0Qdi4T4KoWqP2fi6EYqyq2dZII5FrxdQwqCpod9waEfTirGfMt1qUNyxtb+a1Ed GZE06a9QgU2/dKS3I9QrA+FDvirUeleblcE67G8XUq9mnKvw/tK6fD9rala0+LahVV4dJ11rREut blW7UJ6k1rBbxoxVOLHhNHcEcm+P7XXpttiqafV5fqPo/WZPUrT6zSP1PGtOHp/8LiqTXH5b+U7k 3JutPjuGu1kSZ5i0jcZZDKyqz1KrzYkKNhiqKsPJWg2MfCG0RwGDRtMWmZAoAVUaTkyqgACqDQYq qf4P8vcp2/RdnyuhxuW9FKyKWLEOeO4LMx37knviqcQRJDCkSKFSNQqquwAGwAxVKb+11Ge/fhJH HacBxPKYSeqOXURvGOPxCu+/3UVWG21iOAw21zAvBOMLzRSzEEFuPMmYM/w8anlUmpxVpIvMap8d 1ZyOGQ7W0sYKj7a/38lC3Y708DiqO43n1OnqR/WOdefBuFK1px51+ztXl13p2xVH4q7FXYq7FWAe frnQIL0DVL+K3eVVSCNoruQ1YsqFvq8ijiZDTdRX7NakYq1BBZxx20aa3ZWtrIsaSRRyXMEjzfAI yv8ApaFS2wZGUsagEnuqjNL0mznmeNNbe7EMrzItte3RdHkCsBJyuZwyKsgKow47jbFWS/VY/qno 1k4cuvqSc/8Ag+XL8cVR+KuxV2KuxVjevaxb2VxNFJdwwXLxj6qZbaWYJzqoaT02Xknqca7r4V3B CqBj8+eWI9MjurzUo5kWBZpryGCcQEFeRZdpeNaH4S5Ox/lOKq9p538pThfq16rKSyIVjlCkxj4g p4U+GlDT5Yqmv6a0j9F/pH65D9R58PrPMcOXL0+Nf5ufw061264qm2KuxV2KuxVJNQuHtLy4uP3A i9JeTz3TxgOGIVfTKMiKwr8YNSRSm1cVVrC4jurNZVMLpJyFbeQTRGhKmj8Vr0odsVV/Si5F+C8i KFqCtPniq/gnoceI48q8abeOKovFXYq7FXYqxTXWtYdY9Wa9uhK6AQ2kVxBFHXkApEcjx8yDX7VQ a98VQseoafpthDZX890OQUvPc3kEcqIoERkdxOrU+Es1KmtSatiqJb/C7q13+mGEXpcmkXUpRGI5 SaPtNwFTC3Fu1GAPXFU19DT/ANGeh9Yf6v6vH1frMvPnz+z63P1Pt/DTl7e2KpvirsVdirsVYh5q +qfXeb6aty0ZUtM1g13QkHf4XRiAq/shjirflnUXmskA0qeGNnKqxtRZKI+RZawzStIOIbc9+w7Y qmsd9KzhDp9wlSikt6NAG5VJIkOycd6eIpXFURUfo7/eRuP2fqn7utOlPten03+1iqY4q7FXYq7F WJ+ZdWnsbp3QapKsZj5Q2NvBKreoeIAMicjv9ohqL3piqiPPlpW2ZtJ1ZIbmYwesbKQiNgAayKtZ ApJADBSKn2aiqLh80CW5Fsul6gJWjMi1hURmjKCvq8/SrR+X2qEA0OKpp9cm/R31n6nP6nKn1T91 6v2uNf7z0+nxfb6e+2KpnirsVdirsVYb5n1jQoNTawvTqC3F0vpobaaeFCDGzEoySxKGCqdxvX3x VJ38x+UdJ16C3WXWJtQMdFt5Zr5ogkcagF1upFiLFIuZ6t1dupOKo+T80vK8aymT142gNJklRYWW kfqt/esgYKtalaim/wBmhKqbf4x0b/Bv+Kqy/or6v9c/u29X0+PL7Hj+HvirJcVdirsVdiqRapHq SaktzZ2iXPw+lIJbuWJQjNVisIjkjZhTqaHtXFVOeXXzCWTTLOSckLwe7cLxqBUv9XY/ZZjTj7d8 VTBE9SIevEiu1eaA8xv7kCv3Yqr0Ho0ptWlPoxV//9k= + + + + uuid:C1BCCE1871B8DB11993190FCD52B4E9F + xmp.did:3cbe7e43-d8d8-f741-857d-d8115d20e967 + uuid:b90a3430-205d-463d-9657-410ebf9db87a + proof:pdf + + xmp.iid:8999a25a-7d4c-9342-b05e-40a44237dc4d + xmp.did:8999a25a-7d4c-9342-b05e-40a44237dc4d + uuid:C1BCCE1871B8DB11993190FCD52B4E9F + proof:pdf + + + + + saved + xmp.iid:68134316-a8aa-d74f-9108-ff386fa851d9 + 2025-05-20T16:57:32+08:00 + Adobe Illustrator 24.0 (Windows) + / + + + saved + xmp.iid:3cbe7e43-d8d8-f741-857d-d8115d20e967 + 2025-05-20T17:00:33+08:00 + Adobe Illustrator 24.0 (Windows) + / + + + + Mobile + Adobe Illustrator + 1 + False + False + + 750.000000 + 5573.000000 + Pixels + + + + + PingFang-SC-Bold + 苹方 + 粗体 + TrueType + 10.11d9e1 + False + PingFang Bold.ttf + + + PingFang-SC-Regular + 苹方 + 常规 + TrueType + 10.11d9e1 + False + 苹方字体.ttf + + + + + + Cyan + Magenta + Yellow + Black + + + + + + 默认色板组 + 0 + + + + 白色 + RGB + PROCESS + 255 + 255 + 255 + + + 黑色 + RGB + PROCESS + 0 + 0 + 0 + + + RGB 红 + RGB + PROCESS + 255 + 0 + 0 + + + RGB 黄 + RGB + PROCESS + 255 + 255 + 0 + + + RGB 绿 + RGB + PROCESS + 0 + 255 + 0 + + + RGB 青 + RGB + PROCESS + 0 + 255 + 255 + + + RGB 蓝 + RGB + PROCESS + 0 + 0 + 255 + + + RGB 洋红 + RGB + PROCESS + 255 + 0 + 255 + + + R=193 G=39 B=45 + RGB + PROCESS + 193 + 39 + 45 + + + R=237 G=28 B=36 + RGB + PROCESS + 237 + 28 + 36 + + + R=241 G=90 B=36 + RGB + PROCESS + 241 + 90 + 36 + + + R=247 G=147 B=30 + RGB + PROCESS + 247 + 147 + 30 + + + R=251 G=176 B=59 + RGB + PROCESS + 251 + 176 + 59 + + + R=252 G=238 B=33 + RGB + PROCESS + 252 + 238 + 33 + + + R=217 G=224 B=33 + RGB + PROCESS + 217 + 224 + 33 + + + R=140 G=198 B=63 + RGB + PROCESS + 140 + 198 + 63 + + + R=57 G=181 B=74 + RGB + PROCESS + 57 + 181 + 74 + + + R=0 G=146 B=69 + RGB + PROCESS + 0 + 146 + 69 + + + R=0 G=104 B=55 + RGB + PROCESS + 0 + 104 + 55 + + + R=34 G=181 B=115 + RGB + PROCESS + 34 + 181 + 115 + + + R=0 G=169 B=157 + RGB + PROCESS + 0 + 169 + 157 + + + R=41 G=171 B=226 + RGB + PROCESS + 41 + 171 + 226 + + + R=0 G=113 B=188 + RGB + PROCESS + 0 + 113 + 188 + + + R=46 G=49 B=146 + RGB + PROCESS + 46 + 49 + 146 + + + R=27 G=20 B=100 + RGB + PROCESS + 27 + 20 + 100 + + + R=102 G=45 B=145 + RGB + PROCESS + 102 + 45 + 145 + + + R=147 G=39 B=143 + RGB + PROCESS + 147 + 39 + 143 + + + R=158 G=0 B=93 + RGB + PROCESS + 158 + 0 + 93 + + + R=212 G=20 B=90 + RGB + PROCESS + 212 + 20 + 90 + + + R=237 G=30 B=121 + RGB + PROCESS + 237 + 30 + 121 + + + R=199 G=178 B=153 + RGB + PROCESS + 199 + 178 + 153 + + + R=153 G=134 B=117 + RGB + PROCESS + 153 + 134 + 117 + + + R=115 G=99 B=87 + RGB + PROCESS + 115 + 99 + 87 + + + R=83 G=71 B=65 + RGB + PROCESS + 83 + 71 + 65 + + + R=198 G=156 B=109 + RGB + PROCESS + 198 + 156 + 109 + + + R=166 G=124 B=82 + RGB + PROCESS + 166 + 124 + 82 + + + R=140 G=98 B=57 + RGB + PROCESS + 140 + 98 + 57 + + + R=117 G=76 B=36 + RGB + PROCESS + 117 + 76 + 36 + + + R=96 G=56 B=19 + RGB + PROCESS + 96 + 56 + 19 + + + R=66 G=33 B=11 + RGB + PROCESS + 66 + 33 + 11 + + + + + + 灰色 + 1 + + + + R=0 G=0 B=0 + RGB + PROCESS + 0 + 0 + 0 + + + R=26 G=26 B=26 + RGB + PROCESS + 26 + 26 + 26 + + + R=51 G=51 B=51 + RGB + PROCESS + 51 + 51 + 51 + + + R=77 G=77 B=77 + RGB + PROCESS + 77 + 77 + 77 + + + R=102 G=102 B=102 + RGB + PROCESS + 102 + 102 + 102 + + + R=128 G=128 B=128 + RGB + PROCESS + 128 + 128 + 128 + + + R=153 G=153 B=153 + RGB + PROCESS + 153 + 153 + 153 + + + R=179 G=179 B=179 + RGB + PROCESS + 179 + 179 + 179 + + + R=204 G=204 B=204 + RGB + PROCESS + 204 + 204 + 204 + + + R=230 G=230 B=230 + RGB + PROCESS + 230 + 230 + 230 + + + R=242 G=242 B=242 + RGB + PROCESS + 242 + 242 + 242 + + + + + + 手机颜色组 + 1 + + + + R=136 G=168 B=13 + RGB + PROCESS + 136 + 168 + 13 + + + R=127 G=71 B=221 + RGB + PROCESS + 127 + 71 + 221 + + + R=251 G=174 B=23 + RGB + PROCESS + 251 + 174 + 23 + + + + + + + Adobe PDF library 15.00 + 21.0.0 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 9 0 obj <>/Font<>/ProcSet[/PDF/Text]/Properties<>>>/Thumb 12 0 R/TrimBox[0.0 0.0 750.0 7549.0]/Type/Page>> endobj 10 0 obj <>stream +HWۊ$}ﯨ)uK0a~[Ŭgƿs"%uVuUVzfZ +"8Y]Rɗ˧?~?__>O^E]1Kp6^}}%t=O?bG] U8]YEUHU);^jRί '좧E *TЮsH:TZPBG 9As )TJϜA';N֪,%CΐES,ٹJ|dV9vB#=0`0u#xUJocjHW-yl\Kt6m3=AxV^. +u 1 , Qmߠ'1ug4%g:[Voy]fk) q*tYVQ?+,{.SYnS*j(nYSZ2QЩ:`d$1ϯfjl.UDgR:̂cGD$.Z@؇͆65)h9fw"nVBRn]\-k *bPYakcO3SP (R6 ${#m.]gZ~zQ?A릅34dHhB#H u_PU6lZvA]+b4j4\ZOdަ)*pz0P?h_ͧba-h[y D؉HHVZ1 =syD2L( P N%!בߝ$EA`%[*l1ߡ |JdLRtBn1uTp {RrzӺrtvbx(QWbc}4q@s +\vB)Q9Q`OKZqPu|EqT/uYhe-!D(M?hDdHGOFrs#0?SC[׆ '0ᰗ){O |g:~6># wG?2) G!2*HhrnV2*&R#*pW(Px#"\ W13O^3o+y[zjB^=Vp=[kyB4SǪ[.q[/n+|[2ܽ1[~|尌ZRYsfl%vx &`vr.$]tU$buv2q1<4qrq +KZZ\o0n:EЫ{o< +1Nzscuov^IqpPz4<9Prd ֢\ ]{lu1 bٙzOށȇiǣcds۷IY8{nj^Gqk+|T@4^A͛āZL8ŀ6WP5[|!E:HJʽXĘ=^@P>m do` xGzd7}N1G0԰]T54adY'+珀~ d?QY*tcgUf +endstream endobj 12 0 obj <>stream +8;Xp,*#I+?:PU@NZj"RDUc +endstream endobj 13 0 obj [/Indexed/DeviceRGB 255 14 0 R] endobj 14 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> +endstream endobj 7 0 obj <> endobj 15 0 obj [/View/Design] endobj 16 0 obj <>>> endobj 5 0 obj <> endobj 6 0 obj <> endobj 19 0 obj [21 0 R] endobj 20 0 obj <>stream +H|Ɋ]9~Z)hc^@\Նvڤ~PwɇDHߏϟ_oxzo//_??"}ۛ__??חԧz_owo߾z3wnOO[_?~/ۃ>^~sbf>ݿx[no{s~ú5~/[~c4ݦjܦB~']&c9)G=)O?EIM;-b}?׊)ZM=Ʉ&{>Q$8wm93%뾡eEֽ(vEٰd bLLZ:(:tBmIOEgk!fQ3ֳfx\IE8i%E Y$W>+{ieXXX(l=&g!9ւ(u̲U| 6r8bʝBk|PY݃=D)f/ <~nlše ǡ3TY0P  :{r |^tztt+qfձ%vFɈ|E>T,h W\*]tG]V +lr];wTU-u ~P\xI˫HBS <]}y|t_U{>D)v%T +/h%֨{jxO>6Ig9c;k5(dɁdE샎N抜|LF{gAgGgDKGKEKG 5JO[I~;Ӯ ):ŋRa-y1LQJUu!Bw)5gm K9HZ$uCБ$B!+P1<1/{$$e8'kkgtЩ>EiegUy(ys Zȇ@w"E +DzޙKr[W $iXG= :BGuDL]%Qhz] "0uS(Ӎj9EbgA?u'*FuA-ѲFE)-\n:E"k*Φ(s\$uQQv(ok:]^g=qQq,D$&}J +쑋bQ&'4,HuiVP28|ۣnY;2?SB"۱A3ɢ$*=ӓC'VT|NjDձ&)QpN}VtD%ԞJ%jV?+UHG˃mk\U/40UK״QU!kЎ+"Bj&^(eKPNk- 4}gQDzhS$yіǷMG&O8Oʚrc6639yQjA^JHb"seI]gO3:gH=35Y-'ʍر]wmA<-YZ2QO3 iiЇдr_ += Jx5/ 6۰|wY֘PF DU6!/(F,]dJ ֥SUעGԅAu!wa~ey2&}innzyflSx:&o:'qʟkʻSng&yY1CA*d7Q^{TK֓(@Ϟ.'ޥUBL#Ik ɾ`a1]g2B0,hqh-l_AGה0u^@6Bj77H eu`CN`%( "sAJM,PpM,KMUH.-*J+IL.Q*e%*(u0@c +endstream endobj 21 0 obj <> endobj 22 0 obj <> endobj 23 0 obj <> endobj 24 0 obj <>stream +HRNAv35YN b,VbZQZN&P6< +q{wAB7?= ez8|XM 3ۓwΚ!v6kAB$dW0w|'8o "AACC>]*M՞Zw9ɾ%,3bZTmPki3&mD :¸|‱4&(5V$K2#q6]ě|o^04MεX=31´)K"_CK)9?h|bUjv?jHnjM4.÷'Ǵ/>x@9rF&pH$&\Y e2R +endstream endobj 25 0 obj <>stream +HVyPoWH iA t 41`SSۀ_c1mמNڦLOZiiJ&?ZgRL̪߮PZO;o=B "jisЉ~O ½i-0524ȼ + Hgcjd|v}Ϗ87~WT?>0A6އ X_410>m|W"*JC2 ?(lj>OD&RO݀<`!7u803-㭘{(WxQ6h4UGF±gXh--65Ymabe;N5`84;ѪTVK,> MP \FkҚ8 9oa'\*B6-{V! PF2"L%6 9$'f8TYO~m|-KoK4Phq ԗsClE^0{67Iꥰ"v? Z3@jx,4Ӭt:ڣCΛBUY92 v>xolZcZZ84-4 +i6aC)|]sbY%:9sgr+ִJ^eȏ}^X[J}ndLwQf{[/t0Ik&Zwɲ&<=Qɒyik<>b|"a֖HpTL1NlP4҄ pAun[/&)fؓ'8AVybO=rc]mRc]]vtנ7|uW/]i@G tTH 6rD_bMHmF {_E[gLp[_z LɶrkAQG+ t;4TQ^\/QZ{GOl@n-i=e|Kß {<=ZBgNU|UaWVo zDIB>K 6 u og[a5.НfwFl& W7 +Pд5B~>]uħO BvS6^Uo*]O|wZRv;W +"J:V*t_-i~Mhfs"}Mn %#Ptj* +Wtv;t7LLSjjB݁ #GԠMʺ=Ŗڲ2_KY&3tOy" ۪TweLJ7HPtle|7mVs|Syf޵Eq>pe zZ##D*.?K%Jݝ]<Ρ \bv)L`Wq;שm<Χ|D?ي)\@kL<(_l,M&3-zHWĸ )F!M; +*VӡRZPPtN& kyФB"evheR!җ8Pd Mlnެ֒ b/|ԩɾc+2'] t\rbӊ mLSmsTE,w.Qdu)2ȊHX>JvC|A<=K~/7_rtv*>E )SR$ArPgEqIpRlir>"JnOpfJcHu{JܗAឳf21  +wfvT$%gI$z![ˁ9aza.Wթ/w}Ϋc7Y! `ߗVKE~H3Jx^:ah + 7|`ÿٮ,?F?Ml FQ@[@PTdUD5jB\&a\!FQKT$:!.db\f2N,gP)~=hfG5wϹ@3IiTwFc9V56uΧ [F:'&qusvfmtڴkjKe B7qzcMbXrFPXW(Wl=̌vMe0N_#d8 WUA`dԉEik_@4c;v +O>g|N|}?Db0Ëj|]Cu.κP k ԦmѭƝ#ZcM6"|rD&ֱB8zpCԜN`q:\AEJ&[$qg^qғpqE'ʳՉ %h!ښf\3ΰ?LW5=;{2 H,\h ә!~eAtëupfA2]DxףƙZ~+:jO 2#::Ёqd{n%zrYzr!Bneyσ #>9s'&7h.P]%_%NFβ`&Yr IN) oka@EB}yCeD1ͭ Nrw#D`:3w> %;~ !QZpžwqhtaCx+o9=iYnNGGIӧ"F)#A/)jOY-Q Q8c_ptp: BK -ca&PflCjaP[-spN)ّgҥo/11gDe&[z:ҽxӽoY;̀ +!WL#(1ʟxOI@M:v2yk«N7U?}npf .X[u;u,ߜllkO6$^Z-ݝ Mz=$kиhDstU'ӔP5jEԆ8]9ӵ_$2/=#ڍuĜbܱc1g\T Z$tv,?^@ɶ은5vvLJ\C,sv {1f2c`El6j QQ27SEo~>8㬓Z)PJ/TͧY8 D߰s*{pYCs]6}9),A4_4ÐEQ)'tK lCzg/ l-bs3F4<|=PFW=W/Gr-ˠ8JfF!}Rrwm[ŦȋUqJ7wS%*9-̟IbU ̰>#<-0z-(ƟNo!8.㨥:8,ŷ2c/p(lAVq.?:-ئ^} +ALm]=cEv$5RQ݄5 RZ +_ +miWU2;>U~, @ۮ&S},3A2$+H?(`SB<cz&f"Lwj,,&WLчMbz-R¹M $kW2ւܸOF6~|:,z++mȿtG_%bg "S((/ɘAH͞BWׂH6OI[KԵ%Tjngܽ+Cx5u{Mb +%@^> W0RDҥ",VecǺSVhnveՎVʠ]U ?%#^X}Lyy0Rb-:S"RwۼDFNzy\˦5?FD'ffEM;`;d"<ϪLju<!N_xn p`OS|y5pR +\$э9;5m@DS\U#TS=mW'vechnN㟟9UG쒘T&;r3(kN6C-k +QqF +Y%j +XJf>7u4)4 3̓{Uq5:յc${Ƅ˜ l:GhCU=~"o+7ɮTͧIKNdc«]i6_v}@8G'NDB|qʚAIZa4%8"x l 5ߺh VS}7Y9b]08j'&^ ~u+Lv\ + zhDmOQʾۦ}W'×fj۵/?^v3-Srf ը3޾ܴib7{1&A!Nɢi.MNO<;] \tvN] ݚѲOg{)澇bv>Y+nK +]nK:BWXG'ѼxCteЩY +y O!#Ԡp +`6mgh;Nl&oSn4-9,pXu3j,\er<0*<S?QN8tH4BP&NRZľ U?S~KpಶǕ'^T@ƥ|<rͣv= ͜?L40$Ë`03XD{0Zޠ&h3._`򕜠;Sx?E3݃Q="%Mo2b9 :F%M #* +wVh:y)~]ޜn5']_Ȯp)Ն$F^#].(&=-Z>(<B̄?>趯onGÏNΉ}>@i8c0ȕ'  % c•cqgdKOhFfR^8 E6hBWs9Qfij:nh00pm]o߸cn 6N@Tq u0#4=22,۹R-+դu L#%#hMvϖ i$CzK S(v nWT >]k֐BnJkJb,V7_6h +SL5E7g,`'O{Sm8rK#_]* nA"5C#e=z(/h#,>(x]<^yKo8?z`SXuƮwK)Q[4,g3_ t5$c\ܤ>Y ~U#2f\TRa(r=5'4ThcC_eLN +3CC+lFبZK(wX!Q?>]CH TХiԄwriORA -vKI.<3>emELf&@jIKȢ *Va-}Y +JS唉RG6Rq[BO㚞B /t$p2#$D`%՗2>QY:!#jԺc jR Zj +C{ҲvC ,B!!dyK@V% +l(((nP\ vFkGEغx[GVϘޗ!prq@V{^]|-q +:w7KB eAm2z{' A>hO\;,*_Vy`3+ʮ|R,SW {'F%,?>l@ 3 nHR{nzIh7_/7Ll@w@O2LJ/d +%ƠOVs!X2OUq9ttC4r`QJHmv. d/z?Gfe>h6}6{`;*rMų-ڦK"{ uiTx^9YH +yy683<_3[qvS1$Чs(OtPh?5X&҇^NEP|9­:#r>vxo ImUcˬsg@0zj=oT-=< lfKʆ" >;dcX::+‡ ,Fvbb 9-8 =Q: S >iHxVBuekswy_Fc ֜ހ/W6JQ}kd &N1&[]#݅ܗ?&DLxdOL1uhr*UR>Ux`y)PIC[Ri/;JekJ״1Є!AԐ'"zYq+bHe>rā76Ekvf@k~mۇrh=ߡC-LO Kv! ummmL˯5ϊdv8_?9xp0QʀM4 9&HYpМ ̇)-g.&Dա HowZȠc l+ TJ Җ|'X]'K|}iv؂[bt}c7oysuYs,ݍoRvjP-&eFq쩯֕hB]{[gs:mVԸ#̇]۬ oo|0F?~J ]~1~#o^rǮr 岮Tܽ6AEwGhVZoOen} Wt4qa&,J93nrVoD.Jġ@Ͳ%xP4IЪ} փ,|& +TQ8beNF1/)SrWKϜ> 2ΊW7ERzgHK7OBBˆmBy24>]Si:Z>*:0KWg;qB&8 ui:r6 +b*!a- Fs|FoJGr@O/ wmgh*@ϰU(H#]<ꩀ=?8~)mLB1MÌ qJq06LgLJrUQT2xUy +>sP\XvQ} G?pB/tAL@3>H~kۜof{\4+Ι30PX)-17Jz&߄!',Uц<GJQ}eH w 0G35 +K- gCjՅJi47EJs;\#/Uuƹ/ +100̼;"*vI%h&ړ`Iʢ%` .m$$k{q88~.kmt 2y\.4 @j:NfA +ʵ<:?`+%*O(ɔnX$Eؔ/J7S;=)ucL`f83ǗY \udla/0HKBߙO=RQoHS$!hvU((d_2'b؅, ܴ؁W3\jC!*Xz;3Eԋ$b +(9wr'*&sm7xcwZQQJ!@4mW7z?lǘI#)1;&ƺfȠr;F$~,&w{{|VQa(\d b<:J +u_ߍw֝Aǎy) fdDrA77"FO߰`L)I19Lp +q͟_ Ob{!`b[>y|>+Cq2Zk~-H]OXJF$/\EtĄjLqq:]eǷ~- O FdrGc011фlOMUx:Hq~ N~3jPŤ*:|1#& ˝qfa`%dzW>Qӭ^[fYDw%pYD38SF&me($Ԇ"[|ҹ}@'\^x_f83i+;/S)p+MSo9gH/q5y栐* +f;lg/srM5k;VæNQ2AtF\ D\Nڸ0٘ZR_UnkXoֽH*cbUΐUuKjW4KfVoO3YR; +o*T_eάUVۢg?TUOա1xlu$ûT[RS`q#>ҋ =M+X9!j, $&@HG~xbe*؆RRZ^e9Twj%R; 8_ 7H>:0pлȸO:c~J#,,-QvIVLlX=|'h2!#{ĉ^ Y:5etO?s?Jjp9ϸݻk[.s 8t% ,El_Z8ߐz)mtV+S%?0p0^܎ljUjKύzpGQ!/ ,}ed _17q`ɷd Q}6:` C1?s?rhގt^nĊ? H!vt!\b".mKDz ^, $iYlf +J?RCOmbǗJ^8wػy{ lH' jAJ +xKWQҲQ:#ゥzuR˳N*0C/:}"|h?X݈<~U x{n>N_yK29 +,TE Ix!,?$s E#?BQqUa#)?^s{յBxu'ZڦpW1$e>#>dg]Mb_Iz@ll/WC*ryYWTOҤ襜xL~PRU4_h 9UM!ۍUЎ $):-2ҪS'GX[h{aږ@3el$ EaX?QC_ hHXVCZW<)E59JA 5ёΉMjmRYX?P!y^Fe0Ph!ىZm,:;}g;VV@<9}7uNb&~TTgLA @ˡ~!23'yOF8-Y(rPt+^ʤ0 QNKe7Gk/:Yg}K0s2s1OwN0Ԑ+q)WzGXA| 8H|eؓbƣYz߽+5CVݶ X?잽Fu쪇8l7- y(CHmcC~1Q1-L6kaGqj*^\>itY_&ftcwCcy>6`|rRɃBW.v݇NJߢ>R丛7w]{{ŋH54CvTSpeTA5? aU믏4~R˝ + $Wkh@IE)/];ixh|Of~en-Vf/S'NKMyI:j +7DBj=׆Haѣr剉+t*9քNdp-8[RTiUV6Z: MtS +Fꔍ|F)F<3@PZI(%,TOv!+K4fk7%%KFt}ƱO> +{܌UόE[l /ut#v3"K~<4.9Q +TEʜ5 CryUkP*O hpŹ .Zq:{z +&,"$Shv-A;A~ZS`ζX,2Nc uqS:-.ZZf 8E xYС+ =@×n"x>n{'5#ོ8)@+ YsTsc y$;NJ g$ުm>lXUdKr3Z=~h5q:!~i?Ɋ,O^ej4e+pPsD|A90MMyW͂zJAw#1&\ls~脟v;U)dut:X:䝄FfkQ9eihp>wr/]M Q73KxTq O.csS-{/s9~ + j&zRXTfO5jMlAB3iԜ}A)(%ZR[F +2f;&Xv*j>%! A{KK@` V"ꎅiխVGk +XUw׮ێʸtqw֎k>{/Aݝ̗7I}QU^ 2ܮQ==p|эDZcZz'nGXNƱqc*ȀQbB ޑR\R&0E P#˗x;o^i/,"3ya*,ѳ@7$B4(T1y X3V~7קw +K*c; o$Ixϩ;lb;XBF/Ѝ%hc @ p"X1'Uo(dE٬,yR6׈BC=+fEx $ *Pq7`8֮eŠaq(Hˌxgqa/7*`rW(0m]t#6iBz/&^$ἧ1 \}AOU_= ~(j$vo C1nh:N>Y ZG5/RۛI:e=CZ\bkdKҝE(qeY |)DCbÅ{~8-~b0gST /B:;JP:v BtV\YJg?Ԙ23]HWU;-W9L8cY};&dVL7  <zJT}fM . _nm3=41u&`S80 +{!ZPhD:cDu".6TaՍ  geu!'ƥ`kdσƒH a xQbK;;@] "fb=|OtƝGɞq=R(Un yc`r=4٩Nj)U+)3S6+l9Fu'KD~f>0Kϯ_G3?eڗb*oQ^NH]ixė'NNJZ]_0p39Q8ҭ8Q*Ч:Ezk^f)17ƘKz<ws֌x'i/sF~ϧA+@7;3-[t@ +99ӌm>(<>a"%5Js[ˍp}^yIFLР"XrΓ:#A,GHBpHRDmGQ{+ȢoVT3rPTMnIq޲Fk?=0UaT ˾U炁vhisjY)_O*JWlh -@Qd{$xs2|3sX}NmJ*|_aFEǰ:J# &d=oڈ &ڭ2hctه ;me[]z׫y5dQ&9HƛAgv_3 +H4;e+y5@Aٔj]P^gTFw [~u Fovn*g_&5"}z&^e:\\ +akNV1|Ȃ|k7 { '&И,٩YuU}ʾ2Ǥ0 <s{fDQˢTk+;svf[9ihv:c}3-|tZ37P Na!L%̱S#@Fc Zn,hMDqnʰ=\oҴQ* E_[^2k8@>6Q3Jʧ y e}nE?UϮJw# +.<+A޿E6M p710N"{ z.7*˸C+$HXs!:>t=LgVJ-K\g 3Уa4vҠiT* C|לNό/׆\Ll6RB|&}z &f+{{7ل_K CgKMG*Hт\'.9xMfcȫ:gm *|h:Ky|7j2"?c}EK1TOCπ lݓ"yOrjC4#JJ(B/N& +,"[5@DXהwwŲal'H+Ιc4充-6>*V,Il^^ĦP I.,K1$C"kҨT +m$q.ΰE: Ѹ2]0*tW;)eZ]wVw_|{0AA#4DbRRdW(p@SG&0T?Q kJC?riQ>4V gq'>X6kJ+7ͱ;L.[I0ר;,͛ pas)½Nª(QzV,hrt)t;6]],fa4qzЧ&2βp ١ Z#)wtړ=|?r6:oBy>K5$BvCckjp+T=?Hbg2uLS6L,Qqo oc,'ZBC25n肖;QiWt + 6ɹ_ĭ.߻dLōHmXBiWͦCOq^js첖2&36T[?gSiM*kl]!0Oɣ"KRxN_8|z`x ( F]"Ḃ]5t%D(XCtА{GTNo"6P!+&ugOGnmq7LH#m0mUηU@ǃN\KJ9@W";=o"Kw`A 0 +W} ܒ5s=64QjZ9;ՈR!s uf:îSC41ׅ^AQitnAhaaK@@n  A<p u ht-EJ㑈YXƭ0VV-dn1R59:LB4SW eIЎo-`DW,w y$;%UgG=ԟ &͗a6c]vk]SG]]^1^#,-167^\ரCY&>2f4Y5в h@g9Ccd/w0ԡ);<{$x:vN FE%O2 2Tpll/ŒMb(ꡜxa`Kִdu[P&sDREp-@k>{a6/YLظ9G!DyjM@mb`xf +ZK-^#ro:ӘF+3]HՀ=3_b޿_~8oD3,FVW}5y5)9cDO,.uw߾mv2}\Nms;QRp~~n@EUCJ`~ +}v:9ϟʲYWSK2m4uuaBbI " W4w^y 媠Nnܰbm|9z` ̶tڲҕYB7HRc?Nw>Rn22"Ru8b6 /rqXt'90&./UU-}?{Tu]1fY2-h@'9f__֟=jF},%\INfǸExng\>/Jn$w1>r"pT\Xue-jaiT{ö#}}'bFWϖ~8:)Bb4Nkѯ0.*c71c'\0=d?uIŤ)6sǠlZC"W\Faw@Yq0Y\?8j 7(zQ=lD$ѱͪ`b$&a!HY2{H VI8G(ƽ[Z:Jh P"[? wGF>tƚ6{IA%[:"%d[huk>U%/3dŽ"RsU򋃗CPC@ln9$[hPEkLy5\:-H_0D#O=/:yZ^{:^RYE藉pw a/bh_pܧe-yށ}S1/ЍPʓJN.on߀Hf1̨V31w ᇩtx~j4m'6lCʺ9/"t`n|f0 +K~/X `h]_9BhTŨKL{ƍ+Wm wuVWnɮ(-yX_~%#E#,fY;3'Q1Br%3^jF̑[RO%O_l$H"u)V՝/|\).1 +2TUWAϰղf4I%C5˥`*I,$VLi0)u'蠶Q@ 5xSrUPjЫPk3-rO-Hj_'e=l[B-:~I1dUQ_}K:MLяZoZE&% v GK?A)J0vB QOL It<$!ʃa*fc-i.p R'nKJi7,`|u|RGͻ)%o pY'o~ +}ei KM3Ew,!y ֿjO3}"'&d _?_xiTeRNW:1.T%-Vjp90p4IMДfH3ٙnJd$Z^=#B9E;IT6$q& +qs dl@IRA*Qy/ <rH,dD?.F\2 '"{J2ڕp$LN\OVLP[FO|AOmr kFػnҒ?GF&= ߕ\nYcj]FW8+4gqT(yMʒ KNT[Rkoǿ]An?Q3kw]p4n 3NSeFυF.mLy3s2^zwƥ9 MUDy!Z/wvVTV{2#ѿ"~e +;r 1`j//4 +Xщ#msm5jj G_&-.1/Hc&uϷ—A @x`V8lωm~uSn- +N prTMJJǠ v@ZU>-x |f_[=;,&YꗑȈD5'UPmoWJA5ձ12v U8Al%^][?:Dr T*DG,Ws:CvVWO!͑#Y}׍tQc+8*aE@d\>b }*";֜Tnoƫ<;_CBn !@ߕ`B8IjocݣZcݮnuXV[;vu]tv;;#63oHx|smmlgQ+$ +)sYt Pa F"g*Q麟`az ?U*iEE\BJ4w;)Ak)1S2:!;tCXCZZ /HN$L n]DVlZ ߪ+A4> JFr|LvrW)WQF,e) =#lzMry1N&S +POd +BjIf澾kT74?~+QOLͩTbzۙL3c.\Z5QܹAitdj]>XVFETDHeXww)1Q"TH͡TnN]%/I +ENh 6z{ocO0˻kᥳ<ú6nx鷭mm^~lI/o8 U +FՎAMQû3\yN#Qn2q !dm!79z\he|Jipnn6nqFx8 DlL2 +eRZxʎF#].@M֡nr+(6%oj9tی%a)Xff An)-wE,pd0졡\Smf9SOZcVf$7 &Yeކ=B?|#&C +zls]s<( g-k1P ({v:D"$RF=%`ʣ}Lh9ԑc%71&GօԀt\e!FUŭ|va. ۻ̅ U*R!՘W$((߰nj .>$w^)̱@?3Ev70]4Ѣ .H. G=|lѸxhIvѲp6rVd :gҍ1OfKD+z`7  ѼADz֮E07<2?i157I)4&Ş̞.t3"'NtVmu؂8UiUWqgGNmm]v]:nG;v!=&u7s2Inr m%ͩ֗:S5y8XLHf3t?Wv_Q{ Ċ ٟNS`*BK.G$%+rE/1,QB{ {]?&ClXd j9׊Wŭ(_'oφtmU|yvmsKN/D)Ӊ1:y"̢1GQ/J)pVK.t^.th ti,,5w1.stMΨJg[+V)5Ce3l%24{۫ ^t38pB XB`G\Ë4/EKN u5Ovu ˏFr#xd(:fw)HKy4K\$[YIqa04k:w Fhi]rKE’ѵ?RV5?\JiebFW0Jpl^l^L R :oE$v6 x??/b>x.s댡޹rg}AoӜ;~RnCj,CX6;V9$FF|jJy +y凷H{om`ZjgN\B..y~фiWFYWGF + ^ud1Έ=M0v_?1Aʦ%dj S>FFn{gVsIh]rGܙ0#UeC'k%rX3Wva<8͜]yՇ/}YyUG_٘W$~m_ח@G^ڛK`P@ZYQ,B_@@4pw "bJ?&O*78`v]*LcU+ "?44HNi%~&1IJpgynS ~xX5J5] T|fK1"s#<lZx,]!o82u=ƀ ySStzN=A/+@pc&C`cQK.4b%V+\L #P_lEl +VDW75~Pk~vzt&Z|i N \pO`8p|PI)Ns@^/KjJn}_O3p3%hYv]`Y k`'i8Iٵ؏C[k@9i32¸+9t!:.F po3_*"1B{tڿcS}>.b* +SܮO@ȸ=xSxzWRCpcRQ-O~^*:=HYD9K} S0= {+57K؞VEҳD274nK'y`D6n^KE\^ćq_oLɔEp ϴYl+v?Ƣݏك, 'Z-Y TGp < 4w6];7WțV{xԌ+[qe8Oy@Gd68pE(bP/Y"F o+\}fpp +p-z҅2Ie&[%lz:w v >< Q([Y#HCb<,;M SO9Jj]E:Pl#!hAQ|aNC켦=0h#b68wg + lpBI^TNM]]_h>į*:BZ.CԨ]cZ盳kIqm;nG +ht  ܾj~_Ƌng≊iTdG"% ܢW'%D+4Ձr eG;XὯ aβs`L6=[`Jǔr>T" NO<^)N= DZdn=AIQ}P??)%;[Xe"*-.7{vw&g( gl&0RM6R:ƹ7Kx`'qyדR]wX^8_=; $!B"b\$lvy BPނ +(/gE|V)gSFVG +V^t3ӫUz@^0o6ȣYdW4&WiGΙ;u~^:.KMF}{gO.EIɘ'h_`/OGϬW$FuhΞ}£PQ"F+n"QNcpg,?Hk~Q#= `w+OP0+6. ؟\!z8=ïjM]SwPsfc9QضtsOpKtƱg<4{K8!̆9 V +1Bq~'1M>W$u|J\= ȅ![?J:¢NPR%t@6UJ%nv\6-0L.:`zJ'xR"ͯzC4φ5WVX/x { ?;z ?8ͬ\ i0OS#Y4ҵŝy(^FDh"BɅ6EbzmοGJbW}Tlnt?s,KMǁmT@z HI3nǽbRFCdA$&|~ IwIGOptLJHF!rÒpfn]]xB[J!ºš4 )("+>:$obInW4f +om՜erP9צL8z)ʗBrLuȽbȿb d&oPZVϭ!s>UmΛͮgڔ97cκE wyc$*$QXSІF瀀2Ԛ+% x2V ϞAB2η$QYubrH[/|q^Lz$fmR^g+S @S ?FYɓ!jlW Pg1A"B$Đ1!?$J*ȩ)Q*0-Uף]wNUvuue꺺][kAV]u O|2{9|5 5[=nCzs'ӐB*pDOr"r/rw"A fC ajT@~S)ycKϛ]@B#SFaB";}U9 !~nAzkt3IĤW;!<2J}L/Z(6aJw3.c]؇<ϒD`TiyXY( +pdOFp( g)IP2םi2mDh{Mq$V_@wT; ن'IyVW2TlKmyK@DlsB"݄$6v&tH)e[Z!tB 'gz#fP >;iG99 QJWF }2xC.gELzq۾$#ʬ =?)bcJuht[⤔+ +zY?7`;/]~UϮInZHd-QoN:V]"1 6Ư^qGMxIeia`,ʟw4Ʌ(~+3`;me7)5P_AcvjyU%+bZ'/Y᜵\U6 mNjz +mb9n0LY4KVxA<>R>>Ϋx:R 7x !%>n/g?%KVHgSnJ )~Q0"t(TDO:t!oFn4d[֙Ҍф3OŘĆ+ x2 k!'A^dIdjC<5ǯmi<mD2 cf-uvRp:qL~H&" +"@Dӛ(F_| "!!l +VH;w\Б@t*.<<]Iƙ\uu1,@zBfeDbAHym9ޟ9^^ͭǎ,j /ڑrjፒ6 -KvC+ `_ݱ=q?9U3u#M /߾m<~Mq^վSZ9TƭݭLZC\.o{lkR[,n# +Srbmo/34]̽uI=@1{N V59a#L.ņ* iNܗg=Ļ.)xj7K< +!ӖVŇ{ƍ3~yh޳s +z/}uȓڪUo~1{INaN{ih4-W3㨐Hbo=^ȗ'UϴJ6&QgB*50oT }$=̠, f8K=}.)AT&0~[qǀ_} @6LG7VNSis> <>^q nxq⨁Ggct?YGx~{[opGabKֱ,I Egݫt:;}w"5<5Kթ͸+3q&{%:'Pb\n]ԎA_|kCS$a]'Phwg sIqq\#ojfP^p'47&)+9U)b{\ec2#HV@p $cT^] o^F"|[p}XOu4_ZZXTRc*ybgXb9@^xPc_hz<m; g#.q$ަ wnϜ53RTq!tNP9e tMY({3_kQ 퉯y;;yXQrQO`0l ν$?j<3eaB6ȏ99>d\V\rh"1ÄXTђ^n*jvw^NBoEеxSL;j)M.{y~ )ė썃Ds(1ę3:&'V +ֹ$k-YK@kc)`%ϷW̃@}cE+5q<CyEr^ߍN-ܚFZErH"ϐA)q40gaMR(3̤sQEV):A~MqPum;?TH'b-4ݸK} b19Lz|={(_3S0TS>t;$1Llעm\"PvZi)5ګN}Jd!20-3}Fޤ[o4?#6UZ*tȜ#DE4Z{?on)wƞ]2A5F/Mq5>/S,B81 %4C"}Kx5u| F7 KĠ!Q;+"X/ ꊶ,Zv+ʮkwݺn3Zt֙utl~99&8yԑ&G@.I- :Y'+DTQNtGг d'ߪ|e6Mm#s ݴ""_]SgdO`%3!V3OQ?l%Djc3#CS{ nА6GB +H8oI%fВa-T;"wՒLhTi)Uqzj[JռUD/lreb-?lB=hxjblJYS6[i%dce˖ãb5(*|`%cu8]=8WTU֑[d4.w_*ev{B/IМ DŽz܆hX^V ӷfkH+Ƭ!RZ0tXZw(ʓAϢ%$1\~"ܺAP Zxjꫪ5%ʝiq6Qecg. +F\3iy_)x2f{k_ZWɹg78pC/E9@YM٬ e J9O~>戼H0(;wh׎>o^X-iuˆE`UP(sE +ѭshs_w]-G.%8qoKG{bYa!z+`ѝϋ9aIJhsH:w>P,2ˉ-կlr(41G+oT$FsvΞח Ve )pr4vO%v)[)ʼn/KP\t4諱6gc]fK_c(m[|EneIn5yIM]BԂ<-(d2mlht%ypz _9h:`2k>^u{~gSWV]ŪkZZvv|Zu\aW:KݮSm{MvgOfp~;TCrq +B#MrsE6C +;X>p,fawCm]EFT""C*s~LL|Rc'Ha滐?lڑPr\rĖH\6QYe{y̒2R{!t{$P B,trn7tꛣJHd'T|{Kfgj^I. *[] ߥRe+QLD(-OϣeՒͦlFx7c;CSb\L*|G'&6j5M@? te]2`a>yY.B+4^q9Zt `zKSۭqH"LYn~maA/n7{g϶Jfj,/Aw\Frw79/Y]C5XB7>խ_y٣#0s?.4 _c`>VwǀU4lѮ +﷍F{b"uUV<#>@Y|lx`bVH9Kݢgl&t׈䁽ɒ_V:[!_,ͼz3\5KefHm%u˻#ֵE [ؾF[A*3ci>tNv +,KCHx:8d0ycDF:#"jy<#ck&ƤHٸ:m2|Η 0>C6MhRYuSM}S.(~ 8aHA<>^kFF2 *"|rNeȞuv꺺>t+[ w'&SDQ=88F*[j +*IHQ8Z5jwE`\>xP^0s73G}snfۊh@zSy=F,,c,ez:6==8zdtwhl!aL 9RRv1s>W:wSf9 JkW;oUQxG̛o9o6m٘QİW#CcuMo,@th+\ښ(9s룮c# #5ʼnRc%q3qoࣨC :V6sќrB,~P CR4/|ep8P|^2=ƇRRpTD(5m4`";j+,!Eiz|{j p1 ;~>0#Fq +ձWɫ*Љ4]beIn0f/0 y_0O3)'Qz]Y& vvF%ښ:[zΰMoeIZ,^Y`wn3) "ey3)B2Rf]ت\Mݯ:SQlB&c8jY{iϴptrtriXV^M `/ MY@V8@eZJNLvpR$Z XРmh@"~@E? g_RA]/jISr\j Nܣ6ʲET:2 +`ke֒j^Qӥ~B,Lb,@Ⴃ_UJ'<œ#k=X{nV [IjN7HhɆ_ktE aAy=\澀{R|pQp܃* Ǘ M68C6;j+ 8O2=+I<3tS!~]@YRTTp{;֒ 2߯ +X liHQӄ.KDi}znNMؔl"$f2g}r:~\d4>gapeOXi"2uBePZ@Aǖca"$n3a:` ~5unFiZ&.N+3=ד4.$[-'J{|? PSgwAA^!\ +܄qsC!@IxQ+Uj}@UjUںn+v]ⶵ֭v-ބJL2|;wg$m#K"?2@VJR,EUX0mD+'O{JON@r)| +56]mE;(BTBy?&=9@ju^5{Bgբ zx,Kˊ14&;S+a8Iy@?54|O +"%BlQM3%+vvĝZk].I9zbN AF% +Iڧž;=etiPO_&Q:24kuWУ/]2 +TcTʯ$ǖׄKehs$ zn=}N؇mU8;E-5A/ }, %j2!?/(5DϜ\ɚ;]" >$̍_j4mdl+1G"(eZ0xX(zT}?ĎlPV:f:ꋷ"09^R#1!!&eErѡlʼdV-$E|pYڴ/w-㋗kئ_/4HT~c7+ +JФI-G.3,tfyYkּsv +m U_ʳ՝F:@ȐĠ鉴ώV2!O} \so^wʮZYCFY^g`28B[P()ALP;P0܇F_q+ʗUG3| H 4-F.쾪qV!##&;@ 6zvXiG]NGӈ-8/ϒPJ;NfcV+xfu\¦UԐݸnȿ¦Y M`:< +>/8}Z*d B'ۤEY"y s48|!# DaS?٤zeML=zR4;J-l҅T],V1~sDM,6]"x.܅ZaEeGwtQtjҹqodƌ{_~|\8fx| pbɗ˗d˲d]JZK-ٲ,[2_ %I4O:ak6$0  $)BaLJJ0?J6nK:;Ѽ.a@>L,+pYލ]*AMiScj|/,6C./;4 +|pnŨEgx0̡(H!bG3f "'vX0RKH,ܖQ\*!EN-Po( Vgvi fFHgtu ACMZჍ/׫+[@PNJ6x<(.e?~ +'tHG5@pbf$35,Q.4*AejW詩k׀r]413;Xu8EPjvd%Z:u=6G"W`>vM@'0P__FI`$^k9iQ7g> 1ϰ06|C+Ī5m(;J}[+n;y4t)m+&'>I{-skUqt YPQY,OQ~g%Ur v'/niVD ZO835= +eI٬}e,2{ ,тtG~}M¸0 AaZ#w ø Y*HFgoo?<ֿQxpaZwM ܮYȥXzOrh{k~Ȏ;ϡF݋Glu0+G fwM$T">E gFqǖgi2hlËhyڱ5.4啠7KAۅ_O9%m_5.1[j`\2ٚeZ`s{n\A/ omtXL@{A@Lyj]t!/^vp(``r A)PLJF*6D$=2deo S3|m'>! +kǽf'%sjvN^ԘKDx,wĺ(.e?#{vnv:,9xmx^n^+UW@x՛U_wTmA`&xfi4#M*=OG&H@ f'b`:c{>hUf; B46t9;mjϗDr㢫AZ,X_W\'W)1)PT]0cÙGϑjwGAatRseR4>)6 +aQW o} ~#迍WmJ0Xj5K6K>i߉ťϴ!P$@v5m. E{SA@$\khΫSAJHƞNsOo/rZlp'PN {i9ZYW)wֵIZKk஢"3qq̈g h2gAخ%L٬9) +ʍ-T,:٩:!5{ ޵RB>w/G\ܸPy*qBo +a qx#@.Gx)3O < w ktoqEXof7 .i)s(]n9Stah:2C(-fM7jد n]XʢV N1kt8)y +x/dUK{!Lu+8傛%BP4Brnhg_70|qۜc[G-YDq(o>(?=)!f8+t3e'h1k@No 4Σx?nr;׉E4POz NT˔q[}GsќA[.H[W@|jw~ڴ?.}u}Mf<1`H_cy&§㨎hT?r1iCp2f,6{mzJ{Qm^{u4\'O9$~aο)3ºXXe_q^`aY^pyQA& P'jVӪ1CLJ46mTĘI6e2tl+ָݝ3cIY(U$F$L}.]7t`DCyWԕGzȑlVmsm׎Nr}PvyAUD_Uh:R̞ٕmtE2V%懵Xe԰BGZ&ۤiVQ:bFxPYbzQ .z͝J G6f0ÿ-形MʗMMTn2E"JRYf&O$״ $j738sS63i7*4غ3;]t]*{TY,+pt1kԒb}QYgУyFp9qtxRYcOE~]RĮ#ibyբCEsڌ6Xg`Wy]:M39 +Oۢz`g"b`[)B0F5C2D0d=A !ۍf JupyU3G~' lV)g@*G:H7Z ͬ W5H]piMF~rOAIw.]wxJebL 55iAuJHFHEJ1kvgdbC5.qiY@[BװjK t%E >u܄G''TE/> ឳgO@UxWs" u4\k:UP ]~jJiR,$w'=kJ }3&XtHrY:oL:vgqEJ HLW]R3eʩ聜n^yea x + +%N!bʼn%{KĪ8W w{qT*S38͹vۤ冊W&E oH$LF >,# yV #6`avZ9LRd=Hh: 1^ m?AeMdTtT芐q?5a18_ +p5&t<.=Ҿ~ڒ=T_;.* \G&]MG#.E$P:3?Ym1k%K^Pf;T`ɦ4;AŠ iw yt pfLcWʫupwEY>%RlԫQa |8sagŤzu@ǃgzGmT][VEa[{W#^Hn[%"#!h:tll l ETL4GJ}|$ج +T,-jL'$HBH  D+8BX-Z5ғ^]ZE^;Vg:^NǶVϻ^oL>D=gKfgv6}} ȐTh}1uD5UMVaΜ295d-k\`Zi^xn+(=A h)\YZ=ol=oc-;Ƃ%}1"u ѕR[/2W]K>EHz='֡1 8pA_,P9[Rt΀$oߋGWa.mv1EkڞYt}nǂ84 XS, t@b14+njO]u \s + Sz]K_~nDS[zss}^Uՠ\ٵg5{k@ŠuhiHV0^ӳUZn&cޙY, @K >KBF? g<5\^h/B5 uafOȘq zХiBvuK䮁 z->bEm2::Ch_9|)!E*5F -|ysnie!B`Mb0l;n?Uh D+D5HDcNnbuټ:s l|G6$)0ʲ, Bӎ' +i޻޾&}z6rvUT ЌahTYՋ|>r(lt4@#WEiو"xf-h#L- +LܻBR-uO˃){vE|k:FekF +21+9F)v6*N~.~Ws6kaÚT P4p`z{w d5wO۬wV̟'nRYA\?AFN.mp ^U;LJͩ08]o!uaׂRR~qTyˢA_W؜!58~N>x5l*!i_cH޽1/2vX zc{ +5 !_9~qFfYP\\^ q˫kfi 7>#_~'XM8(A˖,6۫@:}!!$$Χxg>b)ц+taYV@ ,,Wv"D$XQ(D34è)F3J3D`Ө1V#Nt4uLZ֨(ILuiE8[3?{9?,9XBn.>dUccƬY>9r R>0LB J{O%JEym^f͢+ 8Ј\=wixj@X_0`\mzsa9aY(J]c + Ԃ,qּێZB]}끶ԉ5m +btIͯX5[n +202VWaS +lZ0uerW}M]!lsSMͽv"h%bx&1(>Zt4ž79 nr kt2yGvܼVUXQY^R]hsSۢVsv/9wmMrI)&$ap۰>+ 5ޯ@PN׉cyѢ]w];:}+*Rc(~keRxљ_լW3'ٙMdd9m|zezQ[VY:>?$JSξU#ښm,m4vC9ΗT^|n,tK~])ԞŇr =wӪhl#eCmniy˃ft*Jztm--ewzővW|NF'v Cd t0(CFɅrisEXτbu0Wӧ^NT?'CL\")kn!])NMF;g#$Z2G$+Pݭǒ9jjUB^e͗tǽC&&W*yU{ʋ9{6{`G+iw_cCMuLv DyӌFs}Rm~9Of5'TǼ;0LOU~A`iEI>Db~NIDXXɢsvx (rJ k&ko!ew Cbf17񙠧xjwA+GQ[Hw[ 4 Ȓ<+u++Y*$,FQ;K"V{`l%C<`d/D؇=t6)w0>ߑ.:9D%ّ~6XR }%unO$xo,sx +&6<6(&%gI ~$t%]O3P"t <=@܇}H-GT} '-cy=@V5>[<cJ}ACMQ)n]/׸ng࿽|< $OJ2}$Q|*ƀ ǩyi@`+`&" 1M~oE`\1c +Wi44ִ [5;s|cv$ڧ|(Ax;Qt}%WYdnA}u5ŗwZP#&xF3{%O ~mp-& &Wj0W緰O7}q3%߿? 1A˰k;Mn#|ēhs/A 4 ~{|%cNeb@^*4#UMS@u?c2<h޽Ϫc4ԛ7e +Y8I~"9t:?̗ylWǽ~T*@\vݵw}W'q:v.IĉЄRh9 m!Z"R5 +HT("@0}&A$$wμy3붇Z{ ۭ3G 7cOֿZ4>!6$EP3ZhfkjyNk7|ֿgͫfß2~#7  Y^Za:G l6pHuZp?݇  + ޕ ` A1 #.4|p7S>C~0i~ u4n8 m8o^m6t{N0ؙ!w:Cm,Yޏ,ӵiݐ :N_0쥕/9d>vI䑯-C-j'\sX 3ő@mOr?w%{ w}iQl'Vo^[WTVɷ~gh5QZ|Vg|%6ٷqkY_qkBi2L> +^i_/F|$Wfo !ɶ3+V,| +d4_̩nPEy;N ?Rχ,hnQ5|~C8Q.#Js2U亱l O36\[Ws3YNSEN5lVcޖRgfkz3j ?)lQǚPPިNƒWU5j' &#Ьc^a@ےd;ŀ|M!|Eyԟ +Y X R3j9ѫ̞1_B6s.$:=-U\>"ՉD_ߛgs5%O43s.k%Cdc#7y#riF<+ҺS?Hss{/cunNΑkυh;Ĝhhxz/ukse'|='H;wܧj5ն?cЅ\]l9]AD*2wY ȯ=S_ZujJ jxQTIǖ8'Jw9oTbb6p+}xN㾟5/KwN0>MKhm==ﷂvn"B.xne%|{v gkKrS'69ƽj_dJ!%Y5rgS1/oy[]Id}г 2:{+cJ2+̗B_>Vc;O;p[ s\me)l8 iD.]ْ/V]0/lNh%2;لM+4~'{^߆<]4 sɚ˸v/rvC3Ru.RJdݝN7ܶ Org[=3 \_;> N'2eVxlIaeOW/&3Z9-Im=O':)&%w"cf3Fݜcz|q &:YeGnd,-9g}d3M{Pw}㴊CP>S~Pr{޽Y|NʿeZŃr_{[^ +*c^ǖC/tX6X5%(g=}!Eym<bz﵍uh Noceʜogw8C!?CJ]\¿ +ף^'v#6НN s;k~Ehv8?gSt; XQPb.t: :XW&~(A=B UӉ^cu$S F+^߉Sgbr^>D@mEEg/s]T}bM]MG&?kmdݧTF}t&Ҵ!wsb:HC\b}ߊܳȒ$ˇVX(B+(ǫWn_c9be4{aN;Qb'g&*uu1p{'}7񚙒';zX]eM{qoٙ2w&X9spztg1TE9+sBɝJn Eu׾Ҳ Y7+B/|<(0rsWKGOSe_m~c' h(^ۃ^V&H.˓(rzve)`Mq_JL ~}l#-r~ٯY_j*c}X1Z/\;1w]lg/|wTÆf.Gpe-A _J=%ؚ7{;{>*(kP=Q?O#eNAG:H6uXC'g;+6YOQY/W4|W]t;Թwbo䎕\L{w?^YM(9| +Z\Ou\,)9TSYb='o5KeNb_MPr*i7o?c5ΕE\Lӓ2G<X0(rz|<܁+`1U>P^]-S圓7 8Pu9loa,weكo}a;uxʣwdR)kz玳~UXni%)SYWq^,}a3=@U1\wm˹c :e#b3Fl^0v>Rz70^鰶,> =ز˵uo<Uw~{_vzG*^8w~!6e{iaO,-)sř؏'L/>ǹ/[{;ֱ:ז){g]s'~Z00seM E'6Lgk{^7qܰ۱2E]WzU7E~=W9 {]t-ڡ,,C,|;RЩ'JN4Xֵsj\ܥm%>y.ZƩ>1L 53 oN6Z%7__I,aV3b3E yǖOI|30/w; mv|ʾ"휕1<'f`/8=&@ڎew =ƩVxӹ_vMܯ"`7𳯬OSl?[eB<]^3ݱ7p2Jo[R +~\;+s@ʚ?)g:U3zoʺَ¾G {y> ئ{Ml,g36P~^r_ EDR3 jHGSi=aq_r󵕸?\֦?:Z*{s} nJ#k]~xk;ޕRrfpSˬ-gߏozϏ-?&fkOum[:;{qPk^W2&Ƚ{<)?ly !p_|ȁ&1'&)]w eML=׼$Es2ڏouS^RKJ~+1նLwφO{w-9lC>G<~gԹݑ>w5KvDnG<*㝳`=b_/L=ߧޏyzSܕޏ3unr:m_=.]aG˝8|o2W~?^ؓ3%'~?xo[7ux +=O e\]=>T#m2Wip58uHܭ'. +3P9'<+ ,Ac@GtO|n|dg&&qM7Q(j Ex!Q) E<<)[[կ=FCg"jFFj5/ioGr_]ud$^`]k;)Cw)Id&j|N%&{Dnve +oi[vQ䭮ؐ Ę6,zێEz$lOij}ϢV޼>oXBঁllz/X`U/=B/I\xZ=?cQΕdu @|H4-R?\peYSé@) ,رj1=l[Y>qص + o8 ,rq ټӭ%ؤmx !}oSO_6k'7tCsWo!c;msDش3඾ƫVYy|߶x37↟Kħ2rvcx|t>Sك*| y|'ۡL/Ҙe{)kd,|cK"zAO'+y}⎝Q ,ҕχECr,0ϡX\Zk%V].;3:{=ьnXEioú4#k3kijPoc؎E_ڷ14'Q)ލtf΢w-DݢFk?>eq) CiΛq8SGE[;:{nt4XLr+zi{~^*Yz R_]h\O߃ۜY +gmlDZyM{>#Z,?\72+.{J|?G/ӑEvZ#g> s]mtIΊ޳ٰ*k")$@ണ@Փe{oQ+}ۚEn/= @ <+Y)lw[6pz5]! ^зrYNOAP*杤I;߫#Uۮȡ>_\l%Zz1%>J28<1c8c: j16;߬RS3#yZMψg8l>駇 +ya΢I=|.t݌&)DA7) e<:}BFk)C?'d,җsj1=o?Gɦ=}Kn{m<0vl<s]K#9,Pn@ȹ7>k/DjauF֞|U|[Z[O?%p7ruXor*yO9Ty9Hmbr"iJ}}H|gD$9u}y,Vt:w+suAO{&ȻGY{olOt}ܒp"oV]2=V`MH)ܹ\Zn sܗxg9}ÛV-l[K_/B][y?%sKdZ[NE_Bw~k]˲snߨJ8`owww_ŚRV{OAwkKR)qtg_*'3F;{}#+1cUkuNԛu&O>6NzKw໪moUy%D_)}=?_?kb|DL9/X)?%; 7JŽYA;Du>e3ioJUϚ緢yN.JO h8I}z+/q+\sU+0AG +j+]]򏂿yws_lQ7j +Z+Bbv[QjO6^.s(Zײi|i͵wb{5/x'YN^:{ߑwu䁇.Y=HEץ'r_|ݢmi߂}go_џ8mK} ,z[x +\4[ٟ]CV[`L[gf\) ,!>Ӷ:b7#ϜO']mRa$?3tҧt1:t2daf@[ 7\"$\<1?ٝҪU] - +/%w;wYs[LEs/7}q<>KnVk|谝۱#*vZ{Lv"_'Ə߈ǽ~뢹wy7?>KB>8$v-PߑO|Nڕe#udYo%E'KܹQ +liJ_^>Co%}:y촧1d_[En/[ΫZwȎӴR:S:~nPS|/'|3᳞xM-A"k{s[}++OG-0n'm + X`#֩'{n-bv5>ZBkؚY?&}g?Q]H} +oQXHr[ 1Ν + ll\r2M_~X`#gv.qrww%{hސ.=/oK}xk +K/D䗎|=Is0#t.c;rXQn_kl\pL}_Z`ץ"Vu5ۆybQ[ycs:-j۰ȯ6-zSh|_u-p]ˢFUZ#`ECle_%ݨɅmxKYĜ?$L4p?uhK![~Vwj%d5>/-b߰ש ;X`Aq+zؐx'7,X.+ګ}0}wI'=i/wsܵcOl4ݱ-7?k/ssϏm'=ihX{Y'{>,R'd9Vw?|{TuvQݺϯEsߞ>ֲɣ`'X3Iεhxމ޿.>_x dkzW@Q{4rόԞ&&y%UZY~XSU;޶\ΝDC$7kro =17j76f]cIɽg[}%ӪEρoK<Ӝ%Z/`Z1{a ׏|A#Vdb:}#Fs,z^:;j&р!q7lGRq{I}XQ|o&N3| +Y kGx3i -0;d<B}WKlZua纝['=rvV5׎E[Y50:=L=Ukk oR4ǧ X3{"58SNK"k-j=9X{?fr vĶN%Y;rC&[m.@U&>+|!_ҟ֩sQwJobKߊ>/EJ\_Kgy!Q,@гyIpyۼɤE掌nTlY.᡾Yދ>$O0x#]7ؑ}zѴu'(L_wލHr7EKҋś\;BGv[YHrgɇQ1 -rF:|ML|_ѿ?joh'ѽ]n%?=\i=[}$gg2}ovoLfOKϽZ?5ѺotWڿݘ}rkgk6zK|.^YEMt/;4UT}IL"C_DBG*{Nl~lM~TP@|8݋:DDo4uL0|S:7ܻ7qMμ9ܓqI<'R䌴>W߈Zwg_Hv⥧Åh6$F~׊>}\4ҟ^bGxz3KBZi/ɠ_L6Dm~ эeW{]ϢzׇQ}w#:bG`(?=#M.v3nԻ_P?=&t2څӨo!NbzGUQ1O/t5XkIceӨ} gwQ5\a=L؋X\wXkhR^eaג;zdv If6ؓ3}7ѐ{94iI~DmJ+M]KuRxU~+;PQ%M>'Kzї8 +K|;ԥ㨞}Q}lϷk5)9ԏOS{Q +{RƱL^w=Sdv5twxlvZsəhs~;6j5g6΢jСhos{c"NA.@#gQms҈ ䷴? _p + &c͛G6?zSG8ω?ʱ8J^v 9?HIgO Nfz?@kޙ<5Ygݕ52Y]7iFaO FױcTg/,yܟ1@~!p=Qls[_[ݱ {bC~+;@ؚ{<7R/Or8cː3񎌇CMg:3pυȢf5,5;i' l5 *s_A|7gFױ`vTL#tG`k&4m/*CliFa>)JIYVW]?FcҐ/tz;ϩOo'rR3m:5i{=osΞJI `/$ox8ߙc3v7{_G5i/*(X#1 7O mCiT?L,NM.4(츋]E}ދ˜öt'F$%۳A†.twmAΚ^@&NEOxA[zQx(ۻqOyCs?g_;}'%=nuGO%Ftmtx{.zo?|;3w37=3^DaΡ>v;ڌGug&%Ea.2ǜ_&&`ǒM>IN~gMɜJr_Kn HY001sm'ұ/9Gm8?Q87=6UT_-=.8]ֺ|˴7D+`۷w^ڻ,8$(@ R?{ϩS:?L dG>f ӟ9w.Ò]#ᄿ}du\&|E.YpGDXOXj>sɪh_;޵y3vjS{Jt_[x +dU-n7>[KźR֒|-,CO{hӭ%a1%kLpK㋤f{bt]ج6ک}&8u?s#scof,t,<٥Ҿm6sތ@~`FݑG=ʶdۖ\ִs5!~9+%_K<5Shݷasȁ UA@ϗ<4}`fP5,f|>''Y)9/=;ϪIZgFr"QLr4&]u-}ZvD|K\y_pmk4uEBp:?]3cK |N\Sg[bANZ,M#/_S6-bgE{^3;RV,jsWu骐rlY6e +yNDˌS&c7's~iX:?e خ!A?E+sҗs(,jP: S&Y6ΙYvx_>gO0u {̩zDr9y8l#^>LןE??NoOess׽tl,13V/r(y~=Զ֞opNo߷鯨m|Kn~/N Y[K1r+f({:ekt7<^[̅EOMf^&;sc  +EF—']oh1G1[D)z]Ob;|`{C>8Pj'<7лwXyÿL-&s+q8'EW6_4r%ڱG^ 28e_&<6EY_t^~j +ݷ>Ǚ g>Dnm^\G$~2lpgg>fKd~9]Y>> a YG;`̝/Z]?$z-Bc~2rw}7Kz<9 Fک{! saWaF`6' ٧j">1о)Y,f޶`% +Do~b}âe*黲K=P3'ڻ~lXO6h['CM><:%m إo7gIq1h9$ؔ #֘hl +{ffH{·)ƒ޷,bm"7E -f3Z9a:{nesl4~8cM ܵ7bEޟ\3"` O[4\{ \) G_[9? IG%\e]]_brXJGVz8-fIt/ϮG%;}`حH:|>'Bv>ƬytEX=9r؆YS=-COXo~&p_&GqO-|aQXDW-6n]?Ymf-j;>=H?Q{qݢ4߯ZL y<~nϾEB.,kAwvuab@LH(JΒ-Yvb;d;q. +(E4) +)RmP t/6kϚ5̞4lL#{|Mwd^TvHR/c.Wq_U,ϥu:{xwn|NL[:|Ax4sٚ|@<qTP:fG%q*ۢOt v^GQ}?Q7H0oə)ۡh÷z"wlA<ÞhCV4ϵ;/$h/ŇtۨZTkSzRg߮l6: +S/Q1Mg^T܁~Z.u +/bc]6=O/kAb=x/PLϡtN{e(?k/{hי_Cs&+%۟>􏸯˿aTn\'ߑ_7WѤO춥Qw7%7edN%,^6Oؑ/%Jt#F}&:oc퓫t/|#iKΎ%MS|^B6hE]LrΤDžt<-.w'D:1m._HΕũ_P:k?~':|5/Lon 85u{-EﯢjThf}G==Tz>1 yT.-%Wz)sh; W~^dy&{"Z^=׬{?Exc^D{-?KX|ҚxF>љgץlhx!OJIQ3Htgcqm.f54 xЋ4gOwF3 Mvw/XkkH(3`˩[vv $mv1Gp(>1/zM3..T2s%M]]Fa:&c} 3EaVp$(&:c>ϣf?0jP̴̖#7;8fdߎkD 1(<~"X49dmLC; +! ^Ozs ߕorq+2kELLґ? ECzO?NLƆgoOFTaQ=s$~9fYTcKGa׆p8wm|̒}GQX +`Ce0ЛYt7p݉vԬ0¬u˽Cd3krL+X!77+ؒD0:qw0|ޑ#b}FK| leN<ڱwnDj{_Of޴)RSxWgE6q5kQ+1zt5( (M1e{Z߉OsYQ[zXWQɷinhFg!u6i|neao[zO bAT7#04Ld=(Z3; }K@=k(v:7C.? `^\ 0]ۦkߡyew3m|N,i.r]5bkOV~q,/1z0=!9 s{qs,_9=ף&u }oD=>g+6v-*ݎeڋe?tc]r|MgytY0k[bkNTbobǁWrbNNt7)֘Eսt?d 5t["EqgRH eٲ-˖F#]vA6&&!,.Ppw#~+h?e{.Cj zQ8<6ml0;0ֽLO.~%6 Gt4j6n|*<2wTXʏ>z{29}S{F2CFgGtc׉eT<ՙN>GδyT UKw,*:GJυhEc`&恍M=Qux!^Gsﱾͥ]xṈ_j_֦\2v`t'fZ#v΢jYTL,#7CXľ؏]G0W'Q2\:vᇝQJ|t̟SٹGW|}}Ah!'p3be7[xtuou[>rn:BZ[|@| E=웝fQXG []KWQ5uUާ0VmB߱ǙCX3@?q#$#u2ON#тoK [ MFp> o-(vOK5Ϣc?fQ3LnS㿐& j^959҅\?9J_HdF}#9IJ/ vH_HVUTR?\q FF0uuЈK=E7㳐)|:KS?N-KLg&Q| *F^$5>، l9tQ +$^2{̲`Iw/j̭jտ,J?ʖ̈qDGƃ{c {^深t9l@\gr6fnl(,?MT0f ~=[PKkB^|>uH>,>%$>3>3z6 <^DAm76Т^sdž-CB.baG\'ڻ̹n[_D ͎ntim mYο}uuBy *Ow{\ݯ ~ٝv(d!X&f[5u0@Wo㱗3[O ,u`r~ozvtvh4{RZsUF?Ga<>8Mܔ'6s!esy.1xs6ׯp }_p*sT.c;nOlo_Ŀ'^{ yYT<-\+BϹⳊYܛ3@kpxֻ#&F4W&D&:yT.kmdfm~]baiw>è8@4gin&O/E碏չl|& >+;P,\5,}odܿ{RfzN?jv;rZS:(<%h⻑%:};C,3G؎fKɆLv$I(x]11ǐCdfeTKPj!Z? )ѻ],\fnᾍ!7ِm _moc~]92gW/2z?z,>N\⚎lfw"f>җgg5KL ƠnR[/tXH V]G֥|׵E%K%sfn(2|F@w*oR37^%BU3zag*#g3`_FY\@&l~7gQ=|d =<{hv"PfA\ROSxn?V1o|H},KpZGƮpb>Qf۾ܘ\zo"RÃB~pfekr}=>Ktt,dzњ%.EJ.ug5y&̖ ~If)j(xUhgV)oZ?^Ӑ??K7ɳ̋J23H|l~;:F/_Md/`#~dzxM6DI"s;:%r ewf {>̵㯑9M>H ~C-{?%ڷu;~iOF<뺂ڧr}Ý_ []@D'3 +ft M?.v.=Am_ToL{`|83ؠG ^QψcxQ#w^Uw#SqRt&F_vq7̶?rٴ1v_+rlNWt_K +9?柅C"kCd Wec7p$Y:^#ha]dDX콞r;9S:%nϋu'۞g%qwZ;6ۙ<ܒ |v3Ǖ;[_es"C3_oثnQmCdݾD0jQ>Dͳ~[n`Cj%9N]1GPj١P|q'z~J~f"c_"ceK܇;; hm^ 9MoM'1wUغ9ؽq$3k̕٪xh/uwu,@>FΝMP[*wؘCeGLtgϻ̨-S}MInoFs;i79[t'iͼd|nuXt E)nKa'ګ"kXy3̀Ԙ?΋Ⱦ&{,#kq/׊\ŏ?%F9#5=~tb6I:f*}?̉dh#y#菟ů:GNdLgF{yh݋sdfnrYӯ[7Sx'WwKigKuǨ==FSSݸKhw퍝%"qSd#UCEcnx1Qˠ|.;MuVr;DbtaYdm}[5yl=߉l7˚ںi$neK\cd|ZEK1s)|F{jZ7ZESxL֑X+87]Ǒ=,R,2:`lLv@oi࿵bkjm4֒s :2.'2Zw|P_=Id]]E~ HDrG}ӳwo p>iDέYsGƑu'q9-ڣ=7z#GWk2xύCڿ7^#.S1}^q7g!%QEđPK%q*ȋ(pڮJR]o7@hpK;/YeTҷrλoxq{G{b~vlr`<b|ի^sl>c?l{$XGaGp~.ݫwx3-=~Op}I u}Hy[N;gܩkZ3Ӊ_#.w2>9Σr'UN^Nl^lE͡FVن8^K3y9Q711sss^3]hmk{৭`g2xNϵxo.x$ +{oH>Q؏>ӱ?Woo`uT>"`*zH"W7|ߎ4ÙX<[gdm~3/dn~{d[̥xr]|y䗤&ݧ(,p/uu[䎢jhE:oK<'/Pwքn箢 `US0uT;2?m}:ujxC١'y=ONlDwiO$WRֱ>gGվ(<5>gyspuI*zR8 +n#s_o#mK&;]9>i7xpX}tk~Gs/2Ljݐі|tigt/dH@.rZ{1~s{?=Ktn >yt,vn7di=z0O>]h<;iԛ!O#M7*?~ O1v'NQoc˩_zG5{FO>fڳb~"&R ӎ[75GNl]*Oq~C;11rӹ}ݯλߐmO; 8U:0~3CylwΧI4s|'=Y/LQuj` x" Fk5D}#:./Qxe/regl:M&==:^p$m^/95bk鰡/zkՋ]{=ɤ.:2yBKoMNGkfSƚർcށplF%iJe3,>60 5OYSG_A|!za)>h}v=?g帹?htF ~/YOɼZkw҉~+E|#oE{/>vߛio{$^tIYvlh|ȹ1?F{ڹ7 |0J7F ͍m.@}lo}{ᕴ/oǗ[/o0RI3ExDgȻy|XJ?۾Kc׷]cv<'4/=}tRvH^It71WD+]񾖼 >:6 +g׽;3O䷐Hs-4_n.{O|%\=m7Oc+}{nsZ'hz=SMY껕Ng; VZ;;DթixOXS ݒ֞FBߙStZMÇfQTg6ѹ-,y(binҘv=bn_{`̌wG ~sS xP뇒Lr_ȿ`Md?5u>Fauvb#]E̋ϣS `C$3?g`~ cH:z/lHHޣoAn(|}G&b/zΒ{xgY䒔} ]w&!Χƣ#WQqNş(CmάtX5]$H/s:FOd 8)ϵS05ΏzܖDzGԒ IqLd(_j5nVy=މ6^b3N_RO0Z=Z/]Ga6ΝWzzbO=/pJzF`+>gi_KIX˙(LP]Q<=G:;0a)k?*G ;Kn[RǺZ[ruxxw-ڲ~TN{$}:6A_F>πus̐+ِ\GO2uec#0>h˞r͕l97EK ׅP[;QXLБ=~TM""*GeG4,+QsCKLSg7Q/b(ϣj,oe`{y ]uĪm;QTKĚ .sm3[wlԴ7NY#%y( pɥ7R1_<߈6Gf,5ϵ㨘7eyVq?@D +nm=n_m, ! A@\ ) +$ q"!ی"~~r xz~El ,,0TaOv=%3Ը?~kgu|vw <z09ܴ>m~w} \2#}}ҫѓ7]XM }Bt:t8b#آacڲm'ojn|BoV{uu<}}w-*=Naѿ>`Q/䭎vY j&h΅exf=9>r wK;H +SI3ESa'j Z0 ޿AНC\}+ɷ$;v,Z9D:4<.^;c]=?(\_>қ>I 9_}sZkѼ|{NԚ}.˒bk7K_n-F]Zu.-ѥ_,sudMM_ˉv#[V%þ[f,AKY>Met]OE_$ } v?j8ȃ]~;OVC6O/%öۭi,af+-cו:x]Գbv;S?wN]oM,5~]_GU*,~-z_*.}8b,t}ob]RaR&Kuݙ*wbLtKv/ 1=ĴK$26Kq przZr!#֞߹J;;=o];#ظ^o^;Ѹݑ4_߬ߧ6 ّm$ht~[{1#wڇs%~j37Itf|pxҽKYtBah⎏d׬U~$F\ٗةϷ:TsZx_/,2yw<y?ŗw6S[+ \D4xwԷfr\C|4v,L4Ua߿=7^S jS{Gk֕ '=E׳虪L[5-z|BlI|39{ǺϪN6jNTuXѤ&A y9 ?M%Y#olE~Y*? l(;'tҾjEM[$|B_vɎh}"fC|o^Ɂ:;o5ޡ֧q|;G-܅v#ɷuߞh><_*Tw_~Pg\]tsrb99w&=⹯'D<4'?j(4z"C4?Oߑkɷ G*ے=& Y`䛁q}[n3/ Mps"?Y|q9}7i'ҫUsU2R+z+:%O~vI9-Ss`'j e$;6-j|kL_s٢o"{NW KcOcюE,uؠ=Jg|^NzKj39i7jZC?D+~wu;b[ELgB]|&[p& +;d},01vok| m%GUÀ_4eم>'=؇Ӕ_j_`cލ|Y`uJzw+]eK{MkuR9kum)],d7"aZ6ok>V,pLG.~_znrv-p8Ntj5u!!&Ket^ԹǿݬZ`dnߞx"E^;eTKrM{ ~"אЗBc 61E>$/~؅|amW;k9t>[`ܟagΕ~)e=T +ؔZƾ?)>mc桵1/8WLBE;+~^YgWWJF7qщ\(c:-cV&}[*s %֪uYZ]K`O,O6|a<Ι2ty]ѓX9%z{m3D6{?#G?){'eYjtlfYc;޹7~j*QΙ.:M%FN|9/)lĩݝ5iX5mOJLӳ~F~Ke^3/?篖/|?sT:2>[/=֟ν}/z |ZF3۳A)C%!R~9@_j~{C;R4j|džͦCl쬷 +Mb9xĿޱ}bLٻc?wem.wd/ụiᅝBƿ[KOkE'0ǀ#O>[m(k bjL#OiN`Gl3b6>COkQ#_6Eك~5R퇱}8az^(ki=+{7=k{FN˳R2J˜vB}}n,m._J0_ Ik+i`+59x.e]&^<->s(C^9M&c;\{J@`v7s}<46/0 +x/9K㯠wėg8:xl5ltĠ(1Ƃy9vQs/u$WS%n=P|!7؎y<ۑW3 T̳߀+ΊmUba?nPxvxr\x{ul{1o7ӝ+{LH:~cvdf ԍ2o#ۣw73~􈋏?2V39W-~3w:5v!G O^(ck vԏ*q2oO^.T+jyyj){OK|^+ce^yµ⽧P!R,Ùr.F4; }YO~%s53bDxSx֟)krM mٞ˯vSʪcWXCCOEbv{d| *?)r6iVbq:1? #>ԈC-9pUWY[Əzq99:3ke\b밯(㆙u=_ߟ%VN_Z) {Lz+;Js;kۏufϴeeBz̦ȃߦJlyKӼYoߏ>g;{bmPEٓe{`{|´wf ,+ȳ{C=2s;[[=o.2-xR#WcFJ5PD`#E7ҧ^:a˕"w#>xNt|4֡=n1έZ9M]-m3v?XF`ӍuÆ aV:(ge6ߚ*g?sUZq~}a^-e ֳ0f;˰Tɭ2? Lv̎qKwu%G Z}uf%FN] LsC۷`I1, 3 rvn3e geLKn(|Q] L>"4T5{Ѷ{^y__'*^d{H$U X n\w8M>:O>zy?s8{;W'&>k5 =s!Y8w I/A QCX;g;XRUm4^dOm:bjQ'JOntFbSjԞY~5pE~l-j<*uT%/'4-8O]GE!] یt$'}/ڝi޾GJ&?J?h[k gXF8xCڃ\1sy7i<q'>G$꠾_hҽwjęl>ٵW?mr̄ջ}/wW;C 6g:9k_YeQ{ uMOn!7.upjŻǻ]|g1Dzss9Mlr;K"j7nӴ>WjZ{: u7eǛo'Aҿc\lc\=N>5/%ysp]]ƅmcX;ʙy`؉Z[9]ܼG!O#w0n!_V,\ 6,]rɿpu|ސOHz\?B.oXBNjCnɭ,0Lk\?o;da{apcs-+8ѓMseibwivݴ_7~KW>Mzun,xI.q0 >Y#13Vx˸J6빾289=Wf7;R =l}V 5v=, έ^>p^Ǫjr_XY^9~V2?R}9mn$Y2}ql5v+}ݧPcz\R~֝tt?uO}9n8J$90ۅErSL=,46MN$2~d\ݕE-­i;`>Opγxۅut-x |Bvۛ3<_,(41N>:Bs/zVfTBotKz!3^K/eeZkƒymu/~gAʾc M%s*/?wV#F>}. "G4僡whK{3zSWӘZUL[4UjF1js9ƘYݞzyH:nF=ſȇ# ,:e\]}Y@p#Els]v\Do螖'n&9qO,=IvI, [xu Mz$:ܗVuPFn \_t# lO]ErM2"SMtYLO+$Kˢ Dwhq{~K2߻/q7J`3·NPEhuzހ8~lF;d칭;fw=;yǑ3fGGyǨM#Z㴞.,|Ǻ鍹ەұ31L6jIE=&Js_\BzHW3En"dXx3[zӞLgZ$nѷK~1Iwo3_rJӢomǐ,Xj >>k3ojFѢ+IF1=P +_Qyb7ٵ-ǩ#}ˁ9ɽզ_ePe T෶EnoYtb?VϢ6~&NZ-8.Mx}ȖjQ[gz;%[l`[b\`=jXc]ߏt|I P#'dz@S$Y:r)k^p>g~4O-KO]ggKTݎ|G:^맺yk]黭QGZsP岌-b֒dw%ņk]rFWk"7ofkvezOMS0XvӚ|9"6~ש;U[Ť>^L߷ x-rA"ƒe-Ϣ1 f5E3?GpQˢN-mUwuڽ_~YqqxoiK+̶UG+om:7En{N? +_<_"8|0=Wܛҗx"/i< w|FvR5gO5BS79YEڕOt8|G{8gz(#[Ot Zuõ77E8ݧ׵Go tGCΐ?\c;yOČ{O̼[6tU=,ux`Ş>zQ-&y֢6љ_lY5LL?T$>Kv8Mw$kˢW@VEK-@r5uǚKsܵȕD7Gf,gw8HtWǢGڱ->An[,=QEk|O8+[*&7 7mk|$EX*dQ/Y=o3ȕ9f*_(%9ƻcu,7c5G΢&m_i2*Jf{֓n5? V׿#-tW8~?nX`cQ;ɾغ"=KjX4,j[#~!s ?w3۶9@ow"V{?+^r [nXක֝DW-/ے{_}>֝vI_ *=g͢ ~}}&5\SX}N Uآl&.lGM^sI5 2 g ,|ܼؔ*[`QJg}`#j4 ~etgsU[FWO,r >{El3eسq]^==&vy}:E,~;;!k*|W#hWw e?V[ĽO~xu/8iݢ7mr,\M}O /mH~[~Wu",jܧ?_˹>oo.K~Ϻ/&]`uHVt B $=Q/f`r8,_ɖ[}zc|n|2 H#_K/ĻlI +{Fy-9~3nWxV4ש_{vs}Z8?Kpx>7rKZN=NInř¢q#zㇺs ΛL=M$ˉyUǁq.Ky,:Lv~O 7z®EʘLJ #t5uqҺڶ%]z>h5/-␘f5YnW"?ũc},I&!_pDӵeײ.޺mQ{ˮE';EFo2-lfvRt,o,jơ. +:&/L-p 43^H-S.L¯I4/5@Gt,0aST-|*ykX+bIݷ-ڲe?e:'5܎/tL|~}[c5F<:aX/cb<8>-Nk кz}]ox xȭRZFmh˃@ՇPED*WjTT@JEjE<*39z}\>~f9̙sc?g="#C.r>OlgFc7ߊ3ydUߝ)Y:QG X?ȀJ!$qrd \B=reJg[]-E 1#9[ٰ{W'OD_7c&ӬD<;T|1%'Nh{Bc-T[&m͂jU[Efr)CsB; z`?{,I%'$?;׭|>rlT߇7ڥ-A.GS !2';QE.? W'XwXB[<#]˰o:b?rLm}\>D~)g!+OX兇$gk &A\-- 9ŭ򻅜?z&]+*>#~qE/6r8[o-;9V+rY&3;;$y 9Py;)\[G5;[*SNc.|][+*YsJt?|qLtCrq L=Ӳ7S3(kLӢ> ;OZ)$cޮ朔y_"[K3Vy1jC]Z0r]./IZd 61ҐuJKl]?l fgour~1.llRH;)• .cZ#b89_?%g/u֨Sb_c}WuO# ױ9 [m$g[?"|ȃnRrWݠhohPbb0"F %=K;>!ۿL ak-r2'"m&w`"}DQG>ZێiowIrϣy6V:zp&1U#21pBla |0O{G `YRfe.ڱI;rnr9=O]Bwq.tL.ީ'K~<"fyX}쳕[.jNKEV#0vĐ-7?FM\~ ga+ɝ] mZzKňdog\cSjy"^BxKͧC޴t\S#z:D.$ĹjWs+[/D~V B#y]#_v~&O{>y۞c{NPm'k $SWw1i}֎u!s5K}XŹ1G6F~A9@{7"ɐ57&>]jjr1u\#g#"ޠElZt*4g MpSoa~1Wd>4~yOy~k-ټ+^<[>>>0I[ϳ7y+~؛>>,:\iy&i3ƌNSͿy[͐i32妎]gLz35&R"&ťF]4 &a06ܣδ:jyLIJ}k?½%3I;ͿkL/Uf3 +)cekoUL_rKmܶ1Y/(A [{dci>1_V*-ח}A hu[;izNrn>k:uf.ogV>kk tRVDf(ef8s?sP g&ggEl\"`gn;VF(S>B@@@@@L)Q\\ 7MC?sVa7c̽dȸܝgO?wz|*kJ<7_7(.9֖,|^ug;Gs|X8[ooft ;+E?/l` +d;/ϟMf|\:=e% Wg;3S>|]\ rTɃn%˰.SU2:"|#WR]~?;K_f&3nM8jTF}pѐ`XMln<^:=# ?GiYť4kC"NfrvnܜJ{/LNJ9rZs{yѵn8tYfƖYx>O&[O6Yg`t{z^*̠yzH?F| e +pߘm׌~0;J +0*ܘ˙cgp9iaW!r؝y土 ;ձsػQqϾs9F>dJgXC6=[\Y$8:ܘ?s^nj/GsM(.̱"qpwf{0ܘ? Oh8v,[:hw N]xJM  C m|- CbYiڻw7oFy̼y|5c{u5%ͪxo)y-eÜ v.GVpe/3E89%7e ϥO\1;*gG`[~W6M<ί1ȺH;ѕU]s͊" ֯_vϵkBC^mu'wh>]]]3K~hH}t6{)rl[ӭB-mFMA^w'mX^w-Xw-\^QCTOi^T_z[Ys_Cǃ-'mwxwb)o7pGMQõw}?[~;Cxz[x|EUO Q OnoO-H1OQ YϴSIn[H>ϯ*f?CxaA2\^$7cr^^:Ҽmczvs(ޞ'^K%vͬ=g^N1s!ѓMf4oXagܝ5pim\1ֿ$o={w{;'Ŀ{䃮>.`X?YwT:O`|RԣOUgQU٪57;7!|49WUzw.Ikhh,Bj5 P!lyᘰ "jIQ1_ɇ{[|X^x'}<=45cn 'C:\G=+kB[N1!ZcaX Ǎ:{qZcvU8nerg]xN?y޲S+וaY8-N dž88rNhV+ɭr*& +endstream endobj 17 0 obj [26 0 R] endobj 18 0 obj <>stream +H\j0l/J$ !`blv a'ۯOZ2G3mwtgu8;;O}2{oӼ A?\Nf[=_G1=5?o1ƞ~ug=/˟|q߳1K/a/اX2kc-!-ov|lg* +{=O+eqBBZ*QH + l-)֕@\]!u_ڂ2ҹZ7R#n\WmRB8U +-\{98Eqx伾'iw "D* *Uia$ +Do c [*ᩗBp0]juR,^uFgۃGZӌzbANrRWۑ{S׾AkB[ > endobj 27 0 obj <> endobj 28 0 obj <> endobj 29 0 obj <>stream +HR; |j cmii|J"?!j YX!xNS = l( "N2̌Pt`Zyw^H'k‚N2ԥ?s p{<QUOc;&L[Ro+e? ?zVM!?x +endstream endobj 30 0 obj <>stream +HdV PSW>=@EC !DKț& O +@HB@RTĂ(_[CDZVۮvUөֱtMNܛuZwr?AAF2)i٪!Z}뒞겏G:ۚ$7͜k6c;*E(.Σږ{*:CKK760!A #e Ke=CwaF^I +3EESnls=^QPbj EЁO@Ft*PuFQ'JHm47w), Nmԁ +}~kg^q~^g: *:Fa.ZHQ4oeiy5rh"d^ThmdnZjH!s0>Cg4JO{ !! +V&X|GST+U xH^urA+m G13V d}G4rhKfBQ{ 2MVQԖi'%f& +VZdcɉ1- +[͟ Sz}YѯEIi# /}M!I2YLf]>\z?5Y~]B@}DWiҢ8dd*uBM95O 8`~?EUo:3ߔ_2H{sD$-f3Yɭނ_4 _Zfejqj-'SKm999{kbNс\''# Pwiٖ:ߺU`DncŲETAcSȹ֦.Xq盶8>Gbhڇ`S(TTm((h30͵ +HhlUˈlr(]:?͒0͜Czhz w@9ieD}0xx-B&KOJsT\V:/@'fL$t`򅚘!!mVS;J״wM1fk+4A0]u7F1ca|v+QzB\5 += !z= EpS0ǏG5k:]Ixv +VCߓ3K& ,Ո'Ql@ +B(VppGbSP`O<~HFFF= ~?DlѿK*XHYM !eu +TLtAkZR$rZ҂qq/-1%gu@[ZڪՙAn\[֠ݸЄ;/_=h!3^Uב.4CxU!  <$$Hx$@ `^Eb[Vkum-U|TwtRÖvFZNueuh{ԙ9 x%07m~3q k-Z=n"y҈h#&T78j835[?I~0rcr3tY ЎNpA+8aRJyY-$8fyAΓ"7.O?LJ( aY}3\”vBDUfp ۥ,ZZ;TK͢=5B:S8`ZF>nRϘ= oC9?1W1t/[Qf'ws Ì&Wk eh/-J?4 ٲC56RIH\GtEh5~KFݣ@:JZ..V"?gN'l/g83ić` ?@ }K}oN_۶sL?p; q֢UbpXv!&~<ۇ%SbWIr-KtBUeƵصDžmǮRە5DceB% +y%J%e}!ZN0Z[3u6y '](\|3.:Ir:2<$>% ik)Ħh|b\=KoR4As07^\XFn7x/v~'eVu&Ġ[h30j |?Pv\ex Cl?~^#ibzHXC4næp$qQ|B{!*DC0}IQ·7*rL<_I_&<Yiu$|wJW5ݛ TVkMTvl۳ۅht]8(޻Ni!e5jp`cۊ Ǹea)CR|% ,D|xf}=xk7C`JYVxTǛɦ|8o/;Rp/zzM6Os;QW˴-=~w{`0M(D| \ G7y2?E-S#;, +;ORiLTeT}tRæ/_GϏ 87> gSd~`h?Env?h:j$sUA E$5$hPv{Wwt`zI6wOZ}+8Y#MbaBTʓE]?w̍.MO'n>2bX{\9.R[mȳTG*G +H֬ޛD8ZΛ/' '8o~8s|&6)vee¼sK%SL1#SW}@B!-e6Pf{莚{bq|ÑQ^E']|M=9FhOՉԍ D +GD4#TQ[vjl?piyL*lC[BokZLK"_=Q-zr8`N)-çaVMXqD4` Vk0, $]]uj%D]~ò|7ō  +'Ks%u1h4]7&)OkBLD8?VH鳗G!6m7.Xf\ [WNyxgӏ2vu3Q&mQØLd d!p)t D& Ђ QPĔVciM|UْRlQjdά-[g]d^ .+:֐!߄yOeQ[+9Lqm,għI WhDPI@1 |\-*ëe3Ilp,uDFE:wTf1su V +v5qw !$!!! @ $L  HH` +b}"'Xk,TQΪ'gkNi_^WV;Ӟ)dnp=7N&^*"I &YЁB&Q. +@̎O 52Ł$VW^B+w%5фf$bcbN/rȝS&ɒա!ΝO6>?N|fW {lh{FP#8}璅JjQi.8p +od +5,ѳCJ 9[ >-{zpo2[a~&OI`BqK#=9cٳXUo/G_ƚ{￸MU[DaMMg&7ZLBE‡j.<(IjxtƜf`#ޣVftE$ F0ڟV3QȤk8M50 s:[uc94_<,ϯE촚WcjO/H ЛCj,>Ed"T@C8Y4 +[@zNx<'N:qNL_,0ѯhzE)hW"O=hQZp "YdKزиֽ@m"d%<}1-İ#P: Hb *S סμ`\"?HB(QDw& M8"<˸tsy*nߑ]V-RՔ;Ogo`Jƹv7Hw +]"0`{dRB> q bm0>4O$JщO6M2$tȧhC8~3:Jo/2!߱|?%/N]P߰cM ]jaamk/XqA LZ(tB&/K{}$Γ++ݐA,~*3HF0tG 4%|37 ڒ +Ӽh4( #eg郲|ͅ|!!$.Cal@ZD J_.e9C[Q-r'SPqL1Zt</3/6Ǔ#m-_аWWx&"ڃ)u[j+OuL,'K) 8Tr93xεl n+Z3 +L b**U.J _]5?9P_g?7j|໗Pm'ߕ꺚Z[e?<3TS[mYbxR>q !9@3Nu&,]ѭ/C%r MfW耮wHr`Hy +aM̒ +(V?Xue,[b~?NYFƚfCGF7~m "7*UejuujĹ5{&s-Z_Z8w]q)r5f< +ēmX~*>\P2Qnn -.F"ːlm9ǔzbXndfc 8=@!G_ioX5U&eXeKʞxQKiаzi%LT|Y$$B#B4tSB@9zzfG٧oXoLT?a)ʰeT_.>Rєr)_` 9Mu}r?U 4tm k^ƘG-lZpOe۞G~Kf˅L4-|FX1n1UfQe?rjKݸf{ٻwb6>oHy_ܱmmVՊM7"{uoo~YLDQCh v"/T[^-}=.~T3ɏ-'vx[zwߖꚵ2fsX PlEc +zưL!\4mȒb NKaE=ڱؠ]F678ԠJcE_BU1P->>a꫱1Rn~ɓ\RUypDO) .R[fJ6T{@#ĒZ? $dB{E0X'29Pf.[{ڱ鋝CdzC>'%8ؖ.h ʔW{>Q /2WL[TMV1uI8Ҍ蝹鬒Yhn^IuHB(ww~MkA*8`46>aU#2k^5ʔ4EyU&mʧy pWo{aR. Htms\WzYIX\W]Tﭨےj^dd:T: agF X|@C8_p]uvE?nylj/wYm5Z XO_D.ILwPA#3ECdB? $db=?ұ.$"5 0E@΂(| :#>3##оKoAE@?h#O -A~ +F:*M#-@Ipup1݇`3JDgПB-F' ϯ$ +A "r >63_>ANOb/>@od@v? w`/A_n0vP;@LoTRt?re뜹 +Lr ~ĕEmH#= # y]Q?AWAgֶ){ v%0ysq {@ +C`װ TS興 /8@:`{n8N#>k7>v>!^<4ޓIxHQBAPcZOC2&9d@ljF#}6PY,}\ϹI69%[/_Ӭ,zO@WQ(Fjv) Y8.;ilyK7$b&1*<3EUܓ,)RLj_2Ա:B'oejQm9rV +gO u\Y]Ni7;G[ܩQO(g J3fTӘW({jmb=tMu!Nuo&oUIsJDyjmJkԀQ~&IUlHr󯢘=*y2T?bP۟W\xPCZū++rE튲bf n.]L SkV4wyǗo {I\nIGUӕ=E׵q;* JuJ5RRkR;IoQ7 +?q2ӸQy5xDM3!EC8 8J\LLOb&.#96!{u4'!j$cLFYŗV|6**`K+s;/SQ)~Sěnb!L6K71cv["?:;x ݽO1'q|6/@\TA;'SQ/dxGlkb$>I^(%σ|狊O(?{ßF@[vx?{U,S$}r\w>XMP'?V-q>X+^ZZ?mݺKiw⽊o :MEi2)E<\$ĄCv/P5$=Q_%мݤcI[Z+$_ىQ GG '9)_=Wy)3O{6=L#YdU_J\uqLu;u|,>?yF|h=]I-WK\c^O}1@]$8 mRQQtHT+%z%ǃC^57\ME]Uq/rυ0]/Fsj{ ɵ\7̵k㝼p)y@1EMpdU߉sɣyF?yVQ8u>Bs-.pmSro2fp]p@ddio@뷑?ns}nmsӮ> 䃻樃֧7u:hF. 7G3I&*qv2 |l#mqm/32|H|)7e;Mc"Q{ y]:o2e-|F[crOeE!7"~)31|W< 8%!7T8sg-܋ص:Pۏpg8(UBv.!V|tr}F U=[MJO@N oکaޥE>,A 2yy2{$tӤ mxmxӗ!az63=E yʾ(ZgFY[i9FE y/9}X~<{8\J7cWYB` #o5 jHNNn]C%%$`םnM'E$FXڍJ,'i1e!K}fHUN]hgrm#Sv סZd{+W yMd2 n;󳜟;rO}]9/vۋ8m`y'\֗fEڱd]1xٚ΍X>8^?)N?it>]}L5gg^awrw,9󼌟+Ru<γ.SlO:7_Ozo,}=u^Og&]pFOY<|ík njir 97xO d|owwL39~|x}Is nV""Ǡ6۵MI8MCvEȁ  V+$iow%EVߘ.? r_B0½u Vwh{ltui6Glm7ؽ9g5xrڟcnwH{[k{ԇy nmrؿl\=PV^ `6uZvX$;yq <{58oKK +~U~jX"^gS2nvέ.3wYug Ifٸ7OyLq6*/-̭?5u:>fqCYB!Gڝy fcs-40$-JY|c$6]>Vڙu;[EČ{wnVs(eȵsӘUyzޣtLIl})g{9n:&)?k[nTB(u}ug{Uڬ-VoN<IE;8^IYo)k3^5wݜ뗥2dXc܏}%OhG|Uގ]&eE^CLiUe].fA- wiAȐOgV-'N N6?QX{N_j^6j7yoKy[Gq;i}ۇ]r!ۡ'q޶'ofzEϊLUcrݝs0pG{#b*9Ȇb}7swm/1@܁?]VΣ^skC?<܏_Op A{:FO#3ukɑ\Q񾊪}نxF q_k-@zt='g]W}"=Qu.Ͻ {GG"Co|wf+13yWW~'t_c\{:yCT.o5Oeӡ|sl|Gs$/Rdǵ|Bsox=K/}/λњ?lϵo(e?k.}(J?WO_I<-$ +P֓y `=.!ym}gG1={& '(*WQNb}{oDal2. +c $ +Sۇ8s;6𾎭':v>kgv@b{J; q6 +j 3aʚ%НMŶ_=IzL<3GyIߘOv@8C"_ȏ\4wd 痒ul{Ckk%'e ꬾdN_g֘ET@nv5ǽ?xōB` = \ 5.?} k{ϣ%2n׎|0w-13 ߑC6S[|&vN;my{Q/[HgϢz OFɜi g/HϙdJ n׹9%aρ|s,ϴvfk?za d1 ^ <\'5d`6i=3(L~bl=-ϔ#7ԠVT;QFc~8OB7EqwI t,7r\ߓg_pqlc{/Crfv3~<Mxr>]M.l/#ܔ\Da 6lKelc@hۜq+e+>8 +sNdL[+\tl&[):$t}FF,p'g̓(nR?pO扅ak9ޡFk9~[ʯ u UGF}N?ϽN[Oۓ2iͭ[e6:|7 +C|nh<}9 WOuw85Msޣ {E:Lf'A&; 6nEo1Nk{Rr2 +90'QaoCx3o;9ef N3k>Jww}[A|ѓq#>|=S޵v"}8Ay(r{vgSyd:{\сA4egu09ܳe2whwvMp~l^Įsg=y:0a_Q:ݙcmU|Kq<<|B>EgaܝumOͨy$pr֮3_AUIx̱iv\"ouߋ+swY'׺mϣ~r|eBQ$xC¦(>A&XC:]D&XwEqJhdGqԕã׾dzeg\ho39B;c%3^j1O½@ ñЉSӱ#;v籍kN͆z^4uǜoz]pgT&l|YT1G,l:Y3=:_΀ϳdgLMgk2K1qTe';y߆ݎ|z8/20yѶ^ UIC^{/9kET<m&Sg:rddܞFկ_c.)>?$K=Iy槒翐w;5o@w[j?0:ٓ>(}}L{%qsg,eS濟E׿E|FQI_ELzH~q|{ DMvtOwt Yd.Q( +B ^#ك=^yP/"xTrTEWϾn@ޫWU꽪o|5>B/i~\F:Dw lF!Sw7e|G:9Eq.XώoZ.cy;^ ek2w/{q(/}W47JWC2'9}}/FF:d9!, كWM˽u]l|/9Ī-9 vۊQSb!wp,][@~: +_~_D{x2ᾝSˎ.ڳ^=w-{(+%!bSVA]kXܿi-}u>Cܽ_ x@ s?taU,Pؿ%[|(y>ĞIfz%<{U^պB,gTV|[y:R _f]5=_\ JnR1DY:k"X;v-cwV #H~)~|d+|I}לӧ,v K|BݰKE/%-qO\A#_o'#^]],m83ElNi[Z{ +뵂QȋBGW +jY)kXV O[i|w:M iZ~ԺacuA1Fr] ˘ kz]Η5Pc.⁸wE>)ܙbO~T=-;_gw÷G.N>GvrC[Z('Qk%J3)m3*_i=LN}Y߶i=xMLu٩'z2w-Yv6Cw杼>g<g٬>g;rfmJb$V$/9kAW2^[% ="xe[eږ(_K#Xq%íZԴ -}=xjr/lX["?eENz Rx ~9c/X)cķ+o|lowoe ۰|/[VdO_ծߐ/ozȁֵw½X[*Z#p?`uB=Fڛjה]&U_@]O;qlg!JQ !Ď +8_ܵ3|`sK>YϿGt#~ױ{=oj쳒?::e9F=^_/wmhF'ĉhBk%g3 }!e1|Gsӹ3O%؝FQλ2֛ދ/ܿn#lsgMNޓ9wm!-^;ήwl.옝ޥL/Jih?EOܥ{2ϵ~*ۜ{7ߎzwy+^C- DE7nA{!=%ۢAU`aۤEwΧ,^tn58 uTQ+h}c:⻈LK%Cu/B2 9Tkzi5EZ01ɵk:A\Fv3>M8]D_o!gO΢=S@lr4Y_/LtA{my~[ʔ5zH0oD;J66'R':2sѸ๊/plEja9w04;7}Hi_rd$٧~/9xQg"Owo0" +_%l\8[8f_?/z\WW ݹMk7kkнҹ(/Q,sF`߈xQ4>N}wϢz9l%fjFN =;Xe>hDa +}=jW溮EPG:3+ۙl61۟f׺3=3wQuW:??q5c#w]i*_RۆQX1uvzz7 +U? +lomFMFޗ|M|C =ۧeͨ~mV:GZ%_}X~ %FӋ>Nt_u%D`_lK~7}oWkdk|_c;z/Gn}:q fT[pɂϐ!ydܣ&ABd'8C"cr9hqong >r9Dxᣣ"ȱaT `vCvfwɶ=G :g|gw  +|5^Ё>؇Z Mx]Gs}tX:Ek.`]\htvBqbgƢ:*~Ւ,~w,xE|fݙ 櫨:'zmْr&﫨=řQ9i/ry!^xϸ96jk|`;|x5)dp̅`"*V9,75ߔ x >h6sT<_ҿ6e5`gzvְ:36Aw&gWѹ $%xY9DB ˉqb~1Ji?~; qU:nd3vpdg3YKmDb;O'Q>:ڒc?#T6/sؘ1?>`o'sׅ}['R[惮3yawDny,eZF~F] ̱ɏy<]t?Fa rخݥ/,b%K.8n3.OIoeg:W#154H oofY՟^[Ya&'~.򧨹PtSh11۝FS;G_Z}'_INPab|b_Ez;-ub'Qf3u5S9c}x}XnϢrdڷo\#*7F:=t_ஹuSO~TFaLq/]dɻ=KNACgos;^=5!Es5R+iǾj(}r%/to&Q/Vy5fS^W&< + D~+^q=}-IF}2|kVy61yי[~'z_8H.=F3ǒj=:5k50>sc~Hl]ewi}[7zg"N_hHGF^ZdDC33݅ΒC.c#~"ɼz>?? tA|>|~{$F/FRS;oy{_CP_t1v-޷v^Fl6[F .渒!n6f戢vl`s7z /C{ +3ݐ>1 7]?c;iu=Q-(I9دxgjxƐ[wls 34s<8{smԲ΋fot+{vQ>Oi'Q5ND>W l>ӝ-6u`Q:8{ ׄ3mxD\bxذ tnpJ[l:м{t=4h'DZϫQq漡m3 2od|y61>nXc_coeK|yѽG!GQuۓQdy:7e$z M]wUcU62_#?RpW(8\:ͣꟑwvDRp|*Wk[Gua6\G'uš&Z2ښԥdΥ׃t^_k_ODLQ;y;/}Ԩֱ.m~{R;vXIO$5ϹGx1o$C鲍JtPK׈V[b>8/8E.c^uOZ r:~`4i]7T#?#==C&v{smb!8~EzR.|O}}X2vQq@\바Av.1ҾaT~~~ǶcqxR/w|i(,<o7޳ΥH&?Ts0yt&sg#[! +zQoEn{\X}ܻ99qũ$^p>ym<ԜGܥۚq8wL.z'Ǡ3y1 :r!$:y +q|vj{<Fa@kQ\zgZ}ՉQT 5-{UAnpf>܄!xS6jAj}XFȱt6=z&kjv }kEFop)p Ax6 +?Usi~59m9']r~9_8?`MZZNutyAq&3ʳJn8NG݉{bn{"r9\M̤< +>K=0{9}wS~KkPQQTyrQNL4$*'{M3.ksk܃u 6Sr)b{Q~[ci؇=ב㈩da<^;dg,c_L_ +㎘sqr.zMGp&6YO 7}:cZZg(fZCNmQ<ғ|jCv69t c ]Q5:0 _M΁0 +~Զ4*lњsއp/㋍ $N{v/M]gQx{UriT8Dŧ ؀&/h~dg$ksq."͢ꝋV[Q<1Ɂ?s_5jE摍Zk.|qvﵾG&sd(n@wg=鳖?kvuvy?*>oO?4OZ>ig/t`:嚯Z!6[5پE?k`?X}FMkmQ&_il$;Q7\>j߳(౟JIc/=S-sF(W^?iθ–QTANҧK.2ϣC5}'u)}6˝|MtyT&Ϡ??@o":cnT}}'J}4N!˨^N}(}Ui+^nM6닅 ;P cf `%5ad;7Ycm}jq8yӎ},?ލylè.nO#(wjhmSޱ۶3ɳMtm l+mTvQ5˅;stGÚV& پ_4vMg Z-cqym=6{Dqx:awK~æܟXs'?W?QuZ2%w#;YV#՝w1Xp*m'8OQpUg͵fl\r>q!*]Fj(\XQ; Q9}}<*lp{A<XGx"v}QżC"hQ$E"E6ZVk#Mm4n$(Mt +4}>A:?\2ws=׉_318sybm^o[Q{CkcG6UNP_b3Zs$ +B3n^Pz#;zoKv܎CӨIYF.&֮(LwM?:5e\'À'}cɎ ޽U+ ;0鶾Ty\f~':$=/ G? rx_7bocӑ`kF^3N[7EyT;NQ1҉M 9ԏ@m(FJ׵(ߦ>Dۓ^ٜ>O\ݴ3+%?J?uO1v%ٟK'zV_ǹ0JO^I?uf.t{ =\E6ƆSf7K_0s$ +o;9wEmk5{̫aX̯@׵vT,ݨܢ>{{#y|=mi0 +wÎI^ Mo}è>LζpC!KbCj%XҥU7lahZw^HuĐ:S|>#'w ft曧v'XC>c5nKAoO#7>xҽO'A֎]\o0vOb# V,>љSbӨ^DӷCIuG ~ߔf~C}d>I^;˖6f-ۂ,MQg|Cnbj.~GVwu+=2ET.<'ϵo ґ/eҼ*ѩDZ 5t'jfD]yoõޯjsGF4zA0Ϙ7$;Lғ~-ә|T;迳>c=ɼfIKԗѹ>fC ~{#;`w?+][j:}^gḦ́9>~#c[R6Gzyb>b\ɵ|מ4y0+>1DRDϬksǺx%=2&uF+ݭ K|ܵhd+{oC ?:]WhG;>3y/܏ 7wX |>2[Ƀ w~-+ s?ܶ o[Ot8^Qewe$N^%OY,x=Aze!{2>lxb>|~7ymsg>m|tǁd:7K:z7QѼ\E/cGel'nLB|R.yT^SܩNQus}髉_-ɗgV{Y[_9xiQ5^6_3IX#|Ϝޘ9x5gt~h*`tp-۲۾瞵[(j_iwYpކ^ y#98_Z֋-o6Ef13t; +Ocw=fsNF^3M@gin~ʎϵ$<>_sP;8oSvZ#6XaTc;ڱFJo%њj Y,Uxy57_̽(Nfv%b +sG+ +k.ϵ`"gkӑdX-}͙s;M_fbm,fHf??gg؛UN,}aG|eT8jiudg|{oQ<|?2uvh> Ox^f#ڱcCߩ33K VGQqҋCԻͼ;qT?^Q=~z-~ ]I]&|-TϛZhWtvK+1ĶGQumDSO)uʼ16=Öd>ҩgҊ/9a.Q9K>'y,َ>7%Pc؉~Ҍ~E7gMnT;h7ە 'oM5|~.>)^wMl=MTڋ!kgDM|O|k_4Oj|$F*z`'y>7]D, ģvkEgq3̍`-?7cd*&unۉѣQT_)+8p&\r8-9z)D4yljd=Q9m5e3'k[C0I;}Տg37d>=* +{QZ_DgLߞGpHlg7u2Ltߛ7QLHߚD::`y5yi,"#־F%t&~R3Ѥ.d}E2 |ozL6K=X|߁M҅Ga"pe'*Q9{̍deGzDE ʬyb,IuI"EJ0 2`x[0V߇xE"3!mT~ћm#Ƈ~b*^{޻oLa>>Xz$Y,[v3Cã{i]T~'&[ɞ6ygs/[wAxCTMn]r#YGfW@o pFzGQfP 3~w3<׋)S3MsoǖQ1ʽ~T蛚ו\]DSMgo]0DN=1 JD48񅽠IݎBҹ6єր 4q-?D\ueNvAM~)~,x9VèZ9NֽmTI=~b7-?2]hax`#{zk;{-~lyjq~{)ӝ[ކmc|tjϛ?1+؏^=FaXa]>&߼@h{]'Wy#VF5\Hǘw ['p8#?C'z盜ȝ4dGztgjD|ָ&~cg727"/lej}/ +Px^&P3S拾?djS?0!~;nyQss,|9߿G}V4$>j={NOG%O}'_=(p>;v6ezzՓw⽿΋_|bϣlgF{?HhEQf{`:U˱%k|19i`K23tgML5<2*f۽?0M78]~`ȑeNp~/jrݱ}Fnz);퓟5l{GrϢ9aof3Oc!>>2Zl⟜㉙~c(}u9m=󚃼S8fyů.3Ple#k[=w;?y>6%ьg.uٰ\`e4ωڶ{Im,?؂=.$yTo}3 ;ݮ[>78㨼#nja#rmmJm:/bc85OH6GSvNLMTYgQqsxFw 1۽ATEkg>nu"NL|{?o%x3ųs՟'tz3cF.ͮ7F:@̦'5b.9ȱ?̡Q|gE̓ 22]6~hDg^>rttwtZG|sԎ}.MT^-D.t;01j>auT΀'0vX>ZkZ*V#Ȉo*o0ukK'cEVG3Cm[@]JNzLws /+ח 7v~m__Yy4cl170?}M.tZyz>*6Qu-&Cr{jM?CK7ڈ=3غk<' ǎ|ճ ˆխt@盅G'fl7wc[{v/,k~”:jNNX'l10jߩ!b'msïۨ@/ vc7sći1[73}**/QyH`1@̃W2{{z0>>"o8JzϔLY/&{˻:OKMj)c͢z<Qy [^ 5~ [e Oο5[{!;SvK(|y:;NJUR\ECH \  ޅ+ޏG>eWs?yXͩ hv/]L<ߐ+=_gQqCl8>Cu Hvv}Fa/j>K~+7ZMe@mkwK0Hm:6y)*^vLC%#->Az:.yF=|܃bwn#/?ԙ:Ƈ'ؚ׉ L+>'Lx_Σ3Hg:q*]DS؞vB|cw];{UD`Pv/>H2XzUa|m׫X#~CwdO睎ْ|H?6V{!uxux.1)}__'ITu>09vUσ} #in6Dsc?z〩ٔ<#+LATlRψ |Jl7M|3 6%y5[/: .W_EqT sPt/qF="ƻF 1PMO%V2 xn>O /0O{; 9ègo☼joMs/}a^Yc\ͽzS?P#E+ ]6D|''r>g%6 _iaa??=_DaԍZ-))}5<#Da=95߮}s {qϖEK;7-!Vt}T+7d?:7>l}][5?1wR23>WFvOͶ΁wj CHm_gZxhGè|Ake9%`#wG94\rd9?ށj>} Nແs^=;rO^qmDZ;صAF<F6=lyէm->#{;Qq2^,/0cT8͙9Ϧ5S溾hy֘ Yzڃ7d]ٛpK0^cC淓:Z{4k'b1?ンs-k'.*ǩn9nFgRm{ltщ:D>C؃z2볌}8~>čóJk?\S}{,%I, ?rz)ډQc漖.N+H^-uhh=Νs$:#z#(]֗ csakS5\w3#JD{':s{ȌSk!=7MLDTF{Sy";vh{#GՔ؟Lωm,F|"VbLՉٜJ0? kt K{t^cI=4u&^Z;@zQq@3gsQirguzx!6\g->G/&Dmlh ۙ3J~g6zonW==z ^@=1cuՓɇц/u}-3 ,l^L1ע3Yl8XF>uLFN*4wN,)t#Ss0B{Qxܠϐ culC~&Q1^ZI3[Ea{S_cO,Ac yibhR+E oQeT/!mylOM?]Л>y9]l?]Qωjc򺏊Ͷkdٙ>3? ɀ(Ì|"*O9p)$*>~TL?6V&UTl37Z/ 9xx#9J]c;|G`AY-gtw|,}F{s'֢3|Խ+4uSxSpۉ1~ࢾL,[FŝTp/͟GۍCߛ{cQ#w3YrwcO\u[:n>Qz-sGd4CǨ:WcwFF{7a;0 ۽R-!Xk4{" o#`qs~j"gl\i/ϧл|):?3FFYցgg|EO0|uح=zxAwt^ρ׭؝1sN^^qeG}_P`9dE$}%~8'T<_Aߗ'bI.=^f{+{ٸ$;%GbgxHL"Y&G/=Z"Lt/z}!Kd}dMH{,zJa(vK?]dGj[Xv[߭I;>߾+>/d`(8-:{oEsswG`>l1[9o|4{|TMW##|kpJeg;;v貑^OУ8MSO=ݝ#m oJcr~_g3|X?G}7Lx,"V}/9lAMnܚnԲ|fXGkd-f'~'>EAN?/#dW{ZGDJ/qqҝW6dg 6#gVzW3H|NԐhD12Gf2=~-;Dl@Zdzg7fr1|QVCĬAE IXh%$r8E֬c+;۟.aJFRW:g׈Qd?OLi 5c,YvAC 3 fxMLU$H 69+{'vҩm<5j92 }_FƇں"෫H|}c-df?09}N={_"緁Lte΁8_ 9elhwzHU#r ;:?H–ȹp9s"Br:vW8Ӂḋ-gs 9MGAO$ë/#ĝ|5z3]Y01@}-z mAo(vOW`,ӑheQd9͖'6"cbߩy>=(z?}Slul0k郭n#k5"s#Q~;Wmoo's\F`sˮ~Үq^/m-Ij-mhRNSmvtF3Jߍ ];wjMٯ:3㦼C¶n^ۉ5@>b}[['T9}Yj9\~'zO#P1sd]t97촷lS|ɶ +~g`o bkb<瑱wSǯbL]/_y-Gޒh 7u\Kwc#3vKmd\nUͶSo71E=$^aI\7yr`ܾ=wqy<ӣJc>Wf{bkKMdGRxa _uZ c*$su%|<A$>,>FP9w٣KWg3ܝ}ї92okH,7]ҳݒ%}Akguwރs8^_䤆i{A1# PwqzGdܣ6?nঃg|>,>k="k.XnH9p:NlE_Gu>[o#c1f#2װg݁gG\1# A&ƑsCxabm96L49(S`NtCvr99пLcݽ#%sCI}!n?/?Iusuu&)ts 1ߣ#1 wD_̃zȬ;s0gM36y4wg?KÆ^G}ԄRfR#qO+Ջ8\r;wYdK9Yr,;"k>sdF${ > `\Du$Vj"6ރzFgǃ~ sB1+o)4|Й;O̡ydN3kƶ﮻_;러_?x5[A?Yu|~qo/z}_Rk%nC}̃h7wd,O#goڻLEH,RhөOyiͨ`0totw7ٷ`S/H|LQ;G3.pۖڻ~ܴJ(:1v9}ڻw-םz0W=HG%ؾoO=hWs%C|N]~_Bn")o#cF>xJVܻ+oN]w&߅ y_q!z5zr7ݔ[y.1߲wW5Vމץޡ˥>vck. w| ? tamd\ mGw5DQ{α3~fvy8l 7`w5f fW+q^be<bc=ޘ<@s慖GJ#e>?V32Ѷ3dAɟ;oeWL&}ھk;<2?bO&@B"ЀQB!.*Β?&z?)>n˖]];3Ye3y5ĮN 9?ylٻY֢[|x0M|~nkWM!߻E5{iqz=ûjgE<@&>;_#bE.[䐱vF"?jpً +ލ N&oynF& ܴs鍨2C9yÇ=oD>gF^&h`jkyQщ=Л0:aD|ܳ3z^Y 쐽03kCS,r>˹ j=k:Oj}\-*z\χ:{"Vq>)sݿatX+ߴF+G+i@p:PXxFwa_cI>#Z3~yOt0i_L:{Wzޖ^'ۂ;қ]#׸D4o\Fv̆ 4;.y;mH< _ye 5lh_䐉=%+k t7ms?ܺfrEȵ"y@z~;Qt7LDc`Yomݏ2ב ǒ{wkkttjh~k$Yu`ÆLgQf2#3@rw>'[ p.[]|&d܌zLvmK``4Ӏ|j8/ '=;곗ϩ-ό1||7?4:M۲wQ+nEtZF?fM[ohjߴ3|?ncW!6{;rګ7c CDY}Y{QbڃN<ԓ&Y2k!x߉}^oWr,Е{`یw^%ONtv`2l^5nJz?(,5 Mlz-%*7GQ%'q+k_.P+̶Zhe}~Y%t${agQL]FICMt%Y~x.'?l wjt ?-ƶܑ+Q}ϣN!Saw%6UabhE;?x!ǓF^5II[%jwMzI\y1Jmꉷ'+'z% +'OM]R+鵱ՠ7:B7Ϩ-`˛ֹu_<.+bk^8.KCl;?pxulJ AzOϚqm]?gtkf{Ս9mħ}N6xv -|/(JL ץh~S8wt>- v(siQMjCB?0ջ'mlE/uqtKr hgv쵡w ]7}#η/cs umG=vWԮp+:[z=sl(=>xFunK'<ѡhFQ\A k{x*QǻQG[@6B$O_̹NZ;kj#p=}DHύ- ~=y#΢K9Mv~c jY8JnLL@&KfQf,l(~y}%?tzstH.؊R;Qf(g'OΣbc 4ʌ91X"ilgEszC݀nQj>M{7&gҷYΦ?g:WDuKN%_޿. {gaj@kC~卸3x{Qèə2^[QXD_(=r.SW=_ŇKg?TY/W6Z,W9erEo +oWZ?{˕˕fZ߮﫳WsOjT߹iAx?Tߵn~S}ZӞE\mG|Kz-W<-}x;?|Zߐm"~Fw _nXi˗GN^ǩm[^}%5{#u}^&u59Z܎RSmCEa>:(=ώ=2 o*Qr`FaًrSpa˶H z/CGQ!('%О3Z_~(5E 7}ҕ>u+yGɫԶZD̀3љ/gQ/Sz~^?|GrkL" `'lO{'y^iu|x*n{9kL=_Qx WΞKՂgGᙩh?*:4;T g[뿫m o=_>~Y뽑vIg&7zm^ZG^bo?cdGoxν'/-7ok;ﲸ=;O=/,v6ݳ3kl˺2cۆͮ7֯O1Ϗ~>ްߟǙ3Y` {{'ɥE9t 2_Po{}`,ע݊]jDwW;%W{CՕ2yVRGQ84G1#L㨼%t,:yw5W-(zی$#x>N':CmHVjPk xBtՃxcK↾rűΝF5OhOQ@Ʀ#n0*\v'qS㷎xgֲ~7ko!睥+3F֖lqӨi<`@ۗk? ~Iﬥ_-V%3g$9|_Γ/Koh,O}'˾E<:",@k̺è>k3S~'fKpP3gvM/`}UKʶGᖶG}FG3ѤMN=Izovۨ8ȍ>=1OL[LL zsF a>k'Q}Y"3HggQ5|o_MtG27!\k>[nS]{-S۳3?*N13$2NvxG L/&Ϡz|vL0|G#:z.^y1C'=,`?5\O &9sh4jG'_wlȯxei%O\;/:s5D9%7ZQ{gcWq(q=عCQ=5BN%WAl0e{K>5c&wkh7q=4cNN䒾c{(<ݮlH繿|v.RM阘Qq?Di=oj|Eڻkzӎlw%|q&@tzDa#f`({g**WR`itWfԙUTJNp01!壾(b=޾}`Q?_ƿsڑq}o;<'Uw??j>Eu2*_jS~-zZߥopqէvm2N;Ff^0{E-:)\綢]x#D6w}7`'O%ߓh9~O|mcz#zl Ͼ0׈kIh^LGܷԍ8aQpe|:4yWz(Bos%k{r~;v1!2+Ev&3-eޙh(|˝6ʗqlM``w3g-w[ҍ-;|E?j}YT/\E];v䦔$ +Qk)x7mfQMntVkm;M7Dё`mlz'zm).K/ϓO^@_r]T>tZ{(qs.Nt^^7FFF\8^cҗ>07{QwӨ#o,y)xXT4K(wsXvDVw Cԋkl{(\rUS+ͮhBf Z@>O7$Ȧ`Fһii&No{ⶥALٛNj7Q~׈ҖdlI6l7S+E靾qyCwCAot?}* +'rNYyqd󞭝ٹ391wOly7vfs| R|!x-wf_Mu>^y;v58Qx'gڲ 9ϲ:R|]T|UsGͣ#޷Ak>Mz5sM,FwjܱXp8 +0l;=;èz=ɑًӕ#㿏%!e⽉ꇰOWtsxOL>)^xl?%\oXxQ9 O +u_`͉҅c\١k~co޳weg08 /d;E4WET f\okzF,]B)<~rVտ%"Qy'tAT,^wQ)^ץUTO0E:.} =Zr ET-q<\ΙhTc!:Co1y#NXiyTȋ;cѡf6zQXѐ~ oj>xQ-S36w9fϻC;GFersi{ޞ]U1ԳLu; _39Ommg-2FToXoulA/e#_//'͓Ư|?Oοvܻ/9>hqMLe>cCoKw:;yKg,zO\mTߑpsu>c50H_z{'tfVeaT|#{pHKۨu$V>C3ukFK&c|F83Mً#-]-9{FMӾohL:-5V¶Q}&kC3g=鹰Xfԩo57!Ox=GxUzy=5/ l:Ȏ[T~}$6 +G7?YSxz&?hW?U1Ox {F!ϾI\Z{6igr~[>N9xyOe] =.{Or499wJx~tה>HrX9~*9`:\?|MN!yѻ[?}̇ԳybGRJc--bߑ2*~lwkY?Sb joCjߨeoٍ?{B]gޫ='^3ez?Ouc~O}玕go߰*㹯/ٮ/ =nGlC]7ʸ.~!7'ud<>4Tbڡ2׃e2QX+}sce^ba_z>2MdoӶ#/^%=!B`ʦRʸ'gd۞}^ƲL5w;Q'yֳ}cr[K&gȳ?Z̏lDZ^G񉟍ro[q-+#yC >r yڤ{}?*Sezjy| ߧȱczcF>3O+gyjiF>8 }aj:әy]nV̏ƽK4M ,زvMȼωuw@k=Mu{ϴ#^  e/_5xl[ Cߩ [+_no'떳[e4s;,#~@#e-Y&|JƷB<hYߟ-8r%r̫Por,}UOw(w o*}y6|X>׶;m-N{by|zE^cUٯPGJ5Oʽ'˺r +_{RhKawk_,к/o,w!x['_gQ>^7\]3ĶuX6P_T{|;6L`8-6}lke Y]MI-FUx*ˡuSbSreϬSe.)z<; U}֊&Ժs픳_J܍?4ʺf'~W?S掏{yDFb<4~|>y _e$ w?u/ex'ce\kݿk>[zX|f>|g\LXO=e߲_jyY> +^ީWJD#%9P zmA}>6Ho,˝iGJD7o/}Z3C-`?YpF,kir{e{bIR&{Z({^OW[wǿhџOXA7Xzؕk:K4.F*9leINbǎ;vdIY +!(bTXl`k.XBv,k??cSE7{9ynQnd+ |[yF͹yMmÛoZZ.= 2Dl@,e}h'wGFv qbQ;۞3$gSS""9jbXnix,9}FHw9,rz9O5͹Udn"iQCxO^uOjڢ-+vI'8Nauݢnt,c =NNt@goӂs$ xE~dZq՟Srsy'3E/rtw;_==U[ת9k } ?;i#` <(ۖױ:a˚~S+J\-s𙾿-{}X㏅=>(xcX.5|}]MSޒ7thMMl~8_͵oQ3M-bgޕl@Їs9m܎WKkg<\:.-VC N>['}?upE}:J|Lzݦugz?xI+ɻվRs{ѯZԚ+to'@2dswDg,L}nlݱ!6Q́zv-8Di+Zyіyw< U-WWץ5Y- BZ 5gyd]X4 ^= \^Rݓ] `5z;] J6ZԨsKj3xgHȡi;8۷qʂ,*=r=<ƚ:L?t_d$o;㷚o}cXU95ӺGuTv Ic}*Y|d5-l;hS6 !XCmh'W>%;dkim-=-w$s] Jmxn,=; .CG>swl ^Xptr]p]^<^KcɎ~7e+IyfQOJ?ˡ<Խc^snE5ƚ'(i=ȲW"^mYfs}I bU;mG>Z֐gC=}Y AV"Ny^sرȑtE|2!yc?=}'vw9iHSp\M~zOm/%Sـ;4m\@8Y./+ϯJx +vgvgY.փWXn|߉)poG/^=>f-G0xSw= 1 +vv,zc}lsҗ^4X{;lY#N WOSsӽ v޹d@=/4jyk׽nO%mwƛ}tg#*yPM6mJ֚ҺUY<}10"{-[Գ+9 =02#=UARj|@l,8O]gV~I67#,Ģ^:~-ͯbH,"?カ>]d' lK{q_|`G>ڱ ykײGϢ?]sz7|ǖz%f1=FC:sFS{/|Gwse9>j\A&]s/d[]ؖv-bKٴU,q"],j +muf݂{wk咽`HI.|{OC|՞N/cLm=1~2y >nNAߴw`P5ѕ䷆,x@?_@~ӂ+8.y^7Ǒ_jZ5jrn&vӀ-8]4ǻY3 V3?ҝNǁcij9=~6x7 ^n]32=SԏFz/Ǩ5>l?^67axlS߳ȕIYy)?}kG<kq?ǃRi߯Rz/|Yz,0u(jB֧DEŞ^/.i[ÕG?V~U~YX;c^~J*- A>xHRÂF(%iJ1.X` .X &w,01ƅ C:Z(;~sϽse/jFgc0%vE_ll{9l7g)6e;r_ڴ>ugF{sؙњ+Vߑl5.Д+ǫYm)ЖnCYiv\wʾ֌9?+ +wĊlڃI'k!D)~⧸lolwĞ4>3B7>csGpOo|׏͏{biF,E]|h1?VF}η-(ΎE{YD!\s +PYR\[eN4Lʣ43ꎕ<}/\ܓΘϨ(Zu/B'7p?ӂ-l ZxT=Stf%;9 PPUP}OnuZ~jʷߪE`:V_fK=T`z^9DU Fkq_fMfC@5ZPrk+{؆2CujQYZT S62#;g]9V5'&lkTSjcuuZfE5d+)sbQ,YEWR>77co8ߦ5ŮS~7Z(}T$ۓu`o#[OD> W+߀i +endstream endobj 11 0 obj <> endobj 8 0 obj [7 0 R] endobj 31 0 obj <> endobj xref +0 32 +0000000000 65535 f +0000000016 00000 n +0000000144 00000 n +0000043581 00000 n +0000000000 00000 f +0000048567 00000 n +0000048704 00000 n +0000048377 00000 n +0000203471 00000 n +0000043632 00000 n +0000044007 00000 n +0000203358 00000 n +0000047623 00000 n +0000047815 00000 n +0000047863 00000 n +0000048451 00000 n +0000048482 00000 n +0000149265 00000 n +0000149290 00000 n +0000048844 00000 n +0000048869 00000 n +0000051315 00000 n +0000051570 00000 n +0000051639 00000 n +0000051913 00000 n +0000052366 00000 n +0000150028 00000 n +0000150202 00000 n +0000150271 00000 n +0000150545 00000 n +0000150765 00000 n +0000203494 00000 n +trailer +<<0387CBBD1D3BF04FB5D480B9AC1940E1>]>> +startxref +203716 +%%EOF diff --git a/assets/img/隐私协议.pdf b/assets/img/隐私协议.pdf new file mode 100644 index 0000000..969e75b --- /dev/null +++ b/assets/img/隐私协议.pdf @@ -0,0 +1,1078 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[7 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + 隐私协议 + + + Adobe Illustrator 24.0 (Windows) + 2025-05-20T17:00:54+09:00 + 2025-05-20T17:00:54+08:00 + 2025-05-20T17:00:54+08:00 + + + + 60 + 256 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAA8AwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A7pepr7erLFc60ixPKRDD HpJLjlzVU9VDtxHBCT3+I13CrIdOkneziM6SxzBQsgn9P1CwAqW9EtHUn+U08MVRGKoqL+7XFWP+ YLXVf39xZ318p4USzs0sWaqitUN0lOTU4/E9Pl1xVaNG1Vltz+nb5DGv71THYkyE0Px0tyBSlPgp 39iFUytIJYLdIprh7qRa1nlCK7VJIqI1jTYbbKMVRP8Aur/ZfwxV5LqhsLPUdVeG20uKd3nkk9e8 SFY6mUepMi3IIc1aUuqqeLL+0uyqBgXVraIxfofTIkupEkmtZNRAjPNwojBFxRHUxpIVCMpPdmJY Kp3c+v8A7kTaxWctrUOJYbtgeUb0USL9ZjULIyoSOQBVgDvtir1CxcvZwOSCWRWJWnHcV2oWFPpO KvOPzF+sDVTJa6RbajPBH6zeveixYRpxpx4yVcPIVX4wo2471qFUp1GINJcQ2NlYnmPR9CO/dvTu I1RzE7C4gNPVmYURP2d+oxVZDY2NwJHm0+xa/UemFs7kPzKoPSQxi66s6qByb4S/Ku7MVWVfXdY/ 5Vx6/p2v1nnx9DlH6X1b16ejX1/T9T6v8H99Tniqv5g0OC5F1aSWE95bSQXM37qCxZQ8lSY4/W4V ldiSOYZD+344qh7W0lMcd6dG1GORZuD2Ekekh3UqFLsY5PT4EOa/vOWx26YqncXlvy7Lbxc9It41 qswt3ij+CQkOSVXknPkBUjqR1OKsgi/u1xVivmXSluLue8ks7m9EMXFLWGLT39RiylTG1zR+UdCR yYLueu2KqVp5G0+K2SNpAaQpEB9VslC8ECBuKw8a7cjT4a9ABQBVME8saMYkS6tYbuVNhcSwwiTi AVQfu0jA4IeC0HQYqmX1O0+p/V/RT0K/3XEcKeHHpirzTVtVW0167db2ykuIbkMzC2NxNAAJnSPl b27u7UAIFa1ZlqSvxKpQnnrzKJ7hR5ptLkOZ1trdLaVLnlE49MqgsZTR1nT9lgQlVLAsVVZPpHmK S4trZn83LcSJCn1oLYenI0peVQxjZOaB3QgKVBKJUd2xV6HYyiayglV1kEkauJEBVWDCvIAkkA/P FWOaxout3uqTMtxbJYFo2hR4FkkVkALMxbY8mVaUpSlfkqhoPLXmG005LDT9ZjsooiBD6FnAiRxr X4EioVHInr28N9lVS+0fzrLJMbTzFFbRtEUhU2KSMknEqJCxko1DRivGlfbbFU0+p65/h76p+kU/ S/p+n+k/q44+pxp6noc+Ne9K09qbYqxLWdQ8vW91ctJcTmeIszJHf6jy3nAYcIEk4rV2OwpRR+yt VVTKw82eRoLi9a31Qu0aCW4klkuJYwsbND+6eTkh+JDyEZ/yj1riqNTzl5WdyVuaOWSOpgmUsX48 KVQcgTIoBG1TTrirJoCDChUEAgEAgg0+R3GKsH86aZJc6n6kA0xiEBlW/nmiqVrxRhG1OLsU3Kn5 HbFVCz8reYLOKWGzhtrWGIq9jBHeXqJVKCNXZW+wATVQnE06Yqjl8u65NGFluxbrE1YlS51CRiOS uxkk+sxs1StAp6DatKgqpp+itQ/QX1T6yPrXq+r6vO5pXn6nHn63rca7fbpTalNsVY82n3n18tLP rMsby3DOsLJHCT6vCIUmkMooi/DxorfaoKjFUuW0aa4e3tdS8zS3Ts3r3AhjiUr8Qr/pUSQhSYm4 qijrWm4OKp5Z+X7t71JZb3V0iaJC0M8ttxEjDlVnirLWNV9NlVuFTyFSWbFWZwLxhRak8QBUmpNP E4qwzzZFqc17cRWf6Rjr6TpdWkixrG0YZn4LJFLG1V4g8gQTttQ4qk1xovm+8VLv/ctZXEqs/wBV j1OApCPVLBDSJlLtGoXowFftcuTYq6+s/N81vd/V7LVUMEYiitf0nGjTmvJpllCuVYrHxpzUDlsA fiCrI/qmp/4N9H0b79Iep6no/XF+tc/W50+sV4cf8n7PD4adsVW3t1qbSyw251VHUyoHjhsylQeQ YNKApFHVV3+e4chVSg/TzQSMZdYWSZqokselcoVNKU4jgRsaVLEd+2KpwdSuUhLnTrpuIHwj0Cx2 32EuKpzF/drirGPMuoXNpcyCI6m5dOKJYQW8qq7/AAKwaVCAV+18R47b7dVVVPM9qLaKa5sr+2Mp fhG1nNM9EbgGb6ss6pz6qGIJHbFURFrtjKsTKlyBMquga0ukNG6cg0YKn2ahGKo363F+j/rdH9Lj 6lPTf1OPGv8Ad8fUr/k8a4q8nvwL7Wby99PSLq9E91bCaRdRjeOOKVlhhkuviUH1VkDxBabqVGwq qnWhJZenGumCxbTIwJrZRpN+ZPTlb1I29Z3/AHz19RmPHdiK8e6q5ILG304G1tbSK1VQlvGNA1A8 FLAUESsG48jU0A618SVXotioWzgUBQAigBF4KKD9lT9ke2KsL816X5Zl8xW815LHBduUWRQtwJJg 1YVQtDIimochQynx7Yq7SdF/LuK1hOnejBA1I7ZBM8RU82kCxqzKynlGxWm9AabYqvj8ueQjyijl iL2rAyEXbGRHKNOGdvU5BjG5ep3K79AMVTb6j5e/w59U9WP9E8+Pq+qKcvUp/fVrz9Tbny58t68t 8VYq9j5rn1m9e7tdUjtEZvq3oahbGKQl2RSIxGjRjgwfqabf5WKo86R5iubma4ZLpBHGhs7V9TeC EMU4cT9XhZyVFS3qchybatBxVRtppuri8M09o6BAnpcdWu5Vbhy+3EyIg6r48t6/ZFVWWQcvRTkA Gp8QBqAfY0GKsJ88291K8vp6iLEKvNWGpfUCFKNE7f3E32RKWWv7VDsQCFUJYWl1rE7TWeo8ow4S 8+p6t64jDpUNwEBUMyMrcAVG/wAOKpy/lJnBDazqRBXitJwhUfGTQxqhr+861qOIA2rVVGfoF/8A Dv6J/SV5z6fpHmv1mteXLlx41/2NPbFWNz6x5WvNXuNJvtKsJYiJoCxuLGR3kDO08RgZw4NKu3f4 t+9FVU6t5CnUmazsxZcTK148lgYOc7tyjLLMSXZk32oajfrRVcnmjy1YpJe2mlhbgUiKwyackzFi OaVa5QfC4o1W6iu4ocVZxbtzgRqFeSg8TSor2NK4qwvzTokl7q10z3cZSe3EMdvPpi3kSciUJMnC rBuXxKz0+W9VUBH5KvLqzE2n39tFZyxUsLefSoUVYZijMJoisMnLiZBQcN23G2Kpho3kRbdPW1S6 jvtQqQLhLS2jCxrHJDEqgpI/wRzP9pj9ph9mihVN/wDDtt/hb9A1T6v6X1bl6EPHhSlfQ4+hWnbh wr+zTbFUsj8x3Daj9Xj026FtFLMZJDZMFdk5ikchlFGLpXkUowYU8cVaPnOxqlNE1NmmnS1oLM/a NWRmJNPTDbc60Unem+KppPqk8buo0e7m4iM8k+rUYyOFYDlMv2PtN7dKnbFU+i/u1xVinmPSLC8v LiS50i9vmC0EsE6RghQDwjBuISK1odhU4qpaD5T8sLEJx5eFlPEhtU+urDNMYKA8Q6yXH7s/ylut dt91U2/w7oHP1Dp1sX5K/IxITyQMqncdVEjU+ZxVG/U7T6vw9FOHretx4inqcufP/W5/FXxxVi8u u6lbS6lZ2yA3Kh57R7mHUGjH2x8bmIoV5JsI36bgbgYq7TtR8+X3pSxppyWzQwu/rQ3kMpdgfU+C TjxB2IG5XcEnriqLhbz6ILYTrphnPAXbR+vxBJ+MorN0UHYFt6dq0CrKLb1Pq8fq09TiOfGvHl3p XtirD/MuhW+oX9/9ZntEt3hUSF3mjljCqT8ZjmiopUOwYcStPpxVVTy3q8crRpqX+hKo9BXe+ecO R8fOU3Xxry3X4dsVTJ9OuleM285QRtv6sk8vJeXLp6ijqzDeu1Owpiqj+g7z9A/UPrr+t9Z9f6x6 l1Xj6/renz+setTj8H95xptx4/DirDr7zHqllr91HYXVvccHlNrbt+lbp5WSrTIUi9WNGj50VUDH 4SAor8Kqb22sefVJ+uQ2Do/p/V5IYL9eXInkXRlfh0oFqf5iaEYqnOmaxdGCU6pGY7lGZhHb290y CIGi/E8al2P2jRdq07VKrIYGDQow6MKiu3X2OKsO80y6Ompsl55hutLuX4CKCJ1QUNaFUaNw/wBl uR399sVQ48u2V3LdQQ+bdR+ss4imSC9jLQtRmEaIVfgePPrV6dSeIOKpja3Hlb1mMOsiVyFUodRe QCv2aKZTQmv0/diqZctM/QtPrv8Aof2Prn1g8q1pX1+Va8tuvtiqS3d+GuZUBtPrEfJUjXVpY2Mg lkqrKI/hopDHr3WlFFVWvK+sWDRevc3lpHNcxIwji1Z9RjKqzENGZRGACrrVlXfYdgcVTey8yeXr +drex1S0up0Zo2hgnikcOn2lKqxNR3GKp3F/drirE9eF0+sTC1sJbyaGESAJqDW6bq5VXiVqrzeL ip40O/gcVVvSWG+W9jsdRll4RoR64aP92roAY5JwtfjPIgUY0ap2OKplFdSEkmymiY8a8vS/aam5 V2Hw1qfbpiqr68v1D1fqsnOv+81YufhT7fp/8NirAVv4G82Trc6sHs7h2VbabUZLVoXgkEDiKJba F2B5A/FOQxNBt1VZXb695UUukerWjshHJWuo5CtR6dPickV4fSa964qmyJEByjVQG+Kqgb7ddsVR kX92uKsW8w3c9veXLJf3ULCLlHawnT/i4qWJj+s0atFP2244qt0y9jivP9M12VpJnPoWN21gpZdk /di3RXK8zTdq8tsVTGTzDoEUZkl1O0SMKXLtPGFCitTUt0FMVRv1u0+p/WPWj+r8v77kOHh9qtOu 2Ksav73T0eS3bXbiG4kkltjIlvA5jlP70Bybd1X00mQDnsRStSSSq6Kew+otdHzQ6Q3QMsMk4sYj GqpzYcWgjIKIrE8xVd+XTFU8k1jSYbVLqa+gS2fgEuHljVGMh4pRqhTzbYU6nFU0tpI5II5I2Dxu oZHUggg7ggjqDirE/Md1oqavLa6ppl3qX1m3cIqWX1qERBGEqB40YguGIKud+ijFUPZP5akt1RfL U9vbqys6NYikckkIJ+FORbiihGKBh0WuKo8nyvNK5fTmZ0YszvYT/aqzGjNFvuGO3j77qppXT/0Z /dH6p6lPT9J/tc6V4ceX29609+m+KsbefVLS/uDNqkEUN1OY7S2kvLcqnFakqXtPVL78ijO/Hah4 4qjrKC91IPcJq5EKOUQWrWlwjrxrWRjb/C37zdQewPcjFUdHpd6rTGTVJ5llULGrx21IyDXkvGJa n/WqMVTuIARqB0pirG9fsxdXT28SWvrTq0fK5s5ZgXC8k5SI8YoONach8wcVdp3liwh5SXtnp8ty eIWW3tBCOKgUBDvMSQ5Yg17/AElVMrLTrCxQpZ28dujU5LEoQGmw2GKov/dX+y/hirAL/TkstYMj 6pcpzd5pIYtGWfmjNOeHrR2z19NS3HfluOXLmOSqNtfJFzbvNJBcWaetGyf8c+FT8XL4jTi3+7W2 O2/TrVVCW35c6lBam3/S0EjTTx3Nxctptl6haNl+yojEdfTQKrFSVIBxV6FbII4I0X7KKFGwGw26 CgxV595ytvJV5r5h1q3iuZwViZLie4A4yRl/ghVHRj6cbnb/ACqkVOKoTTf+VRRRvfWl4skTTpBM 5nuZEaYRrEiSKzEN8AC/EO9Duxqqm9rfflrIrywJYlWETPOYBRqr+6/eMlC3Fdt6imKpx+mvLn+G P0h9ZT9CcOHrfFx9OnCnTliqBl0jzjPcSONdFlA5nURRW8MzKpkb6u6PIgowjI5hgwJ6dCWVXWuj +cYbdY5PMKXMtayTzWUY2p0RImjA+LxJ2/FVbJovnFoeEfmIJKTX1fqkLUo3KnHwIHE96HYg0OKs sg5einKhanxEbCvtirF/MWrzWOpBrb6g1x8K+ne6nJZrwNasYlinUkEgA8a79cVTexFwbaNruCK3 uiKyxQuZUU1/ZkZIi3/AjFVb0ouXLgvKlK0FadP4YqqcV9KlBTlWnv1r9+KvPqa7d6lfm20zS47h VuLbTnuLS9+MtJM0nqylI1VHohbj9olqV+GqqZaPp3nXTLWO0tbTRLSxhkJisbRJ4kETNIzhSDxR mZlavA/tbGuyqMWXz+8ij0NNhjBi5szzSMenrcVASg2bgSe4qNjVVlNt6n1eP1aepxHPjXjy70r2 xVh3nN4lnmZ9RSypHu76m1hwHU/CEdRWn2yK/diqUaNZ6ze6dOulaob22jkaFLqHWfrZ+Bt+crWj lZURxRNweI5nkScVTuz8r6nExjuNZv519JIxctcAP+7DBf3SRRpU+o3J6ljRa1oKKpz+i3/RH1H6 7c8ufL65zHr/AG/UpypT/J6dNsVYvc6gbnXptMjtpZpkLRzi21gpJHGTI8bvbrKjJz3pQcqU7Lsq mMnmHzMkjqvlmd444VdX+s29XkINY1FezACrEbGuKqdpr/nSWZVm8riGFkB9T69Gx5EA04+mvw1J 3NDt9nfFWYxf3a4qxHzQ3mh9Tji0qG5W2Uo0skUtkkcnxUZWE8M79G7U6dupVTGxl15bZxc2Nukq CkQjuS/qNQDlIfQhCb1rxU7dB2xVbp115mkIOpabaWyErX6tePcMKk1qHtrcbfD0bx8N1Uz5XH1e vprz9SnHmacOVOVePXh8VKddq98Vea65FDY3uo3013ptpdSTSCQ3kGnI/pDj6PrM08bSVMtF5OpK n9k7lVFaHB5eh1e8W/vrG2NxdRwwWDxaZBI90FjDx/unmkdmrGeB4vybwK0VZVZab5SVxaWNtYqw iUi2gWIUhR+KkIv7AeOnSlRirIov7tcVYb5ys0ubsqZjHVYkKnTGvlKs7I1WEcgoyyFf8ncnYnFV 1r5c160s4LXT9UhsbeKIqY4LOJFMhqfUCNXjUmrL39q7Kpt+jtRIctqswdypHCO3CoQwYhA0bnia FfiYmh61ocVV/qV1+jPq31+b1+X+9vGH1etfs+n6XTb7H44qx6412Wzlubyaz1W9hD+hBZi1tyHk 9VyrxU4P29Mc2AAAY9eRVRkPmn1bw2/6F1JHXgRK8CCMmQuuzhyPh9L4vCq4qp3nnWxt3j9PTdSu xIyqZYLOQqqvK0Qdi4T4KoWqP2fi6EYqyq2dZII5FrxdQwqCpod9waEfTirGfMt1qUNyxtb+a1Ed GZE06a9QgU2/dKS3I9QrA+FDvirUeleblcE67G8XUq9mnKvw/tK6fD9rala0+LahVV4dJ11rREut blW7UJ6k1rBbxoxVOLHhNHcEcm+P7XXpttiqafV5fqPo/WZPUrT6zSP1PGtOHp/8LiqTXH5b+U7k 3JutPjuGu1kSZ5i0jcZZDKyqz1KrzYkKNhiqKsPJWg2MfCG0RwGDRtMWmZAoAVUaTkyqgACqDQYq qf4P8vcp2/RdnyuhxuW9FKyKWLEOeO4LMx37knviqcQRJDCkSKFSNQqquwAGwAxVKb+11Ge/fhJH HacBxPKYSeqOXURvGOPxCu+/3UVWG21iOAw21zAvBOMLzRSzEEFuPMmYM/w8anlUmpxVpIvMap8d 1ZyOGQ7W0sYKj7a/38lC3Y708DiqO43n1OnqR/WOdefBuFK1px51+ztXl13p2xVH4q7FXYq7FWAe frnQIL0DVL+K3eVVSCNoruQ1YsqFvq8ijiZDTdRX7NakYq1BBZxx20aa3ZWtrIsaSRRyXMEjzfAI yv8ApaFS2wZGUsagEnuqjNL0mznmeNNbe7EMrzItte3RdHkCsBJyuZwyKsgKow47jbFWS/VY/qno 1k4cuvqSc/8Ag+XL8cVR+KuxV2KuxVjevaxb2VxNFJdwwXLxj6qZbaWYJzqoaT02Xknqca7r4V3B CqBj8+eWI9MjurzUo5kWBZpryGCcQEFeRZdpeNaH4S5Ox/lOKq9p538pThfq16rKSyIVjlCkxj4g p4U+GlDT5Yqmv6a0j9F/pH65D9R58PrPMcOXL0+Nf5ufw061264qm2KuxV2KuxVJNQuHtLy4uP3A i9JeTz3TxgOGIVfTKMiKwr8YNSRSm1cVVrC4jurNZVMLpJyFbeQTRGhKmj8Vr0odsVV/Si5F+C8i KFqCtPniq/gnoceI48q8abeOKovFXYq7FXYqxTXWtYdY9Wa9uhK6AQ2kVxBFHXkApEcjx8yDX7VQ a98VQseoafpthDZX890OQUvPc3kEcqIoERkdxOrU+Es1KmtSatiqJb/C7q13+mGEXpcmkXUpRGI5 SaPtNwFTC3Fu1GAPXFU19DT/ANGeh9Yf6v6vH1frMvPnz+z63P1Pt/DTl7e2KpvirsVdirsVYh5q +qfXeb6aty0ZUtM1g13QkHf4XRiAq/shjirflnUXmskA0qeGNnKqxtRZKI+RZawzStIOIbc9+w7Y qmsd9KzhDp9wlSikt6NAG5VJIkOycd6eIpXFURUfo7/eRuP2fqn7utOlPten03+1iqY4q7FXYq7F WJ+ZdWnsbp3QapKsZj5Q2NvBKreoeIAMicjv9ohqL3piqiPPlpW2ZtJ1ZIbmYwesbKQiNgAayKtZ ApJADBSKn2aiqLh80CW5Fsul6gJWjMi1hURmjKCvq8/SrR+X2qEA0OKpp9cm/R31n6nP6nKn1T91 6v2uNf7z0+nxfb6e+2KpnirsVdirsVYb5n1jQoNTawvTqC3F0vpobaaeFCDGzEoySxKGCqdxvX3x VJ38x+UdJ16C3WXWJtQMdFt5Zr5ogkcagF1upFiLFIuZ6t1dupOKo+T80vK8aymT142gNJklRYWW kfqt/esgYKtalaim/wBmhKqbf4x0b/Bv+Kqy/or6v9c/u29X0+PL7Hj+HvirJcVdirsVdiqRapHq SaktzZ2iXPw+lIJbuWJQjNVisIjkjZhTqaHtXFVOeXXzCWTTLOSckLwe7cLxqBUv9XY/ZZjTj7d8 VTBE9SIevEiu1eaA8xv7kCv3Yqr0Ho0ptWlPoxV//9k= + + + + uuid:C1BCCE1871B8DB11993190FCD52B4E9F + xmp.did:99c7fc9e-4cbe-7546-8907-ce2f9d76bbdc + uuid:f4d5fdc1-bbdd-4bf9-9fb3-a24b88fa6a03 + proof:pdf + + xmp.iid:3cbe7e43-d8d8-f741-857d-d8115d20e967 + xmp.did:3cbe7e43-d8d8-f741-857d-d8115d20e967 + uuid:C1BCCE1871B8DB11993190FCD52B4E9F + proof:pdf + + + + + saved + xmp.iid:68134316-a8aa-d74f-9108-ff386fa851d9 + 2025-05-20T16:57:32+08:00 + Adobe Illustrator 24.0 (Windows) + / + + + saved + xmp.iid:99c7fc9e-4cbe-7546-8907-ce2f9d76bbdc + 2025-05-20T17:00:52+08:00 + Adobe Illustrator 24.0 (Windows) + / + + + + Mobile + Adobe Illustrator + 1 + False + False + + 750.000000 + 5573.000000 + Pixels + + + + + PingFang-SC-Bold + 苹方 + 粗体 + TrueType + 10.11d9e1 + False + PingFang Bold.ttf + + + PingFang-SC-Regular + 苹方 + 常规 + TrueType + 10.11d9e1 + False + 苹方字体.ttf + + + + + + Cyan + Magenta + Yellow + Black + + + + + + 默认色板组 + 0 + + + + 白色 + RGB + PROCESS + 255 + 255 + 255 + + + 黑色 + RGB + PROCESS + 0 + 0 + 0 + + + RGB 红 + RGB + PROCESS + 255 + 0 + 0 + + + RGB 黄 + RGB + PROCESS + 255 + 255 + 0 + + + RGB 绿 + RGB + PROCESS + 0 + 255 + 0 + + + RGB 青 + RGB + PROCESS + 0 + 255 + 255 + + + RGB 蓝 + RGB + PROCESS + 0 + 0 + 255 + + + RGB 洋红 + RGB + PROCESS + 255 + 0 + 255 + + + R=193 G=39 B=45 + RGB + PROCESS + 193 + 39 + 45 + + + R=237 G=28 B=36 + RGB + PROCESS + 237 + 28 + 36 + + + R=241 G=90 B=36 + RGB + PROCESS + 241 + 90 + 36 + + + R=247 G=147 B=30 + RGB + PROCESS + 247 + 147 + 30 + + + R=251 G=176 B=59 + RGB + PROCESS + 251 + 176 + 59 + + + R=252 G=238 B=33 + RGB + PROCESS + 252 + 238 + 33 + + + R=217 G=224 B=33 + RGB + PROCESS + 217 + 224 + 33 + + + R=140 G=198 B=63 + RGB + PROCESS + 140 + 198 + 63 + + + R=57 G=181 B=74 + RGB + PROCESS + 57 + 181 + 74 + + + R=0 G=146 B=69 + RGB + PROCESS + 0 + 146 + 69 + + + R=0 G=104 B=55 + RGB + PROCESS + 0 + 104 + 55 + + + R=34 G=181 B=115 + RGB + PROCESS + 34 + 181 + 115 + + + R=0 G=169 B=157 + RGB + PROCESS + 0 + 169 + 157 + + + R=41 G=171 B=226 + RGB + PROCESS + 41 + 171 + 226 + + + R=0 G=113 B=188 + RGB + PROCESS + 0 + 113 + 188 + + + R=46 G=49 B=146 + RGB + PROCESS + 46 + 49 + 146 + + + R=27 G=20 B=100 + RGB + PROCESS + 27 + 20 + 100 + + + R=102 G=45 B=145 + RGB + PROCESS + 102 + 45 + 145 + + + R=147 G=39 B=143 + RGB + PROCESS + 147 + 39 + 143 + + + R=158 G=0 B=93 + RGB + PROCESS + 158 + 0 + 93 + + + R=212 G=20 B=90 + RGB + PROCESS + 212 + 20 + 90 + + + R=237 G=30 B=121 + RGB + PROCESS + 237 + 30 + 121 + + + R=199 G=178 B=153 + RGB + PROCESS + 199 + 178 + 153 + + + R=153 G=134 B=117 + RGB + PROCESS + 153 + 134 + 117 + + + R=115 G=99 B=87 + RGB + PROCESS + 115 + 99 + 87 + + + R=83 G=71 B=65 + RGB + PROCESS + 83 + 71 + 65 + + + R=198 G=156 B=109 + RGB + PROCESS + 198 + 156 + 109 + + + R=166 G=124 B=82 + RGB + PROCESS + 166 + 124 + 82 + + + R=140 G=98 B=57 + RGB + PROCESS + 140 + 98 + 57 + + + R=117 G=76 B=36 + RGB + PROCESS + 117 + 76 + 36 + + + R=96 G=56 B=19 + RGB + PROCESS + 96 + 56 + 19 + + + R=66 G=33 B=11 + RGB + PROCESS + 66 + 33 + 11 + + + + + + 灰色 + 1 + + + + R=0 G=0 B=0 + RGB + PROCESS + 0 + 0 + 0 + + + R=26 G=26 B=26 + RGB + PROCESS + 26 + 26 + 26 + + + R=51 G=51 B=51 + RGB + PROCESS + 51 + 51 + 51 + + + R=77 G=77 B=77 + RGB + PROCESS + 77 + 77 + 77 + + + R=102 G=102 B=102 + RGB + PROCESS + 102 + 102 + 102 + + + R=128 G=128 B=128 + RGB + PROCESS + 128 + 128 + 128 + + + R=153 G=153 B=153 + RGB + PROCESS + 153 + 153 + 153 + + + R=179 G=179 B=179 + RGB + PROCESS + 179 + 179 + 179 + + + R=204 G=204 B=204 + RGB + PROCESS + 204 + 204 + 204 + + + R=230 G=230 B=230 + RGB + PROCESS + 230 + 230 + 230 + + + R=242 G=242 B=242 + RGB + PROCESS + 242 + 242 + 242 + + + + + + 手机颜色组 + 1 + + + + R=136 G=168 B=13 + RGB + PROCESS + 136 + 168 + 13 + + + R=127 G=71 B=221 + RGB + PROCESS + 127 + 71 + 221 + + + R=251 G=174 B=23 + RGB + PROCESS + 251 + 174 + 23 + + + + + + + Adobe PDF library 15.00 + 21.0.0 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 9 0 obj <>/Font<>/ProcSet[/PDF/Text]/Properties<>>>/Thumb 12 0 R/TrimBox[0.0 0.0 750.0 5573.0]/Type/Page>> endobj 10 0 obj <>stream +HW۪#}?_ں`hJ@ $~B@$-r̄:e]u?v|ͪ.7Ͽ?/WWM]%8] ǷW/Oo 8VJ_;=RvQkTJ$HQ׿}; _$eCK;h UZ`_QJ|;|{Qbvavp4>wopaMjWʛQkBX*4ByluQ%k"7Ox5TdQv͞'zw;H.LN+JmYZRT۲T}8#se?_gK%3# {KBrpgӄ4S^%k ^?A9tkX~Q](;Wdl<%])!*PrP-ȶӤ"{8_Og1^-+הN%xs@Fne~pwّNj晝p>N(EA#|هΐ?9aVsl\" .Y-@R VO]OժK;(Q *ln?~ݔ.u|XRk7`ȹkxh`K8cJ-d E-y)&4ZT@bѐ mw!CJ4\h>&+yuB}ɡ:aǴac#V5\\kOJȗA,[?&==0tCA=)j,R/X񪣂F謪 fڄWx_3ԵG]YݥazCu1bg֑BxO'ڟfwv]{'Rjnua[Kճ؁y7 +g` xBȨsRj Qy ƻ3:Xbp'K|tZ]MDQf֊_࿗X!,7u;g8 +0 +Ke&K 2 Ȩ|:{df,;^46LyijC5Y!581 :i}89'q8}fvgv1.Trkx֗X 't)7 Hiqan r#j ~ t"Ckl8:Iܺxfxb bnhD&d2bc f2` 5SV kTƾ~_+xE>#o)E{y><:ړuꉏfƂŒk9$3{=X6}'DM\y6UK+nUJ[9&lk')] $r;gO/Bg}bIC۲@SlE/5iӜuK.O<>'9ݤZGPH0* B{{y`Yf0*09LܿI5OgJ.ulQv䊔TWZiztR0f4/EbabP8rN-*@i`[kޞΊLslhnx1y`Ӹp2:C`aQ##H-P ]aua`px<_AGuFZn[*" D8&F#r\gmu*djRe X5 t@ͩF>)n.EC:]8u剕̠}#Ȥ.QWM_>a|#IKbh@mis]fuBykϳxfY7)Khًfx?aOkQeOSH= 2>SZsfɌqâH>KRe26R>;>eP\;WAAWDY,FAk%8tbꨝ P9RȶY !c:>J#qm%7=j}qϙƸv+ P^yUџN/:!5;0RvXz,jclqSE'mSL=eǒE۰V:Mx .m{vbK +/C1ƂbjD,F:l85QSsER:j1 g?CN3ύd[ FvdpX 0T{xРV=9XTE84Z$RX3S!X5pڝYB1so +&xО҆\v~|lI[A)x:z:v֩p}0=sO: a*D-m:ٰO֏'x/5cf"BA9kA lУkȅ\ d$;uN|q4爹9 ; !tWż[ըڕ b?5U8 yv<:-O8VZۊtG>ZETH#z x듄H 8͇ЅU؞_Aofzg~nX>CC]NQ$Ҥ +Kn*-^g;k1١erD&bwTֵrn@:2d`J3n j #kS"VIJ,S`~p Hb7>stream +8;Xp,*>tqE_l.Us&09]WKjW`9IA?Lqg,Ed(W.!a[#7t8CMjL73~> +endstream endobj 13 0 obj [/Indexed/DeviceRGB 255 14 0 R] endobj 14 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> +endstream endobj 7 0 obj <> endobj 15 0 obj [/View/Design] endobj 16 0 obj <>>> endobj 5 0 obj <> endobj 6 0 obj <> endobj 19 0 obj [21 0 R] endobj 20 0 obj <>stream +HˊgY ʬ~MX`Dgw >?秗h@]l]TiC.[_}\A2D~&yOUYR%&ʫ+tPIj"CvVE[ R\Dk\Xv4Q#&U?'J1,mM2XzA&EkQr9aYiep ا6Q_h vg/QՑ /vn3; D:̓XE9КРY#:MxHxP=˙JkDtKUwz7`]c'A qn"w&R5fAat.-6x:+]"FFe~zC\t OTכvtHzw*6u-}3$+W49^'Jz=ݓhk6":)&CotVs{x묣@n=E|ȕN&t*@tAѶ92u^2h8"j^dNsҋ Q6Oަ)ז"ɛ T 7jK1tS~kT-T?TEDQ /1D;tEVgVȤu7}5Q.͝Oޘ]UWРeV +)* vV::<)%}F+ᬗ\ +]SӑGS# DLіqS"19QL<Д"!zyh˘O:` OuNQL^(*0D[nE49Ѥ",k:d/4^l Ex"wIa9DF'Qܰ ūտz:5Q1KaEDv'7,.RD?%dL)C|Ρ,ݸ2T2+Z겊_Li!z3k)>E`@FD%1v&__Pj`*Pb +3iL헔c l*%{zY}mE6{NjDi +ٚM>T #[PFVRȪkϗ`ủ5TEg#QIgu:E{[[Q|7Xu(ZXGkg=O֘JB6Wt*ӡthE&=7 rv5?:Α煁VC٘"-*~ZƠ?zˊzA,A'^D׍5$/(٠МL98ՎHcޫ݇UPntQuS,1W;VV +VtzSDi(ŗK]huW9#&Sɧuv`EOM19F妅M2bhk׽Q/GSvoSld*똑b&Asi d f&|"ʍ/=h| ўtorW^Y:vhzi&ꪥ;RD[SOǹglmJŐeXO;U&v=d}ȼE!Va :e6E[m? <EN~ph$E׀ںdd=7F4me&1:2 cUoM?Ky&5/VD495yJ> t(C=N٠ķ29?4d?(T?Dp3A⣗ᨊ USX$a +r཯Zl<*iA%T_G2K3xIh<(QheH.p,zm,эXVp 4^֣݅K`a lس C¸j  +Ji c Y$(H=x' [2fc~KR(%4]]ϯjJyM%}ĤUe+ +h +endstream endobj 21 0 obj <> endobj 22 0 obj <> endobj 23 0 obj <> endobj 24 0 obj <>stream +HRN@ }wVIp(*kU2R%A@> 3CYF@ +Ntqg?.vz~G =3h{;Gսk ʁ.0ׄ=V?۰`'n<\uBΑDQ٣%η&n"G/Drvju-0$[\% +rȘ,D+U,VⰴWT©^6QMxqo7|L%IIYhܜFT Kwtiijd.J + L4l\Ii\IųOYU:[Vn [UܖNߠNMər:,c{<&Z^%4 +endstream endobj 25 0 obj <>stream +HV{L[?0$cma_ڹ@yy,BBe%iJu[4ivmIS7M"ueUEb.4E$;!4[>{ 4t58txnK|wq#m=Ug {s<ߋ֑~p +ϏÓ/мcSa)Ȣ.+&o?k +gmՀmRǿxߚy5B`[*I3Vd@]$_ קj6Xh6 i9 sJF:|r~O(K_# L|d /,L BLkd F-mRF._wK,F ZXʩ%s0t804<]~m3m3BVf08;}Sccxg> ૞giyB~fݮ*ȃN. )oBqDPRJ;QC#ᅠ@Lewcl_ࠚNw0"Zoo2^|6`C両cѨʩ/Ǿ5_uHִc*W7`%Q53X͒o7U]C3G  +u=O@Pd=nEm QH7 > lCPKIO+@~S3p\^>,KKEi\l'khz2^/o{~x +rnՅբ60IZ]N+Iw1nnZ*eX/fP5V`ۭjjh쮧9_ U!򥐀 Z&g2y~8(b1FY`ϻ&`N )iyOSKn6:R)i=tg(dZ7]˘ܨ5^tHp5-={Mbfm=dhL77O۹zWb= Iwu%ժOŋz[p$l1?ad +Һjd)a.E:cQ-aWqD$[U|W:!0b)GA=v-@ +S充\K1<1>\w*uy\v?㾓c2՝ |RҺ[Y@` +ʔVmMA?L_ bD)4Kv/i?} EM+1|15bcF+λ,oDpo[ HD+6RJ U!MPT4iɄ&ڨkmRl$?q5o!at߼{=;9gAQsUmȔ:Ukpuy)!r ay6MOTCFdbЄiQ(oZ/=^GЅs*pcFiwof&a*Nwhͦ,;ĉ^g1i!Lڭ%T(Mm&m1̂ț h #8{VhCPʜo@: +_>t>ǹ8WL ?xh yut#;/ (۱]=Уv&ۃN z}=U&lՐVq0=a>uTzBP ԝ,[f#sƓ< +Z I=F0lΖk4zP1l"9\Pfz24OuV;x uσ}M]U1'$3:5>y+dW[ MY½Qp2 5|`*fO;Ff4;@NCT6Wʇ|.&>mlf׺s쀘ÖqYKҦA;fH 'FT|85c*Hiyy@KwHl4Eƿ]}\ !V0 ڇ#p|&sZ'pE_ΎokׄGH{ WH<ZZ#[ +BPevK >CRi=H$yo$ɹh+uS'.MY%-wd,]Qf_X^S(rAnlL'fYx:$:3/:^4^t 9Z2@$D( f($bo'301Vv(EAtɽ9JV%7G}S]Ep#cw'aDžj?}6/ݼԄ_3]iw> O?Cۉ܌UsR|H +SQ!ȓۼt@IEʼ [VN;Påβ/,TB-7v/2^ũWU}"_zVr8RH9S$vq}bCA675.!E2&gWcab$10V6u6L +h$eZUZ9ATpySDհ`\Q1>:txΖ-;< +Va\QP{Xmq$ +ݞ]5tf"e/YQ{"o8%'!$_ 5k𥒆Q%f;R\oPْ}HuI47MIYy)SygqhP{V P;Ϯ@k}YHIۄ߱vPQ+wO| +ve^lOs !* +Q1*%R$t_NkHN?3aP"v^h Ebz</|@x%a ;4VAD%C $~hE)4eQHlMuz0^$|6֢Ev|s5,!PwG)Gf=I{~Qgi$ avV:^("6 !Ù$y"Ę3keKHXtjwy*j|ߓS!\Bw \p AKPUaՖzUTZOPHB"PWNǹY/_7C{ _N8LM<_:R>GxF@~.g5p]^Tzh084,e; hƗv4ήmj2'W9־oc̴Л1?=6@i;#{5,EDDp#Cd0,6}4_Bmi)pZ^fCnǪ=C #O(<;9@GRk6pr+Њz. C~eA) +r֠$es!nffcNp `DU̙P`Ss m݄Ӫd4uxɄg}KdI123=6bz7@Z5]]B5/r'? Dg;$\|nKyB 3c~D~Nt~hl~Hyv->M ?-7!Y.r^h"RVd/uvfG{PA0DܸRmJEVoDa5&1~$^^ΖY딾I} +1e}vz^X HYh=-E`iez&iH@# yG׈7={8S N \V[rfj͞L. Io.Qwi ^\΂{B΃>ىyVq-v$:csinbpڵ[*sCKn*Ĥpdfd;bhzhhTd#Z--ی4Jp{BH !!dy%EPK"&BQVEPt:UpŢVcP#㔙q3EFǽ3Tr3t=;r|K.+XZq,Q@zN0GCʑ#PF!?D2|0Up,'6i$$Qa54l=Ꞟzi0(!LtlZOɋ{y<.@ᲲClWN,_Ьh9Yk[>#"PTqObyFUj^AW[ه$>ҽ$߸H4=iuuAr"|in:X`&Ać4Z(G&!+o|7x8R{Kj2ҒR)$>:EG4Q=yqD݃CMɍxpG- d@a!]@o{Ev/1x~~4Ф[Iqׅ{4"=#,8OO;(Ɖ,ۣrfX7z*CNWJbJD:.l `U^*ctɂ}X}W-S]Dt2/!Nb0<1R|>8JsMV A4bj? 3}L%Qg|u vğ>M¥f="H'x֝=VrFVd@셽#ej! \DCuDHD|ȱU6piLd.g&RX]-@M]i8眀:lc>uvuv՝n[{so:{101Q0ԛhUք \\Z4Î\͆ ,9$A= 6jjR4$rȼL+;f+ إNlSP?^d1՞q @?teEq%rzjד־|KdS\@^&UDv0B7ڤfh޸Sw-㆓(X BDj)VD}$IXtoc@~LJ[oX,ydp#`yzW.~o$j< fA9/\"GSvgDr##)΢Xd@];^?v֬3g4kj %k]gꍬ +T" }sWI*om)0ޮ`)LS4/CnGJ (=EyQ᫕0gd<TYXqlr W^rVL7ΪGpzCseJHE8Ql8U+}b-njr#I q ~KM GּOٳpolz] !}L Tʹ鎊{H ʕK+^D1kkLU +rORw(Dr7SwS]K*)ԓ.yMO/5 ƻkZul/5ǁZܕeZp)6øy\%d~;.+DQ$Qˁw1`iߞG:wϹ ZA(hBF"s|&:\Pz~PFPz!CUJ22ƖGA̍!٤09uzbwMcp;Q/%E(kaDK?+T~5NKt[Jw 3 +|O.[[QB Ea⧍*5nz>"W! ,u3/j;܏v  Ju9`f XF| F 6H=a&r&:pYw" [+i&6)R&=^dSUJGy.Pm1h-?f]v· ܍'W)ԃq%1o6vg cQ̪X)v~л +v 6.'l"U×HJk+(F"-r֯k-[ըY}Lss}3 дw1{-ַo+27۩}P\ZI$: +EGvnbjQ?qdnTz@:!*W7@ "@~kgm~k7&T,ݠ03ឱFLzPߖEad +!`,0M/aR8濇*j_yz!]K@F6ӍCl`Yb+/Zmѭ:fmPYYB\65rQ˫tѼ%GƟW}@O/|5k]g n `9>} +҆MK3sp{fdUYl7VHgg獉YqtO@9cT#*0thC ~w`;+qیA}iڴ.铥` OMTk5j Tw>HM*|1@&T%|%+M&wle (91j<tt s3 %^O,XD.h 1ycVg)iݺ?OH&d29rb,ΕgY!,D kZ7tN3P 0( 32l3a]eDZ#K< +KP"JD1AXcRIpZO%R[mB [}o@&s~`^S8UAAhK13ye&es卑^}j>1EA {peuY1~yEQgpC:\G+5ݝ޸>IRn#a äF^=D'EȒdcWBk6quT6#E]@w޴K./BӺP Z$ _IBFm5=.^}Xh##fVQ_kHF̷ Uk"v*C#lSTeVU.SL,ZRKnbw;,(}>5mW=o#{wv%;*FJ6Fbz?ėɞu/tq W+U[N3 #۳Nj/n^ZX]t{{[8oŸě{2sf鏤2a,>"5dW]Y~ug:K+v.g*xu,^[SeVU-O +ŧg“KWY]rrW@ozLKHGhIiRΔVp;0FTIBQ. ~?tU/xC\WN:o}cˠAa[?FϵZ䍯:xVvHUX}r>W>/N1:kPb읡ɓܱM=L:0)/􎞖f鳟UwN;u"Լhׁ/ppmzʖM[PF|jF"5z}8/\+2ZܹjFvKEL1eEMEo9*%6Rr ]۬5|, +?EY>>[?&jō4 (m.6ϐ (eJ807 ,\ $\&n8m,[ykNRm7mXG/+ID% l6<)j3'\> e-꺻(uy1[Cm3Bz!Ō D \dz,c9NP=ѮrS\Ux7V nZeK5υb΅Rwۊ\iM+Md&!%qLh#oxmA +prʀ}\Bar23%6xau ~>[U }Lĥ'g5,lr6qU,R@j#P(D0vs0Tq ũIEr$F6< .H + DMyύ}`|;^[>+ք+b$Ó,X̐ GB Ydp a0o&.?ބv?QLa,(3:$ u]_U%=SNx&-In ޡuNlZC` >32~}\9gEd7I57J-$1+ +Gf(],pgO;},T'w9l0 fibM@,ПpE5~s1 4!l9ؖ9~I㐖ё/m BCwSh&+3u6& -we;{6rDS +E[IyۈF(Tz޻', 2kZqiw8գ)s"O ~]ެ~Il#0yF};68x +С:[`ﵟޯƏZD.*UzF"(!*yS~tO<=Rz:Գuu~UWK6[ +|' +Ԙ-er]Lac5{.! ~.+ Cqc:ix!65R[(@b_J >B|ҝMzޘZ#ݖ6ctkgۉ즏ьgQ0VcqA]BߨߍB>F>DŽ><"{ȍިKPɹ#ݓK`>Y~,uR5-yhiW:(que (S+s-EJPsltRT5bI|:LQF^O޺R3Dh4,wA4YI F6DIp[p$[3sܝCeByہ_d Fet[,ֵ,wzիdx7bY QV⬩*/G3)Uf8>pւ:) ;d`Iȕ#7u,2N5qU63Ʃ5X5=6eڕQ⺊Vﳹ*,еLo/J7U2}(H-lWyTSg=@  (@B6 k ʢUAZ +H+.uqXةֺ3gaO=qF81{ +!}e<@/"m3gYխ݁}/R?&n$$.|QXClvK {Җ>q5'E sL\8J/ĊDnV2n*:Rw Z½O[8P1EOW/`=>6`=X~h@bhx'b}I/KYkn-U; S!*ۄi\jd3b{hptR#!0p:zy^4;wu?t,*}94l:MC,X+z?w 192i&#cV"( XStXH!zn>Z ׊, &.ƸE2-y3 iQ P#R ! @(+!.'~B}am8"mF !=xMg%C\kZ􅾻õu;Q )ejuܜxf_ |O&n!TA8XŻ,Kף;gSF`,:eaq2BB_. kmE]V/diM$mSRP3N"Geap0|5e?b:=kuozz.p:)G gIfaڂ! {0 H4Tʄ76XPaY١!8,>~^DKSخҁ`ˡUt0bﮒ%*H_'è9/ JEJ T7|zz=,?)#botYV_*Wv `4ƪl?b;X}tM7, T|V# fX>zU^RX 3mpE,D;s,l K A;|Cr>h寕j ˱Nusg1$3$$Hj|8"[s'V>SCV[\\¨-w4zuhQ&ͻfsf[:740a ^D2G+jk3RNW#UG2+t*TGeIVZ&{ py*:)ov~[*#_Yj!|{XNYD0y5 C?1a.pŋ'Aw$H؁j!6ڀp9 6TK [grP|0#"Q+ \G4 = +Ft9B̼j +6{)X[ .. 'bBϐ&G(K'LGP-xLM$s'z5~"pAL ąH4N \ +OA€<z̡g,ع-f9\Ot"ホV…CE ]& +fRD.8)okkOS{Fcv"ӹ'1>UYHb5::Ԡ?H ?&~۔o;5#oQt[ȁM3v2(z]Lk8EDoQҞ`22E~/AKS6>"gZzi+q8XcZCglMSHc1E]6&bFهi;+W.t]=sشW=JN|{\(Y"\;uŒItfX@jlp`VD*=]@TAH vã^Df_E|kּkJ,خ.>pdT2M;.$4-yQe#XRejn8 )1l]/ɓ}f'+\U.!x", .Pb +/#⑇so;788668ȍtwwߘFГQt"03^ڼxৢ?yG/BW҂?**C^}gUUge%ܝ) 6QjⳄNF)LgL{dQ=좢JVliSN ]7:zis0XtEprWcG>suz6zn"b uxwKC +2;"W8K6nT*;:(-բte +_CA`[#Oj>k^Oe9!# ީC  r O3K.2SqKzC aay"8VæT?VJ C/#JsĞ|}ֶɥ +@844v'q*PYQ~-_HJ yZ=ܲז4J{I}MJpŚ+Zu%W|+|%{a=~[v~%7OawVuHWY+-Iن*>l3ŸmHOQt::#$ +JLcvEEh/qأ 7R]E*;ؗ[73ut[QTAJfWȗ /800inAJw#%ٱ E"pSw +94!ȋO~hxY2?I7&pm{)Rgl6mn6MKv.YqìnCr͞UN'OjW)pt0g]s" +eQ3QPO,ot  ;ʈYcuO(3;t+n fKurLً4還$tJ Zs +" ZBU:߀p!޴BBr"EZQD_&MdBMU|y?FUSzUlRD#B]:vO1[p +dv-!>0R5ij\q)\`c]6_U96ZE}ƕXXJk &(c6^Y/+C=hH4%엵,YsL4Wob-;[cw*;߂YpxzW欃n\" L`KP\ZwN&| 5fmvg|/%>:ҡuy̙9<̢IM,n(;<9g(VZSD{T @/! yIȍoH;e , Xh!VRei˴yUju@̺M7ݙumeGyۺ=P=99]j2 q&|c'I履wg΀!2աթA؍0*ipD42hM~^0k>0Wͱ 'mҍPR\>ŊBe*YW=[5SEIF a^,$D"к q_xW(/BBg%oe{O@mōFb6|}8\Yu7m=nEmɉE%SQ;.W1V-Z8cJX:i$,H"iXq1EDMPV<{i^|;<&LlҤ̦LOFbI1 8&J2QXf-|Нy,NʔhިTLExlv;W3 I[dTh15Wkڏ* V}1ٶO\¼e2" _N_![rlwd%V w1d1ٸK8G-k=v.D?[e+ZH(\*̮*L-yܱ4!.o\Wʮţ@$?S*CHY䶔㿖k4geX3Q9 /ԕ[x(i%p̈Į&Bv_+4d\4 ?`?'a,FҢ+wstPڭ^]uXWd qc5UYei'/1vgyM< +/撥*nXd_g +W߈dX,*3U 4>=⁣PFq`B, hj:aد8ԩpI^#mG-q"oMe~+#yvo0n> O|SjsW̎\G5m= J1 vZ wCb oC Y-dx1;;~n1q=IXubxfz_"Z N4<]A@7!JZ*e ut {sQFcI~REz7[-`WvGH잆wNN ȳ? ^LE97lJ&#V[%J +;1n+0 +ӂ$˯шl 9"'KBy GIEjb&Br2W({+Sv4e2>{X#sXLZIJ;W^[[\,ZT2jA][ɴѮ?H33_'>&e ¬Lœ_'NЗbF*gE9hGb^̇a8aCN<z%PXYv-dIs֙'[Oh[u@[1uN$=QNˍ i^INY 4&DuVY~ۨk۬KWMk\LSv]Hk*YMx`)Hj|ׯ~HWCiY4y ML[ݣڲ_Mp$R+O} Jyɬ#O{K#l5IasX4HNK,s{ 1f&\ >D Ϥ- F:ܾ״<@16;t_׫^oܹp pՆRlxb^ 4 Dt]g;MnU':Vg+UxXX+kp<Ç?ӿ' rph!@d5)q8twȾ €~2WY8{OÂ_%a1eãX7qCCYD% +#gt\,H6fQRv亡S})^ z{. eH*ݎށG@ f`*MY}3=85^Śǽڗ*~yIY '_a=PkB BF}"TLF  +qs#-L;Mg%,>מeb2rC$=tJYM}{{sրJX2uoxDcF{3<9wFM Ft@wr}Af.G׵NLc%|L4XaU r'x΢Drk={}NxV~V%yZ?\~Ղ #\SljJL0ovf\"ZtU E_w ?L@薳u&!x]aM=YT.+F= ,eQx=*<6|5֧4 3dQ?4Ers,V=J$ӖiFZ#T䄊e۷󽽌B[ i6r~4S]%Ty"S pg3PTh_)0 uwv_ {$'xe欽8fI"C]'b|M2!jpA+Q"P٦]:CVA{8J(x?',9}E|$h5\hM*n +Uc2A&:䕦^JQS%ZVܲPʕL4dЕ\ρ<(ST*)s2+|]\6>tx 9-."6Թ'} +^\<2yޮ,E8>b!wf4Jx +5n@tԖKm4 lh<,GjQ07B}SIл1٭L10̯lex7[PֹN1ba~E39bC침ߒ}ovX\ [Vwd?7ԕ7$$+'h8ʘZzx?l$*T(]YnpLݑA%h[[PDA|m"H+~#>цt?4g&;o2IcThH+5KG 4ےo)rbWuCU` +xNuoWAP7ܜ=۽Jбiy['M +w.r_~ +# I,$ 7R2G8fWιW(T)Aqzd}Ş0c:߿Oj^kO}/YE +\}^j:;;a^}}bCåq0 ˊ yiсeQ#?|&|g`CV~wQU(`]TFZ\.ʅqTMMEA,iOLMVAiYhufٸ,Z 쿌DZNM ?+cن@%(.vh\9pa^zY+s[i88%G4?pfs3'&'Ø9Nȯc2;¢0)ؽ`8GTN2M2s ɱX@94Pj?:46˒?<_ cs)" %)Jk@3}^+4?~9g/;A5 HmW铼:{o?'2#F!(-ʘ.uUZeb +1LN&4 c鹃;_㜜@MR2g0/ۥ$ m߽NڲͿ,l `yhN"NվM%O#QbsqS8kLjW%B;-咪0>f_Я;#禧?*6nXzǺ]-VVwGT`F +0g_d(fk@'R Vk/Hg& K*`x2%M-I?.w7/jQɂFX2MITdh , 1+wkDD26nEYu f3S#p{ə Ռrd`%' +Pʐ&C w2X =g3A\D=7%Ci6| +A*n3EUlڑHz6A kxkA zzYj75^!BO0n3@2$va#xzX4a,m#4{g>}/cJ>&ڞ<ǩ{@-I3#>$|oc:ojһ>^ykwԠXUkO׬Qp49ysx6y6D!@OLОj(&ȝDt,../X\5 pBdX_o@ث_Q߭s}T ހa:Bxb^Q#("#/K{N,3TmKMH,46̈#!LN[6ǽk՞ +0&` [+:B&Wfjvب`qBYe\>^ 8Nc)yV1΀jyBM!E_irr Tku$F[UЉSESB="U(vrxlhJM Miv5uhG9OǿαP{šL!<,5) +"$h0I90Q 7Vg`#JHK\E$|zt +m.oIMp>IL R/&r#,8nqI8ُI 3σMw$07'ZbalGoC( L_2-,V2(&^ӥK#G TוxS-?{uzf_jj*E̘:h=hDEL&U"+Q9\q<_\|+?rےtyYFisc&S*jlՋu~}Sf=t|-ڷ4;4tf}"k}(nCwnlc9>BY +k2R N<$"LS ^*Z;wīѳPՀާ^̍ /Zɍp4)=KOd.sZ\΅D{6g +9̨eQ} T-6B8+e"%kt~Вg@K,SKCiYf>Tb>s@F4jxc~yUu$T?]XKz4u\7dlܔ瑪˧LJ|t?wtypkY?N;ޮXy^QJEtp CEѡ+fsfZ]]5.m1Er +)ia/L<%J94;+Pԛr$aVm7嬥}rmmYѴ&3ԂmQ |a~}9n|4kCCQ_&ٳ˒Zp͝(E18A)])Ɉ0qӓ= Î'T&EQIO9Hqz؉c.tbhע1U$9h~ +!w,hw; `Q$\:>X4rJR +@Gۼ9#'4ʙDmm.4M !n<4 xZ {yTys +A};r@q#S}ߢ2]8өaj1D q +֦:!#s9 =oz5ps.|SZN^7槩Ei͊X7[ӲCS [$[g^GP:&6j퍪 ]M(\ܢUοSb}flo80sUKH$H^!~u{IϪ}ϙ:^]kҍzcWuʏ546q8J)m1HΎ-H^`lxgnl1oNYR}BwBV"¬} +17(VL()y []6hd/| +{oJgǶƢXO|[yd5ƨ18?`"yqO'Ԕh QCG'7J3jUJ+-)S#SiU|4{)zuvYQNB`Z&Jٽ#;<̦jKE9[ZR4PkD(kgu |PxBq/na +xZCú=gOi"69p͔1޳Է7rqFi?t"]h?pOCg~x3BP1Uxuw$Gf&YTcעbUux?[Pgp5C{S%ӾWe2z~tvF)T Ԯ)#,sܦBf0RA26`)U?CF 60n+ymgsO|ޣglYܣ<8}"ׄ@b% !P@E0QNǺv)XB[k=^8\]uzv<ɛPy=Ųf +: ޲5K02ՠ+ZM_fOD3`B.ahKNefuFۊR35=q]}ChAP#ܜ|/5w[mE!guBjE)3Fs H (b 5dsH>ީΣ)MoIFIuYQ~cp3DZT&~,*|N2 +_`OֶҥG@8XRXڰaQdU9uI_Z[I,+CQͦ N&lss\i3*7qb) ȕ?FAڵ[Cd]z[ȌZ2is0yWT 8}b00쬫D_ =x!}z~51Y*r84ˁ]NIh|E<f(E~<*V| s?ăP0Oz5Tp8sj*djAV c/2o8'yW9_Dτ#eЫڋHkod{n։9w"O$FWJʋ% N{; Ј7 +& K H^5ޣȯK@/ N %0ozR5_6,*X&DZΈM=ez 9Am0p=W]p(_ȸx_az%lS*mhxroK+kG`9Hk&ﰿWSB }-,r/V$<%.9nXЮpҒdKZ|ʕ +{MoG;=pR]\yYFW=:7.R/M7*ATl- ƯBMXl : V-w#\钅ޑpPX\1 +Ȫ꼞bWC`w+h>'ha}C0ߊy\Zli Ndh0O ӃΡ5뎼`na?*iģg<:YtW {.l^|Oע23Aڗ̭l=Ş^'ەZMf]M ے2[1Id2SH1䬔|Pl3󼟩e? +$UZ8!]_v 0D'dk۲o g +-}֕5f{/ wZ^J@sLpp[Rؑ`ЛxM1~ +0 +\fIը (O{Hc|q.LoD*TCQ5b(pTcccނ` q0M`N 9-X;YYu]*f`&%P<80%ivpeA Ng̻gYYѴ<6jQOxtUm>?F~BFgh_=Gp:o 1hcNr4=Zn>UG[R1n MDIU"Mfrũ̍/F?6ϘޒcY42 jj:?! +$B^@T*#تX1A;X7k[uRmUЮz6k:67uGݬq֒\B{%}.d -hZU5t^>*D=А| B&{/\h(Wl-8[K+Σoo ,I:dيʿj284( z\9ߘH6݋>$xnX~i.) EAj'rPTLV~?qZmt$*V9>']x;r3WLjN(tz2^Ss|/0^$|Q^y"D/%eVo\s"hq6%z7 n+[5KYq9EƬ%4"ƌ@8@0'-l* XϜ?ϬYƮ 1$'),GbV;sJLУԤ(T)8RH Fpr' Br@@)ӲHn?@  +eEV9PpB*ohc'(Ukw&L${?:Kӳa2$x݀b@fB4DF`5b:}&(Nã[y|G|),ۂ ]V7~8?vZPmDZT4%wT"[ŸSRߝZc|fa\8.Ž@SG@[ӀaJ`x)&= ZNy&ŎKg_G~shh?88x~^zdYggnK4٭Ν;u̲260h hw6O&\=gg4)pd!?!$_5%5妎LƁh!ttc=o]vG6qtQ|cj ^'D뱎005lKFpat##'P,3+,w*$?5 +0Bg:>x 3Q$(CEwE_b6(&.6P +Iж+ T-8WmbN0ð0W=nJ ŗ'zE32KbMxDzWs P߭ԾꌹEUJe(>+dm9L&7͚V)&m#a=a +K)/S=59F3@N6Ár@CdنPL0 tddvа&iLSU+q8_Zm>{v]aUI^W\U +~}JMEJ|Yo)f~Ŝ$>\:w18sDC +pC?2ȯyi!y<̲)p}c*:/*Nq5n)8cחԬ6pq&`|%XAN}8jLvF"= +#gnZU伡hQ0_靶pj}=:%FX,fm[{ivwmi6-6/Fkmp+5S{gud;O`T +^ПJ&8!>ޖ&]XJ|_x$:7 Fkҳ96҄ Z6`  ,ͨ1|jijގ=]ڕStvuNv?7fk5͟:NN "38'iHJ`a2=[g=l=.j]+zd;Ӻ񁳦__UWjMOl /,J϶YP)^11, `!U omI3qF67Е 3"A[!Aiy<0槟i1pj$j>hyEt!vAr4J-,q]wu))MQMhX fËpd|0+8&1n8ba;В4ߒlJOVRHqQ [_wE5qsu͍XĪqWk[$uA7?+KB/a1ꡯ ~o\DniuQ~^1S|a95+Dvq+k"ZdyBLWN0V +GX: ] +wJ..`t?pđ0NG櫩X/? <[1Meexbu3tRC9ۄv=ڑW[w@@d=(`5߉=|#YBIZ:n"߲qԄGVM)D, '_n<-9lfڅNdT],tGv*rRxP|8$"G e^k H q# R/؞| 0'* sMp,!r?@n,P)CTqhʟ].qQ׿Dr>53Wz}xb_߄,դn] m00\28ѼױG¨(kC6mb6ۖ8} 7{lR$ͯ>@0ivU Knf;wttafwNϪU%nDtT-] +pq>Fy$q[#Jkϯ1΁ ;k_1' {v҂8\5_97g@z]bbT'͈j!׃Y1;("S@sns9d+ٸL["fFtl/ 3 .utQ?PtiD3?O/4>aMˬ7gu&Ψ +cRE;噢()̴*$J0%I$޶bS 4X YK,e-nBeoM)z?jRhGB題%~㱂~ lH^6ho2,?w۔ޱkx=$׺ѣ֍T7MwSJŌղ[A̵C3ۮeQT.-fʟfHT*ɰA橖{a\k@%^?weؽ$:ѢE8O`WGephFsmt{{gm sŰP<-&LLTLٙ$wٶ%KFhr,39Ѳ~chKzGF*œn:1*@M:%Uѕ*9KHeyH9PQe:1*eŽwIFLˌ衛Vh^!NƵR6"0RUEg\{ P2AnqcJ|SX,oEWca#g=~689ts`6-~VEwNLeUrYFL1}j>_Z&/IzM|@JXjn nۏg mТܑ-C3F}a0 j;҉4;*o7f7" +ojL!JϦ{rƁ(ƕuJg8yZQu\n)Zm,tivI5Vfi΂reo=0A6DMEMe m1]!Gj#!8^:ao6Q䤗{p .HEay*L/sNM?ŀDp6TNDLIiB<4Q0^[ שk/d&ir{:lZTgVdAv?RpJr8 `w{i^>@p(~_oƫ<;$!$Iߕ +PD9bUD,[A𢲬8XzbmZ]v{lwp׺G]wk~%x̼{|Yax+POY:q68X(ƨD6mFy'Sh0^P@.!۩#)!\[4 [Xk"u]^J tbis}!ƇF\Ҫ'x\:6)SFsٵ =M +Ԑ=GF*a53op)o;råNv6ZԇlJgsS(FG)Kwp;tv)-wX1~/fm+buRk#UٹNm}Ky*_@ }<i.^hKh +'{8f㠔P +tl;ht=JM(H*9ɩS5TX58g02}JPIF0zÎv]]'R 9ch(I06ܥRJKQ#i'E*E'f&q&`ݓs KuhwJMw=uGi]N$uii# ZVg+wݥL48Φ68[;w̮) +.\~%6&# +rfztJmVK¼olE*xoq,23*R=.n` @3 -s zSzww~zkxFwՄi=;cTO/8,گB*w1 f=fxW.Ьؑ+SHԡYDi@GE[7[x@J<F37֥VK4 +XwgB_ KwXkm7ܶ@Qu" mn Tj3MBIXIdN䘃 3Я$YV <.i"H>Fà[Ç"yeUdokC}r_FHw@5u yBBBr;JSېVU~6U:x4I-ބ8‡((,{R8@jFۉy/_=qU5v^._bܴwcQoPj}qs2ֶJgI Θ;. +fU8Ȅ_8XqìN ˫ëIz]Vdq7:C"4"Rs`XрLо,9}rGƪZl!xH>qg3Z( t?'/zYv:NSi/,kgWd߾Ύݓ%2hxpс8 ;$U)f##(baY^L^)a5,KC$Ʌ2-e#[ K9bf MXhM( )e`?!3y ;DT]0D#fڲmn>^$~s 5ٸF~[]g^l^600W ~?@ P|"hrEsR)-m2VikHuʒ6ȏ>z:KL'4u g~KK:W,~+J@ЭH?h?r<௞V.qCq1m9L|C&I}'#ӎk\(\i6HѩҝUջW.\)*Ɋb'}19h2'_YRByߟz&. +Wz_Ei|ÈDžXYn+qx \"pV2k%;v՘jP,B$[D;=wt.YxLrRDb+йANEYkW(C-r2uR;UlxZ9bg *Ç'6‚01C4|%:z7uV6Nzx<_P@rvu>DbL^!A0em ; ?5D$moYmNV/‹]T_(=IZs}j6a{Q4f, OqYxeă˧<(}\Tq׉N$u9 + %ƪq˪fmTzo^7XPOm5ݠw ]E>>tρ1xmˮPd8ybXepM8%a>*r7 +"B ~:  .v?ԗXv fD jj+(y&$!܄H!< Sh)s@|V[=NĢv棾Z笏8ծ;ZQ7O=uv=߽In |?r16h("k>.\I")i-)xa +[wtРc<Ln[EbAd^|x 4jחrG9?fc s), M +cx.F ^prNC:Rk{#Gɕ]g?Fۏ>ezbb2JU.5kbO#Nok"iYBa +i%\fGxBL;@,tKO\ =xfS;SL+QI4+m4ޏK'>ܴ. ]쥪j)` %-+[Hj|`u˥1;2ϢͯyJO/wPOݹ6( qY7#Xsu?ȲM%6$g! &Sۺm[.KX;SAIizq +x%j9 -3Z^drmg*ꃫp e#Ow@;\"NmE&O_;*&R2ץjK2@Np񁆣Gpl?d1 쳰ccc3\]ǰ>!2vn\T '(1 +I%,Y#>v]Sp\$J5 +T.3ML] D>ODLEd[8M^T`ZcbSUppml3@Qrf(U`ÏK.\y#zE +#fyUTh"|B#]oWpɜW;'?aNu{;#9:.dۇp 0mPhqEfnqn2 +o +=^a9E; `A|;.Fض]aTۄV$xz_˺p*ij:0? ,̚WQR`y&$?_XcZtUVE<sR?4TIQl:7{ vh! ,S:U +>8% jvA\Cl;VجylBטc !M;>"j./]țyHR%VQ"[`&q <3<%-UlXU #)䵣]fcGU+tb3>oh? Kث\9lFxw"'ug޶23mK|~s N0הZec`ܭCP(~wuZTmn 7UM [lDjԳGq.HTlRh'x8fPƴ<@H0`0ꪑX dP-yYi#ph2x\&S} $̭[iS%Nζz֫%$Yr9gXcX3T;:␎QN0֑ +FҥEbmcRi)Bɨq씇~N9p8k^SH`~J%\;Q>ټJJ"03 +hzcJ,ΚFkybEZ:3(M4' O, j?Qͣ2N@.X;#O^cRx"w s~@$ GIinZ.S*sT}m}jEBth$4V7k,`vD[r%jXh0feovc_:^X't_ g]*~5uN؞h@w-ywup[Wݳs-rrS +$S%dԌAbMTc4%x6I;4Uiq21ڴ>sPXzvvgz}}ޒYȯ# 'S\{`euJy G!!*ZY,KE.RUs( TrZJ.6#ý&xVP9-%Gʪ0kND7Ȭelمo I=Bez}/4 @4%Y P7H螦K>l!28b:桃CNGyFrc DGg2!ZHgW)}4I>E3 #Qz38 |~cc=ixY^gRi +ůDA]Y/3oO(o45( +rN'"dn. JN`xr0DDJn^ e$G)tw ?6ɨJ4w8ңRo9N&ҀZhBcS6z69̲p],GajгQ&`VgmdbmQ)Ꞔtp)Iee!Sm-Kn39R6Ŝެ(\/s%+0-/dܫ3~~ug ]k_fJ%"\QW$"p9KWx\uqSH8y&W$ ޔ4aFw4_"GG`Ši|)GGt'cO?٣qS +|ݘhFxv&4LW^"ukEP73Ep Ӓ6PAvmk 4xHhh*it|ذ*f V|ye ,bX R?ٌ+¨}ޱلSE7cF 5ɜ۳\?PqL o OCCc8 B%d_YtLQuZ4 `(P2ERG,G̖HԦWܩpTi{P/S@3X?n&O]5kvWl tlZ6hnldG_4> {+{'#nL$RwBJil>0˰cuC6< NorU-ZFgN%XI{eJ& +ߌyǭ %XoX .LK yd</B'9ܗlp:"/qVFD(uNfIjʞRβ}rw3',t(+"Th]hK%d 6Ǧxq(gl0'ja.O!#(1!d"u߼@EˁVjlISkUo吨)R5.r̆πRXǤ3-mjEcͲD:єڋBʺ 3PmSB6!*.I/Ot./(;?+ ®^ "H/@`TT5VCV' +I0ZF'6X֣&ZMcrYGFcS+ҩ<,hLg>~>xoN\:6ЇZ6/|bessF&ktS:JmsONѱ e6i^j+7Knzuђ%7d/ď(y37+2V7w1'wT̈́q2]Щŷ_=ң,4H-T g64 ͲԬ);a::fR"i3Mq?l25Y /^ +ь*]ev:vJPygϟOb1=>;vmܹk.^NgEE (b֛)>՘OʛVb{=Vƭ% ^2P~6/oljkt<䗉tۭ .R 7M.A#򍛧w[#F"n]N&׆Yܽ4e̱ͮe "#X[viko{e|Z9A&ӍK'\ֳ:727>Y(7S~GœDb@ 8}_6ҽɣ_woVx?O|lj=X +eJ:ZʝLӚԱ8iHk*پi55|ZWxcMaw Eɼτozx|-5V.K~[|jI' $=Mb ~$d]D*b Wr RE}Ch%&tYvJ켜 ͤA!0p IB&{$mCSτ<}C<҇@t|YVY$ +밋9Kَɵaf%9,ZTf$Z6Hi'{qd/@ڡ Mr-OD2 .$OH`أ+AԃDe<ġ"qrKH(c[V̱Jk,Dy!&ȕt=l"_wCQm= +>]<DC7 "Ew壎]>&؏=ݤcvGǗ=>nѸ[^^¼g +A_R~Rh1= 1n+Jҏ}ίH}[;J_b@ ǮRuïl -!bAѠm*"WR4&n3F?4yA7"`"uvVR|(yd '`@ݪI0]7j50Mcҫe[I_ "2o ce81߳>iĥw?(0MC5h/l?ȵ`~7RrQ5~PჯU\gd4|. 8d"D>.&%|1aـ/&U "A "υ) ;9b1U ^cea'ѯøV(PIB WP6or:*gy )^(MEsB͵ |xsWkj;Geb{!1D>W2Dut쁞LQy4Ui<'zڊCYƲQNvP!{3''|yS<8NAme~LR_R@ hT>V*)א G!`?.zC y RUd7tA8U9k-1KP: +B7Ƚ ("8!* d& + L>R+]?B;U%uy=˿xW"+0K>E2$BیgƞN'q:Nv'q6RRPV(҇J,BRAX/U*@<?s~}*4B>pGJG>pm>ZkׅҘ[/Q=ǭf} v (sZY~pc/]KJnEZ,x;8apH2'L&?D@9`&pwLuh1a{͊&$! Sr]{ //{ĆL nחmV3Xn|on p#:g%(npQO+b채gGv>s)_J}:g1?\){h(@{0r_9澄4w?q=7/[꥕cm IHXMy>{z۰+ԟ.~⾔r}kMXa|4()5bȢ59;+b,cmɘbAu+OgkS#߯'VԿ&Qw=$z_wbTv +' >O2(aK `|Q®Ba⢤D1)zˊ573,`MyzJwWU=.T't̆9h2/3ơ/Kj9|5b/Ἔ@}"tWC=|-, }?rOMwSM[췖^kΞp4s_^ ?Z|L5s+߃nP*ߢwc5-3{?zA=?T8918~ߎn=W[Dz[t՟dEQ?86|GxMbs(Ƒ$Da#kgtVV߫Ro_=jjI;A&}%_Z,בQo5˵zO&-rɧu|̠O=u[/o`k}SAyie9gFy x7~ g k8iǯwX<˿FgEd)"kIңȩח]S_ZedݏjYC^دce~rnn9v{  wIo8T Q˽y֕k_pغɺrOvwO4Cgw_e*{en8nϽ{`}.yo6܀ew3}K1+q=&k = ZJ=dpbs-v^6иON{g0nǰi#j2d<Ũ1þЬeW]. u{o#C^C@ ǯrޕ +^ú#L|}oca>Ⱦ!h=gB='m|$|{m1dw*{v ^_1/U.r{kKpf&LA-V3*Gnb]| mاA:k~_3&[Z,}pjߦ3e]}ƌ{;VN=6^br>a9IwwP{wޘ^-z?}؅>-0kwct XsW9fmq~^Or7v2yW+mDa{|߷,1jSYGtk8jGYK^adwY5Ww h]86_ʜ`n8-w6ÖL=Ͽ=aomrlH3}nt7s~א%$+z-+ʡ)ox?y&Q]VOs +fQwCoÓ8-E2"]\#0oW^y^w.|˵ź,lBםK]~yu6~{ F6V^Njziֽ,#rȿ9myyl1x|`^wF]YsrtY+z}E^n/#§~(μY'zUlvj-^Mz-j?lὭݽ/^s~/Yk7+[nZ&'W3=cOs1-Al׀5˵u85>lGs:ڴc^* A3fOz܂ϴIwA4mWowو+5LؕTzO<<6#sur_>t9 ˽sGvHQtq?Dsd̙1\sWu]EUMob$bPw 6a{dgnnnnvZrkx8xgΊ;W]zݥBpir.#ަkqSlf!:/v;(kE&֘*󖻫NpG5:7N,7"ܡ PC?nKJN®V9Z\h=%j*Skf̉>[xn(- ]vS~<[K?`;s_t;~䑟x8Wp:wqs{XWX]Zt]{o1//d֞G e?:=3|?L߉}6Aɩr38X~"j( +ٹ216Ge`!~ݏyz#`P9T>xZ/W+b|ֻ/[v79o[q{Z2nYZbm%^ >vj\G}|y-;U%nrGz`Of-gJ^݃{*W pߵ-'ڏ݃3r=Գ:nU|{PYwʃ:Ü+z,3R/7}%o{s̔=L¹e>.۳MKe ;bKm|%@|-v|b#wOLseX>S^n}n[ǩ?ֹ̅Wyl9+ }zרu+Pִ0,:af=wusGȍʾ˞(|R8{UZ{O/J>})ek!^Yt+shh,;Qu{W"wi[OzQ1Trg#|SkVsf JK?e?˝pFl&!0r7Gc_ò{eN|G35onw\dַ2&\ǣ$X۱,N=*{c3x6}ڎvܲ9־+?m@z=ʑ/~9byJ 6MceALUo+csoM~!Vs[J(kQ͙'1 `*uuƿZcwtv1v-2g3%Cl,gߎox,kOmbG3vg~g\xKj˽ke|,r2-k[x'>v7}8r`5I ‰{x +1w]C-5o<~;52ږ!ږiNُ}2*7p\ʿNa4,s %<>6rm?6Y"{Fݢ+փ"߭vPtR^,_VKΎ_ezew|6}Teoeha;9{]?E&am Y#r;ᙲ̹h3j9Rm=Ub6A9{ g;=+Ii(Ve\\3e kۅe7s'ʞspw}۷Nضϋ:{meb;JF۵WzzX(qNg-'g1}mǹ7J̆?^eO0fZvlu}=<22?^(yMg%GFEfQxng{⃙29 v#s[}j$~a/tw؇Ɩ;-G։oqY +?]^XOpG[+sus륏=*9Vru{ۺ;S~=,v)k?{+sWQ'JnqT0^ s#8;qV֧)72^S{M~|J7ֽR2}[]m}2`tۏݷLIc^I#$"J@@wFq""PРn݀ +Ep~TDEqwNԩܓGrCZ掠= <.!d[2VOgu¸G׺9kw,"yں>dKC}gO_k}/=[:OKv [C_K~HFւu#9ԯud$^`Uk;c>דU;yM:x6򹿅m[(toHѓ.z-o&H׾n'CI|C&w,!wˢ.-lJ;H_>˿,p1D~Mwo9mӜXP_2`E+هl9G~F?;_x7uy+mE}{,Ělɏ1hӢXGY)1 Z߳07cϛ'8^K:{YrKW6R<>yOOZs)@38G?Mȟϙ$93Aip u^رju5,,{ص +u ᷵֝,m9g8؆lV%ؤmxM)}oSO_6+'Sكf+|y|/csJٗi̲=vu+#d,|"/XbuM z.\'g{J\|`cg,r8{iEd/qQ"ܞI sh=:}&ֶZQh}[ِ`I=h"mi_7aC4)iQ&L3g6K.!c;}i99L͘HLg,śhXu `iP{O-b _JsތȆq 1L?].o<_n 6:w,p&Y4=zT ?E_,=si]]i\M߽YK#g]lD~o߱25 q>[,?',r!H]:]x~^#;x}> 7/hyUk#m޵lX~n W@ണ%@ՕEͻwݢVrGm+/t-p5pC$kA߹FSo@t-jBBF}o%~YNIAP*=杤QV֑ӪmWPWYr.?N|=Tuwuqgawڳ \mvRS3)Z=џq?b_ఙ2 }X#bÔE6{ \IًM >]tA7IMe<:}\fjYC?Lv=%uO7o|I~M}/,Ed]<[̡zz+clO6H_ݓ~]رCzDǝ=.2JXw:GMsn:GhG{]ն[՟t$+ez6W5oEO[\ԕ31p/u6y+c/egb?\ԊzT+Pݧ=)( c-@AEݨ=(*j +5뷋wmEͫ=WTFXվ/{-WKO|ʜ\{gA**<^S"ynN[^_9i+?q7^gk'9.VKx肕؃4|Uzr-W-zܖZkHOKZ;{8 \k`9:߶kWzeRvY >c1Y|qV-ؚXOZo`H?S:?t% ^zxew6S'9m?Hl]2v7V]Jm}o߹:$>pxeH_]xsG`+#FZ׼:J5jJ,EL\ѿJv[k-{ڵ,zιM}Ywł^چέJ\kߔvM~ߜ 8w7amZvJ0#%(D-Bٖ-YgeOu2SEKUuI7c/q3.s?y.E{tQtxqW>uPoiJsݹ׀ֻV9"ǭo%~^WٖI/hN~u_?t'u ݻ{a??>趔DFrݸ/l߷W3| >"V럴YJ4{bQߋ7tNߥݤ?f}?w}kzu ɡ]'W%7yH~Y4tm';絣u0J!-SKw$O"ov5fZ<k_y1_-q[Jw*#Yg. x +͚E$ג9`&lE,;7ڗ W-ԓ^vQ+Й l:d7-Z`ܾ Wh ]S3%,7˴\3Oa#؍Z_\4 + I^0]c ?ySa\O>ӗ؈7Σ;}3~{;[upv9rn:O| |Dn"+t|{.~&T<]WߴOLoguّl23k~iD gp?r gjO[2NuɽLgL7h-z{gg]::~p;Ǣ]k|{{OK}]+Fdy){=Ͽ pMaI`d.KUH[--,j<:$ -lբ,"5j4uw[jn"flgћr^׵,jX5| VdH0}%X2rі\CwYsZy仗Vɣ`'X;ϵ.Ѽy:^v}Ltw:]~oi&%[S{=msM,'~%ٝUZEvZSMEo[`.jN:C$7kr1 UN4YX9!{_ѕٷȫml^r>YD=t2˻>g̞qu#_"Ax^p3w,|^[3ӽYl$Xhk ?fo}cwaxx|jWɹ~glfq7{d j57%@O K}5ts5L|' = ]ͨ z%hwgӽ^j-a6"'e9ޅE,mA [E=5l-o`gdH笃&h%?} :Z䈩1="8zq;U:}eICyzW'e`Gf;Ͱr'c?)8g3E+4X{1+y76y* 9޹gyz(ba]X +ܕΠ;YZ+錚F~kǢW"VGFih͒r $#-;(u|ؔAK|OZ_0ǀ{*ƶdYIƄ?i%]tհoҽ=9Y|뱾-gհ^LEڱ9`{KsJEkNyK1O ZԦF~f&=7O]DM ހA4 zgˢgk$9i^>Tk`k_ǣ/}_YB'2&o[4g;ֻ᫭Q_|޿OZwYWkv[#Hb p I-ydQdqY[Gu~dE۷L'EFvx"Z7sRt=]]Tmkk>9ɗȟ{?j}gF6f՝_kNss{XK?j31qF]z.-ATѳ>zqT7z?F7*Ol# .=̽wϱSsџigO]#[ c6?4"e{:jߣحCKƎNXgdw$뀿ͽ{&GbE!Wgʜ ɸ3gZLnxW^7 +Kc \H~zeT}L|Vw7ƃޖ~enKhշ-bD7]y- J]ϣz˨߈OO%8GHvbZlÿk DA?D36Evmғwzˇ ?ךF3IseA i{W qF#6^w>Yp8 +9x`3r5y ݨ؞s;M|3=0}y<.?ƌ!㨜ulNt_~?-d۝eTz}؄34lFx6iXɷ^kCԛ&d=>ćPK{Ө9-X8ږ'$\J#(<~g0̙V+ojw\h4$&ͭJ0 +|ϙcE{Ugh>3:,T~n7ozd?ʃ[u?v!wv4g<>6bρf2oͯ[㷴5}OL y\;.s Fۯjđt\F˨tT\Dդ Kڶv5fӱz Lok zފف;ϴ}T_/9&oP'!<5y%riTӕ<}yr)n79v+^Qήuمο}_ޒ&=K1, +K$|;ԥ㨞yWQ}l쮫xjlG|{OG{Q +{RfL^w]Fi)A mnckkm~c9'4DjDl44GՠCтFaW|E.V.@#Qma?g]`(ȸ%g&΢zw̉?ʱ3(ڱ$#uj)l78f?j{xaS_JKӕ55^G&o<2؟3Գ^GaY0?crO~!p= vm$=sV:^dO,1~mɱ I_Ft?!7/Lnzd\_Mr5^`A~4^MO䃶|nKf?5z<7R/FOr8cː3YǥfPk]q/=‹ն欄no80jqTG_A|7F׷`^TLëe#5oKFnT~v9Cl,1҉|SI^V7[?1ixѸ$ޞ̩/o'rZ3gujYTG͝K{!Vv'18䑾9Ecyc47={o⏚K~y*~/HK6?2AIumybX\]iQر]E>˜Þd'F$%۷A†wg O~tޏi zl?ٟt{p%k29O,ߵe|2> t^|/߉ADMwZ}t׀I4GИ)@?j. +sN9|}$Sp.(睉uo}s_Ga:K]N:d9/![w&Oo%|Κ9lif HY001{¶s8vv?gQ87=6MT_-=8]҃sUS7$:swϷS=|WQ{z'{Q-~\ލ;;g[. +[]gQ5Gͧ/inŁyT>k{" bA|䓖ml Dխ=٢ԻnNS#L׶;瑱ճϑ|?*77ϳc3[\.޸" կ@qn/}I$N$6x&Fa ]QUs9uj_c=[>ݲEϥwyǒEe+[Fؼ#b(CHos_05uHp t㋤Z{bt۬6ڑ}%8:п?9۔Vt=l73cu,<٥оa39oF/wd?h0nJ}eCmH]vSvYԹ5$_S&܇YCs^zhw32 +U/udQ;^JWu-ϦEaSB 7O83|yvsOs8C~@u"^‰>>觨cu\\rñEr[ vGݴaIޒ9Niw- .ao9-]O^I5'3]_҂NrN&_V.t}żB?AE,Az›rvFԕM47zG ~ >OW5tg +,hu Ϙ g^I!-1#71AۉtVG'(%'}\{gU+>C?z>K wt-qh;ˉ>g'39ߥt==NGY^a˅,Y赓zu[Z̹/ztf5gڒ}~z+>]E?4]Fw7rlkK@zF5N_pj?T,zE M{+ GUZŦxw\Zy]J"/-su->d1Fn dOlF=Í\XM$[c-ryf?nY*h4-|y":\9d—&LBo~6]Oׯlk:)MO6}W.kZz?Z>IMgԔzZcUpv_kS)DSMFvk#67mb>|K<\hO=\6OׂLo w.7ߦ[}#?]'hJ>y-8 Ztw~ϓޯnoēy| cJ|_&tI^Ev'6i|Aơprޱ=Jv52/~db%Bhh$<7һ;{\ N;6VxdF9.x}>J\vxl /76y^_t^xdς7Xdv߻<ӹaâׇ'l"Ʉ k{)qeY,;6˧'xx>y_6!^(w? +{iR: u~} <# oUHynsS׷E> saGaF`6'OgFǻh G_d +e{[X̖̟[k#<uyU+¢ohZ-{8?x,'+&̌dEΛ^ :Dn?:۰7zQ]ޖ9Nt-D+@u'ǚlƌ_7Dc(ZO쁛/ +P<%k3oZ<3ڦEnvX*9w,fsŽt^@Gdl"h3bq/j~eoĦQϋ^=?9Eu?-p}lk',rP6_.|8Ŀ-r,~ZäBvw#|a+E:%[mm[/Y̒Q+8'_Ƀ,SS46%{¯[C#m?C1fݤ+XZ\ɹԔ6}?w_-=7b Y5rP |#ܷ{r$gU_"&'ZBo9vW-?ղt?- 5&njǮbmu67-9t"]dsKoVѻ+}AV lGǽc;դGKƎt ?C(wu|Ǣa'r6w$ˮ4,j@g&oۂݐ oY_zs{cPם#Z0;EX'Cu8E>^3$R[vƕWa|q\m`lq :@#$VR $5g𑿟WWp;i/u{֊D$*7.3/=Eg'u춯coȜJ YK(l(1Ǣ{<- 9{Lw/楅8Ÿ+loeӨUTiBO0ܓ\G<31C}O =|_$J3+h+K|<Y^;Y~^^_?K%ywW֨LoDd5t\}"9.EԬ#FT?zQUCF29tQT3n2:}( +\ dO\i VF `dUcZnj߱>tRFTsYXD4 ^cjs,*1}'}UQ=^Qy7>ȸ5V:LN#>89/d]|7ݞoQq}>Dcj{l#YTϤcDͨ3Ǿh.d'bm5l9Pv[7*Wx)xp51K2dlA Cj%:?ѱ2xf<0 JfQ'[T:jXǧ'94q⊚4[Ong6>DUT$O-vH};='ѯybm+*VeC]"G:ߍz?5pjt׏#&루\{vr8*ֈ7$6c2bG} =a^\c;݊"ݨEo\c+x{;EQ߈ѥ&{Eȟ4Wo}?*]l}e?  F;3{olڑ]C߉%sblOЈ`?atSXpo\:a{l 6;#gF~cN}O!3<Ġs4ZQ o(AÝ(3S0ȁ5DV -Cε0yTYγȸt%nZfwzީQ/_EDόW#މKw7o;fћIfˉFCu,H>w0*;}6$D,v앳W湒+}Fӕ֒w컸iDJ<_m͸rGY} ]|{J;#Wc}&ZKs-}y<ՙR^[lk$\;gFoiI-~B俒-G͆[r\^Jי|?0Y5?&Ug3H`״G_ojع[CC;}U]`Ӊ>_>OM>3:Y`fd.y3fQ5y7mKfIy5Z]z |7꧝ک֩kܡ{hE#zVW͌/jhk=[s,/l]34%}GQX +`Ce0ЛYt7 E;jVDaVwvofMtϴb3rsW-A^!R2eYYc`o洞c}#jVC6OAn4yӦ`JB4*ojwfWcykQQi+>K1cR:[:5غ뵆_Ƨ Y(-zWGvGfmŻavZ=Q]|H3>26\èx8VBq ԍj?]bvU kԞqݮ }K@~䘊=k(v:7C.?k`^\ 0BYۦkݡG1\w3m|NNl괒 d͇(ձ<+qK z6wO݉͜^tv$oRnTcɃ{݉axcb&?99rȱ.9Լk}&sږRggQu*1+Mـ\{9S1'P{ZsW)XDսdq`C?e!ϵ ( ۍMl0;Ȱ{]ә ]J\S/l@:j6݌3y-yje:Q}2 +LM08IW[{v?(:23=QxXEʵάv9r/jYT"BӇQqyjsZz.E/: fb8g+ +.u/k}?G\I]&mWNp_#H)3YI%Kvnɲ%hA.&Q\y·{X@;nm#S;KKtKJkC}Eۏ>i91qȏ(|7 :.jv$7YdWfw b*qvb~뽋ydh}g|6zCZ4CXľ؏F0'2\:vᇝJ|t̟SٹGW|}}Ah!'pS12-<^7:-EL97K]H׭o> vx`"?S}SwNځnTvoدȚ:wS}YF\oeqfloq -EM~DZ|ىylt'Cz'ojP>q3#O=fKtF)ai2ud|,#,r& "yjD+'&G%]Md$.QdKQd~'5IP@ bŏ[lE_G-o%`l= Ⱦԓ\ͺ{ok6lOK_>t,qLr[2`L"1<} ߣ>x`37lE.P|܌f; bOχH,E~So ^x:S(|>1vhr9WfdgΣ6kSs%< +-:-ٕ#t&]itCud,t#Y/2#c)#j~՟㿿U$* 8<%*ߥ]9K\FX>#{:ȇec:|w;Gc΅| F?c OH\E"W?&}cesLJ_߃9n3*!?X~2-:N* {^J: 6 .[|39E7q0mokm"=Yxgp Աw{;@qlg)ݨ EdӼy %oɜ3IљzO@w+29E^˽kS}~6٘_Ɨz@:Cׁދ\^Ԍ>obv9:;zȺ @k;7`)Fdz6}-9 W}\D_ڑ|+KK2C0~_g}oT==?s<=w"k` <=3SNuA璫P_9&ǭ:|z2k{9v5pYtW;ۈ] .25gdddVii O&~GFcd4MϖLڝl,sy؉aΏjKۑG&NzW`X?/%vs\~#cFSx#$CmL_ol>LeoYW˙ Hlc+j)_$3v}dNc;QFttA65qGѾ5OJtA{GmkgnuN]/9',Zsm}e:g#3yQڟ"d|gޗsxb;sccA{ڭΕ-SʳC<Ģ|cj 5|d3qЩbފYu92֕;uKYcO~M~1oqF#A>й5ugŖEԫc:EEb!7BNmQf |nۦomEf͆-CB.baG\| ڻ̹nF퍭[aW~:mݺ71 6_ ֙XG_/^wy"߳uR~m~ovηgw +LcoO_% ]U71oŬyxC^^lwʙ2x~8 c_!(2W"c7fdwƜ$42ك(4_rh`^gɭ#{" ӳ#cϰW.=ߋ޵\UpAF?Gbrn}/qZpS Jy%es\oyF,k̵e*w/1FJyKkO{L1EѢuz֝,io!>:șmTqG^`T;\=N瑹N#Ɋ=`!}Fqp%{aӁhΤM$q_t?KE-d3T=|:0>Ww.'Xj9o;91YZ6e#:7{$==v*2]j .w/D4[L#22ƺ{f~wKz/u};C,3"s"c\~l@#q!_G(koE\dvd>y?۲=zNYS+qMK6ѻ6N#rv{K`Kg5}L ƠnR[/tXH V]D֥c[ ًZ,c3{ԉ#5#|-z!>5>?[OX֑}30Ye<'Wjh",gND@&l~7]&%U^瀮v:yμ9Ne%@BZ,xlxB??ս7"1>ucl\t>6EZ2q7=ؘ1|GѡOݸģ% ,"c,ߨI$.ڍ]57b= |LOv̶2#*rDd56x(Y֑>`ދYrbxݚ ȁ !bm ȚNa!-G?F5tgm }pQdBo+0ߣ0O5y@΃e?B}Fi⇼cvļHM'Cݡ& Q4_E5٫7ذ"cH{?`V4n/ڋXe%g'Ugߤc$ӳ/p&.q):~Pt8}o71t}]o*[+EO0=h`vĖ mI*hzM#c&fϳzNO9MbtAO=qsgQv>ӛyfr.Z? 9ֺ9rK/82wt%nz"1K9kO$'e&vgIsKG+Sd&/y?r."6{t"{Y6'}BΉ;.>`>OW҇BN7gfwxAOSdm5M7#k£PEkd-lO S>bc;a9uw$ZǸMy6NwYwڱ!?Ok9Yr#L̞C0P߈zm g^/ua{<5>g"A߱@}2=u=zfgyèE{{7ϒAf0Rg*;x 8uAMd*PCI.#)1z?7I|ՏEd/qn,aOI^>zDxb691's;56 ",XY .glEVc N/n\w^Fs_o܈Pr8fb#;-{?&;=}eF}'oF黣ojV_rs~;0]۝}c=ٶ};M&jẏqYeHt#q)2Oo,u=_ ;88 HhDbtaId}5yl=߉l7˚ںQ$nd/9.kLgi!w%[N"%>}=~xwz-")|y6noxM凢!~A\b1OEyׯ3w-=m9_;؍:5I[z'5rW+㿍׈꩛mk臏|@{`Ⱥ՝Ս^7ؓ3skmߞ|0GS[ۑ:3 "l[r[Go{oFevhf/&+9oDM$b+6+>gyNq +*%sӗע-p"ϛ`~vl5ݸ%"gՓc{;:<[I';C#d_^F3O`aAu!n!F=h<06jsBS͸9[Hwrt{c xa^d%Oy=@mkh`Ջwb{bnV=?ASoj63#qI}]nEQHI(R([˖qؒ?j'iNW0>M2v?v}w䡃=3;F<J?^smTrh 9}38 @öX7_NmNn%7ӛf=fz:U3.eOjI#:Z9b1 4שGa4d)_އ@0nC?j&5ftܾx^{;OkYTkc^Ga]Q.ސ:}VQ؏>ӱ?Woo`eT>"`*zH"W5|ߎ`7Ǎp99VYT,EaKcACl26ҙ7c;꽂m2Muxr:g-jU<ʃvO|26$y=`G|¤H[5 ~NW>miO 㻣h:shg59qҗ| M[wNnhK>2I{$_ 9-鋽z]F?9v{?-Ktf >yt,vn7di=z2>]h<;Iԛ!O#M7*?~ Owl2lOG-'|~EN'&2z1{О4$ 1:xEvTB=/wl{}Q}܁٥otMc~uo|ڑGľ7יw%ʯ{`{ow>Mՠ7l;n2~}''ޏSE\ 9f`^6\a '^u}:ƻU/sjg+?dmym<49g|GQo;27|eρ^wU_N }ՋMxH^lڃ oI&u}a#rݎgJ:ЙNsNn_,roLx+_4G;alz7tx]{d_Evd6Yn4>hV_ܘ5vMn';}s7Fsc#i3m oݗw!^Iv|)=} [=iqo y7|g`|{:;=f:{u;o]>y.}{{%}gCRr;?]j}!>wJ${%=wumκ{=ws?םN7毑Zj>ݾx"=ksx }N_߅l{,_H<&;K;=ҝE BWQxgZ:ho!̵vjw:SiӎHNt'tKZ{CS?~'V#ROv;䝵msE-X@4ҾZc_{#涵Gx'/}с:71~ ؏Is,]_En% ,$ +ٱ}%w^3/>N'BIg" 5@ǎ曑t^^cِhGԍ(3AQn*LxP_iD]17޶}0-}N+uwr;ٛ/΁'&V>_O݅^5X4h+쉶oK2{:_ٙ,7,wFE.Iy=ݙߍz`|b<:Y9zoދ;ԶOK- }V;Ïl4;ɱ}nG|ۍ5swAltDJzMrX* 'z0'ڧ& 1}{Dѓ8iFŔډtOG=nKj##ujI$θxXe5Ϛu7 +<מc@ͺSW`|O3}QmsG2#}WK/ET6EN>pWQ~/'=^bw/gVQ,סNXx~MڶsFD2ؖ|g뎍Iy Zz$ݿ$oaa{/6Fjց֎͗#'7ّ͑~W"*&> Lߋ(\BaO{yo5Gͻz}2_SQBo&'aT?K{QU>G.侮87KXsJ| r.fl[QRQx;ͷ T6>{yX˨|gNuUTzESϻKZDauT^G<0\|^IOpxd '|oY[+vme{|>nX@+ D A@@!H6#_+{U֑޳*Zcݒjطȃ~'N*4|&dضݚfpȚ7,0|¢wj;vl6Jw.so_zc;홟WobK®]{. +K/*[(z?ܟm1^,(1YZѝb|.XĺTSN1 +ڥk>?]wu.Zfօ_鵐ޔ<_'_ b-{IlG?-74O=yiY/]e[Bܷ)^h6mSJ,u{g}5~w6]V}^`czY,5dx-:(ދ龿"MAuy6=e65!|=u ڎRCJM۷RC؅Esқ闖7ku>oї.ECѢ~V$k>ҼiQ7.voC _["&uk,j3YWZ?չ}Fߕ3E?莵|-{~t6dGl2Ҿ'}dG4jϴ4;=Mgs]J._$޷{ҽ ϒSw|'w]{dBk;ϴm==Fh}QKvt? }G|&B|.~ck3"pn_υEhv'5XMNcǢD|]sӢ5%?|<ߐ6E'~hwLeYM-zEETMԠfOߐު8iћdr`Ko6>Oms:{{:[IjͨM5^u,5d`K`۷POYJ~p̡?Sä;.B:WIiX`eӳދi4DwޢWY<~h[lUo}V<hwj_?|'3B}GXO{_πc+L:]oG6|Ww#R/˱+Nu@BNtP>u|?ޏxi>OvaID.);u-@O[v-}gQͱCg5{:sorX%S-Ec,OnWgW2RW,#ez+ ےeE~==ѲVwjuyTD!,r~]CoӢ 5-&{+.YV-{Lr0w- frpo}մ6vjnGg1;=u=[Oĝ]|t- m8B={㢻E[`탯d/Ew40ลd0l; |YzOIO3!4eZA?FW3>OhY,~c| +\ f{ybe=Ekp z`r~uO_x9O`T߱5޾3Np1lo#&r^n9Pˈ1>>z zEly3؏;3a^z&W^{٢_^ѻiq;n~2{Qۚth_Yj;䢚E־-|_8.$H>hlo-﫺w%%ݻ[K黯E:͎YW-鋜赇VOztyc&Ys-Zͨ \4?-ǟORȏ$Ǯ.rGN͢.%>~鲜7/R7] 9ttmO䝷}jIr8iO3س2[r%^w`Lp55^9ߵ'أ{zd+7vN?".&zKZ W;ksYr%~6 ;^UΞj- Fၾgެw̻keKF &=C.u;5LENp= ,j,1fKa9xc|܇<1FMr7tWr}d}m`hEEF_6x.gO[3ytѱ`x ,@zjg 8k֕ O{:ݻeIK\-͛ߵYUӿh>zXzLZ(MJ|tn[;Qsf]|ױ+crGFp6vyؗW#XYf3y ?}s\|2a Xk)clHNߟ /WNǢн(~~YgW WJF7Iщ\*c:-cV&[*s %֪uYzZ]fKqD< 191rF:g~~wb-b4js*{oy7>0i/4^^=P_gY)g2gij__Koj:׹-,D?,sguFcfZ*{5+eM^GTYׯ,O\){:JW@`S溩3ף}nd93;P+GM gnKΒq++=Nۃeg *1(4Jxby`^΁iS|/gK7'L[ʙ/1sj;_jacj\yUpy @J, ϞON +rڳ-b/͵ns 1^o̎ `t91V-ucl{4γF;zAGM7xdʞI?wh _ڦЩC 9Vh|Fnk9 NXZ'Cz~w%vr_Q3N{J\ dzݶy ދ{1OAJٳʹѲ<3RV>ux{JԈC-9pUOYƏzq99:3Ⱦ2.u:*e0S<=#ըmzJΣ<uc7-dY^>)ෙ[>4v;{s^إc>Ah8{w~m]^?=6K /ѾxM#ĺ6VOK=kdžԈ@o 3}}m9E>])q:vT7qNr7r^Ǿ6*18uhb;elKVyӼz{K?茴Oy3tmݰ| F[3#}J[g̝#eQlrqP}ȏwf}&e֌:)s0S)㦭yťD\oew[Wb͜.̫뵈YJ-\/w-O3Yھo}>J>WȩQK-N۶޵m,+ eͥrnc5o3Wv/zϜܺ3{} ۣ}@^2tɫUum~T֮?)7Ye>)rӯW`,`8WȺ6b1οQb]{=0Ͱw^gk*1 +v&eh}پuWM Qmw3e+d8W*ZMݮ)6z(6fGg~sȏ/ޏognBvC_^P}M|0ҿ"xD~WⅡ \Qά+F9RϥpcZ rB{ol}Ӱ\ 7Mg73r`[Ԗך~M[Ym]eRM^2א"fݖm~8}݆eqR]"ly+g#Lỏ2[n+p)I;Z%lYef.&$WK%'+F(_<\t9h4N4_i-PZSWJ}UgZ/EGC, +YO4V$90& k=zi{د_jyHfgk_.;Rs.WX`8N6Xͥk.W!s/9EEo36[<1=?9z,Ck[Լ/I^KGWěJ7R,Em['%lxs}MA QCX3g;XRUl^dOm:bbQ'kKOntFbSjԎZ~Upm +O$jyU4ͤ;|SW>u⾛g[pKȎt9f‡Vݾڻ-_Rg˝oȎEڱPp[uy&}}_]][ȍ g_=~|jw4OkZj5sB0n`uyEkk~d]`W~\Hg;qS?O =zFzrJӢޡFбGݗԋ2OEWu"n91Nc4NNZ:׆,q;"ܲ3-89>h?.;u?:Zw}щtScٙr9s˿&LG6k?jsUwMnor-E]9 |)7R^S\YZX{%=W:ۦ7eǛo&^ҿc\lc\=L>5$ysp]7]ƅ#X۷Gʙy`رZY9]ܼG!O#w0n&6_nZ`%ff58!sYN|[>Avr6uеryS="R;u k]OvHnii~?Z} ' e_ [I@mfW {j_lړK 県O3 7i=o|I2^ }9?Y/\`|L2Gcg0bQ6Xq7M[~N\{mݡb`%gclʷa ` unMKqSUu?%P?V+WE嵑cg.k}(߭,oEMw-ϒScЍo؍,jJthϿ߷?CqI}Ywk[st $oOmؔn0m3Т."^79ʼIqw ޶uݙQ_~ Lt.4ֵS7{ekSF<[A`A1Zws{_|ou3]hп;ɿVϛKy/dN%{%mIJś?]RU~H-d/r79.&?̉;ɺ/7̢GSc<}tLC2ثZ`'\ +n> \wMKgf71pٜ)cGC^ZOCE]85$~l[t7,8\:' fIw>#wcO-jd=QndL$}~|rm,LryE}A-xugsӽ;չ _܂tIp׵+Aݢa%ys} >8$˾ԃM QZ_XQ!=Hs +\66<|ٗW}ہm.hnC}$W$[]Qs,ҞޚśiX(,jś\Jt@z# ^F'puTkm c;v=bQM{>#8=rm,U#%v65^_13Nd\-,0qW=|װ/r +5Ȃs ܱkeSdm,$GZhi:w放Sjϥ`}xCku>J}97Z?s7ұSOu6jH'ZEm&MK_,b{%ic=l=>o*9x޴)ɱ책,Vbπ5Fr?>@u,bKN[RUkEKXNrX琱^XeS3V,zUH>_z!W`6W3,f_4c r}{b{90'X5Q u_{08Ԡ5-r{|3M]$C O^{%o>/[&nټMzk.ؖ>G-k΂/j}(~٢>l^/Ivjѣ$ X3.&^} ڧ6ZLo5qE~i\z|!=>Jײۉ֝@qϱۨ# yP϶eZ&!}WHOKJ˯/8 ]rzZWE~b}{Zrx-r خ5ޗl#8Mߵ ߿:u*yW%J +_Lߵux-rA"xgQ`EޢJYGX#aQK;;Kg>,-}˳x<88;^Gեefdxm~fd76{ +Ϳ_<_I7kry= /fDt/mk6͞Kw[MK<l-χ痛4I;{#;P߾wxSM#vu?}8>kCoH-\^JSqo~x,`a$=h}"ڍ4>5r~{8gwuѲ#EK_JwGt~vfcm_:GKo%&XmċAƗy|gQqsMnu&E޶&ޕÇN`Y;a+ ˢQx'꺣RL<+h % gV=ڱ,#OP1KOT7X~O-p<>WUMn -bVl|,+%wKUz\Ϗy>\c,{eы_s~;,v +^7Γ~3Vt6~ /,j\/Ҟ/_ӞEItWz|GΩ^) 4p79nM#Jo <5ڢ^HHc+,IUQz3˽^kI[L}Wi{*wݢmi/HsΤE/A.ď-AGس[ɾGغF"=Nڶ ٶm YX=ɏU,o"V{?W+^r [[කw]YtD\it%}>ѝo#[ef_}.w4ŷ>j5bâTmycwxyU5\DmsRf:Ӷ-_Oi +MbjLjd"7-z\fׯ@C ]^N-o}֝;!5 ܀grurl4]}JC^%E'}>^e|i]kw5Xw-bآ}jXle6nŸl 3x=ɊnSȿ.'% YJP:g3Ehnޣ3?y>Z$] $[ +{o˭$[_sBgܦ,̝Iڃי_w/Ew#}ky.OwZ]$ߋt7\o{nQjF#ZOtߥCMo_#r{eǡq)ky":Nv~Os7gz׵煱EʘLJ #uoj4jwG3+!]z>h5/-␘f5YVW"?ũC,wx/cFi"kX`p oZƶ-b ٕ>\X=Aq#Ѹ=^[o&[6[`f/tώE^E=8Sٜo3o7j|%aw.+ɿ+yV 9>Ӷm$鈮cсAv,0a]T-|*yiX+bg3X؆EonmXIJhnX䡝ē nZi&>s?ICEXMNshFιx.%o,jyhNL4|ԩOăڊO"wQrT,pd{$;mʽ : H{sl e|xH5=|eO}Fn8OyćW'w2^}ùB@dPƞtJ}HZq1wm;t~#v-u١ ]eSs2Ļeaꕱg A;N+}GÎ!_ըv +Uq7-yAVfvy|ȃ`^fQ!߰JY6 v++ll5zsvna k50eM@ 'W3=R<)[OHN*c/CyyAR}_r5|p&1Fg> :.Y-iych9$iŹ}"֜aӋʽwݲ>џ57.دV||e|վDpyYM&|Մ'B.U'm&v2.@}L4s'cyGTG]L;=vnrJ'E"mM S:[M瑄;o9Χ '8O-7wujTNM_N縤:JGTuA(eq~/|%SXJ8slNTF5erM>5pfS@EmKk>*GR}R _yrIO ƛ6mN3ܴۧޔeQi :{~ӘO7cUWk>?ɛL1:I)IGZ:wvLםb/6)VT5zsIl9g`2b,) 3ˆ0F$2,rQ "L%3DCcy=>>_)'kf'_D}||||62wǣfg^dS.1cp9>XtY=lfyOjJ Fc1=1oH;l1ox"]Ჵ&.]Q܌ϓEp^< _d .#wOV.[2DbL.ܛ+C^pY$c.(l)Rx|2-̕)ZF4n wY!2<ݼD&W`/QeQ5rPg&4 O^R{u۵~t KKd2>ͬgGHbhIdx[& {q/Er}iڱ33͔r>` C.Is/R{È˞>.kǾU`dv:bpٴU`b\:ag +a|u977/ݬo +L\9^H84>չ98 gɕGtL\WozR`e5\ +磤xuU|J+EÁ1Ѓ )QSj ApFA`VZuъUVߨ] +UVEŏ/&e^~3ɼL;0 +V캱$dM7jEkYmS֚u[$ +DnIpʞ&Q^D:<ޝqɉE\[øQz2`75COWD,U(ɁHXV?wʝζoO,J/3Ov %Ԛx:6=nI2rξW'jX͏;!so4fXob2]5wn5ѳtx2(x\m^>,S;N죹9ؑڡ릟׌IYgY˰O%#guy(#EU@#͙,m}Ug'3l :}#mM&kNA;~˞G7w[F\/!Zן}#}DzZ.)L) ~a? TXA6phBB,]܌`rŽ}i͙+;N_=s&nVUFQ~j:,CtV% EE!5+l\)Jᜨ5K|M<όrK4ZT2+ yF8;0KBeQy<ό8\U77ra8?\.%|i. zlԼ+ZuQ]WEưpuKXPisWX56 ’, BuhvhN[>stream +H\ˊ0~ +-g%b B@mȢ[8E޾H˹?G*á=m8ƍ]y\4b4lOp=-Er+v;VH>؋oZ1^~++'^1{6KJ|=]#+v}o)Yp}9 q=ٳ]>"vc(|~yu>Qm"=H.TXKg2ezz6D]'t  r:M&)E&c)NVt )u"ɹȞFDlJ@ :S2"̓Q D#gD'A&h`Q"K-$ +D&lA8Nn͡gL=kCХP]kR5d d5J.Q]wLVI;8A`r'0>]-5rZPmqvUa8x9IԡzϛU +53*dLi +j u +Ӵ GiQƶ"DY7tEΎv-@iN&$]i#^z+yF>oiaoyw!?_嶰_?* +endstream endobj 26 0 obj <> endobj 27 0 obj <> endobj 28 0 obj <> endobj 29 0 obj <>stream +HRI Cij}O|R@4:h&i' |DB`N=Oѯ}n9n])xuI~aՉD]lìegC0.Moa1XUri*B5_Zvs)IJ +endstream endobj 30 0 obj <>stream +HTU TTˊc^w/P{wA^< ,. +H(F'*4jjѨhID[OZizjjKSslν919wfvvoA#PUmsENgUCO[KSs`MBr:gnxǷu,[9| +:>-Wu-hȿ3Ѵr0 A><@ <]H[@/muhx09?Oq<D>vxCH<b# DtVe5Z o-|<brVA +\ iW +v)tA ](U[* SiYe*l\4rvX ,4V7 33tfsYŒ>#3M"dl*2:l)@I2S2gEZ/2CWD*64D*#7p({*aժ le:!|J(7/2OiO&ckiôufwfJ.-Q|06PTSjdxCo<0-<|y&]xvru}F; +hœI-zl ך~CrOY'vZ.\BŐzKk]aȌwj% iCx+"U +UPrbi<xX> 'N +m +.9oy/2sl45dlZxy{.4ܒY'k[.福|y HtoaN*(6WrJVt[̓Eӡ|?|}>u$5lb*P?nP(z"P3jU +sƼ˄6J-9 WϘ,obLHMF4D+ޞ|ZfR)DZTFL9Vé0#3+- +-9 !Oϒ&" %PR^4Gr"ji3M+P ̘߬vvOٰ{PTL)V/i1i3΍wŠHO OXH.:'K`NWױX8E:"3hTF'8%ZjN0 +EKȩ"]nӘb_fklt#Uw\S3xB|Fe7L3ӊ'*UsԴ +"pjC`,*^+umi"R@%9;߭3m~̼޽Z6F3+uKh| ʿ!^KF5Fݣ(E8` ?_cnE}է~ZP]P282at{]݅ Yc|$b-NȮ51fυ*`=}*xchv[cv(։H/e(dNYN8(P $S잢7oAćon55n7!T*fKz 2mgJ8>Ĺ +EPuģDPY/ʬD\jGwNn-Ǜ\Br#. B]xLbIN9PGNfo" 292ydi=81Q,aI*@sPHy84jw^M3xAͰi5V9 ^-1Y_18)gk+4[l{5VY>r~yw]^v"yjo)^SZ^\>6YZ_eSFrёRH^RsӘIZJ֌c0L9pa9PB8O><-c["$i'똧{hQ =hR!j\Ng0|ty;jkTd^~ݵtc[ dČ$cquhlSc&ߜ _Fz/$]v- T~ ̉:ᡖ^7:WޱYWDF 5Esmw}?)3q=#H M.z'A&EjpCG @0qBU`XQ2dhhp9r׷[2j*xp +@H 9 @rpCI +xZh=FEW]DVj[Zf:;e1^ݶ#{/,ya`a=ev>Ky܄7<2~>;-:YB#H 2x(J\ 'je(U&yнWfi%ڤꞅ*2h /7l̜\iY M$+&ʁA<+%"qQӣhf04+18.hF(`_WzhwZ;[Y^@0}0D"V&$EU-$(05SecڊK*chK?P| \V5Wi] 8u|ݙllnURpήͧ0N~Dda:x^,?3TV8 V§"+]+W4Y-%w!rir:1A~mw lK!8ˁۺ+h,Ȗ783%+.Q4J.hmjjv ܌Za^loi.. cx8r,1KMlOhz%=z/ :$9.#\!v| l%Ilo-֤ٵV .gsoޤ~MJ;Gq*(A!sC"  'a*@h^YQhz3<ԋ$g*Bٍa +K-;Zp[?bwFP J(d♟,FUYwg6c85d/S&nN <(-*x:{WUnO&Gʬ&iʖ=wh&,rp +TwQˍ<O@| sA$f{kw9*+GIWM=@~(n""CH{0.H8 60>}^l5CXAIΡU +F'# Xj[q-oֵpD2Ng\B^y ]mW-.ĽXIXe;Òr7Kҋj%{"N] \z>k&\kW"ꄯ'@M/t7PI(I#!(v1RK-ˀʪBaZ- "FDC_k1'Ź )Mnm eKHp( \82涚&3zR~e7%'{ڲ_*lfjŲeq (Uh^y_i;Cny`ʞ_Rw*bfx{2nS vy- 5O:ɎtLxc|H@ JPneOT-lVn鶢-XIsܔ%wC;#X^tl0w*zC፿㱱$Ώ q֙]lpOdyJy/'G⍇'HMޫSsPEC/@yV\I1x6rs7'?~'ʙt{03n~NjAkbByKTXr/~lȪ("URsaI"}kξvn8?dzbp{#=͍\ #ߺa.rCL͛cvkǺGjv:LWgQێ֪ÞsP:2{~%6>Y`hؔkpbz۶ +?BdQ(4"TO:>o"FSfR;@xQsgyefġmop|pͳWМ5Jo+h_mſUEuVE`H8~Fo;%A)1gJ'bJ+:o>}#|=MEn8PVcR=K" h}1QdܪFf4B`WoKⴅkM%B 홢\He*N=/wVQ8)!F&⒐)H\`5 [ڿ}28j>)p-q6i#o޼ Rnl:s2괔i&ea$v/(.AtI"zGg;o{8I136Ti>/CYeh$bMsFA}MZVhTHKNs=&tDEFR0uT#͝T£`#OKտWSL;ҧ?~j՟!rC!Sj%&m:M?i_;˗AM"xxeh][,~s4k-KP~Kyr3ԇdA&@Jiz ], 햠C>EA"=Zl&eZlǏաgWk{.KD~Dw>j~ +&=oxG$؛|`e>¿>HX]pT1, %Rc +#w UcuAuW; >P61e0:/<0%b.#~1A"_[e1-`}bd1'Gd+iȰ08 +Zm>NZXQ^",,`Ӕ~^0z >/-の0C>fDUV\#}~LJi 4SqQL 9=F6"V7mnUF-?&]aےQd+f )e^\Ǿ't $MmEK&ï'PfO h97t:3!ݾH!Ui 7wW+jE׏R&X +Qg:YBgeRêSwSOS7:3&H?Ÿڡ#'l ՙG/O.)rٺh𭶲:ę5zũcn#\=UnQ'߲iyxiWJv(x2X3&DPR70N=z:mF+ajm981D!gaEphռa4X3([jѥ贚9v.# ڇ4Fu'HhIGjd!ND'Z! +do?`KV IRG+uj%+ơ>Fd׳gx|лɯQѩ= Ԥ3-9TyJmJ=upi߿۵?}⾚j]WwcVI,؊W. |rs_ɼ͟dU (-zd"CE"ݹ;Adbo۝&$BZ%EԳ~xđۚH1^;̓;3b w6 1LkyIuj{6>lufs؜R;3:fd 'cRZӥx< 't@]3o;ېxO_, ӿߒ|!`!dMп/'k&ԅi5r=!zl?Y+/uqHae(O٢/b^R^ՋV7`}-|=aJȻྴ}>&Ї/bb̾O`WǗ1}V=tw Sqs2;‡#m'NT`"WʰU߃q- 5?c_)}:'<r!p +B|o's lQLW45 4UoQMgS6VytBqf-. [[4" +\*l"i&$cڅ~~$v $:w`CMւ0AkdykI_; (#245T9_vir"~8-y0]\.Ҋ!AG*9G>e{ȍ[;l [^PE5ȯ8d"D>6&/bk޽y_M!Dn{{*߫}-SyGa ;9ף{*ǪĘ|Wiƽ r5Cho҂G(WhwU>)`C# xsWkUΛݒAqog 1Ds0R!fy$։r#88ݙQr "8 h` eĔo,} +Yb}# U R?A4upX}[>G}zRh'Fz|Y@}Qv+vcc8'D|kV⌻ r_dK!+QGHD֢:H?{UP)}d'A=2Y9xoRS4+: +DѪ3*Á+9qq>}xƇ繖3<@-(}}pHhY\!?g/b4I{1F1EX+#^TxmRx (i%ؓo-Wv~o%Dҫ]}+vUUwcz2=8c8D +BPE +&"J\(`p;х܈;E"(wsOQpqw9?{+a #bkcl6\6>X d Unsa`?ƚ/cZ6^Dc{z6sς t^cߟ;;r:|{<dwxyO?q/m{ywl|&?CfcSfgk,D{ljNa ̾‹^צ6;+x +7f2q#? &~y57q]!~G1t5~OOd/sjR?r }{]0Y~~1=I[x=^~ipEoY Ku.MK=sзY\GV;3{-'xM7ƣ`߅ qz [}(GU{]KT_WRO!rcGX_~;Y'/[ʏ:beu]g񍟹M(Bw|VCydγ\om~f_{7,2(|x5"n>&Y|z v(`+LMT,\Rݘ\+uA?&>A/c.̪X0\OwkEǜu̺{OyT :>^3~$кh/Z1)t6쟠`1<?{/|q0z$TK\ 2">^S |AlۃO@wΏz:nCaSmqŀv/Wza~;ƆӠtW&f>:=F|+^W۬k&~w뢽|+ȼɸ^@l χK:[޴z5@Hާc/V_3l;nu d{Z&]ۣhد!S^CO96w#`ߑgB;Wy끶z7C\RKrpOXԳ޶ޱȩ3/wos:~6,g{롇 +,,up *O mz90W_x{C^8kR9zqef[CaTu"t=$K{ާo.ȑv]¡m_ZFлf)״&̥[9ۙQNs|^^91vnMS~;>g KzTkOнq}o=<^o4'i[gnaX;=لgu뎥!g{VnRm·̬;,S{ u(9Ku{.--w3?{.#j·=);͞|^f[WX|_L}KÙKwׄ30i;ϧ9k%)09c<9SnXz35ޣ57-vF[7-{`u7K`dP:]T2~3U-ԃ~U䴡iãx,XoRmX֝!ubQ Tk]"[ubZ fr Wҽ1~г:S'a7@:+-S(u׽-|ϣC,d2Y#=ŊrᘵCg)un4,Հ,ަU _㒥;yKo +c rro)&9ճb=o_Q݊vļg&꧕scJW\gLºa>dƻP(|ܖzuK=k3_ +ߍ'\c򡼈9~HCIOy%+қU2 KwV&QMХ报.bL#y)S0,OɦA>>_x|F{p=Τ =+ٗnEkHSK= +21G{|KRZkUГy,{]C~csrorchg'5{&>9oGQ[Ik;Q5ee VsQXyU˥Y׎{`p_HLxgִ"FICV0WxP9;K?s&؉Qr vlkM:F1kwD1߷v`!Su!߭x/G-Lflx>xP<$ϳ椆.u׾xL1j/(>=y2^I6 A dΤ0ÀL{< vgEK`#ETߞ=`` [b3ߑ6~|vO;my=0 +%3QA'#xNfOB,KΩxJs-nױ9Oxlgzvس/SN [a:%3B6az5g|{US_YC>_l3y|ۃOANlEt9(GشHr$NT+4j#7yf}p-ЍGQX㝼G2y]⿭gRجa,q:N7k݉|y4"Mxr>]/ά,#ؔG] mج-=s%&8614*VWjg(}~QT9}>?kbNot&s5gӉhǦZ6~-*j$gvcn#}1?b0G+gAR'ŽѰ5!φvߙk9~[ȯ / GFs&p +`8>lۓ~=gWS+pFD=8Hfbs?3ݹgOjAm͙d^.OuyCo_u)?}{'R̟v&y^N:wA/UvhUC|nvcl9 >^ZƏ=Q oEdNlA&}ٱENmOO/qz)ܓ{{ʱ&gɸ>+}3ڙ?ON}?H}[JZkkK;x+?ܣAg!od6VQg3]l'G]Fac$F҇x"h01N"λЉ#vCy͞A=Cө_7vtfwuL'O1 "R=h3N/K\wf?_K΃3:*X={Zеm?;N9_j;ږ6ȼz=g \&^r,c¨+у}E͒(9V\;#P%5gbr{dHcЉ£ӳZLUl5l <z^4̤c7.t8 6ѹ==&¦@>-eO:vxCcb2_̗QT^zcE*qmȏуy)}m] jxmvg>rϙ<*ϟD)޳f\'˨xE6GQؑ\k#=)D73A-~5'tmnry|ڊ/1 }'yQfIlA˵Kf5g,dåWQ_QqޣSQ\ELɥ|zO.eCǶ=u+R9ؚoןz ygGQ} j11,sBOۉ̤{F"NnuTQzL78Ե-,IyoDJ-z6S'ЇXji܊8x!3g`Qݙd̙^i]Iǥ?1~]l s\(Lyy!Q8~7vVϳ(NwJ=԰NH{ ΢f7Һolp!>j_|-䣶r㋔Q1]w 7&jNqk3-_Gr3k퉍}Ѥo%|y:Xr{K_kO|5?#KbџMbRgUNf(?,y~nr著dfVBx.ETQԌEPg'|fNE} =^#MU3׌:F~鿃( Ơ13K?'%k90 +3}[?G#X( Nd$ؒYl!S %6N0"t; +[ oGa!+|e/ +;vgLp+/uq,Vp c?ѓK3: {͓X7뛳{n/S{Ɲ +Ѐyvcsص;wvm<{7:`7 + n<`vn< +ﶢ橝 klgJB$1sХH۰ƹ2>=вlZ:>Y~;lU1)b6 ev]fcHݰ?_b6km[rq+"X0nx=Jyv ]?{\|Y[_oX<=X-s^k|q/ +p]Zѳaыq g"05 ߟd|.+ft(f\[Kn?~O0>qV}>%\7#%O7sIdP.99[JW|u=+0qO&9h x,1> O}~3-sg3͟6b*1na %t0Z=z=gӢ`N-c^c$ e Xע{ƹu9 04^нRSgwvOa +Xf/a1=RC6b<XO-sǨIflsRs'}TÝ3ZzFgM^x7/a6Nn>?vf3{؆}w,|ân:x1Y~pz}l-j7ߋi,jY5^^gQ<_@I_Xרy9q#߼֬]b/>֡ۚns2.zYUwlQcDEl5k6^"& +ؾ| Kf--ڦ +\u.uN|:g Ŗ{ܻci8}>?x1ti|?u !ㄹӞz30ޛB?iޅ s{K%:*ow'gS?-s9Oヴgbôo/߈I~ ~zx=s&?oD>e6/Vl琽] +~G)~x{Oegn`aGn*z'x.g'xNi'> |$Ak!# go Lے :2a|jZ">clS_m S+xv ZԞ;4>mTϳu~hN<}ϫwlס~}iF.8B^[@ǪzoB +)-ꅶE}z {D֛ebQT-Q~e+rѕeZd gmAZTŢlޒ+HO[d]0u*F|%z_߮X{oyg}8dok`d؁ DZEZ#,?[SmaEOT>m;[mEȫb}I!;[mWwշ[,V@^>(c3OX} ڔ{=<9w@r<w[(cͻ$tNsEX YM6~Oc~x}?>߀!qstW>'@[%I^~7I\]=_+Ͼ=ϼ;C#9?k*d]͡ԥ8pgdAn6i;b#cxmx2: ;.gv~ϒ1onOٸzp~ -}Ѐ23:ly"o`-a^ø`Qo!9EعY%\M"W^FޥQew,j +|4s">1?im~M]|ׅHz]k`~\Y.Zԏ]5ٴG}%wX@[E5q?w,1qm9poY+lEN}7˸ؘe,L92.2e͞8U,k@ڑuY׀?҄˘_is_2ζ0gM޷Ї5Y1ۘA:7ᗡE<^;Ku]4߿ s_z%[-_KwmvFQx99G39{*v!AKli5Ć娐ϧ8݋{?< 0x/?k~/1{!\_F0ry_?Ktϸ$QXL{N2ή">=nwgSb\&d/1S3*bs4`)^ {뺶6U-tfPķKlj?=.^z_RAg_D<*G\c'^nE~Y};2ۃcboB7;#y,xQzOOW˚Q!+mV:GZ%_}X~bKeT' ["Rg/%țw#:30؎}[4Në{~d牉dgȐ:/rEf7dg;`zl۳I |{}n?j_ttVB^Q1@9]NQZ X"==i,3DtE}ҏY-y.W[y J2o\gН iCk˖ԖsH~ozoS g8IH{KG=&*7c*$DT Ix]!Qs}~07QX {'=G9YGo֢KjI=^9C} _ɵZNNF>E&s D}j@gUs륭Q?r1UAXoNhON;q CL{gOt=K}UkFE΀{gQ58Lf=mmɜ==tVؒ7{Su#'ĮmzQ/H9OM\H flmbsrsMЉ]]A6%赙3`V~IJb斣y;ӳeleיS?6y8jlONx$[7ț(L. '&ԚC/JUT= ٖN-M|ډSd%gߋn#V晫(M[H2L`ۼ;?pa;m|3ݮwa2@ɶk%'WG_z>7 Se]ίb7>̧ӨY18M6FLcv썜d0uuoF8w#K?dÆѢ߭ngèGGj[ѼОy>2tm 3gsA汔40(w/d f&?5``wi`ZȭVT~cvp+ZrQ&QuL_,E*b FFI? ~L>xz}{ɉ}K57D7u& +o}k=jLrRoF SGOLp0z"ۙoӨ>Ɍ5ABfy,=M^ENbilԹFTntu{脿]kkgU3Qm/&i.BcS5y749y n>  Kؗ~Y y.*̭ٖZAOkD(?}UCgVz4 +?փtg^i'}~-kוɷ?ѧ}<m{z_X4M.˗緺 [?&k:s+^z2CpavCpcuj5`ϞMcG @D߱=t&~2Rīis=F8lpZG|ޙZ'>Ѣ&c=:;cTw֢Yrh5e?I_K>bd~z>7l;&b6|b6r^=s̓tD^g-?]oǓ?\[;s/]>EՉG{nt{I_~AK 7'rHOc> u!Igsy7m zhڹ~ Q3gٯ!n:r2:.Fdn ^6#0j&6xv쿏+vnd߮|ym> GmcNoa`ƆݡKoz LqNoYߚ <4o`NUT8s0 ndzu6{0o&׾]/˝ /CΣ涏Z[EagN~Wґ97i-Dy \׉1*>-c"(,*O3|wU7u|@mGa#;{v8F%1;4y$^+e(Moϛ]\4Sb_a{?*^|"~Wcw=t <+w8y7_6|ۯp8lYiR}g }7F~f-3!7?_Μ/r݅xmd}$}ϤC;t-4ڌQ5t-^(l{.ϢFk莍}ɤMG]I<%˙%{'ueȧ ͯӵt]Gղh.p_F{񺉪3Mn=DՆMT/HѽGA!5VQ9D:=㵌zWkv }kEFo`)H,>ApUT??nT ?EvOiG~яQ +t!Uéy;4x:y}T縧* +kv5໵䮴~n~Jŷ`jhQ1A&au9/D/0:?A}=h^gO>I{%?OnC.=!{] #Swu#kLp,om׉mvcؿc,O[:w*3C\Et8`{[dHG:sbO04~J7?GU+=693iN:p!3鷊sǩ/Dw#/4I63_6yly&Qy6؝'',*FՓ39*Rȥy`jϽ6~{ϓK`(C?0#nkxt﹎GLr'KB< f!G3}+`4;bA'?o}dc7qLM.؄;fn!?K0u +D 0yuͥ'~`+MEՍeTN˱ڵ5IT-zi\5= 1{>S,_d[?'%qڳ{z؄5+_ɟ䨵 eTWIAT88ON{J\ל;g&LQ8Rz,pYT3IԊWQoxW{~O-s_x枭-k·|1X=m3~;fn6`Ļ;泞YK4;5dQ;w>?'/вIm^hG:%͟D!6Ƴ֚{bh>o|ʶNm7Q=FstDM+&N ؊/ ]ә{k~g>-f( C'noؔs_?wQ}υx܉B<;Dcj@<ۨyTzQhNLΑ!.Gè> }$_Mܒ4C0ʱt\rUw9y8 :bqՍ։р ~ybuhkeϷz$WÆ-è9C;&Da Elc,8^s^C֑|Wq&4)7{Qoh2×͘O \?hZw^HuĐ:l Kn;cD4c j߅md5mK}nO{^kC>r{ߠ[v7y?OW x?;|u. zc1?eVvE=CA(Q8S"Ek$R82"'SD_HyqpPS(>3g:շ?Sx\tfmrqfk8=/9؋~5@-(|ﻲ2{PO׍v>%[0\SХpu~7&f2ߜ߮f[2=}WeKG4sܯ;]x9޷X̥.ڢѩ_YZ 5t`1f"\gXy;\6L1*lܢGvuHtFZCŌy)t_Ie_5}hkE9iA~gO53X:9L姖qI>~ӏL^@MnlḦ́w-~_R>@={O?>}8c?;9ŜѰ=Z!DlY&עdW 潎ŌF֞qGSgy;9\ S\Jp#3Į+ioY૪m[pMU$v,p |ڷ=뎝E9s_#Wҙ"#~4Kqɏ'Z M=bǎy9sO;8oW~Y-}v3[C9s#`5w,Vz{+x"Mj)VmэmubCD~1-p:8ٕ\;)l"w,Kt}}gswbڑD^|9}N~IY\뉆/c+{M^'u0_?wiԳ:Z |2JZE3UYfpOx޲KGcGߩ3KVG&-dۢQoݱ,kq;zmBtd2 j(UgzE[ٮc;u]Sk%yllKˆt?ґΐgR/9aQ9}O3zF}oK{Z9g'E+q ;fuдC{gmʇC߮d -roqs?I6߶ćՐkzE,-92FډW}ؓuk5͆EMwcO')9ܟK; mhhݪyzdFyAL}gQg:7LQȢ/W8V o>Wx݋;v׮P4.TKΥnvX3oflf3Gz\ފf<򳻒o}c>w<^ɢ [Cq`QGGLdˡqw6>ʢ?} \=/a3㺝0&:߱ewZб|ؓ.ߞ*m:+Œ"{\ٰ9E`a=f)F;[GMɠUR/IҳjG38-?o|=ڦhɮ wsDsdQ[hdWÍ]Ή|IahᷲtHWd]B[o +xTϧ'Ģ2#WMqdW4әt@״o Y}>c۴%=S -[T^},!9NG, |Գ沾|)Y`003Y`p'fVg=pu}`14ӢִR,ĵ*BH?-pw`3 H6mc3,[տR?t*[z6|\o*v.UK,3p@C-'=,jfim5{n{zyEٷўE)VNf\[ ZssKmJ܇0;pr>WdF_V w,Ü9%c6NBÎ-a|3s"xoz˜J8.yCE?採zu,j'~3Z`<̺+rhVgPjGŢQ/Om--%|Nu[7Ad<\3dis '_7jdҢ+~nḚ,߲sw,i7#ZUK-`k]nբ^9o]L\nlID~ +R9gvQ۹'/a\C>lZ9R6&8w}9;<Bd5{= ;ywl7Q5No?3_ב_Kc̥3|1r9;DaM'yS믣=%vW8!|4qN_ɞQxӞӾ:6ӈ+K9ޒ_6l{%u ovc D@l +[c?j:^7Q|:[N>9r#6&lsLXGءU&g=z̬1уZ==>5nߘl-2M mx ؕЙz0>eb1qⷞ0 xX +Gyv \s]dWrn==?<~''=}mXsО[[:}y~>jNz}ѓ!ؓoE{'9kCf>l}[7w{gs?}o6*{9]_L'mG{__5ܦ2J{;{c?YDǴe#wTzPè^ n{R >EayN\J E\ Wlnm{rNDx _ʽ/ ׁwݨA=x(=bU|qcwQ z:_qwcZ̙68E?(vlv2y΃ [RvM4Ps%vڅxiwgmN:yuTvk5~FqAy,wq!&qzL;1;è^s!wSK?jD߁enj6UYv <+SEfؑX I:Xߙۜtd{K989zl/GQmqw׎:69v11Ns'<^xwtæKÑ/ض{ =h!xz΢M/j;]ؑm=8=F~n%W!Fx~}!&}ν[ӻgWf{akΟ+F:O'LrX9Xz5MT6E~ݜZؽQu'{Q'~_Dgh3ww@ "Ϲh]G;ܖGa:*Ο4B2O;FT)^{:+fk,PWb;eߚv7znwc~~g܏͢xHBQLXؙ3Ywh-}P=O^4)/oEgx0{35=lM#ݽ F,'8Cz;GwYET?Meo[O$(9G/uT w;]E5{i2NQ9: W& ?+%'GtOre.*gum;$rN;N& +t7h(. nb1YԊ~j13ܡVUrc[ڽl~#powK 9vl-fzOs++FZO 9E. +Gۈ+`obd>n+|?qΐs_c|=w5s;=ol?~®^ϰ!~Q5 <`g7H6t34z'3-ML]Өzz0y [C>Qnr g^} {<|}j-xS)dyzwtTjP+t^i~@ 0q/\!MUɿFcY(G?O[ :y+2&'?[ {%;SnR/gtE\q ~9s1`?.%8"NKL|Ө,ea8n+;My#CFcmމ/"43rcTm-8Ky}-ޓAWZ]rͣ|)zϢbte#xgE 3֬NL`gbsr ?P;M/;5;go팙L]'Y2Q1a)7v?(c~UC9ޗ|(~7 8s(|&[F>5;DZ=`>= wfKaig&&=bu*÷Ս1]bS_ 1ν2?3>Egs7yç܇7Fϱ^ylJsx<<{1Om&B}mWOQ<o#I^ώ'èނq|9qRUT [F0z#lLx,&F\;ꛚJ`ST-&ݼ@_ra+9mlgC(>Ξ7h{Hwʍu_pGFOUYzwV>EaFH~[G;V6͗GWwZ)ST~1KC?N2w0:> u?s􀎗؀|!ɇ#:`>οy7[)h5g̣jB66Q8t1;IspW)~G;c?cce>?!NbtZ,͏WQ56mq>iioO?1TO?탞tH:I{Ѹ2^U㞤_}UW#o7G羷s 7I: - ;;ח-!QtsTڍx\Fuľ;?};uK?w#Չ'f[;QHWx`v6ӯ3_Z3Nu_PF~  ^KoL^f(\?r/=e87]NL7ǹkxC ݅s^}cwő^Ou} 22wշa˓>=1w-zB97x1g93'1hxzHzoY~u.LKq h9s]vbĘ9%˾}~/[ѿFw}'#'y>zEvDo+cpmmltF nysI^R47ҙ!3ME{j~LF{cy(;vg{}jJ@Otngdw= ފO5j%RJ|Ffs>KlwfÍ 40Fջg6Mε6ϥ;:E6V/MiTϝF͚ ӧʝlp)^{uďXM&hol "O73C=:;}g6_zonWg:ӳ{j=1cՓɇц/u}-3sm^L17Yl8XD>uLF*4wṆ)t#SǺ-& K-`^CΟEMr>C.wv,6Q MWF{km".nof[M}E>e?&~ԵGCL/zFZ /jxG}"vQqHkwr~޻775}j sbE6&l=AvLV|Aoq: ~w14GQG|0;N>asmi2y\F6SuO'9Qu;b|QCƃ|!&QQgȷv5&xKTEǼ׽_Xq¬aFkߖ];׳IvݘoAG>lwS"gOubE}GLr1XgU0Ir>*Ǩm @>~C|Gj}QyH_7&=璩{t3Yr`O\u[:n>9;ZV>?3Z~h0OQu]nv`zg1{IZ-=!Xk4ϻ,p<9ϙ.al>!>šnd}ʳϼ`[ëx]{?;[z<;Ύ<_AUl#no:н'1;WmI'K:0d$쟋ץO'z?(,Q5mZC_f+Yk>L[ ښMԬm(|k;?SxcكYbw|dGOf{46s;N4:?ۺ3=#u̱yy.ࣵVk`}rc }z NY6J~'ޮu]*^gpz}ل8޽]^'*{-ɰ1c]vZľ᷒oyf[,*=a1 f j"utKѻm˨z ] ]osQ}Lk7zvɳb3m| 5mFͬ3y~ f'j@4\v#cP4{u_ʎ{PM%مliTĬmGWߓVckK~= 6ͭE^3A?*OOfIΐGDHj65f#!{4e#\ɞcѼ=#OD,ՈYDZpjOp'gN\?;NqUQ!3 pyTn zϢj~: +_z5xf3Z^fM%IWkeIhdK10yg&c"梢Ω}>'Ͻo淾TtؙsC!9v ٘Cj_VF23R,j.E͜|"9wWӾḋgQs 9MAOp;p~|>Dh.ק&>Bxp~;6{F͉t?!=vkshvear5қiOmEPD]QľQߏd]3y*}AT ƓCvnEŽGuJsl8j;n#'8\ 3åt0PtS3GhuL4]NEEm:DumV #?n6۲_'ïQ=7&*m.oaTYqni=}fr8q?ď<ξ2߱yԁ{>‹|Bl:yzQ3\҃ؿsHE׾E=lE˵1kK,cEl>Q=P?j7k}݀ ^>`&8}ȯ+MqT0{gMku7x߽W0܅45iT0I`mfbwYyS%=bw`lqf.3j/gI鉝 ;&C;۬d˨ +~od]G 56{}W1LM]b3NgpQpb4J\JS9֑;$2*.fUöѷ/71E=$^aI\$<>.>#e7uT\|ϼQ1 =1A]9s.Ϣ-:''F ;?Bjz?|+Maپ_o5CŻ&EP9wF{/: fv,ԗ(jeޤza;$ݘCzqGȻ"j@Ľ6M#ݵZ9>>夆D8nn_lԍ7c2 gbf:T7]{&ZaO6K/7IT9fz؉Gmd>磏Eu_[ӧDs\Þm#^ }G\1#@LL艹憶$j.l,iPk|GLsϩ̡IO25KEKC3'$*'1vd<̜4~MtNb|6\Gk2v!Ak=s?I\zY,͞Y#-=t%o~>YԬE@z!xQ;*;26{@;%G61è4Q}F}z\9SOzEƢ>VO~ӏ9=+7=2 tUʡYTN3׌˿yۗW5p&B r7{`1 /o%;ݯ+}u-y*q3:G8+U77}w}ɔrE&}:5/ z3!=[̻Eow)صrM}Fs5|z. GQo\g{Qoq{6Xx/Q'uc*P7j[G;/ىt^R;M^EJjυl,6{؜ekKۂۏOً}`Kym-;<'܎w#} ǂ +@0Mٟ|&3}VǶ4=18nm-oad 췭3bcx @׎e xha;|g9eG@Gʶpo7#/um;gf7wî}Cμ8Qo +=+{xG[SI[|nǬqߕnZ3/t>r9Chx]CG)>-ݏMae:܁{{(f8|k։vaCOOr kqֲjix<7NIZ }k!. ?1Mnym79t+6s !{졼 tu@M?[ޔ'6eFc^ M=BywY7Ytwجg`v^u?r>˹ww'S\-~̇:*ח^_x.Zl^4?jw([d,nWNz  >d,:.4s[>O¿]6|rA7sנqϻ`oK|n[C26eC_t~cM_dIgfe}EcKc~&B:Xrf.t͛~.=REN4rLc-N~~=%J07=uF8%3U:k&oE#e=RvMN3_5':Ka?n=_W1ݙKɁ7c ddzlE=~.-2݈Ϥ`sRx \g&R2i-dӮLv]fw)kFTb6/UY5xc_c3ό޼nH@$HI **$4E@ B 4b/X17z?Gb)uq;4!ϋk$g}Oa^L E3qqn7ma oU bnm\+e{YLt]A#4[]^f +d&y<=kkE wou!k:fvhXNYbV!^H:DZ:ωq []t& ر|[{"vۡ&=+4S\-3狆d_sjI}sh[~n|A>Q}vnIq*ʻ"ZFcF?ۺ#gq{FzE}c;rWE.cb1)eY.kuJzjcYd`>4-f-Aby?BV!Β Uȩ3]:`\w-dg3%xU״=ȕgd!mbeMn%MڢhQ{5>h%k:c[K";S +'XGX3|M>/.p T-L;}hѓ=7{ssc~zw3g&!] ?Ug&?< +!s/;t{$o/-+|X5;cej[丹El2>w[?m[>/Vk~{yag + -ri-O?s~Iqa>E6BW 8>|ܢ6ד"A"fw{W3,m]ZIZK[4:nK,,X[cڀ|8:_:=}1yT&^)8+Y=#E}礩G?~QX{KE `\ E6-XջFphխ ț%U5^U&i_>dO5Ebok3p& 4G=cwo|;uZ̥X>6Y\;}s\7纸ºFX} =ϸ7hϬțث5Km + ؠ'jd-\̕e5!+`t9'6[,ҳzNNDGijg:B,|س7wiK5 >~+X<~+9`{:~ ylhwmt:`K͡mYF/-bHK{ycmhvamC5a%yO?5t`3[oB/KEd\6Ҿlp5|-FS`W,z +lNh:s#{ג~ycnaN[YK ~=1>Wfpg"'qmO,rt3:=K3m_^a[1'ɝ9@u!sEZl{gd ]X]X̘}%_#]bo'g̿SN?$N y 6+=MpI_3MglNAzgc-bB>|[ s_u~ƹa Z+/Ʒ΁gǾqbO-3җENfżеEkj#{-si$}w~my1>MZO/XLwi<dBSH9P]H +$֟ +|ؼSZ +IB}a7;i};?ϥn|~}_ax?*nov_?ؼ时ć} j +>o ۞,ܷqUw,b_S/GvS 㬫eYZ}%kFey-kREhpέY-j*k=6~uW8=;?Jz /'>WaZ̕- +]Δ\ٶXUn-h˲p (u }Mp?g}^Myi}6ԫ51+Uu-"fmE 8:ZZ3O[efcoo&\c_bY3CMTl!zXS>܁σ-澰|7O5؟r<}~ Cy/|zN) +xJO}y%7iBpkdeyA;|X{SO7 wѝ|^-п^v¾Iuƽۈ~q2w|*Ogz%lq|1Sз{;crZyy+ma>=+ Sڥ=pf:0 ̯]6-sް^hWm aɿr\uIuj]lXĊW۷Uvm1NKp8Kx`ͦN{}4:>k8{P[=׼3ϭ/a<縻+w +k~"v[= W}O12;a\m|@V9gbᇾS]B8wGkt}_<Y̡̓'%=f(=V}_u'fx2 +|VbG3zZcG1>3э+}KxP'g.J piT^Fa)V6ߊ-G}FG+ɤ-O; 瓜?9pJ~zN-k}~78/68SQytd_ׅ~IT9sp=WQu2(޷ʋ|:o;2cӍu|Z&r:DTtn\BNp}"=od2Q\579|cv'.9./ڟ'i_;ı/%2>Dwe\:Ӌy2u=7[QԵl +=~߹GQ03eL`79oz7g臨:p8cFcne;>DS87{*}?86ɬ_>]ɽ3yY[l9}~SCogݷ:w3ߛlH?d_>ٹˇ7{:[={'>LoxPG21{r(.#9*翧}iE "ϻsp Fb d?5OL7Xϼ82Y%s>1Yz:=]3_>s6p} {N(u/Κ}(N/1g:<8ٻm/3e8Wt,lOȧcM?ewѕ{.)km~'O|c2pŌ|<58*WMRd['fR8}/?''Kr:Q<9(>(6K߮4Nw趒d04j[tC(9tb/3}o0 +''Q\v~'_;_/G3ɘG7{7u;mTn[fzu^]pSƞ؝'='WP#pمa>;RNcz- 559Ef+N0zع Gv,,aGϣ.^s9#{; ]8?r;>ؾ?ANd<OQ_yvG/urdAu"t.f?[/"/gptNk`.C.$rL"jޙF͟k3qC{eGQC>Il ˴t?p+qgj{}?spV GFzr2FQzhW[> ޹+Xp~ oy՞ۨP_z#\d~`,~ξs~۽{]['}{#OËcǓ7o|WQbK>uQ^ĶkM#Z&˟|M'vqu-mn *O;|ϙ?Q}LWHqv޵<`_O07븋>͡D݃9wSV/񞓙?{~ڵӏ7 nJOQ{t1ld_r,?l$7|w}+YR%}/'M>G F60wG25|}wYsn-y>iT8(Ᏽ献GqfQ=q5?(O ͏^ҽps6v~4}e'`/L{t1 +`*%'R`hFq®Ƀ7cсpbqo*3 -[cQ8]nԊ $^璳C /K1[vz΁WӘzkJ:]ݍd<">gQJ63Ed/uE6=zN?%f"c?'du?_Ȇ_8ǁ'Wm^| +w@/3_qGs87ϼ3Qs*<`nv3CGFQ!=kfon?gY@<owd]tO ~z>g$^%\4=G=G}})$/m^~n2᭷:s#+ydҗ;6.N}}ג\XF浹|oܗIo$adMkzߛ!f%> f>D=#WKddd,w wt.Ov+-bRo'[ƜM61b:ב?1t㾥_`#>,$NZVr<$Ȧٞ;8Z~G&-HO7Zt$ +].ZlOo 5`d3l o;rΕEYBiF#i'y<>~puDz=WNm s{~OȇdK9X";\Z`Ɨz:([oқ0}E}Kw#w~38®s+yf+Y߲g{~ga?zW≸mv{A?%όe[t7x]Sv~gq}"rcu%7_+s1o3ȭpuѾ[5~oGKA8_It]H眒K8XÌG]7S׻ew9hC:`ޡk]ݣiVzc +һ:daIM= 5wX`ǎNGk& ?G\k%nHzp5x 7-,p{co,OS_|w[l'}1u >ov,|C /if/y;>>J&зZG\ dǖ\[ml[$KW~Աj~yXz} 8W+=ZYĒ?~ҙŞ}ַn?[cES3m~O~ş n}nQS+vBg Y L7$oɦ`Zzwdlew]zⶦFL7қNp X&k J 8=ԯh~V }8<Z[deZ /Icn6i}8굯o/ģLS6!^68'߳w-j] J"_`?}'!!Cބ3"U%"⛻Szi .,0]6-jPiQ݁EM/,uaQyFt9$d,[ >}ڒ፺Z?J^'{[}_zKٹ4c1׻_9 Gf_`et>zg~MzNzZ+syM3-_eS#5=/Yp+r"=7 q~ +&n4瀃Jv?Z7?}ޱ"xX~gKyc lxuim hu+}ssɅi6қ\/-juc=c5Pmc!Z7&}^/j"xe'ε'9,ހ~%Ut5UM=Yo] nZp rAWoٜW#S .?{SېjI^-IͯXp$ ]G7nj?ߌ-WyVt󐅾#//.G_w//{?=i9y>[TgR9=kNi{lg|5`ϝګ=鼵yf'}t޵[.>SAs.s3:(J[=wXYڋVA$ךY nɞEj9 ?\r;΢6溝yp΢>##g0ބ^{^MgdJ!k+<#cBr.=fGůWK?1ӷ#>L!^ǹ`C֍,58y=֔9Iop}l(.~AyгVO]Ϊ[` $km^d_7d};V;inނ_U^٧uc>HyX>~H9`:\y +B ]΂]~ 8gB~־tžUY-xHo +/d-߃O^ϲCڃ;eɺ`ÞdW'^9g~ҹܵEM鳶M"zi]vV}b +SZz 9<qc|jaн5MaVA^/sQ΁P{\?|*;S~=JGwzEZ<Zݥs[%{xIQvI+ c4ג{GK d?gֱGuֺҙnOmo#̂5j\>rm,+x|fN;~Ŏcǎtc<``,` g|6| 6la$ֈ[G {u]ڳ[OW,|M ,j;{D?opG=C[[ѷEj0-z +Cp u5n7ddN,uhdW9 N-0 uM/-L#}؋+Rgu~_- \ٟ?~\Iv[2vӻf6w'ˆ qi&qr<㙅uNwk:}azb}ut~ahуv=btm'n?7軨߁wdF"Khph|ҙk+ԇW#%+muז\Le"Cީț'ȍ֥G0 +~Z^Q8"Cd#/"ltGk`+gJgV@âZ$zKkVņyukQ؎pou~."Sye䭕{hz'|YԲ|^:/`G_8 _qeqfو}=AC Λpt q,=c]j|Dg!8jx<.hQKr?Pr~mhö,0>SKV+l1 96R|ˑ/#l]$ѣ,-׹ަu]xx/5 ޿O,z ǡME,1z7點iқs?O2 @K]􅞯֒z2I --{i ]d*^=[ LKwnO{K~V/$Pru-|fKWmA<֥wx: $9שM{; AZoY`xd;ә*? 'slQKz j<§-ǭS{رr#Wr=n1 +5&WXnt}w:7,=E_Olv$;/;}t|wOWH{ +u|ִ0Y~:+^ߵ5xڕ +_M||}zr?p+~G ~-^,zkyr?yg^>^mrpVz۶x,+"莯-œovMv%EoB}6F=n;hXपxRMoXgMɕ>_Hs\z3^zo+ o?ZbjeK<W::K5/WG7ڛ랟}i׻}11u^)8Nwy>ٺrxmg> +C ;sh$G= ֩C"4o;%eckXJg{w gfsE!#q 6nks} _XI}ps}lr`QߡO~7+ kߢGQI:{$0C+݁'x`ްu.B^IآGCƆDjћ0_YdYM{Y?]"=?\ԉ)bi۱+=.#:'~EMx.]ZǚE\=jΝttnael n~s}BOAy`ѓ+SerT4n>ĝх\GW+͝,tf,^?m[ТFt,r~XכּљXԜFD!h-B/ۗ.:Yh%|T-$/ 6=Fư`fIž\Q6F>pM5X;8XI`u'Nt'&yZ>QsOov;LZXFL$DI3^NdcD/jaU<`v⵹a{W綎\`r%׵pc}HO#$y㳾6DtY\r%^Rx6׮cna;{\ݦ#孮g>\ߍE;EO~Lvx^?_i}:w\FN$nE^f}ѯ-jͭx?[Sy$a\b㼪8~HB4)M=1kƍhH Yy V"PY + Y X`E]EŊE$PUBE*Tb=s< Qv?}s{,u +rXs5Ωw:ec̢}X+>尖= IU}g`m8V,jg!cD쨍@{}wWf8Ȝl=S7 ygy$,o>xЎYCcC :z腮Y 0}B,'i ^Nb&f DA;g8*l乛zs%ٰKjcKIЕ)'sG11msPxu1?:"vܸ ̗I}i%[CXwL? ȠMNzudRb:YEYM6='F;l?m_˫|ka-,vFhe9s^|v>=0c 1W'<#܃5ҿ3^w56a7q70ggm@LM g#._'>)(}>?tc(u)GϷb9#syQM,O妬EVr}1yX_/o;10?/9>ΖGsb,dsl. ^b>?~S/kG?[߷&`5niN/j_9~\,2~B<歶ި~3xqmX'cڭ.azŝRUwEcv=Khսg戣bX=ĺkE^5 m+d)#|J z?oa.I۫5OPǞiL ~B̯@Cb1Y݀7kacXXH?N]\cX(c\?򂘏o Y{ҿtuɍ5s.g1V1W'ኘ8Ә\G<2؟>6ϼ=~3sY,0-{7Y?ۅ=>cF:2OM4oxk8wG2W8E}6>2o|f3;7'|9Wn}+E<`ͅWr̕~~Iտ8oq_'c5"tp0w˙t 7nkrm|V-v'gpE,|k:/{NTѮW9&kr}G"O*Won gO`Nˮ{b(g /`T>OAw|.6o҆s<+Soɇm؟ اo}'{r/sgӞuHP~Ͽ^I/gN+mggL9m4˺y Q/~Ӌk++{*6qׯ7 +ҡt}p!x+y||WWZJ4V`yJrz4^L}8?u+p3ӝ 竚rRNf]|of)x>=G\{Z֗zn#4t89UUrώRӁ:n?^7=7 ҿoһ;3-dZ3^\qmw/9͙sifY.BmNriOO]ʿLKO]5m{-\bAA[Av}{wF۹m~KʽSKw;;OlM>sѣîۃ2ٷؓΞϾol% `+xjl_(mQ +[ +A܊ʯ`of,Ե v?=yz:ܸ=mpr-   `gx%l] v +׃ nMA[ε  m̟7KiC OEϙ   E|AAAAAAAAAAAAAAAAWi$ +f ik/ *6Fe-ΰ Q7Uca{fxy|g//lg!ry?1/wMPBt_&k<_y;"U<:+y*Yz6+EVIg|8w5 V[ dן:Gt> endobj 8 0 obj [7 0 R] endobj 31 0 obj <> endobj xref +0 32 +0000000000 65535 f +0000000016 00000 n +0000000144 00000 n +0000043566 00000 n +0000000000 00000 f +0000048193 00000 n +0000048330 00000 n +0000048003 00000 n +0000204778 00000 n +0000043617 00000 n +0000043992 00000 n +0000204665 00000 n +0000047247 00000 n +0000047441 00000 n +0000047489 00000 n +0000048077 00000 n +0000048108 00000 n +0000151203 00000 n +0000151228 00000 n +0000048470 00000 n +0000048495 00000 n +0000051053 00000 n +0000051374 00000 n +0000051443 00000 n +0000051717 00000 n +0000052188 00000 n +0000151927 00000 n +0000152095 00000 n +0000152164 00000 n +0000152438 00000 n +0000152649 00000 n +0000204801 00000 n +trailer +<]>> +startxref +205012 +%%EOF diff --git a/assets/langs/zh_CN.json b/assets/langs/zh_CN.json index 9dd66f4..76411bc 100644 --- a/assets/langs/zh_CN.json +++ b/assets/langs/zh_CN.json @@ -360,6 +360,8 @@ "身高":"身高", "身高输入提示":"请输入身高", "用户协议":"用户协议", - "隐私协议":"隐私协议" + "隐私协议":"隐私协议", + "呼吸基准":"呼吸基准", + "呼吸基准介绍":"呼吸基准介绍。" } \ No newline at end of file diff --git a/lib/component/home_page/DynamicReportDetailWidget.dart b/lib/component/home_page/DynamicReportDetailWidget.dart index 07391d1..65570d8 100644 --- a/lib/component/home_page/DynamicReportDetailWidget.dart +++ b/lib/component/home_page/DynamicReportDetailWidget.dart @@ -41,6 +41,9 @@ class DynamicReportDetailWidget extends StatelessWidget { mainAxisSize: MainAxisSize.max, children: [ _buildHeader(context), + SizedBox( + height: 33.rpx, + ), _buildSleepDateWidgets(), SizedBox(height: 20.rpx), _buildSleepDataModuleWidgets(), diff --git a/lib/controller/setting/pdf/PrivacyPdfController.dart b/lib/controller/setting/pdf/PrivacyPdfController.dart new file mode 100644 index 0000000..622c4a2 --- /dev/null +++ b/lib/controller/setting/pdf/PrivacyPdfController.dart @@ -0,0 +1,40 @@ +import 'dart:io'; + +import 'package:flutter/services.dart'; +import 'package:get/get.dart'; +import 'package:path/path.dart' as p; +import 'package:path_provider/path_provider.dart'; +import 'package:http/http.dart' as http; + +class PrivacyPdfController extends GetxController { + var localPdfPath = Rx(null); + + // 加载 PDF 文件 + Future loadPdf(int type, [String? url]) async { + final tempDir = await getTemporaryDirectory(); + final filename = type == 1 ? 'service.pdf' : 'privacy.pdf'; + final filePath = p.join(tempDir.path, filename); + final file = File(filePath); + + try { + if (url == null || url.isEmpty) { + final byteData = await rootBundle + .load(type == 1 ? 'assets/img/服务协议.pdf' : 'assets/img/隐私协议.pdf'); + await file.writeAsBytes(byteData.buffer.asUint8List()); + } else { + final response = await http.get(Uri.parse(url)); + if (response.statusCode == 200) { + await file.writeAsBytes(response.bodyBytes); + } else { + throw Exception('【PDF加载】类型$type:无法下载 PDF,状态码 ${response.statusCode}'); + } + } + } catch (e) { + final byteData = await rootBundle + .load(type == 1 ? 'assets/img/服务协议.pdf' : 'assets/img/隐私协议.pdf'); + await file.writeAsBytes(byteData.buffer.asUint8List()); + } + + localPdfPath.value = filePath; + } +} diff --git a/lib/controller/setting/pdf/UserPdfController.dart b/lib/controller/setting/pdf/UserPdfController.dart new file mode 100644 index 0000000..4d29421 --- /dev/null +++ b/lib/controller/setting/pdf/UserPdfController.dart @@ -0,0 +1,40 @@ +import 'dart:io'; + +import 'package:flutter/services.dart'; +import 'package:get/get.dart'; +import 'package:path/path.dart' as p; +import 'package:path_provider/path_provider.dart'; +import 'package:http/http.dart' as http; + +class UserPdfController extends GetxController { + var localPdfPath = Rx(null); + + // 加载 PDF 文件 + Future loadPdf(int type, [String? url]) async { + final tempDir = await getTemporaryDirectory(); + final filename = type == 1 ? 'service.pdf' : 'privacy.pdf'; + final filePath = p.join(tempDir.path, filename); + final file = File(filePath); + + try { + if (url == null || url.isEmpty) { + final byteData = await rootBundle + .load(type == 1 ? 'assets/img/服务协议.pdf' : 'assets/img/隐私协议.pdf'); + await file.writeAsBytes(byteData.buffer.asUint8List()); + } else { + final response = await http.get(Uri.parse(url)); + if (response.statusCode == 200) { + await file.writeAsBytes(response.bodyBytes); + } else { + throw Exception('【PDF加载】类型$type:无法下载 PDF,状态码 ${response.statusCode}'); + } + } + } catch (e) { + final byteData = await rootBundle + .load(type == 1 ? 'assets/img/服务协议.pdf' : 'assets/img/隐私协议.pdf'); + await file.writeAsBytes(byteData.buffer.asUint8List()); + } + + localPdfPath.value = filePath; + } +} diff --git a/lib/controller/weather/weather_controller.dart b/lib/controller/weather/weather_controller.dart new file mode 100644 index 0000000..2aaca91 --- /dev/null +++ b/lib/controller/weather/weather_controller.dart @@ -0,0 +1,367 @@ +// import 'dart:async'; +// import 'package:EasyDartModule/EasyDartModule.dart'; +// import 'package:ef/ef.dart'; +// import 'package:geocoding/geocoding.dart'; +// import 'package:geolocator/geolocator.dart'; +// import 'package:json_annotation/json_annotation.dart'; +// import 'package:vbvs_app/common/util/CommonVariables.dart'; +// import 'package:vbvs_app/common/util/MyUtils.dart'; +// import 'package:vbvs_app/controller/setting/language/language_controller.dart'; +// import 'package:weather/weather.dart'; + +// part 'weather_controller.g.dart'; + +// @JsonSerializable() +// class WeatherModel { +// double? longitude; //经度 +// double? latitude; //纬度 +// String? weather_info = ''; //天气 +// int? current_temperature; //温度 +// int? min_temperature; //温度 +// int? max_temperature; //温度 +// String? wind_direction; //风向 +// int? wind_speed; //风速等级 +// String? cityName; // 新增城市名字段 +// String? weatherIcon; // 新增天气图标字段 +// String? weatherIconurl; // 新增天气图标字段 + +// WeatherModel(); +// static WeatherModel fromJson(Map json) => +// _$WeatherModelFromJson(json); +// Map toJson() => _$WeatherModelToJson(this); +// } + +// class WeatherModelController extends GetControllerEx { +// LanguageController languageController = Get.find(); +// WeatherModelController() { +// attr = GetModel(WeatherModel()).obs; +// weatherFactory = WeatherFactory(CommonVariables.weather_apiKey, +// language: Language.CHINESE_SIMPLIFIED); +// } + +// Timer? _timer; + +// late WeatherFactory weatherFactory; + +// @override +// Future onInit() async { +// super.onInit(); +// await _getCurrentLocationAndWeather(); +// // 启动定时器,每5秒执行一次 getCurrentWeather 方法 +// _timer = Timer.periodic(Duration(seconds: 5), (timer) { +// _getCurrentLocationAndWeather(); +// }); +// } + +// @override +// void onClose() { +// // 取消定时器 +// _timer?.cancel(); +// super.onClose(); +// } + +// Future _getCurrentLocationAndWeather() async { +// try { +// Position position = await _determinePosition(); + +// String? language = "zh_CN"; +// if (languageController.selectLanguage != null) { +// language = languageController.selectLanguage.value!.language_code; +// } +// List placemarks = await placemarkFromCoordinates( +// position.latitude, position.longitude, +// localeIdentifier: "${language}"); +// if (placemarks.isNotEmpty) { +// model.cityName = placemarks[0].locality ?? "未知数据".tr; +// } +// getCurrentWeather(position.latitude, position.longitude); +// } catch (e) { +// print(e); +// EasyDartModule.logger.error("获取位置和天气失败: $e"); +// } +// } + +// Future _determinePosition() async { +// bool serviceEnabled; +// LocationPermission permission; + +// // 检查位置服务是否启用 +// serviceEnabled = await Geolocator.isLocationServiceEnabled(); +// if (!serviceEnabled) { +// // 位置服务未启用,返回默认位置 +// return Future.error('Location services are disabled.'); +// } + +// permission = await Geolocator.checkPermission(); +// if (permission == LocationPermission.denied) { +// permission = await Geolocator.requestPermission(); +// if (permission == LocationPermission.denied) { +// // 权限被拒绝,返回默认位置 +// return Future.error('Location permissions are denied'); +// } +// } + +// if (permission == LocationPermission.deniedForever) { +// // 权限被永久拒绝,返回默认位置 +// return Future.error( +// 'Location permissions are permanently denied, we cannot request permissions.'); +// } + +// // 获取当前位置 +// return await Geolocator.getCurrentPosition(); +// } + +// Future getCurrentWeather( +// double latitude, +// double longitude, +// ) async { +// try { +// weatherFactory.language = Language.CHINESE_SIMPLIFIED; +// String? language = "zh_CN"; +// if (languageController.selectLanguage != null) { +// language = languageController.selectLanguage.value!.language_code; +// } +// if (language == "zh_CN") { +// weatherFactory.language = Language.CHINESE_SIMPLIFIED; +// } else { +// weatherFactory.language = Language.ENGLISH; +// } +// Weather weather = +// await weatherFactory.currentWeatherByLocation(latitude, longitude); +// model.weather_info = weather.weatherDescription; +// model.min_temperature = weather.tempMin?.celsius?.toInt(); +// model.max_temperature = weather.tempMax?.celsius?.toInt(); +// model.current_temperature = weather.temperature?.celsius?.toInt(); +// model.wind_speed = weather.windSpeed?.toInt(); +// model.weatherIcon = weather.weatherIcon; +// if (model.weatherIcon != null) { +// model.weatherIconurl = +// "https://openweathermap.org/img/w/${model.weatherIcon}.png"; +// } + +// // model.wind_direction = getDirectionByDegree(weather.windDegree); +// updateAll(); +// return weather; +// } catch (e) { +// print('Error: $e'); +// rethrow; +// } +// } + +// Future> getWeatherForecast( +// double latitude, double longitude) async { +// try { +// return await weatherFactory.fiveDayForecastByLocation( +// latitude, longitude); +// } catch (e) { +// print('Error: $e'); +// rethrow; +// } +// } + +// String? getDirectionByDegree(double? windDegree) { +// if (windDegree == null) return null; + +// if (windDegree >= 337.5 || windDegree < 22.5) { +// return '主页.天气.方向.北'.tr + '主页.天气.方向.单位'.tr; +// } else if (windDegree >= 22.5 && windDegree < 67.5) { +// return '主页.天气.方向.东北'.tr + '主页.天气.方向.单位'.tr; +// } else if (windDegree >= 67.5 && windDegree < 112.5) { +// return '主页.天气.方向.东'.tr + '主页.天气.方向.单位'.tr; +// } else if (windDegree >= 112.5 && windDegree < 157.5) { +// return '主页.天气.方向.东南'.tr + '主页.天气.方向.单位'.tr; +// } else if (windDegree >= 157.5 && windDegree < 202.5) { +// return '主页.天气.方向.南'.tr + '主页.天气.方向.单位'.tr; +// } else if (windDegree >= 202.5 && windDegree < 247.5) { +// return '主页.天气.方向.西南'.tr + '主页.天气.方向.单位'.tr; +// } else if (windDegree >= 247.5 && windDegree < 292.5) { +// return '主页.天气.方向.西'.tr + '主页.天气.方向.单位'.tr; +// } else if (windDegree >= 292.5 && windDegree < 337.5) { +// return '主页.天气.方向.西北'.tr + '主页.天气.方向.单位'.tr; +// } else { +// return null; +// } +// } +// } + +import 'dart:async'; + +import 'package:EasyDartModule/EasyDartModule.dart'; +import 'package:ef/ef.dart'; +import 'package:geocoding/geocoding.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:vbvs_app/common/util/CommonVariables.dart'; +import 'package:vbvs_app/controller/setting/language/language_controller.dart'; +import 'package:weather/weather.dart'; + +part 'weather_controller.g.dart'; + +@JsonSerializable() +class WeatherModel { + double? longitude; // 经度 + double? latitude; // 纬度 + String? weather_info = ''; // 天气 + int? current_temperature; // 温度 + int? min_temperature; // 最低温度 + int? max_temperature; // 最高温度 + String? wind_direction; // 风向 + int? wind_speed; // 风速等级 + String? cityName; // 城市名 + String? weatherIcon; // 天气图标 + String? weatherIconurl; // 天气图标url + + WeatherModel(); + + static WeatherModel fromJson(Map json) => + _$WeatherModelFromJson(json); + + Map toJson() => _$WeatherModelToJson(this); +} + +class WeatherModelController extends GetControllerEx { + LanguageController languageController = Get.find(); + WeatherModelController() { + attr = GetModel(WeatherModel()).obs; + weatherFactory = WeatherFactory(CommonVariables.weather_apiKey, + language: Language.CHINESE_SIMPLIFIED); + } + + Timer? _weatherTimer; + Timer? _locationTimer; + + late WeatherFactory weatherFactory; + + @override + Future onInit() async { + super.onInit(); + await _getCurrentLocation(); + _weatherTimer = Timer.periodic(Duration(seconds: 5), (timer) { + _getCurrentWeather(); // 每 5 秒更新一次天气 + }); + + _locationTimer = Timer.periodic(Duration(minutes: 10), (timer) { + _getCurrentLocation(); // 每 10 分钟更新一次位置 + }); + } + + @override + void onClose() { + _weatherTimer?.cancel(); // 取消天气更新定时器 + _locationTimer?.cancel(); // 取消位置更新定时器 + super.onClose(); + } + + // 获取当前位置并存储到 model + Future _getCurrentLocation() async { + try { + Position position = await _determinePosition(); + + String? language = "zh_CN"; + if (languageController.selectLanguage != null) { + language = languageController.selectLanguage.value!.language_code; + } + List placemarks = await placemarkFromCoordinates( + position.latitude, position.longitude, + localeIdentifier: language); + + if (placemarks.isNotEmpty) { + model.cityName = placemarks[0].locality ?? "未知数据".tr; + model.latitude = position.latitude; + model.longitude = position.longitude; + } + + // 调用获取天气方法 + _getCurrentWeather(); + } catch (e) { + print(e); + EasyDartModule.logger.error("获取位置失败: $e"); + } + } + + // 获取当前位置 + Future _determinePosition() async { + bool serviceEnabled; + LocationPermission permission; + + serviceEnabled = await Geolocator.isLocationServiceEnabled(); + if (!serviceEnabled) { + return Future.error('位置服务未启用'); + } + + permission = await Geolocator.checkPermission(); + if (permission == LocationPermission.denied) { + permission = await Geolocator.requestPermission(); + if (permission == LocationPermission.denied) { + return Future.error('位置权限被拒绝'); + } + } + + if (permission == LocationPermission.deniedForever) { + return Future.error('位置权限被永久拒绝'); + } + + return await Geolocator.getCurrentPosition(); + } + + // 获取天气信息 + Future _getCurrentWeather() async { + if (model.latitude == null || model.longitude == null) { + return; // 如果位置数据没有获取到,则不更新天气 + } + String? language = "zh_CN"; + if (languageController.selectLanguage != null) { + language = languageController.selectLanguage.value!.language_code; + } + List placemarks = await placemarkFromCoordinates( + model.latitude!, model.longitude!, + localeIdentifier: language); + + if (placemarks.isNotEmpty) { + model.cityName = placemarks[0].locality ?? "未知数据".tr; + } + + try { + weatherFactory.language = Language.CHINESE_SIMPLIFIED; + String? language = "zh_CN"; + if (languageController.selectLanguage != null) { + language = languageController.selectLanguage.value!.language_code; + } + if (language == "zh_CN") { + weatherFactory.language = Language.CHINESE_SIMPLIFIED; + } else { + weatherFactory.language = Language.ENGLISH; + } + Weather weather = await weatherFactory.currentWeatherByLocation( + model.latitude!, model.longitude!); + + model.weather_info = weather.weatherDescription; + model.min_temperature = weather.tempMin?.celsius?.toInt(); + model.max_temperature = weather.tempMax?.celsius?.toInt(); + model.current_temperature = weather.temperature?.celsius?.toInt(); + model.wind_speed = weather.windSpeed?.toInt(); + model.weatherIcon = weather.weatherIcon; + + if (model.weatherIcon != null) { + model.weatherIconurl = + "https://openweathermap.org/img/w/${model.weatherIcon}.png"; + } + + updateAll(); // 更新 UI + } catch (e) { + print('获取天气失败: $e'); + } + } + + // 获取 5 天天气预报 + Future> getWeatherForecast( + double latitude, double longitude) async { + try { + return await weatherFactory.fiveDayForecastByLocation( + latitude, longitude); + } catch (e) { + print('获取天气预报失败: $e'); + rethrow; + } + } +} diff --git a/lib/controller/weather/weather_controller.g.dart b/lib/controller/weather/weather_controller.g.dart new file mode 100644 index 0000000..7920345 --- /dev/null +++ b/lib/controller/weather/weather_controller.g.dart @@ -0,0 +1,31 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'weather_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +WeatherModel _$WeatherModelFromJson(Map json) => WeatherModel() + ..longitude = (json['longitude'] as num?)?.toDouble() + ..latitude = (json['latitude'] as num?)?.toDouble() + ..weather_info = json['weather_info'] as String? + ..current_temperature = (json['current_temperature'] as num?)?.toInt() + ..min_temperature = (json['min_temperature'] as num?)?.toInt() + ..max_temperature = (json['max_temperature'] as num?)?.toInt() + ..wind_direction = json['wind_direction'] as String? + ..wind_speed = (json['wind_speed'] as num?)?.toInt() + ..cityName = json['cityName'] as String?; + +Map _$WeatherModelToJson(WeatherModel instance) => + { + 'longitude': instance.longitude, + 'latitude': instance.latitude, + 'weather_info': instance.weather_info, + 'current_temperature': instance.current_temperature, + 'min_temperature': instance.min_temperature, + 'max_temperature': instance.max_temperature, + 'wind_direction': instance.wind_direction, + 'wind_speed': instance.wind_speed, + 'cityName': instance.cityName, + }; diff --git a/lib/pages/device_bind/bind_device_success.dart b/lib/pages/device_bind/bind_device_success.dart index 5846a94..f9a65b1 100644 --- a/lib/pages/device_bind/bind_device_success.dart +++ b/lib/pages/device_bind/bind_device_success.dart @@ -4,7 +4,6 @@ import 'package:flutter_svg/svg.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/util/FitTool.dart'; -import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/CustomCard.dart'; import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart'; diff --git a/lib/pages/main_bottom/home_page.dart b/lib/pages/main_bottom/home_page.dart index 0bad425..26a0229 100644 --- a/lib/pages/main_bottom/home_page.dart +++ b/lib/pages/main_bottom/home_page.dart @@ -304,15 +304,63 @@ class _HomePageState extends State { ), ), Obx(() { - return Text( - "嘉兴 " + - "${weatherModelController.model.weather_info ?? '未知数据'.tr}", - style: TextStyle( - color: themeController - .currentColor.sc4, - fontSize: AppConstants() - .normal_text_fontSize, - ), + return Row( + children: [ + Text( + "${weatherModelController.model.cityName??'未知数据'.tr}", + style: TextStyle( + color: themeController + .currentColor.sc4, + fontSize: AppConstants() + .normal_text_fontSize, + ), + ), + Text( + "${(weatherModelController.model.current_temperature != null && weatherModelController.model.current_temperature! > 0) ? weatherModelController.model.current_temperature : '未知数据'.tr}" + + "°C", + style: TextStyle( + color: themeController + .currentColor.sc4, + fontSize: AppConstants() + .normal_text_fontSize, + ), + ), + Text( + "${(weatherModelController.model.weather_info?.isNotEmpty ?? false) ? weatherModelController.model.weather_info : '未知数据'.tr}", + style: TextStyle( + color: themeController + .currentColor.sc4, + fontSize: AppConstants() + .normal_text_fontSize, + ), + ), + if (weatherModelController + .model + .weatherIconurl != + null && + weatherModelController + .model + .weatherIconurl! + .isNotEmpty) + Container( + width: 35.rpx, + height: 26.rpx, + clipBehavior: + Clip.antiAlias, + decoration: + BoxDecoration( + shape: BoxShape + .circle), + child: Image.network( + weatherModelController + .model + .weatherIconurl!, + fit: BoxFit.cover, + ), + ), + ].divide(SizedBox( + width: 20.rpx, + )), ); }), ], diff --git a/lib/pages/main_bottom/message_page.dart b/lib/pages/main_bottom/message_page.dart index 445ae72..a1f7e71 100644 --- a/lib/pages/main_bottom/message_page.dart +++ b/lib/pages/main_bottom/message_page.dart @@ -102,138 +102,298 @@ class _MessagePageState extends State { child: Column( children: [ SizedBox(height: 40.rpx), + // Expanded( + // child: Stack( + // alignment: Alignment.bottomLeft, + // children: [ + // Row( + // mainAxisAlignment: MainAxisAlignment.start, + // children: [ + // Obx(() { + // return ClickableContainer( + // padding: EdgeInsets.all(0), + // backgroundColor: Colors.transparent, + // highlightColor: + // themeController.currentColor.sc21, + // borderRadius: 8.rpx, + // onTap: () => _onTabChanged(0), + // child: Container( + // width: 160.rpx, + // alignment: Alignment.center, + // child: Stack( + // alignment: Alignment.center, + // clipBehavior: Clip.none, + // children: [ + // Text( + // '体征消息'.tr, + // style: FlutterFlowTheme.of(context) + // .bodyMedium + // .override( + // fontFamily: 'Inter', + // fontSize: AppConstants() + // .title_text_fontSize, + // color: + // messageController + // .model.type == + // 2 + // ? themeController + // .currentColor.sc3 + // : themeController + // .currentColor.sc2, + // ), + // ), + // Obx(() { + // return messageController.model + // .body_message_read == + // 1 + // ? Positioned( + // top: -4, + // right: -14, + // child: Container( + // width: 8, + // height: 8, + // decoration: + // const BoxDecoration( + // color: Colors.red, + // shape: BoxShape.circle, + // ), + // ), + // ) + // : const SizedBox.shrink(); + // }), + // ], + // ), + // ), + // ); + // }), + // Obx(() { + // return ClickableContainer( + // padding: EdgeInsets.all(0), + // backgroundColor: Colors.transparent, + // highlightColor: + // themeController.currentColor.sc21, + // borderRadius: 8.rpx, + // onTap: () => _onTabChanged(1), + // child: Container( + // width: 160.rpx, + // alignment: Alignment.center, + // child: Stack( + // alignment: Alignment.center, + // clipBehavior: Clip.none, + // children: [ + // Text( + // '系统消息'.tr, + // style: FlutterFlowTheme.of(context) + // .bodyMedium + // .override( + // fontFamily: 'Inter', + // fontSize: AppConstants() + // .title_text_fontSize, + // color: + // messageController + // .model.type == + // 1 + // ? themeController + // .currentColor.sc3 + // : themeController + // .currentColor.sc2, + // ), + // ), + // Obx(() { + // return messageController.model + // .system_message_read == + // 1 + // ? Positioned( + // top: -4, + // right: -14, + // child: Container( + // width: 8, + // height: 8, + // decoration: + // const BoxDecoration( + // color: Colors.red, + // shape: BoxShape.circle, + // ), + // ), + // ) + // : const SizedBox.shrink(); + // }), + // ], + // ), + // ), + // ); + // }), + // ].divide(SizedBox(width: 10.rpx)), + // ), + // Obx(() { + // double lineWidth = 170.rpx; + // return AnimatedPositioned( + // duration: const Duration(milliseconds: 300), + // curve: Curves.easeInOut, + // bottom: 0, + // left: messageController.model.type == 1 + // ? 0 + // : 170.rpx, + // child: Container( + // width: lineWidth, + // height: 4.rpx, + // decoration: BoxDecoration( + // color: themeController.currentColor.sc2, + // borderRadius: BorderRadius.circular(2.rpx), + // ), + // ), + // ); + // }), + // ], + // ), + // ), + Expanded( child: Stack( alignment: Alignment.bottomLeft, children: [ Row( - mainAxisAlignment: MainAxisAlignment.start, children: [ + // 第一个容器,宽度占屏幕一半 Obx(() { - return ClickableContainer( - padding: EdgeInsets.all(0), - backgroundColor: Colors.transparent, - highlightColor: - themeController.currentColor.sc21, - borderRadius: 8.rpx, - onTap: () => _onTabChanged(0), - child: Container( - width: 160.rpx, - alignment: Alignment.center, - child: Stack( + return Expanded( + child: ClickableContainer( + padding: EdgeInsets.all(0), + backgroundColor: Colors.transparent, + highlightColor: + themeController.currentColor.sc21, + borderRadius: 8.rpx, + onTap: () => _onTabChanged(0), + child: Container( alignment: Alignment.center, - clipBehavior: Clip.none, - children: [ - Text( - '体征消息'.tr, - style: FlutterFlowTheme.of(context) - .bodyMedium - .override( - fontFamily: 'Inter', - fontSize: AppConstants() - .title_text_fontSize, - color: - messageController - .model.type == - 2 - ? themeController - .currentColor.sc3 - : themeController - .currentColor.sc2, - ), - ), - Obx(() { - return messageController.model - .body_message_read == - 1 - ? Positioned( - top: -4, - right: -14, - child: Container( - width: 8, - height: 8, - decoration: - const BoxDecoration( - color: Colors.red, - shape: BoxShape.circle, + child: Stack( + alignment: Alignment.center, + clipBehavior: Clip.none, + children: [ + Text( + '体征消息'.tr, + style: + FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Inter', + fontSize: AppConstants() + .title_text_fontSize, + color: messageController + .model.type == + 2 + ? themeController + .currentColor + .sc3 + : themeController + .currentColor + .sc2, ), - ), - ) - : const SizedBox.shrink(); - }), - ], + ), + Obx(() { + return messageController.model + .body_message_read == + 1 + ? Positioned( + top: -4, + right: -14, + child: Container( + width: 8, + height: 8, + decoration: + const BoxDecoration( + color: Colors.red, + shape: + BoxShape.circle, + ), + ), + ) + : const SizedBox.shrink(); + }), + ], + ), ), ), ); }), + SizedBox(width: 10.rpx), + // 第二个容器,宽度占屏幕一半 Obx(() { - return ClickableContainer( - padding: EdgeInsets.all(0), - backgroundColor: Colors.transparent, - highlightColor: - themeController.currentColor.sc21, - borderRadius: 8.rpx, - onTap: () => _onTabChanged(1), - child: Container( - width: 160.rpx, - alignment: Alignment.center, - child: Stack( + return Expanded( + child: ClickableContainer( + padding: EdgeInsets.all(0), + backgroundColor: Colors.transparent, + highlightColor: + themeController.currentColor.sc21, + borderRadius: 8.rpx, + onTap: () => _onTabChanged(1), + child: Container( alignment: Alignment.center, - clipBehavior: Clip.none, - children: [ - Text( - '系统消息'.tr, - style: FlutterFlowTheme.of(context) - .bodyMedium - .override( - fontFamily: 'Inter', - fontSize: AppConstants() - .title_text_fontSize, - color: - messageController - .model.type == - 1 - ? themeController - .currentColor.sc3 - : themeController - .currentColor.sc2, - ), - ), - Obx(() { - return messageController.model - .system_message_read == - 1 - ? Positioned( - top: -4, - right: -14, - child: Container( - width: 8, - height: 8, - decoration: - const BoxDecoration( - color: Colors.red, - shape: BoxShape.circle, + child: Stack( + alignment: Alignment.center, + clipBehavior: Clip.none, + children: [ + Text( + '系统消息'.tr, + style: + FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Inter', + fontSize: AppConstants() + .title_text_fontSize, + color: messageController + .model.type == + 1 + ? themeController + .currentColor + .sc3 + : themeController + .currentColor + .sc2, ), - ), - ) - : const SizedBox.shrink(); - }), - ], + ), + Obx(() { + return messageController.model + .system_message_read == + 1 + ? Positioned( + top: -4, + right: -14, + child: Container( + width: 8, + height: 8, + decoration: + const BoxDecoration( + color: Colors.red, + shape: + BoxShape.circle, + ), + ), + ) + : const SizedBox.shrink(); + }), + ], + ), ), ), ); }), - ].divide(SizedBox(width: 10.rpx)), + ], ), + // 动画线 Obx(() { - double lineWidth = 170.rpx; + double lineWidth = + MediaQuery.sizeOf(context).width * 0.5 - + 20.rpx; // 每个容器占宽度的一半 return AnimatedPositioned( duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, bottom: 0, left: messageController.model.type == 1 ? 0 - : 170.rpx, + : MediaQuery.sizeOf(context).width * 0.5 + + 10.rpx, // 动态设置左侧位置 child: Container( width: lineWidth, height: 4.rpx, diff --git a/lib/pages/repair/apply_repair_page.dart b/lib/pages/repair/apply_repair_page.dart index fd88988..ffaddcd 100644 --- a/lib/pages/repair/apply_repair_page.dart +++ b/lib/pages/repair/apply_repair_page.dart @@ -436,6 +436,7 @@ class _ApplyRepairPageState extends State { hintStyle: TextStyle( letterSpacing: 0.0, fontSize: AppConstants().normal_text_fontSize, + color: themeController.currentColor.sc4, ), enabledBorder: OutlineInputBorder( borderSide: BorderSide( @@ -477,6 +478,7 @@ class _ApplyRepairPageState extends State { cursorColor: themeController.currentColor.sc3, onChanged: onChanged, ), + ), ), ].divide(SizedBox(width: 24.rpx)), diff --git a/lib/pages/sleep_report/chart/AdviceComponnetWidget.dart b/lib/pages/sleep_report/chart/AdviceComponnetWidget.dart new file mode 100644 index 0000000..1542737 --- /dev/null +++ b/lib/pages/sleep_report/chart/AdviceComponnetWidget.dart @@ -0,0 +1,119 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; + +class AdviceComponnetWidget extends StatefulWidget { + final String title; // 建议标题 + final String description; // 建议说明 + + const AdviceComponnetWidget({ + super.key, + required this.title, + required this.description, + }); + + @override + State createState() => _AdviceComponnetWidgetState(); +} + +class _AdviceComponnetWidgetState extends State { + @override + void setState(VoidCallback callback) { + super.setState(callback); + } + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + decoration: BoxDecoration(), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + // 显示标题 + Container( + width: double.infinity, + decoration: BoxDecoration( + color: stringToColor("#313541"), + borderRadius: BorderRadius.circular(20.rpx), + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 28.rpx, 30.rpx, 28.rpx, 30.rpx), + child: Container( + width: double.infinity, + decoration: BoxDecoration(), + child: Text( + widget.title, // 使用传入的标题 + style: TextStyle( + color: themeController.currentColor.sc3, + ), + ), + ), + ), + ), + // 显示描述 + Container( + width: double.infinity, + decoration: BoxDecoration(), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 28.rpx, 30.rpx, 28.rpx, 30.rpx), + child: Container( + width: double.infinity, + decoration: BoxDecoration(), + child: RichText( + text: TextSpan( + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: 26.rpx, // 设置文字大小 + height: 1.3, // 设置行高,控制文字上下间距 + ), + children: [ + WidgetSpan( + alignment: PlaceholderAlignment.middle, // 图标和文字垂直居中 + child: Padding( + padding: EdgeInsets.only( + bottom: 4.rpx, // 调整底部间距 + right: 10.rpx, // 适当调整图标右边距 + top: 4.rpx, // 增加顶部间距 + ), + child: SvgPicture.asset( + 'assets/img/icon/ai.svg', // 替换为你的 SVG 文件路径 + width: 37.rpx, // 设置适中的 SVG 图标大小 + height: 31.rpx, // 使图标和文字大小一致 + color: + themeController.currentColor.sc2, // 设置 SVG 颜色 + ), + ), + ), + TextSpan( + text: widget.description, // 使用传入的描述 + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: AppConstants().normal_text_fontSize, // 文字大小 + ), + ), + ], + ), + ), + ), + ), + ) + ], + ), + ); + } +} diff --git a/lib/pages/sleep_report/chart/DataShowWidget.dart b/lib/pages/sleep_report/chart/DataShowWidget.dart new file mode 100644 index 0000000..c55b465 --- /dev/null +++ b/lib/pages/sleep_report/chart/DataShowWidget.dart @@ -0,0 +1,108 @@ +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; + +class DataShowWidget extends StatefulWidget { + final Widget widget1; // 第一个传入的 widget + final Widget widget2; // 第二个传入的 widget + final Widget widget3; // 第三个传入的 widget + final Widget widget4; // 第四个传入的 widget + final MainAxisAlignment alignment; // 控制 Row 的对齐方式 + + const DataShowWidget({ + super.key, + required this.widget1, + required this.widget2, + required this.widget3, + required this.widget4, + this.alignment = MainAxisAlignment.start, // 默认左对齐 + }); + + @override + State createState() => _DataShowWidgetState(); +} + +class _DataShowWidgetState extends State { + @override + void setState(VoidCallback callback) { + super.setState(callback); + } + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: 66.rpx, + decoration: BoxDecoration(), + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, // 设置横向滚动 + child: Row( + mainAxisAlignment: widget.alignment, // 根据传入的 alignment 控制对齐方式 + children: [ + // 放入传入的 widget1 + Container( + width: MediaQuery.sizeOf(context).width * 0.4, // 固定宽度 + decoration: BoxDecoration(), + child: Align( + alignment: widget.alignment == MainAxisAlignment.start + ? Alignment.centerLeft + : widget.alignment == MainAxisAlignment.center + ? Alignment.center + : Alignment.centerRight, // 根据传入的 alignment 设置对齐 + child: widget.widget1, // 显示传入的 widget1 + ), + ), + // 放入传入的 widget2 + Container( + width: MediaQuery.sizeOf(context).width * 0.15, // 固定宽度 + decoration: BoxDecoration(), + child: Align( + alignment: widget.alignment == MainAxisAlignment.start + ? Alignment.centerLeft + : widget.alignment == MainAxisAlignment.center + ? Alignment.center + : Alignment.centerRight, // 同样设置对齐 + child: widget.widget2, // 显示传入的 widget2 + ), + ), + // 放入传入的 widget3 + Container( + width: MediaQuery.sizeOf(context).width * 0.2, // 固定宽度 + decoration: BoxDecoration(), + child: Align( + alignment: widget.alignment == MainAxisAlignment.start + ? Alignment.centerLeft + : widget.alignment == MainAxisAlignment.center + ? Alignment.center + : Alignment.centerRight, // 同样设置对齐 + child: widget.widget3, // 显示传入的 widget3 + ), + ), + // 放入传入的 widget4 + Container( + width: MediaQuery.sizeOf(context).width * 0.15, // 固定宽度 + decoration: BoxDecoration(), + child: Align( + alignment: widget.alignment == MainAxisAlignment.start + ? Alignment.centerLeft + : widget.alignment == MainAxisAlignment.center + ? Alignment.center + : Alignment.centerRight, // 同样设置对齐 + child: widget.widget4, // 显示传入的 widget4 + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/sleep_report/chart/HorizontalBarChart.dart b/lib/pages/sleep_report/chart/HorizontalBarChart.dart index 4cb75d9..a36ba1c 100644 --- a/lib/pages/sleep_report/chart/HorizontalBarChart.dart +++ b/lib/pages/sleep_report/chart/HorizontalBarChart.dart @@ -204,7 +204,7 @@ class SingleBarPainter extends CustomPainter { TextStyle(color: themeController.currentColor.sc3, fontSize: 26.rpx); final textPainter = TextPainter(textDirection: TextDirection.ltr); textPainter.text = - TextSpan(text: '${value.toStringAsFixed(0)}%', style: textStyle); + TextSpan(text: '${value.toStringAsFixed(0)}', style: textStyle); textPainter.layout(); canvas.save(); canvas.clipRect(Rect.fromLTWH( diff --git a/lib/pages/sleep_report/chart/LineChart.dart b/lib/pages/sleep_report/chart/LineChart.dart new file mode 100644 index 0000000..4c204bc --- /dev/null +++ b/lib/pages/sleep_report/chart/LineChart.dart @@ -0,0 +1,158 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'dart:ui' as ui; + +class LineChart extends StatelessWidget { + final int startTime; + final int endTime; + final double minValue; + final double maxValue; + final List> dataPoints; + + LineChart({ + required this.startTime, + required this.endTime, + required this.minValue, + required this.maxValue, + required this.dataPoints, + }); + + @override + Widget build(BuildContext context) { + return CustomPaint( + size: Size(double.infinity, 300), + painter: LineChartPainter( + startTime: startTime, + endTime: endTime, + minValue: minValue, + maxValue: maxValue, + dataPoints: dataPoints, + ), + ); + } +} + +class LineChartPainter extends CustomPainter { + final int startTime; + final int endTime; + final double minValue; + final double maxValue; + final List> dataPoints; + + LineChartPainter({ + required this.startTime, + required this.endTime, + required this.minValue, + required this.maxValue, + required this.dataPoints, + }); + + @override + void paint(Canvas canvas, Size size) { + Paint paint = Paint()..style = PaintingStyle.stroke; + double chartWidth = size.width; + double chartHeight = size.height; + + // 时间轴刻度设置 + DateFormat timeFormatStartEnd = DateFormat('HH:mm'); + DateFormat timeFormatMiddle = DateFormat('h'); + + // 绘制Y轴刻度 + double yAxisHeight = chartHeight - 40; // 留一些空间给X轴 + double yAxisStep = yAxisHeight / 4; + paint.color = Colors.grey; + paint.strokeWidth = 1; + canvas.drawLine(Offset(30, 0), Offset(30, chartHeight), paint); // Y轴 + + // 绘制Y轴的刻度线 + paint.color = Colors.grey; + for (int i = 0; i < 5; i++) { + double y = i * yAxisStep; + if (i == 0) { + paint.color = Colors.grey; // 0线 + canvas.drawLine(Offset(25, y), Offset(35, y), paint); + } else if (i == 1) { + paint.color = Colors.red; // 最小值线 + paint.style = PaintingStyle.stroke; + paint.strokeWidth = 1; + canvas.drawLine(Offset(25, y), Offset(35, y), paint); + } else if (i == 2) { + paint.color = Colors.grey; // 最大值与最小值中间线 + paint.style = PaintingStyle.stroke; + paint.strokeWidth = 1; + _drawDashedLine(canvas, paint, 25, y, 35, y); // Custom dashed line + } else { + paint.color = Colors.red; // 最大值线 + canvas.drawLine(Offset(25, y), Offset(35, y), paint); + } + } + + // 绘制X轴时间刻度 + DateTime startDate = DateTime.fromMillisecondsSinceEpoch(startTime); + DateTime endDate = DateTime.fromMillisecondsSinceEpoch(endTime); + double xAxisStep = (chartWidth - 60) / + (endDate.millisecondsSinceEpoch - startDate.millisecondsSinceEpoch); + + for (DateTime date = startDate; + date.isBefore(endDate); + date = date.add(Duration(hours: 1))) { + String timeLabel = (date == startDate || date == endDate) + ? timeFormatStartEnd.format(date) + : timeFormatMiddle.format(date); + paint.color = Colors.black; + + // Draw text using TextPainter + _drawText( + canvas, timeLabel, Offset(30, yAxisHeight)); // Position dynamically + } + + // 绘制折线图数据点 + Path path = Path(); + for (var i = 0; i < dataPoints.length; i++) { + var point = dataPoints[i]; + DateTime pointTime = DateTime.fromMillisecondsSinceEpoch(point['time']); + double x = (pointTime.millisecondsSinceEpoch - + startDate.millisecondsSinceEpoch) * + xAxisStep + + 30; + double y = chartHeight - + (point['value'] - minValue) * yAxisHeight / (maxValue - minValue); + path.lineTo(x, y); + } + + paint.color = Colors.green; // Line color based on range + paint.strokeWidth = 2; + canvas.drawPath(path, paint); + } + + // Custom method to draw dashed line + void _drawDashedLine(Canvas canvas, Paint paint, double startX, double startY, + double endX, double endY) { + double dashWidth = 5; + double dashSpace = 3; + double distance = (endX - startX).abs(); + double dashCount = (distance / (dashWidth + dashSpace)).floorToDouble(); + for (int i = 0; i < dashCount; i++) { + double startXDash = startX + (i * (dashWidth + dashSpace)); + double endXDash = startXDash + dashWidth; + canvas.drawLine( + Offset(startXDash, startY), Offset(endXDash, endY), paint); + } + } + + // Custom method to draw text + void _drawText(Canvas canvas, String text, Offset offset) { + TextPainter textPainter = TextPainter( + text: TextSpan( + text: text, style: TextStyle(color: Colors.black, fontSize: 12)), + textDirection: ui.TextDirection.ltr, + )..layout(); + + textPainter.paint(canvas, offset); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) { + return false; + } +} diff --git a/lib/pages/sleep_report/chart/LineChartByRange.dart b/lib/pages/sleep_report/chart/LineChartByRange.dart index b2e341b..024e608 100644 --- a/lib/pages/sleep_report/chart/LineChartByRange.dart +++ b/lib/pages/sleep_report/chart/LineChartByRange.dart @@ -154,19 +154,19 @@ class _LineChartByRangePainter extends CustomPainter { int totalHours = maxTime.difference(minTime).inHours; int startHour = minTime.hour; - for (int i = 1; i < totalHours; i++) { - double x = xStart + chartWidth * i / totalHours; + // for (int i = 1; i < totalHours; i++) { + // double x = xStart + chartWidth * i / totalHours; - // 垂直虚线 - drawDashedLine( - canvas, - Offset(x, 0), - Offset(x, chartHeight), - axisPaint, - dashWidth: 4.rpx, - dashSpace: 4.rpx, - ); - } + // // 垂直虚线 + // drawDashedLine( + // canvas, + // Offset(x, 0), + // Offset(x, chartHeight), + // axisPaint, + // dashWidth: 4.rpx, + // dashSpace: 4.rpx, + // ); + // } // 5. 画左侧完整时分 (HH:mm),往内缩 labelInset String leftLabel = DateFormat('HH:mm').format(minTime); diff --git a/lib/pages/sleep_report/chart/RadarChart.dart b/lib/pages/sleep_report/chart/RadarChart.dart new file mode 100644 index 0000000..41d110f --- /dev/null +++ b/lib/pages/sleep_report/chart/RadarChart.dart @@ -0,0 +1,109 @@ +import 'package:flutter/material.dart'; +import 'dart:ui' as ui; +import 'dart:math'; + +class RadarChart extends StatelessWidget { + final List> data; // 存储多个数据集 + final List labels; // 每个角的标签 + final double maxValue; // 数据的最大值,用来统一尺度 + + const RadarChart({ + Key? key, + required this.data, + required this.labels, + this.maxValue = 100, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return CustomPaint( + size: Size(300, 300), // 图表的大小 + painter: RadarChartPainter( + data: data, + labels: labels, + maxValue: maxValue, + ), + ); + } +} + +class RadarChartPainter extends CustomPainter { + final List> data; + final List labels; + final double maxValue; + + RadarChartPainter({ + required this.data, + required this.labels, + required this.maxValue, + }); + + @override + void paint(Canvas canvas, Size size) { + Paint paintLine = Paint() + ..color = Colors.blue + ..style = PaintingStyle.stroke + ..strokeWidth = 2; + + Paint axisPaint = Paint() + ..color = Colors.grey.withOpacity(0.5) + ..strokeWidth = 1; + + double centerX = size.width / 2; + double centerY = size.height / 2; + double radius = size.width / 2; + + int numOfPoints = labels.length; + + // 绘制雷达图的轴线 + for (int i = 0; i < numOfPoints; i++) { + double angle = (2 * pi / numOfPoints) * i; + double x = centerX + radius * cos(angle); + double y = centerY + radius * sin(angle); + + // 画轴线 + canvas.drawLine(Offset(centerX, centerY), Offset(x, y), axisPaint); + + // 绘制标签 + TextPainter tp = TextPainter( + text: TextSpan( + text: labels[i], + style: TextStyle(color: Colors.black, fontSize: 12), + ), + textDirection: ui.TextDirection.ltr, + ); + tp.layout(); + tp.paint(canvas, Offset(x + 8, y - 8)); // 设置标签位置 + } + + // 绘制多个数据集 + for (int i = 0; i < data.length; i++) { + Paint fillPaint = Paint() + ..color = Colors.primaries[i % Colors.primaries.length].withOpacity(0.3) + ..style = PaintingStyle.fill; + + Paint linePaint = Paint() + ..color = Colors.primaries[i % Colors.primaries.length] + ..style = PaintingStyle.stroke + ..strokeWidth = 2; + + List points = []; + for (int j = 0; j < numOfPoints; j++) { + double angle = (2 * pi / numOfPoints) * j; + double pointRadius = (data[i][j] / maxValue) * radius; + double x = centerX + pointRadius * cos(angle); + double y = centerY + pointRadius * sin(angle); + + points.add(Offset(x, y)); + } + + // 画出数据连接线 + Path path = Path()..addPolygon(points, true); + canvas.drawPath(path, linePaint); + canvas.drawPath(path, fillPaint); + } + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) => true; +} diff --git a/lib/pages/sleep_report/chart/ScatterPlotChart.dart b/lib/pages/sleep_report/chart/ScatterPlotChart.dart new file mode 100644 index 0000000..c16d98d --- /dev/null +++ b/lib/pages/sleep_report/chart/ScatterPlotChart.dart @@ -0,0 +1,118 @@ +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; + +class ScatterPlotChart extends StatelessWidget { + final List points; + final int xMax; + final int yMax; + final Color pointColor; + final int divisions; + + ScatterPlotChart({ + required this.points, + required this.xMax, + required this.yMax, + required this.pointColor, + required this.divisions, + }); + + @override + Widget build(BuildContext context) { + // 计算向上取整后的最大值 + double xMaxCeil = (xMax / 100).ceil() * 100.0; + double yMaxCeil = (yMax / 100).ceil() * 100.0; + + return SizedBox( + child: ScatterChart( + ScatterChartData( + backgroundColor: Colors.transparent, + gridData: FlGridData( + show: true, + horizontalInterval: yMaxCeil / divisions, + verticalInterval: xMaxCeil / divisions, + getDrawingHorizontalLine: (value) { + return FlLine( + color: themeController.currentColor.sc4, // 设置网格线颜色 + strokeWidth: 0.5, + ); + }, + getDrawingVerticalLine: (value) { + return FlLine( + color: themeController.currentColor.sc4, // 设置网格线颜色 + strokeWidth: 0.5, + ); + }, + ), + titlesData: FlTitlesData( + show: true, + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 60.rpx, // 给 y 轴标签更多空间 + getTitlesWidget: (double value, TitleMeta meta) { + return Padding( + padding: EdgeInsets.only(right: 14.rpx), // 右侧加间距 + child: Text( + value.toStringAsFixed(0), + style: TextStyle( + fontSize: 18.rpx, + color: themeController.currentColor.sc4, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.right, // 右对齐 + ), + ); + }, + ), + ), + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + getTitlesWidget: (double value, TitleMeta meta) { + return Text( + value.toStringAsFixed(0), + style: TextStyle( + fontSize: 18.rpx, + color: themeController.currentColor.sc4, + ), + ); + }, + ), + ), + rightTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + topTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + ), + borderData: FlBorderData( + show: true, + border: Border.all( + color: themeController.currentColor.sc4, + width: 0.5, + ), + ), + // 修改散点的大小和颜色 + scatterSpots: points.map((point) { + return ScatterSpot( + point.x, // x 坐标 + point.y, // y 坐标 + dotPainter: FlDotCirclePainter( + radius: 3.rpx, // 自定义大小 + color: pointColor, // 自定义颜色 + ), + ); + }).toList(), + minX: 0, + maxX: xMaxCeil, + minY: 0, + maxY: yMaxCeil, + ), + ), + ); + } +} diff --git a/lib/pages/sleep_report/chart/SegmentedCirclePainter.dart b/lib/pages/sleep_report/chart/SegmentedCirclePainter.dart index a7fd27f..d6cb1b8 100644 --- a/lib/pages/sleep_report/chart/SegmentedCirclePainter.dart +++ b/lib/pages/sleep_report/chart/SegmentedCirclePainter.dart @@ -89,7 +89,7 @@ class SegmentedCircleWithCenterWidget extends StatelessWidget { Positioned( right: 60.rpx, // 放置在右侧 child: SvgPicture.asset( - 'assets/img/icon/add.svg', + 'assets/img/icon/score_down.svg', width: 14.rpx, height: 22.rpx, color: themeController.currentColor.sc9, diff --git a/lib/pages/sleep_report/chart/SleepRadarChart.dart b/lib/pages/sleep_report/chart/SleepRadarChart.dart new file mode 100644 index 0000000..dd5b1c8 --- /dev/null +++ b/lib/pages/sleep_report/chart/SleepRadarChart.dart @@ -0,0 +1,100 @@ +import 'package:flutter/material.dart'; +import 'package:fl_chart/fl_chart.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; + +class SleepRadarChart extends StatelessWidget { + final Map today; + final Map yesterday; + + const SleepRadarChart({ + Key? key, + required this.today, + required this.yesterday, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + // 雷达图 + _buildRadarChart(), + ], + ), + ); + } + + Widget _buildRadarChart() { + return AspectRatio( + aspectRatio: 1.3, + child: RadarChart( + RadarChartData( + dataSets: [ + // 今日数据 + RadarDataSet( + dataEntries: [ + RadarEntry(value: today['type1']!), // 呼吸暂停 + RadarEntry(value: today['type2']!), // 入睡时间 + RadarEntry(value: today['type3']!), // 离床次数 + RadarEntry(value: today['type4']!), // 深睡比例 + RadarEntry(value: today['type5']!), // 睡眠时长 + ], + borderColor: stringToColor("#00C1AA"), + borderWidth: 2, + fillColor: Colors.transparent, + entryRadius: 0, + ), + // 昨日数据 + RadarDataSet( + dataEntries: [ + RadarEntry(value: yesterday['type1']!), // 呼吸暂停 + RadarEntry(value: yesterday['type2']!), // 入睡时间 + RadarEntry(value: yesterday['type3']!), // 离床次数 + RadarEntry(value: yesterday['type4']!), // 深睡比例 + RadarEntry(value: yesterday['type5']!), // 睡眠时长 + ], + borderColor: stringToColor("#FFD251"), + borderWidth: 2, + fillColor: Colors.transparent, + entryRadius: 0, + ), + ], + radarBackgroundColor: stringToColor("#343844"), + radarBorderData: + BorderSide(color: themeController.currentColor.sc4, width: 1), + radarShape: RadarShape.polygon, + titlePositionPercentageOffset: 0.2, + titleTextStyle: TextStyle( + fontSize: AppConstants().normal_text_fontSize, + color: themeController.currentColor.sc3), + getTitle: (index, angle) { + switch (index) { + case 0: + return RadarChartTitle(text: '呼吸暂停'); + case 1: + return RadarChartTitle(text: '入睡时间'); + case 2: + return RadarChartTitle(text: '离床次数'); + case 3: + return RadarChartTitle(text: '深睡比例'); + case 4: + return RadarChartTitle(text: '睡眠时长'); + default: + return const RadarChartTitle(text: ''); + } + }, + tickCount: 5, + ticksTextStyle: + const TextStyle(color: Colors.transparent, fontSize: 10), + // ticksColor: Colors.grey.shade300, + gridBorderData: BorderSide(color: Colors.transparent, width: 1), + tickBorderData: + BorderSide(color: themeController.currentColor.sc4, width: 1), + ), + swapAnimationDuration: const Duration(milliseconds: 400), + ), + ); + } +} diff --git a/lib/pages/sleep_report/chart/TimeLineChart.dart b/lib/pages/sleep_report/chart/TimeLineChart.dart new file mode 100644 index 0000000..180db24 --- /dev/null +++ b/lib/pages/sleep_report/chart/TimeLineChart.dart @@ -0,0 +1,273 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'dart:ui' as ui; + +import 'package:vbvs_app/common/util/MyUtils.dart'; + +class TimeLineChart extends StatelessWidget { + final List points; + final double yMin; + final double yMax; + final int startTime; + final int endTime; + final double width; + final double height; + + const TimeLineChart({ + super.key, + required this.points, + required this.yMin, + required this.yMax, + required this.startTime, + required this.endTime, + this.width = 400, + this.height = 300, + }); + + @override + Widget build(BuildContext context) { + return CustomPaint( + size: Size(width, height), + painter: _TimeLineChartPainter( + points: points, + yMin: yMin, + yMax: yMax, + startTime: startTime, + endTime: endTime, + ), + ); + } +} + +class DataPoint { + final int timestamp; + final double value; + + DataPoint(this.timestamp, this.value); +} + +class _TimeLineChartPainter extends CustomPainter { + final List points; + final double yMin; + final double yMax; + final int startTime; + final int endTime; + + _TimeLineChartPainter({ + required this.points, + required this.yMin, + required this.yMax, + required this.startTime, + required this.endTime, + }); + + @override + void paint(Canvas canvas, Size size) { + _drawYAxis(canvas, size); + _drawXAxis(canvas, size); + _drawLine(canvas, size); + } + + void _drawXAxis(Canvas canvas, Size size) { + const margin = 40.0; + final paint = Paint()..color = Colors.black; + final textStyle = const TextStyle(color: Colors.black, fontSize: 12); + + // Draw X axis line + canvas.drawLine( + Offset(margin, size.height - margin), + Offset(size.width - margin, size.height - margin), + paint, + ); + + // Generate time ticks + final timeFormatStartEnd = DateFormat('HH:mm'); + final timeFormatMiddle = DateFormat('h'); + final startDateTime = DateTime.fromMillisecondsSinceEpoch(startTime); + final endDateTime = DateTime.fromMillisecondsSinceEpoch(endTime); + + List hourTicks = []; + DateTime current = DateTime( + startDateTime.year, + startDateTime.month, + startDateTime.day, + startDateTime.hour, + ).add(const Duration(hours: 1)); + + while (current.isBefore(endDateTime)) { + if (current.isAfter(startDateTime)) { + hourTicks.add(current); + } + current = current.add(const Duration(hours: 1)); + } + + void drawTick(DateTime time, bool isEdge) { + final x = margin + + ((time.millisecondsSinceEpoch - startTime) / (endTime - startTime)) * + (size.width - 2 * margin); + + final text = isEdge + ? timeFormatStartEnd.format(time) + : timeFormatMiddle.format(time); + + _drawText( + canvas, + text, + Offset(x, size.height - margin + 20), + TextAlign.center, + ); + } + + drawTick(startDateTime, true); + drawTick(endDateTime, true); + for (var tick in hourTicks) { + drawTick(tick, false); + } + } + + void _drawYAxis(Canvas canvas, Size size) { + const margin = 40.0; + final midValue = (yMax + yMin) / 2; + + // 计算三条虚线之间的垂直间距 + final lineSpacing = (size.height - 2 * margin) / 3; // 让三条线之间的间距相等 + + // 新增的 y=0 实线的垂直位置 + final zeroLinePosition = margin + lineSpacing * 3; // 确保 y=0 位于三条虚线下方 + + void drawLine(double value, Color color, + {bool isDashed = false, bool isSolid = false}) { + final y = + (value - yMax) / (yMin - yMax) * (size.height - 2 * margin) + margin; + + final path = Path(); + path.moveTo(margin, y); + path.lineTo(size.width - margin, y); + + final paint = Paint() + ..color = color + ..strokeWidth = (color != Colors.grey) ? 2 : 1 + ..style = PaintingStyle.stroke; + + if (isDashed) { + Path dashedPath = _createDashedPath(path, dashWidth: 5, dashSpace: 5); + canvas.drawPath(dashedPath, paint); + } else if (isSolid) { + // 对于实线,直接绘制 + canvas.drawPath(path, paint); + } else { + // 默认使用虚线绘制 + canvas.drawPath(path, paint); + } + } + + // 绘制 y=0 的灰色实线,并将其放置在三条虚线的下方 + if (yMin < 0 && yMax > 0) { + drawLine(0, Colors.grey, isSolid: true); // 灰色实线绘制 y=0 线 + } + + // 绘制最小值、中间值、最大值的虚线 + drawLine(yMin, themeController.currentColor.sc9, isDashed: true); + drawLine(midValue, themeController.currentColor.sc4, isDashed: true); + drawLine(yMax, themeController.currentColor.sc9, isDashed: true); + } + + Path _createDashedPath(Path path, + {required double dashWidth, required double dashSpace}) { + final Path dashedPath = Path(); + final ui.PathMetrics metrics = path.computeMetrics(); + + for (ui.PathMetric metric in metrics) { + double distance = 0; + while (distance < metric.length) { + dashedPath.addPath( + metric.extractPath(distance, distance + dashWidth), + Offset.zero, + ); + distance += dashWidth + dashSpace; + } + } + + return dashedPath; + } + + void _drawLine(Canvas canvas, Size size) { + const margin = 40.0; + final sortedPoints = points + ..sort((a, b) => a.timestamp.compareTo(b.timestamp)); + + Path? currentPath; + Paint currentPaint = _createPaint(Colors.green); + + for (int i = 0; i < sortedPoints.length - 1; i++) { + final p1 = sortedPoints[i]; + final p2 = sortedPoints[i + 1]; + + final x1 = margin + + ((p1.timestamp - startTime) / (endTime - startTime)) * + (size.width - 2 * margin); + final y1 = margin + + (1 - (p1.value - yMin) / (yMax - yMin)) * (size.height - 2 * margin); + + final x2 = margin + + ((p2.timestamp - startTime) / (endTime - startTime)) * + (size.width - 2 * margin); + final y2 = margin + + (1 - (p2.value - yMin) / (yMax - yMin)) * (size.height - 2 * margin); + + final shouldBeGreen = p1.value >= yMin && + p1.value <= yMax && + p2.value >= yMin && + p2.value <= yMax; + + // 根据当前线段的状态来决定是否切换颜色和虚线状态 + if (shouldBeGreen != (currentPaint.color == Colors.green)) { + if (currentPath != null) { + canvas.drawPath(currentPath, currentPaint); + } + currentPath = Path(); + currentPaint = _createPaint(shouldBeGreen ? Colors.green : Colors.red); + } + + currentPath ??= Path(); + if (i == 0) currentPath.moveTo(x1, y1); + currentPath.lineTo(x2, y2); + } + + // 绘制剩余路径 + if (currentPath != null) { + if (currentPaint.color == Colors.red) { + // 如果是红色线,绘制虚线 + final dashedPath = + _createDashedPath(currentPath, dashWidth: 5, dashSpace: 5); + canvas.drawPath(dashedPath, currentPaint); + } else { + canvas.drawPath(currentPath, currentPaint); + } + } + } + + Paint _createPaint(Color color) => Paint() + ..color = color + ..strokeWidth = 2 + ..style = PaintingStyle.stroke; + + void _drawText(Canvas canvas, String text, Offset offset, TextAlign align) { + final textPainter = TextPainter( + text: TextSpan( + text: text, + style: const TextStyle(color: Colors.black, fontSize: 12), + ), + textDirection: ui.TextDirection.ltr, + )..layout(); + + final centeredOffset = offset.translate( + -textPainter.width / 2, + -textPainter.height / 2, + ); + textPainter.paint(canvas, centeredOffset); + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) => true; +} diff --git a/lib/pages/sleep_report/chart/TimeSeriesChart.dart b/lib/pages/sleep_report/chart/TimeSeriesChart.dart new file mode 100644 index 0000000..eea0fc0 --- /dev/null +++ b/lib/pages/sleep_report/chart/TimeSeriesChart.dart @@ -0,0 +1,281 @@ +import 'package:flutter/material.dart'; +import 'package:fl_chart/fl_chart.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'dart:math'; + +import 'package:vbvs_app/common/util/MyUtils.dart'; + +class TimeSeriesChart extends StatelessWidget { + final int startTime; + final int endTime; + final double yMin; + final double yMax; + final List dataPoints; + + TimeSeriesChart({ + required this.startTime, + required this.endTime, + required this.yMin, + required this.yMax, + required this.dataPoints, + }); + + @override + Widget build(BuildContext context) { + final midValue = (yMax + yMin) / 2; + final xLabels = _generateXLabels(); + + // Prepare spots and segments + List spots = []; + List lineColors = []; + + for (int i = 0; i < dataPoints.length; i++) { + final point = dataPoints[i]; + final xValue = _convertTimeToXValue(point.timestamp); + final yValue = point.value; + + spots.add(FlSpot(xValue, yValue)); + if (yValue >= yMin && yValue <= yMax) { + lineColors.add(Colors.green); // Color for points within range + } else { + lineColors.add(Colors.red); // Color for points outside range + } + } + + return AspectRatio( + aspectRatio: 2, + child: LineChart( + LineChartData( + lineTouchData: LineTouchData( + touchTooltipData: LineTouchTooltipData( + getTooltipItems: (List touchedSpots) { + return touchedSpots.map((spot) { + final time = DateTime.fromMillisecondsSinceEpoch( + _convertXValueToTime(spot.x), + ); + return LineTooltipItem( + '${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}\n${spot.y.toStringAsFixed(0)}', + const TextStyle(color: Colors.black), + ); + }).toList(); + }, + ), + ), + gridData: FlGridData( + show: true, + drawVerticalLine: false, + getDrawingHorizontalLine: (value) { + if (value == 0) { + return FlLine( + color: themeController.currentColor.sc4, + strokeWidth: 1, + ); + } else if (value == yMin) { + return FlLine( + color: themeController.currentColor.sc9, + strokeWidth: 1, + dashArray: [5, 5], + ); + } else if (value == yMax) { + return FlLine( + color: themeController.currentColor.sc9, + strokeWidth: 1, + dashArray: [5, 5], + ); + } else if (value == midValue) { + return FlLine( + color: themeController.currentColor.sc4, + strokeWidth: 1, + dashArray: [5, 5], + ); + } + return FlLine( + color: Colors.grey.withOpacity(0.1), + strokeWidth: 1, + ); + }, + ), + titlesData: FlTitlesData( + show: true, + rightTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + topTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 30, + getTitlesWidget: (value, meta) { + final index = value.toInt(); + if (index >= 0 && index < xLabels.length) { + return Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Text( + xLabels[index].label, + style: TextStyle( + fontSize: 10, + color: Colors.grey, + ), + ), + ); + } + return const Text(''); + }, + ), + ), + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + getTitlesWidget: (value, meta) { + if (value == 0) { + return Padding( + padding: EdgeInsets.only(right: 14.rpx), + child: Text( + value.toStringAsFixed(0), + style: TextStyle( + fontSize: 18.rpx, + color: themeController.currentColor.sc4, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.right, + ), + ); + } else if (value == yMin) { + return Padding( + padding: EdgeInsets.only(right: 14.rpx), + child: Text( + yMin.toStringAsFixed(0), + style: TextStyle( + fontSize: 18.rpx, + color: themeController.currentColor.sc4, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.right, + ), + ); + } else if (value == midValue) { + return Padding( + padding: EdgeInsets.only(right: 14.rpx), + child: Text( + midValue.toStringAsFixed(0), + style: TextStyle( + fontSize: 18.rpx, + color: themeController.currentColor.sc4, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.right, + ), + ); + } else if (value == yMax) { + return Padding( + padding: EdgeInsets.only(right: 14.rpx), + child: Text( + yMax.toStringAsFixed(0), + style: TextStyle( + fontSize: 18.rpx, + color: themeController.currentColor.sc4, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.right, + ), + ); + } + return const Text(''); + }, + reservedSize: 40, + ), + ), + ), + borderData: FlBorderData( + show: false, + border: Border.all(color: Colors.grey.withOpacity(0.3)), + ), + minX: 0, + maxX: xLabels.length - 1, + minY: min(0, yMin) - (yMax - yMin) * 0.2, + maxY: yMax + (yMax - yMin) * 0.2, + lineBarsData: [ + LineChartBarData( + spots: spots, + isCurved: false, + color: themeController.currentColor.sc2, + barWidth: 2, + isStrokeCapRound: true, + dotData: FlDotData(show: false), // Disable dots + belowBarData: BarAreaData(show: false), + ), + ], + ), + ), + ); + } + + List _generateXLabels() { + final labels = []; + final startDate = DateTime.fromMillisecondsSinceEpoch(startTime); + final endDate = DateTime.fromMillisecondsSinceEpoch(endTime); + + labels.add(XLabel( + time: startTime, + label: + '${startDate.hour.toString().padLeft(2, '0')}:${startDate.minute.toString().padLeft(2, '0')}', + )); + + DateTime current = DateTime( + startDate.year, + startDate.month, + startDate.day, + startDate.hour + 1, + ); + + while (current.isBefore(endDate)) { + labels.add(XLabel( + time: current.millisecondsSinceEpoch, + label: current.hour.toString(), + )); + current = current.add(Duration(hours: 1)); + } + + labels.add(XLabel( + time: endTime, + label: + '${endDate.hour.toString().padLeft(2, '0')}:${endDate.minute.toString().padLeft(2, '0')}', + )); + + return labels; + } + + double _convertTimeToXValue(int timestamp) { + final totalDuration = endTime - startTime; + final pointDuration = timestamp - startTime; + final xLabels = _generateXLabels(); + return (pointDuration / totalDuration) * (xLabels.length - 1); + } + + int _convertXValueToTime(double xValue) { + final xLabels = _generateXLabels(); + final totalDuration = endTime - startTime; + final ratio = xValue / (xLabels.length - 1); + return startTime + (totalDuration * ratio).round(); + } +} + +class TimeSeriesPoint { + final int timestamp; + final double value; + + TimeSeriesPoint(this.timestamp, this.value); +} + +class XLabel { + final int time; + final String label; + + XLabel({required this.time, required this.label}); +} diff --git a/lib/pages/sleep_report/component/AIAdviceWidget.dart b/lib/pages/sleep_report/component/AIAdviceWidget.dart new file mode 100644 index 0000000..67d125f --- /dev/null +++ b/lib/pages/sleep_report/component/AIAdviceWidget.dart @@ -0,0 +1,140 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart'; +import 'package:vbvs_app/pages/sleep_report/chart/AdviceComponnetWidget.dart'; + +class AIAdviceWidget extends StatefulWidget { + AIAdviceWidget({super.key}); + + @override + State createState() => _AIAdviceWidgetState(); +} + +class _AIAdviceWidgetState extends State { + @override + void setState(VoidCallback callback) { + super.setState(callback); + } + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + List advices = [ + { + "title": "调整作息时间", + "description": "确保每天在相同的时间上床并醒来。保持规律的作息可以帮助调整你的生物钟,改善睡眠质量。", + }, + { + "title": "减少睡前刺激", + "description": "避免在睡前使用电子设备,如手机、电脑等,减少屏幕时间,以防影响你的睡眠质量。", + }, + { + "title": "创造理想睡眠环境", + "description": "确保卧室安静、黑暗且舒适。调节室温,并避免过于嘈杂或明亮的环境,帮助你快速入睡。", + }, + { + "title": "避免摄入咖啡因和酒精", + "description": "避免在睡前几小时内摄入咖啡、茶、酒精等饮品,因为这些物质可能会干扰你的睡眠。", + }, + { + "title": "增加日间活动", + "description": "适量的日间运动可以帮助提高睡眠质量,但要避免睡前剧烈运动,以免影响入睡。", + }, + { + "title": "放松身心", + "description": "睡前可以进行一些放松活动,如深呼吸、冥想或听轻音乐,这有助于减轻压力并促进良好的睡眠。", + }, + ]; + + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: themeController.currentColor.sc5, + borderRadius: BorderRadius.circular( + AppConstants().normal_container_radius), // 你可以按需调整圆角半径 + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "AI分析".tr, + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: AppConstants().title_text_fontSize), + ), + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.white, // 或设置为你需要的水波纹颜色 + padding: EdgeInsetsDirectional.fromSTEB( + 14.rpx, 0.rpx, 14.rpx, 0), // + borderRadius: 0.rpx, // 圆形点击区域 + onTap: () { + showTipDialog( + context, + Container( + child: Text( + "AI分析介绍".tr, + style: TextStyle( + fontSize: 26.rpx, + color: themeController.currentColor.sc3, + ), + ), + ), + ); + }, + child: Container( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 0.rpx, 0.rpx, 0), // 外部 padding 移到内部 + width: 28.rpx, + height: 28.rpx, + child: SvgPicture.asset( + 'assets/img/icon/explain.svg', + fit: BoxFit.cover, + color: themeController.currentColor.sc4, + ), + ), + ), + ], + ), + ), + SizedBox( + height: 31.rpx, + ), + Padding( + padding: + EdgeInsetsDirectional.fromSTEB(0.rpx, 0.rpx, 30.rpx, 0.rpx), + child: Column( + children: advices.map((advice) { + return AdviceComponnetWidget( + title: advice["title"], + description: advice["description"], + ).paddingOnly(bottom: 0.rpx); // 在每个组件下方添加间隔 + }).toList(), + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/pages/sleep_report/component/BreatheStandardWidget.dart b/lib/pages/sleep_report/component/BreatheStandardWidget.dart new file mode 100644 index 0000000..58ab714 --- /dev/null +++ b/lib/pages/sleep_report/component/BreatheStandardWidget.dart @@ -0,0 +1,315 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart'; +import 'package:vbvs_app/pages/sleep_report/chart/TimeSeriesChart.dart'; + +class BreatheStandardWidget extends StatefulWidget { + BreatheStandardWidget({super.key}); + + @override + State createState() => _BreatheStandardWidgetState(); +} + +class _BreatheStandardWidgetState extends State { + @override + void setState(VoidCallback callback) { + super.setState(callback); + } + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final now = DateTime.now(); + final startTime = now.subtract(Duration(hours: 5)).millisecondsSinceEpoch; + final endTime = now.millisecondsSinceEpoch; + final dataPoints = [ + TimeSeriesPoint(startTime + Duration(minutes: 10).inMilliseconds, 50), + TimeSeriesPoint(startTime + Duration(hours: 1).inMilliseconds, 120), + TimeSeriesPoint(startTime + Duration(hours: 2).inMilliseconds, 80), + TimeSeriesPoint(startTime + Duration(hours: 3).inMilliseconds, 180), + TimeSeriesPoint(startTime + Duration(hours: 4).inMilliseconds, 30), + TimeSeriesPoint(endTime - Duration(minutes: 10).inMilliseconds, 150), + ]; + + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: themeController.currentColor.sc5, + borderRadius: BorderRadius.circular( + AppConstants().normal_container_radius), // 你可以按需调整圆角半径 + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "呼吸基准".tr, + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: AppConstants().title_text_fontSize), + ), + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.white, // 或设置为你需要的水波纹颜色 + padding: EdgeInsetsDirectional.fromSTEB( + 14.rpx, 0.rpx, 14.rpx, 0), // + borderRadius: 0.rpx, // 圆形点击区域 + onTap: () { + showTipDialog( + context, + Container( + child: Text( + "呼吸基准介绍".tr, + style: TextStyle( + fontSize: 26.rpx, + color: themeController.currentColor.sc3, + ), + ), + ), + ); + }, + child: Container( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 0.rpx, 0.rpx, 0), // 外部 padding 移到内部 + width: 28.rpx, + height: 28.rpx, + child: SvgPicture.asset( + 'assets/img/icon/explain.svg', + fit: BoxFit.cover, + color: themeController.currentColor.sc4, + ), + ), + ), + ], + ), + ), + SizedBox( + height: 31.rpx, + ), + Padding( + padding: + EdgeInsetsDirectional.fromSTEB(0.rpx, 0.rpx, 30.rpx, 0.rpx), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + // 圆形小球容器 + Container( + width: 14.rpx, // 圆球的直径 + height: 14.rpx, + decoration: BoxDecoration( + color: themeController.currentColor.sc2, // 小球的颜色 + shape: BoxShape.circle, // 设置为圆形 + ), + ), + SizedBox(width: 15.rpx), // 圆球和文字之间的间隔 + // 文字 + Text( + '正常范围(8~20)', + style: TextStyle( + fontSize: + AppConstants().smaller_text_fontSize, // 文字的大小 + color: themeController.currentColor.sc3, // 文字颜色 + ), + ), + ], + ), + Container( + // color: Colors.red, + width: double.infinity, + // height: 300.rpx, + child: TimeSeriesChart( + startTime: startTime, + endTime: endTime, + yMin: 50, + yMax: 150, + dataPoints: dataPoints, + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 30.rpx, 0.rpx, 0.rpx, 0.rpx), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Column( + children: [ + Text( + "平均呼吸", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().normal_text_fontSize), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + "12", + style: TextStyle( + color: themeController.currentColor.sc2, + fontSize: + AppConstants().normal_text_fontSize), + ), + Text( + "次/分钟", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().small_text_fontSize), + ), + ].divide(SizedBox( + width: 6.rpx, + )), + ), + ], + ), + Column( + children: [ + Text( + "基准呼吸", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().normal_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + "15", + style: TextStyle( + color: themeController.currentColor.sc2, + fontSize: + AppConstants().normal_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Text( + "次/分钟", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().small_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ].divide(SizedBox( + width: 6.rpx, + )), + ), + ], + ), + Column( + children: [ + Text( + "最低呼吸", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().normal_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + "11", + style: TextStyle( + color: themeController.currentColor.sc2, + fontSize: + AppConstants().normal_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Text( + "次/分钟", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().small_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ].divide(SizedBox( + width: 6.rpx, + )), + ), + ], + ), + Column( + children: [ + Text( + "最高呼吸", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().normal_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + "18", + style: TextStyle( + color: themeController.currentColor.sc2, + fontSize: + AppConstants().normal_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Text( + "次/分钟", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().small_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ].divide(SizedBox( + width: 6.rpx, + )), + ), + ], + ), + ], + ), + ), + ].divide(SizedBox( + height: 18.rpx, + )), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/sleep_report/component/CompareSleepWidget.dart b/lib/pages/sleep_report/component/CompareSleepWidget.dart new file mode 100644 index 0000000..fded756 --- /dev/null +++ b/lib/pages/sleep_report/component/CompareSleepWidget.dart @@ -0,0 +1,197 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart'; +import 'package:vbvs_app/pages/sleep_report/chart/AdviceComponnetWidget.dart'; +import 'package:vbvs_app/pages/sleep_report/chart/RadarChart.dart'; +import 'package:vbvs_app/pages/sleep_report/chart/SleepRadarChart.dart'; + +class CompareSleepWidget extends StatefulWidget { + CompareSleepWidget({super.key}); + + @override + State createState() => _CompareSleepWidgetState(); +} + +class _CompareSleepWidgetState extends State { + @override + void setState(VoidCallback callback) { + super.setState(callback); + } + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + var today = { + "type1": 40.0, + "type2": 80.0, + "type3": 60.0, + "type4": 70.0, + "type5": 100.0 + }; + var yesterday = { + "type1": 40.0, + "type2": 90.0, + "type3": 50.0, + "type4": 70.0, + "type5": 30.0 + }; + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: themeController.currentColor.sc5, + borderRadius: BorderRadius.circular( + AppConstants().normal_container_radius), // 你可以按需调整圆角半径 + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "与昨日对比分析".tr, + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: AppConstants().title_text_fontSize), + ), + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.white, // 或设置为你需要的水波纹颜色 + padding: EdgeInsetsDirectional.fromSTEB( + 14.rpx, 0.rpx, 14.rpx, 0), // + borderRadius: 0.rpx, // 圆形点击区域 + onTap: () { + showTipDialog( + context, + Container( + child: Text( + "与昨日对比分析介绍".tr, + style: TextStyle( + fontSize: 26.rpx, + color: themeController.currentColor.sc3, + ), + ), + ), + ); + }, + child: Container( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 0.rpx, 0.rpx, 0), // 外部 padding 移到内部 + width: 28.rpx, + height: 28.rpx, + child: SvgPicture.asset( + 'assets/img/icon/explain.svg', + fit: BoxFit.cover, + color: themeController.currentColor.sc4, + ), + ), + ), + ], + ), + ), + SizedBox( + height: 31.rpx, + ), + // Padding( + // padding: + // EdgeInsetsDirectional.fromSTEB(30.rpx, 0.rpx, 30.rpx, 0.rpx), + // child: SleepRadarChart( + // today: today, + // yesterday: yesterday, + // ), + // ), + Padding( + padding: + EdgeInsetsDirectional.fromSTEB(0.rpx, 0.rpx, 30.rpx, 0.rpx), + child: Stack( + children: [ + // 雷达图 + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 30.rpx, 0.rpx, 0.rpx, 0.rpx), + child: SleepRadarChart( + today: today, + yesterday: yesterday, + ), + ), + // 在左侧添加一个 Text + Positioned( + left: 0, // 这里可以修改文本左边的距离 + top: 0, // 这里可以修改文本顶部的距离 + child: Container( + color: Colors.transparent, // 不需要背景色,可以去掉 + child: Column( + children: [ + Row( + children: [ + // 长条容器 + Container( + width: + 34.rpx, // 你可以设置容器的宽度,或者使用 Expanded 填充剩余空间 + height: 2.rpx, // 容器的高度 + color: stringToColor("#00C1AA"), // 容器的颜色 + ), + SizedBox(width: 13.rpx), // 文字和容器之间的间距 + // 文字 + Text( + '今日数据', // 文字内容 + style: TextStyle( + fontSize: 18.rpx, // 文字大小 + color: + themeController.currentColor.sc4, // 文字颜色 + ), + ), + ], + ), + Row( + children: [ + // 长条容器 + Container( + width: + 34.rpx, // 你可以设置容器的宽度,或者使用 Expanded 填充剩余空间 + height: 2.rpx, // 容器的高度 + color: stringToColor("#FFD251"), // 容器的颜色 + ), + SizedBox(width: 13.rpx), // 文字和容器之间的间距 + // 文字 + Text( + '昨日数据', // 文字内容 + style: TextStyle( + fontSize: 18.rpx, // 文字大小 + color: + themeController.currentColor.sc4, // 文字颜色 + ), + ), + ], + ), + ].divide(SizedBox(height: 25.rpx)), + ), + ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/sleep_report/component/HeartChangeWidget.dart b/lib/pages/sleep_report/component/HeartChangeWidget.dart new file mode 100644 index 0000000..76c67eb --- /dev/null +++ b/lib/pages/sleep_report/component/HeartChangeWidget.dart @@ -0,0 +1,316 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart'; +import 'package:vbvs_app/pages/sleep_report/chart/DataShowWidget.dart'; + +class HeartChangeWidget extends StatefulWidget { + HeartChangeWidget({super.key}); + + @override + State createState() => _HeartChangeWidgetState(); +} + +class _HeartChangeWidgetState extends State { + @override + void setState(VoidCallback callback) { + super.setState(callback); + } + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + //0上升 1下降 2持平 + List data = [ + { + "name": "心脏总能量", + "value": 5262, + "range": "2055-6000", + "change": 0, + "desc": "心脏总能量介绍" + }, + { + "name": "心率减速力", + "value": 5262, + "range": "2055-6000", + "change": 1, + "desc": "心率减速力介绍" + }, + { + "name": "迷走神经张力指数", + "value": 5262, + "range": "2055-6000", + "change": 2, + "desc": "迷走神经张力指数介绍" + }, + { + "name": "交感神经张力指数", + "value": 5262, + "range": "2055-6000", + "change": 0, + "desc": "交感神经张力指数介绍" + }, + { + "name": "自主神经张力指数", + "value": 5262, + "range": "2055-6000", + "change": 2, + "desc": "自主神经张力指数介绍" + }, + { + "name": "血管舒张指数", + "value": 5262, + "range": "2055-6000", + "change": 1, + "desc": "血管舒张指数介绍" + }, + { + "name": "SDNN", + "value": 5262, + "range": "2055-6000", + "change": 0, + "desc": "SDNN介绍" + }, + { + "name": "PNN50", + "value": 5262, + "range": "2055-6000", + "change": 1, + "desc": "PNN50介绍" + }, + { + "name": "RMSSD", + "value": 5262, + "range": "2055-6000", + "change": 2, + "desc": "RMSSD介绍" + }, + ]; + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: themeController.currentColor.sc5, + borderRadius: BorderRadius.circular( + AppConstants().normal_container_radius), // 你可以按需调整圆角半径 + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "心率变异性(HRV)".tr, + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: AppConstants().title_text_fontSize), + ), + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.white, // 或设置为你需要的水波纹颜色 + padding: EdgeInsetsDirectional.fromSTEB( + 14.rpx, 0.rpx, 14.rpx, 0), // + borderRadius: 0.rpx, // 圆形点击区域 + onTap: () { + showTipDialog( + context, + Container( + child: Text( + "心率变异性(HRV)介绍".tr, + style: TextStyle( + fontSize: 26.rpx, + color: themeController.currentColor.sc3, + ), + ), + ), + ); + }, + child: Container( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 0.rpx, 0.rpx, 0), // 外部 padding 移到内部 + width: 28.rpx, + height: 28.rpx, + child: SvgPicture.asset( + 'assets/img/icon/explain.svg', + fit: BoxFit.cover, + color: themeController.currentColor.sc4, + ), + ), + ), + ], + ), + ), + SizedBox( + height: 31.rpx, + ), + Padding( + padding: + EdgeInsetsDirectional.fromSTEB(0.rpx, 0.rpx, 0.rpx, 0.rpx), + child: Column( + children: [ + DataShowWidget( + alignment: MainAxisAlignment.center, + widget1: Text( + "名称", + style: TextStyle( + color: themeController.currentColor.sc4, + fontSize: AppConstants().normal_text_fontSize, + ), + ), + widget2: Text( + "测量值", + style: TextStyle( + color: themeController.currentColor.sc4, + fontSize: AppConstants().normal_text_fontSize, + ), + ), + widget3: Text( + "参考范围", + style: TextStyle( + color: themeController.currentColor.sc4, + fontSize: AppConstants().normal_text_fontSize, + ), + ), + widget4: Text( + "趋势", + style: TextStyle( + color: themeController.currentColor.sc4, + fontSize: AppConstants().normal_text_fontSize, + ), + ), + ), + Column( + children: data.map((data) { + return DataShowWidget( + alignment: MainAxisAlignment.center, + widget1: Row( + children: [ + Text( + '${data['name']}', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: AppConstants().normal_text_fontSize, + ), + ), + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.white, + padding: EdgeInsetsDirectional.fromSTEB( + 14.rpx, 14.rpx, 14.rpx, 14.rpx), + borderRadius: 0.rpx, + onTap: () { + // Get.toNamed("/deviceShareListPage", arguments: explain); + showTipDialog( + context, + Container( + child: Text( + '${data['desc']}', + style: TextStyle( + fontSize: 26.rpx, + color: themeController.currentColor.sc3, + ), + ), + ), + ); + }, + child: SizedBox( + width: 17.rpx, + height: 17.rpx, + child: SvgPicture.asset( + 'assets/img/icon/explain.svg', + fit: BoxFit.cover, + color: Colors.white, + ), + ), + ), + ], + ), + widget2: Text( + '${data['value']}', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: AppConstants().normal_text_fontSize, + ), + ), + widget3: Text( + '${data['range']}', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: AppConstants().normal_text_fontSize, + ), + ), + widget4: data['change'] == 0 + ? Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 0.rpx, 0, 0), + child: Container( + width: 22.rpx, + height: 22.rpx, + decoration: BoxDecoration(), + child: SvgPicture.asset( + 'assets/img/icon/score_up.svg', + // fit: BoxFit.cover, + ), + ), + ) + : data['change'] == 1 + ? Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 0.rpx, 0, 0), + child: Container( + width: 22.rpx, + height: 22.rpx, + decoration: BoxDecoration(), + child: SvgPicture.asset( + 'assets/img/icon/score_down.svg', + // fit: BoxFit.cover, + ), + ), + ) + : Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 0.rpx, 0, 0), + child: Container( + width: 22.rpx, + height: 22.rpx, + decoration: BoxDecoration(), + child: SvgPicture.asset( + 'assets/img/icon/score_equal.svg', + // fit: BoxFit.fill, + ), + ), + ), + ).paddingOnly(bottom: 0.rpx); // 在每个组件下方添加间隔 + }).toList(), + ), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/sleep_report/component/HeartPointWidget.dart b/lib/pages/sleep_report/component/HeartPointWidget.dart index 9073894..b9812c4 100644 --- a/lib/pages/sleep_report/component/HeartPointWidget.dart +++ b/lib/pages/sleep_report/component/HeartPointWidget.dart @@ -1,4 +1,7 @@ +import 'dart:math'; + import 'package:ef/ef.dart'; +import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:vbvs_app/common/color/appConstants.dart'; @@ -6,7 +9,7 @@ import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart'; -import 'package:vbvs_app/pages/sleep_report/chart/StatusBarWithIndicator.dart'; +import 'package:vbvs_app/pages/sleep_report/chart/ScatterPlotChart.dart'; class HeartPointWidget extends StatefulWidget { HeartPointWidget({super.key}); @@ -33,6 +36,18 @@ class _HeartPointWidgetState extends State { @override Widget build(BuildContext context) { + List data = List.generate(200, (index) { + // 随机生成 x 和 y 值,范围都在 0-1400 之间 + double x = Random().nextDouble() * 1400; // x 值在 0-1400 范围 + double y = Random().nextDouble() * 1400; // y 值也在 0-1400 范围 + + // 返回 ScatterSpot,使用圆点绘制器自定义大小和颜色 + return ScatterSpot( + x, + y, + ); + }); + return Container( width: double.infinity, decoration: BoxDecoration( @@ -91,24 +106,30 @@ class _HeartPointWidgetState extends State { ), ), SizedBox( - height: 83.rpx, + height: 31.rpx, ), Padding( padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0.rpx, 30.rpx, 0.rpx), - child: StatusBarWithIndicator( - selectKey: 2, - showLabel: [ - {"key": 1, "name": "正常", "color": Color(0xFF4CAF50)}, - {"key": 2, "name": "一般", "color": Color(0xFF8BC34A)}, - {"key": 3, "name": "注意", "color": Color(0xFFFFC107)}, - {"key": 4, "name": "警告", "color": Color(0xFFF44336)}, - ], + child: Container( + width: MediaQuery.of(context).size.width * 0.7, + height: MediaQuery.of(context).size.width * 0.7, + constraints: BoxConstraints( + minWidth: 430.rpx, + minHeight: 430.rpx, + ), + child: ScatterPlotChart( + points: data, + xMax: 1400, // x轴最大值 + yMax: 1400, // y轴最大值 + pointColor: stringToColor("#00C1AA"), // 点的颜色 + divisions: 7, // 刻度分割数量 + ), ), ), - SizedBox( - height: 56.rpx, - ), + // SizedBox( + // height: 31.rpx, + // ), ], ), ), diff --git a/lib/pages/sleep_report/component/HeartRateStandardWidget.dart b/lib/pages/sleep_report/component/HeartRateStandardWidget.dart new file mode 100644 index 0000000..9760fdd --- /dev/null +++ b/lib/pages/sleep_report/component/HeartRateStandardWidget.dart @@ -0,0 +1,316 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart'; +import 'package:vbvs_app/pages/sleep_report/chart/TimeSeriesChart.dart'; + +class HeartRateStandardWidget extends StatefulWidget { + HeartRateStandardWidget({super.key}); + + @override + State createState() => + _HeartRateStandardWidgetState(); +} + +class _HeartRateStandardWidgetState extends State { + @override + void setState(VoidCallback callback) { + super.setState(callback); + } + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final now = DateTime.now(); + final startTime = now.subtract(Duration(hours: 5)).millisecondsSinceEpoch; + final endTime = now.millisecondsSinceEpoch; + final dataPoints = [ + TimeSeriesPoint(startTime + Duration(minutes: 10).inMilliseconds, 50), + TimeSeriesPoint(startTime + Duration(hours: 1).inMilliseconds, 120), + TimeSeriesPoint(startTime + Duration(hours: 2).inMilliseconds, 80), + TimeSeriesPoint(startTime + Duration(hours: 3).inMilliseconds, 180), + TimeSeriesPoint(startTime + Duration(hours: 4).inMilliseconds, 30), + TimeSeriesPoint(endTime - Duration(minutes: 10).inMilliseconds, 150), + ]; + + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: themeController.currentColor.sc5, + borderRadius: BorderRadius.circular( + AppConstants().normal_container_radius), // 你可以按需调整圆角半径 + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "心率基准".tr, + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: AppConstants().title_text_fontSize), + ), + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.white, // 或设置为你需要的水波纹颜色 + padding: EdgeInsetsDirectional.fromSTEB( + 14.rpx, 0.rpx, 14.rpx, 0), // + borderRadius: 0.rpx, // 圆形点击区域 + onTap: () { + showTipDialog( + context, + Container( + child: Text( + "心率基准介绍".tr, + style: TextStyle( + fontSize: 26.rpx, + color: themeController.currentColor.sc3, + ), + ), + ), + ); + }, + child: Container( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 0.rpx, 0.rpx, 0), // 外部 padding 移到内部 + width: 28.rpx, + height: 28.rpx, + child: SvgPicture.asset( + 'assets/img/icon/explain.svg', + fit: BoxFit.cover, + color: themeController.currentColor.sc4, + ), + ), + ), + ], + ), + ), + SizedBox( + height: 31.rpx, + ), + Padding( + padding: + EdgeInsetsDirectional.fromSTEB(0.rpx, 0.rpx, 30.rpx, 0.rpx), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + // 圆形小球容器 + Container( + width: 14.rpx, // 圆球的直径 + height: 14.rpx, + decoration: BoxDecoration( + color: themeController.currentColor.sc2, // 小球的颜色 + shape: BoxShape.circle, // 设置为圆形 + ), + ), + SizedBox(width: 15.rpx), // 圆球和文字之间的间隔 + // 文字 + Text( + '正常范围(50~80)', + style: TextStyle( + fontSize: + AppConstants().smaller_text_fontSize, // 文字的大小 + color: themeController.currentColor.sc3, // 文字颜色 + ), + ), + ], + ), + Container( + // color: Colors.red, + width: double.infinity, + // height: 300.rpx, + child: TimeSeriesChart( + startTime: startTime, + endTime: endTime, + yMin: 50, + yMax: 150, + dataPoints: dataPoints, + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 30.rpx, 0.rpx, 0.rpx, 0.rpx), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Column( + children: [ + Text( + "平均心率", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().normal_text_fontSize), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + "89", + style: TextStyle( + color: themeController.currentColor.sc2, + fontSize: + AppConstants().normal_text_fontSize), + ), + Text( + "次/分钟", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().small_text_fontSize), + ), + ].divide(SizedBox( + width: 6.rpx, + )), + ), + ], + ), + Column( + children: [ + Text( + "基准心率", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().normal_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + "80", + style: TextStyle( + color: themeController.currentColor.sc2, + fontSize: + AppConstants().normal_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Text( + "次/分钟", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().small_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ].divide(SizedBox( + width: 6.rpx, + )), + ), + ], + ), + Column( + children: [ + Text( + "最低心率", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().normal_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + "68", + style: TextStyle( + color: themeController.currentColor.sc2, + fontSize: + AppConstants().normal_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Text( + "次/分钟", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().small_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ].divide(SizedBox( + width: 6.rpx, + )), + ), + ], + ), + Column( + children: [ + Text( + "最高心率", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().normal_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + "98", + style: TextStyle( + color: themeController.currentColor.sc2, + fontSize: + AppConstants().normal_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + Text( + "次/分钟", + style: TextStyle( + color: themeController.currentColor.sc3, + fontSize: + AppConstants().small_text_fontSize), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ].divide(SizedBox( + width: 6.rpx, + )), + ), + ], + ), + ], + ), + ), + ].divide(SizedBox( + height: 18.rpx, + )), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/sleep_report/component/SnoreViewWidget.dart b/lib/pages/sleep_report/component/SnoreViewWidget.dart index 1a2fe58..bdc277e 100644 --- a/lib/pages/sleep_report/component/SnoreViewWidget.dart +++ b/lib/pages/sleep_report/component/SnoreViewWidget.dart @@ -61,7 +61,7 @@ class _SnoreViewWidgetWidgetState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - "呼吸暂停监测".tr, + "打鼾监测".tr, style: TextStyle( color: themeController.currentColor.sc3, fontSize: AppConstants().title_text_fontSize), @@ -77,7 +77,7 @@ class _SnoreViewWidgetWidgetState extends State { context, Container( child: Text( - "呼吸暂停监测介绍。", + "打鼾监测介绍。", style: TextStyle( fontSize: 26.rpx, color: themeController.currentColor.sc3, diff --git a/lib/pages/sleep_report/new_sleep_report_page.dart b/lib/pages/sleep_report/new_sleep_report_page.dart index 45200b7..3a6df3d 100644 --- a/lib/pages/sleep_report/new_sleep_report_page.dart +++ b/lib/pages/sleep_report/new_sleep_report_page.dart @@ -9,10 +9,15 @@ import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/controller/date/CalendarController.dart'; import 'package:vbvs_app/controller/sleep/sleep_report_controller.dart'; import 'package:vbvs_app/pages/common/selectDialog.dart'; +import 'package:vbvs_app/pages/sleep_report/component/AIAdviceWidget.dart'; import 'package:vbvs_app/pages/sleep_report/component/BreathPauseWidget.dart'; +import 'package:vbvs_app/pages/sleep_report/component/BreatheStandardWidget.dart'; +import 'package:vbvs_app/pages/sleep_report/component/CompareSleepWidget.dart'; import 'package:vbvs_app/pages/sleep_report/component/DiseasePercentsWidget.dart'; +import 'package:vbvs_app/pages/sleep_report/component/HeartChangeWidget.dart'; import 'package:vbvs_app/pages/sleep_report/component/HeartHealthWidget.dart'; import 'package:vbvs_app/pages/sleep_report/component/HeartPointWidget.dart'; +import 'package:vbvs_app/pages/sleep_report/component/HeartRateStandardWidget.dart'; import 'package:vbvs_app/pages/sleep_report/component/SkinPercentWidget.dart'; import 'package:vbvs_app/pages/sleep_report/component/SleepScoreWidget.dart'; import 'package:vbvs_app/pages/sleep_report/component/SnoreViewWidget.dart'; @@ -505,6 +510,14 @@ class _NewSleepReportPageState extends State { child: SleepScoreWidget(), ), ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 30.rpx, 0.rpx, 30.rpx, 0), + child: Container( + width: double.infinity, + child: CompareSleepWidget(), + ), + ), Padding( padding: EdgeInsetsDirectional.fromSTEB( 30.rpx, 0.rpx, 30.rpx, 0), @@ -513,6 +526,39 @@ class _NewSleepReportPageState extends State { child: HeartPointWidget(), ), ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 30.rpx, 0.rpx, 30.rpx, 0), + child: Container( + // color: stringToColor("#242835"), + width: double.infinity, + child: AIAdviceWidget(), + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 30.rpx, 0.rpx, 30.rpx, 0), + child: Container( + width: double.infinity, + child: HeartRateStandardWidget(), + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 30.rpx, 0.rpx, 30.rpx, 0), + child: Container( + width: double.infinity, + child: HeartChangeWidget(), + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 30.rpx, 0.rpx, 30.rpx, 0), + child: Container( + width: double.infinity, + child: BreatheStandardWidget(), + ), + ), Padding( padding: EdgeInsetsDirectional.fromSTEB( 30.rpx, 0.rpx, 30.rpx, 0), diff --git a/lib/pages/user/about_us_page copy.dart b/lib/pages/user/about_us_page copy.dart new file mode 100644 index 0000000..fd1f00e --- /dev/null +++ b/lib/pages/user/about_us_page copy.dart @@ -0,0 +1,113 @@ +// import 'package:ef/ef.dart'; +// import 'package:flutter/material.dart'; +// import 'package:vbvs_app/common/color/appConstants.dart'; +// import 'package:vbvs_app/common/util/FitTool.dart'; +// import 'package:vbvs_app/common/util/MyUtils.dart'; +// import 'package:vbvs_app/component/tool/CustomCard.dart'; +// import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart'; +// import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; +// import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; +// import 'package:vbvs_app/controller/user_info_controller.dart'; +// // import 'package:easydevice/easydevice.dart'; + + +// class AboutUsPage extends StatefulWidget { +// const AboutUsPage({super.key}); + +// @override +// State createState() => _AboutUsPageState(); +// } + +// class _AboutUsPageState extends State { +// GlobalController globalController = Get.find(); +// UserInfoController userInfoController = Get.find(); +// BlueteethBindController blueteethBindController = Get.find(); +// ThemeController themeController = Get.find(); + +// @override +// void initState() { +// super.initState(); +// } + +// @override +// Widget build(BuildContext context) { +// return LayoutBuilder( +// builder: (context, bodySize) => GestureDetector( +// onTap: () => FocusScope.of(context).unfocus(), +// child: Container( +// decoration: BoxDecoration( +// image: DecorationImage( +// image: AssetImage('assets/img/bgNoImg.png'), // 本地图片 +// fit: BoxFit.fill, // 填满整个 Container +// ), +// ), +// child: Scaffold( +// backgroundColor: Colors.transparent, // 加上这一行 +// appBar: AppBar( +// backgroundColor: themeController.currentColor.sc17, +// automaticallyImplyLeading: false, +// iconTheme: IconThemeData( +// color: themeController.currentColor.sc3, +// ), +// titleSpacing: 0, +// // leading: returnIconButtom, +// title: Container( +// width: double.infinity, +// height: 180.rpx, +// child: Stack( +// alignment: Alignment.center, +// children: [ +// /// 居中标题 +// Text( +// '关于我们.标题'.tr, +// style: FlutterFlowTheme.of(context).bodyMedium.override( +// fontFamily: 'Readex Pro', +// color: themeController.currentColor.sc3, +// letterSpacing: 0, +// fontSize: 30.rpx, +// ), +// ), + +// /// 左边返回按钮 +// Positioned( +// left: 0, +// child: returnIconButtom, +// ), +// ], +// ), +// ), + +// actions: [], +// centerTitle: false, +// ), +// body: SafeArea( +// top: true, +// child: Padding( +// padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0), +// child: SingleChildScrollView( +// child: Column( +// mainAxisSize: MainAxisSize.max, +// children: [ + +// SizedBox( +// height: 30.rpx, +// ), +// Text( +// "企业简介\n\n\n嘉兴太和信息技术有限公司成立于2013年,是一家以传感技术、室内定位技术和人工智能技术为基础的国家高新技术企业,AI非接触生命体征传感器、高精度室内外一体定位平台、AI视频分析系统、射频消融等技术成果,目前已经拥有30多类知识产权证书,多项专利技术处于行业领先水平。\n\n\n我司研发的“非接触式生命体征传感器”是一款基于BCG信号原理,通过检测人体心脏搏动引起的微小振动的传感器系统。传感器系统通过将人体微弱的心跳、呼吸信号转换未电信号,进行相关生命体征分析。该传感器可为用户提供高灵敏度和精确度检测结构,适用于需要非接触式、高分辨率的监测场景。该系统的硬件、软件及生产维护均由我司自主开发和管理,拥有完全自主知识产权,并已申请多项国家专利,可依据用户需求定制个性化方案。\n\n\n该产品置于床垫下方使用,全程完全无感。采集的体征数据通过睡眠健康管理平台实时显示用户的健康状态,并对每次的睡眠报告进行系统化归档管理,支持长期查询。一旦用户在使用过程中出现异常情况,系统可及时做出判断并反馈预警信息和建议。目前,心率监测的准确度可达97%以上,呼吸监测的准确度可达95%以上,其他生理指标的监测精度也显著优于同类产品。该产品主体材质均采用符合国家标准的环保材料,部分硅胶配件达到食品级安全标准。产品尺寸可根据需求进行定制,适用于单人床、双人床、婴儿床、椅子及枕头等多种场景。\n\n\n睡眠健康管理平台通过实时预警与远程管理,提升睡眠质量及慢病干预效率,助力养老院、月子中心、康复中心、智能寝具等行业降本增效,实现精准健康的科学管理。", +// style: TextStyle( +// fontSize: AppConstants().normal_text_fontSize, +// color: themeController.currentColor.sc3), +// ), +// ], +// ), +// ), +// ), +// ), +// ), +// ), +// ), +// ); +// } + + +// } diff --git a/lib/pages/user/privacy_scheme_page.dart b/lib/pages/user/privacy_scheme_page.dart new file mode 100644 index 0000000..4604ca4 --- /dev/null +++ b/lib/pages/user/privacy_scheme_page.dart @@ -0,0 +1,118 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_pdfview/flutter_pdfview.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/controller/setting/pdf/PrivacyPdfController.dart'; + +class PrivacySchemePage extends StatefulWidget { + PrivacySchemePage({super.key}); + + @override + State createState() => _PrivacySchemePageState(); +} + +class _PrivacySchemePageState extends State { + PrivacyPdfController pdfController = Get.find(); + + @override +void initState() { + super.initState(); + String language = "zh_CN"; // 默认语言 + + if (languageController.selectLanguage?.value?.language_code != null) { + language = languageController.selectLanguage!.value!.language_code!; + } + + pdfController.loadPdf(2, + "https://vsbst-api.he-info.cn/vsbs_sotrage/privacy-scheme/$language.pdf", + ); +} + + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (context, bodySize) => GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/img/bgNoImg.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, // 加上这一行 + appBar: AppBar( + backgroundColor: themeController.currentColor.sc17, + automaticallyImplyLeading: false, + iconTheme: IconThemeData( + color: themeController.currentColor.sc3, + ), + titleSpacing: 0, + // leading: returnIconButtom, + title: Container( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + /// 居中标题 + Text( + '隐私协议'.tr, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + color: themeController.currentColor.sc3, + letterSpacing: 0, + fontSize: 30.rpx, + ), + ), + + /// 左边返回按钮 + Positioned( + left: 0, + child: returnIconButtom, + ), + ], + ), + ), + + actions: [], + centerTitle: false, + ), + body: SafeArea( + top: true, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 30.rpx), + child: Column( + children: [ + Expanded( + child: Obx(() { + if (pdfController.localPdfPath.value == null) { + return Center(child: CircularProgressIndicator()); + } else { + return PDFView( + filePath: pdfController.localPdfPath.value!, + autoSpacing: false, + enableSwipe: true, + swipeHorizontal: false, + pageSnap: true, + fitEachPage: true, + defaultPage: 0, + onRender: (pages) => print('PDF 渲染完成,共 $pages 页'), + onError: (error) => print('PDF 加载错误: $error'), + ); + } + }), + ), + ], + ), + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/user/user_scheme_page.dart b/lib/pages/user/user_scheme_page.dart new file mode 100644 index 0000000..16320c8 --- /dev/null +++ b/lib/pages/user/user_scheme_page.dart @@ -0,0 +1,119 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_pdfview/flutter_pdfview.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/controller/setting/pdf/UserPdfController.dart'; + +class UserSchemePage extends StatefulWidget { + UserSchemePage({super.key}); + + @override + State createState() => _UserSchemePageState(); +} + +class _UserSchemePageState extends State { + UserPdfController pdfController = Get.find(); + + @override + void initState() { + super.initState(); + String language = "zh_CN"; // 默认语言 + + if (languageController.selectLanguage?.value?.language_code != null) { + language = languageController.selectLanguage!.value!.language_code!; + } + + pdfController.loadPdf( + 1, + "https://vsbst-api.he-info.cn/vsbs_sotrage/user-scheme/$language.pdf", + ); + } + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (context, bodySize) => GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/img/bgNoImg.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, // 加上这一行 + appBar: AppBar( + backgroundColor: themeController.currentColor.sc17, + automaticallyImplyLeading: false, + iconTheme: IconThemeData( + color: themeController.currentColor.sc3, + ), + titleSpacing: 0, + // leading: returnIconButtom, + title: Container( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + /// 居中标题 + Text( + '用户协议'.tr, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + color: themeController.currentColor.sc3, + letterSpacing: 0, + fontSize: 30.rpx, + ), + ), + + /// 左边返回按钮 + Positioned( + left: 0, + child: returnIconButtom, + ), + ], + ), + ), + + actions: [], + centerTitle: false, + ), + + body: SafeArea( + top: true, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 30.rpx), + child: Column( + children: [ + Expanded( + child: Obx(() { + if (pdfController.localPdfPath.value == null) { + return Center(child: CircularProgressIndicator()); + } else { + return PDFView( + filePath: pdfController.localPdfPath.value!, + autoSpacing: false, + enableSwipe: true, + swipeHorizontal: false, + pageSnap: true, + fitEachPage: true, + defaultPage: 0, + onRender: (pages) => print('PDF 渲染完成,共 $pages 页'), + onError: (error) => print('PDF 加载错误: $error'), + ); + } + }), + ), + ], + ), + ), + ), + ), + ), + ), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index d3ab8f2..5efad74 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -51,6 +51,7 @@ dependencies: flutter_pdfview: ^1.4.0+1 weather: ^3.1.1 geocoding: ^2.1.0 + # fl_chart: ^1.0.0 dev_dependencies: