From 73f14bf8b76e9a6e3d26da700c946c0eabf615a0 Mon Sep 17 00:00:00 2001 From: rgarcia <72655+rgarcia@users.noreply.github.com> Date: Tue, 26 May 2026 21:12:22 +0000 Subject: [PATCH 1/7] Record replay audio --- images/chromium-headful/Dockerfile | 4 +- images/chromium-headful/start-pulseaudio.sh | 13 -- .../services/kernel-images-api.conf | 2 +- .../supervisor/services/pulseaudio.conf | 4 +- images/chromium-headless/image/Dockerfile | 3 + .../services/kernel-images-api.conf | 2 +- .../image/supervisor/services/pulseaudio.conf | 8 + server/cmd/api/main.go | 2 + server/cmd/chromium-launcher/main.go | 3 +- server/cmd/config/config.go | 7 + server/cmd/config/config_test.go | 16 ++ server/cmd/wrapper/chromium.go | 2 - server/cmd/wrapper/main.go | 24 +-- server/e2e/e2e_recording_audio_test.go | 153 ++++++++++++++++++ server/lib/recorder/ffmeg_test.go | 24 +++ server/lib/recorder/ffmpeg.go | 73 ++++++++- shared/start-pulseaudio.sh | 23 +++ 17 files changed, 331 insertions(+), 32 deletions(-) delete mode 100644 images/chromium-headful/start-pulseaudio.sh create mode 100644 images/chromium-headless/image/supervisor/services/pulseaudio.conf create mode 100644 server/e2e/e2e_recording_audio_test.go create mode 100644 shared/start-pulseaudio.sh diff --git a/images/chromium-headful/Dockerfile b/images/chromium-headful/Dockerfile index 6f1f7409..7bdb780b 100644 --- a/images/chromium-headful/Dockerfile +++ b/images/chromium-headful/Dockerfile @@ -360,8 +360,8 @@ COPY --from=xorg-deps /usr/local/lib/xorg/modules/drivers/dummy_drv.so /usr/lib/ COPY --from=xorg-deps /usr/local/lib/xorg/modules/input/neko_drv.so /usr/lib/xorg/modules/input/neko_drv.so COPY images/chromium-headful/image-chromium/ / -COPY images/chromium-headful/start-pulseaudio.sh /images/chromium-headful/start-pulseaudio.sh -RUN chmod +x /images/chromium-headful/start-pulseaudio.sh +COPY shared/start-pulseaudio.sh /usr/local/bin/start-pulseaudio.sh +RUN chmod +x /usr/local/bin/start-pulseaudio.sh COPY images/chromium-headful/supervisord.conf /etc/supervisor/supervisord.conf COPY images/chromium-headful/supervisor/services/ /etc/supervisor/conf.d/services/ COPY shared/envoy/supervisor-envoy.conf /etc/supervisor/conf.d/services/envoy.conf diff --git a/images/chromium-headful/start-pulseaudio.sh b/images/chromium-headful/start-pulseaudio.sh deleted file mode 100644 index ba5b995b..00000000 --- a/images/chromium-headful/start-pulseaudio.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -set -o pipefail -o errexit -o nounset - -if [[ "$RUN_AS_ROOT" == "true" ]]; then - echo "Not starting PulseAudio daemon when running as root" -else - exec runuser -u kernel -- pulseaudio \ - --start \ - --exit-idle-time=-1 \ - --load="module-null-sink sink_name=DummyOutput" \ - --load="module-null-source source_name=DummyInput" -fi diff --git a/images/chromium-headful/supervisor/services/kernel-images-api.conf b/images/chromium-headful/supervisor/services/kernel-images-api.conf index 064aa538..c9d56107 100644 --- a/images/chromium-headful/supervisor/services/kernel-images-api.conf +++ b/images/chromium-headful/supervisor/services/kernel-images-api.conf @@ -1,5 +1,5 @@ [program:kernel-images-api] -command=/bin/bash -lc 'mkdir -p "${KERNEL_IMAGES_API_OUTPUT_DIR:-/recordings}" && PORT="${KERNEL_IMAGES_API_PORT:-10001}" FRAME_RATE="${KERNEL_IMAGES_API_FRAME_RATE:-10}" DISPLAY_NUM="${KERNEL_IMAGES_API_DISPLAY_NUM:-${DISPLAY_NUM:-1}}" MAX_SIZE_MB="${KERNEL_IMAGES_API_MAX_SIZE_MB:-500}" OUTPUT_DIR="${KERNEL_IMAGES_API_OUTPUT_DIR:-/recordings}" LOG_CDP_MESSAGES="${LOG_CDP_MESSAGES:-false}" S2_BASIN="${S2_BASIN:-}" S2_ACCESS_TOKEN="${S2_ACCESS_TOKEN:-}" S2_STREAM="${S2_STREAM:-}" exec /usr/local/bin/kernel-images-api' +command=/bin/bash -lc 'mkdir -p "${KERNEL_IMAGES_API_OUTPUT_DIR:-/recordings}" && PORT="${KERNEL_IMAGES_API_PORT:-10001}" FRAME_RATE="${KERNEL_IMAGES_API_FRAME_RATE:-10}" DISPLAY_NUM="${KERNEL_IMAGES_API_DISPLAY_NUM:-${DISPLAY_NUM:-1}}" MAX_SIZE_MB="${KERNEL_IMAGES_API_MAX_SIZE_MB:-500}" OUTPUT_DIR="${KERNEL_IMAGES_API_OUTPUT_DIR:-/recordings}" RECORD_AUDIO="${KERNEL_IMAGES_API_RECORD_AUDIO:-${RECORD_AUDIO:-true}}" AUDIO_SOURCE="${KERNEL_IMAGES_API_AUDIO_SOURCE:-${AUDIO_SOURCE:-KernelOutput.monitor}}" PULSE_SERVER="${PULSE_SERVER:-unix:/tmp/pulse/native}" PULSE_SINK="${PULSE_SINK:-KernelOutput}" LOG_CDP_MESSAGES="${LOG_CDP_MESSAGES:-false}" S2_BASIN="${S2_BASIN:-}" S2_ACCESS_TOKEN="${S2_ACCESS_TOKEN:-}" S2_STREAM="${S2_STREAM:-}" exec /usr/local/bin/kernel-images-api' autostart=false autorestart=true startsecs=0 diff --git a/images/chromium-headful/supervisor/services/pulseaudio.conf b/images/chromium-headful/supervisor/services/pulseaudio.conf index b5df4abf..22de4810 100644 --- a/images/chromium-headful/supervisor/services/pulseaudio.conf +++ b/images/chromium-headful/supervisor/services/pulseaudio.conf @@ -1,7 +1,7 @@ [program:pulseaudio] -command=/bin/bash -lc '/images/chromium-headful/start-pulseaudio.sh' +command=/bin/bash -lc '/usr/local/bin/start-pulseaudio.sh' autostart=false -autorestart=false +autorestart=true startsecs=0 exitcodes=0 stdout_logfile=/var/log/supervisord/pulseaudio diff --git a/images/chromium-headless/image/Dockerfile b/images/chromium-headless/image/Dockerfile index 5348c3f2..1cbe7199 100644 --- a/images/chromium-headless/image/Dockerfile +++ b/images/chromium-headless/image/Dockerfile @@ -143,6 +143,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=$CACHEIDPREFIX-ap gpg-agent \ dbus \ dbus-x11 \ + pulseaudio \ xvfb \ x11-utils \ x11-xserver-utils \ @@ -229,6 +230,8 @@ RUN useradd -m -s /bin/bash kernel # supervisor start scripts COPY images/chromium-headless/image/start-xvfb.sh /images/chromium-headless/image/start-xvfb.sh RUN chmod +x /images/chromium-headless/image/start-xvfb.sh +COPY shared/start-pulseaudio.sh /usr/local/bin/start-pulseaudio.sh +RUN chmod +x /usr/local/bin/start-pulseaudio.sh # Container entrypoint wrapper (Go binary, replaces wrapper.sh) COPY --from=server-builder /out/wrapper /wrapper diff --git a/images/chromium-headless/image/supervisor/services/kernel-images-api.conf b/images/chromium-headless/image/supervisor/services/kernel-images-api.conf index 064aa538..c9d56107 100644 --- a/images/chromium-headless/image/supervisor/services/kernel-images-api.conf +++ b/images/chromium-headless/image/supervisor/services/kernel-images-api.conf @@ -1,5 +1,5 @@ [program:kernel-images-api] -command=/bin/bash -lc 'mkdir -p "${KERNEL_IMAGES_API_OUTPUT_DIR:-/recordings}" && PORT="${KERNEL_IMAGES_API_PORT:-10001}" FRAME_RATE="${KERNEL_IMAGES_API_FRAME_RATE:-10}" DISPLAY_NUM="${KERNEL_IMAGES_API_DISPLAY_NUM:-${DISPLAY_NUM:-1}}" MAX_SIZE_MB="${KERNEL_IMAGES_API_MAX_SIZE_MB:-500}" OUTPUT_DIR="${KERNEL_IMAGES_API_OUTPUT_DIR:-/recordings}" LOG_CDP_MESSAGES="${LOG_CDP_MESSAGES:-false}" S2_BASIN="${S2_BASIN:-}" S2_ACCESS_TOKEN="${S2_ACCESS_TOKEN:-}" S2_STREAM="${S2_STREAM:-}" exec /usr/local/bin/kernel-images-api' +command=/bin/bash -lc 'mkdir -p "${KERNEL_IMAGES_API_OUTPUT_DIR:-/recordings}" && PORT="${KERNEL_IMAGES_API_PORT:-10001}" FRAME_RATE="${KERNEL_IMAGES_API_FRAME_RATE:-10}" DISPLAY_NUM="${KERNEL_IMAGES_API_DISPLAY_NUM:-${DISPLAY_NUM:-1}}" MAX_SIZE_MB="${KERNEL_IMAGES_API_MAX_SIZE_MB:-500}" OUTPUT_DIR="${KERNEL_IMAGES_API_OUTPUT_DIR:-/recordings}" RECORD_AUDIO="${KERNEL_IMAGES_API_RECORD_AUDIO:-${RECORD_AUDIO:-true}}" AUDIO_SOURCE="${KERNEL_IMAGES_API_AUDIO_SOURCE:-${AUDIO_SOURCE:-KernelOutput.monitor}}" PULSE_SERVER="${PULSE_SERVER:-unix:/tmp/pulse/native}" PULSE_SINK="${PULSE_SINK:-KernelOutput}" LOG_CDP_MESSAGES="${LOG_CDP_MESSAGES:-false}" S2_BASIN="${S2_BASIN:-}" S2_ACCESS_TOKEN="${S2_ACCESS_TOKEN:-}" S2_STREAM="${S2_STREAM:-}" exec /usr/local/bin/kernel-images-api' autostart=false autorestart=true startsecs=0 diff --git a/images/chromium-headless/image/supervisor/services/pulseaudio.conf b/images/chromium-headless/image/supervisor/services/pulseaudio.conf new file mode 100644 index 00000000..22de4810 --- /dev/null +++ b/images/chromium-headless/image/supervisor/services/pulseaudio.conf @@ -0,0 +1,8 @@ +[program:pulseaudio] +command=/bin/bash -lc '/usr/local/bin/start-pulseaudio.sh' +autostart=false +autorestart=true +startsecs=0 +exitcodes=0 +stdout_logfile=/var/log/supervisord/pulseaudio +redirect_stderr=true diff --git a/server/cmd/api/main.go b/server/cmd/api/main.go index c226e5a7..1e77ef61 100644 --- a/server/cmd/api/main.go +++ b/server/cmd/api/main.go @@ -71,6 +71,8 @@ func main() { FrameRate: &config.FrameRate, MaxSizeInMB: &config.MaxSizeInMB, OutputDir: &config.OutputDir, + RecordAudio: &config.RecordAudio, + AudioSource: &config.AudioSource, } if err := defaultParams.Validate(); err != nil { slogger.Error("invalid default recording parameters", "err", err) diff --git a/server/cmd/chromium-launcher/main.go b/server/cmd/chromium-launcher/main.go index fd0979f8..9f8d1928 100644 --- a/server/cmd/chromium-launcher/main.go +++ b/server/cmd/chromium-launcher/main.go @@ -122,6 +122,8 @@ func main() { "env", "DISPLAY=:1", "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket", + "PULSE_SERVER=" + os.Getenv("PULSE_SERVER"), + "PULSE_SINK=" + os.Getenv("PULSE_SINK"), "XDG_CONFIG_HOME=/home/kernel/.config", "XDG_CACHE_HOME=/home/kernel/.cache", "HOME=/home/kernel", @@ -135,7 +137,6 @@ func main() { } } - // execLookPath helps satisfy syscall.Exec's requirement to pass an absolute path. func execLookPath(file string) (string, error) { if strings.ContainsRune(file, os.PathSeparator) { diff --git a/server/cmd/config/config.go b/server/cmd/config/config.go index c2dddced..58338656 100644 --- a/server/cmd/config/config.go +++ b/server/cmd/config/config.go @@ -18,6 +18,8 @@ type Config struct { DisplayNum int `envconfig:"DISPLAY_NUM" default:"1"` MaxSizeInMB int `envconfig:"MAX_SIZE_MB" default:"500"` OutputDir string `envconfig:"OUTPUT_DIR" default:"."` + RecordAudio bool `envconfig:"RECORD_AUDIO" default:"false"` + AudioSource string `envconfig:"AUDIO_SOURCE" default:"KernelOutput.monitor"` // Absolute or relative path to the ffmpeg binary. If empty the code falls back to "ffmpeg" on $PATH. PathToFFmpeg string `envconfig:"FFMPEG_PATH" default:"ffmpeg"` @@ -55,6 +57,8 @@ func (c *Config) LogValue() slog.Value { slog.Int("display_num", c.DisplayNum), slog.Int("max_size_mb", c.MaxSizeInMB), slog.String("output_dir", c.OutputDir), + slog.Bool("record_audio", c.RecordAudio), + slog.String("audio_source", c.AudioSource), slog.String("ffmpeg_path", c.PathToFFmpeg), slog.Int("devtools_proxy_port", c.DevToolsProxyPort), slog.Bool("log_cdp_messages", c.LogCDPMessages), @@ -100,6 +104,9 @@ func validate(config *Config) error { if config.PathToFFmpeg == "" { return fmt.Errorf("FFMPEG_PATH is required") } + if config.RecordAudio && config.AudioSource == "" { + return fmt.Errorf("AUDIO_SOURCE is required when RECORD_AUDIO is true") + } if config.ChromeDriverUpstreamAddr == "" { return fmt.Errorf("CHROMEDRIVER_UPSTREAM_ADDR is required") } diff --git a/server/cmd/config/config_test.go b/server/cmd/config/config_test.go index d2b50291..ec9313d9 100644 --- a/server/cmd/config/config_test.go +++ b/server/cmd/config/config_test.go @@ -23,6 +23,8 @@ func TestLoad(t *testing.T) { DisplayNum: 1, MaxSizeInMB: 500, OutputDir: ".", + RecordAudio: false, + AudioSource: "KernelOutput.monitor", PathToFFmpeg: "ffmpeg", DevToolsProxyPort: 9222, ScaleToZeroCooldown: time.Second, @@ -39,6 +41,8 @@ func TestLoad(t *testing.T) { "DISPLAY_NUM": "2", "MAX_SIZE_MB": "250", "OUTPUT_DIR": "/tmp", + "RECORD_AUDIO": "true", + "AUDIO_SOURCE": "CustomOutput.monitor", "FFMPEG_PATH": "/usr/local/bin/ffmpeg", "DEVTOOLS_PROXY_PORT": "9876", "SCALE_TO_ZERO_COOLDOWN": "5s", @@ -51,6 +55,8 @@ func TestLoad(t *testing.T) { DisplayNum: 2, MaxSizeInMB: 250, OutputDir: "/tmp", + RecordAudio: true, + AudioSource: "CustomOutput.monitor", PathToFFmpeg: "/usr/local/bin/ffmpeg", DevToolsProxyPort: 9876, ScaleToZeroCooldown: 5 * time.Second, @@ -71,6 +77,8 @@ func TestLoad(t *testing.T) { DisplayNum: 1, MaxSizeInMB: 500, OutputDir: ".", + RecordAudio: false, + AudioSource: "KernelOutput.monitor", PathToFFmpeg: "ffmpeg", DevToolsProxyPort: 7777, ScaleToZeroCooldown: time.Second, @@ -114,6 +122,14 @@ func TestLoad(t *testing.T) { }, wantErr: true, }, + { + name: "missing audio source when recording audio", + env: map[string]string{ + "RECORD_AUDIO": "true", + "AUDIO_SOURCE": "", + }, + wantErr: true, + }, { name: "missing chromedriver upstream addr (set to empty)", env: map[string]string{ diff --git a/server/cmd/wrapper/chromium.go b/server/cmd/wrapper/chromium.go index ccc87e77..511fce60 100644 --- a/server/cmd/wrapper/chromium.go +++ b/server/cmd/wrapper/chromium.go @@ -47,7 +47,6 @@ func applyHeadlessDefaultFlags() { "--hide-crash-restore-bubble", "--hide-scrollbars", "--metrics-recording-only", - "--mute-audio", "--no-default-browser-check", "--no-first-run", "--no-sandbox", @@ -61,4 +60,3 @@ func applyHeadlessDefaultFlags() { }, " ") _ = os.Setenv("CHROMIUM_FLAGS", flags) } - diff --git a/server/cmd/wrapper/main.go b/server/cmd/wrapper/main.go index 5015c496..888a851b 100644 --- a/server/cmd/wrapper/main.go +++ b/server/cmd/wrapper/main.go @@ -27,6 +27,7 @@ const ( dbusSocket = "/run/dbus/system_bus_socket" defaultDisplay = ":1" defaultIntPort = "9223" + pulseSocket = "/tmp/pulse/native" ) type profile int @@ -119,6 +120,15 @@ func main() { // starts so it captures the env for child services (notably chromium, // which would otherwise spam autolaunch errors). _ = os.Setenv("DBUS_SESSION_BUS_ADDRESS", "unix:path="+dbusSocket) + if os.Getenv("PULSE_SERVER") == "" { + _ = os.Setenv("PULSE_SERVER", "unix:"+pulseSocket) + } + if os.Getenv("PULSE_SINK") == "" { + _ = os.Setenv("PULSE_SINK", "KernelOutput") + } + if os.Getenv("AUDIO_SOURCE") == "" { + _ = os.Setenv("AUDIO_SOURCE", "KernelOutput.monitor") + } // Stale X locks from prior runs. _ = os.Remove("/tmp/.X1-lock") @@ -172,11 +182,13 @@ func main() { _ = os.WriteFile(filepath.Join(supervisordLogD, "chromium"), nil, 0o644) browserStart := time.Now() - startAll(xServer, "dbus", "chromedriver", "chromium") + startAll(xServer, "dbus", "chromedriver", "pulseaudio") waitForX(defaultDisplay, 20*time.Second) if prof == profileHeadful { startAll("mutter") } + waitForSocket(pulseSocket, 10*time.Second) + startAll("chromium") waitForSocket(dbusSocket, 10*time.Second) if prof == profileHeadful && webrtc { startAll("neko") @@ -223,12 +235,6 @@ func main() { identityDone.Sub(identityStart).Truncate(time.Millisecond), formatProbeDurations(probeDurations)) - // Cosmetic + non-critical services come up off the hot path. Headless has - // no audio stack. - if prof == profileHeadful { - go startAll("pulseaudio") - } - // Re-enable scale-to-zero now that the hot path is up — unless the caller // asked to keep it disabled via ENABLE_STZ=false/0. if stzManaged { @@ -243,9 +249,9 @@ func main() { // waitAllReady gates on all caller-visible ready signals concurrently: // - cdp : HTTP /json/version on the public CDP port (proves api proxy is -// wired through to chromium's DevTools server) +// wired through to chromium's DevTools server) // - chromedriver : TCP on chromedriver's internal port 9225 (api on 9224 is bound -// when api itself is up, which CDP readiness already implies) +// when api itself is up, which CDP readiness already implies) // - neko : TCP on neko's HTTP port (8080), only when ENABLE_WEBRTC=true // - envoy : TCP on envoy's listener (3128), only when envoy is enabled func waitAllReady(t0 time.Time, webrtc bool) map[string]time.Duration { diff --git a/server/e2e/e2e_recording_audio_test.go b/server/e2e/e2e_recording_audio_test.go new file mode 100644 index 00000000..31a06a67 --- /dev/null +++ b/server/e2e/e2e_recording_audio_test.go @@ -0,0 +1,153 @@ +package e2e + +import ( + "bytes" + "context" + "fmt" + "net" + "net/http" + "net/http/httptest" + "net/url" + "os/exec" + "testing" + "time" + + instanceoapi "github.com/kernel/kernel-images/server/lib/oapi" + "github.com/stretchr/testify/require" +) + +func TestReplayRecordingIncludesAudioTrack(t *testing.T) { + if _, err := exec.LookPath("docker"); err != nil { + t.Skipf("docker not available: %v", err) + } + + audioSite := newAudioTestSite(t) + defer audioSite.Close() + + ctx, cancel := context.WithTimeout(context.Background(), 4*time.Minute) + defer cancel() + + c := NewTestContainer(t, headfulImage) + require.NoError(t, c.Start(ctx, ContainerConfig{ + HostAccess: true, + Env: map[string]string{ + "WIDTH": "1280", + "HEIGHT": "720", + "RECORD_AUDIO": "true", + }, + }), "failed to start container") + defer c.Stop(ctx) + + require.NoError(t, c.WaitReady(ctx), "api not ready") + + client, err := c.APIClient() + require.NoError(t, err, "failed to create API client") + + maxDuration := 20 + maxFileSize := 100 + startResp, err := client.StartRecordingWithResponse(ctx, instanceoapi.StartRecordingJSONRequestBody{ + MaxDurationInSeconds: &maxDuration, + MaxFileSizeInMB: &maxFileSize, + }) + require.NoError(t, err, "POST /recording/start failed") + require.Equal(t, http.StatusCreated, startResp.StatusCode(), "unexpected start status: %s body=%s", startResp.Status(), string(startResp.Body)) + + stopped := false + defer func() { + if !stopped { + force := true + _, _ = client.StopRecordingWithResponse(context.Background(), instanceoapi.StopRecordingJSONRequestBody{ForceStop: &force}) + } + }() + + playwrightCode := fmt.Sprintf(` + await page.goto(%q, { waitUntil: 'load' }); + await page.click('#start'); + await page.waitForFunction(() => window.audioStarted === true); + await page.waitForTimeout(3000); + return await page.title(); + `, audioSite.ContainerURL()) + runResp, err := client.ExecutePlaywrightCodeWithResponse(ctx, instanceoapi.ExecutePlaywrightCodeJSONRequestBody{ + Code: playwrightCode, + }) + require.NoError(t, err, "playwright request failed") + require.Equal(t, http.StatusOK, runResp.StatusCode(), "unexpected playwright status: %s body=%s", runResp.Status(), string(runResp.Body)) + require.NotNil(t, runResp.JSON200, "expected playwright JSON response") + require.True(t, runResp.JSON200.Success, "playwright execution failed: %#v", runResp.JSON200) + + stopResp, err := client.StopRecordingWithResponse(ctx, instanceoapi.StopRecordingJSONRequestBody{}) + stopped = true + require.NoError(t, err, "POST /recording/stop failed") + require.Equal(t, http.StatusOK, stopResp.StatusCode(), "unexpected stop status: %s body=%s", stopResp.Status(), string(stopResp.Body)) + + downloadResp, err := client.DownloadRecordingWithResponse(ctx, nil) + require.NoError(t, err, "GET /recording/download failed") + require.Equal(t, http.StatusOK, downloadResp.StatusCode(), "unexpected download status: %s body=%s", downloadResp.Status(), string(downloadResp.Body)) + require.NotEmpty(t, downloadResp.Body, "downloaded recording is empty") + require.True(t, mp4HasAudioTrack(downloadResp.Body), "downloaded recording does not contain an audio track") +} + +type audioTestSite struct { + *httptest.Server +} + +func newAudioTestSite(t *testing.T) *audioTestSite { + t.Helper() + + ln, err := net.Listen("tcp4", "0.0.0.0:0") + require.NoError(t, err, "failed to listen for audio test site") + + srv := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + _, _ = w.Write([]byte(` + +
6!)n7!DC$=E)Ipi$ z)a*0am!|4RT2RkQAGPY{o;a$bSFxj3z$al5l2(XdY7}T;Jg(A`T z4BtD`2J3H0R+CK_Ay9hdQ#D48(B#udbSY(9#y-uQMd=VfD1^l8;! re4!33sbnpn!S{AR+IYl@of24cTMJE$%URk6tQGo zBYpzYvAphfkv8K|#zG!;EHtNHVLuY~ =TqoOx<-LWz5skPMwB%TUxf=G>%6k-B zNeetfbqSd>yFcFOGi6?eabI!93U8q?g4*f1Y7(}E@&W^GYP7XxfBO5Ph2ISV&QjR7 z5RSim+uQ}&khd-!N2F4#1^bFMF5sahc770gwA-aF+QQH(=gL(`tb3Kah5H#Z|6~z$ zy7IK2O>M@^CC+xA;0bvNYEaqR%$(cwQRAPMkF9Q}Wybj#KR!fVFFL6F>`@U+_=hk* zFnc4sA +TrY;v%vvJPbB%i^0sZfbM z;mh!jtF3>LAH7(AfS!tVN|<1fM6INvx!71G4OCrzi2}FQt%~OB`s9d{6oT312Cdu1 z9&8wSn1MMrf;IDgm9C%)OwPO7`v$6EV5gH!RsBu4kY-6E`!6N#ksN+ThH-NPx@ZY| z`Y36sNqe=xSofH)9fF7Zo%Ecdyp{f8E3BKWSZbDg8|rlQ9CH07_1at0t%XdbBongx z#ZHTGmm8bjfYFn0wDU@AL!O77ZsYxR^{(Jwg|tD3BHxmlRvIjRQ_|f2wlYveMgCaa zzxi-*xJt^zPlmW@);=o~YV6V{%KDY2dCew!Y&lUybaeA0W`fXp9O%3`16@0wxa~7U zv~jQPiU-tl@hbgt)hcd#WL3CA#$@wnM|jUHwXGuU@|XPvyRL70{e$xhHinC%p=Sh@ zI>VC%o*16|crvWQ3(D7*ul~!v@Ldt88v-2R=^%toT+2<4Pw+f*uLDyRgG8qLeCTaK z yx&gNN^G@*grn@)C-j)vMqe(390&XEVX_}gb7QD$r2u^tjjVfw94}<=i-ls zZFLa3 j=gb4@HQoZ?1pj5!{hmgGRn~fDTygv`gaIDB8b`>*Jz0X}A z!&YUSAl6{9b#Nlq8rv9NaNKjoDsV!E#pNon*F#pcVNk?XUfmg`Bv;ymJ%ZWi;Hhil zWIpcu3>5YynHtJWV~N0QsN{R84?#Dmb~6*P>?QU8fux#DxExWugKKxW91y`C%9LsB z&L=Q>G)!{(HI>myDo_x{XPON-vdm>Sp~vzb$g%-_+&R+fMfR6&*t7dVUTOEcY9-W^ zCG!;ZhPS+i^MY)fHeJHviapp6Z6CxN8ra}!MjA!J@D1)AA^mM0ps{~wQZ-|RZY%7F z+o^hd%|ASkLNxyO7(r=7b^u=maZC<*^LF?PGr{%A4-!GjN%Hk=3g=7cWUUAjjjFvD z=u>YyXOfS<)qf&6pTYdVc(=!TncHKvLCS{`s2d4Wc7_*8=D+3fj8+_mQ1F#r!sATU z{Hv>tVX()iha)~!2_N_PvXH8|ud!kV_v8%6w{C~Pu_~Y0HmcxIVIjE`R|ElH(Qg|d z$lKn=fCQ`zf;7NaqdX=b!Fx;&G`8omfD>+k3vFtLudh>Gk@kO16D-55?A7MX_F1|} z=FuS;L^JdsBqn@jloD0Qwy(4a#cm03)Z}@ep9H>jW370;M2N+WS@M^Q8J|;EjhyoP z>iQN_KzZ &VaiGUf%XxnB%RRd;oCb^4k#;QImiJuy8YE&E9K>O>mQfN z86gO9`BZp4pF(6XkTPJV)b%H(3UHBE^x7v`u$+9P;htKJdunO8RZZrkHcxC7Vl*MP z*FAp^93gAxs59j2m-;xNZha5?HtM wj!$1?J! E+MAA)`(zLs3K755nr;Qkq$Kt?BPX(eKG*?H$sjkoF;}9dZ zz{d7 k8D$msiYyb3Y;qn)~s7-GWGW(`3F)@y&=L2i4d!>b{|F~a}kIstpteu|^ zHF{>%$B!kiMPiGVLOqCyS&iQb5#M)h50!+BR$IoiU >!ElHB=9UgJ?A zGGMah5Y=@NCy*7z_QEjzkdSHHIZ{Y+AkdqKl6I(NJ)qxlHKr1cTd4^HAz=SK7?tIx z^lyNW`VLw5Ue! yUAAJsy%O(-&^C&noXKo; zK+=D6@kh~5wWZ_E!s0zAGi?~m6Zd =@u#0qecy5s;}AakC0P#gSaM`j zee8SnB>{gZ(Apb1%fGnLt`hxLK5OaD%)7v<@7gaatmKcloBFcC+5`#}GwaArjGbmy zTkWr&N_|{?v(x#4bvbS87_niMY?au+DWn_yFue<>ITw91kE^IJriJuHwgLP5o0C_b z6B8kSf+l8`#EQ4+11Ool(<;e5Apa7c*u0`CBah;Fp+}T{wuH+WVkGZ~+lrR^lJ>H; zJ(S(h!f@o-1z8K1f^`j4k~N0)Ey@1<<9o*Z!iBb&O|bl)`Gc^u?JbhUZ~&4_{e@Co z4O8jvcMP}>?P((6>0MqsN<1cu`TVR!UVKmTiU+C2y+% TGLUZijPX zJY>qnP0Uy2v5=aQ;jPBJ&p(}MD9eR?kL m_^r`a9-R ztmUzgK8<)~$}M5-_v)UO2lWpb{Yb@nIr3@jO{dQaPI!BB $`Q-7u_O8AqYf?mM@#Rub=h`a8OUPm2~eDvLU2o6H(@~DP7HH zojq-9Y#BfljP&6@C0*kf0{xY*5TplI8<+>ao(7~kzG!k0jXQ@m9;AgV(-nI}`cU{s z*m*?)E?GFCr+!1C8h+dpaDGCN3i$9`S4_!YDp*Q!2i3@#Nv`B3+@No;8nFg{-(VO* zUp?-3VLsSBOFiIm;xsS*Z7G}H?Abt$>>%B _h=tWEDU^yY@*!g`7J=k2D25~` z#w0m)rU9MaU3sWkU3L!J9p2Q0qRDHS;P)@*Rw?fqikn6Dsd 5=rD_=XxGeeg-O^5 z)` Ypoh%a O*2&9H&!Di z%NC^a1d=;4C7q2OH0&tIF+48G90_hWk$j#(ZVPQfJvWqjvHocxj2%p3q&G*R+Ml2S zS+ A6`{Y%u?{7QfAdvc zj;CO|&*v)-B1Svq&qIDHGs3x%KuBwb15v;!fbK^wN|q#bYAm!^3iGx|T4A55wb7%i zo_fic%CFeootRo9Ue(exIYdS{3;Fd~3Hf#|u^1m3i2Jj8TH2dDl9?Yi?>jn?j3w}# z2!JykQ@M;^C~jT0spW_ubV8bwbkzNNVw~N#Y@-Z0=zn@*x)A+YZea7n{^11_bEz+2 zCDEY_GUSIAsg9Z=y*IE`=pDP;3#ztAjhiTwCvz@Y!&MR%z4?V#ET~ddL6rm5Zffv5 zhSxBoA(7opKFuMDF?QG)L)&Lk&dp~`c)=nc=YcBk@uqlz)pm{LP+g+c^2-y%8fLaq zHo mlj=Q>SPWB0 zi^?9E$wp$Pb0bpYVZzaU5i~ur)5jy1o`Lax^(>nlZlOa9HZ&IlkMv+(e69S7$W-T@ zomZhrxP8HFbxKwMCnWWqEZ08qI}) !c$U8rO&kBJERHM6OIUJ4SIfTE~`5d z_FeLE*SybNa;mn6pWswY&Y>u+Gt(2$%+8*2$5dQzui? 3r=;$!43Vzf?aQ4ri(#?Zpz-pBEt2eqg92#solMGhQPJ QqEJ;D@voDy#xVl~|l)pKZxwTj49 zez8xs#mxf=1EBK9&0M!xPP=``S)v%Bk8+L2#boY63MLF$UqgSlI5vA3x{EVDhEp7i z+p<$tyHhqtiPt`QG9LJs;zWo(swH)M9e6hF2-B^|!4gy(d!&oLP#k>R8K$#l *A z(7i${y8Olmd5&qg7zbM1%DNO1Ltv~KMdFMtpp0ve1=3ju1z2Ef>t3u$1y)GeHA+5&&2_X=S!a#T@xS&!w ziWq|=b0MJMqUX)DiKwwCf`k$AX4+itc}`*6F+!$HoxZeBZtGwk6cexV9=|&}uMl-Z z3
qm)Y|6r-2h2?<}=AfqK%(OG+41nt(^Uo nIXAbrS 6cUng!}7dc{Pr zo}hHS;`bNV1o`#2rzb+@LI^*U*X^5z7lyN7_#4Bdcn mK&$LyFc)xSpmjJ1{$$)Y3j0>j0*XgnrOPe8Ei3ck~wH zc86KUTr}58DP5dwS{sP4TuaEZVy4Ew3{MxDKhD4t>zF47y)MA@2$5L%oBFV31G_Z~ zC$Wg-VTSwbV?AOm))VTEcHvqS$@>RFILwvQ809X1A^)9k7#cq+?`msu*|`=T*m^mx z7qp3T6^bw~i!w{S&>!$SL`Ge!(z(msv@eLNU(FGWpG-O>apfakZGF|u-O}{FV|wqF z2uernmUVl5L9|Am&`E=CG~!axaq}fxHE_Gp*uf)Yj#;wxG(PyfCL9A@n*= zZ<{_3_m}bYO7sWlE2l*cbjQItB;Z{3rtD<-ni~si{*21J?uXWQ*7T9^q|UZg@iuT= zj7AA=S7}JUfA<{bMNGm+?2Fx)+WDHLH$f4F>Elyu=5uTC+V%Hi3HYz32#dQv_vC3C z4!Wh11%v1}sYxjo2-hS1dGirj>-VKnGQUfmmz|Nr2x@IbFvEP r*PsQ`fzLs!1`q=kW z$u8aBtlCubHa2IxVdfIqdGNIi4BC6gy(G_~{!wyY6OnWcJI2#eX%QP39A zY%ivJ0GPga!Jo@=mBm W(#(vr$%PGjICz-liX1$ zybj9#!O#xRRONJvd!) ~ke~J_~ zfVtXa^7o*8|EQ7JSZ~%-wEU^ 4-sWIoXGDNh@`MB#0l%4Go%w z@d%dv9u?IFDr52G<#_L@lgG1A$2)1;*-h~V8>)Vsq_Xj#WMP)y>5ql~>@~|v0m6#{ zsdk`~D4i8UACMMVUzFSZY`5!u=(>06=AZ(aZcfm{CFrDi%7v?rGdHG)n#M4!Op^?{ zb5$w=?SEy!pxKK*M6&AQW};$exPRp=8^g>Z#Sql7a2`rlYZ)O?pJ +~;&u(T1XO#Tk~&hZz3gF{R}DQKB=zL=fY%HOr1lzBw8$_LLIYgW%~PUt(9q zAt}kSWlsOAZCp>l_MtH(zG415tW7g?r0q sMC>LSxAs83b&FLjBZS94(}=g*`gh*`R9iT9yST(^|#R2Tc{CdFI_d|}2mDuOq2 zyGJ!E!FGi`cm*mZyWx_K#}Yn!B;YMVV=Ad BbGx4CJfhPu zJB=K)UtyM~o4>H!#_>i~jR@fr7$@Dl7sN%qLuo)T_lzc4xRgRBQe?C7@1AG9H~l`O zAxkUzFg`mf;OtFTbX3cF`vc+-_KT&}9hPr{3k_ZBJF<0r#O^`>iN2dkKzm~fa(DwQ zy~eQ4{dAM x1F*5lvj!K!hJK91vm0N-f{9z zA`DvC?k6|D8rvj({ OC-i z=pyWu-4iAGI@ct;@5n`x+9I=7DPu6yM(Wg3WQJrTe #l~)c-kQccjW0SN_ezJ~$%Xi5{cSb5;tA_NY9OQ(moOtoS}8~eCLTrtWR^zp z_akyad#TGE&-IUhD+sYrvh8uPpBLA1Ufkc6deWdI;LeWtne3SwNFq_? zcd%wV&wWr}9YfPMd1{1O%7>=`zN;A5bMS^l8ogAS>3@hK47^+VW0}&TaJ`oI2WhJp z)_~;q{B(x%B$fhINnd@r8yBo14v|RXsSDEU#mHt(e;36JZhRk;*2%JEJVJD*w+hYs zB;bP$bAhYY43g&Sy}+HDt`cPBG4P^0DC+nft_Zg5Pl 0&&(FJ6~!vCtnJe|#H;>EbzSg;aQl7{JM) z0z=Ud-11tfl_~vxUf|E>md_1kTDR@<{uY=4$OAQrSFmHlcxpWfeFsJ5rQh*}HQH;5 zF?PaZ%Io#*p|W7^XP7<%B2RLo^tGO-AIP{1wtKnHtFq4?T##MqZM-8#vh2iL@3Zl~ z_E`0^ JproFXr&KXjAl?}09Ma@_hgI;x({X3sTeb@!Y!0LMS1QY{_f6hgvRc}P zMT~0AiiVc#-j?;M{W*T1D~+wGx$fc *~7k~W )DX=>!5t;d+G(!m#P%67hq9c@?R_8xi0vduw8)~wro*dD~XX@6{{!)iqs|Iz6E zpaBW=q(-O_ygpx1W%%0gn)<#t&ZafDbmfFLFH-f)8%m9`7Mf_Wn_Hj;Pcw7lwx0t++pN4AUPx{PPPWNI9_^? +QX@U!peh-%8iW?{Z? z&SO%1v0cZVmE*tv_49MWMeAdh%2g<3)txBIOAi@I3muGS872&J&vn(R=_>~MBXuEW zQPjYDjbt4kN$3$>WVvj*h Mmlav!^vJSwAri*Smsa zQmdyBt(@cH3rxHZ{U{&I{xwT-$lCrM#ve*AqVQUv(Iv);@#Wz<{Z6c^Yx=4}O?tXF zYHy?{2sW|b)uosT?~K2NHSk1QcfCGcxkom466!!HY74zPgR%>z49$>&2C_@E9v^e% zvOa8RxLRcJf>p1-WEbM595=Uuw>7OpDkt|&%b&DTzVG) O1>*!C_mX4d|l)3^RS5yK%Xz)T4;m$du4?IP|v2*+QkEK9xD9 zquLbeE zKh4cyDaNXI2GgRkaFODH{DYbF8v(uz+NDsHwmne7tBWFwsy+$ z`{; jMnT)w-e<{_`G6ruvDFRFMWSu7 z*Q5D}x7TdDo98^)sJM_GzJkAObknzmk@R7+${eWT@EAJl9;sAuV$Sgcm4QnwdRbB6 zYYulnL6V jTy1WgY(c54YV)s#OEw_ z3T= zqgx9t`fvJ_PxIu7LJ&Z8f7Z9Neb>FF`t!Si#4gH$+AlBYPebukW8Vet@P)hXp0pI0 z)CX;RAm5*lomfqT9JE?o*NCNV61F`=r8KIMOn767Cbx2({6SpCE@ql2)b7(hp)_Wu z{t0c+^e~NV 3^KdG`_V?pwzB1*%e*L(B~Vl&97R zCceF|I-36#DeCqY*9%h>66y}F#719io)54Rp1V^`_rhGXbfQr0Ds#54bwbY>PteaH z$7fq?4ia4@dwC4KN@T0UtR~$R$N3Fd$iT2B71^%>e!wMEhRl0uasG2BBFNmulGi~( zm(N~VSf#>N#COQ%6O>IDbqO^Drt)ZB-wk8RZ-OWEx(4G;hQCZec4>MoNTTML;+Z&o zswn$9Oga|(jt}b`eH?oVO}6-Al1gi4F5=fGxKdf$7OCH1*)vf_=dshp$94g&veto_ zL}6O=sCL*IEFard()(ynsbL-uc$t%B2l`dJT!o=T6RI>~mYya7)6V3&1@~wkG^^}q zHj*rNz*KS52=p~(B*8Xe-x0EnVGLq@Pyq~v;dzq$lXmZC!*}5$u!2pD{jr6oP&k}* zoi 17=4_udtvWD1dh z3KdT2h@IzEL qHm_@t^suw$PW1R0W#x; zcsz|HX?tcjvw5yOFj_5NtS-;^3j)(oeo)+V^mn|X^&-pt>UYW4(#ZEpSf6B`J+mUB zP0k-pvatstTy2cVpa>f@*q><^?hdx!t4WSMSFN6k{#LK!%GAH-mV=)mXvj>pMs>~E zaB0 m|;-aX+eJM929RiA#!Hv*KPRs9?r6fCubt86i>>Osv4&Tl@>}j*Y++T43#-e(O zl-J{ aYJeV?PL8=QTYa$a7LP@Cn;m)rQkXLBnxULX!u z<}(~23|g;BveXQo24gHaYJ;}tXCyoqu><(2Th-S^WNx?VpenTrWY=ghpxiNv;pe=^ z3ZK_Q1r8cft_UnxW >kyQOHD3M* zFw-0vHxx w$WGa@#)Z;UrcVZ{+nw zLww-p{s$=G2Dj)NwgT=*I}2nk9RJ5SGlf`R1f4_fO>!Q5X72B~&TMMGipLwd;YMXX zNc1rL$(Bh(bLlJiB~x}5W6~7@N$r9Zt8@s!PbPVwyF8< ;?cy z6BRqUDAHcca96owVc!42fZm~ubo2C|$Xy**k7EfMYE-Ri?P#9^e^WVzXb5sf #1DO%iV!59{x_yB2&3DlUUG%?sF{peMk}Yl9ok{ z@-Nr+WC+U)L$Z?j>nmBv4>mTfZS_#-3|AGZkm_<+S5J<9tD4GM5$9MeCE4SS-+zh^ znZ6uo-^0-pg+ICJ)VBE8Tj3Sy(Y`j =7LvdzBh3Sp-x?5fti$+*D-qW`p4*g8Ne zwU}b)XT&U0jODqz;m7LL)|K(=)!u?iv(2phOl&mz%d%Trw(sZV>sfTcXmf;c`O&y| z(t|x-p?MA>HUwICaGFTfZu$F+g(F)xHvs &-gmD&`0B?iFb8>)4^+?+q|E2F;fSk4IFkljPX@5 z1p)nQBf_I rDs_1gqgEKl1a#5w>6d!gy$rB*fHEfco|PV&K7X7b*iicE^oS z(k&k_L2Or|=KUqS9HC6$!IF{^%S|L4vYf76^Q$0B) &~57>!_KCGj@6Gr?fJP*xlauCw^dWM0m!Ut1?YM#96uP#D78qHz2Qj36PzOv zIfzpgk#ykV7LR7L53TQ=>D?V0kL~HuS6|z3nC#dkAdk+cc$GjB&`={PXYdgt*&x_* z38^KEw%Bi+VFy$)wmId9Mq-Rz&&i9SJe)$s=srcb&m-M?dH-1@?E3{ w3Q_yeMc<>7o3rDm%=lLv6u*~KyKsoe+#=nn9e zp}5$g)KsGHC`!NbmWcxmvjP_ok$G1nm9{mbPMaj$YUIp# Z`_)Z zYslrjdKmC+4XcTnR(O195~n)K@@dg~XrwU{zWSK7EU`1J8cwZ*Ly!|cl}K2XoX@VY zt v5TOc);c>pNmtke7$UQV3;Ix>lfA+PtoiVa?|Hd413L_;9gfouxvt z(MykUWI*c$`TBTb+Ac=dwJL%r_mMUvUwMu&D%&voOPh2!vo^s`29yFVBj(o(%~EUw z)9@u}{VzVhm5K{RJPq7^p>RUeHMIxssta!eB7X1hwZ^KJU4an7zMW=Xy>eh zs?Booss<%yi$4eL!hyb>qAOcql3AcMAy3X$qJypo8d5F3LZr2>A5_`f1YR(~btT43 zKeNJ#EO$?15n`O4+RI4m=E-wa-mNZD z4tSo) JUTrir4@kj U5U}`)ebY(J2HIc-Cv@#AC#oRpBx!1aG9P_TL)SlJE`ej@H~-kp{B&21tUKm zZ2z(0hUKS%J12A%`m94Gd0Bm>IJlulH=UGKD;^+<%qCe~JZ--m9Ur5_bW_T5!y&3^ z8c+~QAHLMXvS#nC9GzuehT5IFdMrYfTgmQb%^Bly?}~Y`Jy^@}H2*<&2iC@M?gxw@ z#S-mrZ|&5@NpqqT%SKDOoE%n4uLygAtnC2Ct^`|)J8b}ZBL>!=7U|Vt<@G2k%2^8x zh7?QGjZ{2&GCpi#io$3)^g^5caERGqO3|`{rR(4?8<6Wf*yRH5Q&`t0XUrap+$gUf zex-@2=?7{@0M=SDGn_$^eOa!^BpIbU#yE<>w9U }#X8uLYur)ALl6&|prkSaLBijspva3d3KN0W#a<8^$gCa8zAEH qRr~^RGqZ5Nxj;=_)KHWjdg!BhEvP za(U}BFa*rc$&-Tv1Eqt*KUIg8Cqms}HB5+iSf){NxDN`uP;r<4@kO_U&gB#TfBuMi za8{B9WkT(kxx= zIu;tGYT(eMv |Lx zmLs;$g6dIxZb)-OqEtsnnX?Or(yhhq^!+w=J#)GK@uejr&44@mK2DG(T0-qxpXfEuG$VM#2l{#d|$m{{1oagUBcY)Dgn$uC&Sb-p u7QP_b?Ye__xsg_c#Gkn@XA3n_{c?NE*2 zx4E(dKp>dD$zJIRMA#!B0!RjLLsuD|lC?+|uPqyXF-ATJCUtOflYSLP-LxI-uYbLT zR0EbZWE7G>p?88R{==CY>idq0#%2-UNX%wZWE#>EsMAVdO0bXvWr346@S*~z+#r_q z6g;WlTiVFuVLvUR_I0IL6WhzIt>u22Wo{iW&m`tDtwH#vcM>pK2N$+Hc@Dxrb#y zb`&V^;o>pNX4o*&6zY(55p>~i^7J!4!T4Ci6q5}0Ms E~@@LaFZ8BEi!DnW7F zQ70+Fp?V^y3Hs$&V$52`lErcIYLg>O;Q-3K{u{36tviOjR)s0F{B8MTv(S64$>&8Y zmlENji6GZip%^^Ko;|8N_2bVRf}J@>=HLZNaFz_>mIVjp%BE%P33WFy!pm3s6yvxP z!9bH!Ro+%9YEi#G?A36WMi~jHXWUn5_&dIN0UobJ-w|h1&qhNldJ9?FEX-Mhe~$au z{qDr2e!41Q89u`cK|slBbPjiM^cp?7IxFNk4hzif^0qS=eni3ad;Pfd-o-MP#@=|M zB3(h~no6tw%|ur^xijXXs&5EOvTwSEB#E+wxWi^RO^xzc$_ivGNkGTxz+nSGuO#Pi zv;&Fzw)d}*b;e6(s+G?s?)7&Y{5u)q;n8PmU_mzhYBJpBceIHm@AJN+^;bAsB7W{g ztxo8#DK38>LnaQFnaN;m>a~u<16!#~R`@X|WKOJ(-Mf~P2g>ikFuS9cLv2qmdP{Jq z=-@|##|dB-(^-xzy{|UXUqY^f0{57TYqt!_Tl9m4iJk-Nuu(I_W|fLBqASZDfr#Ra z9qshN{bNiHVd@Zney^a^c>w*EZl?q@ek|ysyMDj^987K?X*<`088`g}idYSm=o**N zkEW|>Ar%$@$hbnPs 2}6AphSt*eTa65&(#{ FivTA6GFOB-z0Em$&A~b&817h4x@abnrQa;%HB+r%k!H8c%aoX~*q+pbN z*^W@Zu!b~#XL7U{zqtwdqwWF5ecZ{6JJ>!@TRxgH8Xee(@!b$j{z@im%auTeaCweT zYCYMrz1f7lzN0hbT3JQ5dK?zWg`)8(1ta?4#xKiOQPJ!g1+%k^WwrlHMxGn&j)4i1 zSZ&u9tm04ePfRKC&g;%DbcEl*KlA%L4NM)37G T^i^ zm#n@}jB53SBu+Fr9+QK&?jXA8fHzTjj1eERXt$*N1Naq$MJgx2XOORrl!#zoi1lo` zW$Pi%yqd(MAgX@u gcV~S!!VsC&9|4wk!3ylMC?iMV<_k_}AR|u6t&N_@f#at{cI8*} zH39+gv+X`Rt3_f2{d;aoj*=Jh!{vT2?Zn3lSDv}3?oZ&)o*-GzW8I=x?h;#{_QM=2 z&W%2H+Z!;i&+tAd)3$%G-kIW)CfEqn>tGdrtT}8(Dt7{)j6(gSD;!;7I)58rEt5!P zq{Y;9PPKfu;RFp{8crJ<5Zj{xu+3|x(~G^X1jrA!2U1?AUt5yY=j#H>)LVT%31H1l zJBm!&umGK4r8I=Ae k_eS*(Gha=Iw+#&a~{y$@D3f`d_SsyumE# zAu+$uQIxLlhB=Ve>fL1gt9~&@XaiS=5#4vbD*+1%hW1w)5Rt`;eLw 4LI8{JK#z;W$u!W4>? z{)$>r(w}VNI_he3?fC<|XcPA%wCAuE$xW2EhP_&F2e*7CDJJDR6*y(^O9z9`kA7~; z{afsT&GUt5FpiRH+;&oYl&i!TpDU^Re!~nqZ^d`Vi>)FkQ @-`ui5x%#vtV$MvRkv&qs Rhq_78i}-DfjmJxmON_(FZO`PnP3t*4n-MTAV}{65s>o z*F0|oYMB-McH*-&mT=ZR2(oQLc$K?9wpmxGfm&Cg%x97&e~x$Ao|u1F4M5FnY=Xr4 z1~t% f>pR$0wM0zuiaXzob(VQZU-G~gQ gujUOD5iG@p z&Uqcb3&h6eufE)@+gNknn`b*CieW%kyNG22)>m6tB~`f^)NWK5D7MIPdV&&uwC-fE zn;~e)*$5SFn+k4IW(&jO*7(C}!Zf+LN!VXmEo%gB*mc~Jx#kv9N2vvsn_Jgdyb>r+ zsPuj;3km_FztC9s*_6f0+S<)^e@GEW{u(p{m00f~uI@uPpb}68ak;l4xh^y1I9?cv zI-08}q$PCgVr&H=iApxAJ)!nLVj~233#OSq?P2KJ{K@EI^@ L5&$6UFTMBhRZ6GNsw8*@@fX cT5{@lU3rO6Txe!`2aG)@+mH~?Td!4ytT zD~OlD3NBQ$a)^uX2tlEVXx55I!8?x@MLzTdw K4GUZ*EEQb#9# z1K>O<%Nf$=u$TZ3bxMjJ&z$RwNiCtSq6qJW>!g#Sl}6M^m-- dTW9r z`S$vp 9rn53(BQK##@!S{?zpX;@LZP zMydC~ +t;aF$SQ6AogUY z`tI~NQ9b`~rW3{SXiwUh^_+ffBWzQmtBbBNk6=3DoKhy4iVgE@jY|AC7BDqTY71m? z9(=vlhksLyKy&%Xi-S)cl*`-{pniztw?PQ=s3xJ4 g8=Lr(Y3wT3PP+jx8lV@%}FJ+>gkoXhWD;+J2pp>Q1vku=a5q18XBGwmD zyP^4(% 9SNH4fi4|ydj$vcRG_tJ&=vo2x0hVvM@W{?a8IkY#@5Xs;U5^= zq8~8{=IIccZ80;zj&6VGtMQ|UZXCfj(A7_1NY&n}%s;;yLzMdOy7nxQm3-qCaLNkw z22i>QXDLl0vLNe7OqGZ%N#8_eoMoh24joz>(ZNRVwIGgE&R(hE2e8lInv^(9^!QXU zxc3uH#FHDQD~P9`=5JG<9<&0+Z11_NP>Tna!6I8Tk^PMN_E%Y;ndFe;@CAHhIzM&J zDrgRfSA6L~1PP#;? N`LM?J(-=ZulW{vE76T>q`VA1*X=n4H@i0^^JlD%+loa? zv`777fg)_U>Uk{Nc_L1$N}A=IqQ$e$J^_{@#2P!4B;bmtdbCelr=gte5#vn86@<{N z{siMt7rmpDUGk<3ZqiOiDS9;#WB}I# 8~$n>qF)~cBKgY>t`fk#4$p6t|Sh4 zAjET1?(xakd(qgJ6eveI%f$JbmhWtP=f`!{u+T #!eV|7Th3}-D`RV$`_SJVI&QCrI6`<54KZ_e8i zNgy=_pRk|)Fc 2+9wY94F8pcHe(kI$U3md+y>0WD zB=nKP7A1IMexG7a^t{sY*LVGDPsT)FdW|>Hws>90!hwjb z>70Z?i;?AP_&^t+YsjzI@Vz8zbubErT)|CdQ99dTp7yQKn|%wsvtZNy<{n6j1mW)< zb=-vz9PnzzQA_UL)&1&xwyk-wu&;8ym}SaA_d>#0*G9B#86ci$*M4&eRgYRf>vmo@ z`-*7aR2hV!|2(e$>{nGmUxas9Snx;QZE7*VQH~6zkftvej_TDa1fdksZijm5ARX8d z9VGg7eD0GcqKoAyM+l`Dz1`69%UgVK2bo7k-L?Knz4|Qq8PG_Lhg$n3A*{R{?6P#P z+2fqDd=qZKJ5;?c?tud5Uo}J c zC;B&y|2s~U!D=$?r{9b8FiTYMS=XWcD`=Z26uIcsS9JuzIrF%KV_Id7Rj3JEJC&8Y zMwoJM{wpPp<}e3zOA$IkVV}eaf(uWL{`D8U WhosB6&M?@$lPZ-~ zhy1>#CbrKVPqERul - zsV+;YtICCw0hydl%h+1YB0 H1t6zPS_c6ub=!j$xjRy2@ zuHe-0Rvh217OO1)@dtLVxfoR(Eef~NuJj?Y9+o9u|1~l3a!Ql$OT|k>jU4Zi|LBRK z5Q_8cOqR9n4{V}!E`3DAq+8_ced4UrY#!=OFs<%kF_zmWs%Cc>pbvCNgc!#D0br zv?n7f(7F_W5H8Vw|MuG6z$x(uOb96z{;7Lsa5Fvs)89=5#3z>x*kYo@s(#jUv7f2e zTfs_6&MHx?LDYJ)ILu#@XV^Sd>_~65xPxiVW5gFYbaEQcc(cPsx;+bwL&^y4)Li)r z_m-|}GHB}sC4&S*TWkY2#re%Z5@G(g$-d~n3NoCj#Nng6M|KqFr0l)qm(QGzNE1$< zxcce$W(oY;JPXvOTUI-);B|4Qcefp+bO2Wu{>!Ru-OlXd*SI74plGB7FSG0bY4*Dg zOb#XNIoS=qNTN9r2Uu%ZX{2j6MgltKPHruc?BLZNEbHqs {fqI<{~0sU-5g%m=B^o2n~~N6jASKfoo>oxA?{Lj zaQIhvi}MUSI5n~`*Qi=}j8oL%(z<02N0}zmKb9{=+zzl7z2D8LO=ON5+Tu 8! zqWu0Wr@WLl9)zP*PYH@)zt3E4tN?y6e3B-B|E2tJZaoR3+k&fCr_6*E{I1DGZLy+= zbp(8QOX={PQ-kFHpaFY{UZU2-zBt6vjIIt8fVzkw{L6zG5-(#|l%uz(CB)Ba--$b> zA8Mmt2BFd~4mtH<@OHR#m8zIpy&ny8bVf%}LePNG{Ga$Y82I3~l#7#2Oc&A&f_sW0 z8lOz%C&mRYV_1QGHqnd(B$uht=Mc9CvfdHlh7mEkwel?*IchR}O8(D>9So&rhD`LF zk96YK5Sf~)FFrWx3lL3b8t68T8c -4ZMM__)n xx2E@t&(={h_h-5<0g})uWn%0w4HSKa$g`&~`x4;t9TeAATm>4uU(8#2VnsX`e*G zjdl>y(pe1K3BbpQJ{Km>{r; |z*>ygi44XL`)W@ Fa?(hJ1tmjme!wn~6 !Vqn7B#nxquqD*4J(BM4 za7-|u8eUF-b8Z!(Y9}dU_= P^!({bNP9_g2$lBkz1WH8^ru{xwvYdMZ5 z%tgRH^xBP?Xe(+>($Eb@t=6i%YA6@m0|4-lQwE)Df#thqqhkZRZt~TxLJDwN?;S?U zsXwWeziX$2xCcW69Mxp*T;j|8ug5YF6n~6qwYnL#j%jU5i1?0ncid^zZ>Q*MYd<%# zA>$gx`T}h9)ti03Jf`~^y9LAK+B O+2Ca*rKLhT4fYq|^xH!C=`}Gae z@D6nk$Wl;6$GrE(otrvfB5kv!rk5lyfSqWvC~uZd_p{W(v2Sf72+~ML^0e!y!{E0n z3bY`7VIpM)F~IHUm1gRC1a{XnsH6ZzZ_qB;JB2naOyk_s laQ^-?#lUuHmU1n^_gTj5?YUBxPEn+Hfdu8*|=tsiv+&3BxAjyLBsUeiOR7 zmKA@gjQl!q*r>$8KdK_V=3xNL1vIx7Yhu|4@ruiXN
FqNd>et29%v`&>!l&yQFZc341M=u)o3*g_{~R+X^(GxT2uQ z9;jG#o5N(1V9`F^xpd3vI2-6HHG5s!EQa#v1{MTIW_Z8<0%yeczMTIl3YQiCHGRCf z-)Y(mt*GsYc~^6j`c6!Mv%xa6*K?HHq_l_;)VP+boZanar|@v-ouY^DjGvE|R}$lO zDx+-2+3puyi6?jf1!eF>0Oet5t8!OS3eW?qB}H~q-rq>JjV~aP+p}Y`bU3iuVXm!0 zTeyfljREFZsuj58?#mjH=Kb^uwFvQSjae_o*Xy9SE+KbAmhWv8c&} 2Ww)WB-c5T8@P|0gw)wqcDQTJ1Roxxb#Cz0zVMWN_Z5LQn?U^`61ShQ zu#Vu^u}i)-1J9zN-6wy83zvc-x0-Tn!Q12A%V%6+tgb_PcSMRe5xriqMS7^( HBT@&DhKVr^Mw;Jn%wE!mJrt37gjAU`;XFk?47q!Yj1 z+#)49Z<1ROUzWZ_GZZgSWoD0hqss3d2I9145{qDLr{({t@?CldbE z!46(Fu38>b`NoW_yGq@8>1vtECEnY#Veghbm&Gk=6%VqNu@GJV=tY~DM8e}mEcfOc z$9ChoX@XH0uI_);skU3$hTCewd34a}m?dHWU;Q`$C$T^?2Ej+bZkUHpI<2Ynrae4T zkszV3ZQ=*Q_H#)msc%Eg-FA>_3ccmx*-BY7r<--2V2Ac)<{o%B=eKdb_tGxSpm-%> zrE?Q^i8!2fEytJaR65Qa;Q0f*vd5L;G6ifDrof?#8!*pfr$)#Kpl&{VH3SD-!1%l6 znOI_)G<@O>zpvVAjPb0Nk+y6M$1g YtP}$b+DN!G34%Qb&Tc!&0s2ZEzqL%u&@}d5q8WyC%v*sXO?5JYIR5L7!ww#{e4{MW(9X08oe>hWD|;$za48cJ|6z5zdeLTuG9WqaRzvERP$Aj z;n`qIS_+p`=aCWnduS8KFh+wYL+Z__`~`Kh2`859g+AiF`?uRTqp}ocpf(sKAfVbO zgdIz$-Lgk@^QN 4I6J)RhI!VnOH5!Iw#1*pD#AJ$RvR7HMslsN-7{zP zbVs#mO?V-O+ {!Lj8vpZ@P|$3@J$cAK8o3*;IUb-Ixr1~ XWI!;Nu&36bHrU z><^M&zIIw~MAA^lZ<2{X^|A3%dtsL={tsTslAT-t>I(2WUSC(&P7rvyw%e@w1IW3m zxBxCscg7@rF>C8f(Bt8BD|pXFE(8Cl mJwe)$BbQMnsPn=LwwtNk_$j J(z;AIS4t!&2a#=*$k=^3Bs>#)u@fWK>_^93eo`l*u`;I-RgH7f%pi^BP zq}Xi}AD??L1#36B{8A6BW7;dK#{)p+Oxq*OG&-n~NSB(x5#121&kx)DV@^@~1werg zF#92)up$T5Wq{gpqF@aeIuAG*ACB9xl8eZHrF1Hcu84@S2JoUUe1TTJU;jP^f@Lba zSQ9|gt?A=m)B>VS 6G=+Y@N0igqB$=l8rq?{<0+&tu=p2K?ec}h zf|Q~ghQz+8ALfWiX696F&RxUX(qOh_i%3K&VRVjm3 9h_!P2RWhF@ zX**MI0Z)W8sk)H#f1GeG;jH _jWCvscUpM|dMh(N}!{>noj4Iq17RQ<>H&2FJjQanh zN$ca2dwc%@Y8Y$oPmnzb1dJk8P l4oXzD zJg6T!B~-TzViNJf15-0b%9z70lY3DG>#v}oah&k z)H?>UqF`HbPNbg;3lJRf9dYosGt_#V{qOy{#pKU6^EyYEOwfHy2;5kvMCwiEKuTR^ zjthHYE!2h^J>BZ*uaF|wH4y$~+~3@ZDWrv53DIBCMrj+l1k<(ihMKkc*#Mufl%P}h zcV~3ykdf3NY8^A$a2Na9O*T65wAp$l0n>IBV;upBuQ?+gWeym6Z23 `X_DqUzllRgD%uZ!i3li#ug6kh)-#q9 4vwFX{BLtWzN(!%Ci_c9}n-qT>4apC3N9 zIM58K%LKyroqYjZbTdKD)Zgfe5_3PP^QFUSQ&`O?aZmQ@+{K+!to1tIQW?MU#rn%j z35XNNyx)|w_4Vty)c*@3LK0qen+Mij*B=o8M~jO?;;6Q8U+3@!)tpw`ng|;|6lEF{ zydjVsR+QkSy)?Y;q!3$4Kl8J{Qn9q*B3vVxQK>y}KfMqSc5q7E*MX}?aP6@))4^QJ z>6;^*&H#8`?f?435(>})cO90{0<;1>YdO|RnuK7LFA$iY-TI=*?qC1&**p%!18>U5 zkt_tMA^`_3M^Y$_I6Sb<1}n!|xx}B6`>`KNtL)6LVzy6aWhAkx^szO^c?U8C=QW_b z`{fAIkbIw0iQ^Y2Vi-E?5CVQyX`tNJCf@m6#NkyQ##i}wO(z_{ugYUJQjQF{bH3wZ zmZd4ckGKXki=onG2lqi5mch*mUG#uZutW_YJz4<0GMg@|EA6s`ZtDO(;^+LlZ1cQj zefdT%@QBI(I0UvR(e0yq9gFqr6+C_rhs9zn(uTFo!i>WD31^y*`f}DMC|Nl!K+n&( z(a98$dQlhq&r`A5LEj=W4@X2$K1+1SPD}*^Um tUPVd+}2pH`kDLA@4HVpSemcNDQL*WsI}&Yb6O2J&A++yNUR zSSgtn{R(kt2%h|PZc~pt|1utMWzXB7P}m&ibv*btFdkb6Lr+95?ZDH8qMd%EJW2Jt z;yL<~CVVJ~>e<3ChF1?N(CIZ!tj+;3VS5EJT%GjHdVQ4)_4e|Y{W*&}gzeA3M;Mn+ zGW#^p2BQHD87CJ)2uAiWsr2h1JbpA5$I#rC?kQ3Dn2j9M{I~<&nt0}V%SM_ppgaDE z;9Crhs#`1z21{AZ3&v^4Tt0dLIaqBoN?D3Q{ihqJ Zxr>1Bb?p}DYI @ccOZ{g~ z3T(6{?AM^q9H18jkU9#H{e~^;W-U9kF`4wO%CW+_BejJ>sqvDB@gshDm8s#qQ^zR= z!4U%BrV$;7uy~{*l6S3E^K_)*%y`U0hu4$}@J0Q6eS4rG`TBoQuANuLZ8E)y*UY2W zLx*KQO^sEm$X-UFN*eCRkySfe1=HVrBEK=b-L)f!y#5pJSsL9Uh&j>NL2`eX6qnJ6 zm=tv53}Xsb@0~nr@c3%_+~{jxRWoF&E23!Pn@VdOk_!NcAa3>bX7E;?B_0;=w~ohF zQGUM}?z57|GDxCF?_@FC9U@mXW5rj1Px6oRRrr)BK9i&ZngZ9pGD7Yjgxm^X@^@lq zP1Geq9!sQ-YJbUiJGHW9ao_eM%`wvD*|!GRku~ikm|h;a; `RNtpCOzI-c;hzk<$<33T?~UO~x&$oP+m z6$V#8Yo9<>OlTk0!W`U@*tIZjvgm4c|8nrz!+V1BZiq!Ok9;9es!y_{py7geZ>NW$ zrZsWR8G0cV6vM=@LPFyUFfn=bt@nlY>ngJUJT_5SIaL3_6}@y?UUAhd=jKzvh!hc1 z0YYw~+aigk`lFk3&z|>Oi=@GtB2H_{;6eLDFIlMta#_GDN$Bof^Y;pQmtD^{Po0vT z5ca+6QFy>~V(3?#sWY1`E77VpN@k4s7M^SdP_N-WnQl(n3L |Hb1dV(KP{&K;d<+34#~ zO&iv(PLhF47|@mAQ8+T34hVr3Es;F=00jk}ITxj|^bpfc4DmoxB3?V8ZkWo$mL|v- zqfi0R-ss4+s1Xc}SRZnaq&Ca@F(wlX&>1rxWYE5*o0e32clv38&UGtw|JRt`meIYw z>+1bnKC6s^I{tRq?H$-N^T}Cy7{h0jYdIv _C4UYaZ6F}7++-ZW%oO0?mrdW`O`pG`ek+=B(-lr=a(jRTTX#v0@-e=DR(RA( zY@YUnwuoBL-&02wP4)dw62L#(vJYHY)+V52HL*GS#V LEr#ME 8?c1%L;eyeF>k4;@Omq`Y?y?@=j zV(8mAHY#dtCM0OI +i-^&HAFlawlbv3b02TU`- z3wZVDq9SaJ@nFQ9V|VH8S}MB|x#W8@CHZ3|6Qzj_!a+@i`y;lB;R{KlH5)`ZkOFKs z6on{;Hn#z5T+o2smXNtYMJDxKk-be@`jZ(U#$Q(oWB6y`rz@&wwv1f@O61j-D(fG6 zudtm6hf{6m)f*&;82+x8mjP4G_N}fH>wnGz6%#Lzo>st)wA@g`y>f!z8% <#(-W}L)%y}~ HDXU;C}TGCy{>d&>Cpnx3p&9LL@aLhC*GIPyjWt?q{Xp6BtT7&2?7V2rb? zm$UPKr;9=n6*ar5xB-ZM^8zHjP&E+nO);LqvDg>$n+o18E#3K0H%^iPr0U6p^%wqM z4dXZ?E1 zj)ex?V4wMCJsT4q@cAsO;AI#Ky?lgi1A&MK!?D$xuSx`44L5Y$cG_@pgZ_QHkYw _A6JE`*Zk)ih!v&g83jQ?Uy8zq5~qsmq(^yHcS(F(s} zzdS&-$TUFF-$1kNdm{995wtjW4gVfheuo@v<={VBH;dOs>$!dt!;0VtV=J3?$lWX( zW>&)|dtz3^N9@smvZ2y(x6Z8U@#6fSqv7~8OxKT{vpVq=Xx8IDF&_w!wD&^aU;?T^ z2V-+*T93I6;TI7h*s4NU7J7b_K8Xdm4qBMjB2-ZwPJ45X7WU^f^L>1<-}TR 8?gMrspo5z^SjRu$QFq zn3WYN%hf-& -EVPw>+rn3kl%w$}lRwtWep24}BCwU$mj5W=Fcjzk zq|J@SKf(4K?}2rJp1g7~z;F_8)}U&sx#Q&Z4tXF|MUk)5xTj()^1*0aP-d;hpwCO< z0%B`r2FO^9uGj!8Xja2A=oLfuOz3^Fihp%LtaIMOZ#bo6N$74v&13Lzrik%@UT94R zQz&13F3sTGJYEPB~X#&x(kL_53&ptpm*`JI6Z z;gci6F?W|Zl;tWTyWgtv7s(4WqR#Y+Wj-lZ>4=nfGNx!( z7YyLLF@~W=8+D7S?##sCKgK@)?GytxfUk|+qA*%T`1op_;ykwTk~_aL{@-YT)IK%! zIDX%h0&&rZl>y;2Yej@mA7A*Hg`yx)!m(W*Mbm=pxH^!As?WD|t9>~9c-*`H`(n7@ zM5fhS00CWR6ZClYcA^+Gov0no@|toX$m0iv#s(&iBB}EyPW2W(_|N(Hj_EYQ*H6ME zIhA>oJV7-U{QZ&Ip2z4>r-od9;l6x^l85_vZ<_vH>r=dRHgNoQ&Gr<{s8Zoc$2SLg zLEs$RB@A}|1<$)S_uN#*=gZTB*5{|LVzNifJ6gBW->t= <8LT|116+HQEIpnu2 Y zRNJi^wG^)rwXv?-G{bH0W8JFf<`}i5q9&0tWPa3W$&Bnuc)rjw5bDphtaDFf(A$b| z#nT4CL^rhokLH>fY1Ep6fLlSf;$;*7?&zWs4j!3*IgO~W&L_b;(?K-K-K+{7v7QA< zPd&xpN^%z3 AvV+qt zi >p%81rZ?&Q}c^n?v(@#!le=m-*+L;Yl zJ>}mBzB7skYj-|i#OPDtAsS-rk?g5_$KNvy4tW_2@&3zTT?>naz)VH1avVkVGXKiL z#Q`K(;7kY3_b0a9kTVR8W6F46(CQRSik+gOpRv3&cNS0B@Fjxa;J)RNLX$nx%)Htl zwC)hX!F?fi(mmidlzmYQ+Q|65QFlRKwKU1Zf*M50f+Y|SM$@P@*zzQzLAYg3YG&r1 zfvraMq)>4L_HAU~b~KcGpX<@3;6qJkbc?<~nISBRYAn!7xRo&2bH+^c-N4ua_}I0J z_MpYCIYc9%NWFFM`4xtL&jkV3Hsqgr29$CG2H)k@Nua9tYv`TV>A{@-;=V;)IrQ;? zpMq;`t&ZPrXLYi1@bKgI>hPeO!+g5w5uaREEi62Uh&z71S~lyLXwB>zqw##8dOcrI zsZG6hqk8p{$H6)pcwJ1%Ek{ozr4q7346}0W8=95bCe??%YYU(f^$a+IDu_MUBE7)3 z Y%PI0W-aiOdj}O~E`oRa_F0VQjQ^X#?K-6XDC>US97Apqf z%URqvX*{pxx^>LjZe@q|kwVIEyj3IMXKqy1bp7si{vt~dWP;?LsDi;x2xEnh2~VTi zTduCvrB0TQ6JICNy0!8a! zi@g#+H8uM~3#^f*`|go8@?}FaPusRC8}kFvorI-UBA#nvOLW5|dX*Vy(BX 1g+J(G^9F3Fgr@5vqwdm@MfC%*$#y2Gqu|Oh-a;KU zECO(LC|NPQw?F$R2rQlSs#W4!n8*k@pykt_Xk7EJ;{-P<2t^P|8U-OH;tTR{(!F>e z6&YkeQz2uVB>t<(4;L)y_*MN0XOq%^@$KOXf}B b( ze)V>xpS$Rm@TTShJ%NQ?&;s7+-@@ufv5P;72TXw7QvyZKFqI^x`$xWw#3EakRIX&( zo67e0rLlDIgU{wYzgVtzp-OJk5N?@(^UXg3P7Xv^7Cs2K=UUI_siX-7n7-sB=%yeV zievBvCT#79I}y=E9;U5tv$zsYtg;96pkyP8rKD!{Y1XEe{9cI7JzmSzCiU>Teo_S5 zcytyNFGH*w7&885Dkx$wWHV|60^RP&7|S;sv9pJEsBmXXU&Kqa&v(i{xO}~#965XS zM9?I^(|F=8klLgPP$|he4$E{S@vsb7A&i=fn~)lGa_h6e(66-)w*_ImC6w%Mw#0;8 z(}GyWbdx4yaM|nN76|@w%3_B*;s2}5a==Wt^V5||Wo1E{;#gsi3=LTyZ;BGzg>hIW ztC@LNx4N>}9fki9vbMQ*E#m+!dso$Q69x9YS~d!Nw5_?I%*%!9?9Vy*RhXGn?xXFz z%rgwvj!S5#IR6^2C)q`f;l^;?ZX{zIkOgUW{0iyWTrGv1j@|<4-yPH*j?1UX5z7AA z7_^A{IeGDkXC@vA<$z^OzOdr&Vim@pK&7<1VQX@9sMD+<$$54VYyMT>Ur(KZv2fo~ z=L;-WZ65=>AsW5MgiGK6h>q5hv4LI75o+p|xumpSsMadym&LsWZt4rGEf?A#y9f!p z*NXd$7;Sr?9%#5}K_`ExdLb1Q05|i$>&~%b59Yi4PcS2fW(`)*2j!Dn_lQ%R6}c!Z zQi-Q(0s$szAMh(4BiF+nCbR<2gbod)W9F`s`k#>BnlmG%&Vd6UmXIqmkhJg!76yw7 zhT_NT_Y1yn1CrztWc|b+QJG>kHctn>Qi|zNGyJfnFpkXP*yWXx%-pOrpKI#;?|t}# z9Ca=H$QDc+ih@a4Bggj4B^&wsk8+}3uYSsZ4=D;V{19-C@{zGYAy1I(2N{l9xHHCs z>VW;sxpsUEkbQ!lX@`CAW;m9j LXa@-8hpO&jW&6$p#VX0Agf^Te!UuPrvL8KS-3qOju3`Mn}Z?vZ(!2zxc z)Vvo7de?3kH4?t^J$Y2>Ga ~>%3;p8h^SyOa*kXY4YF1V iJ8?+aAB}QrmK|6%~{j{WK8h&O=>n5C@Wq v)tx_pNv>M}=Jo)K{q?eSIUk7qaJhU2F4mXlz?9Xe zKRE7(Hd2x* UfN+|LGFC;Odv}wZj%d9f-9(CRqn{D& z43>~tmBv+Hbr&(dL8+e9g)w?S P<;t{kVP+zB?)|A1 z4|lDWwsyot*|^p(`p!vI4~$YDtw9+6ya#u}t+T;Jq4BE>0HXIC$id+NNL`M(`-BxV zL^Pn#h7>6WB6D ~GMi;tlf(TmI1B=B`>a zj;634xnW{>U=IGCb4LHQ%lj=b{AZV3#~$}d8S1D%n&8;q7UH@vd?_wU+BXbCxo7-^ z=J&;-=Bp+L)0STV*)aNqUxtuwN+!GxEYO#2Z>D7CmWeuU31%pNT~U$AQG< D}IN^-_%X z?HID#w;EbHGE?a8F D1H%>V zYW9xO?2nEY8qxQ;^fjK_LZrbL9NuuIP|wV{2`Xz#O?HxUs0EoznsfM^gd{jex2a`P z@`JpSSO2{bg||y(SQ1p~EiY6|cu=J&$(pv_ZYjyGGRNYN8^N2`-i|X-7@E8dK;ZBc z?E$oUbQUGZ-sq7h%L34~rO_S5Hzot&>uFOWJg1U$c{>=3tvo++f?wqnabN~&l-z$K z_l)F)4P;JgrEB#89uzRTaOipHbWm_%h`QiM=BOYdqF>EYLqgKQbl0=_1f%3}gM0^} zk%n>`J|U0FOHy)3qEu0(?s>Ygs=GMa(2A(<22E+7E94d#=EbIpL}vTXfoP|WYa!Uv zV8u&VxJR<_eZxPo9Fxn;V2f-?8_?Z&<)kQlL@G8;YQ8D){387omJQE=o*VUJudH0& zU@ZX*mzS3wv5z<;fVETgcQ6^6W`Fr@=!|btySVy88{nt2LuCu3o;DK~$U?1<*Q%6< ztNl(rribf2g)WtJ)3)(<9`)KN-9=OVXUJ3_3qA>r@vw)$OQiKfhQfXM23;5y1oEII zM*n(LF5Qo*NDEKGF{ZcY56USULB|v6k#SSSP(^O6_j9Q1XrGYY<>s6Lsaio0UND-! zo|UX09!QzUvEBAot*QE-qhGGDHk(Y8`cvxO+xvs2W*Z~J_}fOtRo|L(U{RXbEqG;a z)go_U?Y0O`FS61xhggmIuUmL#!UTeW&*g=!wX`L41Ioz%3;4*(R6OG1mv};Teqxfr zB1`wkNL7db7p!1b4-$oJBgN9 HyGEk4QiI1aRpa}!GAlm)T<8D*0{{R60009301SZ5eUC*m`)}tD zE3CecGl~qr*4fL%;}}XO-5Chlt-=E*N1|OJPv!NkGW<0k@#$R81>Kx3^tW|D#e&S@ zi2`<4TDDARX=qFRo{b89t{-qNw#T7Fi*s@3C5>Yf6_{cEEn8rvYB*s%*+(q6BRXG# zQMX#mQhKL_O1af0Qqm2FK7yrVgaM#NU7SH9{ qecGskmb1VdCL+ zL0kiaFpt*v3tc_U7-Oj1^aoik4fYv6@l!Fi0WtG+yk}$Cr9pz CZwg7v7D-!1+!#A~@5JZA6noqGWp#ix62V9xVds+3KtUAJlF zK}q5zF5@x`ba-1Cx;GFSwRz9jllw8$?2M>_#J_v?4vO1mrCVK**OFenIXval&Nbcr zDpUy6@K#gGQdR13Qy0lWOK~n~#u5$Mtiv4RNdlP-$I7|0mHEg%06U}f9Gn^eH-Y}{ zj$Z __B0OiGt;tLL_*rSD^-QEwmZSQbxzVAk(VNo7cs(H>u`xg{Mm7T%OO57@! zWY?Iax; @;0 q$=NeuTnKiGw&HS2CxW%5rDK>p!)IgGef`B1oc)>0*8v5{Gzw^%KvfXBMfK-OrJ z#zrsc5|#>gw}KSLE7cAq0=ov>|2ydtDMH>@hj)D7a%3yxAx2U4KN~0kD3+Q83EGl} z?=g1f6nNSM$VSgA@OBfOmmWxB_lJ)bXi@u*&rHbI5WP<%u#QTQrNcTAVg^#19VCeox|iA4WRYaK*?ph5;FWGmncdfaUPbKE-fgAuY@WbGlUl9%%p zPSp<81nVdsyMRJ{S*(GR);TV~!c5FuNEAmyLV%N(Rs%nB$wuMh#sA^v9>ZyTLI kZpU)l=OdrF7WvD*y5UocPzuQNAA@)4^nI-04lwt9Q1=N(sEaha3#fk|dJ>S-i z)0h}$GP>rQqfz44EqtZi&h=kpTt>&QCr=+DPKsXc5n3 Yo kt ZBp;A{n`dYUH{ZVI z)%oUkZfcNU2C~88+j`VC63=G5D;QN4`v5SNY7MTctYYp!1nxB<{VYwcRq$$w%LvMF zF3n-_a{9hh&4e=x{jznS?Mz=h;Ptu97mIg)S^i%s;ZHv15AwHTT+ @v#WY$joI*SR%*;rL)nLxOAO6r+*8#&8@sBNf%wK;7YHhKl( zQwXAQzRl-U`z6I6wx1Oe@fySD4G_*H% ><)t4u_30Ve2n zAJ5>r^~8TF5H1_F);a&40009300RI5OE-SZ=qK+5Eaz0KF%zNS@uRSQXw)w~_! eRF zt!X3%Yl$o!nRu<5f9>h{c7mj6H)V}xTmLNE`xtvkA@&B|1ycGa1S^IsQ0`K cQDHGfz`?E! z*><1(2=t_1<1n`>iqLi*Kdv~Xh*kS&j8r8%9vB5m)16Koj~UHVcpk?-6|Yr}pQ~_B z9<&kpROe|K>M01HOgUpRf6$o;EGc$36^QBP-23AI%lXzq|1)a82Uvm*efhRV*Am=j zMRBClUBzM+j=D?NZj?^NJy1xH^QGC3%lF~8CvpUoKGxKN7Q`#0&U2JN$(QU&CB1rv z?{)J6Q`lH}AEHK)d^06r#vC$pakFDh+eu!;pjz7w<(7$`Vw<&sHuL#WD{`edrZy5p z9kqfnyr+i?Q2M}FwlIv5`}KD!8^Nle-$AUqfn7|qK0GH$ezX;#bWSR|mbDDP_j)il zYL!;a$KJD2QvlH!hm@&&(blLqxyWvy1sA#62~oHz(wzYBQo*1*?dGJRwIm(Z#%L4t zp&5=P7{1*T4%IZKAYv%#9Kx#oJA4kxpK$F^-sUCo=T6djf1Lz&oTFUNrKy?X(Mwtc z=u%UaHnR7Btd1n$DyiZ0{`Eu!W=6%Ulh1Y=vU${~`}@X6Ocy!ZFGD^I0Em7WKo&;+ z-S)%f4d!4hN-YC+^==BZm@q=cf>&lSlr|;bDq)d3)6P^GM!8dB6rVR!#YV?!o#yF5 zus@&tYA_-2%#NFvCN^NFklFZp_3e-h3SAY#jMcVUuq>8B4@F+c4=?vYgPurS6d?D- zax6MeKLE!bjGK>r-cC|PGbRNPu63hIXOOcs#CtHT9{Hb#sfj=T#y1O@$uYBGj}JJ( z lC`7v| 0!AKdMX(*ea^Xk(Ay$#ZKA$4;Eb{yAL1 zQD>4KdU@5~vl^N--wu>gV=X !5v+R{a&@SGC7A_{D#qdNXw5l8}m` xU=q+i#i76<}=xXJNss%5} zk>7^YZ~W?f`uy 8u>HmUQJD~q2Y@Qzu1fcxfxnqm^P25tGEkul z2>q<0{J2ycFK3T^p@2r3PuXzxOs6vij_PIm@A-F5(gFZ+yBU8aU*OL$V$`|Ihs7nr zh+7~b-OEk8(Fl$DyXu}}y@0|a12Ac4mHfCF^`v5qwo%*^-%xhTx@do=b-F5orI9q| zgS&h^35gZ=W9fsj>!ZLv&ij7t2}9~G5_%9gqcfNx7wKbyHedB2@UO#;D!p1!s6?w- z=|k=&Q!*y8BaFeb%EVPS5(iU&euDHtydMcrJhyE7lchWm`_XN-_vq~NYX9k9A$$jd zWBhsn%g?&wwpS*`jd|+bm`ITPz-_{fL-}0}FNV1BQ6JOlvUZyx?oI7nr;}7KIxWU# zvck38r@Ra=LI|^~+++a7yc}ZH8okA;^w9Sa@(Ak!${4I!IG(vNdap<|cYp^qd5WK0 z)97tB#tFMaU4lb)Kx7!Kl-7Ye+=E}8$el#mz4DILxt8Rn)V|RTg^h;P1Ra;1N5bL- zKB|f4UFB4W?>OnrdaS>86LzNpEXk(>OHQ;irK3!f{%*PJU@gr9(p!`(A<^bLpa1{^ z001=VA00%ywHXMZ6IdhnR1KY}LCy{mJ@GXhZ{ 21REoN?mV%qb6%7cLx#_ =U|j|6uDhp#J{XU@*OcV4A1ZRV#W_e_j9OxyWuPyYU(vs$&HUd zB{kmc$2tV>V;$SAD>maY5^j@$&WkCLax;x-Md5;Ht|U)&arJb5Eb5VLMLoYtOfl!} z*kg&=C%!t&LRg#gy8~4J)W$_$4f=lNd~_G5A*nqMNM>_J4X{IKi$)}(>a4*lZV-Pv z9}M?7>}z2pAX1OOaf{VE(B=5GB}4jE*306~#3)G2W|$SX{p B*DE)eSR~+8?Qdx4k`hU zL9{JRV8%mpH6^pea l>@n*}A~-e>&g^8RY1vv3y hG@O&v&9(ucGc;q=0NT=0<$)I=ajqR#uT zNm6Et^NokFVncVcP3AJY@R2^`q|#8BV$yi;H_T8AxM~l`gmEef4NyA$4X~V6~1No>#C*3e~q?xVYS?9ndM?YE(6sMs5LF zQ;-8%Fy3yZ=S5f`Zft`6LN1kbZ$cC$Py86w%NmmiGT}_e8P0S S?D| zdPo3AND@9u9OcHq4QaMdnYbxJdP+7&^zm9I93K$ASY3{!Vw<9q!TSgq5%?l_FG|Nv zCcI=jh)ZisMq5m)JT_Q}{0ikb^#x>HWe=_x<0cj@XS~pb0t6dmCaVYivJ+ZxSf>Jh zou*_8=K`J8`Y?h&`Kn(vK5peVrHnyQDBHParjsjQ%~$~B zP2tkmAG`h6Gbfhg2dj93H he(kmgQ6u@J>L*p$dyd%>D#gvn zJZ?c~(*Qb*6}}blzG1+}txZ1U76%o}QlYN-6{zB(2)luhKKrtv=>B(65wFch?KboZ zqEKwx4*d2vG_Gr|4*HUVa?ST2bQw4!9N00^qH)ZGeeI$-fME?5J+AIoJSQG(+Af9v zApar$wqfL{G#A}Q`cQuv`dDzAF)LJ&wK ji69fM-TySug9A5wY!fg5@!^gR`|Bk_y)MEN&hugT6`3^?=R z4YI;3Lh{9Mh*Nx%chX|w){?rZHKEtvkr0m7CD6}jq39MykPW}-Zwi+GrQS1zLX#&@ zh`p>3@X|01?0}V7pusfQ0l>D!q@q64OLpnW2q%=yzT5eu)y0KnqS6&Oi!zj`bgx$e zYG3)B10W3h<0wB1m8@uH9l;c13DEc VJ@VQIE$d)y2oUILjb_f#W&gvgb`)E<2< zny@qZ%XYHf44%?*zH*gI)TP?%)q!5`1cizyxmm~=Yf*F-iol_dMJn_Smo*0^hGH*? zzy*NnJ1#;G>M@vhC6k3C^v~-mB6p)J$NrXkK?3(G83BKO)_E1d=cpz%el-n&2-$dh zIKgrSy%LuooPnGyca2dZ7h-ccOfgpmNbi1^vO8)GumkFR=IOU3^dlm@r*qrSXas{q zaJ9|nOFUavN*Mjzi(Df+ja`0-Y8YUa4k-nmbTg=(Hcmvn#8&s?e} >2qd5cahT3KsXze_U8nSR%Wk&f&x z0CBqhMagCsPdxHF$-W>-CVaJ+X>hllA8L9L`xpZ?Dcf{uT_x};ML}?tJO0JWGjtC3 zVepOR7n1V(87%cG2C5NYs1$xUz#r0QxNupQAu)Jl9N1~zqObBiYy%Exz9ezJeJm|S zDDuBkT9`;Fjz>Hqg3<>W^Bmnd >K`D0l2RNZfIU;MGYKMo$ex z7`V9W#nxA5w<%tV%8#?2G(0mll35{t0ey+7ef_?bqqCZ(q4NVQZmY}oc~X-@)Vlz7 zW~;NIl~mTLpp1C{38+&A(k@RWR<9Tuh-~Z%XsFXwlzw3PqQ3KEcop;66Ze|f)lNp7 zN@2@JB2ENH!##>2HLEE#`1{*3?RUm-I`De2)`nhS-W{CjqkdOJ7|J>+{(-w0oIx>2 zUvewiB~9PcIuPI&rH;nll8@WC`>wFZH!-aiLsp)uDA4+djH0D7ZWW#tf%*ytE5Jv> z??K7{00RI30|0_jRpAJ0{-+o}&X5WKmPgvedF@NcQjsZZ_igsOF uwUq41cy4W6Sqa=XVpkaGM@kgV8b3hA@*Z}t2nI8ulf>V>ek zF(kUKf&)TiNJ`nKvWs9u?m6$>fTtHhJe(fUHWf98yP6(JeWS;%DmfSGlgUt`vd10< zD%S53&TO1V9&{MG9(uj%7=J7;9s9E*A}O7|?%`hTN=HlrjB)=p$jrwy-~k_K&$S7d zOQ?iK0kd=rAs-xl4@HUQNpXxud&+ai_iGsHDIv!Zf4T~7fPJ`*IZ*YXzc`=fz3(K$ zOGdGdGH`V40p}zQI?`@16T#&YtvSw7Xv|u8^|U0~rxrJwMekre{)^U(AbyLy-V0ff zONALaaI@MfLBXW%)`L_}evPWgzaRolFtR_>Iea?Vio{e%D{UnEizhvJX9b_29Y}gK z--M{tS-jJY@)`$!STG(t5nSD&gDChI*)2l$!_a!$K`Kr{5Sa&pHjTrat>5#`o={DG zm019M(hQe%tbMCSH{o@=&Uv~0AP||B85qG+yZv2kAp{2ss)TP{hSzsG3F)F^K~BZy zu?p&-db}2UJ3c`{hz3j=xZvXUJ?J?YXF1=_m_oyKPvX`waKljlP*7)6r2E04z&inS zl45U6cMgm8iFyp-b|qxZAL+2R+a}e6Ze^6{j~*%nzuV?R3OkIo!`t~xpdjS5|G}*4 z2ft1?u1`d%1a}-GkBrjY+2?D!%m`$^7#e)xvvxq!2zPFlWSIkBmc2=lMmvwjh@A-0 z7-x;z_T-=cNv=Im#awCd2QMMS2OZbm9@53X7pyOPEqgj;W|R!YHipgL<~cgb%p~e{ z)~oS*>?4Qk6VA?tZM0qA=FWIrp|Z=M*HxG;dq2UgDz6On=B6|!?l(0DI4s;7N(?Jo zE0i-{!wDe;iuQgEwYP`*#PqC|=wwX(jcW&EA*jXwK9)vD Xy2;D4(={ z&QlVPC8Z|vup>f2BOQ_Jd0&U7697itv%xJ!s>7cSUr7reU$)z>Lj^<*sB&)KDYf$R zAit7Jsa;>{?bu!_0V`zmV#rp2w@99x(A@Wy@tY8Lmc?~?nh15u>{&7TsxUm|WflO& z@+VfQX>S!)RI=76E~4WF(cRfCi6WW)zur^iyM$tN$BlJ2$mWEezEQ*yWqR8pMD^`S z)$#`I$qGL2d5QBX8YkkBq_aR>8Lr}-_t!!as!*e4+Ygywy!h6lJBM-8neB&HZ8Dwq z1=dHe3^aRcvLGDM_yW#>CJ)Ax0+21_sk{vaNKzsqpa-Gf6KTuplc2)JD5Q^eI(l YuA7vQYoyCFf`^{r=jiA{Cj5lzvfExQ zZTAG1V?^ni-)pHBX0=gromn)xwA31c7ZAT$6^Dyp720-D#Ok2~_a;%p0|;BvP*?CW ziW;;5d0yUENa(P`VQC-qd9l-C``9^sJ3D&das@uMlNY<}TR7qhr&c35$%Og=#Epz& z H%B*pH`F7hY9w;#n z3wBf)#IXhd(#ow-=i8xi@N-XzzC}imj>Xz18UFC_s~uvpH+@OTfNsuN6PeS48Y-1e zG`YAnlHSxxFQ^TwN%s57M+Kr63~17$zJD#0M}yL16P+2+F9^ybHNjDW`(t}h%LC6| z8(c))B^x>`?64+Ka{nMaP7_Fm&Te0gaptF`pw25;o0Plp(RKFQKcf>;!!aLL;Xpp( z Rv5r#{Dj7*{`H`wu-s;>jm34JS2eRz>@iwS(;%xmi zALpoaA=CDkbd1zKa!66ta9QCzS;@nk-<>rd3p>>KM-3u7TFL@z9dNfIP_)0)wTUZF z6kg$L77;6 iXGsGZ zv*F6{xI;JRhQ_&=WPc5h6|>;KS5bnab@OS>iIs~EhVm&53(;Iywe8{l#64t_T|^1s z?G5pf9`7dMiAh0TcI$jd(4LAu7tD0gr;yIIJzfL+^LF-ehDbFToGwhTYw9gU_?JYm z>-qZI%Zi~#eAoi3bdQKUB~I)DN#dZ~!-&I{L?*PUYs8wLv3XMsf7e7g{-3dIGhlBx zp5}A`N|aj~SF~c@#7kYHq4h$N> AHas(NJ+6xDAV>{3sP)FjjmZ(bZevcn9Vs z7{5rn4CRkh3)i&mr ^P3g#Ehm8x%_NCH(wT^j$S neC{;+oiQ`X;2X(ZZJjOBvsc4zi$pX*|A)Ph&yhw6!n9yyG zZ;+wJZ7R_bvG^o3rN)-lh=YDHb%Ny$>PO&Cr|T2~?I^}7SkLX;Ou>0q>*=9RK5V zQm2uQpLc@AoGWI=KE}H8aU|PPeT&dMuw+js4v1q4`QtLQ-D)C%7uBhflncCA5b(y( zPwuH_5f2P16=oL~L^_^}H4lH~B I8i<>7cY-e=EDF2zy7riw#hjqRNqh@=a@i3ETFLdp&eD8JUJQG4{Glr4 znv)~mmQ6%>RxgKey;sKV&cy`0OQIKWd7(s&u{;`Z?n}U?3Tod}HhvfL#J|^g#|rUN zOIJnL&y$oTLFj=uip}^Cj!ZSHSof$3H{ud${RpTW=8BS~SsBLyM*UiVHBIRQGQg7% z47FmvHznyb%z}SxpufQ%YO_8OV8(naR0@2}t>?r=Dg9htqyCPM&*hZc1r4Bt{)>3d zOXxjUVT?6gK!9ojONUug)IZkXMAECuFB}(O%xX@fd5kDa6Ex*=^gmsd9D|%sRz70q zfZslbG4(PjyI1{zEtKFdHaS2Wa3dLZWf)7eKCC0_<3ImtF)*J51M|1B)5(0}Lm48h zDn* Y!#9xtmhY&dQO) z38Tw8C;tw-%^N|L)jwUifRkl2CwIrt>ieMYq#BugIt0RAdK(u;tC(3 =z~m1YOn=}(QomK8H<+n}iXEnH;^~_BY_q?2wB2p@&tx*IX4>%# zpoA~D_6EK$X%He|dLmW~Ja_2YU8}n|%~zJ8WG~1E;vGshh5hEaFUHxl2;UKqr0hsE z(R$W7s~{)xn>&We;8yGzO$^Fo(OlNOUW)E6XL$2uCmXObx{OPVGEpYIixtFT>D;}V z>@#Na?4@I(HbnS0D&2+u0zp@RjM4ip#@xI1uDl OmNdq+F#X(F8!W<-1fn(gW8g2aA@efTgT)o4N=w7?An4KqB2U$Nh8!| z7XP}!AQ1&tpy)bA dN_i Y>~# YE;X)t-CQeI-$Cd;2Q3zUN>5Rn zsiOO!V!0u=28|v!h2t;bSOQh@E|Z@UFuIfZc<>cN>Cqs`w+;J4-^UBXI##4tkGh4f zdO-ds3kT6Np*bUm@q8##>}nM__0Us!?6yuPq=zE+G(IUUkqlovS8?|uoavIu(anJx znbiq@Sdss7ln`wZ&J&V2A k z0}&;rl*j-80{{R6077d4y>yMu$%aQz@)CXG%i}N;9NRS|b@$|@B({$}LKc0#-O<@3 zf8S%kip3u=08xsY+zdAv1yd@ zecQ bD=nxgqR7lI@QnVTGQY2mL@8Dv1 wbO zskP}m4wcm$MB0v$YzxR0*(K*!8T-?pU>dPk3oZz}2J0T@F@=J2>6BHLfz6Rk^RaG6 zVFsiq#x-%%+^ClHcb1 t?