From 9652b351892745e28f68394d6ce4b6b88b60c106 Mon Sep 17 00:00:00 2001 From: fy59 Date: Mon, 21 Sep 2026 17:09:24 +0200 Subject: [PATCH] fix(report): localize sleep diary pdf --- CHANGELOG.md | 7 + docs/current_state.md | 2 +- .../evidence/sleep-diary-fr-7-days.pdf | 391 ++++++++++++++++ .../evidence/sleep-diary-fr-7-days.png | Bin 0 -> 125384 bytes ...leep_diary_pdf_localization_v1_evidence.md | 42 ++ docs/tests.md | 7 + tests/test_web_sleep_browser.py | 171 ++++++- web/src/report/sleepDiaryPdf.test.ts | 253 +++++++++-- web/src/report/sleepDiaryPdf.ts | 417 +++++++++++++++--- 9 files changed, 1202 insertions(+), 88 deletions(-) create mode 100644 docs/reviews/evidence/sleep-diary-fr-7-days.pdf create mode 100644 docs/reviews/evidence/sleep-diary-fr-7-days.png create mode 100644 docs/reviews/sleep_diary_pdf_localization_v1_evidence.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 5146d6f..00a6581 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased — 0.1.4 +- Fully localized the French Sleep Diary PDF without changing its canonical + data source or event semantics. Column headings, timeline labels, legend, + factual summary, draft warning, dates and plurals are now French, accented + text uses the PDF WinAnsi encoding, and durations use human-readable units. + Long awakenings remain proportional intervals between independent sleep + ranges, while medication intake snapshots retain localized dose and unit. + The English report keeps an independent English vocabulary. - Made the Sleep Diary Agenda a live projection of the latest locally persisted entry revision. Event and intake mutations now re-read and adopt the canonical Core snapshot, serialized autosaves carry the returned diff --git a/docs/current_state.md b/docs/current_state.md index f953a05..45e500f 100644 --- a/docs/current_state.md +++ b/docs/current_state.md @@ -138,7 +138,7 @@ parallel implementation of its rules. | Web Dashboard tiles | `WEB_DASHBOARD_TILES_V1=PASS/FROZEN` | | Web Dashboard visualizations | `WEB_DASHBOARD_VISUALIZATIONS_V1=PASS/FROZEN` | | Web Dashboard V1 | `WEB_DASHBOARD_V1=PASS/FROZEN` | -| Sleep Diary V1 | Implemented on the 0.1.4 review branch: timestamped causal diary, stable Web/Android capture, full-generation companion and local vector PDF; the Web Agenda, Chronology and factual summary adopt the latest persisted revision without reload, medication choices expose dose/unit, and real-Firefox mutation/reload coverage plus a section-local error boundary protect capture | +| Sleep Diary V1 | Implemented on the 0.1.4 review branch: timestamped causal diary, stable Web/Android capture, full-generation companion and fully localized FR/EN local vector PDF; the Web Agenda, Chronology and factual summary adopt the latest persisted revision without reload, medication choices expose dose/unit, and real-Firefox mutation/reload coverage plus a section-local error boundary protect capture | | Web Sessions V1 | `TRAINLOG_WEB_SESSIONS_V1=PASS/FROZEN` (controlled desktop/Android deployment validated) | | Web Sessions deletion and Programs V1 | `TRAINLOG_WEB_SESSIONS_DELETE_AND_PROGRAMS_V1=PASS` (private grouped rollout validated) | | Programs presentation, Android projection, and deletion | `TRAINLOG_PROGRAMS_PRESENTATION_ANDROID_DELETE_V1=PASS` (private coordinated deployment and restart/replay validated) | diff --git a/docs/reviews/evidence/sleep-diary-fr-7-days.pdf b/docs/reviews/evidence/sleep-diary-fr-7-days.pdf new file mode 100644 index 0000000..6ccda4c --- /dev/null +++ b/docs/reviews/evidence/sleep-diary-fr-7-days.pdf @@ -0,0 +1,391 @@ +%PDF-1.4 +%Trainlog +1 0 obj +<< /Type /Catalog /Pages 2 0 R >> +endobj +2 0 obj +<< /Type /Pages /Kids [4 0 R] /Count 1 >> +endobj +3 0 obj +<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >> +endobj +4 0 obj +<< /Type /Page /Parent 2 0 R /MediaBox [0 0 842 595] /Resources << /Font << /F1 3 0 R >> >> /Contents 5 0 R >> +endobj +5 0 obj +<< /Length 17914 >> +stream +0 G 0 g +0 g BT /F1 14 Tf 30.0 565.0 Td (AGENDA TRAINLOG DE VIGILANCE ET DE SOMMEIL) Tj ET +0 g BT /F1 7 Tf 740.0 565.0 Td (1/1) Tj ET +0 g BT /F1 7 Tf 30.0 548.0 Td (DATE) Tj ET +0 g BT /F1 4 Tf 112.0 548.0 Td (18) Tj ET +0 g BT /F1 4 Tf 132.8 548.0 Td (19) Tj ET +0 g BT /F1 4 Tf 153.7 548.0 Td (20) Tj ET +0 g BT /F1 4 Tf 174.5 548.0 Td (21) Tj ET +0 g BT /F1 4 Tf 195.3 548.0 Td (22) Tj ET +0 g BT /F1 4 Tf 216.2 548.0 Td (23) Tj ET +0 g BT /F1 4 Tf 237.0 548.0 Td (0) Tj ET +0 g BT /F1 4 Tf 257.8 548.0 Td (1) Tj ET +0 g BT /F1 4 Tf 278.7 548.0 Td (2) Tj ET +0 g BT /F1 4 Tf 299.5 548.0 Td (3) Tj ET +0 g BT /F1 4 Tf 320.3 548.0 Td (4) Tj ET +0 g BT /F1 4 Tf 341.2 548.0 Td (5) Tj ET +0 g BT /F1 4 Tf 362.0 548.0 Td (6) Tj ET +0 g BT /F1 4 Tf 382.8 548.0 Td (7) Tj ET +0 g BT /F1 4 Tf 403.7 548.0 Td (8) Tj ET +0 g BT /F1 4 Tf 424.5 548.0 Td (9) Tj ET +0 g BT /F1 4 Tf 445.3 548.0 Td (10) Tj ET +0 g BT /F1 4 Tf 466.2 548.0 Td (11) Tj ET +0 g BT /F1 4 Tf 487.0 548.0 Td (12) Tj ET +0 g BT /F1 4 Tf 507.8 548.0 Td (13) Tj ET +0 g BT /F1 4 Tf 528.7 548.0 Td (14) Tj ET +0 g BT /F1 4 Tf 549.5 548.0 Td (15) Tj ET +0 g BT /F1 4 Tf 570.3 548.0 Td (16) Tj ET +0 g BT /F1 4 Tf 591.2 548.0 Td (17) Tj ET +0 g BT /F1 4 Tf 612.0 548.0 Td (18) Tj ET +0 g BT /F1 4 Tf 616.0 552.0 Td (QUALIT\311 DU) Tj ET +0 g BT /F1 4 Tf 616.0 545.0 Td (SOMMEIL) Tj ET +0 g BT /F1 4 Tf 654.0 552.0 Td (QUALIT\311 DU) Tj ET +0 g BT /F1 4 Tf 654.0 545.0 Td (R\311VEIL) Tj ET +0 g BT /F1 4 Tf 692.0 552.0 Td (FORME DE LA) Tj ET +0 g BT /F1 4 Tf 692.0 545.0 Td (JOURN\311E) Tj ET +0 g BT /F1 4 Tf 728.0 552.0 Td (TRAITEMENT ET) Tj ET +0 g BT /F1 4 Tf 728.0 545.0 Td (REMARQUES) Tj ET +0.7 G 30 498 782 40 re S +0 g BT /F1 5 Tf 33.0 525.0 Td (20/09/2026) Tj ET +0 g BT /F1 5 Tf 33.0 515.0 Td (au 21/09/2026) Tj ET +0.9 G 112 498 m 112 538 l S +0.9 G 132.83333333333334 498 m 132.83333333333334 538 l S +0.9 G 153.66666666666666 498 m 153.66666666666666 538 l S +0.9 G 174.5 498 m 174.5 538 l S +0.9 G 195.33333333333331 498 m 195.33333333333331 538 l S +0.9 G 216.16666666666669 498 m 216.16666666666669 538 l S +0.9 G 237 498 m 237 538 l S +0.9 G 257.83333333333337 498 m 257.83333333333337 538 l S +0.9 G 278.66666666666663 498 m 278.66666666666663 538 l S +0.9 G 299.5 498 m 299.5 538 l S +0.9 G 320.33333333333337 498 m 320.33333333333337 538 l S +0.9 G 341.16666666666663 498 m 341.16666666666663 538 l S +0.9 G 362 498 m 362 538 l S +0.9 G 382.8333333333333 498 m 382.8333333333333 538 l S +0.9 G 403.6666666666667 498 m 403.6666666666667 538 l S +0.9 G 424.5 498 m 424.5 538 l S +0.9 G 445.3333333333333 498 m 445.3333333333333 538 l S +0.9 G 466.1666666666667 498 m 466.1666666666667 538 l S +0.9 G 487 498 m 487 538 l S +0.9 G 507.8333333333333 498 m 507.8333333333333 538 l S +0.9 G 528.6666666666667 498 m 528.6666666666667 538 l S +0.9 G 549.5 498 m 549.5 538 l S +0.9 G 570.3333333333333 498 m 570.3333333333333 538 l S +0.9 G 591.1666666666667 498 m 591.1666666666667 538 l S +0.9 G 612 498 m 612 538 l S +0 g BT /F1 8 Tf 211.0 513.0 Td (v) Tj ET +0.75 g 221.38 509.00 78.13 18.00 re f 0 G 221.38 509.00 78.13 18.00 re S +0 g BT /F1 5 Tf 223.4 515.0 Td (SOMMEIL) Tj ET +0.5 g 299.50 509.00 10.42 18.00 re f 0 G 299.50 509.00 10.42 18.00 re S +0.75 g 309.92 509.00 67.71 18.00 re f 0 G 309.92 509.00 67.71 18.00 re S +0 g BT /F1 5 Tf 311.9 515.0 Td (SOMMEIL) Tj ET +0 g BT /F1 8 Tf 386.3 513.0 Td (^) Tj ET +0 g BT /F1 6 Tf 195.3 502.0 Td (M) Tj ET +0 g BT /F1 6 Tf 195.3 502.0 Td (M) Tj ET +0 g BT /F1 7 Tf 620.0 522.0 Td (-) Tj ET +0 g BT /F1 7 Tf 658.0 522.0 Td (-) Tj ET +0 g BT /F1 7 Tf 696.0 522.0 Td (-) Tj ET +0 g BT /F1 4 Tf 730.0 531.0 Td (22:00 \227 venlafaxine \227 37,5 mg ; 22:00 \227 ) Tj ET +0 g BT /F1 4 Tf 730.0 522.0 Td (venlafaxine \227 75 mg) Tj ET +0 g BT /F1 4 Tf 730.0 513.0 Td () Tj ET +0 g BT /F1 4 Tf 730.0 504.0 Td () Tj ET +0.7 G 30 458 782 40 re S +0 g BT /F1 5 Tf 33.0 485.0 Td (19/09/2026) Tj ET +0 g BT /F1 5 Tf 33.0 475.0 Td (au 20/09/2026) Tj ET +0.9 G 112 458 m 112 498 l S +0.9 G 132.83333333333334 458 m 132.83333333333334 498 l S +0.9 G 153.66666666666666 458 m 153.66666666666666 498 l S +0.9 G 174.5 458 m 174.5 498 l S +0.9 G 195.33333333333331 458 m 195.33333333333331 498 l S +0.9 G 216.16666666666669 458 m 216.16666666666669 498 l S +0.9 G 237 458 m 237 498 l S +0.9 G 257.83333333333337 458 m 257.83333333333337 498 l S +0.9 G 278.66666666666663 458 m 278.66666666666663 498 l S +0.9 G 299.5 458 m 299.5 498 l S +0.9 G 320.33333333333337 458 m 320.33333333333337 498 l S +0.9 G 341.16666666666663 458 m 341.16666666666663 498 l S +0.9 G 362 458 m 362 498 l S +0.9 G 382.8333333333333 458 m 382.8333333333333 498 l S +0.9 G 403.6666666666667 458 m 403.6666666666667 498 l S +0.9 G 424.5 458 m 424.5 498 l S +0.9 G 445.3333333333333 458 m 445.3333333333333 498 l S +0.9 G 466.1666666666667 458 m 466.1666666666667 498 l S +0.9 G 487 458 m 487 498 l S +0.9 G 507.8333333333333 458 m 507.8333333333333 498 l S +0.9 G 528.6666666666667 458 m 528.6666666666667 498 l S +0.9 G 549.5 458 m 549.5 498 l S +0.9 G 570.3333333333333 458 m 570.3333333333333 498 l S +0.9 G 591.1666666666667 458 m 591.1666666666667 498 l S +0.9 G 612 458 m 612 498 l S +0 g BT /F1 8 Tf 205.8 473.0 Td (v) Tj ET +0.75 g 216.17 469.00 83.33 18.00 re f 0 G 216.17 469.00 83.33 18.00 re S +0 g BT /F1 5 Tf 218.2 475.0 Td (SOMMEIL) Tj ET +0.5 g 299.50 469.00 15.63 18.00 re f 0 G 299.50 469.00 15.63 18.00 re S +0.75 g 315.13 469.00 67.71 18.00 re f 0 G 315.13 469.00 67.71 18.00 re S +0 g BT /F1 5 Tf 317.1 475.0 Td (SOMMEIL) Tj ET +0.87 g 382.83 469.00 3.47 18.00 re f 0 G 382.83 469.00 3.47 18.00 re S +0 g BT /F1 8 Tf 388.0 473.0 Td (^) Tj ET +0.93 g 528.67 469.00 12.15 18.00 re f 0 G 528.67 469.00 12.15 18.00 re S +0 g BT /F1 8 Tf 549.5 473.0 Td (S) Tj ET +0 g BT /F1 7 Tf 620.0 482.0 Td (B) Tj ET +0 g BT /F1 7 Tf 658.0 482.0 Td (Moy) Tj ET +0 g BT /F1 7 Tf 696.0 482.0 Td (TB) Tj ET +0 g BT /F1 4 Tf 730.0 491.0 Td (Remarque fran\347aise synth\351tique.) Tj ET +0 g BT /F1 4 Tf 730.0 482.0 Td () Tj ET +0 g BT /F1 4 Tf 730.0 473.0 Td () Tj ET +0 g BT /F1 4 Tf 730.0 464.0 Td () Tj ET +0.7 G 30 418 782 40 re S +0 g BT /F1 5 Tf 33.0 445.0 Td (18/09/2026) Tj ET +0 g BT /F1 5 Tf 33.0 435.0 Td (au 19/09/2026) Tj ET +0.9 G 112 418 m 112 458 l S +0.9 G 132.83333333333334 418 m 132.83333333333334 458 l S +0.9 G 153.66666666666666 418 m 153.66666666666666 458 l S +0.9 G 174.5 418 m 174.5 458 l S +0.9 G 195.33333333333331 418 m 195.33333333333331 458 l S +0.9 G 216.16666666666669 418 m 216.16666666666669 458 l S +0.9 G 237 418 m 237 458 l S +0.9 G 257.83333333333337 418 m 257.83333333333337 458 l S +0.9 G 278.66666666666663 418 m 278.66666666666663 458 l S +0.9 G 299.5 418 m 299.5 458 l S +0.9 G 320.33333333333337 418 m 320.33333333333337 458 l S +0.9 G 341.16666666666663 418 m 341.16666666666663 458 l S +0.9 G 362 418 m 362 458 l S +0.9 G 382.8333333333333 418 m 382.8333333333333 458 l S +0.9 G 403.6666666666667 418 m 403.6666666666667 458 l S +0.9 G 424.5 418 m 424.5 458 l S +0.9 G 445.3333333333333 418 m 445.3333333333333 458 l S +0.9 G 466.1666666666667 418 m 466.1666666666667 458 l S +0.9 G 487 418 m 487 458 l S +0.9 G 507.8333333333333 418 m 507.8333333333333 458 l S +0.9 G 528.6666666666667 418 m 528.6666666666667 458 l S +0.9 G 549.5 418 m 549.5 458 l S +0.9 G 570.3333333333333 418 m 570.3333333333333 458 l S +0.9 G 591.1666666666667 418 m 591.1666666666667 458 l S +0.9 G 612 418 m 612 458 l S +0 g BT /F1 8 Tf 205.8 433.0 Td (v) Tj ET +0.75 g 216.17 429.00 83.33 18.00 re f 0 G 216.17 429.00 83.33 18.00 re S +0 g BT /F1 5 Tf 218.2 435.0 Td (SOMMEIL) Tj ET +0.5 g 299.50 429.00 15.63 18.00 re f 0 G 299.50 429.00 15.63 18.00 re S +0.75 g 315.13 429.00 67.71 18.00 re f 0 G 315.13 429.00 67.71 18.00 re S +0 g BT /F1 5 Tf 317.1 435.0 Td (SOMMEIL) Tj ET +0.87 g 382.83 429.00 3.47 18.00 re f 0 G 382.83 429.00 3.47 18.00 re S +0 g BT /F1 8 Tf 388.0 433.0 Td (^) Tj ET +0.93 g 528.67 429.00 12.15 18.00 re f 0 G 528.67 429.00 12.15 18.00 re S +0 g BT /F1 8 Tf 549.5 433.0 Td (S) Tj ET +0 g BT /F1 7 Tf 620.0 442.0 Td (B) Tj ET +0 g BT /F1 7 Tf 658.0 442.0 Td (Moy) Tj ET +0 g BT /F1 7 Tf 696.0 442.0 Td (TB) Tj ET +0 g BT /F1 4 Tf 730.0 451.0 Td (Remarque fran\347aise synth\351tique.) Tj ET +0 g BT /F1 4 Tf 730.0 442.0 Td () Tj ET +0 g BT /F1 4 Tf 730.0 433.0 Td () Tj ET +0 g BT /F1 4 Tf 730.0 424.0 Td () Tj ET +0.7 G 30 378 782 40 re S +0 g BT /F1 5 Tf 33.0 405.0 Td (17/09/2026) Tj ET +0 g BT /F1 5 Tf 33.0 395.0 Td (au 18/09/2026) Tj ET +0.9 G 112 378 m 112 418 l S +0.9 G 132.83333333333334 378 m 132.83333333333334 418 l S +0.9 G 153.66666666666666 378 m 153.66666666666666 418 l S +0.9 G 174.5 378 m 174.5 418 l S +0.9 G 195.33333333333331 378 m 195.33333333333331 418 l S +0.9 G 216.16666666666669 378 m 216.16666666666669 418 l S +0.9 G 237 378 m 237 418 l S +0.9 G 257.83333333333337 378 m 257.83333333333337 418 l S +0.9 G 278.66666666666663 378 m 278.66666666666663 418 l S +0.9 G 299.5 378 m 299.5 418 l S +0.9 G 320.33333333333337 378 m 320.33333333333337 418 l S +0.9 G 341.16666666666663 378 m 341.16666666666663 418 l S +0.9 G 362 378 m 362 418 l S +0.9 G 382.8333333333333 378 m 382.8333333333333 418 l S +0.9 G 403.6666666666667 378 m 403.6666666666667 418 l S +0.9 G 424.5 378 m 424.5 418 l S +0.9 G 445.3333333333333 378 m 445.3333333333333 418 l S +0.9 G 466.1666666666667 378 m 466.1666666666667 418 l S +0.9 G 487 378 m 487 418 l S +0.9 G 507.8333333333333 378 m 507.8333333333333 418 l S +0.9 G 528.6666666666667 378 m 528.6666666666667 418 l S +0.9 G 549.5 378 m 549.5 418 l S +0.9 G 570.3333333333333 378 m 570.3333333333333 418 l S +0.9 G 591.1666666666667 378 m 591.1666666666667 418 l S +0.9 G 612 378 m 612 418 l S +0 g BT /F1 8 Tf 205.8 393.0 Td (v) Tj ET +0.75 g 216.17 389.00 83.33 18.00 re f 0 G 216.17 389.00 83.33 18.00 re S +0 g BT /F1 5 Tf 218.2 395.0 Td (SOMMEIL) Tj ET +0.5 g 299.50 389.00 15.63 18.00 re f 0 G 299.50 389.00 15.63 18.00 re S +0.75 g 315.13 389.00 67.71 18.00 re f 0 G 315.13 389.00 67.71 18.00 re S +0 g BT /F1 5 Tf 317.1 395.0 Td (SOMMEIL) Tj ET +0.87 g 382.83 389.00 3.47 18.00 re f 0 G 382.83 389.00 3.47 18.00 re S +0 g BT /F1 8 Tf 388.0 393.0 Td (^) Tj ET +0.93 g 528.67 389.00 12.15 18.00 re f 0 G 528.67 389.00 12.15 18.00 re S +0 g BT /F1 8 Tf 549.5 393.0 Td (S) Tj ET +0 g BT /F1 7 Tf 620.0 402.0 Td (B) Tj ET +0 g BT /F1 7 Tf 658.0 402.0 Td (Moy) Tj ET +0 g BT /F1 7 Tf 696.0 402.0 Td (TB) Tj ET +0 g BT /F1 4 Tf 730.0 411.0 Td (Remarque fran\347aise synth\351tique.) Tj ET +0 g BT /F1 4 Tf 730.0 402.0 Td () Tj ET +0 g BT /F1 4 Tf 730.0 393.0 Td () Tj ET +0 g BT /F1 4 Tf 730.0 384.0 Td () Tj ET +0.7 G 30 338 782 40 re S +0 g BT /F1 5 Tf 33.0 365.0 Td (16/09/2026) Tj ET +0 g BT /F1 5 Tf 33.0 355.0 Td (au 17/09/2026) Tj ET +0.9 G 112 338 m 112 378 l S +0.9 G 132.83333333333334 338 m 132.83333333333334 378 l S +0.9 G 153.66666666666666 338 m 153.66666666666666 378 l S +0.9 G 174.5 338 m 174.5 378 l S +0.9 G 195.33333333333331 338 m 195.33333333333331 378 l S +0.9 G 216.16666666666669 338 m 216.16666666666669 378 l S +0.9 G 237 338 m 237 378 l S +0.9 G 257.83333333333337 338 m 257.83333333333337 378 l S +0.9 G 278.66666666666663 338 m 278.66666666666663 378 l S +0.9 G 299.5 338 m 299.5 378 l S +0.9 G 320.33333333333337 338 m 320.33333333333337 378 l S +0.9 G 341.16666666666663 338 m 341.16666666666663 378 l S +0.9 G 362 338 m 362 378 l S +0.9 G 382.8333333333333 338 m 382.8333333333333 378 l S +0.9 G 403.6666666666667 338 m 403.6666666666667 378 l S +0.9 G 424.5 338 m 424.5 378 l S +0.9 G 445.3333333333333 338 m 445.3333333333333 378 l S +0.9 G 466.1666666666667 338 m 466.1666666666667 378 l S +0.9 G 487 338 m 487 378 l S +0.9 G 507.8333333333333 338 m 507.8333333333333 378 l S +0.9 G 528.6666666666667 338 m 528.6666666666667 378 l S +0.9 G 549.5 338 m 549.5 378 l S +0.9 G 570.3333333333333 338 m 570.3333333333333 378 l S +0.9 G 591.1666666666667 338 m 591.1666666666667 378 l S +0.9 G 612 338 m 612 378 l S +0 g BT /F1 8 Tf 205.8 353.0 Td (v) Tj ET +0.75 g 216.17 349.00 83.33 18.00 re f 0 G 216.17 349.00 83.33 18.00 re S +0 g BT /F1 5 Tf 218.2 355.0 Td (SOMMEIL) Tj ET +0.5 g 299.50 349.00 15.63 18.00 re f 0 G 299.50 349.00 15.63 18.00 re S +0.75 g 315.13 349.00 67.71 18.00 re f 0 G 315.13 349.00 67.71 18.00 re S +0 g BT /F1 5 Tf 317.1 355.0 Td (SOMMEIL) Tj ET +0.87 g 382.83 349.00 3.47 18.00 re f 0 G 382.83 349.00 3.47 18.00 re S +0 g BT /F1 8 Tf 388.0 353.0 Td (^) Tj ET +0.93 g 528.67 349.00 12.15 18.00 re f 0 G 528.67 349.00 12.15 18.00 re S +0 g BT /F1 8 Tf 549.5 353.0 Td (S) Tj ET +0 g BT /F1 7 Tf 620.0 362.0 Td (B) Tj ET +0 g BT /F1 7 Tf 658.0 362.0 Td (Moy) Tj ET +0 g BT /F1 7 Tf 696.0 362.0 Td (TB) Tj ET +0 g BT /F1 4 Tf 730.0 371.0 Td (Remarque fran\347aise synth\351tique.) Tj ET +0 g BT /F1 4 Tf 730.0 362.0 Td () Tj ET +0 g BT /F1 4 Tf 730.0 353.0 Td () Tj ET +0 g BT /F1 4 Tf 730.0 344.0 Td () Tj ET +0.7 G 30 298 782 40 re S +0 g BT /F1 5 Tf 33.0 325.0 Td (15/09/2026) Tj ET +0 g BT /F1 5 Tf 33.0 315.0 Td (au 16/09/2026) Tj ET +0.9 G 112 298 m 112 338 l S +0.9 G 132.83333333333334 298 m 132.83333333333334 338 l S +0.9 G 153.66666666666666 298 m 153.66666666666666 338 l S +0.9 G 174.5 298 m 174.5 338 l S +0.9 G 195.33333333333331 298 m 195.33333333333331 338 l S +0.9 G 216.16666666666669 298 m 216.16666666666669 338 l S +0.9 G 237 298 m 237 338 l S +0.9 G 257.83333333333337 298 m 257.83333333333337 338 l S +0.9 G 278.66666666666663 298 m 278.66666666666663 338 l S +0.9 G 299.5 298 m 299.5 338 l S +0.9 G 320.33333333333337 298 m 320.33333333333337 338 l S +0.9 G 341.16666666666663 298 m 341.16666666666663 338 l S +0.9 G 362 298 m 362 338 l S +0.9 G 382.8333333333333 298 m 382.8333333333333 338 l S +0.9 G 403.6666666666667 298 m 403.6666666666667 338 l S +0.9 G 424.5 298 m 424.5 338 l S +0.9 G 445.3333333333333 298 m 445.3333333333333 338 l S +0.9 G 466.1666666666667 298 m 466.1666666666667 338 l S +0.9 G 487 298 m 487 338 l S +0.9 G 507.8333333333333 298 m 507.8333333333333 338 l S +0.9 G 528.6666666666667 298 m 528.6666666666667 338 l S +0.9 G 549.5 298 m 549.5 338 l S +0.9 G 570.3333333333333 298 m 570.3333333333333 338 l S +0.9 G 591.1666666666667 298 m 591.1666666666667 338 l S +0.9 G 612 298 m 612 338 l S +0 g BT /F1 8 Tf 205.8 313.0 Td (v) Tj ET +0.75 g 216.17 309.00 83.33 18.00 re f 0 G 216.17 309.00 83.33 18.00 re S +0 g BT /F1 5 Tf 218.2 315.0 Td (SOMMEIL) Tj ET +0.5 g 299.50 309.00 15.63 18.00 re f 0 G 299.50 309.00 15.63 18.00 re S +0.75 g 315.13 309.00 67.71 18.00 re f 0 G 315.13 309.00 67.71 18.00 re S +0 g BT /F1 5 Tf 317.1 315.0 Td (SOMMEIL) Tj ET +0.87 g 382.83 309.00 3.47 18.00 re f 0 G 382.83 309.00 3.47 18.00 re S +0 g BT /F1 8 Tf 388.0 313.0 Td (^) Tj ET +0.93 g 528.67 309.00 12.15 18.00 re f 0 G 528.67 309.00 12.15 18.00 re S +0 g BT /F1 8 Tf 549.5 313.0 Td (S) Tj ET +0 g BT /F1 7 Tf 620.0 322.0 Td (B) Tj ET +0 g BT /F1 7 Tf 658.0 322.0 Td (Moy) Tj ET +0 g BT /F1 7 Tf 696.0 322.0 Td (TB) Tj ET +0 g BT /F1 4 Tf 730.0 331.0 Td (Remarque fran\347aise synth\351tique.) Tj ET +0 g BT /F1 4 Tf 730.0 322.0 Td () Tj ET +0 g BT /F1 4 Tf 730.0 313.0 Td () Tj ET +0 g BT /F1 4 Tf 730.0 304.0 Td () Tj ET +0.7 G 30 258 782 40 re S +0 g BT /F1 5 Tf 33.0 285.0 Td (14/09/2026) Tj ET +0 g BT /F1 5 Tf 33.0 275.0 Td (au 15/09/2026) Tj ET +0.9 G 112 258 m 112 298 l S +0.9 G 132.83333333333334 258 m 132.83333333333334 298 l S +0.9 G 153.66666666666666 258 m 153.66666666666666 298 l S +0.9 G 174.5 258 m 174.5 298 l S +0.9 G 195.33333333333331 258 m 195.33333333333331 298 l S +0.9 G 216.16666666666669 258 m 216.16666666666669 298 l S +0.9 G 237 258 m 237 298 l S +0.9 G 257.83333333333337 258 m 257.83333333333337 298 l S +0.9 G 278.66666666666663 258 m 278.66666666666663 298 l S +0.9 G 299.5 258 m 299.5 298 l S +0.9 G 320.33333333333337 258 m 320.33333333333337 298 l S +0.9 G 341.16666666666663 258 m 341.16666666666663 298 l S +0.9 G 362 258 m 362 298 l S +0.9 G 382.8333333333333 258 m 382.8333333333333 298 l S +0.9 G 403.6666666666667 258 m 403.6666666666667 298 l S +0.9 G 424.5 258 m 424.5 298 l S +0.9 G 445.3333333333333 258 m 445.3333333333333 298 l S +0.9 G 466.1666666666667 258 m 466.1666666666667 298 l S +0.9 G 487 258 m 487 298 l S +0.9 G 507.8333333333333 258 m 507.8333333333333 298 l S +0.9 G 528.6666666666667 258 m 528.6666666666667 298 l S +0.9 G 549.5 258 m 549.5 298 l S +0.9 G 570.3333333333333 258 m 570.3333333333333 298 l S +0.9 G 591.1666666666667 258 m 591.1666666666667 298 l S +0.9 G 612 258 m 612 298 l S +0 g BT /F1 8 Tf 205.8 273.0 Td (v) Tj ET +0.75 g 216.17 269.00 83.33 18.00 re f 0 G 216.17 269.00 83.33 18.00 re S +0 g BT /F1 5 Tf 218.2 275.0 Td (SOMMEIL) Tj ET +0.5 g 299.50 269.00 15.63 18.00 re f 0 G 299.50 269.00 15.63 18.00 re S +0.75 g 315.13 269.00 67.71 18.00 re f 0 G 315.13 269.00 67.71 18.00 re S +0 g BT /F1 5 Tf 317.1 275.0 Td (SOMMEIL) Tj ET +0.87 g 382.83 269.00 3.47 18.00 re f 0 G 382.83 269.00 3.47 18.00 re S +0 g BT /F1 8 Tf 388.0 273.0 Td (^) Tj ET +0.93 g 528.67 269.00 12.15 18.00 re f 0 G 528.67 269.00 12.15 18.00 re S +0 g BT /F1 8 Tf 549.5 273.0 Td (S) Tj ET +0 g BT /F1 7 Tf 620.0 282.0 Td (B) Tj ET +0 g BT /F1 7 Tf 658.0 282.0 Td (Moy) Tj ET +0 g BT /F1 7 Tf 696.0 282.0 Td (TB) Tj ET +0 g BT /F1 4 Tf 730.0 291.0 Td (Remarque fran\347aise synth\351tique.) Tj ET +0 g BT /F1 4 Tf 730.0 282.0 Td () Tj ET +0 g BT /F1 4 Tf 730.0 273.0 Td () Tj ET +0 g BT /F1 4 Tf 730.0 264.0 Td () Tj ET +0 g BT /F1 9 Tf 30.0 240.0 Td (OBSERVATIONS) Tj ET +0 g BT /F1 6 Tf 30.0 226.0 Td (7 nuits \267 Sommeil d\351clar\351 : 50 h 30 min \267 Longs r\351veils : 7 \267 Siestes : 6 \267 Somnolences : 6 \267 Prises de m\351dicaments : 2) Tj ET +0 g BT /F1 6 Tf 30.0 216.0 Td (AVERTISSEMENT : 7 jours non valid\351s dans cet export.) Tj ET +0 g BT /F1 6 Tf 30.0 204.0 Td (19/09/2026 : Remarque fran\347aise synth\351tique.) Tj ET +0 g BT /F1 6 Tf 30.0 194.0 Td (18/09/2026 : Remarque fran\347aise synth\351tique.) Tj ET +0 g BT /F1 6 Tf 30.0 184.0 Td (17/09/2026 : Remarque fran\347aise synth\351tique.) Tj ET +0 g BT /F1 6 Tf 30.0 28.0 Td (L\351gende : v Mise au lit ; ^ Lever ; ^ Lever nocturne ; S Somnolence ; M Prise de m\351dicament.) Tj ET +0 g BT /F1 6 Tf 30.0 18.0 Td (Sommeil : plage de sommeil ; Sieste : plage de sieste ; Long r\351veil : interruption prolong\351e ; Demi-sommeil : plage de demi-sommeil.) Tj ET +endstream +endobj +xref +0 6 +0000000000 65535 f +0000000019 00000 n +0000000068 00000 n +0000000125 00000 n +0000000222 00000 n +0000000348 00000 n +trailer +<< /Size 6 /Root 1 0 R >> +startxref +18314 +%%EOF diff --git a/docs/reviews/evidence/sleep-diary-fr-7-days.png b/docs/reviews/evidence/sleep-diary-fr-7-days.png new file mode 100644 index 0000000000000000000000000000000000000000..bd1c2fe2c0f7238cc7c0de2d4b1c7c025e5bc252 GIT binary patch literal 125384 zcmeFZc|6tY`#!2knq(*<(JC2AWGI=lG7BM7rb4F3Oc~pyQj$!WLgvhwGKCaMk(taz zW`&T@^7MMk#uE5&B~&5ZxlDE@DUt(=Yn85un_>3^F(vCT@5ksT(Jmy*16vvZ>7mR@Za zi^MelQ8V=yjl@i>YVF+yCc_hH&@Dzkenp zdnhSI^WX1Sw^Pgi_nW6oQmmW){qCGSRlwGNzagvn|9|N3TKvCwA&OY0g4NX3gMxxa z$2V;u=iuagSY#|OFE1q}b>YGV0|NskC8Y!g;J zmW2D_Q>vz7r|}y-#iun(O-xMQxGg-PGP-&-HX~!rY0u)%o)QKIh8PL2wuXj==H`Q^ zuAH0dEv=H+9QxVs@niSj6FSb$&N@0eU9YW`E?f|Ho-n_9wZbU7Oh960W+q15Behgt zMn*; zhLE6@We^b&apZWZ>dsSwf(xx_THaLr{QO(CY%yJV|6p%gTAFU2`PFOJ=A9M8Y%&oSSo8?rdtxsaSDPR{k>Ho;5nI93`A@-Sw=f;obZ9;ku<~U5eOMqJu+2 zX^B66{2<@U+|9ATFqCOzZJiMpM-;R_``oNPnwp5`F|)LM6$H&KyceQ{0s$Cm*hM%9dJKJkx-ErkdO^~#i&5w@( z`7RR96JaC%esetv;f z$2-&9gW11lfBiD&)6!~}Ne?YwU-tdU%*3>sSaoxDsBSsB1_u*I?UIJZv1N+Z*4CBZ zleD`Z>=^6F9S%96byKvLe(+OktA6QR zkC8jvxN$?7A|N!Bhl7Jkf7DOyb||-gT+Ne1B5Z|GEIqu%M!*%jx!Hu3ysaup36cm({H|E}#xz1ZocIG2ns9d;U zb!w&~*KC`}R#HC5*POlJ5y0XU}L*a_0A}J z_wLNLt#|K;ii*B$KEA#O zB|P7hmU={$mX;|iDb?ZpvnfUV7#Wevdck(uc|x1ZdsFS-AA<1LEx3Uc(IA^HT#EH?d8s-V zo`Lv^JY$WNU@TKxif`&AHsV|nI{ zaTRyB7nnEppHNbSZ%vzJAjm5q&(S#+@`h<&oFAZv<3 zlz9q=k+hdMRbpHJ8l2tV?rL;eL>`8zGcNFIYX zi+vmG1@23~c-AWMboh8tRB^Gf*~T9zU0ht)q9dcDJ-@yECtlWHQ%fsLzvQ(_jQD(r z7pmS}jgBjuCDoIadrI93Mg(e|mM071mmMcN=ZESdYh&_44b{}tu3Wit?%X*XaAd`_ z)YRWUdvyD#8PiM(^)l1aP8@n(c5|j*De}yY-~Eq$eY;*=eV?IQ(BI!rck;61&u*dE z9=zijyM8Ix0w$a`q?PTIOdlO3R;S80umZ?un(FGaT{h)|gM*WO<>h71v2U!$jyX+y z%`V$YO-+p|+rQ7|+_~E$x|LPF^an-d;=9fMB#v`5p0C7XUcY`lHxqd4&hl`K*O+4M zciXTX8Q2fazALq_UY)vj?HbW1J$(YTcZ@0jq=2IqlcVFS=iM87cJk=t{P308&L968 zp?-PT01v=#_9emM{+@$uN7xZ#i8W`eJ6n>J4ibI-`9~59AlSBz-x>xIURVX9rVJ`+i0hgu(0uebuo7~VnIZ8*p7TeWl7 zE?U*a05*V{A6r)+AqtfS&zkCvRgoX3HMnmSwi)H!YH zCnYsqqpJ32nfm@+GR8n^caNCuH?pW`ub^ z+LYJEQSZDPJ;DM4d1Y0$KL!W=StM@Q*r>Q%?T@~6 z^XAPfR}K>r@UgTq^-^qPE_ryYJ$*{WnE7jd-a1{qp}oD_VVF|iY-pj+3pLujsrr=F z*HfMUkSe+!cfl6{;3P*sdUp2YWrg^qeJ>~sU98ua$FsbtC?Dk7et*ZaT1`tgENG~OY$HDm=$E;N%j?AO z8dr00a0CYj`z%Jsoqz4*=(v?W?+=o?J=MNRm++$svsNXKubJau{y1J$ID3`}1et zvUO5CUQkz6l{DtX)(DztDidX;evg!*M=u`&=xA9u;a)nR8-=}=46%e6E#^c5)-A(8q!|AJnOOS z81#B8l7ujo2o79X3Qd{g$JZ^pUfE^UU44JQkvSh|fo6l~x%BIrxj6^Hqlj@PuzDwisWrY$Rr_rW+48bRf3qO0rL`5kG=nt-5 zz3OOeV8A>nu<)6u{OsAY0ym!;e|S>$=j&lnuWwj)cegp$R9l9wQqO@f>cV{XkMZUO zTzmHH5zaBlGgZ6o=Vtx0uRO+p6JYRTeLel~K-hHu^8C1T@Kc#oax>Yv)czy`@Wm%o3g#C;~!4uCd9kJnOWfoF`J;nj4|s zL(BiZ_F(1XoP_#e@24m=O&TFpRyCcSoq5Nuqvz}|%Cl^Jlo?G*4b_vfdb%h$<}n>7 zv@%-OvbFKB8A1+%!FgHF7e}?ZM)X7e9K8ZFa0PNG&MB#i#?8L1PYM6 zOHNHZa`fou&!6x0Udz@NkkU4j3j8q8*!!v9y$yX5vMBZ;EX!09p_7@(UAOzsdajar zKKEhe|ISFOiE@|Z--hll|Gm6paCli+SwKKzftM?Qx!rjw$LoP;xMyY%Ln-O$&qZ8r z43IklUCJ7wknbqfxOnm0$}b!&a|??`zdGx0XZ$~ixXy7zHCp|i=x|cDSxC(1Nn*>O zCsO3TDa_B$4=b6Q>o>ze@!4qMts!=yt!)$HxaylKg>{I%?j5)0X>|yyA23HIzN0WxHTL z9U56(TK{J?&owVe4jK2)+yp3K_jVj_^UKWsEE?1-JA(>f-B+e>8~Xe?6Olr{?DgyP z^z>!6hu8bcJSIzf%f0%pJV-%A*2PGam$?8FC-#Yvb+IDtfQBwY33zg2HIe)E}@t+t0Q8*W_6y<;lUrg?cx@iC9@ptSn3+WhAR? ztW1?3O#EHd?ugU8w7SIaaTR%Th#QM9EG&$~TH9@#cdWfV48YYxz0<xYW0{hA1aS#Kdd>QLf{|@bU2>d7}wAC=Qy3 zaNfJ$rFO4zf1mBvtm_p^91IBgk?x||5|^pXn>T}e;a;TkJ4wlO_M)Mo#L1Hx6?^UN z?27CMKLG>*_g~I4udv#PBXs$>#r&<5Nwat70(S4(^|`i|HNRT_(Sc&cmB5!NDXsLB zuQIkzrZ?^bu_Y~Hm8o06ed0t~Hf35$io9XVPml8t?pd0fpA{C~DSoM0(izaS_Hvq1 z#+x^*=T3qcqvzIp@%`ie6PnM3ol?JeiW#b|)WsT55Cq7jC@gH14oV9AuH&+(n|qYX zFOG=4WT@Et>gxFc%{ZTDZ6j!C$SIlRD0Wa%a&vNCeQjoHD(?3CF*#2q6Gfl<&R30D zO6Sj?FaBn)ps+L7RmDRozBc-VVEgKad0TS0Ds-daI=0>W;tVcJ0uW#$nUcEw+U zazaC~2DGtNYjFA5!6)CuWGN=uI0bBVYc*bP6A}{QJaIzn(j~nTXC+&aLpeRgPSTkzG(=SZI6ouHg5fi!O7=U(V8)KMEWLnS-F;L9no}Km&p<`6vEo zK0J=6-E;7a_x<|@0E9!b)Ax_A%QhUOOp$mp+TWjp+<>463p-%SR>#AbQ`c>Q{=x%M zicgrLp3K)3PUzy}+p}@Mb7X-5J99gx5-FtEag@)r_CST-US?6M)r>VX-$lTspF&Qk z>NRk9di$72OK+R>jg5;_bNj(FDJIMEZJV(gidsiU2exj0o5)CD-EQ%iK0I^hXY*6_ zvv`iR-wq5y_6d=Zk>%wZ;4VR1-n$>~>Ew8~>`L(~-fcu1j#8eboJqld#wN>OWhyhbhxxRlVlNG(0`man!CG-bC!xTGG_2>v(+sSd9*N zKMhS_OiZ~+O(1f%hg)(6iMb_?^j4&k&rWpk3peDS;SP1f(W;ITojGxb8pUj?A$Ch- zU76!(;6cRB_1uH*Rp} z&EQ2!s_J=(I8PppVGUVr2sA9?c5-r*ucoiv=<>|liD2x}W+dhxp5JU0cfGm0dllYU(5I`XleqRgAD^U`GUac`LLyL&C%5>Awc_OIV^n zfUARU@an;X4<7@LqP%Y`4ab10N4(}}lNfqn-_n~icRma}yd~kjJjY2u3VFtG(4Y(C zF=${KDyr!ZEM8Rq5W0-+Q!|j56%CC++q1|Bi5n|Tgf5)PI5%;UM)y_=Ef530>4nK{ zWB~d|Z-;gtXJ>EEGAth(8xtO;+rB6)L6i!l>^$aOSX9)ybodZ8^$b`$fC}&zrrExP z^Y+hp!lEI5J%83>@`E2SP6Unuc_m#&szcbwRB*Rh<~KQdX+$=@C11>gne} z12Cqj=cHuF%)0(`6185*)%wQQSK#A!f$;?)k!G`RvLW`ov60bDQG=T|3!|ce*$M|w9MMp@rwTB z`uX}A=XOX+N)CMRx0%jGt)J>ESD|1yb>+6t%n(vPs8V@FMYr|UTjic>B-H-E%FDvV z9wit3`0Q}~_N`kRd{`&1a}GWI!$~ZvanbpHIcr$LUJ2v}_+_r;4|b4-xV|{Bm%8UR zSy_tk9nDuKuOF}4l67>4+w=05MAv1mOJE%2Wc1YM!PG0^NNWKsLEM586 z*?S%(jh8mf3x@r)G1OmC%c55}fBt=M?>d?=#FM9|CnASF3ddw&j{dl{wRO^mrzt5Z z_wH4BZLGN<7b1az#?zRSL{>2WnrYX#|B_`v9^2rzZw&~sckkW-bOKMtIDh7YGNNZ+ zDp{967CF}mA#QGFhC#sm;;mat_^{4Xz4~TX5i3uray(X?8>wsZ@&trG5bLAGLPA1j z#1z0iHEs?L3c8;D@X%O7YO2D@<_}d>4}Iil{)uj>jS~Qnb7XEpODiNSd}gt#;OcvF zVTY$9)7S8jqtg4Rs2Z{iB^Y^GL~l-O?N*Huy@i%%80k1NCdLrN;Pm(NzXm-{l91Q8 zF8v~V>F0f~HkEa{^o@RNN>s#~ds9_BoWA$?px_f_Q?I38gP%Sr6lde@97B=W0pWbt zgGmI}twPr7t}b0^>3j9V^^t;8X|lfbV6S-{kqmGi%wEsle1j#SCJG1$FflPni89a- z7u`J_78$(7g=TMxQa+fS%;)KGrLNo^+f!&~e0O{{)1WjW^LfdwS<{LRvQar_@fZp8 z@F2~pWjVOGNJS^UUD?Eh)sLL}>QNyp2IpOGUHVOC{gn@oust?@6ijJj!xnbW z5F~w~1`qN6ZU$nBuBnL$y2+O4H+Ruafp;%)o@68>VEc%7eS5mQM`%}q*j1|i4$8K- zy*w!)(bv-xrIQ?&tyk{Z)7u+uaM){YUh8gYCSzzxi3q{Fe%S5i&4w#+KGhdlM(JKO z6nHl4M*?{z-c9##cOSd(3M|VqM9QO}2+Ek6l$|XtE%9Dep&W#S;$jj;cD$AWwwnox zjl4uA7Egfn5FMTKNJH#$AUcsp+;b*IMn}G02b6dZ#^3uX$h?LxkDXkXekDSYD9v1$ z=!lPtJ0h$lpcoz=?zK82>+FmkaH8F5pN5)RoMQ9Vty|q2kHh#uM%Lg1E~>7!c1&+S z?Tc*pzPb})Vo{klMWFczr)pJhSq11C-6G0Qm4od~R*qs6yulRuxd&Md1)=oK8zlN# zJtr0kPf;8oAWZ1Vz#enRM9Z3a9LJ9fgEqa(@H#*L+Wp4U=7XO?5U0KmAIA0sjGYgi zzp|d5n)<1(&d7Gs|ENSp@8To=u-Pf=E$i6^y_g)raW)Yinyk<3{ijKSKYP+BZd_jpJ*a)KpcM znwX#9praT8egk{5dXts~>WHDMB@M@01eb4_^y34(aX<D67(R;nx&J$l_W21=k#9{B<%%a*_S_|W!ZvFaEgK`6sFfZ0q)$p@S zdHoyrB{j#c+3D%GUSl|s(*rwp@2-4mZEn9h)qxWg9`|*ygFDUM6(V8f&(5~a|7th%de}^Z^*CCnrK%e6jVTmAqhIU@ z?e&U3vsg<@OV}g`!|d$r`N89yoGCya7mUEJJ2*HXVUrvg#)u9GE#_<}9CwN}NHGbdWNq-p%A-E5|Iiq;neGxl* zcJW}AQt|!$gdfO`N1XRf6gdOE#JZp@+4^3^-rhcsGa@{EM|A}~m-fY#kB;v&d5cO) z1hsQf_6_Hpo&^Wb`9Zt$;osTy@goN$jW0b1OHCHtN%64Nt&x#|0dfNPQ|GZ3`RRih zWhagtK79LkZ~{y;h`H;=#zzb}*@ zCyyUD+MIspApmpul%a=*N9^@~=#uW=moe@!d&Z?hEMRA4J#}zkV4zC$vV{dF3l7J( z6+!zSazi?i^}}6XzuKOC-boz>E+HFJ_Z-jeNzxq@#z*XG-KdKBR{K+s{6 zeL!5<^?Nro(F)$^evy3U+NWUh2k&^(g5^BE{pKlOeJ9$`lo{Zswi1|5PuND192XM4&KPI%X4oK?pgBG_*{ zEHDql!GnSdiq8T9EWm+4e}@`9|FcJgO^$G@mMe~nZd|vmHNbXL8(aAG*{t$)nnooR z1B3OJ6m@px=P%Zt6zOqWKLS#Aq-;h%v$VW?=IplbDntW=GNhZMvQOrI|MtXAA>5Ds zZlt87#HlL)h|}1mqs{hCV-jEre&5p z+rAf1@e4t+KG@4*dhObNdU|*T-ocgC*5=&sLh?X-XL>?%avyRz5;+W8Sbtt%IzGO! zwv5Pc=d7raDbeYy0m?uV)X>xfAp;TQ8me=@$|+KZMkWzPQVY*ARctaLQ`+>utcttu z|9J)JRsSD%C%)iC0XeB(oR^dHi(RM>U;!=%>Um1Ce&d-X_u&65!>Sc>Ef#n8o;~QL zb`bC{SWu9iyq`8TsbT-o$P?u}JPoi{Oe$ zM(Tn^D>GAhublsR3RR$1Rn=JCuU2Qo82vvW$w1V;-ZWeH@nZvixuzzaU5?cmUC=|4 zlK)Vt>FK4Tir&n@`{PY&H=+MUMTSxX*7pjGd~l8Jwto8YH3Mu3keMc)R&f)j(8lmvh!yzzz4EZ#YrNk5YrO? zv}Q8%Pk53&d;GG*OHxyh#~y!?FK@^{$n*7vg$7Ded!|Uz3v^Jx`Bj|WcqM+7Yd=b% zynG7i9Qn8VQZ9y@TUyfX+t;E@F2Vn=5%ycM15|IX^`&H#Yh;<{=-z@k)!VWRr$$E3 zBGC~)=2?)k0{nt=>uYWRJqQ2@#_*cdhw%;oCCpKPP(V3ngi;FVj}E#M{K%n0Q9yz7 zlU*)gO$F-kIuXZ_bB18+!P|mDh3bQRfF~Cb76#!$Lxhflv^6+B-X+C;5TRy2sDL*E z2c)jv44l<+E5}{D4+f3*?~Oq`cvD@!J`RdzXY>TbC-5!LA|gJS=DN*|@LDt_z^`!N z;KAk>k-53EFID3cJabS#ujS;yE`pCz_gqLFKC1d*v|-OhZ}IW++F=clSs+&+i9j+u z&cSi&%o$~6<)o0)kh}Et^)vIePTGhQ|E(7j9wU%P)5t85@H%=mSFnM;DHSjg1Y_ z=SoSU#u5n@WR~DRJW{6s(1(E{HYNwmC=ez@xx$-rh277NpI@MApIqG~z%} zIwB0KwLdQY$Iv{jzO*et0j~}qhz|DZf8^wv{x#ZesIxjCT#*UP_KVR0s zbU%Oo6!?u+0RUfJBrzq0vxj-#K1UFV*hBdVchDgF4je$zmZi{vrVaXg`~tc$aX5&O zq8oiotbyOe#l=C3AVy%EJ>oq9*CF&hq`J^F{JaBOEVeyGRckjMO>9%C)YizUw?(u#K(h&lT zin4NMSuhbAFKKJxmrx4l8yr{8aNZA|h{VL8pn6lm_7btwIr+MxSW!`tHkV2q?FVYv zA8isL11r!YU*Dddo_i6c4NvBe-Ho9;68ID=m7&@cbp;l1(R*L3F+x?;7x=6j@sKWiGqtRGvbW(WqbQy zfK;Hukh-vT)x)#!V$zZnTxc)O_Vx<$@&s>Dul47eiO-(3;RsrKHQ@MTtqkH2+H3(LkW`zob}uOAExrTQmJt zh)Gb4BpAMU^ev7moPxJRd!GwAK>w2z1Po~GD?}0iW+=N-vAI|uN&3~RhWh&Yo*sQ& z-Ia|KTtbeV+y1Q9;?F(k?!P=20#!6Ta}$BTXXj4%fRw;7Zmf$%U7i8>z$tSqt3n7N zgSPhd8P@ukV4FuJ#~ko5VBbG|{%mGuh62OD5RMdztvcOU18N99Jooig9a-67qzm9S zz#-_4G{PNdZ$aYA%6>p|34|I#Vxw2#sc&JO%j2b|9l9-jK| zwj`ehq=IVUJ}6wxs$KCieyJ~CPS4KLS`{2Q5_o4DOeDuW2^S&+I1e8_%+4+=m08J2 zyBNMkL3oW8r=e>*ft8Q12`w?WHrv1!unr`97XGTQFXo{f$tFBk1-J+s%jD>2O#(@> zr682A{f;au5{jVsv(|6-Cc(!Kz+X^MFx8sYj$;W2ux`HPY3oh_3^EcPEJhBhqLU>8`0CJTi?Cw-!9(K3Fug;$31j)i@CUo=Nt9q!BE4d=4Rl- z(HOK02HeEHU0U;(UFFpzE98{t+oD#Z z;&8%y=;@{!vmN;j&v!|pdBVGM(WRkIJBm@ky$Fz^z(tg$Xl!W_IDIPAlCnP2|N}y>Jc&G^QEcW(%gdd=u)RQjQIXPh+LQKd}QRZ>ZX^8L_qmW{QB|uDpC$4dK zH8mZAlm2;B)NpP1`{7w*V`EuAMv(Lu`-uN2eTM-OO)v@4A%ZCg0O*)H2~58Oif#M$ z2LVTAn{I{P`*n1a9=A*NV+On@MCA>52hne(>*R`xiekWkHJkWUp>Ri`4+aQH)Sw`4oRZ_( za>vXAjTeANQE@Sh?22i06a=t6q0@;3ZHhTc3p2BY-;=s2?vgkwO3%;Qfqa6d7NVg3 z#$}56%~sL`(B8UQ#Mom$zo5WCP$%fkB|KL@ zn&u+mpUmF9xV-#(w3(Epp~RwQBIORvF5%y0b_4fK_+9~>Q zApxL#lB$H?7s2~*|D7Lc20oWk4W!hA6_^3uJ`CDJNWhWe$*{kY+ks=^?C2P*N#2&J zzXBH=rza1v^)I{^o*0fgc!z?Gl$BvlfHOPAJrBb1Xmj$C`#Nkgz^6a>4~OtbQ5!bE zma~hV8!jFI%RPJdhJNzmL>;w5u)4T}Y7!{c-X9L%O%d$`h6L+?pGU3&x16B1Ypy^S z1O!?I(q`X#``wmJC7P>;X9R~14LuU~;^LxQA}1dmkHPBq_uEtUy?Y^f7u#fOI}Pe^ zMsyq5VQGnP{f+2mfF3NHllBmP-~gdRgOlkm&yUtpLSh41%5nekM#RS9vtq{t&cjuH zMW$ILLcpRX@EBeW_tjHva?{$d#yDwT^ln5Sq^bw+3EtqK&|X15kUPAERC(~2^BnJmURAw&db-#pvFrQ_HFc- z!a_niff=f=IMqOxHnq0G##VZ1T@f~xshn${X=rF*tGYeRNk+!G+$duWpbnk$Bh&+K zLkIZAkYXy=B}gWZui5d7TME95&@eHHf+ycW%hvGH`-dNk#5w@iK((LZg$u!7D>(o^ zD=I2TXvT5mB7lBa%>YiV3Ex|z?2!XCu%X=OeWP>ySQel=G648u9DcRqOBkY3QBYt+ zCB|?9NkO7ey?Aj1L4koM2!bZR4lkwJ+=w`@&gu=HW-4|KY`5Cd99kJj?XWh37uY4f zDBlEY48%LggKsQbkEfWtNKe0@to#!Wg5KU4l z%nJJwabIk4afA#wtZT=db#L78UcdTO^9&Bq{QUgUqel~ejRKyK)-V!yQdgLD6^zpIkf){~uED_o$IEttl!iurUS9BrftrtUKbxX~ z?qQ)JP2$w--Jb{Q5`qQ5eSu}G!tte=`g)RN0_GUZBn1KSj8AHhu}1-cVC{2K$2I!8 zc5WfLNkm0gf$K1Wa))10VK@IjNuXTM?menhfi#AG3AR#Ly?GK7O~IZb9l(>9 z@C%-=QGg)yjC%0p%gIqh$C8mHjL06y7lW`iBt*iEFiddYKmh0fMa0T(2CIS0hTuXy zeJGv|L9T%g1~p6z#WxD5007uKIcdN{!e>G;NjPy8po;{KU%i5a6QDi(0xn`Cf$Ex? zhgAKeqeb`#$hGj~)ra%T@-e^(s}9x|SdW4LdH^dP=w7pZ`*uV)Y03|J2aZT!eLeaY zem=e=rAQfya3Kd%(BSCBQO9ZqW`v!_Si^}=-CG3(>tZ=AuU`jLK(l1gU1+Dq>5Yjg zk|YLFgh04j8^)_va~{np)V3nMpOp`36YWn#3ppf}l(^a2+M*Rl=}AzdK$jEvGo1$! zshwl;5UvG~yRHjA*MgA0;0GW<#>ubQ12}dtlt>IKsg1CZV*qc58K%;{p<>}P1LO~2 zoGej|Viz6PVbIaul^;I1jJGNMVgNT5cE&mahvL$u7HmD<5a>GQtX&+&s(_3y{cQ4n zioa=2;@A&)XO1Nq?HEAY0K+4y9P|zMcG17S-cBh^c!G_El>mWr4g-yeo2LD=o0jc% zzu+X&=y8Wu$0y#YA2u^F!70~#bnl|J_Qyecj8rr*C%lBi2FU@YM2!vF-g`JNI3HfW zh=)n@CYLWWpof8Z)e_k{`i{py zjOY_rYx6H++UVIcU>;WRsa43V;K}Oh>&+T5L8<*W- zCH%dxxL7z!?QWeZh&uPh=?buA($a~=#g~1Mr$4i=;d=9}F#~@9YgoeWK z3Z5PZS#aZ#X>JDy;B@_rJ2sdQ!7)KayzGH@Y2yON%gGs=EU%RmXMy7XUpm+TY?G#@ z%w7x-)w@5-vs8bTgB}^^Im|*B6L$bhQAWBW`3-g)ml^X4LHd%UllP9M2B2GG+msiO z2U^1}PjLg2zLu8DW34A>X@hWtG7L(WF>FZG za7O|Mv~P;(Lu+@e=*p$L`Qed~n4xV$d&Wp>)0|X?vJPWR?eHuH*zs7eaWIGNK&G44 zMM%HTK{~?wp^t@{)>&wGl<)(=4EzVv8BsbQJp9(Tx0~>u=qQmn6zzU8E|z_a{oBBk zeM=5Rs}d68gpqdQN9?SFy}dJ*9uz8i78)X|G>LmerO>{783wR)!}2n?iUb8iDet5> z#6!k{Bhx{g)N<;gxTL09zP-K4v0)ilC9LrSnrE2zm`+<>0{TSW82LedX9oy{H8IUO zahpndBs6K)T0saIYt|U)|=+#2;FP=$~Fx1spX4Cc!SjMe*k542Y4# zZ2zV5hmEdWfnV;_wNLxNCW11~x9Z^I<|d(pIejEv;ge3tfg_t|fMkF=9edsh3j!1H z#*&O9r{AlWIgLLH3{-=&5iI8@or;Qz@PpfE833?QvQXHjdP-#76m}k4R6bGs#WEw~ z<;xLNWB7GAID9g-V9&QSGO`C&ND{Ern!)T1*yJ4q)V5W$))6Y!G(vg0p-C=rFD z%69A+$qj|GjzmqQrD_&Z0b3Uy-T`;14Yt{|j*&4Pdm0gO8J*y0ncDN?m%LY3-H#nh z1ghbueRx?%r_sR4vHC4W)4CzzVQK`-U}_Y|rD3=9LE$u#-!u}*Y+wfSiQ%^-&<={> zS^?AW!cGk$*vufp}V{umqE5P+VD%TLl2xV$_Zxhh}`?ZD+AWN3*$drQ00 zw0I)0#x;)1qL8#q7dj7u<`%m0_V$qbC$RWPRbW$cb92!?9U_?E^xnBHQ&Lovp`8sr z^s#aPXYe<-hjIX3$Jp67Fcau5ZV0NvIsboCgi^(s0ccVmJlIaCtgW2@76GJX_5N5> zvj!p!1V5OPwA@FCYPJjon^$Lc5CHZ&QSi{sjl|%5!3asJc(VS{!cNEiKcsmuB^4t0 z!UF@F&}$-mfbpA;Vz#FvY%cehvdFf3YxI6-m5 z;*vNk^jUC_{BM5iA8rn-|B_l2J=bmAv24gyqt`2>l>ucDF&8Mp#oS(_47aH00YBB5 zI-F%9ek4(6G5?{?zBV+xdiCm}ZE)t5&1|nws+8+dq+09ivx-_LAm9V$ETQ1Rg|Thh zJh6)6qq#wn1Lh}5E-d!wjUkc8o;DC6@0>2 zm@_e*m(o>~nKn?EAzpjPfwU_DaDNvCh z55Z)04&8fXgk%fK6A1wT(NRs2%xn z4@BN(!AN4G~lZJhK3AV_k{R9Z#Rm zM;y6b|`!5}beL5_}$MHXU_0t3YCMEo*|7TpZBl}aNZUGdi>aD-03g)3^6qRLV zhbQ8J)A~8UD|vaVHM6&g=g2QoaBOYaymJ%7Il>F7i@P|yO$|_AF0$j+p$+EQy19T= z&$|`VCjrqY2;kF}!vAl6O37QMxX0P@R9Nd_=5 z{x%zPXjG#RN^jn{qqqXypj#ph7h@=_+-Y1hqPnw_gwd$%@oJD?tEY}_MEw^I!I+Z^ zwFL|<@EFunl6q&+Oqyk0n4J{??*!HauHObgP-cG@P|koJVt{`jdf+4Zn^^Gk=u0f7 zk78^GC=51};P7xAU~W_$&_}jK-7uv<)dBoP*9GUY$l0?Eb4--O!0iAUuuOAuaXt3& zv2}2u?dCXfVg)z`j%>V zirpy5vYYUib*YU3cM5R0fB2|2R~xvh9Rxs?A=|TH2bShWgW}@)fz$qWTy21c5K5}6 zsv76eaalCR-NSt>ST6V${(5G%3BJbt7{CL_FDR_-jg3M#rwFfxAAEs-Ks&xL zKaYo*pPokYpw8vM-6Uu*Ntf1C%CLyJCZwfxArUSQ<3ZNbbn@$AQy04 zK^3kAu9v(NkM`_Rm1KPsaoDIRDNH*~&@%I({A0oo%XC%aS68K_a;?tn9o;GCa>SEXnu_{YU=Y<6l;`4mOE&LgBRr zS_AIDi(D{LjVeV;ynxwFXg}z>i4l~c9e%mgn|dSChYR_c|pO#l(SkVita5a%THJ& znCa-)yg@~FzqXD{P0G)o2W0K;>5*9a5riC}5_v}HI18p2AfJMHKYHW{ycu|2Mp!X0 z*#rY0fLhuE*H6Km^{0N}NRp0IYtZFvqkGxecJVBwCjYrwjWHU%GbDF_EJF%A)HCpl z@OX5hdDE!q=ny({Mw0@4${ujkST|fl0j!E_L%NuXq7e-WLPKJW13q-zHPv`~(-vK7jzFY&VH8MDeE|vhUFy)S`2z=wQv9U-O zpo8b8rx))=JqOAI!Hx?|a&YegK}uQq30@H$9i2+NaU(OY5sQ!Wo%TsXN3|7KN@>8! z3d4kj#ptZ>o8;u-spv}sGBSVD_>1p|ffu-A15Fvm7uhd_9qy4i=^Z9|D<>;!3ho)$ zC>KVPV?3uTwj=d+0Px@l7{K}sP>Z4pGv!)E{8n;uaF~Fw=P9V^=zar=VR8+e7=m0} zrwD{T90DZG#BM-FQnDiG9?2>TfCV)da}`L}(N=^bM~uK_g26!z9|7^nGLdlao;2Kb z(a{FDwS>wD!V%zRs57u06h6{v#mU7GD)^fY96I%g2#9h>zMXj%@dn!3+8kB6;z#=m zYl0Q7ou6>g(|ev5%XrmXEg`(Oe0jdzarqq82$|$z3cYQ2&TXgIEcxv?l{dX8#ajvG z*o!7+X2`K}E_*<=4h|3F&#Qyv5C}lf0T_9u-ND5a+1VI+2EJ-&Y`mrL-G&oHqbcWl z$`ia^@OoQqL&J1U8z^PcTnbnNXg;YLClGYWc@F4NF&_)xfpR#Xbi^>nJv*F;tkU0| z5(kz($c1O$kEAnx@)s|j8%V&$Uha{mh)qjd5ezaKTVUHbp0f7g*TeG5i@LaQY5kpL z3lLNJ<;+XRG27%#g(XK>DenS9Gw^`LGYkX0)dy`}?%cmq8sdP&!6ljdkN*Qk8I#$~ zl*IMH03)e0p8y%BCT31k?@dl1rE7d$v|+sJxd0LhL6n=510#83YwLa@lut-`ODij| zL#d`Z{P;+%qEe6dg~buap>%mHO)XXA#EI+J@Fq76|NTA>AMV(>vlGNJVjDg3ecYlH zBGG0A9T8##dUsd~NR|~UL^~Q6Eg)auSWg#C{=bjWuutH%P#}^v97%x65MWB@!fvCH zgvkL@lzt5SZ2bJ{sm|!7!2q+cuwYagl|V*Hih=-a4@m=VpHR$oGBO@-y#Rj#hU?ME zVF$oLLqTC;U|2HARY=V7+E_>a#}ym!CoQ5q4N(|G4}iNY;2vI|$R$nV;_G&GYIa?~ z<0ns$rba;-q5p&L2{a85^Y5uXQtAU5fw{$Vb>;(TYS0%D5O7k%#660s-gR^o<>fho zXNAxhe){?|syKWS1V?^ut_X$!kTrU54M(A-Muvr*6%qmmvXN2H>zdvHIv+M$us|0m zP-Yx)6%iVEgy0uaa%x0sM|}V#OwRQ8F(V4A&&b;2Xf^4#f;fbP)E zF{wdVas<_2_!O66;S2OpH=rISFvA=FbHqsJ9egYt5AFkgf|rgVEs8-4Mhe98Lm`A` zuM+|VK?)2oq+&k6reDA8K^0F-JdcQ2e!o|uHcAAmc9A<2B;0olB4QF{KM{k^P^2Jy zWtO*EK|F=RfQh9m;6XJ;dP__4$e&P=?i+zR{`ky`8Z>hUB+a{l485s*>3P;apOl-r z_ENxS7s=E7&BoG-p$7T^0?GY%hgs8S)V-5BIjo|h(3pE+I#7|5TO5h^7hjz|Pw<9L z91x(2(RAG32)-PbQ$V$)p{5Q1EDaAYGOBunCeY2zjX=723wRD>I3d3SL)-XAylui? zV*Mtv33PZlCt%e1pCwbC^Q~IIYY_IpyaNtBKJ)jGy~w`CiVrodEsxdmS{_Ztb{7{F zAp+{cc+bP<)|n5$4MhmY58v$~z`p=k%MDZdYinI>7M^H&+Lqv5R0JBNwK?+8Y0|B1 z@yuztShw2R3y5|2kM1-6dApZhILtVeIKBQMxDN9bM1%7AOavx8o3vu0?2Jm^S>Y~2 zdPDK>rpmaSuNLyzBnMShaa8UhI-lg^WXIwBl$6nC3AeGj_2c0ehQ`Jeg#T9ORdqbq z8;pB=*ojb?!N(RK)JIR?&L&IZ;bZ=MrKMd*h)PLS0${+20^zSB(c)7c1!>q1jhKq~ z5@>D}itli%!Yo+rk%QQfhck)@q_G;sZX`&7#lb2)dyQyUkJY`q`!&DNnA?`&K&MP+t#P-_xL|G>zonHTHx;RWp4g; zM5PVtk}w3KAQ`V5q`#z%_>`26v)p|!Zz8#aMn%tsOV-c~;)1eBm`tDHmc$5w6!;Yj z3vZGn!8J%CxX%n1(J2E}0y^RrpWa@BQrux^jw>B;&<#QDL0-lnkvG-Yc@|LjEt_6ou|tp7+Hq?vTD;_c*ZtIWoO9ZSZa$S?C3;RNPK5b&=?>Sm?ucF;>#oP zNI;-9FtEFd4guaZ+_?f*B}xG9JxILN0Sf5lOLK5AnC!p+0CEFtOMZZCsTV1-VFMNv zEJ#RTZKWM+=^|}}qoX4dPHINRAr_WC_~Hna=xR{{q9-C@F0*_#gLOk$N1x(NMf#j@ zqIeF#Whf;L8s5)uSFY>2 z@8@36eLd@b-?iSgp4PqY%SpBO{{Mgf?{IvN`D^)Tau5DgK=p!Ji?N9pM_-r&_} zsiUK#L)*As3Z$uV`EY2ByNvuo-=gq@GRR!#l*Y*xheN#p8O6|TG*Mk8da_#AYFIWo z9})Q>3QEqYiUQN!`*4kU{=xGZs;xhNe%m%f7{=7FTnE8Snm2phx^mhnP%T-D7DrtT zFKz_@>m4406UR!#+qBzN*CwT=do*Q`-d2)AAv8=E60 zJzF(mx)m}bHW?D7R6f5$aGTDHdg$p@5__ltD&GoW)(H5F3*lZ?khss2Wd{r}P2Iht zfCB!MHT=;evIx<#sx--sQYk9gt695h2kH&KCow~0irA~Q>#AG1`WLrfJbwIrpusr3 z3F_WRlq(kx!n1_|YaW~gG6QAXjOVvE*H)g^ecawP^s$T5t_f0-4bG!#8WPFK3VF>< zkQ}bm&iOF@W%R1vG+IYYcoMN?o8UoBg1`q-rKvfRN=i!u5{sc>VR5l|HJRdw34=&# zcnX^csv6S=jFEYM^{B4S+4h|o-AYxsA&gvv>F^zdQozIw|qKY#deF_iX{^PA|(P|!aibOaAmcmi!x=Kev~ zPQD~CLmD@AqVE8T|4BDWyg*nVqWU$}!sg=n^OhL&P^fI%x|N?8!KCiY^$V+jn&Ed) zcj_|=u_J{X?zJd-MK^GGs!P%xtXkoCICZLeMMyuGqm+uLLSZE_yv&-8v3id6MfL6;%QmlbUVv7qZlyHCgL>2oq@q?Jfl-%nbPPpQA z14cLjsDstGeSb6#Xf5|sGVTCNdE;brLi7^kb@1s3xF{kbXno){!v!+E1$XUEO&yw$4ld|zdy0;WJ`@Vq z_-x8t7;tcaS}9 z@CH5GdrqXnlT(7=5@5EW95nBYUT20{L zamEz1D=AaDn$x@zMS~p8#}>c`;9}>d(q;vj*_)c~(Oxpi)Y8&9$BnyjZH$9w$4;Ga zNB_hL22f=>E$TMP7=fY&j@#L^HPMdB028d&fWSn6vllK*NrhvIy#Pb)A)u$U7@;0K zSB4As8g!rSb_POBht8cjXUyourPI|CZKs`o`^=e{fT1M(FO-cS2dbIfAM7<7OmZTH zGh4wzD%Zklo0nH7Cic`HrXgk;J_Gg>R;T&jiJ*xiZca2#&SxN+m6=NFu_ z<&p;LtF&(9!4K{2lTV_4d?Ja7aPa3K;5{?5y}T@T)`Yf~ZdL35R?pwKD`6g!S6X{- zz4r=F@+Zw9Kx~yq8rl_-Zw9xDUY4G2E|0Zfv<_YVZm!b}>T2_!)mkNLH4^Y4h`U@k z^Hi+KG0NA0Z%)$!L)`rGwrz>LV$|xU8F+n>S!O zh+wNm9wcWdWoVy*h5^i35+A7A>~cA_d|)c<4}Y)xwh>b8=v26o4?eI(+Tc{x5FJ z*UU@C89M#@gB6-<_|&OW2k;-7L~BJ)pL>)bxO$%)J4VDhN+r}IMOKj_+>n&<<}}sa z+^PuAR!BJ&;kkcr=Lrk_8pxHC_#YN<7LLUrdyy9|2s1zmM4j?E1B9e>z{Lkh-JpgS;o5rY*zz{JaS`5>pz1==as#ejXYGdMDr` zxT2OoGaw@R<@q;k99J_NKr$1@1Q4YfSb>KOH6WdHDRoBBFfK+J2~QA~Kqz=(LMrS3 zmcQ|1#zkU;n0!D5#>K{d-aHIjKgOr+-Lc~#*GLaK3o|+LHANw?ctiP1m%P}WOSk$8f7llZ=gb z8kW~>-+zwi%m7I6;9m#W#8XVH9x-IdS}a=Ww^riF2rmX?m{&dFyp4)-^X5C;cEoSu zKwGU?x)k@E%DFq+_texhSM34dnycR+d->&sd9<9A3U|hoVmbQpNSRH@cPoKDNgIoM z(`S0U^^45}#*T+{{+-n%E~cC&&fgEfjDc7R%`agd$YuGI%?#BZ(bT<=mclRkh0TOi zTH+YHB>l`GncDE-KYOjvBwS<6Ml>mSdhE>;hKe)eU1Pz)jQmTw@^HAzQktZxXExYq z64MXi1TueOExZju|>6Mxr3T?<%TY@ z`jV5Xrna9GBBqTxl3Jp*1)L;8p54ep7TRu`+g8F^nISO--}s^yMYe%^cC=Dp)MB{E zN#BFZ0Tm^%=c`-VM0mP)VkP{a>{H=!We37Yv&4+|3CpQ~mK&L*b3Z{&MohKin1c%~ z6_0}UjP~vliK|~ki(AwHz;sXf)OD4Ng{wAVuv58iHLoiv=_-bC zBz^B8%D>DX+`o2~|1UjPZO17wal2bX=aHP$uN{d=o~RC}87WF~YuiDIq-fkWndEBW z`?qgL$^18hvJNy8FY;>5KfT6mrWzy083Y$Nsj4A*lg?hW=%?|axB4&ZY`ki|cG*Vd z5A2*(Gy9NiDErr*@bGLX)o{JE`t&jD3&?2AF_70P9v+2^m*;Gpk@9MzPC_flo`rXd=et{2@N1ecop>sEg2d5_=yu}{NPR7 z*kr*ANMq#0+qiX$O+MiuOpxg*GpOAE1;h=0O97P%{1+2Le71>MyNrP_{AFXISdeLh@*f1eVcI!`)F2@PT7DYzX@irh7SQe z%-9YcrY$xv4Ea));mE?2A9~zy`f`f$f5DBV&0Dv=NHxlZi!XhD0BD4wdfA#afdl4a z{g=w#4pxU0Gy9^e-~*HAL=GdCz+Mv|Z#dWTI%Nv~8GI!Aa9b>jI$2cg^^k#U$Q0ZFj$GBk!TAomYeCpu zFqWX<_tfn+S>1a**MmwL#Faui$TXzmKhr8u0byj5NfrV}1E5dLE&w-?kA_c8jl~>| z<`?V$ugZd_a%Q99r%t(W2N7-YSte;Xq=x!%I^ZEe@F4%?qF4u(p=MK33BWKZ$6tT> z5@x1>NQ@O*aB;9j;)7Hb23Daz0Xm(m5nazZkB(&0X+8XOY<1a}#EDk)$WFH$ z>vw!uUmO?#de0Myp9jG;VcvN{!gO`-3C)aKDNgEulSflSP|=MaRFnk1q3(^r;w2@fBB1*VLPbA{Z%#iIk)9WkQwrw#OmvN^EXxEzezCLv3?$K=So1AnjZ z1dnglY$wmkIvy0-A;0CwLa_}ING^pa@|N?^-wUSYw#I7GarW$Q&lUteK)O=VGxtej zw^N12L$goBG)|J$;|O+0m=wY0d^C(G+)cg(*KX#jquJdh&}!Le`8WZM5op_%^F1QZei_|&58&9 zitCP*w3z!4F{fHve|`J5t9ul?cNk;SE3k@akX`cO9y^1r|CBaw+m_~5_|WR5HDEwT zD%1BJx$bl!QJeQ<9B^KyK<9LA<8O>J?4ab&&D*+ty94oZZ|SWIYEv|Pnx4zzNl3X( zPP)8xq6u^v*&B;^>jRTirFA=Xk=Fm~)IZ1|`5PP5Iq3!&jMG8Tj5mKRNLKUbL)@V~ zqmZ29Lj#_P?pa%VC4U0L;P0ns=9(f}Gc_&vZv2=hnX5#%t2kl@dAsZkc*Nfx9^9&j zPoH9&_EjM8mKX1F*qFwe9ihYwF*8_SDb6ii32aY!PSd>Cmrx3@{{jn>5bKjKXF-=> zqRiC^95G)$njtM5f(Oy7Kj2_H@BHoj;twoa5G#FM_zssN$83q%;C1)zM+@WWQn~J&f}Mc_D*vd>k}@R@zToA1E_Yz6nI2&pxJ;#L z@3$+{7Imo3dH+&yYCpUZiF|Pec|X`tMU+nBDm;AHdDu!j&Q4Gxdc$wuzw^my^-sZy zCsc$62X}Wz{F8BIO*jgr@#8%gUJK!6&xWTvb6M%kB^VID)#Ph z-u_F*N%7D>YTn+I-4pz@>Qwb0WCo z<|tF(qQwlz#MrnmYaZy;LZOM9Lb;@Mqya)N+s8U)2xAuMIiLYHG@@03%{9-~7VaFK zJZR*LCr<=3m0w8v%$zR)AO{!6KmM>isVoL1lB3@q>_%t(6>u6>Qm`K_i^$sv39O+T zsI5H%EC6tv2`z7ycqxp8;AY6(FI-pw2@E8OA*5QEY8HqU(GUtvr)pq0FQ)Jz9Vki` zZu9%3z$#Em#6V)76hvuyFm@6g>^EBhzlP`3UBgvKmZ^p^sEU~3~VK>G&?XQrJ~tjY?C=I=MVyWd9$WsX(hN2JD1 z1@l1D^_pK@k#g4}k{fdXteGfEcSqX}v8=oD6M(hjeSqr2?7`Km=rP&pK;&}d({v)y z8mYrPx_9^P(p9TkD;T1{w?&>LR7+wE0xQ`_eTrK+VG5Sm$}C}6Or-`nNH9DZn^Ge- zZQJi~RMfs|VoBd9_?1jrI5d30=K~CcSj{;O4xSGu(d9}95l18EaM>G*ri${yB*7&-VXVr^!z~k*Eg=p*9CNe8Kpm7vT3~UeNzu1&-lX)?KL7aOfcaY^cKiB9@??-NNuU$DgRUz) zd9x5;4ZHKnsjP5y;)VQ5he(n(jXkD+1147@)j5znh>wuakX?9o`?`O`qlG!T67*-h z$54??PeMMj`48$HpTumT`A$eU_YWSApo@lv?5^epZI`KmxZ#^Rc<>rNCY%jZ5%lRU zbJUl~Z}L=MzSvR(xAsTLK5WzJ*=p-;=Z!QuD0IwX?~NyQql-OWZ=ci`kkfmqWEO+cHz<`6$S3A`dz!uz3JJU=mFOy8@7$R3NSiNgv6ynDv_;0bac~5qiV9OB;F_<+lG&{_`rb=g1vR-ST%Fh|5 zw!hZ02M3(r`JI%;^|~LZA5Wo4!e7^B!-t?{FE8@cEKgm{qAM83PEMD<_uWCMcG5N@ z@A>6{#5oQKg_Ph`KVT?`W|k5??e5)^Jnth$%#hAT3ZT2ebmo6#EP1sbWN^%7hVEzpymkMjV3pekuNl$Pz z28cm>n(39y%6$^TodwkpNGA;&@6j7_Wb4+chu`*_cUP7gi4`e+Ub%bgj94M~OXz{j z2A;v}Cs+d*PZXaiyIUYGMN|jhQtnQD5)t=f2}`|JuUV6xQug5V86))-t5$XIq$E=` zHB752=Xnf|DcI`gmkvL>!?#kZxvA01ekNE&K2AxYus(e6K~s2$@TZ~FUcEZ&>Dk$& zrZx(PthiX(G1`U2?1?1(uYAM=pNXbwEVy;<;0yKEM%J*2$Q`%i(p- z9SomIhJywUTtPe1H}<;_R4x<&w`}`lC6RI2vU9RI_$KfOhQkcP`<6zjgR_h{8MN&s zy$GYnzunz=7l)GS<{uO=n)nJp<@=Q<*Q=yH5T-DuZ`pDMP&_)2qM3v^-td&z80Vr; z5Z0B&ufa~ydy82p)DHOK%O2G!UseOCl~iGAWYB>Yi^I>WJ%lro5@kG;K@XN2bk^o! z$2HpxU+sYW9EAhi*)n=#lq}mh9MM~>sC;>H@*t4l0P^I7xsD05-V_JK0$X`hh^UV2 z?G(qV@zoWIY8uCes)4|gTtA)N-hv^g;gb>x zwH|nWVS0xpG2dt(#%Iz3?;o-Z$X!LOHhumaCSGa>j&M7@b!+PlTSVWMI^B?|edpeF z@?&bdQ{%Y|tv`G?VQmUr!<8Tu?CdaDAmFk(B~xk(%<`dNEtKqpWvDbg+Dj_?)R3q) z=-;_<<1H}|N{V~kt2S3VRx?`iKir)+AZ53tazJez3%t2T36fo1VaAiK98^&_e0cr( z$dPL?GRep(=|KbcFbUX7m)5hDTrP)*t?=aHIfAR8G=yW3no<`3N<58d6#tnuEv2`G ztA$4yS3d*q+K~4Qm2l4^3Fl9{0Q+R?&Yi{i`E4;nH!J*43~Y`J8p9y$m}sPIXVh(K zK}kjt1z#uq^z?zCJ`^OUDq9U*`f3AQb#^$hr9;&Ib9fGFSRse#>)>PmfN9L{Vc0;` znEUA1=7`?Ihr1AoC@EkWQQw(#nlx_Q0`3**jp4tTZNV>tC;?UUj>oK^iU+&V2x0l5 zQPedK^0z`dHseBp;Qz9^P;dD=Pb2lN?MHTR+xLd^{0u-@_`3L8M=M+*^Cmn~j z*Xl^L=T9t-U%@U80vQE0FHQ;42O3dG2>fZLN&Ke+?p0=*$X?H%Uye2uES)|G1r*DM zTPfTrYgy>Z)`VrMkBl9h6w~mN&W2oe8Y-m%Z788!v^tc(BsV%~F7Y=`6$vk$Bu)Zg zy#DtmI5i-OUBAmH<*`ImF3kXH; zMfj#R@O;h8XtC7Yhq(MW{p7gpI$T8nT9bh(0mb7V!}$o(?LnkOHvI`ifk)^@Z1a(C zBk3g5tzD>ajhu7dzmH^N5T{X$Zf9KHQ^MHmG$Y9Yj8N6pZJ`J=Ey8c^h)iw3fb-10 zrOSXzadb0(Kr=1?Ath^{<3k;U55vi?@#x>eW@xD>TB)dj2xjvNO5G5Vm1h!?aCMs` zA5B4_y{LfFgMhx?-~zQMz+iI)en(DpxC&21|Ddth#t|#|0*XT){5&)Bz_Nx;;Fhi79Blof|ue* zm(NM}XhiAZaT33&>RR$=*$c_YV`iLGV9ROKPFe#LMuF!Nx>~9dP}80c*u(2)q3Y7^ z4{JHE*C3(vD ztJEqmrwn*`dhbmN!Bz^C2P)LJfLP%eANTC}l*0y#0Id#D_g+-}+&n{*Q8$v41s4)n zraM?IIesy?lFg!}Q0@X<%R&@KN?;@-mRib02H6GI{!ZuC3mhC~n3}4&FZ~bX3+F-R z0UxV*9-#%)pN3T{(2UhwDq#LS?Nb-jcbh^)g&j``j+1S@x^;1-8fmoQwt=y6I8^{n zE-uh%SOH;f6T~6vplv5(s-->O>&uxh5ILzF#E(*F?)OK&p?(S!? z7OHe;DUKS}1T-M9ZmfAML_1}$-$>o3vC!ke#>Wqu*l`m4iPHBIoS#$gE2drm%Ho^v zspCLYjCC7wQq$F@KpYwx_jql{mWZwx+3SsJd2%p$kVgsatB@;r$hgi+AnY){v{|Hy zw+&|F6iDEeWwaEOM5P!RCC(d=I`fF*=zqO=eG9D8@5M$m`zE;uile(k#3uypHDP5|CCe5ZXU)Nr5TID#W2jqwKN!M z8PN-xe#cg=g8a`T?0)%Aoi(OL7SJI>-^UKWA(@ zcs4nl-lCCwuR%7Ulfxh6Hd!i%PJ|sP^=`1UYoGyid6g-e7{Q!2)gY4q zcc}l|v9uqv>$LA}KgjU%3{3cL;|j`b#(^Y2g3GOHS66bl;X;S1U8-*r# zMa!0SN^RP<9ReYMnAWOI8(b(t7FK?LY|Na=;F0u!S*KdZ*gnpHu$ zr>h~ra$A2s9G)kYqs0-W6Yf%+D{v7=%%S=xQm$Ql4JsGvGxmv-i_5q%VJ8#CeR;W(ny=wnPw47gTwR20Bs zrgCFoLiY0gMrr(xEXS!KW{m#ecs$R@hz<%G4SAF5Cqr1bR8uQLzMk5X$V4ui2cxBe z>h+ZR7`+f!cp#eO5##-O9kvxi5J77vnyPA81{i zhnu%nR7>=F_3WPvS$M zu8Y_>xjvoyu7|c4&m!8kzvmpQ8d3M^3bpyS+kZ8+_sTyqh9@B9@4dYl!Pxex+?_Sk ztoXd{50_1724QS!XQ$gO~s^s z{rUmAbI;mVz6KR=gLyBfR-Yt>Dyjr_`m_)kYh|?8CH^cz> zRMzoEcry5bq{Jd}!TOA17K1OSc{rq&{K#BF|9{)mmzzCllT5NfrbcfN6Z0IRe#KuG z=r7&w&=Z{-x-|42oVidr55D4jp*EH-P$?G z6tF{^*MBu;7R$7$IM?>C9Yg#pm49ivj--4QsjRgE(PHJM^`Kd$3x4MBT(hCe($>QdiDPjm+yMx z&h;g0Ck5SayP`(BE_qd4+cW<+-sV3sd1^oX$Q!I&6ry*)5jNA7cO7TZvz6Ng!6aRf zd5R8=r~OVN2(ds70iTwATTuIQc5CCx3lgCqQH@Mw$2Nddk<&*YmDxA`#@(;{&{(34 zkFW2K)6si@8O2B`APzozkzo8%p&BE@l%69GEpVMtKFAWTllVF;#~Ij{Igac)=qddz zkQZP9y(GYr0ZL7}Z%Qa?4>&tQ<BGW^ao#G+*Extnef>jneXCLB%l$7DCDy8R@I$y?3vu`KVy{oa@j+0uS%n zVa4K)Ve@JK;j+9PP&dEgd z77ZIWUa@A48&?P*Rl_?0#vJA!LZ$)rsShCsCaR-L4!OtT{Pz$uRnXBort%3;= z-i(dpaX-Ia;X{x!P`ZRbm4JRoFYmo$k)z`add25ecU~U4Gse6EHNg$7yGKWU?y|A* z;=@5lr+RK}9HjPJ&vpj#sQJP3{eMiz?BiGRYLvdMf4jeW9^Du<%T}Y8f8DLUyJ&59 zXw=B_{J_GWZ!7f*_l5sBH?h~NqVi7zChYxc1^dmgnxnu7AJiWPFUzC5*W`tdL(4vOb(78x1~-2_6jNt zT{B&@vl?>u8CpU!n`-+i;g<|ejS&JqtVYh`j~c0q<#f#Nxb1>7Z>GVlhobQjGfG-M zxB=q5(V@|}Kj)`rX!XUvL;($jC1m`|5GG4>E7bnY4lyfWuvSd33pN2WcyA-BA#|PC zE)tLg20+$_o=es6iGjUB>Y?brD6J2GZ?Gv>asbmrB>&7=r~_S5xl^8!LJvYC`Xdz@ z4fO&sqrq>#RpefN(i@;M7yZEqz5$K_mk_rJ&P+vlIh<46Zr;6mbvQV95LG02kt<*( zW5wJCOeENd3ueW@I>fB8o>lN2f${hfQP-cNumZ8LKl!%IqXHb{zF; z>^R)k$~L@b{{>2s`HW-YHNZw$T~5pSotB8;9a=z@>%VUwXZ$nFYv^(Oedw5(Fn-0n zrpi7Ve>LWIkl7VSfJ!!%o#9;KPq-cu4U>ClLDbGGl^}QClMrvSBj?YHp5L)DmAl72 zXr3T3dpzcd^x2=I$l-N9QdWndERfzT2xj6F1B-H_SX&W)A$NT?iN+FX6K9-Y6K!HLZzx7pI9>S^hMBr=vscAZmVtmblyZ5GH$>2(js;0atUsodH4x$Kz^8ul+WMhEoVy z3Wx+KGSH*uEDMEwN~GkHek&>>%C=T;J7*CEA=fbOu6Qv0adn~}X_cIzBwqkaKM2qj ztHezcXynnM(P!Vdal^c^#+R3|nSAWTL_@+D@Hi=6MYK1VAPHQ8kkGB$=+OOO_EuKI zc_0{iQ|B`^fw)U@s`$Znzwu1<0Rx7@9|$o+|5#2>1e6Eds*8~fOgFYoLmL8FCt9^z zSpDWU*sWjDjp4b)>1iz5I<7GkzB`oa$Ml)}pD_N*%w(q(Gkd{+tM_}8ec1NOt|ugf zpfW}^M}|pRI1$(r&#s7b=Xh$9z(s}Q2icMdKiSs_+)(tAJe-UOXf~N04R*} zn5zr_58WhFS0SV3f;x|k3AuU+WUr?=r$0YqCgViF@RI+UtV(c8Kmtn^*z|$B8 zq2^dNzZ!3Fz<|h5fcmScsZ=6n%z}*T=kJZ!;^PR>m%@Y|@=0=X7k5O$;ASRb3e{;1 zf)~OM*eq9+cZd73LfxDAhil+Uq<})8ZDwt)$B+v7@H!@rh`|QzH>!vQk_T-{S)T>D zyd9J?ZiMK-xsw#7J27!)n@RO3x@sx0ff^O~iZ3e67z~g`j=VZNFXpkva2E~;j3xGu zzWeaulposVt{guM3kR)YHatH1v_UZ7@>r=n7Tgl@lh>9lBHJMh7&IshYzj*$avUS< z($Ny*EmJ>zg=PF=oa%ZORuAICacL?)*;E-!nk1@E@XW!3QT^`|co9UMXM-4QX_9{_iul!X z=njJ1HHS?>MfJLI{%7!!su>rN13;d*>lQFB?%bhvkZU9?Ptnqbz&Fd_&<$g+%`~L)ssL zAwz~naIbF`=I0}Zb7epx7>-^mjl9u_mF{U0woZo%qMz%u69~*mofInY!G$} zRD}r>Cz@-1;K8ZF{N4U1k>q)Xa`>&eo1@GW7%E^`C-h;$uq-zl(25eS62)-{EsFs< zJPble-wYEqS_30|;~JZ#KBI~&D|~Djjh<*=!CxmreHL^RV|xr9c;G0n9vm88jKj(> zVi3L@?lRsEFNJRI<;$03a6tRjD^{>WSSppaMUo7Kh8I&}m4q4UQBLnc08G9_TQvto zFZCo6xTl+OK-*KX~w9tOa0ZjaAb5BBWx%mH+C`>hY5w z2Ej@(eWvB`PkDJ_2c`epcy2eQ73lXv6py$}Fuln_Ow&AgGVOo=ycY+?$(H{#)yNaF923?VSBTdyARJqLfHS+mHf+7>-UP##0WiOMb?U_sbk&+QgT)ww$T9xYqN=`>F=#(5Evp8e>g}C? zFmG(NcZ{WPOqH0rQ0O6x=Mul%`m;l;R^47iReaRUq>=!SGRc0=Y3GoGZNXSY=z5ER zm3%bAnLs){^6Jq|tTF37^E)7|8!kVBDqQy9vm~HTQ-v}gZWwl=ssK+qauW}V)wAo5 zn;}jVVm!KISQ~*ZUx$({Q_sMdE^2p-0z!a<%jKg@OiV~_;FZ;EMAoLwf|x$@J57i1 z!r%;(dZ8_x7+oWi$Zt!vmSPzaW=`{5%>zdjEjIbZB|;#>9;&E-K_NFd<;7+i1AB%s zkmNZz@Z@ifX^{W3rr>^61#@+m4wxDQHqZ-oqkYNIS307X#Oef0A$00vU&i%#i@^*} zx^w3PQJqSpsJPf~@td^AkLhrq!`;$n!dhhSqiF`4Si3_64IN`MF^R>&F7UTky=qJ> zu2y}6DQF<*7UT(IBcspIMm~K#57v#Qc+@3_#`3b_ym-(L{7flP2x#Egx-=UX*&NT} z#>m#s&oi;c(L{&dhTVa*QbOilI9(FZqK2wa?go#GFUOz@Fk~S-r$jQa2MV+VIKxS0C591CH1M5t=!< z^8~(;c27hB`xN>iT}Ay@&1Tow^XA`~H-A3Hj%`#_FlyLkCn-6$ug1coav#&Z7coxE zSba?-B`tsbecSy;9Mr3UwXY-@Sy+QeuHDM5foDy2WS#Qka2x%mP2YP+BpK0>0lP68 zV2u5Zdtv<^Q2Y7i$B1Qy48hgaN@M%ZowyMoJx{=zsHo@*69uIg2)FRV2UMqQA-4*3 zB1{1SfW!dF_G-12<#3!&x!7AEIAQd4Ag>04+?W%=GdJwPHkQ^3dKj!~lG*MB$7j3Y z;cVJo;lD*vCqBa7$13D>*%Yy-4C>zP+hJkbZELvzw)_ZG6NM)rGZbGxYv&1}kD-CX z--6Bq@t$tCX?txu+^tj25EThkv@_IxaOJF44P&xMjVJ`SH0#`AVicETRN1)u zhsrpAmN`>Br6vjE2dTWRz45&Us_T}*O(6f1w2#(_m_yDGlp9766bqEb2mJkcSVd>~ zW?SDD9VH{J(vDXRx0r^mQMEPA=7_^=WkSx*hD%3}&S8W_)lVbnkCq0GFdZgZ5O*P^CDQ<8G2t17 z;7-X)SrS|1%lA<36R&Sa)weuDAP+u%9BX^rTOeMRGg(r23QG3=fgkoS2*3hzD;g_W z1Dp}uWx_`-#%Tq|{`<@7JtUYP%#?RA#$>q>r;CE-{kUO~p!OKuUlBGZ_8Mu(1^4%n-+&5rd3vBil2f3jkPlC4h_H$vf|+Pa zA|w+gnnJcAeFXY|%P1`htQXLu1tc0soq`?<4IUD)@OIp{ZU90mi)!)L^-J*Q+~#Kl=l zmqCtUeq3~qx3HeGYu*=ULnW_)TtcZ2?5mtvf#?vs*09oD`iMS;O7!l$^VqKb{rB(k z(U6w47YTziS|#3x0F-2J_%w{`Fy={2NZ7qtIOf45kO@l0vpaXjN!g@B8xeHum^W3h zpPz70sP-U&&tiMbq$kfg?1|LIs57$IL8QNCBygG#RDAr%(co5Mt_c(kFd14kT+H2g z%E_h*&)GNr1|XOwef0F{T3R7Wvy-9lCW$e}6rTJj-z0|i*=UCDRKm{Qw(Y6Tpc~^) zg@@}OAA7_^_M^vq5H9L{%qL56zYor8Dv2;4Kmcyjhv$0G*_?9fBF{n&-LDB_F7wvOoTA?vVeg0b`Uo6;ehp(y{7R4Qd94Wn5HbQh9me(V$4Kre+9ugqa@? zH(jtoO2L{F{-=jR9_EYGC5K&_Xw?`67(Sc8p6tOs(2_3YgFBs~rS(kiX?CS3+mYg__QIRLIAnNh--2ggwTwwPX#}#nZR2;X3sQ zTB4Ijj!eeGgbEUnhLSP_KD!h48Z)AF&a@lr9~YBjya_Z~Pv zv2ugc`ItOSbTOa456m4k5-F$Z@-ghO;GY>}g36|NoxySf$7w3mR>Bj5bh*~aX+jmM z75*0~PCrnxp_at4zf+3ptgLFg))kBj1pi}5N&T;@F{DWs`WswqK zw*zB!Y~MbY*i#uOr)D~w_M=%TR5*d2+`f%WM2^yeEX)TGbZB-tOrO4=c4O{KmU8M) z^791~moYYjI>xjHSH#j}wqw)Y0fdfkcC4ee-7a>C(jP#bpwLeNR9lD5X7!cl`3r5> zi_#r(W(Q^++#U!|I!j*maUTM7NT8j1W=5~n%MAAb`#H`+g$+asl-*zJulGS=VHJW{ z)vep!9XZo-S@#B#y5Kqt{Q;c6y`isg0%7S zWhH@7N!oCBW+Sa2ZIJMqG;BCImdRw_)Z)(UqAF{)RW=9Y0%z?RZ>EN{8*2$LR5l)Z zh~L*1&|1gP)tR`Jo(QyTeE7F>7cMjg0D|_>vlT}Qx(1j4g^e1F4IRTYg=%BiDSaGA zlo@?Q!A!vbW&tTL^XXG+htGdA_uMyeC<+`WS!;kwF>$6wSZlqAyU=4Y zb}a|DOx=Df3s3z|U%zTO>VJ3HM19GW$azcIY*p`S*Nm$7@0wGP(MWvTQn#`V&S)`| zi3~}h_zlDTE`F_cHD?3aSzcOLhex-)uaB>{!EFdeW3XqapNwGI#Ks&xe3fmvA;-Jc zk(6wH+do&*W!`{i!cOYUOe-6kaMuGG63NxT_pe`nd%hxRVxV3u1uT^Y)h^joq-k2! zY4=)4l5g9~>O#J#-=F~y2%}`ZN+oF{J_~#aVq(_Xw@o3$5XxYS3Jw#dJz}6|_f~X2 z3c*oLQv{yEIHmF&j~fb?R_)q3RhBzlp0SvQ2Z!~5LjJK@sk?S78a~lQzrpUIQ8gc( z&YLyAwPSwmfB13u|6_{(pmvHc+3@}!HX4PG)apy}Rj7NK*JqJkpXt|UZIT@YnyFu> zq({F&gSxXCqT^%)F5;pxWX8 zSDRbd*a#l|BBi+nbBdcu+w_GSjPfgDG_@}SpVo@CY=uBLegA$RJ-s-zAT%hvDUM=J zP7dMUG5yR7nsA;U@m8^G00PCTsR>(xm|`3`@~4(xvkp3+L0&E~NkQdC$=$0L%R($x zuZ|=lwq!6dWm^G=HqTvmDG@sN~lCnojLQPu#iErn;3}V8NeKmi^|mX z1!0oe=u~raAei1=y3B$!vi$NoiY9&%qdhNzNUQyHJw*^`x%m92(9JOQmLIxAiJCee zeLqb?6HH5$h8!R=dKpbdO#d}X+zpLdY@;QoGV|Pb;6OYa3lL)<3UUc+6Qs~KR;?0u zp2`6mFFISCGRgLvo3w*u8YmWn(ZEuQ20#R3w*$!sZo>$;3pCYu5H*yuXqG&43nL2V zMv=f?^a(78-}8{WTMFdIAIBGr$fbBhe7E#ti^ZXq!p@Bmhn)#ms~c=6UC3bI?2~q?cy|?An!o z>cLg-F*WA0hsPlHv!>+vzH9V;qt(C@R3|(wo%CI2gqZDU+aDzU7>yliOtpIYM=@yo z@Ze>B>hcWa{c7&WQQLt_^R^jrG1ljlsSX>1<`_j7&=HvRuKoLawH`KP$kWVBs&t@> zxPp7VLF6fAdGqO=H!=$jE$Mtc zKj~KVnaLE`DY5`^AyuVWme8|c2Q(vkCEKj*xbFP87}6ufp_GY@iE$S?=4p`*`}rI+ z!DGGJ7kz{nBb8(L%>D^sJGnVy7E%a8&E^)K%?4Q?F%jO_kF*-gsSq##TS;t&uQB5L z8BhY|7zX=oM)VpGZ2GK4<{?pc0^<0ddipy?01f4?MV~HyiNI`0Qe(D6u2z~YRpob) zJP>RmC|@^kzH>9Lp4s@o;bP*C2b@_p2#R+9{*Vlwp*dxU$lsf9i$)3n0dPd+W6_L5 zm+2)46^}SgMKi^@Y~1)KfHV|1J~!&6oL8@QaoB{YjfL$D5BFx2pW^PxR8?(EO$Si1 zjmuohjFO|s;Vn`W)gx%?uFbzHSTlTLN?y3D#3t7TepS|{wx_d?->SuplMUD*q#L&p zrU73vg>I)_?yzcGDtOo$%aOP~N#B>2p6>T`nd|li0Z#ATz6`^ZpBnf-J6l{fYfW6? zNDHc(jqYSpgsP^Q{$Wac(3bGk)y@{hYudT}R+AznQu%0hEw$8t4_P?yiJ2bKnUazc zH&?%J2Wo|f;Mn$uR)`G*$xoktq|$rxM2PXtFB2Ys-8^K>!dI?Yv&6xHx=t+TMeeDl zIh;-(qwPsltN_xfZ)f7#KqdrKSVc6Z@-1cEdp2Q!qYWyO^41IrN+i=L-0Pu_)A?xu$01tR}W!rbK4DLOw&Ql*U&{Uf&*Ki zpNBof=Im%;!RG=O3Mvl=oj%9(0jH3h3ZHY#xN&62zL27TU!>pI@B#Ll@$_j7#Xn61 z+CubPOmc;c6QLl)G<^1v*T5g-ZPMl6HL39(8~y1(*Xdx+xM6Z1s0JZ#Xf+9``SBdx@GCE;2b!26FLhq@Ia+&wco_)m23mC)&iXAovc{AXxfUXnM z!DPkG4QvwOj6*Xsv$DDZx=O#uwgr2zMujI>pWy$KjR9TwekC`D5IjCHq2^6GP6x@g zr*q?jBI$mAM7SkoQe6z5LhG7!=MM6-6XfKSmpqipHg9!R<$C#OiZF04j4NcY0b+!L z&&eqzdJ>}4B)y-fWk(@qTDA%02f0)^ygp5vm{o}8lyCU_59$Q-8glZkmEEe#sV*6J zEi>`G@ix|b7Vj4SeE`F53MIk!Te$uolm=izE)?(~W*gksYD}@AoK6$g4tCGN&5HgB zvIOzHNU-==j0}B-_S1!=$iJd2e*`U*edD1#)oiCe2-%a-d6OZBeaO>tsl>Heu;~QZ zhBg)T{Ee4oE`vEratpO)1CSHVC*;?A4*^y2+00@^GgU~guu}|RH#=|x^Kq+*3oODc zSAo!uOB6bsjvYrJ?=;`SV+~D7x%a7ap!8KQ`<9CwPXq@e8eweFNS^!Y6G?>NP;EL9 z)QA!RwjS^~ARADZK(DEZpw!Wk2C0tVBVlHC7wC=61LD^LR-0)A+ZY5D!vmsjo#3sm ziJ%mA-tJLt8JAu`TS<6Q&d6EluV8^8UWA+)a4ka3=cbhfrkhu z`swH9jB$01a~9%upnu+g<&*`4#h}DcGY#e3BgK$LmIsOQ4WA6~4e(DcFCLG8xX^)i zSMyee?t%Isw&F&thqd zo?|cBiIwY8ceiuUoYPGRFJsU0WR3p4#0sI!hb zONK~{M|}$Hib4(92PUZIZi!;BBy>`SWC(O*yLUF0WEiZ-!1>FQh zEi+dKKB9vMo#%`BfRfXR<-wQ+|^p6Fh&G)ftX3k1$Xsl_u@tQHnsQD9Y*msjyW~sYfqrdM8j@Jt?Lg zh`w^gFjHM!eW(6j+y&n*&|^$#KU=xAYGh;h)-I_(ph8j(`cHj69qgB2hQUYQX=g`D znx^?TqN6Xp{ zwB5eYYSbtQRy0}?i_(FA>GDpW`*r)iLo%}6knCi{=X$j zcz3rt1^b1D8($PvM#aG9>;3R^#6%=Fo53RCGw8z+_NE=D4`-6b8QZ6A-$JF+)x2@F z{tYnwMrGgv?6qSDqb*b%icepcqvB-l$O!JF7_~l8ldEqlVM%_T3J=E2Okag7>w$$`xPw5e> zNDmod!G_3!cPa{f$WwH2osl$Wbl_R+&>^$Y;%9Bdl9urpQrt(e2hTjQG9s_6~)JotdX8N8SC>}#A zlW@3C=CQtf_z`AxU)gu9VK{WYgPU_^rd4bZ-$*9M*oJGlCm^7+yl(#HvuS??icL{n zBojveX;!_Ws$?!f5cUyB1Q&k1wxoP=ZIAC}#7u+|+8(dqo|5v0zy5wZ9txcrzA~;^ z3^-y85dx4`KF4ZORI`7w;sCA`J4 zJ397C6`RnRH?XL>dB={Y#qJb(lOa&FNu1olc77uhsinkb2>^a_feUC(=MmG2PTb`- z!?>evAORlWGiZtK*3mUuIR@kAOD+I5EY45dlTj{$-f1+ z7QEIAQyTcq)ImT%U_p=pDsQRSbQ{8`>GZ^^HD}JAg&N@jtnX*da*!q+bi{&3;6`%lmY+gN%=cKwlyDRU0fjw%R=islV}kXAhv0J5 z&0TmdKqjW`+23o*aa4JltWDuDmWtwxPY8pMB-&sa{7*fK}&NIk$Yn8q3Bms8!LbLV#S>EB<_Ga2x)_Pz{t zuR!{?Zl!I3b4ihLi5?0!0Nf+RIDlv-JT1i5k3byNhYkgOFNG5EBR_v1E~oTqRBJ+S zN}UJ$1gI??#Eu80G^3fLa3km^A04t;`--$Mr3;1CIYukPpPmoI=j zz-VPLuZN6R78a`7>7T(xL>sX3pil?t=x{bJ(IO~3ft?KRv{JC+=@E8T!kywrjXOnm zm}NN-Pf?%7m*w{U>Lszf#C);VokGya8MD$p0uG*;e&KK2DKbu{;ZDKxuBZ1hE2|31 z3fY`6Id&`!a$`9U%K^4ITRRbo1=g1vOlin+R&u&%1K9SGW1EYf>Hl&g{ta#fEiOln zR&XjQk`N6CRKE~PqFK_~l=O7y*U66`vz#oypnwH6w?&}Jy z2tv96ljB2!+MskrgO2nEV8N{$-9pi2v%V;mc`g|a%E^fDCx`H4;A0^l4GKbD0s>@f z3ppV5R7k;S3c;d+0#hHPI004RfK|(zXCAk0YY+7KA@!tQ*OG0poC*sIZJcwu)A)h{ zatd3tJbaPA#&{^7>mfijyhc)0au~RQe~np3vYNi=%A(<2yS}A^>CkW1NIrJw3>J>8 z+b$;JSm+JxEr4stZT)N5S7;{YQVr4EgpOLpzSB{oj^UyUT@08Bpw09$of1TusHKiG25#4e3Ntq2 z@ma!^Fxa{@hpNVieiRf4YVzpc?R=PfLWl|v6U>O*RN7JcHC0{bm9Xd*-lJJja?dW) zwsQ{_KRx^BMTe8f{Xs1}WT3%?OX4axVJWv^2P*wLxuyzFF{_6y+RdKSQf&Hz1ec`O4bRC4VX@7JI z{6Kt`-nOut#8?9sw)y0_|r_-p8@I)A38Kdqu%xiU($s=5JJiih->E;=Qm%07T~`}x0|i2qqm1jsWh5a)m`gJq-Gp*{J(oQOX*`}#6Hh^R=; zYYGe+I&){|AN_?G5W}D)lR9H9{5d^bl{F$uz7ZWcmbghdQg$(JE!{TmF>|EUy!s&c zbUV!*NA%jR4e8;+*|V5#W>PFr;-n@*euoPlun@rjY>Cdt{*a)6g1Tl;Nx;xD_fiP) zq}-m)I7zqoIT4Gx6=YTj!YnPtW=sO4M{u7y5=Uh}Egy|o0k$LylHRHgfx(dfQ;?bZ z^~?7f{E~l4W@Ll<`-FzoK)F5{Wg{C+u_bs?&T_!;ut!UCb&@Jq~w zeZipm{m^)pm?-t@8&2HCQwQd5SG<}}F2z(r`SmX>hku6(ph?^0##T9%KiM&lT&anU zk|1a#+u&B0WVR7bhtYvJ#Imb9fz*y#yUnYuq#(CebbTEZ(p;w zqjnJWS{09qtKkd3t>|X8ctBgXF;Mbk*Kw}Vy!2m8tFBJL*wOSUjQ&qj90D;0a(MIx7bm$^pZ|V5dN#4PHWVYGV@* zw9Id#0V2?hOA5A@_vmrw<;$0_!iW|#udI$Gtkd<XRo>EQ-ar6or(~URA2P6n9Q9d;!p08e(>|Ug|K7y>sslaCc0Y?iJiid)t}dwkiV; z^k41Oso#k+&!cqa+WJmWB*^{RweR0(=+prQJ&tZVxw2%Pt6Pj)`iCE-8Emyro~rxR zEml9g_-CPWymeCXr^1kc*q3>JccC*tr55fd)H{4}2r-8Td7%5i)q{bf9(r<~BrtvY zZ2nY;ybMhMKec$lf)fWVE+wj+XMuEcjKg+p*;4xKpS&zg`U-g@H~QYF7UmkMaODu* zFegQ;($H({K*~ut@XWX&>p4+t0{5_%6li8J(2?JvLo-cGx~M@<0ziC_l+>(g(?d{U zx#e?D0KN_yFaQGgM@nH@*Hf*A@i-10+KvU<7%<^TO0g^W;k-7$j+WZOi_XwX7~i}Hnm*7 zCx%$VnSPzfevq|{%b^H>;h1TpZtEL&lG*v@9$P(Ezs3BKi7Eq@lt~pAKrKVe08rEl zz|VlPJU!3n8v@&l5wDJ8dnO}rc`L z@uctUE>m3;V;QE0I>Go#A2pCE`e#ARg&We@#e!~(bK)b+EPTcu3)%T)$IhJ=I%BuD zy=Ly<4p=h!-GX@Q4#xj0exFLSx+cX;n^ASnVm(XNA8SkUXTwC|e#6*e{27tW+>#yK z(m(#F0So#2h;7k(NeGxG6`aU{)Q6Fd`TxV-n}GG4|NZ`7V}^{aucaZ9%9?#iwnU0# zNkXEsMT&}6LWPD1m1I|;RFWlSDHLNXOj1dbLa3BNo7VGq7c+C;=RVtYe&;&>bN%nG z`}$q?%uwGxpZEKHFnc=SMEqDjp- zOY(cBSbj|om|p2lpHD!9k8g->%W9WXzPoH`yDAZ+?46pC|?E8uy$!zDp zB$Hv|+Ky1!0KUrf((1*hgM;xD?4_hMX^|b2Do!Xs&b&>rO(&^Ci87t&HRx3_-->nX z#tXw0*OONSy-K$nBi4*)R~bO3&Jnh(blSkTwS<>8YEAcGqP*FZ zIg#@*(O7}u0~u$&9#O0kb{5PUub~ETJiXVD?a%<^S2$t}U`DVqLOKnL0>Do|a1aTM zHSEk08RB@&uoXgKba~NKBc7fz(r-++FgL-$nZh`5b_W6fS!{gy10+4Pd!2m|Si-vzX+ao1 zQoPGb@kB%^$LXUzm}abbliW_YW9WqRdmIvsT@0J~(U`M>PYCfTatvyClmdiA;Sfxv zvikgu`DidG38ej1RbOz2$$`NCKu!ac*@trm@e~`En}6TIvd3idL*2`4oMqdK%ZKC6 z(ZY$9FT5WLxgfOko`@9_nC|3Z@_FX%wFJXP45}C60^8}y^!owaD^{*Vibqbp!iepN z5vi;j(WXig__j1LIoU|=ObH%GTbj2N8*mOC>PK>@hT@WG+g1a=A~wV#IBnn^mzJ(& zamY5jiYBr+L|%T+_MVdR#>FA`#NrU3hm@Pq%ntGO_3LV%<-h z5_kitUj5LYVsA+0XPbpQWB5j*_L0lM7z!b$L~cXW*`(|q8ocHF8bdI7G%~y!ULm;O zX3Un9_wC=GhExar8YuU>p?EU$8&U8ur3DAwo>`TUIaGfAnE8Q5QC_xk<$M#9S}fNE z1PHCb5G@HLwgeCnYu3YdInG2LC>;c&(HK;~ri0kElOGxO*WwVjbqJ3T^OI!w;^zn- zPK+#g?b$uYZDcr(sEwU4ccb8d_+9DZ86{G3WJG?(wX@_|RaHIh{Rh#}qD$c$@xOc{ zN+=X-MA(mr5S$*jf|#B3$EN^*G0s2wKy>G1c!a8)rsceFxDIP;Q}#D^=NH1qARC`w zh<5?}Q<{t)|MJg2F+{RK(yMF-q7U6i347l7(v(CUtC57lQ{>aiT@T>1s< zzBWn{Mpz@pPqKptN6-g%yfmR%+ozC9GFmDhii^pgXrlGXSFc`qA>GTj6ne2xj&pwC zfy8YW7eK?;W#FJetyZc8pH&Q6fZHffN67l93tMCwld({9=C3qGtqO(MZGpOQBwNGy zk#PFv-qZc+CDI7!2p3%{5xr?#dFmM6su`=NC$vjQ4a&&fnE(1URE(oEk##U@*N$c? zkA$TY3Rx$Dv|Wi`HUGdB$@5E+VFVj`^IB&TAcO(a;1VI zU3uT3L+tQ{T8$^LVE5Tup}#Ur1-tHNU&i0{UgU8R(q=0n5}tMp20q~sfjFvO$*_p!8Eli=PAIEBZ|cde|b zU}J?vv}j`|-YDgogQa3w&iJ2T=BPILqitg@Ass;o_hL*vRRHUc12N1P)k!?0q@*JV zo!R-JtNQ?Lug;y9FKfjGJ9B1EyVaa#b|I1GUsHebN`(xX{Z{;fEJ`qZI<(}483EWS zjwXuAEtVyIyhzd~m`wDDVj-4dQRqpX)`(Q4=+J2Zsz^Yz3!?d&GpB=`Tpwj_5OZ-Z zMV$ai>Jj1FvcdiR`<3wYB_-$0RUJ_nLgfE}HO}3;zn^GaWLK`kg^S4|JwJj7=(g4Z zq?ZL8tp3rUF_rGzyO-5Rj0MfF5WXCd^U)B{Y^wGa({boeFtVVFhVK0M_AQvI*c{Te ztMU1_LxEX~FEgdcHt)+AS&Y7M?+H3_!}jgluTbd5D3mqgKnhL2eS7EfH}IAJgWg-4 zUv__aOhY$HQuaMG-_~#>eO~xn@aCRP%R|bizjwo>#tyt4g|t}kmQbgFn#1mGg}!Yj z4Lz&teMYH&;KLj|h?vooXvmCxf4Ed_8qOD_9}uwgk3AX9HNKWlD<@25s1MI=95K$l z?{x2`IfbBy?=&$V0wK4@grUXd(z4~u=(2!#A4v>C51q}cd-tZqMX;;Q`Cb^g&y$?u z^`OZ(9Gp(1m!-Eos(Zj2w0w7xr8MtwT_U!>U>ZR9K@98pv&33o@yHJ?fVfq)TVZ}V za-(wFU1p&GFgH9X|J<%ko3!k7f*U!~YO&chI~@+qwVJgYC8{F`n48op=!>rAOI$U6 zct9w^<|a*HG>*T=X@g`*ztCuF!5W)9^gu?b^Pw5~u&b|WmKo(POXE-A{9@NpsAjl; zIjpNi=3O`|;%q3~jelkk;hAnf2MUvluj-$A3hxgA8)s!=0w>mdtXZ>$JJ!wVAnr}@ z-aX=0EYikf;u^UgZ~(0udN${x=fjkhwc@a~Sj!1)n|r`o%7!1KQ852dAQ%^w{a3aY z@G%Ul&QK{>135$lkFqA0L5gLoHT{=<0?P~-x)ck5-}nr)*)*e$1K8uFIBc1=Mqvz4 z)a8s{NxS#;B;&2Wmy!uXs7ny>U$DWpNBG<`#)4zZXcjhOYoY#^twk0w8rFrSpai0W z*jhyXfTCQx(OYq{#*7`?;a5p~^Y8dzf-M*lM4x#E1sT9Q+xsaldCX2D0gHfPTt2q@!QB(!Eb)^LS$rK|wj?gxNkIUVm6h;#M zG~UfkC^p*f9ZBe?v&awl%#?Fy>690KUkGZr7JLB&QuW`pO44=##c&Sm+$g%yR_A~G zh^pa5Ru-wM0wJCi1j6Ai1%`8y@{Q#uCAM`O$W>;gGG;^jBeR- z2Zfb|xw)qpmF;(AMKZiR5F}Df7Fr$3Ct+v6}jdhiGhNi^A1)<*NC*NgD)gJ zAQOAiSa*_xc2zlwa4rntQc~7Yf&ivjU`C!nqNG;C)gMtI%?Fb6anft#M>23Aat)>j z_(qS8k5lj6TSr^W`7o2jVEnrqTxy=`yqlX4s#9{DjvNJI!F#6CBH;qgm^BFe-%FQG z2w&3qTYLCq>x5QgQ!q}{IJV!Jz5|mjv>L+tge5{e2fP|}N4jsfW&}mZC1|jdl9EUx zM3oStCFTRG8vwq8)>*Bx@0D)l$RH7p^+>NM#i*7rqZ6yk@zue5A_wsT(;F|gAuDD? z{uOh-@7{^yHfA?hvkoyHh@p--ZZ2Y|2AY?93QfT)faEJBHUTWr%VVCYzWN!TWWpk5 z!RU(*AI{{NPh|y`Xp6>xNzuC^i~lZ804rjw85U0Uf<2g@@v(pm+6YT4LOf0;6 zZ2olZ!+sYk^o1ldq%L?=NYR|^o)hXB&9XB7M3aZbLi8)RuZYDe0h=o_#g+j$$q%n& zf|h16ca>9LafP+_??M>421-Hugn9_|)l7)+J@Y3YRq2YNQbD1(q{NM<16b&#OM5zR zp1}3P<6Z6Gu&{i7HsudV#R%^TN5{vBiBexKRCQIAr!H{@1ps=}Myd0A zwl%FQ%QwL9i}+xXW)*{T5lT>-rIb9Ri^>|+vM*nDd3rvNwloAaAWl<;v77))7Ka9f zr#wd_pB&+xLW9jp0%c`VnD~%Ab3IXd98-Ubrb=LUqE@03T)avb^; z5z*d{vm??y>ZTcUFz`$Qam2rI(L3knlD2cW1^}@9E{?6)nJRXE(E7@S2{hHl<8~djY_#)8b;R1kkN)XwURULep zSEIS5T;WRrg9Nl}cxO;_0j&VQC1v^dT8U6qI}hO6f_X4b9kM61K_b}^;<(hzG#p|N zOZLH_05kq5EjxK^jwma*tc20Jo4@X8+wC%rSuqQ5K-(kf!Pdy0#LMIG)=>TP(WA3C z`)i~4I?AKRk(d$cBp2UmTL-t=rinM2%>0;wC#kFHfXeUowIgM%sV_?wd)^P@Hi-2QA$GB7~IxrunP??Cmym zC zVZ)XNYqS-bF2K;JbEcd?3LeNw+a*gTn!C5K1Q2wq$;tuW#E*itm=S;p?NFp4x*aFH zD(;1!z^ejnIhPKQKh$*8T$mG#CA7u(LBqES3MNX4{t=d5x(ti}2YHT1MNIye^Q9l- zl1dNbVgizY%}4_ZAZ*XX9zr2Y@ddH~U$!1QN1Ie~>XF7YJ-s;rS!y`q@m$2p(rHt7 zc~Wc)Pw7t^aO>6R4?CsXQ@DZcm2o?Nq|R)DzRBcx-Z1pqJM8R6Y^1}C}O z)Dx1}lEqh1uV(~Fdh?he3kfB=Y;bu%8$-609pZKK_-6vI-!n7 zLq#23IS)b+5So}~pbdi`?WgR9=~Xpc0D`snp&!qjJuAj?2}XJC_AXYzy+nI|*Ry*r zxBdBbt5H3h){>&JB+0@XK{CcyjGG(MLAv6WY$UPx*s)`9h|EzHD=UeFMJ5|WASs?1 zvuf!6`$GnU4fIbxA8G7-Vc669D3#Z!`_l%A?cSbgk8MqA*C@;UJgKr}bX0VPq6I_B z<0jl?){5f=Auygi4TkjT90^-^lu(B!Z<~9 z!BGUD$*z65lCTF`R=u6JG`Ly9;$v*HUAgi-wG7qD`9%SKe!QZubH(P6+Pj~-I7(#w z_0*`Q$nIqAf>({3L*f{r67JnZGKPPmLpnfn0 za0JrEV^CP|fS~fj$j}@993qi4wM@DFnYedD0K1d9xP{+48VbZue@Pqu4f6g2vX`VO z{9uM8h3!^bH&0M}$Gp63PXVYcxiCp2wdu0%@jtQfK?p4t|1GrmH-8hVETII~+5yTq z>A5ZI2G&*oa#U>rP75Z#Y?b5=scMeMzV@fTH;0V-k3YhXK~9O|-}V@>f7@eZ|1E>~ zU;54d&wSgxdZ$v-?mL0M*#FoZvT6_Z!U31r91?br@`AMHJ>^x4trNdHrvIh5sJ**Q zBB?Sicin4VH?zfCZ&W`Wr2rfEUjDcKu>Q_{UB3?(2w=kYfA9ItZlGmgD3PjvBca$W zDKp)wT=DD)l!%F!&p^aozg~NhV0N2cDAdKQcK(kaR~QJ8N2 ziZwdiUbob!h3E_Px!T2})?;x}53$9#0bEXg->4>32Wqlz5$AA9%rcyvIjbG&{ z^jVE<2oMW_{$fX5qJg z?i_<`Js3vi8ZH-zmUVGq;X+7zS}JzmL1(l41E?POu$*2L=d8JZ#sQS`;2Y7|B52s_ zh&MqWV7I{Z3jod8r^dNCCiJ%AIgKkV)5~smj&@>V$g)Rl;jh=v}Bm^Z$hr_f^Y&9u{+#)_U zRA4aS1fak2TT|@E-O2`F7%(W3zq_(CJ$>7mbv_Ggd)s@v3ARv zPMHaP;yH~D9-FMX{z#po>aWT|L_{Vumy8nBU~fR>xmmo4oXr_ndNX`Q<3KM&h4qFS z37>cEJdz-^8T4uc{13@R9dHd=>fLn?kC0usy4C}Lf%Z_fF{Gc(C#G=s)TP0ti)Y-o ztjUe-5&KlIR%TVUz)3$wUICUm%!~zu5E+g#!?nqOk#dx3s4mmKpob5pNxU`bVNEwz zY6Jl81;{u|Os<2_A}m<6Xi@X#+W=9B{kTHHbq$^{!Id}3{|6Mc6%RcA78C6IzZNwqTdv$BGD&r>PAdi6qnk%{p?Z-`+xFu4?JBjM^wnJ_mUUI+y+ zk^^A5_ZG0|3DklZ%!`#bSL5OsMbFC2+{1nhX1Ab`;32p%um$YY6EmIsR!C1Z>5mr`wMiVYJequIHM z5!;J!Hx$hHs!}Oy^McEAZ#9=1$hl$xE2hJFD}Zgxa&B+a^$o^O3z{<>+sF~nj2L4g z4y-Z9hI%KPNw?0v+zN)2Fv>5d9xW1BbzCPYcN#3rjV*7C1`C$F;F?2w&z(C7A`9Vq zfXW<`Pfov58n0IWTWoFXlG`1%f4GgfLbAg%o6vcKINMlSW}cYbl4uav;~9hn`fNDq zJX(3qG}Wa+61Bh3VQ{>_aB=dm1pXv^(ri?gmou;b1r}I<3k1&J%+|lQNd812cj(Z1 zIzn(I;#I*X7mRBGO&l4=s;sWRf$<6f|G-L>bhnz0}5h3&WvuBs#j_CLre<4|4 z8U|no0bE}kMWG{Lz>7b>S-!_8LaZyQMjLPk(@82>F(!#w&+-zwes+c4*!S(O-^r(| zMwVa9roKzMhnL9JU3+HJ%XronWvqT{`5$>By_qB_d_`^FwoMx-fcmUv9CG#pU5bvr z&UzbO+T~iBX>=dJhvboSSf26koeT~VNrB@Q*N;SJ5=yUO6|*pM{*_fJTFx2JEC^5H ztKPJRy{57h04*+TED>O@>X;y)`%@|Xtn0-chwVU6G?cn6@Uo~V9h{t)ipdz17I}eU z79NOKqFEf}Y0h6}|C+vjiILN{qA$68WGvG`4(#%>RHDI^L$GF{^f9>|r*2Y0JaQ$&?yw}e${Pr?C8-B5&+Voz- zorT|RT_lCG{y5gCfdHaKo#3U5!+m9r+xh*KoLZiavd}_sYY@OgkBEJ+=WkY@i7J{) z!OB$!sY5an?d{AAD3ruY0tW0gcE^~8@Bcy|fWSe>_-@@9U>Jt7`t|EaACE!#Z@!Qi ztgU*>59QL-2L9znaW9Bwcy2^Goz7wO417EPeJE3K(V*?(Y#AEcnrU;Kms?pC78hHa zn>#@L5(2$+Svmo#2yh0D%JJ}5A>)xA5eUUtrZVUq%4j@@ndbu{TxY5Db#CrZDkNr3 z(3Y*uO`w6tY=R{ZZ@6!Cv`q>#astxTfs?=QLh;$IK2=ytfv8csq#wXPcr!nrM(xGE z|B)slGW`FLCSvvhzm`p9jQpkT2Ylf=!Nxb2<8`rWI*JCKB;5_G%aUpLd67cK#K;%T z2Ev92yBQ>Eq7Z^RZijYoW9c;>9mK6$Cjh5-<8<T?`DO2F|7YZ{L0N z6TmqFtJEMOT^KbJ#?W>NNuygs9dDRPdcVCt%Lm_=6FWVo7_-x(u5qWw=h3jmfUD6% z#1sj&UTv+sxdmVV?X@NhyN9>ViuOa11+tZgAoJIFltN)Nsj8Q#;u#wi& zxLBNQI$B=5SaUJ$kHwj%c{jpN6%KL{3p(8DH%Wm#3c-btv^gm_H{yB!&+8%FX3lIY z{4a*BD%D7T}`R3;4lF(UhVK7eZOQuDj*!JVe!aj;ns6KoKfGiBa&2-UVfMV}2 zCU&e_-B;Yfw5jk1Fr$VM>1|`SLHAH&XWYCFu1oc!BS+URPbv}&}0$hGf9!y%R&Q`0%+KY0yB0Z;Y~MWp7pypGb(Wo78$;E-Ww zj*N4*;r$D$jsaD^n2=#}3?uk>p6+@;Xy#)H&-OG*zGOm?nEf3%@GSKq92`49s=#uA zxKgj#Tf95O?0r$}{Az;*7WPp0XpApGPJ<=J{3|pO zB^W3_A4aZXRGrBbfXk(gqPU5hQ?75YFK#rRV6LvkOJjiCX3bk@Po0{~5STUtypVUy zGyC5F0;eRR($RZwpgp0sR7k^+0h3}GqkY!s2-KHipPt9;{!-G+3v1X7yqB#HHXFar zWzPve3RXsH)+uf}@k0xcq-;!`{KC#(FCEvc-U{LD9xqHe1#cJb$zkfpo)7gVM5;xL z2DONYIpKgj6PxyY6drukAXX^hw19vC{YQ#>%{Z2dyt`K%_$ul+OSDl|Tig7}2V^{cB=PKwdgO5tH~podap@|k$>p&M3q zu3$i5Fm2boF1XKPYxvOKj5m@kgexoapiV}_;7_{^7)OxyA3RvjmoZleJ}e2C6i+KLp%Ewbb8P5d(tj?A{=R!HmnR+jPgo;{4wx7SO4g{RR$v2|2}K<{8O59Rw27 zWGNMkdWx-H?BWAbHn4>mGp7&q!*nubm6b*|Z9+c-J-FD zg@6^SJ}#|n`)^i#oG=~r;>nW>+;5sNB96^-Q`{oK1vVBTb`Xwu+;EU}T4eN7*#s;o z=;BwXa|lT4?u#z#^cp|jBy)E7T#ke2z33YL6c^*WoS?J;&yJNS(f0&jLL&2I)ySmF zhYuU08g~+2>-?7!YY18!dCoXXT!2Thw@1{T5s5Bo6Dt$T!!kfMUziP`vgJMA?|x0TdA$0O!)2L&_{ty_)1<38*(~?UGW=m1 zUz+v!@#8s2?=YXoxT4(;TC41xT+2Z)+pBYfdq6SrxbmFX=+ zQOrHTZFDzm$zo0;DuU5?-jL962BJKPs53O@Ig?iSZ)JLk}`VuD#6vz|-91P6F zu6W)I9$KA!Aq?3@K$+|CpW29jkv77x<_kn15@2CHw8-{GI%fnVWtT2=5KJ!(2-$9s zGB@=GtLXGXsHV@HJ12*B)^5eKJT3;&g9DF}rI#{c37|vVU!uO9QL+Mki2-YHQ!&<4~xL zbI2#SEru>cxL;G^gW?CV4(2-g+DI|i<~@)~$^F*=94X#nb_kjkK2aH0p;s8cfaHZ- zzi^?n$_*skPTDPWY!^$w-TRJV=~lPvgU_;wnI4@akmFht`6aHIdkdCNg1}aBTVsDG zn24MYO5@pHM21ye6Zy?ik?0)mGH3Se(xa~y{ntA11>Z)T|4+5V|Dsyrr+?p2v6Xxz zDqe(BtG>(8vBdfa?)his7k%@OzR4fs*W0a0bi?=cU zL-(XN>K4h5<^q6vc9b6+9&9qr4h*MQ?s8wV{??P93ui!2AW0GsIo3^5=T8@_j-DMvG!r>Gqaf3pj*#F|4#=x zVBkRb)fwzKrj(om5;+zh=D{W^MlDqy-?>Ag8p%O)qKZ$7b;7fc1i>`x%`ID+`8Jae zCf_v_+qx|RTmuOu$}+n$nq_)0FU9-eBpV~F9Z!X7dojC8oib-LVv6;I^c#Xew{JIS z4(EP~m-8jbjTt?f$*;_;EUyR1$2MZfCY?58Mp;=|CttybWM;NyH8FH(C0O;3ei2wM z@!`YN(<+Su`lOeB!NI-WT{Gp;w3d;nqAT%t2=>H&ykE!TO{>{4S22}mFbBSARO?Fs z+tiICZC}+^rXTR}SxZg2A`8pGYboi;$+o0^^04yBlvO~O%nwA?dTD86rh#x{|KY>o zn_UCvQ$Pxw65pWWTdelDX}@lrXndpUuv`XzR@2lBydY`oA9ZAflT!s^1*Q&NaAfuI zk>#&sH?(Occ_O10?e>6~;D=x&c5Bz7*q$|G#&xFNn9IOa_9-nP;SX!p+S?mh=2Uv# zt&TBT1k7n9EDDj76obqdT&>uEO8Xfw&Uw~`E-NTh*k$$-)ilf;Y=mIn@fwx-iik=G zdeN#s!Q=Qy%cl(Va4?}##K?$r496PYMeN?`ZqHL>rU*GJFymK{Mn1+$lb;;JIkdz` z=0c4rFKJU#Q&WWoFm5#!at#JHl*QO_(K-;ftfgJ)($Ei0SbF%a*BAD#!Q( zuA=`*JvZ_szs>+$Xur9nu%Kox!%`LW*#jIaQ8>*0)_#}g_3~$nIQ1VosOzF6qsw)i zx^TgQLv{xxXibj*I(&MVQB=XHX%)v)_mX-K?9I zd*Cxp9m8g0JBwlJp#J?)T3hrRRh6v5?gG7)XX^+1Ka(gfG+(_sVokqmTGEt17u2f7 z$DxOql<8Vj*@8@o%0Ih9ww0R_*f*rdw?MzCJVQX`D(z-&yP!4Dz>BS;)O1JD-YK4) z$vme;d`EV&M&}GoP`uA-kND9jy0HY~h%>Bfc4a(c=cq`VR(p6guJ%y%w?fYbnntj#sB|A7480hU{g`B7cP%OQ+#cGV-qV`70oEG zf&QXDyH87-4w)zf7ApVYY7giuN$pt|R(sU5+G8sDXQwB-iI&^^H@L1wwb5UDRV4N5 z|Io$!{fYkjqLlv>Rs5%@;y*cJH_EhIN%%-m%U;-GA<+v-MZi!9Amv zB)D%4(w+S%Z0d@c`9}=2?;KleU_5)tu%0bsJ3VS8?KEj$uT~v;wQMz_WQXglczZu> z=XV3w*G+gl*C@kbo{`!kw=;3jV6K#Zp*xy24AlOyX-QHY49ZKhSg5qKO$(K=V`D)F zK<=1ASb1>)MCZui!{sr405fOAbFPUA>UcSeWOH1UMBMX#SIyjMv@jXR3c_w*FyWA(50#;};M9 zG&5kNB|R~9bRHH_UEAEFk+{8NXxNUv9klX)gRyJdzCD{ZPKMUE?K0H;))H2d%WCm( z<`@}Gl{tZ6^urTnGA}OQ!Io;O0#KeX2Q>KAI*yKN zNP{w_7?fdgUMvgB0RL&eg}}JF0Btjy(&?85s;a`7bgelp zcq=CV)zo6b!o+HOKfkZcvVn?XHV)$N;RAd{m6P<~0r>8{r%$8aT3oc~=^-pSz|#>_ z7w?5`s^Vi6|KwTRE&vPrJ9iw;4p;K<_D)Vs9f9%-Shu)>(~!!FPUZMg{iPQcoV~gJ zB@ZU8H9Fg4cLQe|7)X_ZQy+dzwr{iQ=k5~uW_#Q(xlc)G79@QlGrILE54Q~}lCql| ze9i`jLFb020V-oAtEa~(L{eg6N&%8R{0gW$(V1A=*bE*tDC9RsOC%7;@?1yyA2`4V z7;$(;A3sQeKW~Pkq2*gp z)!8%n4_^;9r;c%|Hg?z!^;TM1N@wIyJqh?op<`z2PTWs9xlhqa9Ij%jM?g|2pErv+wR@{MoXA`mVk#uZGHArq7cb z%>aMhs6Kt(gO}2D5|4oNgXHEad(br$GdROJ!E(xBrE0Y+4JUmLOQOAIdGFfwrJ{lz z*(YA{fW+$L4I98H4g2Fsg^oxQvUJ0SF|opvy6LOHO**ZQA1h4@KYgnIls&G(fzd{+ zL7&(PuN>ApuUvWW;lmol-iXmUXuZP22UgOkvW9O4}}*nUn`|R@Cl*=Goe9~ zwgJj(%NWd_y=u*x;J*|Yuv3T2uZ-Ep1UkUnQ9RR+&sn%I79}BAe`|5ZDD|^hHKVMH*m)B_UajXW@Z8Y{CK8(*;8HaJkk>A6y z@O0f}Z<`P2Gfe<@0R@Q&54VP?!<&!6AepIuoiCrjrIE#=->$BX8j@L$X%772sM>|(0|b2!DeVi&z>Dv)2oM;E|zOz7$YP^C{1itg?P~B zR;wg2UGwL0_Cd}HmHG8ov6Cx3-JjL&DnI46Ecme6x^M5^8gBI{-ktFh;y&YQOe|(? zBa)vk%oom^*V#WZD$0&Qe_SYp13D{hK<*)B&YoSPt^ITPj=uf-Thbi@Mu^>)%x|iz zt9#u&S>OLeMQ@K<)SY4dX{Na zp_)Xz%T46+@_bvhZf)3Axb#MDnJkm|=n*A}yDP;^yFI0TwD2k(7~j>k^w&SQ`_E^6 zU2Y=%G%{7G~*g~Ppv2F3Lbxe_*+M;OqluExY2O}t@4 z5)-WYxZ1$}0qoqnw_P?0pc0aB$fCJLK_G=lm2c`AHs+^(>i!&b~gkCit?z)3+D z2Jil%1t=Jg5KibOs%IW$$Lfg>&1+}Z+3yYJAjNg!$`E5ZXdx<|)Nrmd-cR*)8>!8> z*jh4u`+nd=bK&q$_4xgF1`#nKnIRnIYYDb-KXE)1Cu};z+Puif$M9;)mrvGF%|siz zn7>X9!@;p(S z4?nwJc(9omQ?M~{#cwaRbIW3pv2yk5tfx=4tig*1`XvfmS!HhzA9zq^yv&pK_vgC8 z)iY;PkBbn26FtGp(5$6Ucx9{Gwc8sM)H60oQtJJ7V#lVRD7o;k`n;IUKQ<=y!GnH8 zO2rIk{vmBomI8hhvu3frN?GCPQPKcu2N22KJpu6wHAXA3F8C=14=E`Hse5FB4v&}d zGNFu+>iCF-AypPi%B`AyOsQK~-9fgaFd2quIxSf)z(y#*s785LNdAV68b#@KTAkAV zQgRpWTyK$8I%uI*v?oLG-#Eh9;8m7SLC$_^RyA-foykzRT^n4Lf=jHv`zQ%Si7T2dc32-;Ca3tXenLB7FwM#LHkjw6QoQTRodZ2a<$_Nkh6l zW@TdtOT=HqU}aEIqAHgAFvC%7li9~Z97`xX(hoMRwPgi}&`_W2&GU*G<{OKXXy%wIi00|h#!x`)5|&7Dt!b9b4+c>*};Gk+%I0}Pm} zmAfFHL$N`f;)`X=vuE$2Nrs43ad?}yPj^9i;Skv$|E%IUlH93(JuOMB%Ai5kOPAgX zc>3Z6)8znBZ*y}owA#_i9k=AWAVVVA)UCy~Eo*y8HmUy*V^nRSz7_@Cx33le#SFx>YbPWZ?t$6K zJ$%=!TIIQGSJcIeCthtw+MAKlQHvE4kep$62-FObahWN8nXVe9y!)8QS1vt2BwrpN+F{0{Y2CcKSmAe?d8RbfN=l^AEK0pc?7AA za0+#we^9d7hp(Vd4pB29gxDN(&H2d}Qlz9x(mn~y=53&OdEnVm(2spZ){Gy_> zr%%JNoaRtVwGgK`F^WV6ewYIo_f z9urQ!8I1rVxd_4;uX&Qwlc?f4iyESrUt*hIf2C&b!ZH}9Z&^%&hzo087!^n)p2ht= z-KJVpeEC8xYh++>;+0&dP9#t6v)7FTn3uE2@=4tPEc_uovfx?RSOxAvXDEE4=;gVI z6vg}%tQPErwop`Gj)`GKp%@v1NW=YrRa|)T znJ!r1>Duav^9{6}gl^ygB@a*!>RqW8ti?@iQdM2(kJ0A^Q5-QP(?N?sjBDJK$7){Q z-dK0^n%7QK(+$gBIydSC871+2l6rZ-Pj%_iB`7>4)zv}&?fdsr^lK)u90q?hbxt93 zAg^D^xYrkhLosK$*53ZqD|j^$F>#e|UqQ9FN|9E^QnWI-((pxIr<5jrD|sO6Q&U&( zsKtwg1AIP$>#&K#Tb4ysS2ee!9{T`ayWhvB-{8UA*ghV@V{pU>zgtU2GV&80Evv=C zi!fuqre-J#VK3&|N_n)g=%u*j^d4!}*_;EuaW4@2o0eo}5sF$g> zurUr={8O2HAHOk}>S85S!QQeAF^;o%3ndtN1X*BHGsADdMI<{GX|mg4IFC8x9@KsmNnc7!XBPl{dDjmZGp1|b&mYoSYeZr@C+*h9 zZ|BN}&|?&EbQ;8W3WcY5rP*rzrVsV$!6DDR^xCs_se z*-lTeDfK3W6Gw!iJ^PY{H%qtxTguhWhlKp@de6_@U9>BTia9uzz-K|!JCSL4%d%P= z$Kl90X)u5Wkr|VM*^vM`fR+-DdUl-Qq#2w*tp{X1>by;yRemtVSbTl;YPv5lGEV0d zF8&R#o-KFKUXb``a^`@JVY{QroP5cEC#+_qyqnSIDj|AGI*pqhxxxX$xSDeF$s8y-D;IHiDw$hKj?xN+USKR1Q}2X%AVosh%%@Hu!8 zOP7K4Ge{GUX>63U{^`kL3U%hggsFs>y`x&#tmFuD8y&4(!vJvd+4$_3I{qUgoG8#1 zGIW>S$Lh4XI!eUwaoPMY7yTd;)#VPO+rGuNNjaUT%P`$Qt<)+ePe#cjR$dVFs9148a4=wE9|oDD#|x)s1|bb)mv=fE z>+KyY{XYI4(5Gil_kao&PT&g!bqh0WIETo`xTde)ywQ3nDVvT+gexvwvJtcqI&tS= zTt7n_5jp`oP4D_7Jz@9pJ5ePY5aabuS zi@quB-PxPu!t$ajp^g9Tw^PQF>H$`256QCNd(hd00(Kd5e=8QV3q<0oRae~d8`=H* zqAS$y=NO@-9Rq&l#v-fWZ7?*)qMc7G7sEL7=de8qA^)Nz_4E`CpMoQIa9}V+EPf^bmtSCB!P z=g2E4%&gn0C4<=xJ>1|~>*7T?jEy~VBb1@RL$T8(8pXCRs0M1XN?ff5Ny?OnfY?Cr zMHHca=KtYI(x|NJDpJg_>ip#=m{be@O(C!q)}7$}q36!k)3#E9f_yXrWG8}xO4FAS zM1ef$;ZYsY8X`hPm>o8gm&G5YI4IjZ4|szvmXgB52U5aij`>tta|(PzBcqa)&*qT; z5UPS=eag+>NsXu_qqeO)RHMbn+nVboAn!wm4dc?%GVa{HdlP$l_0OMZ(?ZE(;ZP6i zstWKb{wj=$i?6JfE+RV+0rzIj^N(7c$O-BZe-#O<;@k*c9D!ojz1@E5l*-0x${SLp+p5v@aJh@yc^kBp^lZ}ttC-g`#DveH#w{Rp5%@^r zkpu`#B?_i8lj}mH5gJ>nBjHHl9@xDl_J;1V!|5`?DCra&8WN1TX6^xO$Gv#z5*m^a zDnCqO_?y&U^2Kp8fUFp}a8<`7gEd5_{hdv)$ z%zypC$+`BV%LY$~77$F^zga2C#F9xrx>Ej&OZ>Id;%(lx^H3!oTOEz1sGpo8+I$ zdi?mt{6kRX+7o=X`aVEjBY%?BLan^_&lVnHFZIZu65_WY8IuRG&dq7{S2rg9lIXw^ zDyjZ^d9;xqneVo~4M(aWYk5_mBFu_Kvpo_?!);A=gh-yW{n45Ik3LA_L*fsKuNy6; zO>0HPKjdrtgK7Ae{LcTke$GkJ#ELqeOFEeb^f^s`*5&)>=8p zD9Om58lPe55L*tMViFCucaJguc)6SZ`KBd{cYOGpi1~l|@%+nQ`nh_8Jrv=z$sqdB zSHia1%8Jf1`G}gAhCZG~^yQg`cu@c+B6quc=g#v~#xD>y2avG*{8W1N8p#X=1P^V+ zSai-?v8Oa@`S#<-aZDU(Jz#(sLO4?$Z+LP$3+)IRd-OI?4v}I*XB>V*mv=D?-5eMe zJ{4>2?4Ir;keC=XvM22) zmCZo8>BhzzD80dZK|*om`TnIjqJ`Jp!jF!gUS9T2PAtMj2ivsCZ#_ZD-u@E4RH)*5 z_3j-NJ8uY zVg`L74X#NT4pac7sQ&VX&QJ0pR}A~l^(>{$%T_#!?d5O38O7ZJ!N;pEK-TU{-Za&_Y$lQ2ckI~9!J&(lSgQigXsxg}A={R5=eXvq6?W<`3;epRO`%>$M3EXHcU3>cx<;+R{3bNo8YW`zK;b3*J5LxURuEo^6!~v6k^d?$6(8#VrB)5 z|3-OpZWkwZjg{5Ot=C7k*d}GKJL_zBkNy7P-2;tt_UbZME!Cn;8=K8gu4VaB$DEN$+Knh;IeZb#81fGD3HMew_fmO;`nO$eZFLN!&=oi<+&6qNVcrOlMku3^pDbG}l4yh|AvY#8pO zkl$moSA%HLJQBO16sUuX3c$G&!kWmaMy9&>ckl4@CB*O8q@fthXc0B#W2)4Ygh@J& z%|o`2AH+I4b}yMHb^u+m8ql)kRAK@_4QLVqzb`c(575SDg5}d*UArE3`dx9H)7k7J zBRpiOR9!Z7Ei?=pce6h=IoLO5&d&Dsi!Ll_cKlO*{(6-EPz_*~bNa*0q7Er)y{V&c zrb~1y`2r3S^TA<;yt)+GH zLt9f0CaB4B1mMja`gjS<-M;~DInG^yDXh3~&4*obYiF9r|0 zd1!Q=^X3(goQxdoTZw(Q{)~VGeNgJ4CEu+Z@h~3Q5!wT|qx$$MuiqRIE35h&$|zBX z5?`^B;&57WDUeL%Z*HV8%29p86O9-$#M@QSWg1ma8QvzA@Y>4y;BHKsg*eE0^r(oS zANox{PDg-xew)C(C&_FmFPyh(RlghW+bEf190c4AQ!>ZE;2L|Ujr3;~{krXz&+=1e z&oZj=2v7-<3^9(6#s{23;ocQ;IGO~EG80`r)@>;T(=_JA^GgGQqC?9x3ix)vn~yA} zh#Bkrwr{^jwZMgS#oV=`4E7$MD|jky5@~R+mlw;PXX@*_mF6~U(c{Nk(~q#7+KVUy zQVj?*IlJiPtYypIfMDL=-4#SVW2REtvS$P3ykzY-idX|Nw&Jt_YZWpa&3xgu?EYP!-lmPpqRrOijbn>V#@6o!!%Ek@{?|uRDt5M{_ z^6K){F!@fC63N%Nl>6LWR{ZKlT#Xi&OGXJ?+(VXDOv_UMKS9ES7LaMSq2Z;YQwLXc z?`&1n<&eFDLoK`sIoEjL{J2Gz`Qw_KtIcg~lY5-*B~)!l>|85%W%2vrIb^kJ)dD=4 z$P6_=wx?-5QrjzE3LB(uB@Xt``8#lwan>rw1+0_y3^<0Kfzc zbfRoQMF`)rr~8){~fg9 z|5oSyuW2onJXp9S)?%vYa1OZD(M%t?E%2hpf%G{SHSF*sB$pNY$;b?mJNn17>wHl} z>gFvP_sxfoo5^nU{L@>bIj#W*zrA&NK!q~_7*~@eaEXa9oeffr!l_FxF2JscOhfHj zC4F1gviy-vbpqr_&h-tcmVvd>o6Db9+#XZB;XOC|dIKnP!AO0&Q|jXOW8;el@6%jW zMiAZa?=RJY3MabOF9}+BrhDx>eh@#j3QChv|yyM1#|0wrKi}Erq6+R?bXr|2E>6%l7E! zDn=aIw@*ukdSVZ07)~ZU-17btcLZZt0;sQm61O3V5l(qzg6r!LH{{X|>ly{_<|tBU zL$U4#_H7+Mt^j4^oo|qhK+Z~Ci!QA?{RTL!u#jA}>gv)zTA-_P{S*@g8L!ML$IA=1rSi zq8<{u($drMm%$N37uQWDhFMDzVj6(36I4)fU4nSJHf1_fra(jFp@2pbO<0$_W?e?LNtYms{%?bn-3JMCu=p0fsNQc3cv%Qny^Q#ylB$ zpc4#q{jh3ANrCoX)Z9nQ(vTe=v;V*W2FL{;PoO3Gli3JiRiVE&K42Hm2z|vH%-xnl z=f2_eLPf5~IpX6}3gFFs<26xd4O|$lJAZx!AB$cX>I0ea%9T@ebWl1B$K!|3dGqE3 zHsFG8u#h$}v4B#D=8ILThsQc1>HBEZzE6|boHjo#3s?s?&#f*X{=m4DQm6PMtd{TD zbGETDJ$z6^L=CokG}vNW7##|-aNGr(N*jI!@OawN^AQnZ8w7PLs~tevIjG{O0|y5Gs^mdyB^J=2&c_fG zv0BmZzy)-go9b&b6B2T<6MOsN1L(+8f<0;EBxbdFd1;ngiY$6T{*!TwcJktRxRf0Z zNfi7^4`bP^7YsFP|Naycz(Z>>4sXlm` zWL;!{DbJpX8Ebg0X3e%xAzeP&|JkQt&g=(XB`hOl?=Uqr%2Hxc9q>>1BLFrSGhhRa z0t09o4j#YK>9N>9N@_mvtGRyrau;3qETl|)oi-yoV(NLgPTP6JekL{HVp=KDQo#h) zmcDN8KTA+a5 z(jSD6Tg3@Ht)&Y@Q)gw$=OQfQjTn9fT?WUXtnMLyiugfDBxv!W=XS$lpXybEFOM`fdMlw&^poQv-Ln|IDFU*z~=54r;YBF<-cNJtFYp))(jeyYKt3fp{mQmhJ@ zHlJi*aIt3CpUW0sB|5!5Y1+4-UMt(COsaKgMjy5H+9i~)Yv;s)Gzbo{Y5)@e_u;W*MsI!O|eQRicM8o zy3~nl)(rGlVmTzNwvb=s;ZfD3hC*dZL_l;)>=fqq&!4j&@)O1JVvX%Il~XW?88?oB zTO=1;fsGqBNJZm`M;Lj7sRZ`cg{_^!fu_R+7Dk*v4e^QLg&m|M0~); zW`dTdUQx6UnTr*FBzE2JuGI;Q(ygUa)&|~v!BM~`+)Npca z*fjF-mScE4bmpv9p+efQaU-OAM=?%OJF~DrA zSJxDFaid@^->q43iCuH_UQv`Zd=lXIf(S=x=gzzVu@)2vEbQKQyhBD5^`&KH=sAaB zdPGL2vI=kaK0lvPmwZHSJaEnx-4$v#y2}d@J)T-FKIyn7;#}-SW@{OJ2ae@IQ>nzg z$Y9T{hQ?;Rbx=$wgl=)}{+4tJdCVIla43Pc_{SLyz6V7b^2+RmnHSHs~AD_r^o+mUfe=S`2AP{spe@MJqj$B+)=23@GJrx!rz#xk}liY77=NljFDW9-a1qYgcAMy9omDtY(j z&2Xeeh2@~*f<$&0_>Fr(xC1yqgfmd?W5f!loLq;j*sE8cyklB{IDRAh1BxxfP=7i2 z4i%Nu!DNUmeoA--l2rQEk~8-Qv!k2Na_*nN^DLw?-0?auPx~FJBkPRLnfgh@2=4vl z8|VyAIt8L_rYyf1GZkc)hj}_AsFob!xs{`>L{o)z zG=|x>w2?&?Czgkd)fnY6n$fN4I6YXMWAX#}Arbfd-p_k!bdkew?DFvt2@lV__||dZ zaoPg$IC#+fEMQ`S1Y>n~mxV_}Sc77@@X@)2F}w6Afm^j{!|P1zXo-Ss zY_Zbuiry~IonAB>>-4s)%%N%6M9yp8qD3EzieB=A3vTk}`KANqA`pL$8dVXo=fJ*w zx6u`ahJJYWE(WD3`iTIOS&XwVAxkgC7iM2*b-{Llb>`2P6Z3f9cbDC8YcMl5zLxrs zSvs}$?USMI!k@Y_Z~$oI;C64Lt8dXa$5YFjUyhD0{rp+r^Li#x=7}ITVa>$;)>+B7 z`IoRClivm6@ImUi`9eRouvB53KCbz(v18S&Zf(B)FHI^S#~Z6N z26NiTT;ve){hY2qg1j?&54s>`*u-i$El=hHZuIfye@*2bk0N8~Nqyrup!*HtpBmzB z-qPF|*QlroC`Sva2%$j@&KJy^KUR(nP@fA@`vO?0HdmX;9{MdV5g{SvZ|=4x;ei5@ zp7>d+ruzElkDfYdJH4pWwp&3N4PAjRshW7yOz%8b>|(Td@eqW@Hd71bj0zt)#kPsY zf1WGAni@=f!uu~=Jm}KV7A1wJ#tpV8di|PFv`V-T$DCVS7L?mF6s>^Q(%UI)Tmv_7 z+#XOcO+_Z-tT9S-+S8$IQzEiEo^4$-Z44eOOP2Ih3O;jY*TQwH=vKst6gVnXXIQ}w zs!2{GeU;c&LUa53?>fnWcS+ND7l}PkPA@z4=<(_G>l7PRWu-ghU>HM4$gyLO92uBc zKVv(|rv5pEF{d-?(e19n%lS7DyE0))8b$t>NiLfUJ;} zIq5gaTliSM1L5g2>zHn2(wFopOcad)j>01=>=YAvdFXm?x{OJG^5m*hvAmK8`%$>9 z#1FlLK0d3QBi7%4=xAp*ymLgzaIu5F`{+`!ANBq2%2MUb&qtos{T^%D97Qrp+*JKP zx&VS>T$g`xtVU}}M#4KQLRTZXqll}!nrKr^{s{2$ia4t2nWG*HC(jFV(r>3@U*N%|_2F-r!-1#wJ+9j4hI_*~6JfQHF6r?7az8&wJnQZyUDEndc@m5ke{znKEXUG?1a4qA1OS zP1wd{N|Ya4W|bt-Xs(n}A*9k)Dn+B_`kmK@Z9n((Jmq<_g-h6`+n|C z{eIu?=kp$}>v~^r-ZS$~{2KIn^wVC44{ync&v9Pnd4whwr4JYXv!K|(Mra(}=542V zSiAQ8&Yij`DazYTRk!P0C2|}*I3Hn{{S<`Vrrwb#f;$!FAp({nm*O!iA?J~vCuBwmHACNUxm1{ofj^#9v_yvulMSG0 z(dE*=(%;Y*F+&c8PE{|xl&Bjgm$uyW^QAzIlY@p2fAiwS)L69JR}UXvc)0-;2ADnq zLbR*IWP-;jAD{3utxkG-uN~Wm^4~6Ud&j8`QGVTY5wB}BX(Ut&zB+5WdQ z7sePIY@fO~dN+Qa_~rV*Fr>@(?)hG8(=;v1uZ@d~3&c4@uN!TGR=ZyuUgc60M8?{? z6&G%?v}AVaRzyTSu-etwzu70Pi~`9ZCm0F{n8P_6BkQy!r%%s~rrO*V*Kyfo3pB*g z{Dc&mG@dF_0V|&c%a?~`txRA0Xb&X8ndUupg{gz!?pT__K}F_6bJ;#PegprvySdWLThdYJ^(2_V|J%m}i9o#HH8p+*@sa^#gsUI!0ydIHQ_ zeVai|1Z(l_37ZzrNmsYb{zxvp=x{3{yedJp4%qi(#4nGChzOzk-OY?no z+xWYrU4Wz)D?mohWy^PJ`E(lGtfKMHAg7E22Pp$u#9bKieLHs7w=r&-Sr3@cn#TjV zw#0Z~|A}mvI)sjwBcw25#42NBF?$D@|7x5Zo%XR~kIs&#TO*s##@Z}{K+Tm>g zw~I28e*8vlLh1f)!GNz-%2Pa=F@HB^TOLddFXrR! z@CyqyU03>E9ak~%LIZR=BLr+~2lEuX_?0WaZQ1fvXZepRV7eR2j~FbAoHHkjtrG9U zESab4%7g;>G4ibjT^(^>3l%hLO@T^?lUz{hII%hK)lpDS$}1GL%yRHuu<4`RVM>J6 z8kBpN@S44Ffz{WJY{o>R;Cw5yhAs!WCtTuDA0J}s<&ACZAEl>Pl57X!YXM%%X}GHL z%D>k(iUKM@F?Wg3n0A&=*HK31Tzg-f(7|;8mgt-&08fbNlGX1Uug~62#IvutjdM29 zh}@BU|GolX8?$(*e3|HmCn6{fq%73cZQ0YS_#PcH-lTKp%_H8%I#oW+$nc4Xt1LZU zC+0);x$XHtu%zVaI&h#CLxJ@BWRXR-g&JWv0Fpuh#+P<~e&vbNN##{$tdIwYq80?2 z(A10!vahMG7G@tjTddkFEk{M)NC$7i92~sGCHn$%!$YWom?yq`xdsS;PDOIin>`{2QVsPR%pMEgF{8iOFqZ^+^J7TrBe>mH*s9S+^&e;U zm=g@Kr>vqPeKjryp2$AD8#4*Q#(n8hTTCuEkj&|rMV|1{T(WFg)V6%gG=v=q5?+1+ zkp1)p&nthdQNb*MyvnUD`n@_ZqI90|_8s=X9f#$bq;Dc??)FKSdVE+}V4K=!f7-N* z0ayHG7Qfjx_wl5;Gv8UgDH(H1S=+$s;oi*y(@th>wte<#Sz53Bn_a_3Xw2_6^2DX| zWyb<7G?Gfaiff`{D+6D+cXrb*DXz=V%4muSZix75d3vu~>2~89;Z10`3h(9(yZ7vY z>8y%bK}`|!{B3r2Gf+J93Q2i!8BK@i=^MUAA`Y23dp1k>_`cpTqw7tt)GR`e;x~D# z8FDvn6YeZ1pupS(hT4BtlvL+vQ%1ofu{0jUg3!l~a_0D--nihAHT;G_$j-!kvP^oL zkHnbZ#8OqZgSvR+HXH=yCw{O2o<^lM)FTVH56C1<+UgVU7&Q7}?Dg;W>zt{yE=SU? zcd0L*l&iwp)hb6dHAT-De^BEmEG-QTJd~Wpnu3!iZR$3*{QVpoFUcObZaa@#$B(2W zphT2jwvAa%WZb+tkk!2&uU+iz?eWS{)jS-1{wNh7RRiLZjiIVf=_Bcl*`cEj00)v* zRo79v?D`e33IabTujorIAQXct)Eo8hlgb0Z31Q6{h+rJ3BKTUR={zNGMgltQ)mm?nSvPVK{=^eo)Nh;I&)}K!F-wA$~s;M0h2N)X=RgqZGZSJW>ny}zDmQd z@GfYFF+l{=#8dv`KGmN%RfzPG>@6rByB0vx}}^Kd#N8!xRqi_wZn`XeMiEL z+3wf5^RU=7n`+j|4PAj~eOhThe;h9bh@nQc~1#l5c8wTQI!L zF=}P7N$R1=D5XH38$#zs)bx(ghfL$d3~}q3vZHDH59v^2Pt~I>N{`SBvTKd3)?F8? z;_ZxyeDeQ$?zTmXQYH3SHD|JuXgtdj!1@@&d-9}Bm)1YZ(-zql|7<{KtmnS>lRvzez;42y|FmlRk26|}7JVlFryn?N*54z?{NY~@H@dvo z%P}OTqtW5@r5?R@Z6r7w<>$~@!+SKdgqjz@p@TY0^C2eU#KEh0{p!`Y-By!UlbdAI zva^#5DqY?$7TlPAFfc8DoT{J~;}b0YX0)_(-|;gv=thv}oqE2pf8W02c5^g&%11jR z#@P`1mNcw;ei0?>iWPTe--K}aVkr3%92A6Je#6-oik>M2v=#fF{Kb)#`?7NB(&E&3 zonjQO$nYA5jjB^gefu_{ppv$Zg!Xy-7yB(yuoIEHxZ(FD_= z?$x7PIHEV0;*i95djdNFvO>c*47 z0{UB9TF#RxDk*WD-k?6I3$=}Y>5cLm1n&+jn*k&U#Owxw~+`obeK)v5jj*=2J&yp zeKjrGIu@5G{ycMzhicXy&LiNOC!J!O?(iP%c`)r1F*zXM@ON(#7!(7Tlu%U6wDfb(F=uG#n~;a)>n3Du?%F+Kkd4>5birPy99J6rDhU zkPC6I@;-e!?d#iBmvTdcrWtP~jlc>PhJyuKm%d}>-;M^GkCpC4$2)5D=o6hCjT;C8 z6zbCI@Yp%M(Gi2_9`ZbbeI?9W1K@s>>orI-^P%fZVqEW?J2$od2IT~`K~8AN6rV(Y zvges~fa@N72oQ~!?po|RoQcsXh3Kypm!LPO4ej=i`}_V)wJvScK1!$nfMdH$FxAsB zTf6U$S`-!+PT8ZOTa1E`JT=a8p;sN zMwsyy#UVUS8l9T5vdL&7F(}X*EH=QxhEbY38#TbJ153d+V6?w)hOUh8Pxf87 zd+%Nj0+LTD;5BamRQSJWROpMbYacSp3R*tB1H<=Bs8MtqGwP&ys+;!5vt}w05MdJ4nmCKlX}SZ5U8p1>JJ7`O>hBIlG=4@*RJb< zCv;LIbLar>Ud!KcewbY!1IPR4)kgr(NGa-TYZ+x;542TPA_lMc6~qce{dE0Y{|hYb z!7P{S2VM){&ZqGXI+RktD7)|Tjqq|*mTAhHB%Ng2@8-Dyzp_S8rJ`Vc#jDkQ!$#vWgh_I?KXczp( zF(d&NZ{MX0%!r!edOjWJlRpKVE?`1hZb3bQf&&kXS$&7M8$tt>We(m=e97YO7aT?UXEW;&dUvdSNd25kCVGJO1j?L7dqy6y9f`$&6=-ta{Q zZeQF7Z@rh$L+j&@l$2N*ZlOE8etlH5mKn2wGnA0M(CZDvNPtn-LaR75fpc;S0n6z0 zkB(Ve?R{KtFej7Ia#V$jmMk$ukWGtX;Y6J0BVk4X?xsnf%cV=-hF>8i#~ihfl#$)` z<*^H$^)`nO9%O}#j~-JYLrC^^&iz8Y)=Rz=*i7anefjbQunfQKyLlef-s=q`%~Rxx znq(WU-n?mp3Xf=`^~~38FzNuJ$E*%wS;^P0W4!gSBka?^|GWHS|myHsn)Z_v_WCkDescvt4(1Z;Q2hdVhet zQNgn`1Pi?xO6cGc6B4}XRI(yL(+jtf*uJ!6Pbx5}avgkdierG?{ zCXnF5-NbB&Pa;z>mpqioH1ZRElMNk|$7uukgVdjhyP6^HD%S!7n*_tFFX<)%zC|7H zp5i@Z(64_dyQt*IXs>{&3h3;Eu3x`!VDpCc>jfZ1=+uqpYvaGpX2w|hG&T~|?&_kw zCWw9FlKS_1QeSX#3`2G9a zw`sGRNc_T!ylyvXxL4eP?_`#uz=ZjyZ=XKM1P(vSMaGNsQ1GhISrKQ!fIlUw0*`8_ ztzb$irz$Q{-r*{@7xs;H?J`Ou7P)2?H5tQ2MzCdLhdSkmd%jr_kYUdYqppV7FmNNwK1%OJ1qD;)uW!WXjceS2)c-(--=hoCx#j* zJ4fM`PbI=>t{yh1=);Gba7?HFqV7}&RpF!3d=isV%t8up<^Y)KU}PClfN|b&Y`D2&;oJYhriq`eb)m2HCG( zL4_U2ZdJZ#@!xN&MPY7M_UsDSe=>`zG!F3y(Izg+7aT)#+&Ccxya~iub_+%cHtRD5=luPlWW?F?0*dpt-Qyxt z_F_Kpb!%k!9S?3A*S{5^hml`}UoanUYj5wnnj_0r!goPu@|Q!i4iU%r|Ws zsiLC8G!6qTa?uP`LY(%Xq9K%&F7fC$73WYEoiRFS4sOJXvBh4`NIAZH+z4lQ5!l(- z=;`ZQZ{EBi#DL*%5DdHGv}{u^082i~9AjhuCuST*IzMhDe33hU4PR0Nn1IU?_ql^u zOHF~JFXKdK!JGrl2XMHvSbzA=P&XcbH7Ijo$rf2&1z~=XCbHK12W{J8hg^2_In!i8W-{DTsWw?BUSZ`4hjve6+GH(o?Ew zR|ZhCY`4Bv6nN*3J+o42wmDa*KPbGS>fVVjp|O1v)eAR>xCdT3)YInPdy*a9j|-Y0 z5dLDf6#xV%X7}pT!%+BvP0`BxEwu1c zvo>*e*M4qFDHYC=du8PtHOq;^QZf*pM<8{+2g`Wl6aaM2=nByf(X?zaH%9_=`N9QN zta8TqWPUvHns3#8=zIkGoP&BcaV=bVqb8K`TI3jfYHWHI;zKxcji6oem$!Vc9snSqUNg)Z;R3Bc3^PpE8y({IbS&(z+5B!ii7_#5vZocmMvHVet zY*{)%DMEcZ`{8Lo@#Xjr(9T!Qd#b6S0oKAZ5S3{jrY_y~p>_zqcaN>yJD+c?2`Zp# z=jw1c>>T2o)plr4*GPT!?%nCPDc-4BSL@l;UcB=`4fFHI``B_8PW*m(hv_q$u0B<$Ph1~DhqcnuZZ(Q)JpH)$9 z?}r2a!)u_=IZ269v{wOsqO{qtFX<#^22Sa@IU8+M! z0-bhM(B_iJvb`>zKmUu)&neKd-Zk3m2iLi3?|rmZ?2=`46pqb}Qk{`B^Jn;qGR`(f zhPL8WMut3&Ibad*v$Ge9*35~sb@~PX7Y>iS-@>ba zOk4_r34W3kT83}TsYQic;N?rS(NQSNJT$`ClS$d!dGDiK8whUV5gDLrVaM4_-a~2% zcp%ULt-`)tyB@W0z}0e`w)R;$zz{&Fy2(eQ)&_Q7VY`!tvuRN3e*RnKl<&iw}uk{gq5+-71A8jVk{uU$8I%$T5C zw<@?QK+<^UHddyPMSi#tS#93Tip#dqGnBl`>RbuzSa-!XeX-__4IcbBB_%j2%1@Tn zuSEp~xCu=`YBJICwX7~hSA+OXfLlajg6CeMnt}3H{Zi^e`W616G7`cMH1)Ki(&lOE z?2Seti_1@QpaX^NGF{z=EgZh^NURr(uy=4^*61<&dq#~)KgyVvhKqjfsLx81$T_OcMKOxZGGGqFQ5)gy(MuEUv4^Xaj>) zG%dUoun{)~wwx1)^wi`~$jt0TGha(H2rWiZ!<~uuM;}CUL2*j0ZvrGiL`jL~*#Qi) z8`OBt91FHz;fG*ncF9f!DC~`kckl$FCCc0v067dlKFHrjGst9R_kJiak4hx5I9^k@ zQaS>CP`F|j9TpLB`d7FH7#}kfoXlf6cai1_5b)ohuHA``PV6{EW>apb9u zxpWnCwJsR9eEUW!7&-bsp=B0F$!PrLQJzNtNzv^h;f-hUDnV#M47&-?Z6cT#vwtjr zFCXhP#e^{&bb8RJSPU4hULCnPbJC|0F{R#68e6mF%ulpS>)7(V$~uWhGh2I9j`csG zH<)k@c_kp6>Bo*7VWW=?NsRxKacgDl>W~S~a&~mIdUtyS`2-n~>`(A;5`T@!q3!Gb z-U{EMY@tiI>QM~(a@-q6`%7x24TDCJVv++IXDD@Du%_K^T`&;dBn>FHI6YK^esyX+ z<DjQv6#Bq($NhX#4xFpX^n$m2C+ym(<_Z+~fD z6!#r$44@wC%j8qzJ`$D?{6>LA(vY-MWPBUM3%nhLyb~~}&>Rm24!j;51KG`tw{6>B+wM)M!#J4ruX8iYD72|tWOZ@%K)-;xu7vHKa&q*)TZ%4GRNQ)Nh1-Lm zI-*OocGcAyDg02O0Mt@d93@#{e;I1<~hAxFg2qfR%r+)bOak>nl z^1F!w1q|AB7LZeq5NXsVP2x^#s;g6fQZ8UJZ+p+EXtNfg8J-Gf=W}VPge#wnc zEr3hkErZFx;IJ3TmY9y(4RJ(Nv~}yaz&h$~qF8W$%fAbj9S)}(U0zG*m08|w1sKeM zk8P@6y=~jAvuEWL^I)}+84mG;Yo&foU&G83Fdz&&bs0BELtPy)C;O6j%aW(wT2(XY z0SeMi5z5E&2(VK_LjzK5p$x=b1jP4V@X3=a7A!b)^yre(c#aVa10WIh2k-!*EC+Wz z;v>x&rUTbM)N91(@#8Bf%tePXxZ6G?cMzofB1YFMD=G+9T67O+fX7-qpvj}$L9@s# zj}mL=c{K{M1F$HQ{WCDottf2>4^3#MEEtlE-ff@^Esyta30*IyEInmqr^;{%&nG<4 zhB$hO<1|Hvr);kSED7#2U;z2=*%S{dFN$?l)lkmbrDo20&D$NsVz7PoN_5pl#UrB# z+bht{*jOD!2GTA<3&Y2-nE<9+I7S)cj8aq$v^K>g);(khtz^7HW}RE$Y!lc0gR@Zi*J+*R+UfjU*wsgmrVs9hQVtXZ zr#jR>E)*^s8LL*ref_PJL#*axAT)5@Z zms0A}CZR4uYAKo(R7;~_GA^Z00gHe*oZbPXHv7d$IWLO%2?$1Y|CpgvM41&7Bu847 zJec1UY`J6Cu2u``IO6FTj4EAnKt5P?A10hzB79)76&@SlfPmH^CZ?HBC&bU^&p-HB zP91UVSoiL%Zg@HX5A}Zqo6_6eF&g7Ql?6RS!)X{|_N4gT>s=fZt#iLv_vvQ=Kj%m{{2esN9MaF>dhV84Z=6#tdDF3XxT#i%?5YdZf~D<+nXzUOafS# z&ca02L0DQcO+#)QBEX$EZp6ZcUx|pcTHjL|fY0eurx3Z|$n(PTVlfOS2OZ0xQdK$^ zVP>A}4{b)N7YI40Z%S243$I0xumu%Feu(mpiXE~t$#cZWkuhP{M8AmzX-54#EfK_DOR`jS`Qj~qFKIdHvtcx~n-h45RZVjdyvVjlD z=t=XZGuC8MhE)a+q|?Wz)_~HO9)~st7gk7fs!#ynp?eaNmf%YChVMj?!UmnvtVp&P zF|M!D>i{S%_9eax6m#m=xU{aa{f%$Jp@g{BYKXWTc;P~&*P)*s+39(y6t;R zw-VDe9|Q_Sg-=5X4HSLp7yc{IILN){5mJk?m>}JTP!rT)4k2nr1&g6m?J{{1)RgTM z`J=o~J{fi_o4=!}vIm~fg7V+bo#_IGwgH-tTj(~6#E1984Io3=3P523Blz9i@Oy!Q zqbZIj6>X=Qp}^*rf_QN&X$rBMq$dmwtt{U7W=mGheI<-79z{4o`jd8y!+azCvVQtU4V%}ag%xb$R^t1J41{$1eS-Jt=`}5}&qwy`jeC^sMMCD1wRCwVa+ng)Hb?3duP<@6v1|R6yp@XfB4d#We z*xXW?6jf}R1=E6N2`CAuBj?3LN@n=O`HU8!Xa|A_y?K+6CXgHg_GKt9L?H+l}h)t;dozFApYHU1^glU?Z zjnGh6GF_FqB1RR3)%w1JNU;hpc;Smh8yb3jgim588JYN`q#iP@ftp;V?*_*s}m+o>ZZ$i9xkt=jkdLZ;z8KCz|-mb|!F z$EA9{axbJ-V;>-)m?B3(ik@r#meq6qle|i6Bt#p{C5fEw-0sX`T|J6TIA|I+NSy2! zz$zwDu60M9vg|$f%u??HqdjMgi%&5%uz!CS>KR=qfVI`sF8584{z0%KO%u~;`T(vv-ygVi$r37QX8z;{4487?AF0WJ zWB*_zwWE#zx5yzWE$UVzJvz0j7x)Y0 z3zV~O1%0r;rb9PfPWunjnnoyew(oS;9o#K}AoA8~(t#(2cdUeiknJl_@766Jke#^r zz+#)$ueZZy!5IuZg@%I43G07szvk~1U$^<&;k42UhL``g}EBfYM8_oSJaiO zR@KqPAz10A>&~KD(gg(<*Mo}pD~?Adgqd1bVJJ@NkkeePc773_d4ClYtTZuMC{qsp zfQKVHwlGcs;FeLO_;s7L?cRHILZB6>BoHJoRqj=D*#Y?ok%50G?#LQ%vA+Rz_mG|g z>Tsv$wN3uO*q@v>59g)=(IN_Iia1@}Ift|^|7IO>?`V5>r#wXD=?C%%bqWKp1 z(R#Qv)*um0?AAiT;W|%6Lm3AL-@x3n;aQx&pvy>!*fKC+48}tbE<(HK5o8VcHWwBZ z0oyY)Ahau0M``u_ALU|3fg!jsVyFC}0Oi3@LQsryNZ>({{vol61}Ni8NxV@&BoKXL z+#+#wAvrMZT=;l?k%<+Gq8cSr3#82W@t+?DcB`a>6c)FMFAP>sP(TH&qvOH4IRs$9 z0MsXt(_%h{3ARppbLOm~vZQlGnKN_P?;Ej!89bOG*qJcwdF18GWsnX`q!YwDI@HZ!gDwYWGjZ`P1*b9nAp z)`<@H1~xGy4W&yQPqhn%qW6h%1~_jh75_`a^ok;mTggL zKP!!z0g&}#W%s`1@do$|4>}&|DvD)}LU&zH-SfOjY${M(P_J49Fd=5Vkjt4^;xfG3 zzFJr91^vXJF8m(E3A9*%IVsUA?hHqsze20WpPeU@`tqfik>qqpyh#mwVVZf4wI*t4 z48yq$0sZ04DC=CTcP9Wr;6uT}v9psl_fuR?lZru&F%mi;m(Wnv1$mTso8R2zwai<- zd^@Wg=*!l@?$D!Fm*(ipB*e!X-2Tm*IRXTNsL03xGK$O_o4S2lZe-*K6^&WxcV^}S z{fkfH#RS3ob6Vc*AvN(l_sC*cMxEG$t3wS=dx1cGo*Lt3N1ksygVjBQ;u$&St+4h+ zs>W0xBF+=u-XU1Yf9KSCDI3tPt|#}R*&vf3ZG{tMUtF7Ce{J8oB?PeUA5#@r?xN(0 z=ACbY-k4lYFBnNd5*e9EkVFlelY<^il9)eN|NLfaYX>_!OjWML#(Kcx!E2#h01H~U zu(Kj;^pMGu9jWR#IVvjF*md5xF+Uc!O8_Tq@-t`-v$C}KEGg%a1+f~HS{!!FgJB7# zKY|ktHkAB&IsI+;z1=pT;yE@k0joX5~ z9zNaw4Mx%X{|uvC{l64OnVSOMz{a=~3OD@m(R5vv!koHII)@h#>@}RT=aKJ97UW%G z?1r&-8IZNBfq`EN3t7yvI>uF9QEb+D^=f&97AjB*SW52Wz$RnY?!-com`hPkDGlR= zxvVzBDTLeSe(J}bR@OBlfdibQz5`PEeX0T@%elE*F|}p5Llo|3r#K;U|9)1mg{nfW zfo1OA75N1PVm*Y$5;PNPW5*WS{)W&VLKB^7G{TNz1Qpy`SW-pLDVUy6gQm=G+7t4V zn{srBw(griW`sl~+UWahFyw}W+6iWcN37*K$5SG$5e({PI*^ujoNE4195ho@f_={vK@% zrS~F8G`)_gt*;lO$M&E9jiY?WQ5a8Nglzs(BCCg|z-|Lqx;Q#Qy!{(V`QM17&}>u2 z+AX$$K_|JOXu$IdC8x!X$VeB8oq6+cOeWLO`waCILqez$z)_UEU2C!&CS+B!?~z95 zy9*2gKWrH2$SCdj=doEi*f9US@Y60TLov+l>q{C%lmcMR*rbvtYuN50DFB~I+swEq zdYH=#oCiX0;WI)ky!SV!OQ1m1;s85;V zcT!rBsB)Vv#NKfqQ`dd!sRpMJX;*ZV{^P(C+PHN?yEPx{w1%aL`9P{wlZOv4q%x%Z zBTPZ8u$r+D351K0CNv=U0^%B6plDzH{097(rKc6>b%0vm%FJvDMb2YH_9^6F)?1>w|#}9+)P&H zLhv>7AR8V3u5s>bes()EC}Cr$kP0CMVvGn7l!yn6jv8(##&f@-joWt5sPkUxhcb3T z)PL&b;UT3(z;p->2^a#0+gnjlEMq-l0z}MU$wWB+Ph&`#t8f3d7!4It*1eAsl9Mm3 ziprRY0WDITgYr7sa|}wcBKl zwB8r8>-?Oen6-SZN$IZ(UfOI#&9AIW3c6%8 zMomFMK~;6Bf^58e(9@a>3TD>aKL00%pbajo3Uy%prloFpyFB`E&IZBPDP2)p)@Jv@lv^ z$mq;HY?x?iv3pjlqVW@|l=UXzS(5W8)(PtP7aXs8(P8&P+8o9e2=KfXit>H3$m(!d zF~?9Q+BRQj?CYO>q4arn%E7^nVo?vu0E<}_I)8G4u3k-e^@>9$W-?mY#BnImC&0h7 zZQHhsjX9=basM$H*4#d?T;^O`O4o=P^*Tdn)!9#s*t*XtyTOWisA-58!hZk0!^t4| zxbUA|oXr|zXaDP*n6li@cBDm%j(z^)$G7-@Ie7M;MJn0H4hHBA{;Y2RlxNG}a+c;f zhg`1ysb`V2z_tmJ{jLLlpSq}72b>gvY|i;yLPXd0yQQyJQ&~d_G_`Fo06y6>t&a7t zh<8fk(q6pSA^+0>y7qvJ{P?4;+LA}PFFqoyO_wId#qB*yt(1Asc9`PeNt0HXn&LkE zfMRDW6NQSzd$_n`&o_n|+~DSOy~dq@R-CCID}0~81JG~)XNtYzm!ZqRMA6XGn(+C4 zTPyKy`TPCn&lfO(|Kdd%y49wlmne#X+0+Ms+#p7UIm~3iq2{;&_{>qB5#Jlbv-9br zF>`J8K8$J3Ia^zmB9pG$LNnIwIgZ z2Qb)8TY~7K^z-NX@YtpW!+WsVk`d|?K0e)bG3{eG4HAXXB4JXit4ARy@rFl&Y$Ut# z6L70ycBH9@J=#;@8Tp5&L7t%PlVIPHqca@JKL?jxNWs`|V;FrFI|@GpMKhipIN}Lu zgcg!#0J&z!F4|db4=3i2Hy!==z1R_}T;~w+jTpnHMh*g>cM?o(J`=uj)Sw4u{E4Mw zsuvxPj%KM#i68qcnK% z`bT>@p@s=AzDibrpeoc|11|%DkaKtIqogDjrEQ?g^W+MPJ1m?5$a;KAYn)mE@c5Fz z7ZmvI6ahYXpDlk!6R-UST6h2cxmX5CQUERpkk}N0Ni|W1L&p*5`}gi$!?+aBBjfe! z@7AIOLDn}2O_Xjt2$@*e`{vDLIteB(Q8irhhZ6gd&cK7IXwrU&RP1>PbU1uCR@^d4 zGv|ym2@?&*?eK6HXJ?E+ykwUc8MzXT7{(*#Q$wH$BwGR8A&ex!h@q({Cvx(303y4; z)&odWIssUaUGqvyQ|7M>aGa9On8iwC;{~fLp!w-~#qzJSO~5RiF7RmQ+nc$eybClp zIW$xVTUhl_S;rVQ_YDr7W8Znfe?wjVcwz={2qN{ajjkScb(DKNQpj^U70AZkOpSnT z(DX5^bnF;F9R)*X!9VbIRC@Lo_5V*B@bJRQK22~UwL zj=9W5+EA_4W8VxyPSB?q3Npmwz!i)&%}D{jmGe?Vv&9X78$Y>%gM~M2JT#2Zqu+yL)FkP5z@pp!?N!!y?R+nka*!s`caarSkXZ7s& zl3_ML6jerEd{(V3$!~WBCRM^1SlyCSoo`$_dl7FqJ)N9B7(MT)v8U)UyS#t$ja~?WEA0wXtuMn zvpGw^#|&1KeEn*_Z5u-=-)d@DfB+Sgmg#&aJRGqFINVEs7*uvtywf6)+oSJAAq zD{u-1RoR=5;RO>Cf<^76A}if^yy-qA`xirB0bmh_3SKZK#IypE3TRfL2~bz}mA!@F zgu(+8@8i!miVZ(OtvhoQB?tV!^~2o;IKRvh%(BZ1-&S*Lol;O8DInkCb5<4w%9 zLGn_#oTLU1$@0+wOwK5ZNoZ;^H|@`A2mfL3Ba54o^pIRZ|JMLm&riTsx1XHcLV>fc zH!-S2S{5H44>g82{~t5{q`If6BzJ*g>a+HUrp~Xc;*8-v+~G8MWMF?6+l?r4{%yJ4 zr*)-zbSm_VEDUBi42t&VTQTZ~%qupmH#iQ*W{@ZQj+&TRWJvWYedUM|Gz=5AGl#39 z!h)yaT9@WIbL}`x2;2(CX>EW4!ObNM4r`_dWKZs+E_cT@>j*D zjGsWnRDJuV(^xhg_=}1`&TCk=ebi5ztJKKg-qZ(WU0I#t#{?0f!v; zARWD3wm-E1RSd{}E-4AH7(_N0szXgA+-c68d%+rVk_ynV47`A#sySmEck0r1ioA3J z!o+do$hcx(a>m?@bng1{!qT+*h*gvx}A;LPO3rx!2S`>}-Q zr8s?$5eCrhj%6RM*v^S(D8GmyY2gBjsDVVU6@-g_xxDntjR6;S$sV22dFJioH&=xPE{R|3XPbTK@So|I z4Gq1mG|tx=Waf6Cdux^aoYig`dWn+{Zaw|m(75gWruY4|vbkxiPE2WBG-_#}VHlNrL1bQ7h6zMM1oAfp8L}-J;Q<~s3x}gH1p!&>y)a8c%f(U{irfjV5K461)NDwzFI zHyGd}To{OE06JY;ophGnK2=`J8K+2RulLsMEk_H(lP}t8diU8$EAdOukRI{T}`R(W8yqQ zW+xR|LC2|&-ho?|@o2V1TKKC9FYAN(XCJ3Sd9=Zp=k$_JMjA=cwkI9^ zgc$Zjk#%ilFta$-WzR=L9Jw$uYWeEg_NRT#m*JTL>|O4l)OH%5{VtD<*cqorrFw(O zd?s)5pZ2%5N()HfF+J>2I%6IV2O&(|GviuE=_qlnNHDUVpN$}NbohHV@Sd(+s#3X} zJO}~DGB;NsJ>Gf{Z7=9N1SG=-u4(OyQZK}94$tZp(^i}CAM-PrpVo;pb}N~5P=q7VqEjsIF7MHQQ8JRBZ4#WT71SBk6d=e zCT^g^giS9CZzYad4Uka+82nwkB*b?IOfCfWLh9x zGdlJet6*NbpHFKLvp}3~Dqe|0wo~~K%$v6r2ZoDrDzbU`<mx4G1|Q>I9*>elG2OlUsAX4V zwY!O83~g$PuTuUfT!-m}I`x|nzunX(W*+rVHAk;`np_)xC1+|mUvb&hCCP0llTkt&qyFLT(^gY~Y02ya9_3Bs8BZqC)B6ZI?OS$P z>Czo+L;8}*c$?=#1q6Ahi#phSh<1n9Y&hS{^YQ;w#n+bNtg>jX@BEl@{$()GP|6kfhtC; zIpWJwi_<9RD6>uNQfI24Y35FGg0HR${lt-)fU_J|{MTtmfQ|T>{J(tHZTS|rMeT53 z|E6@vksxm5(_mPKOUkA55icewTr-{vFEZ)U!aEIddgqBga`JN z@4}f{{YA@q9+^i_d9*q}YK)b56sI-vYs9G2llfvEjUVOll8wS3>w?akvgWPP0{N*; z$?f-jYDqz3_ww%h!Z{`MG= z0?q(Hu*Ypbp~s?$f@fDSV!R%zU?%@5^(n z^{S{`I9NEs7MM&$)Z!4hm)0+}*u#)N{u^q`==Hn=g6F!Iv#7%YuxYK#}MPm=>wf zk=CUQ=bQH$ZMclCOYrV~b@79|=;=OUO!NGEHzmwB{@Oo^#%~EN#*&M3n=(9_R%Um4 zsvlDNk)Mqa`bC%R2iqK!bkVAMfkeaOikV~&6a}1IfqN7sxch5&Ux&?L|3HWiAPz(3 zoosYE5e4W_8dbTl@gt*DLddbui?*7s_+X44-GQ*++ojM4mLEyr)f?mKy%}_qLJdi; zE-wY_p+(Z90g*2nnIWHfRqa8SA-xWKD@^@Jo7cz$M{}vPSp{R5*yiF`ZMMkyB{Gkq zQ(t(2_7Sf0 z3VSp-9g;|c%wp*}q)j=}FLC_^PVlAoDZQs=Ap%tZyhntF5VNDX95Pg%C0a*ceg=;Q zeD|SfRsj!ukc>@^$>WHC?t@um18s@<_}nD0(@uTI2Y~6IpF3Duh(y3^N`)ThMA}%O zgDhBQr^aAKK5Kj7hO67tpHuotMvmKPXR?Zw%E$4qy<;b zsmGuso9oel8=*O~jw~h1IONC9IDGnM1ue%Ut-2&Mg&{@F(glUXHr+DnRQ}#J<%!BJ zbkxPL3Ih&2sn{G0XxvD@Nt615r>$>z6POltK`pl<3yrXwa~n2EPfMORLf*YLw`_b! z)HjLs1HSaI`KN$WCIj~YP6Qf+DEY zyMx*fig}9=W{km21(}_&ZfA}HHyUt@p;2a{`{XEpMRj#2;sBT44als?ojIFE*QS=;6I{ODD*${b zo|+w^xiOa^Qp$!{?V4OpuZ%qCQ`{ zo~&Nr2Pr79x(9Os)PYJFNq)s9FaR0=$vo!(!xbxDlOnchuMC=dVkGlgnGou-t#Mff zAaqIAs(Ej;J2rPuf9<-wV`Gip@a(~;f}*S6m0gD>g;r!sZ~zaRKfEQ@y$NZ)wDzM{ z+i7DlwS*QnLE663)NMP+k+j^)Bk%nup~nZ=00IIXE5$2|>^4odgnMHCx%}l)eg8sl z8whPox2B47+-o%GSvt`+zi|>O8L;4c6<2wiMvl3=nGBoqWS(!uq{ncU3{Sl+%Uo&V zl+RgK2EU2<@{Od%#SI6KA^4j-Xv0et+vkZOZ9Da=N}H$RZ}MR7No94j$A64vMwYapg$ScSE}&-Nv$I2k6#~e&R4*m zNLywnXpWKFw^!VT`FeV%CRn7w!`TkB&Ymk)z3>wGHJ`ZN?p(NOvY>(I(6y-hSiHLS z3bHepmjlnWJ7qg@%8J9VOQG;>XaR1-FF1!pTs4gLqVC(Wp0y_1#Tt_kU-Pq0q|iO% z%27!?{KFNe6Fe(4if@EE*L-c_od{%GW+y&rB(~}N)W%oA?jpJxozEL_Hl7%`nNN~< zd_+1UNLbG`@}{SxMySJfV4gb4I;W7|+9+uY?F(F-I43e)ps~#9gHrP#s4Lvj8(_aV zoY&^KpKs4p^A;+aFK zz{(6`2jkkiDLXT@a*}<+RR!`-JQrt&D&xoXJov;tS?5rYL~}m zA!S{f;SISTJi#$YPf?;GA~FjB?5()yW71x2{KlkHHg$J->?tGzKNCjCF3vq+7V?I; zi%W9%D6Z_c?ulv^RNo z1UL%Zy{ZhFydtA%nRkCrq(yq!G1iTI{>ZGVNm?)Gb?!ul0bTmHZk zY!_1r<2Ju@q=Y+6?wrLp@gJGeP!gJ9WV--#9%e%uqS9z{zXMN59}`h`U}%O~tQO9u zQ4FMpykY*1;CX@>`7ySSI;l;mOj6AqQT=+g^%JuYIDUTT?&wkOv#P#i)==9XmVBVR z;LC<>dIcx2c(N^0D~PW@98$?{rmp4U_w2UCYqyyi)bF>fozbjH;|{*PyLBDB)VdG@ zVh^}?xYgSwFd;^}raCrR@x$1}vXzkEW8|{JpvbTLpO}duWZBl`a(&L4pw=_kRdifiAs~dEwtMpa z=7%j`!$cY=vo~x<**aFHkYxl#(*fcnNj0V8&T~{Dgip=Xqve({5BHVzJq&@$m+nvi zV=yGD){=-K7DsX+lZz7<8bU=^`mUz*y=Rqc3Ha?@0M=aPw!G(7=<74;k$9+$ty$q1qLBF{v5(FQ` z?ZfYFg#}%4r_lv|w!(ss`60Z6?({ZsJkLE9MJ0DfC8F@p+RVjtHr=#GE6VJoDr!4z z5gEGMkh#l(O|<+DTaPYihm*`%h*tU!b(5KVR;T7;Hr`&$Au)vzfMmC2ea*}Zy>Tqe`@&%0&&I>88$y_Qpy zTStDmLpjlNQ50#Q$EX!0Wa&;iqO!pxXxP9`I~9hrzM8tG`|CQ$*#XHN=bf_Na7m)C zheM`9i#aoFlPE=9C(DU4JMkORDSzA@&gSiHi>1j9<9fdMQGz|t z=_)$2zU~(L*5hg;GK-&nJG>VhVZ)Mp8|+Q58{=!KM89|ss;D-utn*`%+1{0}o)i>B z_^X?WR)vop$@ill{V>B}f-t5ZICjl_%4KY#s_42kN*lsN#3W6Lh{O>zm}k#hMYn03@9 zM32O9KeB8f*DCu^LDpivyr}cJGPQokVh%QgBQz(PHj94KMo1i3AL&M{Q1|IO&TIx} z_EF@X>&vc+bbOc2+!AK`>rI`f9?Q{yzexpk57e=qkyOD;( z2E(;bp7V_2v-_b9lTS}9MzYr?=ayUQ%-;C}2UL8$LJYuv`wg5LTsIAf&)Ku?mCx0B zFA`q7LSac;p!zYm+epU=lMiW2vt3H_2ehz_4jpbCIEf9TsOcQY_XuGvUtZ~|k}$`? z-@2gDJ9!I1s5#obI>kFFIa&Mc^#2*h@6YHj6gIaT+7mp29*$VitM#;)d7mN=i2O|o z%FW69ex08$X5>^f)x`7VHw@UdeE}}-UQkX#Qj+km42sRBgLj9KttQ=&$*I$xJ2(uP zd;BgXwO}(L&CB|Q`>|nYTltgT!h)PX1smU`%QgNiY5gimiKi{^l;=$aH@09T+8Msp zVp2+ZD5D3(Hr-G7k)_Q5Fnc)Y2N*d{%b2Z_xRO)|4k(P53V4v$wXHp|Lo|l28df{0g83ek zzAFaymPV`h(prf} z(M6xH)PqY`)$sp!kU!_Uvi8yqgaGep1#>)xyRcS45WmzbR7aveL_yT1cQE-^U)yVPk%kIT`TWcgaq&beofqu>_$lbx2LyCAp3l*Tk{dVS*_(F}a(X+_lZq6r%2 zF|AUiU@3coKf{@SD9AVWIFyH=o1i#QdY2=^q5DQIB4~?*#Y6=K9(#H5m$9QHFtUHU zfl4ok!kmTt(W-85-n#(z~20PWDx2rvLxff#X})92XR`~immy-Y0NgsIJgHs!t|Oj0w` zNV$AoU{AeE5AY?|j!IIb8|&%FKEiN>pC;=W-c#c2()6ZHhyLYPFQ47-p?tSl{~FH< zg~e|mHq?9EGYS2!2njT`z%yC-gifF%lFiC1?Fz$;Kk(`sJ6w3SRMr8NC8|U7v`GmxuIuEOAqE-3P zd1Kn`{6IdCxYt|oC6Fn<=8ez@1Oq4?e6?-#svQhsjVG${o^mT+>H;gwpEC!5=QZ%7 z{M%H@TeKJKXL^Ztu0ES3PI|_{ihfrk9 zoHH%X>JT5Jqm>)WXor9@7$~3Uy5)m~=C(Y&B}>x!n)@xL(&Cs&?Bn$2&C5iAN@^gh zI*csl8S*~v@MF6Az55}HZol)Kcuuy~`i4;yU_)_FeAq$dV9q^hlgm14=Zx6qFu(vt zKk_njw!IRD+diXLui#kEQ;D`Cy@Hh{HQf9oz0gm+?S0kc$sc>P9V6=Io$kK-)|-d} zL`O$(NT);{J6>u{S;Uu8f8vlh{M75lw@x5OJo4>nZMO(*&*iT=L%dlJkVv4Q zrCdT;OQ@@vkz(`R!`6M7bi@zxr)=pWgP#0_7A?HJ^~B$7k@~;-pLIh9AEgMzKP>?n z+MhWh41$hjD#(bYkb)yUGrne3O#qC-ZJ;;Fwn_oOaz255044xU)SramOU7EH18Cw# z79^2WFbQeQaa0yZm{;!=-UN<=%D<{%*|rJ%StV_GHi`pWULaXY>PMoc&APLBwQTDg z*UINtk57te)Gs(*S7%?s?V&VjY_M8OuML#VKU6*RD>^Urn!9)Hydfv_oySYllYdhf znt?|-U|h!Z%q;za63ysTFuC~R0)IU@ylVOMB2uyt_cR-JubVcF{7dJhv}~_V6gg~~ zEP6C1%)V4js&IR)byZwK5DA_9S*`>Z@`_yR2cVW()SydO2~8IxG;-tD3p|^)qY=HG zsvlz{A4{v+Hu7A$4AiJDNc=odJHJtE zRye8b^!d85_8@$qjHImk8d<9SEx(e!RGTVJ{#&1qhboL$S6+S{!cYPQ%u|lNhvX0+ zTZDT``m5*+SDE`WY*|)%Eau7V3dtWf!yC@NYQE5XYYNbhfYujY7gvcte>psIXG%<= zTgLZCbiFVoq6&B>jkm=R!%|MQf{f^{0SthdRBp9A*k6qzdRs(lP3jM!m4AH&o{|E6 zCLeABmT&za2kjyHGi^)^m~;J`{m^$?O3*SPo{IQ+)Yb{`m)*?iWJ1Z4RDltlwhUrH zOuU0(@t+6A)MsJ}Gkvra{FHr;jWpcN<(*Zthv$S%^w=cM80KepEYd%@Y$*r~&u*{A z7|nYC8Stcqr^e>`j61q_`dbUr#kGl*#wo9*w=0lvrKF}b^h*F>HKwXsJD_jt2O>ig zwQA*~K{-D2UK%wHi{j2-vxcrD>f7tp(yGfkf)x9`t(+bpo~FYV+1ALuaUypFP=-+v zFp(gF*k4JR;r_|j{I8k>M1ohS&|;-cr6{T&*(4Jew`ENpASz&(2Lga zE?1x@8^9uAN8(XQrt!mtDY4%@LIxE^_17#HRClmai@*(JTO)LL&GVkE z0hd^yBULZGI15=Qm&6q;;cKk4nfCW_LBVK`_XH@BnbB$TMpa{q`Iwa2(Exxr(Jylx zojb?Uf*MZ1*M;Zz^7HUmF5xMm3KV-~D86zh35tM{g47VzSdo|;eUdC-$l=&`+7ZNF z%;+Vn4)=?65{4_B*HzShrf!#PytDY16W!%9C{g@u z7ZRj7EzNLccIfuNJOpJCv^?9bCM$DGm=52v7cVJ&D$>DmYqegx2KOH3Q0f8OC8}8!QzSL z$blzJ$=g}ev$~RhCwbORaB)CVR7W0Fsk6(g871xygn;_-FOOWn^8ZGJZOdQf(U6&A z0*fh}=#)iKK+Vx~(@}h1nytn;ZN!R#$u0A=_6wAT8hzNvP1(J?RAQ-M|0`t^2L$|` zA0xD;&X%WP?sZ^+?|817l$6*MsbkESb4R=A{)y86(cYQA<(#)~+!!;K5t20$Gfmlx zh>>J0Etm>1C}j&NrNvar-AL9lOr@AM$(~lF&>|#CL?y(Xlt{GQqSEqxy_sje$8$W- zpYZexhjjP(yq9Y^&+9rbgRttdihPV3j_BqzU0T$Sm?5fo#j@Zj}F-ON&-E5B9< zjV8@}O|HPn2l>zNc4~N+##%6Xnc>9-Ak74)A~#?|_YB)M@@5GJ$k%;Wkp^))Q~7AN?+xCzox|A8 zYZXBNrnEVb?q*Rce`%QQ6kbDgQAL}53^cPNXTO2Da+H*C4tUDO+R_ffze_cjt3ir_ z$pI5>A2$FIRe>WA1BL<9f_aUd6Qe1PC{_W?<>VyP>J< z0r22atycS$7O*G;0(Oalebdat3SE9iRU1Ia=`Mh3IZ3pPT3 zdBUfL&)D7$ptI|lqX1l`+ib{P35pvyUQiCQ6YoS%SyasBH!PkZZLj=PQ`ZlM+B5k< zp{dN4f*Xc@N|c%Rw5 zbqWFP1bzrW-0ka7I(0-)&C3AIvssIe@Bcm@=$}I{Z8}5rRl#h~+1s7qN7-!Iv#L zxjOsx|8tS2h6%+!J_4{vB6WN9G9(Nx9IpJ@N@1y2w}-hLyY+Zv{lhyh$IK|B=bGPz zP2!&EHWn@h{+ec;AvjUaG(6*Dei0dZBPc!0z-tEb0Y&kCe*vdkw#}Js6Vv0Th4%Mc zy4-SEA9L{$@LgtF6eb1Is*>N?u({g5m${pML+Y!neJxuucS@_;61-W%enW31;hvSRS`-I}t^^~Zi<(rXBa~lMsO9Y6F0mef> z0V!7jAn&oBpy*t3mSDH0KutMNy9#iW&xZt;EbPwQ-vsl54r=d!Y0L_G-c3_X2<mB%nh|oQ)q&9a9dS@f9=HTV z`*VQnG|1~~_JqKu5wmu&hoOmqpk?kNW!Drf7IiH_b!A~9rp7;Vb+6kanZX>m{o4tu z2qmh}V;DQ28W)JwGdg*nmH1EM=2|m}_&n4RlO+wqR-sml7)8?xU#~H0mZWd%aWo=} zsVfJL5Fv($;&~KO2QmqFUiNxy*tR!kx!R<`oCB6*T1fNNuX}sDk8&;k7sZ!G3`PbS z%bKVft^)v&8LMt#%zEIJMmn^pmJlh$k@5Imp)8oV=$6RDj7q6AthU>s+B^PQ`p^PSTYZ7L zP$^OW93%8szFpp+qu%iD`Zv9|o&K2Hx0hA@CiP`a2L&uOw$)V>dJ$aLTLuy+WcS{T zLu8|Sc-o{_tLG9zkc7O%3Tj+A4#D2`wZ?CQyrP#7cW6dmA$nAd5*J+;l5%In^fJvWSQaWXa~ z0O%u)N#bDQ6)j;UgdM@>dw#r9niU%=8qJ!D=QdSj4(|q5zJx_?a-O=7i$y<*T8IYrJFpSx z>I_ZKG*)4=d&HbHKRndv)%ok3=#@@+lUMf>AYJMd?eP6P?FK+q(n$C0wAm`n|&2PHFi<(R=|6LZ;YE<{w#qAsH|wq zH?`BKBA}IO^pbPlL0-h?Uc+5q>{G+)Y0-9H+FCi~lGG-^#YOZ0QHmA}hh_2S`#rj? zBZ?cosjcqE+4o?n>W39kF-WxWqvXELRQVZ_)vOR%!0Ki3JYzJtp)?xED2^#FYNIVk z$!j4dF-&RoH-`|{3!R#DpDg{~3-Ym+(CasHL!xe9s~F#Ugz88jm)!;RHGkT)Tp@5) zcg5}HE6BKxCL^W9X~yL6k# zw@)u!fJIXFsQX!ZF$RpyuxrflZmde57}v*EK?F=1#cm5{Dvw{4@AEe3<^C}-dtHu% z{95{Nq~-S3%z)GNxs-M~X7&FS{%mYFFF`*yn#{Dnr|p#$e%A50vKQWJHgRN6&-;X5 zhjD|T1yLM8Le5R4>1~uwd>}3fKlAZs$w?>z*0#e)*G%`V@KD|o>ArQ)9${=lUGHGM z1Bwv8HXA~>K4ee84hLqu9Ot1}{L$0h5I;_h-y#zCy0zGGBYW+7FC`2-=W4J0E8<4N zm^Az>(V96>^cH+BBK>il z$c5u53fznh420+7ZaYfHxs$4ykCIjum0@$x4LvNgZ|sOo`*iT^xpw8Lk{9|vA2J$0 zqO;$j)|9Jh-3~nH=Mbp%{pfj;J2^`t*CcuC#!cRIDrTaiZFj?4`HmOzcC4wmXL@Gb z{Fz}bht zLb}NN8*kV;GkI9_Y*PA&o`j>`gEunya=kqJI#l-4^KvGKFSVYenCHJ3X$wef6!$;i zCjm#*^+wREf9vo@i{Kt}Nk`1a9#HGqtC!K>PJSxPG*D4hMF)mqcAnU{N^8rgEOLp> zAo>{L*%C=RU5hu?Ei&`U`whh^8u|4i9jNY8xMtYpT=U1^*kc>EPS$Du!M~`HeM426 z)HfMu{^A==%tLkE9z+3Vb}7TatHJ@H8ij!vt+AH?Ck7TL|=@HGx0l7 zR<_!$-@%5)Y{n}0>$fop40}PS(XU9(DJgA#oj)RecR7S7`WfWH_8o(XNb?b*jJzKZ z6qH+ju3rf5`KC%Tr8qz{et*0^V3A}3y|y!we1YR z7^Hi0XeU*F1ZLCFt`ob1k6|24bD&aS7M-`M!-rqZ%pAdqqILS3|HAR}|8UBkT-#2U zt%IhY%3OW@+9yf#pSDwhVAYd6CoAR=nPZlJ-0l2JB|Zwhkbd^nfOG*vdN|C{O51HT!tO`I2b+@6 zf?YHDI*t7_UR;PSfn{!l<3tBVr5#J4R;nmEN6h&Wfg%Nc=)RBE zuYLb$&_Z7Hg|4wc+HIXT9Q>1#6tgcgsF+sAUwzPBv^%1l~q&VT7n~o)rK;hBIH=8;%#%RF@QeP3V3N5X4edijjzG!VqLnM3m6Qw_Fkq>L_+rMTC^TeS zMepp$kp_3PmyVxCY4M2@bE1k+N$Djgx9@Cv&R0wg6*21I!I!Ad0fkmoQ9;h+_NUHf z175L&LIu5Qu)O?gjX~V{@54k{ABC}ee9TbW@9(1Isyu9%og_6SW!YV413%a+G-PEJ z{>JFS4LNX=FvVDU)~z#w5)4{m+yc9;t*!0p>A7p6k-yIVzcWM%ad!@KSl>9wO?Pk< z*FzMNviOXzVe&d({7$2&qKk=%G;^y=m_YYA8;PzJ`YcSHLW;15+%EG`sQtVMshaHE z!(oh}AM-qD7@*vXLW9Cbj|P1niaREJmHWP>kEUAxMCyE8mIe0q21oazn=AkfaoBS!NoEi?UuvIs-PqnB1!R%$J7EMgL) zU1?ym^S3)Am{&+m@U?nwAbP_7w~-oOxAl+HFEQ|$?d_7CnSJ{AXF`i})M0n>M=vig zQHPGVs&8mWFt4e@k7FSCVIahxTxvoX3iABYX>IKTw5t zTca^3Bs4T>MfA|M3P%>4!pM!n<1sfQwwQr?4B7$NvMjSX%sDa+z9{tEFFDTbS)3+m zyPUZyf8!*SPZmqI;B7HXxT!E(o1};%CZh^$UZ3(ci^$06z%n$}*UOKoIeH;}PP|!= zRig33&LgLMhviLw^zMnC=Az=j+Fb`GoOis}Kp`~C&$M}*JyK1(yuBBsXhhy$#_Up( zaTG!_(A{))evfksx48F!X=e`~o+_xiqqcjD{*~M7CJyS^(BfNA-L0QgDPERh5gSyz ze&JrJ^{3NjVvfjj-Pawn^%{D8-&c+^npEG4W*6p}Y4FGiQRboBaO(%+hgM^qcn&nM zsI_8sPFum8_4*4|Cf+BZfuG;m+UjA5nB)UQ((asoR~q4~R}OZ2qb~92@uE$l{sAw+ zw{vplP3Y>s`$g&glB%Pb8xenrV*>-+ziQjC&$j~q`%XDx10i^)x>%>@@@K4xuag7J zX%NX2@O;fvRAh%LE99~YOOm1T8p^l=wahLY#1 z6v{j^H8oL$jQy_+UY~E$I>td;M|03SW1Yr++xK+lGEUg@SD2WmdR57Lf**g1ufnz2 zKYaOHr(=r$Oeig!t@pReHM str: + return f"{prefix}_{uuid.uuid4()}" + + extra_entries = [] + for day in range(14, 20): + start_date = f"2026-09-{day:02d}" + end_date = f"2026-09-{day + 1:02d}" + + def at(clock: str) -> str: + date = start_date if int(clock[:2]) >= 18 else end_date + return f"{date}T{clock}:00+02:00" + + extra_entries.append( + { + "entry_id": "", + "expected_revision": None, + "night_start_date": start_date, + "night_end_date": end_date, + "created_at": at("18:00"), + "updated_at": at("18:00"), + "sleep_quality": "B", + "wake_quality": "Moy", + "day_form": "TB", + "treatment_and_notes": "Remarque française synthétique.", + "events": [ + { + "event_id": stable_id("sle"), + "type": "bed_time", + "start_at": at("22:30"), + "end_at": None, + }, + { + "event_id": stable_id("sle"), + "type": "sleep", + "start_at": at("23:00"), + "end_at": at("03:00"), + }, + { + "event_id": stable_id("sle"), + "type": "long_awake", + "start_at": at("03:00"), + "end_at": at("03:45"), + }, + { + "event_id": stable_id("sle"), + "type": "sleep", + "start_at": at("03:45"), + "end_at": at("07:00"), + }, + { + "event_id": stable_id("sle"), + "type": "half_sleep", + "start_at": at("07:00"), + "end_at": at("07:10"), + }, + { + "event_id": stable_id("sle"), + "type": "final_get_up", + "start_at": at("07:15"), + "end_at": None, + }, + { + "event_id": stable_id("sle"), + "type": "nap", + "start_at": at("14:00"), + "end_at": at("14:35"), + }, + { + "event_id": stable_id("sle"), + "type": "daytime_sleepiness", + "start_at": at("15:00"), + "end_at": None, + }, + ], + "intakes": [], + } + ) + responses = driver.execute_async_script( + """ + const entries=arguments[0], done=arguments[arguments.length-1]; + (async () => { + const status = await fetch('/api/v1/sync/status'); + const token = status.headers.get('X-Trainlog-CSRF-Token'); + const responses = []; + for (const entry of entries) { + const response = await fetch('/api/v1/sleep-diary', { + method: 'POST', + headers: {'Accept':'application/json','Content-Type':'application/json','X-Trainlog-CSRF-Token':token}, + body: JSON.stringify(entry), + }); + responses.push({status: response.status, body: await response.json()}); + } + done(responses); + })().catch(error => done([{status:0, body:String(error)}])); + """, + extra_entries, + ) + self.assertEqual([200] * 6, [item["status"] for item in responses]) + driver.refresh() + wait.until( + lambda current: len( + current.find_elements( + By.CSS_SELECTOR, "[data-testid^='sleep-agenda-row-']" + ) + ) + == 7 + ) + EVIDENCE.mkdir(parents=True, exist_ok=True) + download_path = EVIDENCE / "trainlog-sleep-diary.pdf" + pdf_path = EVIDENCE / "sleep-diary-fr-7-days.pdf" + raster_prefix = EVIDENCE / "sleep-diary-fr-7-days" + raster_path = EVIDENCE / "sleep-diary-fr-7-days.png" + numbered_download = EVIDENCE / "trainlog-sleep-diary(1).pdf" + for artifact in ( + download_path, + numbered_download, + pdf_path, + raster_path, + ): + if artifact.exists(): + artifact.unlink() + click(driver.find_element(By.XPATH, "//button[normalize-space()='Exporter PDF']")) + wait.until( + lambda current: download_path.is_file() + and download_path.stat().st_size > 0 + ) + download_path.replace(pdf_path) + extracted = root / "sleep-diary-fr-7-days.txt" + subprocess.run( + ["pdftotext", str(pdf_path), str(extracted)], check=True + ) + pdf_text = extracted.read_text(encoding="utf-8") + self.assertIn("QUALITÉ DU", pdf_text) + self.assertIn("LONG RÉVEIL", pdf_text.upper()) + self.assertIn("AVERTISSEMENT : 7 jours non validés", pdf_text) + for forbidden in ( + "WAKE", + "TREATMENT", + "AWAKE", + "sleepiness", + "medication intake", + "nights", + ): + self.assertNotIn(forbidden, pdf_text) + subprocess.run( + [ + "pdftoppm", + "-png", + "-f", + "1", + "-singlefile", + "-r", + "150", + str(pdf_path), + str(raster_prefix), + ], + check=True, + ) + bidi.close() finally: if driver is not None: driver.quit() diff --git a/web/src/report/sleepDiaryPdf.test.ts b/web/src/report/sleepDiaryPdf.test.ts index 49f7ee7..a73125d 100644 --- a/web/src/report/sleepDiaryPdf.test.ts +++ b/web/src/report/sleepDiaryPdf.test.ts @@ -1,36 +1,227 @@ -import { describe, expect, it } from 'vitest' -import { buildSleepDiaryPdf } from './sleepDiaryPdf' -import type { SleepEntry, SleepSnapshot } from '../api/sleepDiary' +import { describe, expect, it } from "vitest"; +import type { SleepEntry, SleepSnapshot } from "../api/sleepDiary"; +import { buildSleepDiaryPdf } from "./sleepDiaryPdf"; -const entry = (index: number): SleepEntry => ({ - publication_status: index === 0 ? 'draft' : 'synchronized', - entry_id: `sl_${index}`, night_start_date: `2026-09-${String(index + 1).padStart(2, '0')}`, - night_end_date: `2026-09-${String(index + 2).padStart(2, '0')}`, created_at: '2026-09-01T18:00:00+02:00', - updated_at: '2026-09-01T18:00:00+02:00', revision_id: `slr_${index}`, sleep_quality: 'B', - wake_quality: 'Moy', day_form: 'TB', treatment_and_notes: 'Synthetic observation', events: [ - { event_id: `sle_${index}`, type: 'sleep', start_at: '2026-09-01T23:30:00+02:00', end_at: '2026-09-02T06:30:00+02:00' }, - ], intakes: [{ intake_id: `mdi_${index}`, medication_id: `med_${index}`, - medication_name: 'Synthetic medication', taken_at: '2026-09-01T22:30:00+02:00', - dose_value: 5, dose_unit: 'mg', note: '', created_at: '2026-09-01T18:00:00+02:00' }], -}) -const snapshot = (count: number): SleepSnapshot => ({ api_version: 1, - entries: Array.from({ length: count }, (_, index) => entry(index)), summary: { nights: count, - long_awake_count: 1, nap_count: 1, sleepiness_count: 1, intake_count: count, sleep_duration_seconds: 25_200, - long_awake_duration_seconds: 1_800, nap_duration_seconds: 1_200, average_bed_minute: 330, - average_get_up_minute: 750 } }) +const day = (value: number) => `2026-09-${String(value).padStart(2, "0")}`; +const timestamp = (date: string, time: string) => `${date}T${time}:00+02:00`; -describe('sleep diary PDF', () => { - it('builds a vector PDF without screen capture', async () => { - const bytes = new Uint8Array(await buildSleepDiaryPdf(snapshot(7), 'fr').arrayBuffer()) - expect(new TextDecoder().decode(bytes.slice(0, 8))).toBe('%PDF-1.4') - expect(new TextDecoder().decode(bytes)).toContain('AGENDA TRAINLOG') - }) +const completeEntry = (index: number): SleepEntry => { + const startDate = day(20 - index); + const endDate = day(21 - index); + const at = (time: string) => + timestamp(Number(time.slice(0, 2)) >= 18 ? startDate : endDate, time); + return { + publication_status: index < 2 ? "draft" : "synchronized", + entry_id: `sl_${index}`, + night_start_date: startDate, + night_end_date: endDate, + created_at: at("18:00"), + updated_at: at("18:00"), + revision_id: `slr_${index}`, + sleep_quality: "B", + wake_quality: "Moy", + day_form: "TB", + treatment_and_notes: "Remarque synthétique complète.", + events: [ + { + event_id: `bed_${index}`, + type: "bed_time", + start_at: at("22:30"), + end_at: null, + }, + { + event_id: `sleep_a_${index}`, + type: "sleep", + start_at: at("23:00"), + end_at: at("03:00"), + }, + { + event_id: `awake_${index}`, + type: "long_awake", + start_at: at("03:00"), + end_at: at("03:45"), + }, + { + event_id: `sleep_b_${index}`, + type: "sleep", + start_at: at("03:45"), + end_at: at("07:00"), + }, + { + event_id: `half_${index}`, + type: "half_sleep", + start_at: at("07:00"), + end_at: at("07:10"), + }, + { + event_id: `night_up_${index}`, + type: "night_get_up", + start_at: at("04:30"), + end_at: null, + }, + { + event_id: `up_${index}`, + type: "final_get_up", + start_at: at("07:15"), + end_at: null, + }, + { + event_id: `nap_${index}`, + type: "nap", + start_at: at("14:00"), + end_at: at("14:35"), + }, + { + event_id: `sleepiness_${index}`, + type: "daytime_sleepiness", + start_at: at("15:00"), + end_at: null, + }, + ], + intakes: [ + ["loxapine", 12.5], + ["diazepam", 5], + ["venlafaxine", 75], + ["venlafaxine", 37.5], + ].map(([name, dose], intakeIndex) => ({ + intake_id: `mdi_${index}_${intakeIndex}`, + medication_id: `med_${index}_${intakeIndex}`, + medication_name: String(name), + taken_at: at("22:30"), + dose_value: Number(dose), + dose_unit: "mg", + note: "", + created_at: at("18:00"), + })), + }; +}; - it('paginates fourteen, twenty-one and thirty days', async () => { +const snapshot = (count: number): SleepSnapshot => ({ + api_version: 1, + entries: Array.from({ length: count }, (_, index) => completeEntry(index)), + summary: { + nights: count, + long_awake_count: count, + nap_count: count, + sleepiness_count: count, + intake_count: count * 4, + sleep_duration_seconds: count * 26_100, + long_awake_duration_seconds: count * 2_700, + nap_duration_seconds: count * 2_100, + average_bed_minute: 270, + average_get_up_minute: 795, + }, +}); + +const textualContent = async (blob: Blob) => { + const source = await blob.text(); + const bytes = source.replace(/\\([0-7]{3})/g, (_, octal: string) => + String.fromCharCode(Number.parseInt(octal, 8)), + ); + return new TextDecoder("windows-1252").decode( + Uint8Array.from(bytes, (character) => character.charCodeAt(0)), + ); +}; + +describe("sleep diary PDF", () => { + it("builds a vector PDF without screen capture", async () => { + const bytes = new Uint8Array( + await buildSleepDiaryPdf(snapshot(7), "fr").arrayBuffer(), + ); + expect(new TextDecoder().decode(bytes.slice(0, 8))).toBe("%PDF-1.4"); + expect( + await textualContent(buildSleepDiaryPdf(snapshot(7), "fr")), + ).toContain("AGENDA TRAINLOG"); + }); + + it("fully localizes the complete French document", async () => { + const content = await textualContent(buildSleepDiaryPdf(snapshot(1), "fr")); + for (const expected of [ + "QUALITÉ DU", + "QUALITÉ DU", + "RÉVEIL", + "FORME DE LA", + "JOURNÉE", + "TRAITEMENT ET", + "REMARQUES", + "SOMMEIL", + "Mise au lit", + "Lever", + "Lever nocturne", + "Somnolence", + "Prise de médicament", + "Sieste", + "Long réveil", + "Demi-sommeil", + "1 nuit", + "Sommeil déclaré : 7 h 15 min", + "AVERTISSEMENT : 1 jour non validé dans cet export.", + "20/09/2026", + "au 21/09/2026", + "loxapine", + "12,5 mg", + "venlafaxine", + "37,5 mg", + ]) + expect(content).toContain(expected); + + for (const forbidden of [ + "SLEEP", + "WAKE", + "DAY", + "TREATMENT", + "AWAKE", + "NAP", + "HALF", + "sleepiness", + "medication intake", + "nights", + ]) + expect(content).not.toContain(forbidden); + }); + + it("draws a proportional 45-minute long-awakening interval between sleep ranges", async () => { + const source = await buildSleepDiaryPdf(snapshot(1), "fr").text(); + const firstSleep = source.indexOf("0.75 g 216.17 509.00 83.33 18.00 re f"); + const longAwakening = source.indexOf( + "0.5 g 299.50 509.00 15.63 18.00 re f", + ); + const secondSleep = source.indexOf("0.75 g 315.13 509.00 67.71 18.00 re f"); + expect(firstSleep).toBeGreaterThan(-1); + expect(longAwakening).toBeGreaterThan(firstSleep); + expect(secondSleep).toBeGreaterThan(longAwakening); + expect( + await textualContent(buildSleepDiaryPdf(snapshot(1), "fr")), + ).not.toContain("AWAKE"); + }); + + it("uses correct French plurals for multiple draft days", async () => { + const content = await textualContent(buildSleepDiaryPdf(snapshot(2), "fr")); + expect(content).toContain("2 nuits"); + expect(content).toContain( + "AVERTISSEMENT : 2 jours non validés dans cet export.", + ); + expect(content).not.toContain("jour(s)"); + expect(content).not.toContain("nuit(s)"); + }); + + it("keeps the English document independently localized", async () => { + const content = await textualContent(buildSleepDiaryPdf(snapshot(1), "en")); + expect(content).toContain("SLEEP QUALITY"); + expect(content).toContain("WAKE QUALITY"); + expect(content).toContain("Long awakening"); + expect(content).toContain("Medication intake"); + expect(content).not.toContain("QUALITÉ"); + expect(content).not.toContain("Long réveil"); + }); + + it("paginates fourteen, twenty-one and thirty days", async () => { for (const count of [14, 21, 30]) { - const text = await buildSleepDiaryPdf(snapshot(count), 'en').text() - expect((text.match(/\/Type \/Page /g) ?? []).length).toBe(Math.ceil(count / 9)) - expect(text).toContain('OBSERVATIONS') + const source = await buildSleepDiaryPdf(snapshot(count), "en").text(); + expect((source.match(/\/Type \/Page /g) ?? []).length).toBe( + Math.ceil(count / 9), + ); + expect(source).toContain("OBSERVATIONS"); } - }) -}) + }); +}); diff --git a/web/src/report/sleepDiaryPdf.ts b/web/src/report/sleepDiaryPdf.ts index b48b2e0..32e1965 100644 --- a/web/src/report/sleepDiaryPdf.ts +++ b/web/src/report/sleepDiaryPdf.ts @@ -1,68 +1,377 @@ -import type { SleepEntry, SleepEventType, SleepSnapshot } from '../api/sleepDiary' +import type { + SleepEntry, + SleepEventType, + SleepSnapshot, +} from "../api/sleepDiary"; +import { formatDose, formatDuration } from "../dashboard/dashboardFormat"; -const ascii = (value: string) => value.normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/[^\x20-\x7e]/g, '?') -const text = (x: number, y: number, size: number, value: string) => `0 g BT /F1 ${size} Tf ${x.toFixed(1)} ${y.toFixed(1)} Td (${ascii(value).replace(/([\\()])/g, '\\$1')}) Tj ET\n` -const minute = (iso: string, night: string) => Math.max(0, Math.min(1440, - (new Date(iso).getTime() - new Date(`${night}T18:00:00`).getTime()) / 60000)) -const labels: Record = { bed_time: 'v', final_get_up: '^', night_get_up: '^', - sleep: 'SLEEP', nap: 'NAP', long_awake: 'AWAKE', half_sleep: 'HALF', daytime_sleepiness: 'S' } +type Language = "fr" | "en"; -function row(stream: string[], entry: SleepEntry, y: number) { - const timelineX = 112; const width = 500 - stream.push(`0.7 G 30 ${y - 40} 782 40 re S\n`) - stream.push(text(33, y - 16, 5, `${entry.night_start_date} > ${entry.night_end_date}`)) - for (let hour = 0; hour <= 24; hour++) { const x = timelineX + hour / 24 * width; stream.push(`0.9 G ${x} ${y - 40} m ${x} ${y} l S\n`) } +const eventLabels: Record> = { + fr: { + bed_time: "Mise au lit", + final_get_up: "Lever", + night_get_up: "Lever nocturne", + sleep: "SOMMEIL", + nap: "SIESTE", + long_awake: "LONG RÉVEIL", + half_sleep: "DEMI-SOMMEIL", + daytime_sleepiness: "Somnolence", + }, + en: { + bed_time: "Bedtime", + final_get_up: "Final get-up", + night_get_up: "Night get-up", + sleep: "SLEEP", + nap: "NAP", + long_awake: "LONG AWAKENING", + half_sleep: "HALF-SLEEP", + daytime_sleepiness: "Sleepiness", + }, +}; + +/* + * WHY: the local vector report uses PDF's built-in Helvetica and must retain + * French accents without embedding a second font asset. + * CONTRACT: user-facing strings are emitted as WinAnsi octal bytes and the + * font dictionary declares the same encoding. + * INVARIANT: content streams stay ASCII, so byte offsets and lengths remain + * deterministic under TextEncoder. + */ +const winAnsi: Record = { + "€": 0x80, + "‚": 0x82, + ƒ: 0x83, + "„": 0x84, + "…": 0x85, + "†": 0x86, + "‡": 0x87, + ˆ: 0x88, + "‰": 0x89, + Š: 0x8a, + "‹": 0x8b, + Œ: 0x8c, + Ž: 0x8e, + "‘": 0x91, + "’": 0x92, + "“": 0x93, + "”": 0x94, + "•": 0x95, + "–": 0x96, + "—": 0x97, + "˜": 0x98, + "™": 0x99, + š: 0x9a, + "›": 0x9b, + œ: 0x9c, + ž: 0x9e, + Ÿ: 0x9f, +}; + +const pdfString = (value: string) => + Array.from(value, (character) => { + const codePoint = character.codePointAt(0) ?? 0x3f; + if (character === "\\" || character === "(" || character === ")") + return `\\${character}`; + if (codePoint >= 0x20 && codePoint <= 0x7e) return character; + const byte = + codePoint >= 0xa0 && codePoint <= 0xff + ? codePoint + : (winAnsi[character] ?? 0x3f); + return `\\${byte.toString(8).padStart(3, "0")}`; + }).join(""); + +const text = (x: number, y: number, size: number, value: string) => + `0 g BT /F1 ${size} Tf ${x.toFixed(1)} ${y.toFixed(1)} Td (${pdfString(value)}) Tj ET\n`; + +const minute = (iso: string, night: string) => + Math.max( + 0, + Math.min( + 1440, + (new Date(iso).getTime() - new Date(`${night}T18:00:00`).getTime()) / + 60000, + ), + ); + +const compactDate = (isoDate: string) => { + const [year, month, day] = isoDate.split("-"); + return `${day}/${month}/${year}`; +}; + +const plural = (count: number, singular: string, pluralForm: string) => + `${count} ${count === 1 ? singular : pluralForm}`; + +const duration = (seconds: number, language: Language) => { + if (language === "fr") + return formatDuration(seconds).replace(/ h 00 min$/, " h"); + const hours = Math.floor(seconds / 3600); + const minutes = Math.floor((seconds % 3600) / 60); + if (hours > 0) + return `${hours} h${minutes > 0 ? ` ${minutes.toString().padStart(2, "0")} min` : ""}`; + return `${minutes} min`; +}; + +const pointMarker = (type: SleepEventType) => { + if (type === "bed_time") return "v"; + if (type === "final_get_up" || type === "night_get_up") return "^"; + return type === "daytime_sleepiness" ? "S" : ""; +}; + +function row( + stream: string[], + entry: SleepEntry, + y: number, + language: Language, +) { + const timelineX = 112; + const width = 500; + stream.push(`0.7 G 30 ${y - 40} 782 40 re S\n`); + stream.push(text(33, y - 13, 5, compactDate(entry.night_start_date))); + stream.push( + text( + 33, + y - 23, + 5, + `${language === "fr" ? "au" : "to"} ${compactDate(entry.night_end_date)}`, + ), + ); + for (let hour = 0; hour <= 24; hour++) { + const x = timelineX + (hour / 24) * width; + stream.push(`0.9 G ${x} ${y - 40} m ${x} ${y} l S\n`); + } entry.events.forEach((event) => { - const x = timelineX + minute(event.start_at, entry.night_start_date) / 1440 * width + const x = + timelineX + + (minute(event.start_at, entry.night_start_date) / 1440) * width; if (event.end_at) { - const eventWidth = Math.max(2, timelineX + minute(event.end_at, entry.night_start_date) / 1440 * width - x) - const shade = event.type === 'sleep' ? 0.75 : event.type === 'half_sleep' ? 0.87 : 0.93 - stream.push(`${shade} g ${x} ${y - 29} ${eventWidth} 18 re f 0 G ${x} ${y - 29} ${eventWidth} 18 re S\n`) - if (eventWidth > 24) stream.push(text(x + 2, y - 23, 5, labels[event.type])) - } else stream.push(text(x, y - 25, 8, labels[event.type])) - }) + // INVARIANT: every interval keeps its canonical absolute start/end on + // the shared 18:00-to-18:00 axis; long awakenings therefore interrupt + // rather than replace or merge the adjacent sleep ranges. + const eventWidth = Math.max( + 2, + timelineX + + (minute(event.end_at, entry.night_start_date) / 1440) * width - + x, + ); + const shade = + event.type === "sleep" + ? 0.75 + : event.type === "long_awake" + ? 0.5 + : event.type === "half_sleep" + ? 0.87 + : 0.93; + stream.push( + `${shade} g ${x.toFixed(2)} ${(y - 29).toFixed(2)} ${eventWidth.toFixed(2)} 18.00 re f 0 G ${x.toFixed(2)} ${(y - 29).toFixed(2)} ${eventWidth.toFixed(2)} 18.00 re S\n`, + ); + if (eventWidth > 24) + stream.push(text(x + 2, y - 23, 5, eventLabels[language][event.type])); + } else { + stream.push(text(x, y - 25, 8, pointMarker(event.type))); + } + }); entry.intakes.forEach((intake) => { - const x = timelineX + minute(intake.taken_at, entry.night_start_date) / 1440 * width - stream.push(text(x, y - 36, 6, 'M')) - }) - stream.push(text(620, y - 16, 7, entry.sleep_quality ?? '-')); stream.push(text(658, y - 16, 7, entry.wake_quality ?? '-')) - const medicationText = entry.intakes.map((intake) => `${intake.taken_at.slice(11, 16)} ${intake.medication_name}${intake.dose_value === null ? '' : ` ${intake.dose_value} ${intake.dose_unit}`}`).join('; ') - const notes = [medicationText, entry.treatment_and_notes].filter(Boolean).join(' | ') - stream.push(text(696, y - 16, 7, entry.day_form ?? '-')); stream.push(text(730, y - 13, 4, notes.slice(0, 32))) - stream.push(text(730, y - 22, 4, notes.slice(32, 64))) + const x = + timelineX + + (minute(intake.taken_at, entry.night_start_date) / 1440) * width; + stream.push(text(x, y - 36, 6, "M")); + }); + stream.push(text(620, y - 16, 7, entry.sleep_quality ?? "-")); + stream.push(text(658, y - 16, 7, entry.wake_quality ?? "-")); + const medicationText = entry.intakes + .map( + (intake) => + `${intake.taken_at.slice(11, 16)} — ${intake.medication_name}${ + intake.dose_value === null + ? "" + : ` — ${formatDose(intake.dose_value)} ${intake.dose_unit ?? ""}` + }`, + ) + .join(" ; "); + const notes = [medicationText, entry.treatment_and_notes] + .filter(Boolean) + .join(" | "); + stream.push(text(696, y - 16, 7, entry.day_form ?? "-")); + stream.push(text(730, y - 7, 4, notes.slice(0, 40))); + stream.push(text(730, y - 16, 4, notes.slice(40, 80))); + stream.push(text(730, y - 25, 4, notes.slice(80, 120))); + stream.push(text(730, y - 34, 4, notes.slice(120, 160))); } -function page(snapshot: SleepSnapshot, entries: SleepEntry[], index: number, count: number, language: 'fr' | 'en') { - const stream = ['0 G 0 g\n', text(30, 565, 14, language === 'fr' ? 'AGENDA TRAINLOG DE VIGILANCE ET DE SOMMEIL' : 'TRAINLOG SLEEP AND ALERTNESS DIARY'), text(740, 565, 7, `${index + 1}/${count}`), text(30, 548, 7, 'DATE')] - for (let hour = 0; hour <= 24; hour++) stream.push(text(112 + hour / 24 * 500, 548, 4, String((18 + hour) % 24))) - stream.push(text(618, 548, 4, 'SLEEP'), text(656, 548, 4, 'WAKE'), text(694, 548, 4, 'DAY'), text(730, 548, 4, 'TREATMENT / NOTES')) - entries.forEach((entry, rowIndex) => row(stream, entry, 538 - rowIndex * 40)) - const y = 520 - entries.length * 40 - stream.push(text(30, y, 9, 'OBSERVATIONS'), text(30, y - 14, 6, `${snapshot.summary.nights} nights; sleep ${Math.round(snapshot.summary.sleep_duration_seconds / 60)} min; long awake ${snapshot.summary.long_awake_count}; naps ${snapshot.summary.nap_count}; sleepiness ${snapshot.summary.sleepiness_count}; intakes ${snapshot.summary.intake_count}`)) - const unvalidated = snapshot.entries.filter((entry) => entry.publication_status === 'draft' || entry.publication_status === 'modified').length - if (unvalidated > 0) stream.push(text(30, y - 24, 6, language === 'fr' - ? `AVERTISSEMENT: ${unvalidated} jour(s) non valide(s) dans cet export.` - : `WARNING: ${unvalidated} unvalidated day(s) in this export.`)) - entries.filter((entry) => entry.treatment_and_notes).slice(0, 3).forEach((entry, noteIndex) => stream.push(text(30, y - 36 - noteIndex * 10, 6, `${entry.night_start_date}: ${entry.treatment_and_notes.slice(0, 110)}`))) - stream.push(text(30, 18, 6, 'Legend: v bedtime; ^ get-up; S sleepiness; M medication intake; SLEEP sleep; NAP nap; AWAKE long awakening; HALF half-sleep.')) - return stream.join('') +function summaryLine(snapshot: SleepSnapshot, language: Language) { + if (language === "fr") + return [ + plural(snapshot.summary.nights, "nuit", "nuits"), + `Sommeil déclaré : ${duration(snapshot.summary.sleep_duration_seconds, language)}`, + `Longs réveils : ${snapshot.summary.long_awake_count}`, + `Siestes : ${snapshot.summary.nap_count}`, + `Somnolences : ${snapshot.summary.sleepiness_count}`, + `Prises de médicaments : ${snapshot.summary.intake_count}`, + ].join(" · "); + return [ + plural(snapshot.summary.nights, "night", "nights"), + `Declared sleep: ${duration(snapshot.summary.sleep_duration_seconds, language)}`, + `Long awakenings: ${snapshot.summary.long_awake_count}`, + `Naps: ${snapshot.summary.nap_count}`, + `Sleepiness: ${snapshot.summary.sleepiness_count}`, + `Medication intakes: ${snapshot.summary.intake_count}`, + ].join(" · "); +} + +function page( + snapshot: SleepSnapshot, + entries: SleepEntry[], + index: number, + count: number, + language: Language, +) { + const stream = [ + "0 G 0 g\n", + text( + 30, + 565, + 14, + language === "fr" + ? "AGENDA TRAINLOG DE VIGILANCE ET DE SOMMEIL" + : "TRAINLOG SLEEP AND ALERTNESS DIARY", + ), + text(740, 565, 7, `${index + 1}/${count}`), + text(30, 548, 7, "DATE"), + ]; + for (let hour = 0; hour <= 24; hour++) + stream.push( + text(112 + (hour / 24) * 500, 548, 4, String((18 + hour) % 24)), + ); + if (language === "fr") { + stream.push(text(616, 552, 4, "QUALITÉ DU")); + stream.push(text(616, 545, 4, "SOMMEIL")); + stream.push(text(654, 552, 4, "QUALITÉ DU")); + stream.push(text(654, 545, 4, "RÉVEIL")); + stream.push(text(692, 552, 4, "FORME DE LA")); + stream.push(text(692, 545, 4, "JOURNÉE")); + stream.push(text(728, 552, 4, "TRAITEMENT ET")); + stream.push(text(728, 545, 4, "REMARQUES")); + } else { + stream.push(text(616, 552, 4, "SLEEP QUALITY")); + stream.push(text(654, 552, 4, "WAKE QUALITY")); + stream.push(text(692, 552, 4, "DAY FORM")); + stream.push(text(728, 552, 4, "TREATMENT / NOTES")); + } + entries.forEach((entry, rowIndex) => + row(stream, entry, 538 - rowIndex * 40, language), + ); + const y = 520 - entries.length * 40; + stream.push(text(30, y, 9, "OBSERVATIONS")); + stream.push(text(30, y - 14, 6, summaryLine(snapshot, language))); + const unvalidated = snapshot.entries.filter( + (entry) => + entry.publication_status === "draft" || + entry.publication_status === "modified", + ).length; + if (unvalidated > 0) + stream.push( + text( + 30, + y - 24, + 6, + language === "fr" + ? `AVERTISSEMENT : ${plural(unvalidated, "jour non validé", "jours non validés")} dans cet export.` + : `WARNING: ${plural(unvalidated, "unvalidated day", "unvalidated days")} in this export.`, + ), + ); + entries + .filter((entry) => entry.treatment_and_notes) + .slice(0, 3) + .forEach((entry, noteIndex) => + stream.push( + text( + 30, + y - 36 - noteIndex * 10, + 6, + `${compactDate(entry.night_start_date)} : ${entry.treatment_and_notes.slice(0, 110)}`, + ), + ), + ); + if (language === "fr") { + stream.push( + text( + 30, + 28, + 6, + "Légende : v Mise au lit ; ^ Lever ; ^ Lever nocturne ; S Somnolence ; M Prise de médicament.", + ), + ); + stream.push( + text( + 30, + 18, + 6, + "Sommeil : plage de sommeil ; Sieste : plage de sieste ; Long réveil : interruption prolongée ; Demi-sommeil : plage de demi-sommeil.", + ), + ); + } else { + stream.push( + text( + 30, + 28, + 6, + "Legend: v Bedtime; ^ Final get-up; ^ Night get-up; S Sleepiness; M Medication intake.", + ), + ); + stream.push( + text( + 30, + 18, + 6, + "Sleep: sleep range; Nap: nap range; Long awakening: prolonged interruption; Half-sleep: half-sleep range.", + ), + ); + } + return stream.join(""); } /** Builds a deterministic local vector document from the Core snapshot, never from screen pixels. */ -export function buildSleepDiaryPdf(snapshot: SleepSnapshot, language: 'fr' | 'en'): Blob { - const groups = Array.from({ length: Math.max(1, Math.ceil(snapshot.entries.length / 9)) }, (_, index) => snapshot.entries.slice(index * 9, (index + 1) * 9)) - const objects = ['<< /Type /Catalog /Pages 2 0 R >>', `<< /Type /Pages /Kids [${groups.map((_, index) => `${4 + index * 2} 0 R`).join(' ')}] /Count ${groups.length} >>`, '<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>'] - groups.forEach((entries, index) => { const content = page(snapshot, entries, index, groups.length, language); objects.push(`<< /Type /Page /Parent 2 0 R /MediaBox [0 0 842 595] /Resources << /Font << /F1 3 0 R >> >> /Contents ${5 + index * 2} 0 R >>`, `<< /Length ${new TextEncoder().encode(content).length} >>\nstream\n${content}endstream`) }) - let output = '%PDF-1.4\n%Trainlog\n'; const offsets: number[] = [] - objects.forEach((object, index) => { offsets.push(new TextEncoder().encode(output).length); output += `${index + 1} 0 obj\n${object}\nendobj\n` }) - const xref = new TextEncoder().encode(output).length - output += `xref\n0 ${objects.length + 1}\n0000000000 65535 f \n${offsets.map((value) => `${String(value).padStart(10, '0')} 00000 n \n`).join('')}trailer\n<< /Size ${objects.length + 1} /Root 1 0 R >>\nstartxref\n${xref}\n%%EOF\n` - return new Blob([new TextEncoder().encode(output)], { type: 'application/pdf' }) +export function buildSleepDiaryPdf( + snapshot: SleepSnapshot, + language: Language, +): Blob { + const groups = Array.from( + { length: Math.max(1, Math.ceil(snapshot.entries.length / 9)) }, + (_, index) => snapshot.entries.slice(index * 9, (index + 1) * 9), + ); + const objects = [ + "<< /Type /Catalog /Pages 2 0 R >>", + `<< /Type /Pages /Kids [${groups.map((_, index) => `${4 + index * 2} 0 R`).join(" ")}] /Count ${groups.length} >>`, + "<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >>", + ]; + groups.forEach((entries, index) => { + const content = page(snapshot, entries, index, groups.length, language); + objects.push( + `<< /Type /Page /Parent 2 0 R /MediaBox [0 0 842 595] /Resources << /Font << /F1 3 0 R >> >> /Contents ${5 + index * 2} 0 R >>`, + `<< /Length ${new TextEncoder().encode(content).length} >>\nstream\n${content}endstream`, + ); + }); + let output = "%PDF-1.4\n%Trainlog\n"; + const offsets: number[] = []; + objects.forEach((object, index) => { + offsets.push(new TextEncoder().encode(output).length); + output += `${index + 1} 0 obj\n${object}\nendobj\n`; + }); + const xref = new TextEncoder().encode(output).length; + output += `xref\n0 ${objects.length + 1}\n0000000000 65535 f \n${offsets.map((value) => `${String(value).padStart(10, "0")} 00000 n \n`).join("")}trailer\n<< /Size ${objects.length + 1} /Root 1 0 R >>\nstartxref\n${xref}\n%%EOF\n`; + return new Blob([new TextEncoder().encode(output)], { + type: "application/pdf", + }); } export function presentSleepDiaryPdf(blob: Blob, download: boolean) { - const url = URL.createObjectURL(blob) - if (download) { const link = document.createElement('a'); link.href = url; link.download = 'trainlog-sleep-diary.pdf'; link.click() } - else window.open(url, '_blank', 'noopener,noreferrer') - window.setTimeout(() => URL.revokeObjectURL(url), 60_000) + const url = URL.createObjectURL(blob); + if (download) { + const link = document.createElement("a"); + link.href = url; + link.download = "trainlog-sleep-diary.pdf"; + link.click(); + } else window.open(url, "_blank", "noopener,noreferrer"); + window.setTimeout(() => URL.revokeObjectURL(url), 60_000); }