pax_global_header00006660000000000000000000000064144463205250014517gustar00rootroot0000000000000052 comment=51d72d34e2b9778a31aa5dd79fbdd8cdac50b4d5 termenv-0.15.2/000077500000000000000000000000001444632052500132645ustar00rootroot00000000000000termenv-0.15.2/.github/000077500000000000000000000000001444632052500146245ustar00rootroot00000000000000termenv-0.15.2/.github/FUNDING.yml000066400000000000000000000000171444632052500164370ustar00rootroot00000000000000github: muesli termenv-0.15.2/.github/dependabot.yml000066400000000000000000000004231444632052500174530ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "gomod" directory: "/" schedule: interval: "daily" labels: - "dependencies" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "daily" labels: - "dependencies" termenv-0.15.2/.github/workflows/000077500000000000000000000000001444632052500166615ustar00rootroot00000000000000termenv-0.15.2/.github/workflows/build.yml000066400000000000000000000011761444632052500205100ustar00rootroot00000000000000name: build on: [push, pull_request] jobs: build: strategy: matrix: go-version: [~1.17, ^1] os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} env: GO111MODULE: "on" steps: - name: Install Go uses: actions/setup-go@v4 with: go-version: ${{ matrix.go-version }} - name: Checkout code uses: actions/checkout@v3 - name: Download Go modules run: go mod download - name: Build run: go build -v ./... - name: Test run: go test ./... if: matrix.platform != 'windows-latest' termenv-0.15.2/.github/workflows/coverage.yml000066400000000000000000000013211444632052500211740ustar00rootroot00000000000000name: coverage on: [push, pull_request] jobs: coverage: strategy: matrix: go-version: [^1] os: [ubuntu-latest] runs-on: ${{ matrix.os }} env: GO111MODULE: "on" steps: - name: Install Go uses: actions/setup-go@v4 with: go-version: ${{ matrix.go-version }} - name: Checkout code uses: actions/checkout@v3 - name: Coverage env: COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | go test -race -covermode atomic -coverprofile=profile.cov ./... GO111MODULE=off go get github.com/mattn/goveralls $(go env GOPATH)/bin/goveralls -coverprofile=profile.cov -service=github termenv-0.15.2/.github/workflows/lint-soft.yml000066400000000000000000000011731444632052500213250ustar00rootroot00000000000000name: lint-soft on: push: pull_request: permissions: contents: read # Optional: allow read access to pull request. Use with `only-new-issues` option. pull-requests: read jobs: golangci: name: lint-soft runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: # Optional: golangci-lint command line arguments. args: --config .golangci-soft.yml --issues-exit-code=0 # Optional: show only new issues if it's a pull request. The default value is `false`. only-new-issues: true termenv-0.15.2/.github/workflows/lint.yml000066400000000000000000000011011444632052500203430ustar00rootroot00000000000000name: lint on: push: pull_request: permissions: contents: read # Optional: allow read access to pull request. Use with `only-new-issues` option. pull-requests: read jobs: golangci: name: lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: # Optional: golangci-lint command line arguments. #args: # Optional: show only new issues if it's a pull request. The default value is `false`. only-new-issues: true termenv-0.15.2/.gitignore000066400000000000000000000004151444632052500152540ustar00rootroot00000000000000# Binaries for programs and plugins *.exe *.exe~ *.dll *.so *.dylib # Test binary, built with `go test -c` *.test # Output of the go coverage tool, specifically when used with LiteIDE *.out # Dependency directories (remove the comment below to include it) # vendor/ termenv-0.15.2/.golangci-soft.yml000066400000000000000000000012701444632052500166210ustar00rootroot00000000000000run: tests: false issues: include: - EXC0001 - EXC0005 - EXC0011 - EXC0012 - EXC0013 max-issues-per-linter: 0 max-same-issues: 0 linters: enable: # - dupl - exhaustive # - exhaustivestruct - goconst - godot - godox - gomnd - gomoddirectives - goprintffuncname - ifshort # - lll - misspell - nakedret - nestif - noctx - nolintlint - prealloc - wrapcheck # disable default linters, they are already enabled in .golangci.yml disable: - deadcode - errcheck - gosimple - govet - ineffassign - staticcheck - structcheck - typecheck - unused - varcheck termenv-0.15.2/.golangci.yml000066400000000000000000000006051444632052500156510ustar00rootroot00000000000000run: tests: false issues: include: - EXC0001 - EXC0005 - EXC0011 - EXC0012 - EXC0013 max-issues-per-linter: 0 max-same-issues: 0 linters: enable: - bodyclose - exportloopref - goimports - gosec - nilerr - predeclared - revive - rowserrcheck - sqlclosecheck - tparallel - unconvert - unparam - whitespace termenv-0.15.2/LICENSE000066400000000000000000000020671444632052500142760ustar00rootroot00000000000000MIT License Copyright (c) 2019 Christian Muehlhaeuser Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. termenv-0.15.2/README.md000066400000000000000000000435551444632052500145570ustar00rootroot00000000000000

termenv Logo
Latest Release GoDoc Build Status Coverage Status Go ReportCard
Example terminal output

`termenv` lets you safely use advanced styling options on the terminal. It gathers information about the terminal environment in terms of its ANSI & color support and offers you convenient methods to colorize and style your output, without you having to deal with all kinds of weird ANSI escape sequences and color conversions. ## Features - RGB/TrueColor support - Detects the supported color range of your terminal - Automatically converts colors to the best matching, available colors - Terminal theme (light/dark) detection - Chainable syntax - Nested styles ## Installation ```bash go get github.com/muesli/termenv ``` ## Usage ```go output := termenv.NewOutput(os.Stdout) ``` `termenv` queries the terminal's capabilities it is running in, so you can safely use advanced features, like RGB colors or ANSI styles. `output.Profile` returns the supported profile: - `termenv.Ascii` - no ANSI support detected, ASCII only - `termenv.ANSI` - 16 color ANSI support - `termenv.ANSI256` - Extended 256 color ANSI support - `termenv.TrueColor` - RGB/TrueColor support Alternatively, you can use `termenv.EnvColorProfile` which evaluates the terminal like `ColorProfile`, but also respects the `NO_COLOR` and `CLICOLOR_FORCE` environment variables. You can also query the terminal for its color scheme, so you know whether your app is running in a light- or dark-themed environment: ```go // Returns terminal's foreground color color := output.ForegroundColor() // Returns terminal's background color color := output.BackgroundColor() // Returns whether terminal uses a dark-ish background darkTheme := output.HasDarkBackground() ``` ### Manual Profile Selection If you don't want to rely on the automatic detection, you can manually select the profile you want to use: ```go output := termenv.NewOutput(os.Stdout, termenv.WithProfile(termenv.TrueColor)) ``` ## Colors `termenv` supports multiple color profiles: Ascii (black & white only), ANSI (16 colors), ANSI Extended (256 colors), and TrueColor (24-bit RGB). Colors will automatically be degraded to the best matching available color in the desired profile: `TrueColor` => `ANSI 256 Colors` => `ANSI 16 Colors` => `Ascii` ```go s := output.String("Hello World") // Supports hex values // Will automatically degrade colors on terminals not supporting RGB s.Foreground(output.Color("#abcdef")) // but also supports ANSI colors (0-255) s.Background(output.Color("69")) // ...or the color.Color interface s.Foreground(output.FromColor(color.RGBA{255, 128, 0, 255})) // Combine fore- & background colors s.Foreground(output.Color("#ffffff")).Background(output.Color("#0000ff")) // Supports the fmt.Stringer interface fmt.Println(s) ``` ## Styles You can use a chainable syntax to compose your own styles: ```go s := output.String("foobar") // Text styles s.Bold() s.Faint() s.Italic() s.CrossOut() s.Underline() s.Overline() // Reverse swaps current fore- & background colors s.Reverse() // Blinking text s.Blink() // Combine multiple options s.Bold().Underline() ``` ## Template Helpers `termenv` provides a set of helper functions to style your Go templates: ```go // load template helpers f := output.TemplateFuncs() tpl := template.New("tpl").Funcs(f) // apply bold style in a template bold := `{{ Bold "Hello World" }}` // examples for colorized templates col := `{{ Color "#ff0000" "#0000ff" "Red on Blue" }}` fg := `{{ Foreground "#ff0000" "Red Foreground" }}` bg := `{{ Background "#0000ff" "Blue Background" }}` // wrap styles wrap := `{{ Bold (Underline "Hello World") }}` // parse and render tpl, err = tpl.Parse(bold) var buf bytes.Buffer tpl.Execute(&buf, nil) fmt.Println(&buf) ``` Other available helper functions are: `Faint`, `Italic`, `CrossOut`, `Underline`, `Overline`, `Reverse`, and `Blink`. ## Positioning ```go // Move the cursor to a given position output.MoveCursor(row, column) // Save the cursor position output.SaveCursorPosition() // Restore a saved cursor position output.RestoreCursorPosition() // Move the cursor up a given number of lines output.CursorUp(n) // Move the cursor down a given number of lines output.CursorDown(n) // Move the cursor up a given number of lines output.CursorForward(n) // Move the cursor backwards a given number of cells output.CursorBack(n) // Move the cursor down a given number of lines and place it at the beginning // of the line output.CursorNextLine(n) // Move the cursor up a given number of lines and place it at the beginning of // the line output.CursorPrevLine(n) ``` ## Screen ```go // Reset the terminal to its default style, removing any active styles output.Reset() // RestoreScreen restores a previously saved screen state output.RestoreScreen() // SaveScreen saves the screen state output.SaveScreen() // Switch to the altscreen. The former view can be restored with ExitAltScreen() output.AltScreen() // Exit the altscreen and return to the former terminal view output.ExitAltScreen() // Clear the visible portion of the terminal output.ClearScreen() // Clear the current line output.ClearLine() // Clear a given number of lines output.ClearLines(n) // Set the scrolling region of the terminal output.ChangeScrollingRegion(top, bottom) // Insert the given number of lines at the top of the scrollable region, pushing // lines below down output.InsertLines(n) // Delete the given number of lines, pulling any lines in the scrollable region // below up output.DeleteLines(n) ``` ## Session ```go // SetWindowTitle sets the terminal window title output.SetWindowTitle(title) // SetForegroundColor sets the default foreground color output.SetForegroundColor(color) // SetBackgroundColor sets the default background color output.SetBackgroundColor(color) // SetCursorColor sets the cursor color output.SetCursorColor(color) // Hide the cursor output.HideCursor() // Show the cursor output.ShowCursor() // Copy to clipboard output.Copy(message) // Copy to primary clipboard (X11) output.CopyPrimary(message) // Trigger notification output.Notify(title, body) ``` ## Mouse ```go // Enable X10 mouse mode, only button press events are sent output.EnableMousePress() // Disable X10 mouse mode output.DisableMousePress() // Enable Mouse Tracking mode output.EnableMouse() // Disable Mouse Tracking mode output.DisableMouse() // Enable Hilite Mouse Tracking mode output.EnableMouseHilite() // Disable Hilite Mouse Tracking mode output.DisableMouseHilite() // Enable Cell Motion Mouse Tracking mode output.EnableMouseCellMotion() // Disable Cell Motion Mouse Tracking mode output.DisableMouseCellMotion() // Enable All Motion Mouse mode output.EnableMouseAllMotion() // Disable All Motion Mouse mode output.DisableMouseAllMotion() ``` ## Bracketed Paste ```go // Enables bracketed paste mode termenv.EnableBracketedPaste() // Disables bracketed paste mode termenv.DisableBracketedPaste() ``` ## Terminal Feature Support ### Color Support - 24-bit (RGB): alacritty, foot, iTerm, kitty, Konsole, st, tmux, vte-based, wezterm, Windows Terminal - 8-bit (256): rxvt, screen, xterm, Apple Terminal - 4-bit (16): Linux Console ### Control Sequences
Click to show feature matrix | Terminal | Query Color Scheme | Query Cursor Position | Set Window Title | Change Cursor Color | Change Default Foreground Setting | Change Default Background Setting | Bracketed Paste | Extended Mouse (SGR) | Pixels Mouse (SGR-Pixels) | | ---------------- | :----------------: | :-------------------: | :--------------: | :-----------------: | :-------------------------------: | :-------------------------------: | :-------------: | :------------------: | :-----------------------: | | alacritty | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | foot | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | kitty | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Konsole | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | | rxvt | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | | urxvt | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | screen | ⛔[^mux] | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | st | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | tmux | ⛔[^mux] | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | vte-based[^vte] | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | | wezterm | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | xterm | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | | Linux Console | ❌ | ✅ | ⛔ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | Apple Terminal | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | | iTerm | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | | Windows cmd | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | | Windows Terminal | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | [^vte]: This covers all vte-based terminals, including Gnome Terminal, guake, Pantheon Terminal, Terminator, Tilix, XFCE Terminal. [^mux]: Unavailable as multiplexers (like tmux or screen) can be connected to multiple terminals (with different color settings) at the same time. You can help improve this list! Check out [how to](ansi_compat.md) and open an issue or pull request.
### System Commands
Click to show feature matrix | Terminal | Copy to Clipboard (OSC52) | Hyperlinks (OSC8) | Notifications (OSC777) | | ---------------- | :-----------------------: | :---------------: | :--------------------: | | alacritty | ✅ | ❌[^alacritty] | ❌ | | foot | ✅ | ✅ | ✅ | | kitty | ✅ | ✅ | ✅ | | Konsole | ❌[^konsole] | ✅ | ❌ | | rxvt | ❌ | ❌ | ❌ | | urxvt | ✅[^urxvt] | ❌ | ✅ | | screen | ✅ | ❌[^screen] | ❌ | | st | ✅ | ❌ | ❌ | | tmux | ✅ | ❌[^tmux] | ❌ | | vte-based[^vte] | ❌[^vte] | ✅ | ❌ | | wezterm | ✅ | ✅ | ❌ | | xterm | ✅ | ❌ | ❌ | | Linux Console | ⛔ | ⛔ | ❌ | | Apple Terminal | ✅[^apple] | ❌ | ❌ | | iTerm | ✅ | ✅ | ❌ | | Windows cmd | ❌ | ❌ | ❌ | | Windows Terminal | ✅ | ✅ | ❌ | [^vte]: This covers all vte-based terminals, including Gnome Terminal, guake, Pantheon Terminal, Terminator, Tilix, XFCE Terminal. OSC52 is not supported, see [issue#2495](https://gitlab.gnome.org/GNOME/vte/-/issues/2495). [^urxvt]: Workaround for urxvt not supporting OSC52. See [this](https://unix.stackexchange.com/a/629485) for more information. [^konsole]: OSC52 is not supported, for more info see [bug#372116](https://bugs.kde.org/show_bug.cgi?id=372116). [^apple]: OSC52 works with a [workaround](https://github.com/roy2220/osc52pty). [^tmux]: OSC8 is not supported, for more info see [issue#911](https://github.com/tmux/tmux/issues/911). [^screen]: OSC8 is not supported, for more info see [bug#50952](https://savannah.gnu.org/bugs/index.php?50952). [^alacritty]: OSC8 is not supported, for more info see [issue#922](https://github.com/alacritty/alacritty/issues/922).
## Platform Support `termenv` works on Unix systems (like Linux, macOS, or BSD) and Windows. While terminal applications on Unix support ANSI styling out-of-the-box, on Windows you need to enable ANSI processing in your application first: ```go restoreConsole, err := termenv.EnableVirtualTerminalProcessing(termenv.DefaultOutput()) if err != nil { panic(err) } defer restoreConsole() ``` The above code is safe to include on non-Windows systems or when os.Stdout does not refer to a terminal (e.g. in tests). ## Color Chart ![ANSI color chart](https://github.com/muesli/termenv/raw/master/examples/color-chart/color-chart.png) You can find the source code used to create this chart in `termenv`'s examples. ## Related Projects - [reflow](https://github.com/muesli/reflow) - ANSI-aware text operations - [Lip Gloss](https://github.com/charmbracelet/lipgloss) - style definitions for nice terminal layouts 👄 - [ansi](https://github.com/muesli/ansi) - ANSI sequence helpers ## termenv in the Wild Need some inspiration or just want to see how others are using `termenv`? Check out these projects: - [Bubble Tea](https://github.com/charmbracelet/bubbletea) - a powerful little TUI framework 🏗 - [Glamour](https://github.com/charmbracelet/glamour) - stylesheet-based markdown rendering for your CLI apps 💇🏻‍♀️ - [Glow](https://github.com/charmbracelet/glow) - a markdown renderer for the command-line 💅🏻 - [duf](https://github.com/muesli/duf) - Disk Usage/Free Utility - a better 'df' alternative - [gitty](https://github.com/muesli/gitty) - contextual information about your git projects - [slides](https://github.com/maaslalani/slides) - terminal-based presentation tool ## Feedback Got some feedback or suggestions? Please open an issue or drop me a note! - [Twitter](https://twitter.com/mueslix) - [The Fediverse](https://mastodon.social/@fribbledom) ## License [MIT](https://github.com/muesli/termenv/raw/master/LICENSE) termenv-0.15.2/ansi_compat.md000066400000000000000000000021211444632052500160770ustar00rootroot00000000000000## Change Foreground Color This command should enable a blue foreground color: ```bash echo -ne "\033]10;#0000ff\007" ``` ## Change Background Color This command should enable a green background color: ```bash echo -ne "\033]11;#00ff00\007" ``` ## Change Cursor Color This command should enable a red cursor color: ```bash echo -ne "\033]12;#ff0000\007" ``` ## Query Color Scheme These two commands should print out the currently active color scheme: ```bash echo -ne "\033]10;?\033\\" echo -ne "\033]11;?\033\\" ``` ## Query Cursor Position This command should print out the current cursor position: ```bash echo -ne "\033[6n" ``` ## Set Window Title This command should set the window title to "Test": ```bash echo -ne "\033]2;Test\007" && sleep 10 ``` ## Bracketed paste Enter this command, then paste a word from the clipboard. The text displayed on the terminal should contain the codes `200~` and `201~`: ```bash echo -ne "\033[?2004h" && sleep 10 ``` ## Trigger Notification This command should trigger a notification: ```bash echo -ne "\033]777;notify;Title;Body\033\\" ``` termenv-0.15.2/ansicolors.go000066400000000000000000000065371444632052500160020ustar00rootroot00000000000000package termenv // ANSI color codes const ( ANSIBlack ANSIColor = iota ANSIRed ANSIGreen ANSIYellow ANSIBlue ANSIMagenta ANSICyan ANSIWhite ANSIBrightBlack ANSIBrightRed ANSIBrightGreen ANSIBrightYellow ANSIBrightBlue ANSIBrightMagenta ANSIBrightCyan ANSIBrightWhite ) // RGB values of ANSI colors (0-255). var ansiHex = []string{ "#000000", "#800000", "#008000", "#808000", "#000080", "#800080", "#008080", "#c0c0c0", "#808080", "#ff0000", "#00ff00", "#ffff00", "#0000ff", "#ff00ff", "#00ffff", "#ffffff", "#000000", "#00005f", "#000087", "#0000af", "#0000d7", "#0000ff", "#005f00", "#005f5f", "#005f87", "#005faf", "#005fd7", "#005fff", "#008700", "#00875f", "#008787", "#0087af", "#0087d7", "#0087ff", "#00af00", "#00af5f", "#00af87", "#00afaf", "#00afd7", "#00afff", "#00d700", "#00d75f", "#00d787", "#00d7af", "#00d7d7", "#00d7ff", "#00ff00", "#00ff5f", "#00ff87", "#00ffaf", "#00ffd7", "#00ffff", "#5f0000", "#5f005f", "#5f0087", "#5f00af", "#5f00d7", "#5f00ff", "#5f5f00", "#5f5f5f", "#5f5f87", "#5f5faf", "#5f5fd7", "#5f5fff", "#5f8700", "#5f875f", "#5f8787", "#5f87af", "#5f87d7", "#5f87ff", "#5faf00", "#5faf5f", "#5faf87", "#5fafaf", "#5fafd7", "#5fafff", "#5fd700", "#5fd75f", "#5fd787", "#5fd7af", "#5fd7d7", "#5fd7ff", "#5fff00", "#5fff5f", "#5fff87", "#5fffaf", "#5fffd7", "#5fffff", "#870000", "#87005f", "#870087", "#8700af", "#8700d7", "#8700ff", "#875f00", "#875f5f", "#875f87", "#875faf", "#875fd7", "#875fff", "#878700", "#87875f", "#878787", "#8787af", "#8787d7", "#8787ff", "#87af00", "#87af5f", "#87af87", "#87afaf", "#87afd7", "#87afff", "#87d700", "#87d75f", "#87d787", "#87d7af", "#87d7d7", "#87d7ff", "#87ff00", "#87ff5f", "#87ff87", "#87ffaf", "#87ffd7", "#87ffff", "#af0000", "#af005f", "#af0087", "#af00af", "#af00d7", "#af00ff", "#af5f00", "#af5f5f", "#af5f87", "#af5faf", "#af5fd7", "#af5fff", "#af8700", "#af875f", "#af8787", "#af87af", "#af87d7", "#af87ff", "#afaf00", "#afaf5f", "#afaf87", "#afafaf", "#afafd7", "#afafff", "#afd700", "#afd75f", "#afd787", "#afd7af", "#afd7d7", "#afd7ff", "#afff00", "#afff5f", "#afff87", "#afffaf", "#afffd7", "#afffff", "#d70000", "#d7005f", "#d70087", "#d700af", "#d700d7", "#d700ff", "#d75f00", "#d75f5f", "#d75f87", "#d75faf", "#d75fd7", "#d75fff", "#d78700", "#d7875f", "#d78787", "#d787af", "#d787d7", "#d787ff", "#d7af00", "#d7af5f", "#d7af87", "#d7afaf", "#d7afd7", "#d7afff", "#d7d700", "#d7d75f", "#d7d787", "#d7d7af", "#d7d7d7", "#d7d7ff", "#d7ff00", "#d7ff5f", "#d7ff87", "#d7ffaf", "#d7ffd7", "#d7ffff", "#ff0000", "#ff005f", "#ff0087", "#ff00af", "#ff00d7", "#ff00ff", "#ff5f00", "#ff5f5f", "#ff5f87", "#ff5faf", "#ff5fd7", "#ff5fff", "#ff8700", "#ff875f", "#ff8787", "#ff87af", "#ff87d7", "#ff87ff", "#ffaf00", "#ffaf5f", "#ffaf87", "#ffafaf", "#ffafd7", "#ffafff", "#ffd700", "#ffd75f", "#ffd787", "#ffd7af", "#ffd7d7", "#ffd7ff", "#ffff00", "#ffff5f", "#ffff87", "#ffffaf", "#ffffd7", "#ffffff", "#080808", "#121212", "#1c1c1c", "#262626", "#303030", "#3a3a3a", "#444444", "#4e4e4e", "#585858", "#626262", "#6c6c6c", "#767676", "#808080", "#8a8a8a", "#949494", "#9e9e9e", "#a8a8a8", "#b2b2b2", "#bcbcbc", "#c6c6c6", "#d0d0d0", "#dadada", "#e4e4e4", "#eeeeee", } termenv-0.15.2/color.go000066400000000000000000000104471444632052500147370ustar00rootroot00000000000000package termenv import ( "errors" "fmt" "math" "strings" "github.com/lucasb-eyer/go-colorful" ) var ( // ErrInvalidColor gets returned when a color is invalid. ErrInvalidColor = errors.New("invalid color") ) // Foreground and Background sequence codes const ( Foreground = "38" Background = "48" ) // Color is an interface implemented by all colors that can be converted to an // ANSI sequence. type Color interface { // Sequence returns the ANSI Sequence for the color. Sequence(bg bool) string } // NoColor is a nop for terminals that don't support colors. type NoColor struct{} func (c NoColor) String() string { return "" } // ANSIColor is a color (0-15) as defined by the ANSI Standard. type ANSIColor int func (c ANSIColor) String() string { return ansiHex[c] } // ANSI256Color is a color (16-255) as defined by the ANSI Standard. type ANSI256Color int func (c ANSI256Color) String() string { return ansiHex[c] } // RGBColor is a hex-encoded color, e.g. "#abcdef". type RGBColor string // ConvertToRGB converts a Color to a colorful.Color. func ConvertToRGB(c Color) colorful.Color { var hex string switch v := c.(type) { case RGBColor: hex = string(v) case ANSIColor: hex = ansiHex[v] case ANSI256Color: hex = ansiHex[v] } ch, _ := colorful.Hex(hex) return ch } // Sequence returns the ANSI Sequence for the color. func (c NoColor) Sequence(_ bool) string { return "" } // Sequence returns the ANSI Sequence for the color. func (c ANSIColor) Sequence(bg bool) string { col := int(c) bgMod := func(c int) int { if bg { return c + 10 } return c } if col < 8 { return fmt.Sprintf("%d", bgMod(col)+30) } return fmt.Sprintf("%d", bgMod(col-8)+90) } // Sequence returns the ANSI Sequence for the color. func (c ANSI256Color) Sequence(bg bool) string { prefix := Foreground if bg { prefix = Background } return fmt.Sprintf("%s;5;%d", prefix, c) } // Sequence returns the ANSI Sequence for the color. func (c RGBColor) Sequence(bg bool) string { f, err := colorful.Hex(string(c)) if err != nil { return "" } prefix := Foreground if bg { prefix = Background } return fmt.Sprintf("%s;2;%d;%d;%d", prefix, uint8(f.R*255), uint8(f.G*255), uint8(f.B*255)) } func xTermColor(s string) (RGBColor, error) { if len(s) < 24 || len(s) > 25 { return RGBColor(""), ErrInvalidColor } switch { case strings.HasSuffix(s, string(BEL)): s = strings.TrimSuffix(s, string(BEL)) case strings.HasSuffix(s, string(ESC)): s = strings.TrimSuffix(s, string(ESC)) case strings.HasSuffix(s, ST): s = strings.TrimSuffix(s, ST) default: return RGBColor(""), ErrInvalidColor } s = s[4:] prefix := ";rgb:" if !strings.HasPrefix(s, prefix) { return RGBColor(""), ErrInvalidColor } s = strings.TrimPrefix(s, prefix) h := strings.Split(s, "/") hex := fmt.Sprintf("#%s%s%s", h[0][:2], h[1][:2], h[2][:2]) return RGBColor(hex), nil } func ansi256ToANSIColor(c ANSI256Color) ANSIColor { var r int md := math.MaxFloat64 h, _ := colorful.Hex(ansiHex[c]) for i := 0; i <= 15; i++ { hb, _ := colorful.Hex(ansiHex[i]) d := h.DistanceHSLuv(hb) if d < md { md = d r = i } } return ANSIColor(r) } func hexToANSI256Color(c colorful.Color) ANSI256Color { v2ci := func(v float64) int { if v < 48 { return 0 } if v < 115 { return 1 } return int((v - 35) / 40) } // Calculate the nearest 0-based color index at 16..231 r := v2ci(c.R * 255.0) // 0..5 each g := v2ci(c.G * 255.0) b := v2ci(c.B * 255.0) ci := 36*r + 6*g + b /* 0..215 */ // Calculate the represented colors back from the index i2cv := [6]int{0, 0x5f, 0x87, 0xaf, 0xd7, 0xff} cr := i2cv[r] // r/g/b, 0..255 each cg := i2cv[g] cb := i2cv[b] // Calculate the nearest 0-based gray index at 232..255 var grayIdx int average := (r + g + b) / 3 if average > 238 { grayIdx = 23 } else { grayIdx = (average - 3) / 10 // 0..23 } gv := 8 + 10*grayIdx // same value for r/g/b, 0..255 // Return the one which is nearer to the original input rgb value c2 := colorful.Color{R: float64(cr) / 255.0, G: float64(cg) / 255.0, B: float64(cb) / 255.0} g2 := colorful.Color{R: float64(gv) / 255.0, G: float64(gv) / 255.0, B: float64(gv) / 255.0} colorDist := c.DistanceHSLuv(c2) grayDist := c.DistanceHSLuv(g2) if colorDist <= grayDist { return ANSI256Color(16 + ci) } return ANSI256Color(232 + grayIdx) } termenv-0.15.2/color_test.go000066400000000000000000000020341444632052500157670ustar00rootroot00000000000000package termenv import "testing" func TestXTermColor(t *testing.T) { var tests = []struct { input string color RGBColor valid bool }{ { "\033]11;rgb:fafa/fafa/fafa\033", RGBColor("#fafafa"), true, }, { "\033]11;rgb:fafa/fafa/fafa\033\\", RGBColor("#fafafa"), true, }, { "\033]11;rgb:1212/3434/5656\a", RGBColor("#123456"), true, }, { "\033]11;foo:fafa/fafa/fafaZZ", "", false, }, { "\033]11;rgb:fafa/fafa", "", false, }, { "\033]11;rgb:fafa/fafa/fafaY", "", false, }, { "\033]11;rgb:fafa/fafa/fafaZZ", "", false, }, } for _, test := range tests { t.Run("", func(t *testing.T) { color, err := xTermColor(test.input) if err != nil && test.valid { t.Fatalf("unexpected error for input %q: %v", test.input, err) } if err == nil && !test.valid { t.Fatalf("expected error for input %v not found", test.input) } if color != test.color { t.Fatalf("wrong color returned, want %v, got %v", test.color, color) } }) } } termenv-0.15.2/constants_linux.go000066400000000000000000000001551444632052500170470ustar00rootroot00000000000000package termenv import "golang.org/x/sys/unix" const ( tcgetattr = unix.TCGETS tcsetattr = unix.TCSETS ) termenv-0.15.2/constants_solaris.go000066400000000000000000000001551444632052500173640ustar00rootroot00000000000000package termenv import "golang.org/x/sys/unix" const ( tcgetattr = unix.TCGETS tcsetattr = unix.TCSETS ) termenv-0.15.2/constants_unix.go000066400000000000000000000004431444632052500166730ustar00rootroot00000000000000//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && !solaris && !illumos // +build darwin dragonfly freebsd netbsd openbsd // +build !solaris // +build !illumos package termenv import "golang.org/x/sys/unix" const ( tcgetattr = unix.TIOCGETA tcsetattr = unix.TIOCSETA ) termenv-0.15.2/copy.go000066400000000000000000000014641444632052500145720ustar00rootroot00000000000000package termenv import ( "strings" "github.com/aymanbagabas/go-osc52/v2" ) // Copy copies text to clipboard using OSC 52 escape sequence. func (o Output) Copy(str string) { s := osc52.New(str) if strings.HasPrefix(o.environ.Getenv("TERM"), "screen") { s = s.Screen() } _, _ = s.WriteTo(o) } // CopyPrimary copies text to primary clipboard (X11) using OSC 52 escape // sequence. func (o Output) CopyPrimary(str string) { s := osc52.New(str).Primary() if strings.HasPrefix(o.environ.Getenv("TERM"), "screen") { s = s.Screen() } _, _ = s.WriteTo(o) } // Copy copies text to clipboard using OSC 52 escape sequence. func Copy(str string) { output.Copy(str) } // CopyPrimary copies text to primary clipboard (X11) using OSC 52 escape // sequence. func CopyPrimary(str string) { output.CopyPrimary(str) } termenv-0.15.2/examples/000077500000000000000000000000001444632052500151025ustar00rootroot00000000000000termenv-0.15.2/examples/color-chart/000077500000000000000000000000001444632052500173175ustar00rootroot00000000000000termenv-0.15.2/examples/color-chart/color-chart.png000066400000000000000000013101771444632052500222540ustar00rootroot00000000000000PNG  IHDR ogAMA a cHRMz&u0`:pQ<bKGD pHYs+tIME $+nnIDATx}\UGR+`"XQ `klXP`%&QEXMͦ'lz6mnw7{>s\~s~3̜9s3?OX}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇ>}CЇˏM4iğm֬))NR]']CuX:IS!+NR]&+[qGO'O9$A݊G\,)d|(q|9B1ћ^}G&8Ycʊ v+3r rB܊>a3򤼵R 19'88xG(7/]W|L|)]a!2vŷ#D>MX5k_] 3o] Hg>dMq Çs!/ǀs_l(cfJr<#YDr, <-W O'ʧSgYMI-9d\ޝ}H|k쥰Q<99u"_5kCF2p@u*P6a;D[@~ 3⩞ضy0sa˻ˆ!>|y\pm۶YHPa3Np_cfVY#w*/ [+Y+|w`_),=4PR8H\:~=Ⱥr_ w; g8r'U-Af|O#F ġ1#6F-$$XLM65[\ә.tALl̩S'۟_7nx*s<qɣrTlK {@|ߞ11Q7始9܇MTE d ~8Б L-&pW\pl؉\&oJGW??+V|;<%L{k__ G`O?4>7 Ǎ ;I7o}MVH]QwЧMĶ3<-zӟݺu%s'_}U£ݷG>_tKg}Fe_ݒ:Hl%"&-mĤI8ccO"[~6EK$  /Q !* nHG9D;*fM'.(Q`6ld\̨ 5Y8'.1ٓ(_ Փ?cDDs:vX {) qdԨϻcnݺ9y- ymb::u8o&$$X5Uh8[lwذ 5Û|s.t u=D2bHhȑӽhaq+?Xeg-?TU?}}38Blw˖lN0'Ɯ 9VU1 p詀LۅeC=u9:064B)  #h_w`(!'_JJgס!t+N2exN|R×˓ii#P.M}#GCųfͤ_zEA?4]veBڣGw| -Zn  ϘY0m}/Svwt#.Lmj2Uhf݅j$J*[(N8sϴkG> 5kZ z衿o~5kI>u}v&{p0UhRJWFEE:uJWBJ0؎̈́Dohh 6yYKaP,H] s+nPPY"ɻ2?L12@C.沀vK_Cv_nЈG_tٳ k۶A` W_}%ݱca23P(}] C~zʰ,--p!M|PYYq6선j~~'|B7Jm%Ѽ3mJMɟ':3~8\R)%7vh%9 [ JyH C͛8uev9jT 5X/FO6ծ]lEBfe)h"]ㄠ*[m3PGU0I3 o݇۩dE,5kw-{EIOXa^[TXXxU''Ɨڥ+}no4_9sdX>-S_gP1\:vPjuo歷.J8fРb\|KCz}o"V8fGU6RO"Qy0ӧ!gn/!Ȃ80g!.5}Õn_@a̰El+RYxe :ol`Ѻ)„(hɄ"f  3#J]>3S'v#YWlrY5kr }'zI!ꫯu',6m4A؋wQB0wx_x7:'Nߏ=RTt!=X|KJ>ϟG `iIy̒%(*^ң>*a(]IO?WeeS's=ośt" LTᇑdGZc:L“'O?䣏>2gNtcDQBձcC Ptȑzp{ ,j+Ԍc`v6̚fqzY8%٭$qQLlޙ,;DQ}13 pʒԱ.g?8jhѱzL@Dջ_݌LufÄ5kߵ9?{ӯ\d14!+..46Hwݵeۗ_~C(б5)AfϞEK 2w-fSB Rhe[n3UUUCz!.J3gpOmY aaDm:!44D`PP`z%۳P,KPMаP4-bX !f]sSTtj D`&W֭XTsX-bQׯ?j8 07v_`jCv޲5ںB#m柈Y>,(`1pl`Nq_3O5[I)\lFgAUW/Y';_PfQ^jn4F,˔`7/A]2J74 f,- >N')p ױ*z4k_x0>e,- qPhͬ.]0Pw,/{|żU*a=Jd{,pq?u]C>IKuL^T ,ǗqF7ݑ_5#{B)O˂ah 4Ec)hLY5 EW'cl PS2e˲nچ* mP Rl[W9GNBjH΢CnO5FaC*^ ? Ն[O4Qv MڙM5k_2>cXS y$ xSO1>^l\blȌ`0\-v蕦b6,r X3T10cx쾙38; "t\n2_Y%Ppi`yA4k_*{qج3#ͮy2íJYZ 5 e&;*fv`cA.$SIbRGplɾy;-+X 5-~uj^|ADg=93^wm4˟215kCJy"xG4-tPwp,sSٌ͜,ؘf\Dw~ 4 Ŭ#먑X5kKvLf*fQ'pӌp;GeOmѴ_Cd9`I~ʚ5k_CJy|7g>YɰT ۭ>2oB1gl7LBH5Q,ے oh4jd FLt~̐CMsP ԡ)=؁";jv25~I-(hWFE 5k_W3`Y 2OfiT?O%|lhX ½n0-` P BBW zX`9Q,п#GW;>Y49X|cf62YNY7z(F%5k.P%AONSaYqY0EU[f0[R+mkYnVUA), `j5[1٘9v8{um8 힙f!ӘCbI#P_`?5k_CY~0nfT1W 7PJ5۵UZXZ5,6yh5IoFePuA iBxDj4fAM7ՍN* 520,tgRX=ܨX5k_!OyG `|4Q7.(UnpNтkdf(s ~3m Zưga΃labm0mfϮ& f<"M4_3Qnżs,Wfj6_*xOcLqxcRm轨nTFfLM@?nn} ,Qg93X& ;Cqt\ez5k_urʳL\_K\h:&eAeVՄ v3Yj#{ݙjY zZ̠dL\ HCG9t1V8ku*HhUôf5k. eqbHbX7= DR(]`AY0X.tȑj%g2'UDv9Pcѱpd5[nQ{‚責k QN,9h1-[U%e1_5#{g#c!Լh8+ YWlh9*&@%lE pcjӡnqнebqX )2Xp251 ff  /Nz hQގʎL_5kWs<э 'TwոuW ϕe`! B"#(ge`y:Omq#q/bbp1b*P7T` \1˂YjjZ2`{ͳ'OMb THo1_5k=7T%j| ʮYplS4[  KƦRe3Xj`cK#"][45titsx(aM! \na8zddco 5^.{%&wsaMz2zػI߾|e67llR'^~lX||ŭ\ Cš]{q^nݻ/}N˖-kf>l'oV4YXS;Ƽ 9z̙333h7&@sR4W;$͈ '4)IԛlE^zuB3ow^>aPq/fފ&tQZɶӧmն}ٶ2m˖ړ3r6mlfONN > ]h1d@r5 v<ۼ=l=VVӭۆ;vmv*mضImt&іHmH$fVciLH[ʹc[ͶsMrٶr|[ɖړ#7n[vm ۾U[qDұqHZ56{R$'OW{ͱ|}5lm9-j}ʭJynv={$$J  ٳׯ'RXX(O6|jgbb"le6C<1)%6PѣWsrrY.HFlVm۶+WJeeY)i₂rrQ%%DZM.X^DhD?I E"YN ҢE $M"\ LVX2V(ih\mj[۶0Iڱ> *oUj*[q睶Gk/>7o;f۰Ȱ[v@r)۩hh [;T٪D`1۱ T)\n[~vN4t@vQQy  mm0{axSs|;RUa;Xj*Zi;bB%kي7laz`RZ5ڡ0q:=Q6lp =udoK1ir&L7nT/<tDopကҧmMokZӛy5԰{ml̘ت¨'"=sƜn^ܨΣ a-vUڷZ{HMGMH 40`Z~hϜ9<۶mK___yTo…t&&&cǎӦM [lym5۷Zaaa[OK,%Fb0iEEܹsZJonʔT \,-UXXȸqc.\pҥc.^|8 9snݚرÔ)SJ%0ZnEg:th?uq/AaǙ: pcvjCh%:V'OMH:ɢC M\mA-3 rB~+:w6~76nMd[va&VV--!~CyN:636emlmhٖ]]J N!Wi\d[b3s0t@lLqm$ۤ'l'ٺ5C$w]leض2>6SllJJە F xd?V~PJ۾EFtiHR6 k0`=rs0ɏaˆ;`hmA&bŜ2``P!wCl6sP*a&iIC1czRR'as)/#"1.zHI&ov[\I¾St%L6### hM^CݻhFj+VwաFϞ=)uY0lk<均Ї!\QѾ~4g~UmZgyi5v^mzN'eݶ*ٶl&j6&1.pQ"H(ܶU;t|/wlemUWlK+7ah5qlJrےV{֚qpҶ l0`agkxv?e X6CwGѨi鮰i8'xN&=2-h+c* BmӒMo~92'JO^QHay!BH ahup ]ꑇy5:)9siNV6; >=|xAˌpme%Fµ>-[8==z:lh+˗{{{:u̙ӓj6۴iP=rhjUPP L6/~Գ+=)/Xa@Y\zt˖Bչsd_:-Qi߾]bbm rrQ}]СkRsd%ΝEBB)H^aa46"͞=[HC )׼CSI)׶"Γ۾ŶTlU(mZ5nKpLvI$[;:жa: W)*v錡w|ٚn5 $'gfR@!Q FD>Eg|$H4D ,U\i0ar40rrĉ^͚ _\ynJrr`f&UbH_ߠɓNطЪ!4mO:uP=뛐 [&%% zÇw-==*əT4OՏɓOϵo߾9s]ríPy<]jdP԰KcVZEW9rPE ϟ?L%^ r!0Y!H*; %ZdKLV\)H1I@FJ …5$jhZ!Z7_;\AXXv S:,|0Ś*/Vz0/?e9s 7Wvn g37PwЊ3l0]tiܸqV6N~D|/Ѐo443;0ЙPj ߶̀w@o|i u$:9"UWrXIдiaVnǏ'&ę{!aZmF C:v0 /ʛN,,ӓ$@CPG7ptuGIgi&QG0jr-G6m*>Ϛ5sƍ{n8|0W/bܸT ٳ'-mj M0:1Bn#ivH$j%:0f.e4$9 /*sSFսEvKVVO\]Cں57-LqzZ@r5 ]i[Irm|z[eٲ#gC-6cl\OKjJp-{zi٘\C 5%fNfَ\5 ͻtl!O%jķehO!ei7ycsZZ5,Jۆ:=Q6lp9 ,$dd۴6lmf7#oL R(('7A_UTݍ!5^.ͷlCW4lCCC'~ٳk"NF@Iۍ,\H2%5ۗ,[C_Taݻ;`(ϐt̞=[iӦ|H*)):t ^ZϵpB:|P!w4T DQ2*XJ/"LN)S"O:+k6|޺uIcz׉SLKVD:u ٪4k,ZM<F^JJVUhJD5˨c> S'#ȅBǮ]UɦV…|xrmE5|v]V &0ɏˆkahoU ZɈsPzH:}w˗D xO->)ASX0%5^.ϢRƽ"$H5IIԡ?fĮ\ɵ}{õC;m Rv?3mqC]Udɮ=foXH.V/mc弳SɒR`?AjV #9=Q6lpRdɽ{KJn\FUI/FE԰{<|LyyDaasԍpuD:w.r~\)_]]}Ѣ˗/3҅ 򖕕~Ni(B:)I;%BbQq Å:zi*a08bx9` /RMtؗ KW^MQf2f..z_COPj5J|nxR4PWq-Ý(ڔ%L &T16X)b%H-/jjzHgDwJh&2q&*a*&Ds3{. %+ZJʂR)G0TP Cu0TP C7.G㎟&NԥEOAO4h6j||E?jja.z.\p̙ ,ps!$Rvv0̏F6#Å?HOX^z$ k{p904ی:U3CJGz[$5^7> ?+*;gou+o3>h_gcp@r9 7r!v22Jz?ح><ɵ0qm\ˉHGEc={N}ڛRuЌoG_}]$*G^ǎ&0GEEűcǞ}}Pj]t1y{{'%%9 4iRV٦Mg:2dȑ5`'V._?M?oo#ట=o#ccСZD#GRi^f _6q90tě#5=U/Ըooݝ;mKC[kL5~a~!)!1i1tw{5 戸{]$7i4y饡ƵD KI IK9pHB͉ ݿ&H #Fٴi\lx{bE%j'_ #6v$U}eq|^~~fc_XHHJLL=7G4cbݛr7FƎKC_r>vgHJC͉ }?6q@jؽ CGfӸoKM{&x#vH }饖JKBM ?6q@2BRRbҺ8VR`ow}^{|gN7xcȑTy饗ƍ?,,,%%%--7 . P~'7oѣ tMm۶CB^^^t9sҘ=0tMǎ喿֍Nݙ:ʄ[:wΈCҽ))5^+$^^ϿƎ-4ؠAn"5ht/KĀJ36vU:w!N$3c[B=&())6kz=u@j hGM,^"}}aޞ{肒^%NrԝbGQeK-qH"8ۺY'K" Mk ͉zlcv}4>1` !ڬuk?ԝ;cGJ-[22I^tfխd$Jʽ1G=۷GEEU: Cw9j(lٲ%##I{o֭G BR -Z҃8ߖ UZl9pz;LJJ H ^=046 }{gN=6vWj*UDEIR']BBBC$#i&10P p׺0:!]BD a0͜61GX܄8'_@RB=K Fs?99ԜQ԰{5 ~.]B >3fht4nT&G23hժSppQBes΢R 5:nLB1n"5 f~(qܧZn`hPֳi&&^R`hfwƍE ҬY6m6f<' 4U RlPP֭gjl޼wfĈ.'ju_\:u^R`w-J\OG~uf涙븷|lnݨO*?dpG;YˆjrM͝7H:n=f潿>}nL@Lݫa04--FVah$:zěo: C|9C}Bu?aJdCPg&ټwo#: zP0|N7ova0ᆪO?tvaP/AP֭U{A~; PFNyf!9pQ^J7( 1c=Oɾv%5ae(zҷFؙJZrR#]T;鮤Q15;{9x:Rݒv=I$zE] {Sܫ.J0/\c`/UӅS>ɾ}6w!IJ9Qo5b9Q!.JaAJ땭u7*-7?bM5/x+5ukIR]ꂡ׫y.!]>AUbUWRe ?db)}mnĻ]IwŜFӜ(԰{5E. M:ʕTq VRݒ%n$鮻FdJi$ u޷ݛ`%07۷oONVWZH%4bo:ٷo_o݀M"Dp/44MMM?3 @޽{A4țn~"2vXa9gr9 ުU|ӦM'7}̬]bh>1O1 ^[SR^6*O {w|:nI?Jٚ25^}qqƤy:t^Cw{w״qP͉ں55sxb~s>t[ahz?5kպ,'uwLLi' C9 H:lk ~{  ɮ]4ӝuy5-&*_aB͉ښ5s~s>ҍC>P@l?wu404/Of.D[fOtoͧ:"a?K/HPʙvޝFĤu73g: %3c5ʈo500MT _/;tX!tP*6;$/9u&Vvab`I_2?^ҍC<[7Q#"ɺu: 93&XD LLl3w.U }e+[ 0hnwBh9uMCV~0ƕ#&ݻwC322.\pر 9CaaaB.URRSO.H9&ff~?)4رtBO[$ӿDP'wnL.'6 ~^3r ՈH $ӿPPI7 ǽ%j0-nTBB2~OP>Vӧ'%0ox~"c?&%%v^x!$$'#""ԈHPzC{ʷiӆ>JO<9000>>V[/11ǍgJ#GzaG|[>;*wjGbZHMݢ0 ʹzaSCcу~Cu}!5~b0Bc!]BD=L:?)^=_>{ ?bTB5Bra^ژ{5>`*ƺt ~ȬTWٱ#`0 ̌s+t@zʜ{O9sl CG.$PM/%@ٯeqʰa:1t!ګH2)z$lڧ9D0 5 p]B?UW=6c>>E#u!Zay].)s8H9QzI=A/KQv󶡩;v1 DҐL9xis&l~0 ׯ_.]D~wy>sNŋcB0433Ś pQqyΚ5BD͘1ÙgCP{r9 }y8V͚=Z_wQbbvwJQQE]/ }|INv+a0T[i(3˼Y=L}LZL]uWա{]/ m̽C9HuݻReਢ? !}||}'IR`>4+۰#:ֵn3b݋԰^&$'V'af3+bҼ,^⌷6seQ]wSepE">`/_/{qIjo=04&-Fa̯({$0ޢOJJg7o~Qg[ZZݻ2xࢢ50TsgeeM4iٮ)9sЯ]uOrR_6ݴpwkt8'cz>7ac?p {?.~:W}"<˸qرxҘ7/ƛ#t|:WOr}`>tث"1|{W)چ^4Kfrc_bGf͚DJja.jahC$q=ajjU!PI?E.QQ: i0qL)9V /2qR)ˆb*y<)E\.'G\&%o.38QdW8rbV׈e.N#߂_|cb@|8?rW%)Q#kWp7r_zd׉`ؖH.rH_ˑľ^ɠr_;!9\Yy\p{ʖ0|Y`DVdoG|qG[mòdT905k_]4vsbw(׀-^~T)R9T2un_$I^A~*9Ņ%(c1$J~r LI!W p{s)9xTZ /SǨ@_)Ԉ'Ֆ #j_IOHC{]~~bZV?Tf".9cq*CrصgG[]&Z}JqP9O!ԱS. iG]ޘȷhY,"S[UQ̃pv5k_vF##%2%/^Pk[A#k4ANB;T%Fl"7_j ~x8 0 bՆg ͶlhbOl;_>2)|lM`T͢\V5k.{69ȌKBlrkrjgΠG>#E 3M 1!3]q `nv09?#-]pC:uUfkœ+‡f:̒ \P5`J#@>!ؓ~1 Y5k_?P4 Lx9*f ˶; J]ŁТw!t%~lhz¬Qf^Ϗb.Yzš`Ε7l3[I慇3%fڳSZmz.̐)4k_u'cЫ4-T8^ [J dz0Y,1>u%ИBȮ<ط nX#QAf߃ Q :Tu0R\䳠qL{tgk_OPe4e47 l"͐qve?6n`2Zm/}Ya 꺀[@Ae#60\^[}(\v5E6fB{|Rj2}Q%ZUe:S^9Յ`4k_*{"`d8#v!@^uca)T.W2C,ܨ;0MfVt, -˲Y;H3 oIԙac.q#a>qlτs˂8 +nE1'GywT ̈E|`jZBJ}Lx[a5k_] Ew]ŏ%`,x_gPL{5. Q4Y1H U,Ƙ̕m+n.6W`Y.5vV mgn^M ;?||< UlmeL9R&15k0UEj,Y9X2&WGeĘU۪iR f,ۿYw1~j\ՏϮ--Emq2b^ Z4 $bf c9X \) kfF d&{}5k_=anϋ[̲Y8Sg6,cU83E f T,ı 2wWŲGmLs>j窪Y2KB0"0!td_8Keul7O5z5kߣ}o<^ljgrodJ-&ԀF~e%dcV8XDx2-etpV-֌^_Mq\2Y^X5f9p?p-hygq? ǔk,3> JrߡeFR5C~i4}pTh7']V17%H цI E]ছzK07tm۷ghN<19=zt?QO꫄Gw-iҾ{3>}!Zf=Pcb6i$9h~cL2@ue4E&XHn6jGd X< ncA3yϖE CfV,]]l2kA_e˖cQQo8`@4nMgW%sT8p@z74| S]>ajT3""W^޽ e@>5ɸqcCBqeAGPQƍwů }v1ڋ'Sh-`_=1 (hޤXa $Q𘧂., zH@$b+ZDCe(@K)nE.gLKeW3A$S1Ő+E_C%,,=8@ ?9"y=R?PLV.)<߳gAz_әcǎB;vlxکSПɹs.:mT٪LJC )_o~PK/o.Q#Y:u0GgaTTL݆LqLb%PF{PNUa~ A 5kBW]=V\!gϞ ~ 6?x S\|˵kܼy@-sϝwYhx_N^tiҤI[o%׿6`g}z{=,>iӦRLk^|933"NHV_|!a(&@M8BEW-[Pꁐ\ytݻw+**lAl_CO<6W9sR@сR1ԇ~X$7w?OuW~-RS?#ҥKd0th'ܻwM<qq-z:~5fxԘ,[3129ڵg3angU 3gVlα#,3kP)x f[Ɣ8,aX.c 9#2-ʜdeIgYg| }ZL2P$z_)/gϞӱbr:W_ѿ@LE@y0B?tFh}Q޽vԩTw޽{Qo>k׭$);ٳh%Pfו5|'￟ӦM&B)O0n۩2n8! QQ0/*uhF{')^tM֭~4Ν<)$]Sj ]$G&ڪ3l۶hեK 50[oeNrGծ]֭[>:iSTU~~i0RB?љ 6Tv(Z'OO Ll3_sNB,IEU˃9?3,ٲbQ-Lfe`*pbXdl[pT$l8%(!bz1Of>p͂1 3&1Yՙ_3c _=g9 Svv@^P5|ؕbVJ2:P%$C1$O1)#FHtOK̓3-G%[ѐNI2|)O AX Oyt|[o%a(* +.JEX-tS~9h)Bo`J$_Q2V>AD+U}sРB#{Avٶm?/ U O3>^(ej$<5S<h؄'KsPb0lGT,wYq fOEQo!a+2Z;\AuEq32TZxw&&a>q`o$1P4ks ]t:!$$_22/ѿ^dd|(ڵK([JUW*`(݋( MI,n;wV"$vJu,[]vIj7կ%㏄'NȘ0a4D0ةtJ-yELYgttd,)/5&ɪucTI yq/L W4ے#UϞ=EmПuѼy3fƯ/.3NfP0O4G1`U(C, jd"wu6͉aa9~JdqnvY3ٰT+=gh4X:AR^́JH5{B)/`w8bbch;w94&ax~ٳy'|PpO<8 zU)?JP1/"v:wo TۡyПa8J [3zQDžVHCOq0!PLe+**N: ݆.^H&, ?0g0 Շ *.cǎ=.LqIIG}Dˑτމ'+DO<)ZQo0T∑;%(a=f;}YH3u/&Ɲ(E=[qGMdԤj,.[Xbt-TxzޗxXjuԈthŅ2 ǡˁ`$xL,!PؘP"f>Ō0j_ECo rS^ %FQԲe˗+Uy1G"`Snn.5Jy"@- ]v Q</I }7GgV'*^$`(yi/Hڼ/2CfT &&(|wݵA\IXPT^¾QQ{zץFntUeem+OLlذW^ر*kN$h˟d,/nYfCyΞ,KˡZ3uScY8mw,5S1Q|PU["6㺉KB1wKR% S,ɇc?(a5tӥ_=SwEl˂;oCF m޼9k@}ԳgV'AА~X컢#{R%͛8,, "b`Y.m8zIk"}h‚{ vmSu^\,(]|BMHBxWC C1ŵնϓ}&%u߿_q=aiǘ$eSQX Xp#BN$,0X>Y7KqgX??#&G_bFK,4#sE% fA?k_P)0PT5aLYhV mUhsbsC:Y(]$0 ۹2.63+5k_]w; EO~6̝ 9|8,$3yf8,UlqpB] gq-@m-c:LVUz \`QXbhٲ lJ %i4pY9Ia'.,2sWw{5k_ i(Δv}Л M=^w,fP;ԝw11CT\{!45BetdvE TXN[ڍ}D3cf&̘;mU/<*-~fmO5k.w; E903"fj8VSa1~LW,$u\(`gjM`o,@=jm׽g@ ˶,34fIfWSV Y:Ƣ}A-yYzeUk_ K>KlaOQU_53w; ς153xcϾF Z[qst`W(WW]X. Aalͤlx̔bp,mu6p >ՐjԴq#.lf辧.4,[@մoj;uRDFĨu5k_,F?3V!P2S WɢPZPAz>X?iE1$"_6lτfj"5cwcꎓQoeÇ#{;>)*n%L&Hnt:555ksh˶hQaq| e3e3-26 ^) `VlGhW R;Hfܸ hn:en7G\Y 0> &R, 2<^I}D&E\i5k_?CJyf$~kE`aX6lSf ÍscJo,7*Fo2ܘFCb>L"e0<3`A6H|M%B KSBa8ઇ2fz25&j2P )i'X0n4`Ȳ썲M3E15˷ƌQЋE|c(WȲV,c;-~̰&> 0suƆӎ4]uscNCԔj,zzY&= Æ\C_5kg, U7*zIq&ϸ)a ƶ&hT%N@cR)BRan*6L¬q/ F˲l"bq2T*},K:f@K7_5kWCкXNeOYfXDr]faXW,&ߨgGj+I1028`<YZ^7[Lq8 wTM#DprA@X^TKn;uZpөf^_,5kC01-| ݨZ)H̚m:Qف^]-j5|1wո+@Lbf+^c&l˅RwQc52̅%@d+&0;̩&&lReYVm Cd!6>Sh_=ᢤ:1dE 0K[yLˢd̐߀ڊůD3p, Q QƎ",̱\8\8rkd0Jdn4^a0.xHf_534Yc3Y4pÂJ0 }. W )0hX^d5aeUZׁޅ)Y-ca5Lk,Pa&)3c%?NfU, $6ec-.I_5kC,W ӊo73(fh4_h0?A {[!Gd_YWf~U#*3څgS j$ .zW5Vsp[Bh2Mj#w0cAXX SM!6>5k',F0d5%JKSj}Y2fbPЭ&`  l^m n8 s 5\_Samf9Lvj5f´H%-) hpQcGFfi0p b^vS>MG5k_C Z23X5~,vV,z={PeL+߰kE/Xd5hj]fYf'L,Քe,^h$i,^(315s̬O5k_CqC蛍.G ˬ(VvqkPjL_ۯK`7C.4,9 =M W즸C= F h߆`/mX ULCb_ "&#Qxh_=CiM4:; hXWEb԰g8lc{&hm@17jߵ,sd4)LuEïYԮ6[\Ì8hՎ ":6wf5k_=)s PlRiRwRAʾ[f9(^o/v1s]6Y rr΢tݮa5Sw?Zx4Aw9"CM^ {kF⺆ 1YJ\fN,B:]Dyx &_53<$AD-S+dmn\BWlxD>|3c>rezz>6q-i|6faØ.T e8gFFM :udž 50 iueduH'n;{2' G8yr/,w+##8QAܹgd#ׯߡMwQtu֬NIm7m2ԩ6' Q+=9Dr0>}yY.[v}042zD99s i ;@ҩaݴm j%HjFuPPUz՜ HɓKKܫǦLy.)Մ7rr6WduS>vzodݴ7T6<^o.'9}ܯ_m!Tlٓn)SKJ$!ዜߛwIĉ_uuM :u{6$N$5g㽠ol?De(-}bWIb a6NUF3"nCKggqg6?K : jU7BY2Nc$)%Sl{Q 9x^8Ν eQ=%S۷o?~x+W:S`W\)**ڶm[ee%A@:CѣWJaa!YtYq""Ҿ}$ѳju^Xh-$xgCStPp e^DZfl%:d_I#,5ߴ ]RrjT:#GίXQDqY{Ϝ,$`h˖ Fz.T Beڴn>>;rrNڴt`ܺu;?<+W_Jee5CXPg99Mtږ^ CW>~渷j*WToT*+mB`ȑj*{ڼ9SӡIbVe++..EF<Ɵ.hT2m3.JǏ?|yhȑWx@޽~';3gt<,G\rJeBA.'5oVI#wɓ>b.^TqsQ:~_jscNn;'ahXr?IR0#Xƽ{1;3g~%z+ŏ_0*TMCݓeeQЕ:E9(d]!Rs~FJ GfF<093%nŶL/X+4WeG5r!XKf)`qųyyyB)/K?~۷oU8q.XMmPϏNuj*zرɓ"D3gN֭L'ODjܹqt}vURMN:VB*%ZѽL՜9Y[ڡW(-v=&M斗WsF:r䖹s\TI ] ֙3wEGj,#*µ$qrرl4={NyS^QQ{^}6-e^ȑG=q钕* *+ 3gϜ0L6]NrfM,/8\ Bm3[ze#GVϝktF UX5:a(0DY+aMB8T۞=6Ozw gϗşϜlt9xG@M=r s>}TY𩲲B]N[>6Ϋ0Iw8񷞁]Ü޿ЦM9/su҃TYeeS Ŋf|7:l|Gs6 "Dݡ: ٵ exك4Y% SF@Ohɢ;pg F (tX#唹%\F,dfi'U&OuV:9kL[R3f9Yq 0*ӧߑd.=)**R C}SoaNc6H3K찦Ռ޽{effVb:ƩFs+][aСNv5aBA^a:mNiJ0bʔ퉉MC5š30pItNVo`qK,OpCP_P9r>E͙&L8&M;.C(ML,4g@zz9\NrrC[ķja3*]X+ 763.&XӴiCٰ&& 3Skzz9'ɑVha8`[WcGCCB:~+so5=ysoՄ 3 CM5 uСItggQʫСCg`hH7Ǐ?bū*y*ʄ {*Ӧ 5ggzl|ra(RWşjt0) (eAYKD[Ԑ8 ,S13ۙ fRV1,t{bqF{Žx⾁eiOqaPqF9wrfY],С=57o*++ɊkI_TIM =%RVlA"(H!%eҤ$e%Ք΢i)V 3n Cw:%-qqKfg u8{nJ"# ev R;HXfuב .Yr@i,1e]%.fuo~y}Tg>AD1xds6 $gkEG{ O'meee NjPgD3fX ךa%jΆ-۷?}pExѶw炡gx62Ms4H7~*;w>:{Q}q%M[o}Q]~T {< 2>UP趲3ލʜka(J[ABMIğx3Ld1hPR+GsFiUPa( ޗ C #=_XdfڽyZ^pE>/ZRשR\y*+{D4t9Jy7 bII4<jY1 a%H5i jp%Tp3yf;ˢٳ@j*y3l]?-wJCBiAX?oO^^]HU#X,EaEj!y'P"*VCɸWplBUB#69s!l'ęΔWe 5ĈHV<|Lwt44.cQQ^e O3Ӧ7thǎUۻt9@PSY×EywZakI ~4<Ǩ0To'lcG]X bDUW tK]-:t--q Pow֭{b_~D:w_;#;.]^%P(wr!TBܹ ;BL>u/dppK)߱nt'Bj+?.ӿw?#:ri(S3":_ [G ᚚ L/ DVV0'*UcB2X`hP@2yClw 0^ݻCQo>1b8Փ:;wnŊ(FZ)2e K|֬Y7ޅoW Ç8{qR'#Fzn2bݧՐi$:喁b%h%HPƏODa CSSP! WTtVԽjH>ϝ23 ,8m닑e譄 }w)+kOr99nY`hj*ኊ.7P#X)_ch[=xJ~s6 w!C8&MqRS_%1uAJIy]4dȋ_n0 ]q$9ӟ-/u74ysE'ݝEi7 5SS)Jbg*+*zB1ݒG0tOs6> l:dH,1u<&m(Q1Eȡ39"QB1!vCgwA8eUvޫ,q(b}|kh׋.,'(@\L`[Pm!Ąt館2lٲ%t ׉w[N<ر'c"QV={62)%)+k6 J[Lπٳg<|)!^CCW2a1t۶հcUWUYO>eqΟsyۛ^üy[^?++ r"#81t|۶ հԛjd6>H?p!m =CM o%)?nو&ͷm=ڪa>}ӧ@ lCXM'EO҇(FjE ̈́ m־]K{а ؽ6\7tM}07 >1E }~#bmύ־s6>n%EDr4D.JjՒy3 %-bUM38+OsbՅbvu4UXa <)_W,|(FHHS:GGG"nWVDD4ONNPO%**sHӟ͇VɝԴ2FNg"ńT"##:ѽX(]p )8pmppIڷ_#()m}]a`}<@rݒP> *1*>tK`gp$__Gމ dzp-~/R]~o? $׍ױ=jyt]Ÿodzy9TL5rɀ<4P? <̨ sp; Ep-nVذX.Sxȑ,B_W@eEL,Z30jŒǜԘ,,uqgŝ]]Y~}ja6 q*?Rc6G,&d#1?l”yyñY @4TҘA $1+ܐ1ÀfB#E C5 EP Cb &İDfe=%j{XGɥ4TE㹜,1 aނi1E,>6"`EbTcF(вLȬѾ ̙ԓ@bNjDKKC5 0T C5 _ CU51rbt$;FcGz#a2$f։P,Z>Q@ƬP0TwٺlŝJwwuqgIgDpJ,<3FɮQs,&F)bὙ1JQ(!TmaY:E>󲗀.IcV Rkaha8YT? ޘb ݽ5΢%fD[R&ĸ,)BULLNUub TYtB+ PQ0ܞPzp<+P1(e}Cf.^RÊOOdN"9.! Bo?"oDdܫQ0 %Ο|BB:Ȝ9s丄,XÆyyɫVU`VB oΎ"9.! vphDޑUw۟6_HUcs}$%dAU yUVjj6oE ~+2MdCyHKȂoxiDWjk_I]C.t7t>Y?D|7"9.! 0y'.!90ȒYs9Ru)3dY$C39<Ò*!c=~gޙ5#Cib' հ(DA,^ hWn, ClSrDN;yÜ![\*Wxd^tUE.;m}KS}7)shM/&uy,Ć1PQu弒85vΎNUXUܢ3ݞ\:,>M0tVkɅkͧ[۰4lmr6TSGᛍ>9WcH#fqՅ sjz'Gxl}WaԎ+_+<мW5'mǨ~k<.9| =ylRiltKy ſPsx6<~ ~Ʌ\_$_W>Nv&%/PO7yQCǜÇ&u ټoaPsO,*^"գ+@/(at4`W){l2)aiBNa}*To(T*SwLpd8IVMgQ]t4qijO,KKdrzѣSoOZ2aҜBs ҠiS.iyyNvQPɄSwp$%@g hϵ^m^oY|^K˽=ٰV.-4ieaҽ9=Ȯ)8~ji(8@Swn8rN$HjaiP4q۱+m8$ nN^Jc I7ڢ+UYOR7Bv h֤U Kr dUL#lM& zUJԜ|9zIcj{l@zǦl.i K)|ڜW)2uZZֹo8mFo7*Sw<* %HZme[s_4qo^~߆eɺF\:ysye9>_.;`=G7e{I+?IXEN Yq P;mF70t6yI$Hj{AߦٜKg/?#ɺF\:y?eg #ّ_fF]ș'Мy2"2)fr5JD_!Q"dPZdC8#ABkAal/[shMzKޱ¯k+:{*Trl?qA^yѲ]'گ066LBumeۚCPkXyǪ3 keK."3  #n_.:[M*Q9 nZom5eg\ CQNZs ? {(U ?*%,ċg~zIC eڽKܒ7=DGB%*MIm2^|o# ~&&5G5^Q/k3s8mޱ2 DIYcJ.F"3Om(~^P‹v =r'B%*ߍ!9Pʣ%шQf.A):Hb3t1P"CF jsȘ}BO#H }e!YMfc牙2TD2\_^zI-/ͧrRi$GGYQ{f|F4t@0咖2VZ]|BUL1t|yQzo"#a [ ʕgRj%LI¸GΟ_QTDXsYY{|Y4t@U>t t;PcGcZExy3$ [;<+Ug/QZM*q aͽ/ygm{JIЖ& VW.TTBeڎRAZZ+ Z,\e=tܶrZsUTTU?kT*6”T!{|"k=mΪk=s&: 9Cm*lt;P޲0wNʮktE5g`>Y$.#bћ4[V~TTOͩRi0%U9' k=kw>}򃢡-Pfk0COBt;PYAj u'/>Tx0tqSe{Exˋ^S/.|z-:TT=T>@*qlEk5~;o+IЖK$0{CBt;P!UTI!,f%9IMeDA,曨Võy8Fr\h-^QbDx*R* d`h5]i_sm"ai:-#{U[Xv*TUX+fM]Z* *I`L{t= [ah5k9\''L۹aٳI Λ7r˖{\}ʮ\ V]ee8$9 {E)˞SɆr+ 9E̝ͻ豈kЦvrt*TYTٕ*P!YaDt}(8fΡaD0&:ZR*t=.Q9{NM;c-ˮi2wgyc]XՆsovtMf=K6,g%H*1+s{sH甍N\IfNVn]׼bNK/Ti|8pc鼷Gnya-U{TB79|#`(Lc'eϩ_' eM^* m2ЮkaN߹+"8X`yߍ{޺T U}ٕB fލ9_dќCCD}plM.{N=cw< #مbC]2<ЊeCQ#s@"bk*Yl))\]]gVLSY*Ěax,G+ot xE+dL(WGi;IPM>%qy"URפ H԰NW'bI%~9 `hȂW(Ν'O8{\֞=Nr3 C JPsmO\|54p|$ji+VmdɒP/lX+АWQhuE/U6y*ʄcyҴǥa(PsKsx =Ĝ]H԰+m%Ou^;gZBG_"ɮZm _04d! ]QT@ljjrP`3 C5 %jΡ5q՜Ckz~9H cjk]W\DCCuE5XPV}{^N²7\~P J 3 C5 N\79|5=ysv@Vv-~}^zCw|* w叮(zU% a|dW WBXi;k C s^9gz~D ;Wm%0o3+ KZr$(*% λo^ٕ2 ^.JJ Ϝa!X{wٕ+*ZYb%aR\ K w}C$VM?{zeZF+9_x"B?{I+U9*I/VLxɅ+$ynEC$V0ꅡ* >"&,Ka(aļ3Վ1Z^Ii3gJRZr:ה$;+5@a W7_X꽧i(aļyB:q /t5qD8Uh_$,5\K.<[UJweWjp+AcNumS9 MXɽ/F+y̓,( uʇ+V~AԒ -2| Jw[eW X! ?4sY#\CD60%!ԡ]P4h9qL1<&RbY& 0^±1SzC3@+_]: ]# .;a(a$LbaOێDhdh^hRIfnQv:cByfFW[bUhYʔ1N&FK=eb7R0I%qyb$%s[@uvN[_I)Sh9zhBCB>Kړ*pXtƁІ07Y#J4wϞkeg-X0lJhfn۶aADIY| s\%eٓjŋEdӁ7 (009 J}v=ʝ vlU:[ w!sx^R֞ɫh#+v}"ۆn3~s!4,vk5 w(3`wazN=*dvLGIB41,J(Mjp"V Z'ф;U3x<QB,Ó2#Q/#nJvu"E_>:'#^n`j:7d ??qr6u"-jbEtNܨa7%p cRĢ=WF~BysU"U_aι&}#KUVI Gމ d?,xU;qf(%'Il_o^K~/R]~&.,8[Ij`,,:Z[ J='Cq nJ@pd֐j%v%D硺9ȣ^´L@ť̮@ 2@n{ 8Fg`/T.,?D+CtG5ZOb"fżdI;ո̎BAmG*zA26sRS"_ZB& qn9+lE,XcP ahahzUfbF"ΰM$DQ"˓l9< Cj~5@ ŒCaݒ Wa(ĸ,s§cѯP>-ahahz\+TmY 1_]QV3B)bMs&3)%Ϲe7TeS RK nr߮԰r﷖Y>R 5.ˌ K1ˢgPԡ'=,bztݝQ萎PnO, 'X,=K1ƣgd7 2ڢrܙY %4{E[`Cqݨ04bn,XVZ,~Fo)+k!Nw;* f\=IdeNZRKhquu;rS/2l%_INl:k3Ϝí+G3[[n6Ҭ*=ltR~-~2j9[B!ṖE-+fGv:l%exI^ƙM`Iԕ1-y/BMLCԐf6B@j0VS[2[bYeszK'[FteTmdԜ$Hj˦YsX$*KXl!Ͳe!T{5 ڲG;#t@R )-dģv &AWXQb0~>Kj:b.>,'HSQ-Zy9lОUͼ  , vm\vX5bitMHD72%-: 99$,jܽ\Cͺ`ֶখk,]8m8>R%1Vث!yȯe%U$MLm H;.5ѕT %iwl%&̨PY7C ^,mjlٲP[:v4 UkE:t@ڴ99Ҫ;.5wѢFrmhBGK5u}1,],]7 2rQRk%<LEHUε='di1' -r- <ꠁz0*T֕x64kr۵Nphgxǐ2 wjllIV?jӫ[-۹+՞e˔ݖ{^:nVЄ㯛[F2*CjeXk_ 6nilNU?жdKLBe݇PkDGx ^1ߺRث,]ؕEBeK=ޡ5*rçF=Yy4'E-ki(M,-)B@6xkw1T74htDKt[MέNDg,Nc0va(kV%.[ 5oE7o`Jls5{7Kε :έ.Dv>  U \?!  soβ^ 1Dr` I轄E q6_BY>F ݘXPsHřD+U~O`|9W\gZvX2LewseN-xӦYo>¦ұZz: 93K% 4^nG;fM,R;4~uu2aIIF'TB`u.|qx.iD)voܛwtK?z" aT"=)?jX֮9IP[-׼b!4١R^ex}'U4kfTtСtnX Dnܰ`ݺҤ%-LZ m6=ʩм,T?ҀTB`߭ ѣ1 m1$H1csocn-4ifIyIl©؄ƖC [jKt 4׍z{2~e`ſQYQBrB˺9shz: {ܰ>ư <ް`I%mUuXKCOTr 2,YZ򾰌/ \e4*X*1 ze_9|жshz: @3J {󶆑4 mi }MhxPȉ`6RX X(ed9jbw`$&E^ϳhFBhD ĢFoET #A6E=%LLWLM:3 frŒkVMe=D~tC>zTCٳ5Rf:^T0F6~a(P㹺[rkLM6ĤGG)6A ^)bI0M0Q(x L7\NPXV*f2ج@K>&\ovVəa%K&e\,P]\>CBM5︟ v- Hі]pv5p\c *EH7u4b=Z me _ vnPQbӧOɭ7_eWze*CO*n6*"dn0` UjJ7Qo@+*SfgM%!,6De ՗UgW=t{ӽy csv^HgPL"’dhɓrx.\:Or7 #򒜢׼( %(FQ5a̗'PE p^zLe 4dk'eЍ*LͮSx3KzK6ur14|<Eh]NUk 5i%.T C؍,/w՘դ=A9?VWSQm\Rb+[z[Í)1XPRO~778 kG꺑逘;e5f9YS >C'(Ls($ie)(O ndy?`Y9:T 3>~ 2z΢bЃߛP%]( eDJ6*;#St ^7|^]p-TZdY= |PVDU\6Ja ^&J !V.T8ٍ,?LxxSOc(dylXZm .W{kUAyanq*^/)~9Cy^;iJ[q ?/號P|p/zDLZ8My{TΏy ׍UWR?Vyi^'V.  v2TuK{ܫڤ3(w&RT握J;SqOq aD{%N`bƕU MNLrx@HKI*GjV2ae>.i{[B 7 @GǓ)C'LWG0'Y]MM49X~ CMMGBGm7ř>/*u&#mcV'`Q:=U"iG֊z" K.s˟]o0'> aC}EDEt\'(\E~j,4PNc1g_HE!x(R16DOQθk7O)ě7xO/ENQrH+V(:珟DWi"%C9,K2nsrJ\9sϠϽѢhTӿ|P0ԇ> C'}J9r8 | ۇIg&/Oy#M^)\Y?d^+Twz r>`X5.Z7>pn"Yg'2jzekì\!a8Ϯ\:X 30Cpn߸G=pi3Hw(Y{ؽ6vן;_Kf?^ }q8wnE8{}vb*s9vaʬkì_sqz·U!:{8.\ǨMg415~6~NXy=fnDP>i;OH]+⠜?GL^_D ÓѮ:jT[cl w <7ܠwMoUtrwZhUHJ{8=7ZRҥfMCw_nS{MesixM&C:wr@ EDR?kp^\\ sB \zKT[I w}ئj_wXszokzʛh0p;mIicSZR2GSD48ũɳpx;Wxu'=E޽8:My"X>I@*7 %Q U]G<ǟo6Ć38OCKFVw7.HbD~U:LׯVL9_BO*yjlhNXsw* T@ys%,QRDNLP#RULZ>RaDU }v5$òl;AԐ[dȌA?1%.Y!9 "֜YaU>hMT;$/"!5G5բ,npWMfyC8bZ j)-pv[퇹Hi:)qKh0{EmD~1at~vM>r8@[fSD!9yy?E)J>KB$BRR\[8w% LS39,sjyX&;&@^DDP`ٳ6բE1<J_5*>6$$qE7ͲkAk\X8 ̭& <P|\z3`I;B 9]5LHmjKHR/Tcx$-McOqqI039AJ(='HHx-$7g.!sHB bJ\ xĸ1I&ÒZ\Tcx -CפGƔ Gt^dpFHCDrKF(d,)RNS8.[.vXrϥyͫDcmQM;o Wb'֫)!jШqK Z@K2Qݯ4O)֬w\Q9qœLn-/aH8r>e'9+8-]yrWCkw1(}Epz6:R I&*@>%Rc}âJN|t0t ìTr+>tb!q-²(2 ^Dr}5>E֌^Бf."uSpΓNMd(hQ{$~|GpU*9?T 6qByE̙#_CwcB e14o>d΅0heOT_4q3lǣ/_ ԖV E =%C=JyppUS~h}s⍝3SdpϫH(,/y}$N8>y1QcP* ‹Nu*RS<'S~\#k}0? Tc~Dmc*719Y n;*7Yw+Zݐ&*D 0ݥ7trkyPN #h3.Y!%6:4J&ݣUi:<c"h>4]bJYC`FCZ? ʕN U7r)<@sBs3 pbg' QH.ϳw.OrdA:d {@9Y^=kt~wPG1Δ__#xdV vB$j{=>GJ{}3_Հ@ {s }F+HF +QM͡?TX $h@]7[xGp}:oJ4@D-NO\K{ODBu柡`!=Ft:PN"# Xeҍx fnB^]g8~B- >EZNEP^|h,%}x(ωSB >%VoX@|BR1:\D*aaw>8Ic) s[ˮTy*鑱KUK ZNQ*ct*ĸXT%jTi"mO }Z&*d锥}\:& Ƈz E骣ctmMںj]+mѧ%,vv&OSxuDeBX,̢,%r p!"`zf ~v;=ޮ)-_Eg?c[xv5apil))tP &*dB7>.]J.rrԵѵqHAZN5O"m;zIiӔL:^oDlae)ivP9^JVo_A C?csߔKh=W$G|âxv5ap]&eOSrxu;ѭ6D,[XGYJǥ7׹HN;4Q+(G>^xO"8ÉXRGp=?6Kй/4i]#wD-T͓_(q ~B0a,_眪ܤj#G USx%-X{XQ'sUc LCS: epbQBK L=e'؊:B5P2Aƴ zC=ǂ t5Ŕ ‰p18PQ22nwFB5(qj:dLw(bh|Y^8:` D#B͝鎜8A0sp(M L;YMTR(('70@NG 1jWo&߭ҡ'ށJ:JY6Lb3Dn! 9kexiC[o3jchr:?WO#tsiīE}PWDZ4y2_m+d אBɜ ES T''sHMo?MqG#tJuZ's'oi:a0(`3E1HnHV=wzVU51ŝՁu܏ ~GQ*osC >vDVɭq m- .JḞ^HzSukcCK&A`J5pB^K]SC#[ s .~j0iT~MzС5pN}0y6C*SV2Oյ*+ >uv|qQUE&֒pJlѨpv%ojQ@TϨ([w AuT\tkokUV|)BۑŹ8"~RyνḞT<'<׸68#iZAu1 ߩkUV|-Bۑ[ɷOC{6k m)JHEuU|w:  }4X4Hyg~g|-0AujOn\UYedmG$j\džr^䥑85t^CTDgKuS1KQU݁"SGF5yno ^IΎR޼<zd-?9H7osRlL%.Y=vO@uauy=5?yzo޿@uyRM_- .KOyk8Iy=yqJBz .\s]d<~({*ڵ{RjlOƆī>q&<7\4`KfaC}^/~`;QRt^Cy"Rw$Q IVN= aO|7"-F4x 5pynnÍE79xhF{GR@_yp- f~?x0QZUԐC}=7O)}My'ޔ{"aC}^/;xksN8q~g88_iܕh)jʦ_dMxΎAEI%D*8{?z%Ġ;k8?Uk}10oJ+|gp'?6 }0Oz^o11.g]cdᥳSr3Opj7ܱ8^ /o=1.g^tr>z//?MLKXS'^QDt~,nWɝ{Uu$O18\˸Cs0ͳyxFY<ӟ'c$>/ `m~SxQ'_{Ou_Q9s/j@5F7k_T͊Wg͵.3=1+0-rϷAR,L/"5B3,K_?Z 8.H]}Bj|.Mѡ|U$%AJTɭ0[` EDRkW;wε(Ϝӧ|YЪ:HJ !6N_տkG~ӵC.J5KL#GE#~=vl*? D gߒH!fgBy{_U/x]>6(@%@#v71`*v׺p $ڄ'y-o`ZL }scOkS& SD5}!-N~<ݵ \;`(uPԺ|1(.ʙ7Cu#*vAn6;ɽޘX>ǵ pj5W:`(?@y]$J]sĆe5nѭk\iIvςծU(W0ŻFGs3[cE/&m4@УGD.$v~NHK޳}χ]P\SIxUrQ}k =z*CC NOAZKaykʕOuP.T5v6Bv! Ps*%# F+E$N·jL ӽ{] q!t.0+Y6J/T'@^, )q2}fa'6D^H',I -uQ~(!;>BM^Wb>Mb(wmzIp % (^FY8͇ki]m; =>"G&EYo] qnCYW0g!92uA^& )q%H%Ě`x/&%͛C3SIU|k*T^^ BOWH )hvnTd7s>)< j` D7/oV{ܥ*dDF^4OVk+CD0쨷_nl.;}4 ~u9ڴFZm$g]#"7ra'zBCh0HDLK |XtpO{LThh|JC< ac~|5ٹ9S)##6&ir*o  7@h( !:( |3|S'w)JH2Q\h|J5+;vدLn70FHN`W4NMKDLK0ܼ/jߡ{CdB#TƧSe+Q:Ν;n윷xcySux QO6ݨBӒ&#Ƴo/~i7eSV\ W1ƣ)xu*Q:Δ  lnQA%Sݰ `lf&׊Ȍ';Qo_ZЇC|(1 dW`3 E *-)kLEyH!y+Ý`|oدyC=|Lemh7(GG! m8>eo }{E|лN]')CCioWDyH7SQR"lxr =6^PǾ{D"ȏrXL^Whb.*73xNgt" J.gPRy r@4|,\l,MϽзRNsm Xs .jPV ~x*+F -ˈr'^cз 5N,k_#~NG|ଵ4J s)ޫhkϝX`_14іT޵yз@48k?6b(37,(_AG}8(ˀiU2)(/LaBv/ƍZaˈҥEC<@+渞Y })HMA:]:KLDص4@DmP qûVi5S]yFmVh܈y(]z 0 _*<Cz RS Κ&*t/}Vڵ4HSI&Vio~ꏁƍ@YZjˈݜq }Ḧ́ϵ }C:^:Ku+ 4Id$?6Qh܈(ob(w nOTk)A"T"n<^(P∜x*Z@TN"Ɉß=?i"@J5W$/":9ļ1TG6m,~dĄX>9tEsL[$/l'mZ-'=3vdMOu(v;d E㴽C,D.fyCW^޼LD̈́G;y] u Hd.L!i㩮^T{CF>6jtcR+b }\˳IL GT&##xv0xҦr33 sGFȬ6q<իj{GP~wCI8>6 SuzC_I2|CiXfE']&*$T-tU;ٟ,1Ŭ?pOC_wtڥr&qfC1N3)>lpߋHO zbVxv_ټC89*ޮK?8h ϢKϜ0wG5^ 1+84Q!j(7(f:t(:5+pv$7a23p;4EO~GAʲa"~/.;#MTHZ|v?mn4.Y }WT]8}Yy3R;G_&k"#W]&*$T-tU{iCoA iWa(w4Lpӱ9و$]*'ѢgAі{RŨW=ߝ6>'υEv+*Ӓ84IFE'8L=N5>㆑QebDA9YW(06T[W%HZ (; 87) jf.JPzl3,sj*i+kTU{hN=ϵjC9YT[d'*Yo=E@|yd>%6>ɻ;wRu$-0tJcąwzgθVm@N'֭29sxX>fy8q?ok? 3 TCWv9Dw*g]6 'WILQBD02a֜Y>\7}xS(.DE֋h.(Dy@94p~.:szQQS{/vΎy*^eITb s؅'X&5 YIh0ԇ>aC_ . sm@9 (&pQS$g&ל2H"FgbRϣ7d/𼠕gx71M0ԇ>aC}^/g#>w ~չVߋ*ExQw~]Ĥr楋xod,z(X]x$w[<(c5S'>'ޓxSěr'ޔ}MO'jF䕉8)D1) ncSJaM)8@2inϣA=?ECyY~P[iҢͩ~C}0ԇ>a"'wrNA"ED#wFRH?AYLptUQP9UeV)w,+oăDCT+Zo+]ڳ}17Ci*_ޛWUTMzO.e~Z=1ʯ:|-8L`{/G=fMb鎉P~}[ Wֻ{", EӳS<<>^9>L`/W/ޞ k)PiYx/~T(5QsU3kKzLX&^R^&VEJShCmtkwr9C(Z@)߹R47"XdGZQJ\#x"Njv4UMko4mYdSLT(?UrO5鵼?`(f ɍvۭИJ7-~l-١ P~1)pʵJpנ70G;!>ۯ1\'g?Vh̥~lDa 姷ALI8ZeIc((ʰ_)XV4: N2qڪn"S!pZ)&*>10'KZwU&2Y{BtuQBٷhh[A~uD5g6/SUj1 Iqsgz CpUHM}mhlo@[ٳaOJ=́z8uʻ*J&> ʁW7B$+$:`Pgɳy%&C 7VEl?7ͳ.J%u4w o/Ѫuu/}'OnZ;ФG:."+S-n49#gk9U]Zк+/KTzcNC ) EDR?JJ*Mҳ}l-evנ70. R #~D#aaxq :w&GCEDRO}j׺Virt%=GNr2yt]+u +~WZ;arjEDRcpߍjow=Ge2͚, p]rզB#^W>BP޹µAk ){N2Q98/R]!!ص̘A-ϟ'G@g"")>7Zѣ}d-yCPQ\WhqxLQ;;0f͋x^PI$ӋQ+Q>)v< 8EXN~.9u#Y\zVu*CoHIlP}25=Ru^,pCCjs7T[Kz'9M.y76} Yv+tתfBa P~Z:޻3yڐ 3[&]8FOCVKSckw΅$|kffw1&X<nw1ecM.w`C)9b[ed',viT\0(?ص ?,c(2Sէ:!+͎wб] [iPWeP4QPM˵ 忮I'ᷯ:`(7/?OxCƜG(,:Xb@-Oqu_>YYv+-ת (?T(sd^ؐ]E>^yN\^_$<馮c wDZ p2%!j2ՁT >QWW-IcMT=D PZfʉrmW,$$ci`'VȎYĚqW+l'6D5E1CŮUsQCi2!1n z\~X6$$i` #eĚ3(jsK-y"&:4 !8@9̵͇WΉnl$F0Ϗm#K =_esIB8@bJ|x flsĸI1&EJh(\IU|< /κ% }*;F + ar[+$$h` "4Q 6ӡyL$ʡMU;0+㠦R$99^ 0hT?~=j_e$!!ԡ 1%>adXWزlMTKh(yK5~?>槽F&MN sk52ENcxldgy=Sc9!>EO5ƭ[!A92L<֖?(oZƓ/$|1`  ZLs;\lU)C;EY{GXJ45oEe-bhL^`cM_CD`sհi   "fp+RF^*!D |Q*|Z+,BEݙ / lL1 c(~a`S Ć38-٭pM&hj^Eyxw1lo"\YB`gnOÎVF2D 2/=iUBJ45/NUhG؃\5׻ % PQ]`Ms&|CiibiibZhj\:UE߽FN5#*ڷ7BE#|sc`& "fp0Qy:=T I&*MԼyjo(w:Jha!W%~:'([Y`(b( EMD{xL5i uuC?{C| ':fٜ/%&~)'G(큡pwPfIc&?>CޞZX1`&?(_u/iH\V|҆_wm.P5Q MOoLOvF! ~m/bG~P֭S{yɓÇ큡TnT^zho>0HN/Wtz2U?cQT$#2D4MxW).|: F|D=ͨDCTgt]bG Y泏{TvtV5J_e>?)ZS伡ײ0!ȌOޝbhm-ȝt~k> 'BYYa\*DLJڅjrC+EO5~p2cj7UG'ڙ$t؇{1 J&Y`*D{x *.TPw6ÖG% )LǶ> |eʧA\$ܸHe~k3 N &=hYa?Rt?w鄺},S%z.长ofG_DG[4_?paZO֣'WZ[jˣM~99>y яӲeu+ p4IkD{ODBu`n4: 2/cos/ /M4d灕"PR8ߍF1@K$ʠ<ɷETwZ5wO|^{z~GM,8ו6 `|Z_N*m5Q]7Wa赬) :-I\0,KvB[-tN0xYF#"o/&kPdP|)ܬ7&qa8D7өMkpFj$w>xw;ibpr≀/&aˇoc3E gY7~!zarj. F:jSJ P8I!J+jMTP$BR>ްPd<8+ ֨rdނ#bzt$h ˵&JqFW${ߔ E-.J ,F 1xyYuJ /VW۝&I`;CzCux~AZ/r2ih &/iL47< 1<،YE:/(ϣN/Y[;}? ]ġ*6*F7|`X`hiŦn&ײ(>)o}#)U3l]o7G\B^K]& o'! >IQiP+q|uU]>۵4<u:N&>ާZ59o#}ƇS>TvQ?y1 .qm3ðUQMWVMC˲1>xȦ} F*WO_{lo?^ awW>gvRu$-0kĠ˵&6kdV`e]vB 'agڗ^"A(,,?Ѕ|U rP}[r4w><3[ 52Qds"OE<(on꤬=Z '&B+[>N }.BO+=~Ro.ىs79)ko T{{UMC8$O#SK(~м,( :"[(^y[Pd'Wg8)k?A&zhX .*CQfW.{CNrxSN,^ @8x]uj2An?]TMƩiM^iػ(eLV㞧X W^IF8XɃkErV׹XISR OЁ6J* -NP1)x~?1$_{Ϻ(EZyP u T{O[wSч61$(Guiz/Tgߠ%[OM z|h KVWxM\{:="=S}"Dό9po87%By{<]85f 'qOc' /ʋC)OyjGj}';MrZJ*P|0)}Mo>'Oceq5EE>;AaCn"- C:?潈gy#bbE'O \ ?H3ֹ,yU^Mo2Oޞ\iSqg͋bXP0ԇ> C}7T'~n>HU9>~?"'D(꽋|&B$Z=&L"G$EIsp=KE+)6Ȝwy ,G"TDA wxBG|E7O)}My'ӽ("]%'AϏux(\<9HMQ^C); ŏqxl$<<ρӹq6PYjU:y)m90'> aC}ESP筃8q'KN<9]$;9׊x~v2E(;j̠ס;syFo /ӽ(*Ji>:7P7:^XlUS0 S|_uP0 @jXmbZch?յa8{V)&*+끽xC5u66:0\쁳Y֚b KVxw [jFx_ m.+l=ah?7+0~db21h"KOQy#^I9Ƃ2dDR}!_+q"hX,W%u1KS~E)V\TUcTxͶA r-M~V]UqUJP8 wjjNz)oZS!Мi.Ҥ b Ĥ@JTב-j?!_7QMz-bh%4[ t`7 [S!Ͱ) \ nË19UТ_Q{hMTyP@<BPѐ% 52@BRZT(A3L?n-)PZk뵰BpBusg1Z kW3?!j[f[ዩp! J|/XPpԢ*ǧ̀Ygơ'#fz C+^ ?ASBPEw̶۩5ir-M9)P_pB-q#~>Deb\eI4#(LrYU\EJQ1_W xzi",+Q+ϲ<-Ihk'Ģ/lr+O)3j@J>9mjZDL5ӿdg@!#~Ze!2 Új,BC쀎 Ǩ7͖C (ɀ ki>*+aK8A}/a]F-c7[3 ZR2/"Ȫ=\>?zk]>qA8 AZ V H^2%GaRR:qPPR /"Ȫ=Ǫ.U.Z2K.pUSKADOw]mf CK Xr-MJak{",9D;ZU{xΥC H% -!.2 TKy~4ntl9M8(#r-MJh͗ dU}jRebХ(xH'49:ƸT$܈=Ouym#4S;IWc(^a~co ]M*7S~mc_ Geutl"QLgFf*Wh1lH&C|:i6R0]5Ȕ18@nM5fGB~g,aZPs$&SNBXIiV;@̄1nحfCy$l )c\kHL~'uan{hlb* C< u_v8L c (𰦚 "!IXJZJ/< /- pxd-o`"?'9q5|fSa!(C4YL 1n tbcXO.U(CpN-*PGƽ>= U4fxS=+nMrPMj"SfBo ~fç"!KX(M*&*Cyv+ i1.=wv:c2i2Bw8/¥Z"͈G+Q'cvPbnjE'Nb (/_41Cߐ ̭$+ Pxt,f1U,5SFNv@ wjXِmnz!% q V +d4@ECY0 qF!?B]&0v" !^؟ P 0y?s 0jVDCBp"P0TQ?G`Cm( U6T@n4FaAT'p.@P,d9 Vdb0 ECq"POSEA,X\>  "~\"C쁳.vW-|X= W[r쎵^x%Q 9Vxd,hĉ8@)M* 2fA;fZ|ǹTw"!=$ bi ́(^g!`r(qi~ P $qCXC`0r-@3(C(ȞE> +5\L L;vS8R4'w:J¼>Xa59g;g{":}9{nnj,Ѻ|P+Po:maLՠڽxE"6 *<\ V{G eX ()3k0X PpG㠚W1rX%kg+ kj\p` ¢˵x'.". 2Wtrz(/ ~E!Iru=99M~i@ɝxT^X~t0 N4IN8+TKP6`. :CKjZwTZ$ "i&&Bch< ;:IW>T#.;n; qLֵ ؕBz6끡k`{je`MU@\1lCCèMfx~+_̇s1~ 8Bc[ CY~*_MUPcrS(jH}p 9kQMM&+\yRqt2͇f$B^!tSw :ECdg]魯h2HH2[ Ι*|JUC\KA^ }/Ra1V&۴֥7T+5VxUP;k`(c4kUwJb݅iBB-Զa&~ y/d;;s?+5M~},o)R^dX;nSߔy*){^:BU_kjA3( R=ǤeC]e yjPzMq -FhNU/\*R4.Qd*\ ~̣_[# ~,.U[Za}?]14rhA CTzR!7RkG;\a1Ur2:Z&hX'0-1TdbF aC}EO#r~ [D%QQ]BEH%EXM-{Sy1J"s( [[)/Ji0ԇ>aC}^GPcK^G% %-gf“*εytHBGW9PQˋ ,z PcQON8<>o ѓ>u'ޔ>o|=q#SmtUEEC >nBOBűRSDʎ8UE$"McW>]Q=;E+N@wC?/$ ` +vӪC}aC}^/"sjDUUD^`MG/J;Slvc"yh;bN<-ÓyM~Y) VcּHex('CV)~Zhl,|l|իL1QM%Z֞iֵV=V머><|^}_յ}zg/ǎZ/}nwmӬk%d+S|߭;U[{Gcb#V{{ϔ_Ɜ|c+59c#|r<ڒgʋA' e@EQ^&IGr+%my=,]l6n,*^SRO~1,h^֣–~>Ak+uAAs3^K.))PUuMPJ- p\Y 8~ hl*5g̛7}8hnnNKKsՅcbbRRR~70tժ KUtUm->C)[Zܷں555͛ h!>6/7Yyy5ꯞvvNҡ`tt0tժ;ccƶ7bժ\vXX\jjlޛZiiU5K'-Ҫ2˥LpoժgbcǶ7jժgUU##ӴaaIsfkSSᠹBZ2be^%|VWbL씔2c⬬m' FGZZllN[uzuccJKoTߚHKk.VVkDsSpNJJ}Uթku-*:Ew[87 اN<;P\]_ht+r282|QIZ<Jp'd&݊{u?:kqbhY%vDxepV -*r,Ν1%%z-MJK!"bOh2 WGfEį+]F}}fg̘ ki_?gyC{z#55mܵhQ[6MWR|`UUꧼM3f9Ųp|Q]teDDȈGvr>+VA-*TKZ5RT/ahO٠0D.ZkA&d:cF9JJ22ee!!QKex"UZ:,2YdО"ڢEw=?nu%%[lk{!7,[fo10䖌Ų!!Kex*UZ5""ed=~qrL0t3Rivv0AAQbMMɢEW5kkO? <3f4ᠤHFFvxHH’%u ?'7ZTFaBQ^$sECv)y^g)Q ^wKQi_baPPvHO{vyddw)s4 ӳt%E'@̜2  ))S3--?!!hy3w#`:gN;BUOĤO^RҲg/WEEϚU7j=F[ݟ< % Pm,XPvtD^:'feDG'X,!8(8NtVvveLL~'2hffsrkz/64663?Ŗ{zzr[nn3f璓e>gjeG$ĬEѩK8NJqqЉZhN'@v&1+k0::b8@).>1t&2P~PlD1S~8Yxu`5՝¹F ṹ#"2.~CEɒqq11]]?368@8(FUV+ͺPV(*ꛜx#5t+s?/.狼"M4i,e 4#t{>`b襱n^jolhhK'TTJU`ht$jg癜jDdxB$̬ML̟r }Omo…wZﶷgty7< q`$r rGaǢ:%D#?͝g)߂pѱ}Gr,>80LBE@LO/p S!f_߁DĚiyT"(p,*X&NNߌUX؉Aq'RoTTJz ::$%눈иS U[,*bttTz.ut|KVµ814**3=}KĬի_ NWXQy,*cDoIXX*R,ߊ\Xw"FE`Sh8YPQɘSxvcy&@ckc9O^3Ӝwu#x6^"Ub~烶Sƛ&cc3'n>KfM=O|6oAW)) bcDDiZԮZHhyB~WO{W14<<-+kH8oiehopp5DXpA[ۻƛ&cc') ECy49Ez#4;xf8 y*'?&4ևⵖxxSǡh%xZS*OT)XCYp }3%b?ma("*)! uY:t* "eC knҲ-J+ e6"hj>pD7VZ744_ NkЌB EtӽZve;\jcPPzaxjj1Y+%%+Wj+OC32j8bvZ,r(jՉ0WD@N ݝZSQ8mZiS+KkuoNff2_&T4((64<3~RSNCݝVP0 &0|<ֳѕX,,m837wCht7e+"}0A4,b$Ijj./Qc-%% II3U Ckj:yܬ}))Z7{Eŋ--[gYِ!* F?̛wWEGNf!NÿAӧ-\ |a1ToVۻH}FDQIJʂ]8HJ7WEGg9Nf^6ҰPc({y yCVۋmv=%O{/0{D$**N )iyO-{z67ЄOn(M] ExnrsŮo{|JgNRZZX{Mͮ{|';9W"|SxCEK-Jlr56EMX<4SiA10P^^W 5!p)Ows (5k*eP9#q!iw<]_U-y%QQ:}y}g"Cqp)ڵgęZuM;%x%B90ԇ/0ԇ>au sNiBEx$\"x-E ^DT5yϡ '$PeDE!Qщ#1ޔszD(đ7w܊ܗՍ1__B.[n'c2X)'xUěr'ޔ}MO'ۤlk>ܝ)ZK&ԉSj]Լ8z}/e_YXɽL_ ~Jս)M aO|z$čxh/zFD"'_p#SyPcA& P _QW⑲%6湋tN<;gYQCB~VCm'4wn=={aĬRgOu_uu1kޞS70={Ry\[qz~zX޽GNfyC>ڳu |׭]۹qKY=׳ G/NZu]qz읞>zujwVq|ktc ?v~q+מcg\%{vFo(O]‛Mukm82~\199-5/j#QL{UmF|Ox$KFSQ@ԫ~1tFM^ 6:vBp8L>[!5͛ v,!2paVmt1& Rry5z+?dW14BN[+h[s8ڸ*6%vl{-6ҮW6WZB,\ iukkjn*75i.RRh^M^@`^wT`tB ]qclJڴnݚM!X܌! :guv^IJJɩjiQ2& 0PmvE;T`tBµxglJFtRc ֭yɴ*beap|VmZBcSrJZ֎ż QV?ӵ6>?Q6=_^P@e콺V6[~15w7]H+X]lk 2pu>붯Ř)9 Z|Ј8a0:a癑8e<6R:Vmz]>t5%$z^imn};5_Moi+E;\9)9U-tΫ7iaD0ҠKx*AED#?^[OE(1W~|y~/.N>X:mJOE,7"^&?UQywQ_1.dc%ѺGlC{@P0a_mgzEAD̖7 %!cbY=ÒafJʨ47kGlVkH ϏV4T5\Zq (ִsWEm4UY}YHxȒ%,o,;%K2diteiDLO>Ã+֬@-+TKK5RkYڳgOPp0b_ӆ v-o۶ͥʥ76PZ|yƜ9ŲzdxX,]2"&f튦#ÇWYdYTWZ%89(ִDhvZjݷdx.|4[h[se!QܦnIqȢ)#y+B-'t1gKA}MEwm{^S7ު7W9RTM8wВdY],uҕ[#bRFF{3%BK uֵchϞ_G!5m^箟,mUM5gv+>վ-7͖7ۄG2tjꏇ',n<12075/TKskH74RegXxxlM#ˋFB+tr"Rxm9kMTtc&L~VcQC-OIb3y)Pϳ>߫:) l fBμahjᣆ1t<#;3+(ݻ2wCB ͛ik'HZq p_$G6)985]5l޼9snfLR Pww릒2;77m`zVD %tv/7o91&)(ݻ5h|Qm(+uO-;U<Țo'.[ 5s{4Px'gFP"?ga7~LR!Pw\7P3-hyj^qiD5ݖE{w49rDW #46yuOW"{XI:O⁡s=/a30 j wCt'ϑm.<ڕCc!-[(RhCHG<$ ,?8Qv$:01-!4(lJI߉ Ydi|¨xG*#֌AU-[Zz1cgБ!wMqB`VIVtB%ĂqRXSeWf$w"feΙÛq MNί>ze˖{T''Ϛq訆;w"e9'fD'$ e4UveeLb~'dfQqyq M̯]5|b˖{zﶜyQ).?M]"&1M4.%fE=g]q M˯]=|j˖={_YG̢sk_IUqv*RБĬ脙He&93O;q!qxXT>S < K˖+={_U}Ye#1z*y2KlJ)jڱ|'f F'ZBbp"PTٕkc hǸtμs1h2P^B%Q2?z]\D<'8'yd ?+?[,X\xSEԩpyVp=w#^ȭiYwY  lvfqWa4@QQǧɋݻJSk:AV3t;} /ݴbtyy} 14[1-B 5@Nrl7++]Z<a۶yBzkyC-RY-AĚ۳+"sk߬n?T4hʶ7yǧyۯG}n wӯn)\шY@KxnƈiZ%}^aEKwd76x+X fGl{*yb#)";t>]qcĴ;$о;]P#Nr :SV NcI.)xJ2V =)?!?@<:M|TY P~Qu4?};g۴oH"K1T& 6(M;o*Zzɰk >JԈ{|Nqn{s{ (1ttDm¾QkЈ5mӆMHvTXيAh8|thIrmT|~ϟ)=ߏ{s'1ttTmo¾>h]\IESSJN Eiڰy&D[oͩR<C-Z6*>ϟ(]a 4ۭڷ64"fvRq[c|MM#)9*0_ EipyID[TTۻ%P6*>oFt q.HYT?:}wZGmBhDM;|EKnEgV6wV4JYC7끡(MntQszvߊ)}Nm/v:'x]Th$*GNJ\^5xl>l<Vc)~ϩ̊͟ qcDFbf:"%f?8qa IQɳq Xh 25TbD2tA"ci7-1#QXTWd oCHE L/H7ֱ}G{dEŅ80695 s*s"b"4;V\Hˈr*qo(EbFT';wؑC,oxC3XBmK{Z]q#?j߁ ahpn J:PFDÜʛ"b24;щm5Į2Џ()RgDL(n/kgc՝QELSX d|Qh۾x32hlrK Xeej{\۾}ޡkq *Y׺Nؾ1vc V;|жfdLhh A?կVu Lg{D8|i\ꬩT{Eׇ!Dꪲ~~F䢂;-jW-|жȠy.1coAm}́zAկLϪj N*?k=і-WV,\ "vmƛAc]a%YVXV?εSu{*0לѓk ]q"'7yDzgVL#Q`_ԥ7sCmQ_TVƞL}"AX<O%WC3 |7w?Ր%i&ns]4(R)7 :]`(ah|K#Uy&]j8ffpo(SoHtBtjN;UHǬ Âǭ̠4% -__)Y^S BfŤ\ QX]nDe^4(8zXúuW|d CGG( ׯ,_ , (P>KH8`AkpXѝ9~Aac5;ǭ4z):!5Uݛ%Ђ-~<tn?N9mzchFČR#:_|*YY.GXӰQ}D'd,tn?5zE' [˖{&G/mߍPC#&ҫ8]}yŮ۾al^$NqOC@?kY-վ}cI6mH]lZ|_/&59 %NuN5qӘ e?^IT_ss7hʣW)1iQ ) C}P0z~+ZI 18YDzo)fw>XH'3c>'EKyhH6/\*D\ ~tY;uCEX?aC}P0'> 0&7G1-a>r>9: yCGخ' C0?ET<2g#zIURD*1RM")Vc61O'#>7O)ě7xOxpt蹋{<^JGFL"g%8ˊ C}P0z|$/) ׋:<X(_8-yK'KUS~^gX@Fe)pyN̙{yy) )@XY5!>,!1I)9k9ex,& Ig/X._۸DjoFPbxxАf[7 'OUUi+׬k <PLzzJiiڵn5%& X1qH.ѩ3=|%8jڴͶԲE8h>y!jvr^Y]~>;tAnά勳ʞИ$KX4\MU^xnm2ߚOVj IRZ_k̚<ςwGasg|:O246gIc!n9E#Png3 ƮWmQ?p(|ϵg/$;fAzRK| FPEg&:̜ONMt?l>Â-p ݚez/7լvB=`Lz))|FDC"?gno>ٜ9?WJݺe-زX՝Y^{wmVk;׶2qHt̅nJ-)Y1xw4ܔ9nLzPޭk{ٷlȂ-= n^<,|LδtCRk9>oRKKG~yzakD %sv'OfΟֵn4{z7g =}nO?*PCTkS#ڤL6܉u`6|#s~oLz!P}ߖ[7qgT dt4&Kuyy~1cџ"X(KsйTB 1Aliq/:v+2EUe, МzJJYKf9_ERs y.I@f?8K6 8C8ĬE ` 8@)$%NL̃Ru='^М(#_n}3gz&f??6KV ;t =5'f-ʊN[p"P5բp">CpD0z59Rӆ'^Znn乳Pc3qgfAVЎ3;:'f-*NMD-TvICU=.geIK#fM=9Q))NU}60WzOZ:qRܷIS-y?NL+ 3{ξrVDNOLJO- KC= ͩ9*%GQcǙFPzw,Ue(A!8fzCYSs-18(}4բOH̫ EU_599Zp&ҕ8]qg0O$F: ]BÕ|)?&(Tq(\%r˄ ei #Rԯ uCd~:g/'z=R% q20T PQ1ϑq)bz׳L~u :PPXқQ>>9X 0$yh0PF. \S)9bmt!Fc&0tۃ‚jW޾s?" ZXpX앃*4x|Nvv#Ț\~x7މZ3{yED4݈Y z頰0$Eqbd?n֬272 (# CWY#99bwmo6mi!I뜃ID'=}l0S!t-7g Ԙ\騥tDf0aGC|nNj{lħZG8( N$'B$8#Y>폴/C3f9Ю9PS@U9i ѰB$/O w:j)syCKw?2j7=@KqQU^19v9ԟa9=j=w>@)H߅)H_t6<5(64cxb=@Su7,~nZߍ+?m̮C&DPW:@þ QM^/iO-[f %u ."$;>}&Yp@:NIq6¡$'<^`DH%Lp}{N^TIx"v~x$jM8S>>@=BP]>:4ѱo>{6rժT3j yvrHMa˹s^F]C<)BPhwԄGwJ)P+BW;l),I=)%BP]](h-lv»TZB#<4: HWEÖs?3Wu}`ʼeP[DbC 88^!5y'ޤ'6aVnaj#'"fKPIB%q@{q*| mP~𖛁T;Sps#S:ѣPsGt!΁X6"R 0ZBrEf~{˗ 5p 74I. q0uDzDǣu+CC .! mo?=R1"dVOj# >q~!N`1"=uQNGU `2| m>~hmUj4/Q~ta`Аxh,uB=4C| ~AS7 ODGQe~ ~Wt)Ft<r庖4ǣ.^c>>gp?P+{Cu3!(ZU%n4Bh,^o˕MDi/=/$1K$!"*-KC0aVlQJ$;N/E8cؒJ49H~bƹ;!u7sTdh¯5 (FlB>&j.+Nq>Kvǻ/]Ge;J?Vs289`z%aѬ TJm8pjvV;U :͈t_%H_b28>88.xa@\Psc2PMlK%@]Ou]ՆS;J[; tΛ}6Jş;J?eNxdPsCx'G v_CjnlTJmXkku:6:V.]fD|Yş;FC?(*8>>8.C<;4ͲJvŐ@o:Vԗۥwk!Q|C)<.^' vGbVa.eP0P+{C͍PrN.Jʮujé7AKN:͈dO]4,x*8.cIBxJ&UO">{Nݥ H6MELJ1JK_'ǀMRS?-$[>N 8K4 [qˉT}1SUC՜K2yоܔYtܕ޼vZDkt;#(yv6N'W9S`VjB \=@ʠ l'x]|rc?ch_lЮbܕ\wdOXxN04!<,mnOQP@1 }] ];Zw7o;t[zrm7w fPۀd~ uU;{KB\yewa(Ч2(,ur?`׺_$wK3}&:wìchqEЄPms?+SC HwӍUJBa¶R|VKC`$\Hc/O[ )I%zi]SiOqH?/p>UI4K]n_ B+B|d,%ml4V.mjVåHy W`nl>n\(MZ< ~{X1ۘן Cpk!Fi*w4#ȈXo5G-n.O`( {}Mx08ڌ٦zhVnm](=ze-D|@#2VwG3I_9zW s}7fgsy/$˒]Qy|PCZZ֭KWSc+@>2dDF}}<^q BÐ_u wit%R3z~7Uǣz7eUa u݅\W}mT ڍ͘][[BhXw{>29hDF}Orb(jD<Iz&l{>V:ɎS{H)&L$4l34(K/r!` $)lJ8PKpSRPCI(쓀t֚Oϱ'ݣ<$A.DiAڦ{oIh/>%Ϸ[>ԪJM6d s-sMyJQݻZM 6%c(.IOӠ8ɣOqM|-M̈́CsD̷x8 LؠGa.N E%\.)R]NR/\~Z1+" IxRxœxRb(!!8ʘJY-qx p88Lİc{[vR 371I8mH*dש,p0>WǼPx1ԋ^ Co!a""i&|%aK$IOIvŨGb%NI%'ꎭ8)9sS`_'D-Ifdq"Rf2/z1+^ bCE0ISQERK8IC±2$F0"c— -$()DI1,b,>H#pc;U$Ң$NvJSCIW<)'IOOIW<'$;N]IIIt^#-Nί1JCjl%U:)*jOpNr0+*_*/%I,lȔf"$LBǰ;C/z1ԋ^bm$A:olȧ@%&Z$8>PA bHRH@"UIv0NRX![ Kqȼ4> GԮu|aC2)JRkNH}1u2]_>+?JN?P}<k{YXchϔ({kYCmN:wmjycgzKNXnjߺ޽kx;랶Rk?R/EӹD!-qq%RDsp̝G1a͓EZ;$iD riJN)w_WCT:Qn<pSRg,3)9zmtBCecF¢].Xjr|Zz9ƯZ ˅Jp3B8CpS`,3i9zmJBCR`1?TTcѮz~6RHk ns]mWZ ˅1Md>G~E`ne,&4qx\KPДBeI8K(uîmW&rBLep3tao|nV49bWsڵ B?4(ԮXQKPۻH%S('n}篩 QQk+DifLep3EKj/:4cYM3v5Gݐ#C DvE ]K̗ΈC'1bGjq#r&Nc띴 i¬Z|/%I8~\Zk"LD}w7l8 9◖"YKIXCםcg.ueሰ9f:[s7kzUX4YY\͜A ek4FÑfV0ǜwCם[WqB$]N%@nhhdΊn BTXgߵ><*{oƨH3P+t\KulgDDbr͍oMT$S3F*:M3X ;eƌCx܎8;" ]RkЕc $OT/]T{&Y㪋9} <1f7.;Ќ1❊+s-Cs8{v[oU?/S*3m }|}v FGQ6PW]-T\k޽ 1P;wkv㨥chS@gl|O_)UFf>>9 UY'㪭͜=% fo|@3uڀJZ7ЕDΤNDJ0 |@uBHy\i w1CSrl1%P ؂Kv 54_Sp(oO6qŨZ͑(4" 욀e{8:c$ޞIӬ[0WZY`ц*]=\+[P]Z$ hȑr_KAmbo՞3Oz c.z.[.W8{dȍ{c*RY.Ј(H횀e{-V isxէ;81t'(X.^%r/F5/c*YBTQPn,^( m{~jf|] o/\KKO?` bQ9Ux.Pi4F+:IεqZx#^ $EDR8&'pjz2-1|RnxO_֑.fbc`]^`p⒆Xd'2%7~Av}C[Qf۷ Lp@n 4@2n. ePbj.űf5Cә]JvyCMvax#(D@7$kخ4lZ _=x`%ABT@hddnG`l*Tҫ jPkC 7G1Y&^&K :^;Y"SCR`}d!Fhخ!̞'Kv^ÁP ,@mv1tq'<Κx|| F7z:^{,hL _?yHj4l/ s@~=o?&XhWD)` 4@2:gu~U8Xm IYaCA|n NQj5Nr;&K`Z n{Ծ>P:^{-DT@ m׀2{~LX+V(a 4@2fu~PX`v?Er;&m%K`v>k{ E xwE 2*$%~lhخ$`h~FdEB$s`|VwW`l*4֦6DdPS]A&W:rJ<$inMjD8XƷ&ƛwHXԪP~2[# c.?oo[/9 F (z˸M4f9VgƷh@h{px>lIzhOB0k._my~X3\nжo(VMttˋ/ ]2"㮻Z-wԿ8r񭷊w!FƍJ h{Ud8<j&k~3g@sF8À̊?ԺY.bƷT4ErhlPjCcP{px>lU&kg.E1_4ANʋث cI\$n&G[b*)@o7ƈx TzЏCH;O1:?bsře D8 DTxv%JZӑtX7tr8TuOO{bHv R&cpz#R7{v\0|x--[KZP;x?Ic\ @mXCógD ϙ;V"k*wj0<} 1}6(V:ޫܫʥ*][/%9styCóÅuiy͑ETh焧oIFߏȓ붠Xh{2(b8G14<;N*;nuu~oLҮ8ȢD>hĥoY BJLP|X 0q~{;;\[t04<;E*.4-W.SB* QJZ^g#V,IIb urP11^{;\ŷ|! izˏv(XMLo/pm-/կFB#<''}h׃coχW{Jʥ@-DD-e'0ԾUc{&bp\(^W]*gҷ C`F_(([ {F=!R ."<Ǖc7D^m8J5Iw)-Ŏ$nPd7I?q fT_\m/pʿp̀[(LUGz8NM7^00hH ƘgDP ٨yݞ)uλ5!=omWtqΝ|'č^> C]wFQP@GyCj x޿-CZ!|F ץd:Fþk71NDA9nus\s>/$;cN ImyrȎ$m'θDL8&')4`ô3[aT/qF9Pez(^oqn RiП'x/ M5)C.§>s\Cjì)6K]ve×6iljfDѯMFr1~8J$|.! 5QԩoA3@rf[x'kWi _Qޝ}b7ҍm>j|`LL  1 5ѨJmG/D9UK4jx)9oF QQa`(R x;`SrcfMkL&8i㢗23]nҗ4ۻ>e_qG^PhX &@i\7zcPmx'kׄLNR.P~×Wy3"XBґEs~q28`AHjpu/Jp0q.O|P. #ޥޙ$ H<ޙR(NTCp2#쬉)$%`%GM$;(`~uyСkgCׯ]7=t[n~{?CWء 2%F}}nvkhLeR(f,{kDYKJڶ9:Y+}_z֯"{_rv)6`S$D 4oBYsA*5 P_l$ '+5p [0a>@(fJ,"I˵PwE$I%VdrNHUrj/ Je/ W;]98OJ_|T󶄆!ҥM["O)ǵ>1spq.c(†u'2c/ )F@~h3e2 Ƕ.mB^MW"{2p4Va ouϜd0*0c}aZ w%%wُ.2Ba ;vXVw 4 ccK7xrҕHwUU(dQnЎXRoum/+GױBcYM0-wiRO> WZ|8c(,QW=81آI12bN|'d '§EH"FA|M7|1Ux#lfP"O؏+1[ ;՘7ZSu}=_̷~s/w0u\u}zkʷnhifmA/Y:zb)1E[+Zyv}fA/`\Hm毞]m Us0ulmz^R{CJd?l|7R2W,/~4KvL=15廾+?=]2X._9s#G lC., $a")AI̟$\ ;`n8|FVlrO /7NPOJt MLq(\J; }# ӊ^aVNzœr+xœOxNy")5ϾI"/{i>yDP*%TtK8*#oTcQJLfa*Oj)y1ԋ^bC/.N8 +L C;Cviz@ͷvq c(I=q-IOq3%D"I{ኙ9{+)@P/zŋ^ bWz9:'EJlԅ=J1J"zRP$ljVJ]jᕬDd_šOS d(%4FRπezsOIxRxœxR ő^ .@{n#8>8 s$ O\%FDOJqt>Q8$9;IA;-8$.bCP/z1+^ 0!5JI$~D"py!G8@|5E)36ܒ $)N;Md" P^I2\9Iݏ]]q4j,i8^hjnka_>+Jfu ި׬v&rv }hk}Ү_|]*T^pIkunZ\Pۇ}?_-yZwvY/H/~/ <nZ\Pۇj߯~e?|ҙOԽ[~|ˏRj>?q/]*y^IixpRH0 @)%1’u=qfh {)MIHBP)W~v͟Lv9YMT>ūw^D/@Rv1WYҦ92+8o&SGGU5,oٛ0[F)tLƌ5K*9M_r +!܋RvȔ2~{}6%W*:W1׉BȞv]m;QuQаiinߓ*tw7VH3 ,k)sCmNU,SMڔ䙖am|goT]24,o4XZǣZyHS St9x/,Cq1eWG.KT/ ]lRhXi6sOT]4,oi*pQa/Ptiƚ3[@8jwSv2~{[{ػ_ N_vQm;_[ ˛b**XxT/Vk Yz(&4mC(Y6y0%S*'m׿Κ VEwމiy͘&f=xT/tiiƚ3g>.* —$A&%l'=&~FF/O *i=w179%'!&HFJZX%NiPO"Sx 5)ĸ+nm86Ud*1:maYYXu`_]z5⬳7sN2Kb͞b8 fOVn{*J?m~Zef]kYSHXZkɻ;⇊]W] ɬ8kp3dJD!W ]Mc; ڵ܈*mDKd*yh9y&)s|<#U.y^Pi<ah)Qŕzq/cU9٧A(KAmt}.4&E.*̞?,U.QS=OoUt^Rfn_خ笿gnj9 ͚gnTC`.Q5{j& uuϟk*M! =u ʕSK/TQk}QJ6ov]mt}=4&'Vfɓ*$)M\\K.gT FAŎq3qfM|`Ml~8! sOJC1ޑHҜ$>6Jv`&bFdCH*3}%C)<M14V]40}MCGhS PYQ>g x?0ҹHKZy'g4$Ŷ8r;FFV˘}aaͱ,CQ! 9|O-oZ;u:h߶v 5VNj1 X@V 6uŠJ4t@|*] m/{ byk/=wFfV˘|}qH-Vmg~%<]5:Pӳ7OwcCKz=ߙ+sCjWV犗1 ,v`Pc~4" D %`(NjoY޼QKOH^JH__:]P,.?O{Cjk W1 bcjs?YhDFP=ӟZ|3C _.J b%R $&ZPB$=H7B"U!Afl~+xI0hQl%ʷ)&ma:%0h|'b;hDb!\Wq4d mNj=e`FMa 4@2Ǘ9 <_S0.chҖ$Y'^ƷKko@l@Ҧ$:~Y "SB2C lȯ=x`mVS@hdg.kqsC%Z|{x5M;Y"SC2a}l#4l!Ş?O zN9^.% W)sI[u4ScYWuU 2_Hf<4|h>@a5(.B$ss)]kKR!jy܎I[tD4VhdW+:~ZdeLUdBuC[~5Ş?&lhW(t0 K_ LU !Y)v1tWg)sI[f4]鮻L&:~JJ _"$;>0g? B$s||(P IaɉY9(%jIv&K$MV'ٱALi)@ Rl+BLfM cw186ж9z+~%mf=;7EՋNm+"32yH`*~՜(χ׼.ef]IW']nжۀÀ̊*NڜYiy?w:/k"+47TkUcmEA<@GT 94D+Ͽ' j^hRr#? &59IDHOgx&bnO8>n L&IT©y$O*x K c'>Yg?;O<7oS dr g#Խ/vbYUyh!1tb1u j93m\q31<8k5j^vyC֗q8C%gԞb; / ^ $~0]^r,@#:1 RzM V6ХF T F{K΄?"ppC;]o1qs ﰼ9jӶ<K|dzCv!p\ JԽ<'tտ~i Kϙwcy5ٜcDB7bv0Wӵ{KRCw5ꠤ8Lk8>'_gm]o!t-;}XS9NCA_@U_2m0Tylx)f|d^o5$LݻpQgƚ1tbBt u˛oZsӶm^T`4 :Yħ0{ Dqz>ر{4fDb$H+Mp1OF8dw:/$MiIP=7m?ڝg[,u%Q{'<,4KY0إ m5WVR2pd̙<.ciIiڝԦj18bUs彖4GVFB6}84B#[)8C21Դ5R@ߏiSp&>x+PO#+^>4B SXlC:{a /<՚8}@kS18t9dm.tr6r,4KS҇tE1g ;~2_hPvMQ@O(\^#>1U t"Yh-إ]26WzC{_'Nw`IR /<[5qqbvT FNR 8 ah> 2b?-PR.>IOǞRhHzv;/=ńpL%I(y:ɺÞ+1IIN2̋M8~*-OWK8(?oS k8R/sf(raa!Y4|~Ohna`АLOah`|5q$mϔλ܎rHq,{&GJ cm BtI0paHf2`Br#5 E2gީ)2T @Br$'n4]/}zC{ayz,h 8v$Xq-*;Oҗuiv9߉qbY|h.5Q$6~ &}pOrЏb'˫ޮyC?0ԼoNI0|>•`~AWxxީ)\@04/BfH9r3~ayY5#{#?ߩ ol }h}V7#mTmr`r~<fW*ɚD}e bIZ5yC/y '5ӺC? j ɚԡImJTTmS8}x)eh)t#?S ^ P>x'kb\и%bЪBT7}n+O(CuQ6%!vbŹaC̓wfZwbdMLbP24TjΜO6_Pk_yΛ㏵))Q qt4ԆDaDwx&iwb@ޢ$"7<8G}'%I""^8ђT)I ڛŗ HE@\ 07M1M\#qi#n.(/p4Bϰ 7C[oJ?U9b6/y Ck_xwS\{λn iQ(tĨZ(}W᛼=yFou m|?`zku] PoZaRr54ɬ Q;B>uTPdJ.~6zCʬchk:J?]a{J<]E)@vzݫ 6׽vOX@Z~78 Ÿ˩B7bhhN,~_W[~khLS2D kϫ Ub!h?pWk$3C:]7׽t_;0t6Kt쩽$D 4uO(45)CBt:** {*RY@"|&zÆYVܕ~`ku_"y~{P!8Ҡ%i qęn4j8&c{Iq&<iI:Ug.d0tTI-{ߒJNߋD5ݦ[fl&N^\󶄆a-+.mʜ*E0+~ЃB }x)gY nzVro=oy[wAGR2 'hv =bM]d|o^uW\ ֟d-ukw ?Q孷Z+G}]l6#D,1~acy9;яRIi{Ix>1b"ıv *= 8]y}RURR&UH*fa훰+ˀ^(zţbW<^qKcöL@Il[Z$8 b" ĜطUZcD&'ـǹQID}l%$=ٵ={1ԋ^bC/.B"IKaup D2\bTq6$A)>Lɕ2y08>RVk^I  gc%+W z1ԋ^bC/^RoKR")AF|h3bGX(R~FAL$ԛ.+-8 >'J$}=ބq&n+l} HJ)mˆLz+~xRNzœr+xœOxNHзK@q'q$քa&hNHyDc2oqzH^'"OpXbI@ B$l9a|ʋ^ CPx1vd!I4:)iI&㇈w#)=&1 $lK8$`]TL8'-@CIRlTM91+uiFZ`r c':l}s9xq.˱^Vne%YG1tM)6%킛up\l\2t-n.c48Oˀt({dsM+<.2eVs \fMwGS운k9ƾFF٫vr <{gA]lb緲?) fabv:n}8>;a'_2.YkwE햆ǖ?_x&>& 2I>)MH0"βI"KGx/VI>-$v/c+q' HPljk6Pb_9r*{K]PaLu葶V['r{{1șe<$$KE#+t]^̢֘1,ft. XL+jke%*n'?y+eaD8Vi`:3nI6d+5Vn *~ڽlo2K03ŬX2_WdG DXL2Z\IlF<BM,{Aj{Y4i31 Ŭ^W";jfǢ~gm9r,*``j. \$`MX.X`#;*v5#!,F mlu{Wh fV)h1/*XlM~ 0A6v>{1t9m?Q*mdgŮ&v.E۫b_zI{̚D-fLoQ 0;=eV[+;w=4{D@_ ,jʓ$c(.%/='D#mҺA I$1Jsۭ_X)åhK2x{Ix;*,GahO}M0gr\Q+`hci.(Ez&z1ftǺ܎u,ULX50b9V4;Y Tj\W̢QŲXӹll Ua>붰~7;a9LuzcʯfdwaG,7s+*tA:Ǝ ][8pIm04&a`&`rV.t٘ t71t5k;/ {\a,^!,Hm%\hT4V$,nU: /EÓ@)<Ž$D9Gr(c2DnfY~8 țBVSkqsC,a:BV3ΞJa.bX"["g~,2&:b>K7*IØQ c*VNKIWWwFϢFy+K EBuzCٻwrXE}rHZ"+3e$KB@6DVuq4f/X X3ÂK8{Ӯ컡,.a fP2{1t/wrX[>yMaKd rd3|%#jy3XTI!+0֌fyCf gGpҕ6YCN2H%w7ĸfl693⥇"V(ē$zIZIL2c>8?@ VR$-r8_{QήoWJZT 1 ط5tbʟ36B|2X3cee3 <8kj ~,|㍬Sۻ܎ì 8 ʊXR0nB)+n$1#tmmlfEe̬`rhs*Kh.Q%ɞy mg#L[/X>=+3:6jfeF18̾g+ʎ`=^$Ja9S ٷ=:vww:f<~^vqvkTpIl=sԳUl"X!+&؟ؠ@ ~h,<9b _,q'0[N{W]bp;Kue7;"a 7'fM gVg&XR^|Cjrb.KFbq$\zqIR '1Ҁk )Sď(q Io_kd F<:r,;q uQa?:zrj?|{:X|7mZhjXifs8-2Q~ғ_nda+^F.0 `f-۬P5-ӎhocۄ`i6=Ymmb 8YM*50,e9_[ƶ6_;ʙKpE (ԲPRM 4ӷs#ټch>%bPX$|2 @'vp ay~O4pnްO93`I3XI< pe#ehocO4]36421tʇQa,>K @mc3L6^ p={~o`=.!Ħ\)&)Ugͨ0&Ǻ܎ &R/kXʧmkĪ'5,=%Q+%2Ks-:C8Hqc? *a5%p9kqsy"o4}~`Oa0PS 7sqWL{˿~v.5NgX#.XpK?̴.\n a4\9Z']nPrʌ WRZF#r 52b?T|܌Oqv<"Yb+ђ$1b:[8 w*)1bTR] k#.P&.k1tx??˱Νs4cxqa.@tnؔ.b *|EQ- (9ws'۠d~6V P8$"L_lͥkc&>c(Q-sBBMbY+Ýl)A6 P cp8.>YŪ|/6 I;X|]ˣU%- +B,P~';djPM$ u A|u2N;/p$S1HHS6Ds.%rƳJ"X|wn `(Q-(f V zKJb;4x*9#k`0,AK>)S4a:B-: ;G(M,no"*P PP(C?'>Y&|ATpsSxˊDs.b\;AF8;;Mtbj$0L=Nbϲ'()H1q.}$]$xI,9'U1c/^D'nfv}\d҅.RXMLwy. upvހFș{I*B 5= [։Z6oQf:w*L } fX`gd{ã@sڵP@sLn Qo.cA;׎F(g"na:]{T\3' kgR@29K\5Yp*kA,j%js4Kε(^,l'{vCqZJil& Z@8EI)IDvTm08" ~;Mb$"k#5c.I$GKR<7H:F[ݦz$~L&v9Z7V\' _ƛNAy˽zu$q"Gn&#ӱ73;jNrW0)`.n!n2||@ݚ\i.=_CgO R~WD~suBd1/~u@1:\VL$WJdBh _;[|]˽-۫&pWӚ&]g ]BWp"$ɿba {([%t޵89%b&F>-b]~{#7sN],miвzi'+X~#]wȊ(A@=ޥ!O)WNwR6rei c܋[by7POEaIg2ԳX6pa$. Plw}v~2Z.uCI;>R9q!8 T'I8/\Sj,$H" $'ɜb,v E8a@8~Pw%u H*? 'nۺc r\d':,]n)?ƺƸܟd=Y 殚XY7(rkIbXɥvA8ޣ/qԔcccܿ `7{'ٳ9e)?J/`8{ y=zBjzOw˃8_d} S?~<ʙu$.YzۃoGL{;5WEc~4~Q`G,]TbOb$2<$'F'HK%I 6C)L㲟cRD(V+-߱E9"Gr^ "彲 e G}CQPx7+G$=vy$uI"W "9ꥉIuQLxj736O2Ó'lfHNJCN\EޓL$ߪ4Y%YnCyx1ԋ^ CA)-Սva"p1wˆq<"E5I^LµZ=-fN|䍳c7MyR-SS$ a=nJ,c4[(NS ~Px1ԋ^ CoFAO$q wbK|^LcJ|Qp(R咔eF5w|COBHLy|MI콊$c?e~xNI9OxR~O?9!b0JDed98!"EIy\c$a=%aer,p"e}i($ $P4$)Υ[a^ bWP/zŋ`$u)9g͔Vħ@qH8)$b&A<abUq Fa0%_c+ǽ$5=I%z>`;.>^;[RxqPok v6շHs{.[ά%l{-axv8r;Nl#S}}ˀt0ר-/l̨%aִmz}donѮ;cq \͵8-ﵖXm\K¬iőS}mFq\c][Kvn;QK¬iۻ#/O]5ݮE^ c]-?c-9il>O CmiTԵع>m Aƺ[~ZEx7\R{wlY]l$9HQu!$0ĔIRb&&K[4*>(LVՓH&r*M[(6Kߦ:dRB; %^ڽ,9k X9f@Sϕ+RƟ^;eɧ]ݷui15o-×B~}]ɞ$/B˒wwwvoccrT4,sL))r^DoХ[k..Pk+4t&`)܎=yIy2_FܻsNcq6`Àj6MJƀec8X. =!ti50;V/tY-k{u4 &a)sC'{Kmb_wQ.xOrT4,1"e~+`_v:%~u"5 Z$`M*XxbqJ\'zqQƯ$Gƀ9ҩB(̎E]!tYGIx\Z7 &cYCI^t.cdϟ6|6u˩m|'9 MsLH)2%rP~BS`k.K=k\ZR 4һ]b#D2a:.O@R.f#b$AGrbw|ߋTx|qFLKI|R&+Q!wM1tudwV#LB R3fjrYr4רbiqs7>*F.:(@BWM PK,볹ܺ_ncRזλ܎Ҁ> ooURUT .779:UYYiqqMO3qj ˶n ei43.`q܎VY}#|nFG~J`;Zv״EuuVeUť7*&6NlXQ.t(@BWMNM*:n,`sCW5Y}H{\貭;W1" b^RjrmѹШN+ol-hu:WMN_*KF?yA/QiЁwV?|5>~{E=ىom>|SE069ЪiqN֝) ]59K,4ƙփ1\niڑ o﷝v9SШʚL7>*LlӦ2Uyƨe[<4/iUs2@ǽĒ>{JXuٵbONN18%'EŤٗq?9Uǧ$;.gĖZ3$)=>}BU( JI R`@",I%~זҢ04П]٪xj8\a`a)NaEs#܌7=M'Éullq ٮܕ,$pM!,-y14߿$5UWNj$8(Nh$DDFo0Ϥtұ,~{.cybt:h -e14?$DǮ_%*hD\LHH-p3/> Iw@vgl :4@ۆ214_WA'/>r7 W'2Ee7JBDhkLjL>Lt.PE 6tn{H=h=wNO.8ʽV'^V mSxCؕS.H(-.*eo"eڝe,`]4@۾-[~s]o` u014?$ux/^˩jr? r7 gRc@t.[+&b(Y:`yVeХCdt9bÁ>PÌp4I!X9R9I4:ZJw$I>T$ E Ǿd1wP ō1tU4SD <4*U =#9XdאrOb[7#ގ+,hRС2'{ny2+;W)R9]5C;r/NlI$&0 MHGGbd$\& 7flp#oMRh2a|JHk*HefRFCm>R`$f/2$uojOÞQW8"a84d2c3p]8Fތ BSaXPx)`PPd$~2+!Kի* Br/ۻYX | SG:K\"ECC+7$@cv9?:\7#\^y?FR)`:hTfv ]]k|||``\xZNGCm;*IlD p]"&ԌZ tY")#CR!3BcvEΰxRСeNJ+T@ BjT0Kd.b~Aد u@t.1D.SEdBC0dCcQ~ҖpsmF|TI鮰 x)`Pπ'{Jب&: Krg7q=pllćΤغ]k%v$=xb%<)MHeNd}TZ"-_U ©F>quZ*2.܁xg Ț! 9(NCo#E`Gk1w%p)8*~92f 7L὆[Qu|^']n@͓q$IܒTƍEEefB.Fq #Lp[0P8/))DxOx0KLXIɡ"FV+2*$c\[!W%k˄1&6N45`,4SA?4@fgۆּ< pI49Szb Egɷ!0KLX n Dh/Y~jA&6>\ܨQR2y!`>@kμ`a~sAmҒ YbL澦{E0oarQnڊ$cn6x^Rk&zE&6\4^fC!FqF (i+/uټch 2w5,(>KS-dt,pX;"PŒ0 4#$>`ym^Yf %=C24 zrМ֨$5nJ) |I%aY):flF%I*ؐ=GE+6x+[UEiQ g\ QB}u;(wCZ8H1֦s !(W" X' !ɮ85:[Tv[82M܎|Q@AcT Qfl6`GslcmC--͉Ј _ !<(di4buvkR!Bl] @QnP( uZ.8rBXP``bd"`4`M:Nαpm8TA`dW+ͱf܂|QyIU@䙸!ȩ ?|61r &4`t+47T|<\!ՕflÂB@9r.` J?ЕˏaQiAjZfM:Qk1SڕY [¸l!ɮخśc+cޫ봣x$PsCBsaKQjeh^fM]P{.Ј /]> P7mi}6C q%Bl]}d26/3*>=%EX"U(5IQ[J]?a:UڝxvtX؎ãȈ7*DRAd%1ya7o贍3 n,k9:wq:#Cf  nU9*ŧ>>o;CCgc[+8DimOCæꉍפ̔D0.2$ı*Unoj^\T}||pf~{L!]+@Qn:mӰgSk ڬ,FxwM77NJi;sa` `ȐHꖹܒ7tvqO7UOLl|zMz3!|R)B>&čMgW!W^/,h.`Ȑx@ 8~Q2w:PCtOÕMՏLl|sMfCBD}||Ox7M + 7oL C0NBDPWrKi?4\TgMACWB+cOtzr P):mo7W` `Ȑ巆E ~DP@GK+ a+IIrbQ.=jNp8?^{֏]Hq$hI uj$=N=YOA%QmGuBdNV8VơV'Jvn;AնZn :(sOVeq )D"b$xPAG(jZOXvnؠUjk'zifɪ,_1u(H C Er{%Q@O:2=.[CZCTJ?%VMTyK'|}|q$~ 86JZ)C2۫(M.i€2sZaѱpJUj` AA|*G&ue.PFZSD06 ;6*kNR%Tm}Bԉy\QXf8 ]P&V;= )3C*JӶ1g "sJ x~[+je AydUք\L Rf!L5c6UJNI \$=py\LTs*1Ow8 >藞 zLr8S)~k8>vV򅍲ΊfS)F[R8 7Fܦz% =52n,f[1eB{_2-٣Y%oVX̽iZ  _vڶuλ܎;vuA#+!A.Z5ꄮd:UXr3chgyN zed$ P*q(a(7zz;vFVB\&?`= tmvf6ը\ɯy66%:E ?[ 1jThkZ{s(p(A֤^]XaQrQNzǎv= 5r9[ Jmn_lЮ[ 1j8U! Rt:ךu'v=+,JS4&2&{ CZ~gGހFVE.S4kwT+|ڰ2ةܡeǭŐP!!"%Ț>:(;uv0 0$Di܎kGY 2ϝv9ϤDo(3=CfLZ }MׂQ+#h2 dMu#,(y_Z%[Ѱ gMdI];N) `/1c#+I)%-\wܼQpw%nQ4ƲXao,]\KEM@RV8wa_ӽ.dۻ.6uvnvﹱB|vW@X_R,\J= o6d]KGc_HoʍX`ØEl$;~BbEI |Q8qbh=IFz\k~&Yc8@8 VM"c+MB |CQPx7+ G}CQP8(I11L$Enjd|LD8=>Pl2ĖE},^?*sTj}"~d=8 S1GREbCP/z1+^ ]G`!F7RC#.ęDMM`HH$"#~$M=lj  Y-q$2i?M0J=pY.&-(ȋ^ CPx1v9c$8G|c6iVyR 3(ŜdRDI$&1>spi%R|~$? W"%@͕K /5lS<'9Gѯ+^+zsB!L]Hjr#(&EI?bk{! I_pM\MQʱ)z/}}q>)^0&L fr^ bWP/zŋrb%F4I|CqUIl@HDN8І3bHlr~M(> H8I%Njrjd 8EI.Dv q5#dVCWL|vIz̬$I}o b&TV` v9{Yr2`fJ39חQFME_(wsڷ)(Hm2E%*KP(Dzwocr27d`b6Lj(Y\"%^](%tw: 7 d"0t߾}AAA&omT* ׀mmmS޽{100`6E(,..?yyy"j4խ_z~G-C7((d&[[T*5-uTNx{ޓfsMX\\/,˫WQKTz^` oh ݷ ɴomRU74z1 8":5`6W(Y\#+nnTM(^b)jXa}ׂLZrJWpxbcoow i67D˕F6\z}RF r/U*f244qK*Z&q`8)Nr(H24{\`TSI-"ĔSPIKKCDDI H~\"`S+ $lDb>a aZ-W=.p;,Nϖ-λJ],𴴹}}lbmđeylps)^Npd]U&TUe;msw:ʩ&'GC4ʼn7#*&&6nT dY^!tl(KUS½Ē~}NqϡȈV:v옅^nٲEJII޾}EwqZWW'`(hNKKoMLLlڴ \l} HqG-CGFkv;ŲBWW`kݻ?74t}պEȫ%'B47tF&&ٴiȲU}Q/2ʩUtn9yY7L},Q~{#c _u:ZWw@PМV-7[6)/&tl(@KC]:Z混LwرXoﷄ+n;\ МfoG?m\*/lDyy2Jt+te7n∉q79A&vDR]jX.~` C0...MIα9v ubIKk%R%|7gP8%$$,$^s˩L>B&͍p3>~Tkg]l߾Q~/Gg0"(ssW4f4:TL(Ghp7 31z],F-e`(Pݵ 6|Zo ᶥ`(`HHHHJJ"233#\FśBp-33E 5LЀIE +܌IMM nry0`MHHOJ$[bihLHLl.tL:_IE[#܌7Ϥ&Ku7'2 G߫Vž@dx`(4TB04733sC4SҪtŊaɴQ@؆#\Ԋ,].RF?~LgGx"0`HOH(OJ&{gHHHcFcvZZj;y7j> T53 ұvſkK58S U:š2<Ӯ;HIRW%q]/R.8NI|U)GOq&8?1c'T?( `C/'9r%&r"H!q ГȰ SrXYX<>ޝM2,,(''04::+)IhOHLe!А|m13cO ׉MfdK`UF :499كJ* ̥`(`BaaxJJ аhxpӮNx#G$_r<29Q&B.Ȑ*ª8 +,*%%`hXXdNN`htK%%4TÉ_yy':rU r_dd<4d29-4`aɌXjXQ\ܨ!X3ZFF ]YYkR EBs):=naa4FGc%%}M{kpo.b(>_))%FGMOXRG1` ]#G~X ""#3!)m13Q~p0dFFTIa]aa&rq6*V q]Nn7Ĥ-Rx"i۱Ud.DIt)D1/H8>&m$EHE(i]^QYY݊$N*jo(C+*0a>΄ _.ffVV\B\T,+Yyp0gJ%Q}/Rnju<ʁٵ̬PȡQ\ *;<h%sH4?ޣTDw7 b'C`m11ab(bEE0ܷo_*mٲyNͮeee d3 ,՚<44D4?~~r7sC (VQ6<흋UﯪꊊJ4bzЩٵy{YYBFqq 4@Ca`>@ug^^Upah~JuMMxgq]&' x-&Hy)劊ow23_5W0tb; hoT^"+bk zh8~R,nL >v=/%P%(I1pݺSUPKmTğXV6P@x@|@VCyyW G4?2uF  )T]vCpMD)qR'ZZ)ka%>8 /jXX|>mm>KcGkA ^b1t^VWWῗ[nm࿗xؘNqqz! ; @aaaYZZ Hƶ~"܋vy~{O44l)x>""OfMPz Pj /jXX$|Zض+?Qfdǧ.3 ?W}0?;x000lbM1T&SKt  ȫP೴ HƶFG_](&rxEJ1T:ʽ ho={rCý@`+ן6jx 1 B Kҽdl[c+QP$Ɖ ccI (6pII'yL]$N"c / 5,=_*6K|p/r3ےܮx "ަPNAA]s]5DKLű1] C&|(Q}E[Ce2ߊU##\ ȥXCZ#֮Mo4,uk1 C&t(QXfflfs[Ce2ܽ{w=ɘx`bb"`4`kBCH8+`mxx8T Mx}F*FF9 Hb B ;?4tUЀ֮BpP8^,=-C!Bl>_Ĩsf m++*UTlyK@hr਎S+:4Ws]z;(ol{RbСG[%I1T:ۭ2ȯ@_2pf棰0X{.Ѐ֮$U`qlR+bСbFC%!3IRc89EO1:>&)H#l#$i @|"YQq)iIsb1VbXSM6nS . cyZk>Qf3+'n*p8(<_==\(ע14$$P.P)+3JUn *:70hddchHH'YVV$Md2EFF|_k@ȑ$WP5s?Ӄu.(chHA 3NN>[V֨V[^ުVkWBf%č@B*_xgW>u.nfBBÏތZ#ĉz:뮧`͑)M{7?@J(dVOؿU(@55}||B7 X"FMM]oA[ 'jw.chHHB^&I49粲juݱҼkJ_^BT*>\S3o;_ֹQPivO~>II|VúItRgV"Қ󥑒#%;; r("l=ž8bjx|\'I*'zc0LXQ1O)fe.6vάˁɹiNOm8ҡ!OVUq' )!Fō{-Cx[t(sozڶm[- H,>YU-c\(5ޑ>] f +322A=zН;w0v۶mB p8.>YUU닍cX\QP!^G`YQ@)v|8A?###bo7gp9G-Cm֭?}||[ TJz.ci[qÏ&%e,_9cdaʟ' 7jF 1^ ?d~~{w:LebE~c:|;II%FU42y~,nԉ ^iiUCh W/)핯[wTק__--144VXx:|IIF)Z72b/0.WōD!Nq?1H4FrcGOBʖҸrN{Rk9ڍ",(%D2CjVZlBiH 'RXjo\ѣ Zq0}ﵤݻw7=ڵ 5ƺ:==jt}.ˡCN-:k||| :|_B/(הj=4޽w+z%={OO+w!5}7ƾ xIpK],ѣAf׮`:uaϞ~FKH`Dʲc0)zM0DP*&X9RNA>I|b7&W"IIC4 '$=I*-%Orc/QmQ+K~xR_OOIW<'Q#clq9$<>}QR JȣS ŴJq$;C𙸔HNYJbf N{6J]lY|ދ^ CPx1vRxOұ%>&saĎ(a3!OIvRN"6l7 I3}l &FYBU"1zqH>)െz1+^ bCH#&2H>;N6HVK)O,8o1i"8)9Ƴ=>YQ_4clj, !—%4fu%I[qu!~\vM_bp3g̺m?{9~ebž'ܻ H7}6H;Fcw[wl?YQK¬S#GN|k# An?3s- .^9ė,w!KſQd6TA6Cj RJ|:g1c˥4i([)-4/ E"%c#1RHҌ$A)ńk>sy\JH$OªAZOC˂B)o`*uUb [nYfL_MNʅ{a9\ nEV\2~W*(PրE\`f^ {9Z4)(Tmʎ"[JTj?aKx_ }E{Ocr7i f@/ڊS~2~{}*D]\hU( :SQ\eS>Q8tQK} 2eցVZoaK]./̳ͫ˩ve={s1pz\`vP.uC!&s9}j&[-[>WY)5mssOrN4N6D[\_/_YEt0}TszmWw(,B[ց):yuÖîs{/ *g=r?mV V8ס 4Į4e5l9bܵYk0sVwﵠ(Sv{I΁9pMsA,^Gq.^y^_ХTj-}Tsz!6͔]ӰһbrH;;J!NEc!6bgV"vMilAX3(l 8>S?s $SCv%xm»:riCjq)LU̲ؓӳcX .a%r МV4woM<6sER̫juq={uz_kC=,uKcJέFUdZU 7re?mI*olUmvq=S:}eP^ISxbJ$<3r)<#NvJ8K֌C8Xt}P~S K؟nS|OE`ŧR?]b%F>Cy>C,KHgICs+Ya sԸ~l}s T47x3,6]ws?=iΤ*<1R2rе8 3#2Cs+WE3&J5¿Gަ쨺~&mp3lI͏Mֻ2G;T)kvM?x0zUi<4@j1(Zb IICs+sC !""5MxXIE wݽ޹Ï?߾黦/NF*]o ᇆ8"0I042`i̘ RcNWadlrR!ϔ]+0hkfLj~>蔎u+ϽG?r}ϞiٳѰ*x;h ?G-C I I%5tVZC 1"Rӊ\DCS͢nƛsgR+bcw}޹Ï~|駦/+ӹ'xE`(`!6=!<)⺜)Ѐ᢭nƛWϤ7&K-?#ھ񻦿3}?8X'4@z)]4T$7g3DýgD~*&%%@d3ŨKqSiUNRGTYh=bI>UǕz_ewP@6Kɥr*8&^yml,BWdy%(I1ba~{(&u5*/ S%d:.bCKhko;uοڼ}u8;з;Uh8UZS7VU|lٷAp3ĘV=pؓ?vXCs-1DP.KjvmŲA*uCZw>W9ذbE;S|ϠYbLv׳.8G?H[Db" :}/]nP@C~=oiRuK4OR__G]?ϔmCCx }@aAYjI$c 8g$(O w ;Nè&xeP@C~{|~[4;΅_B RK)p+ PU]s.*l;(0u@Ҍx T\ו{((IE'1Ab $!  1EƲ,YR&[ vqw';qlvyWt^ݝ,$N貵oQU oku{{}T hoM˓O;PgWZ- \4Ր B TnuxOMoSo??UTIV<ȿ4j8elf>2Bn}PF[Zşdn2JaCb6Z,:rAS?utVxzA2ఽ賯Ҁu|}dY Uzsď*C[PA F ychu 28ݎJo0Ut8x_~{xZfV#3`⤈rs؝0eEbR*?^ _fҺQ*;h울͟MKjbs/NH\: &4`µe{ ڔ*}o`H$("Qms$LN.11 V{`KR chǹO»bBF-@$hS6UiO`$TA"2ئ9QZ&spSp' N$4CJqI$;[S [ɐ i Ϥ>I'iD )}B$>I:Iz,Rڞ<S»؀]܇C\$cҟ.a Y7w.>Y[Ej*wh;3{T*>sU!G(pQJFX@y 5^&TK^Z.&@(~RY2Qq::ˁJwZU1UBB J`P?P/Wr'}lBP9:;DOOTNg# Fۙ6K&l{?Z1gc6$PZr jsr8'QׯgqbҖ'RGoG!|Ǎ3g@ JŇv_yJi{)0 xq6jc@iݨ^9\wKn*;+܄|L7μZGgPpގ6;;{Pi{%xq/, IlԆ!Ѧ1tp*=0Pk=1wh;!h@y;G+O Y1/Fag@H}P#g)&%qp;WRbG쾉oF#/c j\|/-1c&9}H=9OҺJF3C(!;6d3Fd0%NrΝC7پAĀthpsOVsWl) K*~3 jLCx!=6dcMKN a "8J|2:^f-Frrq(k?=}<h mw$ S Q>B{.Ǡ 3]vqdnulЦMN Cъ1L(@0!]'274Z֒c#d† bs{x{]I c]OVWd8gLAmYSW 2 ֍ ܦ (2[b;l:B9t}.'ss6. C085?} f/偡ť]= ]῔o:}_ @3"A/ṋԡ %0)VtA諏 ˠruS]hE*LC3Sx{ J/In)84w=6q⥊9x>ä4y*IAYS|Yi},Ṃk{8f ,W>6¥c : (g~ebUT**՝['sΡmAg[f1{PY{@2:2,kmk[ͯ{d;en4Q~]R1:!&; pK?4ZjZ@ۂ$ 51#Ǟ>r,=?ޫн{A2:`?m(RX)5P~]>@~11XezB BWw͙dB`〶 r9 4k n-1tPV ,ǻ>nkk㏷[r=ر˗*wp8<>nv!chuuLFVE*JT1~h|8(/T8嚰zqZؖLc+)D&K|\z*͐=gPE3Ã/UE:EC +Y{Tĥ\wBbY3s."607Ono{ 0PeBe;bVy^fEn+[D†dh֖MêUaLٵ&<]`oU4 M][XHyc; fzep2 Upΰ04dit=eI†Bh^YLOXs?2aH 486?ޣ1ԺPc{C*/m;uRi4-Zg ]]w/Vu_Ͽخg5$qd jmY@i(1Ԭ0c͝#e .l8)%{{ka:ǛmQ[sIx4\sVz?WMc^ \e5;Yjy XdSX}7auwC3*jk{dƑ7(:$U(q:+l&$;PRQ]P$[ VCLi @a?WL{آ)Mq*,咤D%[VIh!Rs̊iLjTqU<+\αTW944iA[N/l)z*__5 P~jul̂$K0>הS3.[N!S?k{P".Z25{'?m9Y>dpOcw&_>!IpyH$'r$n︠1ObRISJyOxylm%UI {RI'QaЏm|`,ܲr6YN&'$:$1`hleq8Rxp طdHO )͸D6Qyc7Siz '4HLKQjE0&6 a Cmbn=!{("kIKRSc mdžUO6InI$^B&6>$;b& ɓ$+18u(NUYK9lwM> tf/Lu?1ﭚV-C}rNuwMl;$;Q32C>:; 5kWC>ygL[7|DɁ%I&w,hj:1؏u.lC|pWܱngWC>W=x 5ۖ?OwY6L-W^.I$|f"NR'E:C24aZAI$/El$Їԑ'G* IKTP4`gaI!y0dO$ ~ՃV[*a^+f'm`зYq`EhF-q ;(Pfnf#ֲbFr=`LbBe5]0Pt7<^n%ZNx]TQT @3j#2x!jXfљ#&Ut4<}9tjCUlch닭ZwjÂT /wz|-C>&DDPQ!wk\f4LFBʲo*ZEҬ 0:sڤ5 %G6TgN,ٳx m}Ewְz媦^M~ зSSQ99"fo *ZErљ#֮M(.?/qV[RnX4+-C~?| SoGl g6'x ]+bZ G=pvSiC y=g,TI>)Ȏ | ޱNM1kḃ}"1S`XĶLNCqylO%Lo"RR|Dqi%h/ ,mCn3_{*KUxҹlӖbhY =Ȣ7u}֝epFM[oVU?| jCMV'(=̫Юە },TU?|0͢> ȰC ' FAb'gl5Q$[/VPՏo~Q/RbQy\_UᏖRv]Ъ UUchCsFo;ӿkbIn:AU?^)8Pd-1? Uyu^ugD܄Yp>|M4rDoL;`w;9W.ǻBf1QRtVhfI.np*wR* ُ<'ZC 04Nxή Ӻ}U8j({uWfY-Qw[O)FNO?xEnх1MUA}!DŽj>k(S&xJCv8uNDq$[,'3qRK%[ūˤҽ$R N lJJ~'g("} ا c,, 7[tBf.'=m^\ω؎3l(;=jbTRgh$5CaT߰Lš&TDVyG,PNh̢:IZ+t ".OW̺mY1(PL{kSEqzxqht~b1 ( Me4||eʴmi Pj=b>I/>>RmnQ9މgvlvcCMz-+0O N ˌ'iB f}auba߂E[#tꓢg"ק¥c_yN3FێycQݯ]lfO[_`쁩Ѹ,xqht~b0OIXӄj]^^?؆ի:3$u ұA]{Nގ3g{M 1 ӆ HXӄ K;6^C ? Y5B>iLb]B%kxwm7cQSoTA428$ґ:3V "HM b.W(ߥw$ԉO"A&aRfPC41 8-|)Ob;,%J-fCjp5MXV3: ID"́vuZnZJFyUkpY`Ve}PVV 0aM*,Pgt?/ 2{H1a}JEOJ|46_/$m[.~aZT;ZLkC(C;(Ʉ`Jg7G$4@r/C>JN{ H=JV 1I;"Cd2Hh 8R#> \+{ح֩a5dukYaiy}o]#iB%`hwԎ{yRHz/B ?2ΤTl Y!> )$m[&xIU=yw/bQ %Ou#Jʀ*h |tvsMB$`UWaM*;iu~` }zHz: CC ?L ϗNm^/~:RݵZ(P.(0tӪ=0aM*,i{ f߆ȝ"!spLM%> _iv.Dݵ~ F1J(ڮY즂@$@Y ņ:IX-<:N8 g†UDp"Iy7GVGFxx^b+&H\cZUpR›I0O9P(`M.gzхkdlg }w3n=Yt1'%kIT:w!P(#[u~{o8,W5}3E(`TGs0գPnZڗ3E?Q'h  `>@ʎNWt{`~yv8?`-spM!C`qK)o5M \C/+ޙ 4@?~f&(DYryggdpR:=0 ,O3;M0;ʺ$eM*P.s1{g342Bd_ ,;є\x{;)M>q?5fG͘8904 + K)/eM*HzMg@fͮ}};wXhdl߮Gu~+NH./ xe2ÉsR*DO~g[Ld5MNNJҾoflwtqF /h E XvBrn/bv-DO;qiFjBe4al@$U11ll`p\;V1I$I_feRaaoK̋$ fq}ebŗΝDY{")^1a ch8S-al1y1 N  ߳9|$c+9ѣ(,C(@^Znq\|eJ@0:}=#L !۟s ms Y w;|Ϫ|$c+evG_{j眦9kUQ<_x`+eU8* N7o-PA h9P ߿Q ߳؊ {W=J2)GSI1T:ʺ'>S@_Od# l.)Zt  g ?U_HV _YGi?4R Wͷ8O|x0S&o{?l{%Zu%9bCEPl# U_ HV dG_}Uusď*??)P.ը×mU 8~1dgZQ YͮT4=&~T: Cɝ29ÀH%lYYp' 4NQ$ΟOKSo*En'v 9gV^ Wz]"$Qˬ;< &4`µ{(hS*9opR Jm͜Uur&b("s`+:x#cS32wx/omNiH &4`µ{b ڔJ_)b|B<0Rot̹?l&b(Edzo;ql}zU'kK0ﴇA&\g-4 D7z}B|0 $6Kx\dukg 2ጷ?*'/kِ8@LhkAp)U{ߘ Đ*HPbt\d듢dr uru }@g޽nnx|'$=0|=mJe_7 *HPb$,=)R\Q C3x#'߁wĄLvO'4@ARW$b ĐjtA='R oK$:ىI&vtKI {i4=)eDrbv%P?#륉KEިؕ~k|AIyNo1ƀ#PGC6iX8+n;niq W7ig;ŞTQ ^+fIg70ʼAa(Ⱥ} 's|>&m/mBT:wo޶N TA^*jݜNYbOp/P(Ex=<~س_ /61# FKmuT8;vΨygήb n ~z;)|L7^:ZG3PܥĞ_Ȝ94ŞQ'_(|Lں! :P__n%ǎ[HXS|m/+@ymmv 9;=(jж>1enB>&m/}ZGT|8m??XkΟ$#jbK"TWBBB|p~MoNvdhlj#м1 p,Jc0gcŹBQTA񄏱U| 1 mq)R"$"ڏq}_=  !=d mzsӄN Hp/>ݤc#kNnSI\=)hgA 3P=@ M wv1D C{._r3"AmNQ0) (qWO'FGc AA>X ylL)+D?ۜk/yd̆!AVx $C^YC?9J酓NJ7=7P_O6WdbP%0) mvC8;P\]N4} Cc6m JL?A Fʡ>s j[~"^|2?Ş;aS+I\== P.;*5E›NJ@1#4V~{\L:Z^+I\= Ra(}!IR^;jF("/Ec!Vb#+c+#Αv ,{1#b[/'ݱs4F[bqN{1>XbT ; 6l-cOQe7f;AΘhʌt**XNfcy̬nx3F=Yrq]?n^e5ka*=aiݞKIMUCY2p w$ )^ p0?4{bfE 7<Mn:HBfwLՂc?>we0ɵˇ{'u0pج G[ߑD+_̦ʉRx(Sń؛3.L nم;hʌٔq=5UNfc?N@̺d T:)y`MjI|a߽@\pA-k„Xi>ծ j>/k~D+P&,VE(<ǵ>rt=:(![>,d/XBuj wVf{BI#C $Cce7 _ מ?^s ;*suC _qe7vfUV`!Px+SV`Ukaa %jkL8pp1tQ֭e5;U@#e N,Uݯ&,s#nv#ppc.5e#F'ҍ E#%Iۄ4^dL8sk GM3:v*G&aACU:R gN%SXP)PqίjM%qԸ:_u0]Yp0})C.i}q%jy%w7-hWS*rԔQ/_ uÂ}XՔ?'ETrou:ʸ`j l1 R/٥[k?RMSqD+aW|>m7~Q_'EqZ"A10K C':;1I8] ؎SrZ$dSJyxW4^cB%[҄ļjЯ4d9e&)lMS I$d'miu|L$m6=t8cv7(H!$nrY;N 5c|x!&TVch- C~& r|:{8M_^v-+Dh;㵃CP).M_;*CT)d¾pB0N{!߀;{{ A[qk'ʝ=cXvC8-QPPFsI}dnZ%,E>GUh!{6ZZah1!?w{ꊋ͖2+?^ ڒ: Og4ʝW% AԪ=X4xGqY媍aLGg;/h qgwW[qqY9 @SQ[rf2k|_P)jg7,xG*7mt!/6fJkj-\: ms= ;Ϝ {/-nY48h92zw~;j˖Yf]GAj={P,b`^arg c Fq]f~~QJw3A b_Y˨ Ξ[`Eg̫Ю_Uz*3Pp4׾T< 1dRxa 4r'D@uaW6ʝe 7@(@ɻUA/eT7U$WZ] EOll|öG w~g=|̲x"O|M0N8Ab(`6ca)kP~b˰Cal\f-N:z9p _W%}yϱ"j^eicT|64rul?24qUz 1ԐP8fmЩ_,^sJ6SEyK]K> *PL{31: hm #:aV(k⅏I_K ??zkj7<3Jԯ֋DG2tұ4;{v⸪8xhtӬʺP>m.x]LxmG|j̊!?q߂᢭:g"Stұ`z ا ^1`_?m:fYY1.x04`QB I3u ұL;{=T\U4@:}*ގg]=ob 5u ا ^.lF+n+}|kjN"--B 5<84`Qիg"uұÿEy~㪪_.j>G}Jl$1b%0I| IˇIf&Noq!MI꾉),\]?d+ԑ7zb>Ɩ`bX.ZC>gi,b3eM='j# cl\- D⹆̑Ok }M@šΎ}czUCJjzVȝe~^А9'r֧ Ra4µi wc`MHN_Y(gx~Сχ~9`(N3Ih{yjX8̖LViz䄀ȝ~p!2G+4qSDVJ'I۟m?&lOЄkU0'4@rr̪[: KkIR$ܰQRHN/^ ?1){6D̔N?/~LؾFr9ӷͬz*HRWfGYCXQvn]J߾"wv򋏀?1){*|BćAc+󥓤mЋiW:`Nh0??Ta_BQ %kYCGlL0JKڹS??*y. !99 rggxhgOT00hlet cpg HN_2L\z#9H!izil8T%qݶ$R/A.0b$N8W1[ؤJ<$DwaC)| Eq%R"DIʚ&TPwEu|bf?ov520d͜Y퇩V_ԨJw͝L?WPfT Qb i}w1l?ѬٵQrhd:Ad_V]HRV2Éurw$0Պ4oU <tZdC|olk/M(w^;rk<`ZlGWGhdPx)8N E`Dz eɻ=Wzv|Af8'ܝFH?L"mE!JrN؂Fk7K]q _t0P`مݹ+#3y#uZf0QUc?R[8!J1t.{aA*bv-f_vNGWhdخu@eN$.\d2oT+.jT 'q l^eui g2,HJH ]ZˁNtU R)m0q!Mբc(wW8*{֡"N2A]$+;cH[UeA*R8zĐ97 JwX|:T HV\ɎEbGX6J1tC{?Tӭ'o\B1ȴ8~1dOZTzC:؊KWC)LI%O1d;_&IN]<|9m™5I;q$ PIR$8!(^"PUzcqC;$HWCSr?DÔF1w pm'p ئEZCel}}_GƜ1̨' $e )yw;>qiH &4`µ1m^*H) fDz`H$(GmZ$bk=T0gWЯccQg}ׯAKlIG!9!}Ѐv@!wQ7Ew>>R bYk1gWWGah'?>  MٻQw>R ʌb8#s`Q'7?{wEj~unJ*wBr1k PЦT 7|"C0 (6-COܿ﫞;):ZK?lEj~@?{@@}]r1k(hSU DFbHL!aPi(:wn֞TZ/( W"5< ̉,E\'uđR$& FoE*ye $; 51U808= f8WCDs(g|L7>h¶!SK^\B(ƲۘBm^u?1Tmyxmk8Qq-uTʁJ͇W *HG[Z z  h3%=N`]\85-[VYȑq6:*JŇKQŬ hKKXW1wh h@y;W{>z#Pp\>&@0ѐoY2*nB>&mZGT|8o^ TA>z?o,C|ήҰ.`C yy~ }&Ʈ;zTeCqAT 'Wz0 . }U|DЉoItvgāDxCTZ[ I'i2N—M'u"u96wr҄[..^Jsj/{ֹ~.ݒԡMorΝCa~nɄP Me4\8TՄ>c(9Monvrw _v3"AoOۉCAۣ`ӥ~Ѡ YQe(2/ؿ#'&h"4B{.']g&'w'v.['ssΑ.E0tk-!fle_ؿ=gG)7O:+`}?TČH.['s2ln/!LP'7 MG8olС|[q~,3?ʄ4s J̣ "^|2?9#kvNKym ҮޞCM:VV3=6G|}.N0@V]ķOC0>$Jq\v$U|p&b8$IC"Y3%W$@ʄő$ܞINin&7'IRAK*!$I/ 'eD`w-K9̶jF 0ۇ'sD+PfL=*}zsq떳 վW3)9+\E*1t<]F7:e_c^ rg*3Pדhʌ)=j p0?4{z;Q5Gb_/8o 3yaa{A%1Z-jhj:A{P}OnەmOB_/<D)b.PluvlɴiBн@tmNh 2 k =ev z`@1X%UNc{f:U m:q r'Xn0tI]z6&Lh 2kk!t|wfWw S (ΐ3 z=I?6,9er 6X14P8ZkW0;TмQ.cʵ%OŪ\ Ͽخ}Fּp'Cq@V]nqb){$;k.5214/p4VM)yZLxMۢ'㽵$:譹CMe;~O^rRC^igo3C GGrڒª&lFx*jk^xB H{?"E&] ;;k(a&b&)E7Ԥ9*DHɧ6R"LRW {8b8&JSiۆ W|溺\DC; =;.; Sݷ?=nqǥtiuO{m<bWI?/Ke|?T~ӖJ/,Z*dOO߇j3fAj%֩O+[?޹c Z^?)&I$ۈpdžRA >Hl8Fj%=‰ƌY"-x9AW$*jILd88 '`* CHxZî4gCW|8Xc#O36 cC\zmdd՝l]aMlt uk-9^ew>sa`lG+a nlYvxz]d6:YgknHPY֒cU${è&Y4soib#* L7!&TσЫ&W&٧f{f~6 ۸hlLLhZEHvv$=hY hfEuY%c\ UZNW9Ne[,u•t,:l6rCLLLhZeJbHH\`!VC 8Mx3xt8&Qv%q([\蓋{;bk.kh7>HjUC gϓZ_OiXĽɌ3Jc5 zƒLnZ~{;Gm<IJ V Of5,aa[Y89rg]l(ӬBgII,0y: pT-K0̽vjvsddVevFײC'Xyf"Of5lkX5vuC(@,y:&2,Ռ3L>롗:snźD*eB^=ObIЀYjYif ϰ2|0n-1tV3_xWdkgK/$8ާU=; ^c TY06v0mpT-;a3# ka'Q /Un6/% Pi.+_$N_Y Y?հ#3|T0cb.f@YN&Bh԰QlPÂf@?f=*UId#"uq)s& f't26aHSEDI <[Ǿ8as$3W[u`4L!Q>H ƛ&%:soZb8f,oX]Ƌ0-.0(/rx{`ĵKC:a̟` m漚,Yw7xU=gY)0e>r3ren"/3t32ykYb:lp< #L Kjwj۬6pX)/*iv5Sf8'4@.NAÒKg0ք 6),2;y' F5ŰxO0s=jΞGgx=oDox]a=-e Mi,; LŲ`.eZq,XZ*ֲC#u,,ƳL3C`l1jSp`!Pv(k^do+,[`,V8U+Ӳ"tfT ϳ:ٙ66z1qX(^cб.m$:g5wc}T1ͬEԆ,Ve!P&84`Qlk~MצbYs`J 엂*}M˂E^ flY ML0#q I-ĕ1Za6IrPrL)Qe䜗/řM=>" $~l' H*R8[$NyPF|Xs-L,Koy΋㱯7Cj=( m5GW~`/[e&cS-: cWXM $JD\7PLrl+uVk }^bUqā rf7q;;fs)yLJa ]# 68s_B5C&"UŬMe屴+/E %a mflI2ZBXO q`r=w!r&:aUǫ=(;ha ѕ9@hllޜʏyg`x( Ɇ`K*ͨ6ٍfXX"}CXv%% %a l3y]cq AА39!4;X؃)Xak+syZs*?淞,&mV1YukY|y { h`( *VQ 8Z{=80'=9BcɉJo v[GWX s_T~,h=+ e179ڬ/UöLE<֢͟|CX$`( mJ!;!su~r@CC2+O_ װѕ8pmOPyP|XŴfU&&42)miZ\Z=2H"#5a$91a"ЉaGxe"N |2yG%%ax9|28a7 cQl56%>~qaRDM}r{"v,2y#?v#,0P.p 9r03ӪP $MNS zCb[woq9UrR>FC)H1#_iR)k$73H}'1}Sr]ç #4Mί௼7>b݇70bj"hp\ofTˁ%2 0NϼLϯ.SΎK0ߋ=bj[ $r rcNfUf701V2Qo汆93MwOUgX}1,"w=%p)`ype1Y3s'J krCYJ*JB<ŞqĒLVqp6\po`B3he ?\.a%nͬʺCYJq#e\͎ @9(8NGTq {ǾU1,"{Mxx jي>ݟKX_kJ5Ճ\$.ЧKo,7#&,*OS~wW#95p`N:.KX:~#< mf ,8킆?3.677b(|s*^|S":"q>NiI쐊!Ko7"2q|=f8 6NĞ*"&ZbH&Nl;% aW\zH1&9|$ب I4jx'yi!8߅A"5BҭCzg2= s'ּgXC 9GIY`AP3"0&!~3 i "!M=|70 ʴdC,Vc,^kZWsPI`AG0&nno5BN4aΧECNRrezf4zdz=gtv99N´lЍK0\ُh3BDh4kBeZK7,_"c?&အ%lO5k1ԡ' isn\K.̵7G= ^ >`.ềŋ&L* /컸3O%l'l4U/CodJ=7[QEeY${SABɅ5q~,.)4k8!M=|7t!iՒ_j옷piybSyp Ho6QŅH%bM$FF#ǥw8&.I2CIc,.9)J,$b {ST$w;Aȥ#w;{jp}CR]5cyuRx+ n6ݽl*1tJh YPN9F憔Vxz )Es03 Z2u fjP]g ,ɁԜu  46.[*_Z `{AtL+@,d@GX r]`< vâ#u,?ϑ_wk9 fΎ6&W3w:AJ`m\8zTd*n u3\*JlKtB[BVx:ANSP7s9,M _f?T,T owa6}ll͙ͨ[j ` j:&TM r;vnH*Q2J1}L7s]*J6m!US!kj<¦NSݻ 1ߡmw`.TǾiC38K*u@j{܁9AA*gh۸8ͪCe_zl#U"&E|1q^:$4%:1G((BAKa(!PؒQ[11 45=b/G8 3F3^c9׳0TH/g̞[*0r>>\rB? CɌ N5D3^w͜ ГȘh,mٻ9La=K3{{fcM4C/g@ L&VptЈf+aM@cYp+!*䢇m3{[qyEykßRP TOrC/C#ͥ'ٓc14Ee{jx2Odb[_8i>4gr&PVyWYujx9JV*1gՒn~_e}kfS5Y(Slp-+Wo؂TK[_ bScl̂tT+ة*Z򦋼$M)6s 8{EpK],KSݳ_d)1vlx\a\f R8\=RĔF.qKR] [4IEMl÷Kn+'[$ǁR4EHR INS̑A|@q<Sୡ6Y4d9e&)lMSɲb(64Hp쭈ñ1ِ&*7ѤfARߞK{s)AI\bF @B$ S;%OaI)DԆ6 CmjP0aM))蝯$OKb84=)N* (uI^I4G,a.6^%Ӕ"n hPĆ6 aMlpar؍졤'6C'LHx!Y/qMlv%@\Ķ1l$e' 8:X.fDJSJS\IΠ"Ћ \ˏ 6Y>irʈMSnd9c,|i|AtشffYJ&JI9"(͔DBkt\۝'%F)HI8-n& SE..=0-UT|l&LIQLص@Xچ6 CmjP0a8R6P&; zшH>yiy)baTr $h ^71U8DǰK0IM*M)B~\f]aD%>d5\ǚ27eb |Ea֕KUUMVWw[ה9RP0Zf]TmTuu{|սv4e4.~g+N >X RsRեC&';u6e6'bNO8:֒{NO*`M8hRl{HҼFsc%vLj 0b73UЉJA𹧿} kdعlg2@SƬ Ύ$5lw*ĉMe}K 0<=Q%nswf]d(De%$>}͚SEEnݙoQf>)))05 AA(3v֭Zܵ~(uu4j R+<]Oo_SݜY~๭; ၦ2AQq̖t)( 9 IMp@FiƝuܝ]׉BFG>k6-]'7ـJsÒF5͙ͧNzngNx̪J}R}R`4jj҃-Qjffpgݪ:wg]LMeZVcDm—?U}͙nkL~?dlo*Fo9'N 0&`zF G*3 κU^]ϊ2]w(ڽaTVH Zoo_s9SEOv&?AUjYӵ(u(N&B&xzP5ʠ/pmQk(9]6M&LI$†IoGpKR"hb$!S8768z_|4 U$w؊ROSl&eN$^ c|Y?P"om2{q,:4`QlnXzrXK6gsgK9:sȅ9 4Q&6o{k۷T_x@iN:J* I?mzrrZEEYz= "P/]eGYb:678?`(4ݬr~\2BL 04$@- {rZ+OgKGd`P)b(PUL Di)+"5: O5_| LQԵt*]oL\8x7Fl %e'pH(~N qxi$b8Į"a#)$r*)˄ípSl4QV8; $ g$p)\V ~=H  @MaLrf?!z97kX'2r{1S:pfH`J؃҉xp6Za`#7 e^g9Llފ2MQ|yWjjM;49aa RUUL>owYcggt)<<&*+kᣫ# ȶx [/^-(0// n8ϐHP+5WL`74\ s{!{Cc~cM؃I0Q9! \>:@hl߆1t|8x9[:  RИ }_2 ~k-/Z^Kq9"!wLkN<>J'[r0pMp|tutce^}/gbԥ`B+({ xIM`Ըrvajk?>/U6/A1+3Xs?ޠLWGD寄kGWG ȶ>01:Ky| DF8I}=ĶUR|K9:5A1 1CHJ@I.߱7BHd{bZJl<!JahC2N`!jάtl']E,PM>g0cvmLg%Q%4 "8܄ zn@x8 mHnNQT˟PeژXU,wFAD 4@ffƶzNx 2'`(:^])FGY"CІ# !h*WD5f ^Ncz_INg 4 "nBdᣱ-sn“@x8_A /U|ڐ gB$+D:agPg%."fNR^_Pi~%|/-1EG'U0J)-鉟$\U8CSA^i,5WM{k qwu*\ژcT//S"}B 6=t73}Ea(t==Jcbna5P[0:UW7^VHG;Q4&ΔJk T:a OؐIr'rҨy*`ivz4 c%/Gc'UpI>Fp81$ CgC˸0&@=ܞUquKVs[98?V5`1oeQZ&.5J]{yebV"1t6xLPYn=[ZW U)>R qTˍe 5ނTXm=wl_\Qd4`2hv|x6?^Fqqp U. ggQ_k 1t6 -`Q>)^^[綾|;q~EЀb@[Mˁna6PuY2SxJG=uz([bhOG:<^jET5SWw6:RxCЀb: ]-wPjA.nm ťDx3 ;1 p%uq@-C* 'LWNhLzgGIR &%ǑOҢ8ѩ:Y qL\՟`(Ʒ8G&MlNck92INixl$g"q=Si9v! 6EbOGAA14Lo$r-)"XLQ1O># ޹ zl&rr3S8p?CĞ\=6De,l4rQ-Tu nNn8# Ny-0@RCkT.BQS( Qh`Qrr !8+ 'H[C> &OҺZQNCKv3}GT.F̐ _xDF7727'5Έ&f{y.jlg8@~A1X I2ZnCKc֌4 /;"/=QJ'0?/[yݝ\7Gf.UƠSL=%Q%'6\sRեf\ 12!uIuBꌠ VzuԆZ61##U?w<0͎n-1t oĠש„LtrO;$lhA\DQR Q^.@jCaZ5 1G >WefGU=pt"0hm! `9n( 1hu=SW/j?{kRo.ŰҘ##?Wo.Tu]14#ի@u3ԆdNjEY44$z1JÏpvO78]%.-# ͑&5) E"=$xORD {zE)0.ϊ$o>IRDFC_7d?^rjHI1,c?m h-ۛv hӅ 4֗l ۳ґ=aQ/̀B儆F21߿!9Z޴4.tq^oi4 @.(1AqD?&I|diKlNCCr!4+`Ф47uuGMe#[-XC{_3]@:,nY* 5v\QǛ#&E221?!ޛ&=]k <*xĒHyֲCO sBHRb(Lؐ|ڔiX5RpEÿcoZ+j(=ޯI<"{y>ECG]7))xOf']ߺ26fqBHp i=896HAvXI%E]iDiJH|@$ *I\O\XHV陰)~_3p4 ǹW,.BIVNbvziJOq I-JDIj~aMl~e}k۷.)۲\,HOK@=QTtyY[G-yMkOJr.L Bby eEO?3[XktqXSkKNmR u2U7Y.z艧˟,˺֒ה%Q]Z,["?xh,x+[2׶tc[HNTOtTݟ`!{ lY$4" I0#Iq<4vi0a(L8.GZ X-b#ONp}^x'IaZirʈMSnd9c,|iZF#,'NSALҜ61mDHq#|!@qSrcHqPLBԱ(~lɧH}umM ݒ%kPĆ6 aMlF IVFYS 'DzRwQ͡g?7۹cGSYHcⷱt_f]rQDMeM#͡}vi1ZCLtݾ1u8T60x٣foIN~ڹfS3#Cy诧TVFb8)JIPJ+o\X{1b,)~p| #Jl8bngٔ!`)* V=ppvG)w[m}{UhJʱpGM M4d) 3jw\dbR Yit椈k:jA:zGh7=񉻫woF'*]職SX8puVщ=g 3NswR) g,pUg _ &IVv {8"&1|$ RO !-HRRIRRJJ| 2]oI:%^ C'ڃKPtO{5k.gslg!@SG'apOZ,К\m(`]a*Ϯ:vx|ݬ47yV _~.*1tRWi.,((^ chNRkѹeauCanE&zRW>϶-PoV\ :/NOL\KD4sWϟxsǙm1(+0NЌh(OD\cQ&$ѐP@x7= R99?=vV\ үL,eHW|^7; Kyׅǥ0a&KL88J1גxv'2*I;* ߃K+cqD. O=IJR6q% =H K@"La(Fz ~ls&Cd 8j}^aq!8ȹА8΃`_G5g%`Jw>5;pMՙ m9)lF֯ JETJ*0//-J_MRD 1Cr1fK3{K=Uq!~ r r}?ט^:=(NJa`-'^PmL [͌՛ݡ[2OX: KKחaCo hT))+||D-`\fl.ą8z?8LjxUBLtu $$GWgg m99 ѺQa(@X^Zޕ+II&0 J# ][Ԯ_s).$ACC.Ccfx?^ APh&&kGWgW m9Ɣ+|V`Ό͔. //~n-0//J[@cR VJXC֯* 9:RmzK=Dž8ȝ~А_13aG);;{X""(Q+'n $GWg7 m9Ɣ>!ҥatWڕ~F1C>)b(x(}Z 5=ʨ\m\HY 1?3oPDPR 0pMvꬂٖ'6Y%. [)]6m?ЄD|H8[z,ͣN4F8(.r 8IŅH|ĉ'WiQPlFb2ɓ^I)IBHT>NOn$>!JahC!e!1Gg;YA:ˌ L5ln,4 28܄`X+w/ HPKq٣G9j0:z'5bC- e?U|P+BJC&ffF#͢!<4 \ߋ:3+"Zr =i 5ZlSz* G Шm:N l+c/fG0vvTyzGa{{ٳG_{<ꪜ&F'P%c;V{Ci(M4X:N i?ɌgECxb}; e$ԯ C1?aCMP@!iNbt0a#( !I{pCF)'w$͓QK18_zKr܄o}1t6PJ)uq?yyƅp ^kL;8/O@[w5]Ѝ)bN@#h QeNtq's GƢӄj0t6xH]&T!Ȭz4.`0lm 4QzLfrsѨ.Njh1 9ٻ-Cw83\N|^'9vwߔ*kkT*&{{}|8 XlZhL);:zLrs~h`Y dQ˄GΫ՛R7 BB4Mᖛ $jzsζ XU GǫҨ4.N.fpcFxX@@@)BBD(֭z>U'jl *7NtGG:^>tEhZek@Pߍ'dr_X540,nLX}#'DABD /xz{JF-9^?xH =vxEhx?FWd[h`Y4ܘsw>R" Cd>"8bp^zl7$tF\)ed $*`^$KdWKה_2+w8vFŘ7$m5Ύy;{j{?#LXki1txؘ/B7 aWkV!z֒x ιӑ?UG8}bS/v&7g_b6(oi d%ٰFLF OW7nz{x]dI7p\\lP z_}oi4အYbOun^&zdBL[k1RMeDLЄӏ6T tO6pR`ps0ξTvB 'iJ CŞfx\TKwBL^I]= zMeψr-(4~_?_f\ܚ.q$M a8`hqVS/CAJa! q)Oԋ \~KI!\by=1 ~'a@*NÄCH=RJɍ92zM4" +ilM8s3@ A=`  N;.\]XaC}\6@v{iB9x@96pVRykhjg3LJ9EQ𵯄|6]o^e514:Jh wbϦˏ\jȒqHK' syT׏6$9ejwY4LZT8݊CtMHcsǪ)3<\v0t`^Nj@c'czz+*26T(+f/#&AuqԆ4k 5 HwW͙K2j ;btZĞ|RsE\&Cy9|24$q;7P]~1X ǯ64jwY4LJU*@bxK-f-1t`$N&g?K}Qڶ=7P]~1*? T׏ PpAvךF(@b 9 9 n:DBe5 bХ1B{f`sr)o("u_lx1#WR w;̢aj V̥=G]7g,5Q"YIyDIJl,$BLuFkrGUd2z?EH%^[S\c4+ {9"D ୡ/h/h$qRH,ch!׈^ܣidn-46Vq>{ ^ҝ bC3]s5\-S{{nŪ Pcǻ鏎.')7t7_l9„ Ј^[Un.2{;`֪VFËUaLWh<7U8>5cY#_ lq\ƿgW21+W-)FO77=hlppkUGMcm᏷eIFYƎt3q Qiw[12zo^it`֪Vx5/Ƈ%*gDA=IFYjxjCr Y2f7Fʔ%X5xMÿclpZkI_5_ׁ?gy9\$n +x|Gb ojx,Z2J14p+-y Ft@c׷V]צbo6gUy?CqtNlGR pdB|p{P:%PR! |iIZ*n7ɇ?_x|ı;!b'>7ˉS}XͲtgh*>̦jP 5z۸!]>0ֿ֔-$r`,dAx#OOn|'~\.N/~Cc""[Z 5o6n֗Vcc"z:~jCfdjp  ][N)Sg.{sIfXbj՚?ƂF~EpK]|5JO itFKßndȶ,IsCjL;[)uL8Nr{\^NbwI~NI&\WS٠8S%M`TP,+dY1&ˊ6yj~Ex:&;$ p v$i>IF$aTNPc%TxN|m$-.IR|d^ nJCq*){6 CmjP0alG4#_^F|c#1^('9*VCv# u LIKmc-yMCE$A8[7ZM8)J博TmjP0Ԇ6 C!Q8f&FP[~R>G6&&N|M$7%PHJ:zBn;}۫VTjjΟ{WW7.411{Ϟ%v͚bR 7,+ccw|s>qw {T*B% B.<}U_QUE'&sfSJ ]ⴠ+Ii)s$TrI:7ؼ 8^Tx'OIT0CI=1V$*4FO3dz:10@L F3דjj83,?[R4gII\fHOtTm-P/_fws?q¼j 11F{47g:Usg2mjʰ 듒QSd( ] FGխrwwZ/t"2j]j]DDbbR5ՂTI}}AR55 /Titl賫ڵ]Uww=TH 7111F{LWFMMMzzjkka333 2ޗQfXmbZ*Ĥj4xB;y Y ѰpR557Z8l`f*-1{(@Љ_Ձf} &f@F$twuKa}ɤBhOO/pTm l`fPMN%+I8FU"Cl&Α)\(%2[i~HVq)l%٣$T0DK$vna0>H v3hXt4˻C1AÃ^m)&&YƋYOkiaCCܵ,GYY>r¢Fp\h؄: vmNЌ7dFGk C ii: 011!I[lkx'%{h(z^?{tt(+Kȅ :߻^ @aF1yyiR42!a]ʡCbٳ`ps1`QQzɔptO< -p0u5NoC8G0\WbbbCC@xŞ! gϞʂ}_.\x k43b)yy0rwqVb'&nh8,-P^ZO7[Z>4tezٿ*}B…/rϿym71byiO`k𮋏hC^c('x߆剉 tm/oZZ&^\?{磣ogeU>r/3:%mGcI>/FQP%qq$Ur:&n'JCIS` }+qR|>8@7%hjF͓.6 ‹>H tļrPJ1[slb(Pm`.]bqq880kA3C<p6Za5GWWn 4@mUY7Ϗ_-nd73ʼ: t r&))P6籱-{y.\0#rSrGP@AM$w˗w 3=L|뻯?h9;ۥk_ĉp7 澾\" =(yd_xPY$Bh2l--2;:&2 C݀#O bAT.eM-Mĉ~ 27;** R sk6a`rxPY$Eh2lԜ9'7 0Yax/wq <}t?CSSF miiPЇ>O8d27,--}}}]QQ3APxxx z%KMOra 薖Vpm1)MM=C_[[C'N\ ɬa8,-ePx T(J^a`rr&<)a @,Y'46ĉO]]=.>>A1^{niikNST|)a|SS &wyS@d2o(XZZFB '֯KNdId(ÚF46Ctr{ʓAXGaeĹ@IQ&[b+%i=,ߝ66. J\SRw|&lCA4bhb" Z0t>n^13ln6#@tQ#C &0]Sf()4J%蓕ZZ:`SuXN5q0%22Qk(twsƩG,z? `ԤՀQѤQtQ҈YY4u͚lbccxG(9R! ? `ԤՀQz夦Nsqq'}ruqqX(iĬ,(H1XXBgΜYf Y9rD \ +? @jFEI#&&* cmFF2m|rl[uj5kX(dd,pHw, pCpI!ԩ[P޺/гgrEqrQ҈YYԈgU./.93Y浬-66vPXJ 1b%&MKy $;Aܛ N )%v9<5$ư  jELf$2&TFU؊GPvI CN@D[a䛂](۵ah[W?k7CP;;YK  ,8X7P0 >嗹BM gӧ5CwNUlۗH.;;e bJ C;;[Zr.뉆;a^cc&`1;7p۶YOCw^R)HYSKv)-'8Bh0 miLH( /46ffN$}6lXlnnۍwVTІF ˖s?Y~|Gahgg'L'>QcwSƵN0wMܼ@w૯^RԳg/gҪH˂R--Wz҃tae⣳C7l37x͏wR-a ~sH凂=Ro[Z~ԟ'6j0T-|cN Iz#a' E$~9H4xQM/I}Ʉ;FOo?tJIlL$,vncK1?ƏgC1b9kLkpHhy,,8lmkqj(KKNʝK/qd,<4-vt(/O\=VˁȢÇ23kA Z[ZXXBI:аQXKaЎ;7"kji"GT>%< VN (BkKKEH-fkk=i@iب9smm&L/b؞Ge$ ?~|yyH0cccȑÇgffBɁ 7It5qwxkCaosN*\}#G.>Nxx\ff `xNJ(DBkK{!!QݤIa:ҀQMؒC"?*#ahG7{o5bhPPoSaxMPrrB Z[Z~da!lm&MӉ[ "CODc"=za%15"/J'ش{ġ$qb%'Q%1!o ź^L$()`h]7{HJg#dd$R|Ņf γg3??@i( Igeqoil1.?^'AJk=(3W:67wBa}~3O հ0LJΞ=O7P60(кuD?Pس9-MZmI7 {Q~~:ҰQ66V@eifff ꫛa{UUE:ÏR{Ϟ=ұФ}~BR tXXDžγgӉOrbh]ixQ*U@{PسvqV Ϟ2?pp_q}SbD<{"?Pj~Yݰ ꫗Wuu!Rڃž=}^}N.d2kTqyaa3y~~Q:аQcb- 1$8c֧JcyJa#:TvoՉ)IJ$ia)s*l 9Ti 66ďJc~3`\wQBC9 ±c\ 8Pɓ>Q[[͆mmG) ( %x/ Y:7-8_V Jh (4ڀT:hh_PR[H2) 5\Z@> =qbgYY(>P8vGZ/P&[_v5 qlm{#>z{XҀQ(`ŚTF  `:zĉ2 ±cǤPbOCC^pBmm-̆#"oV\|aJGB'9jl1ĉkee5FBر5>~nPP$҆S\\pa$̆(ڕC.P$LF 5lDU00w$'i'N QBCgBر_}@Gn.* lm?Gopt$44lԘۆJURBGԅ 1a{qpPw<am"Ii(m>vǜ1+&rk$IH}ߕc])kO $QE[QO⮞2p9T$q@YU5䥗tchqaM\SGT kn4GlMchMMH@J(ww>R>++d߾NqY֯niiN|4JqPЂ) C}}QZZ%Yrhhب' 3a< Y"9ܼoZ\0&_||nu2ZmC PȁŸ娽 cE+!3ɥ|vvv}}ɓ'=GԹP1+&___hH---djZ'>QchMMH@@PfE"խ6|啟88_ ]0@7@SG]JJv [++zA6%O*RMM/H@@gPNO.>͟Q(/ w*4ut|ZZz@&V=ta6+8;1Į$'Qa$ێXFm1bN%q'}b-$`Jt;piWtK΄D"X_+z*w񔞾m#$:~<2R{CCC٪UÚ뙣#w(9y2g 7B[Z2ssnl~Ma]C##̆:L"F^Z: .V&BGG[ 3@ɓ]˓ӎpTZ6ި򚎷G PUpS}GG9ɾAm:~|GD?xcZYY/q0T׎@vNJj*'haaP8yr7|S;>QcB;--eqԩ'O#bhbiiBCWڅ8::l5yrlyykJF?U KZY2{q0TN ipOz'S̙e55-@bMpc05crzǗ񝝵MM84F ImfNփ;vqsljj#\S5Ky6Z[gc2[gdxx+Y _g15BbkBbs0&R.n:vP#6atr5OcUL~XM(c-aPC ˋK`$:T쨄ѓ&~ZU hq-gŚ0_ZJMbL711KS~0Q1dQ";L68%?3N$(Ve5oIH'bI"GF7&Z <#4=)"!Vc(0Ԅ&1a CMj>+B.E=%INbI#H"X+Ib^b 6SE<=6~%IMi~0D"O5Ca5Υ %cl$' 5 CMjPDŽ& 5 B} majefȼ yEO LءdbRufdXd"[Ss,yPYfr0ys]-W9[c$Z Цjyd#;Z{85wRr-,arݱޡ&s 5vfƤLsrVT+wh5cB_Rưx8M+GۅcahSO>2)W؞)W`i]-ͅlr[&Bs]LJ~#;$Ā;5/5#(yR+=|y`x%yJ4 64]ԑIrrKvtʡMM Ƙ=Gਝsgdbʝ+5 Y(*y1\0G+Wl.W*߾-4ܹeD; \v護&!|稣|`TzNk5cFBYV{Ц~GdR:\\逥_hQsN*T?zdcR9 yN LL[Yc e[2|>zNZ($:v&1a5!VCb$lu$(?D":aڛ 1AbkOr$()ebwuM-V|''φp, )Z{ڕ;pmٙ;RfrW 06 ,n6q~-D*Mj53V?u=;}'t7yjW95vq_, &{E( o%@u6~2**y 7L稢M` 2{Y M[;Vg-1w,h/ޒfdp(ܬpC[/<=.(K*3x qsBUiA>Cw_N7 gn]!]=S(1U7o)wvx(]]:G锒ʒ((n(稢MEe9Pijn?]]닷lwrv(]BӴ3 7n?sҥB.[cʒ(C 7l3GQE69w?x--xc8J mZ:?鸾xKEдote^(K*Ap޸99zuv~>Cw>% 6)b:Vg>88EbKa 5OqK<3dǯLf&艵N zJ8)ME %\1Ru)aVlo418ӟ͈F%042D=z 0rn^'lklliN*~>GZq7٩0.ī2TMa;K=U 1t]mBhKڒq)3$(n';_Kb]%bw;3a~'@^hzhk͍In` r+? C`Ѿ (/P ?Rr\&:P/PF&V›âXy;_+bw wzF8 Ul=۷ok͍KN܍17-F sazOϰ)=(YZ 0r|k;7q]x;gLGgnm޺q󩛧0b9u?Qes?,&&"!A@~GuⲃZ4@TZY X5^Oncg '@^#l_͍n@`WeO s 4Ʀd I饕b]O~7ض']ϧg>G[uk͍n'P,uMRŐpH$6v$Ivb݈AP$J 2G ĊOn$@4 Ŋ$(1i'6U#t¾M1˒Tؐ>M K+`os '_cjʞ`lߣG`Єtv Dfͼ<(t85$,zkLN Ȓuzr; ]Of ͻ{?ztb9֜ƙ/t: Pӷ kK6M= 133G9+NB'ǹȬ-`)3 ݃%/%A>yL_xSZ@(,Y14J!pECa⣀--[{jY0 K+=}N#Wqw/nr7+{*`褰 /NP:qmgx;Rf UEz)>έۄəSNid]МpT;j{ 7${8gqD#MHsa Vvi`8^ X=G$' Y˼`) B`wK:E)>dxS@(,YdhOOz:]>A>14mIhZa(_ZA۷4bh{uܽeg7ًi_ĵkqq 2kk (XdPx%3ssX.(2RU 33NPYnМ~ 8e'(H#P-Yh'2 C ֜'`8ρ:~3 3%wN\}x\ ;( 2+H(t~WR^A 'ޯəKNPYzhOA=>pJ'hF M[weB-MZTX0>k6rN}_3K8g* 5´-W8kB: ҍj_MncG \CښٶT@{jW=n)|MHRZ5-2 5v/nԳ0!;8jN4tP=V:I1tCts 7?kk,η1u-W*ڨjs^.Zc]ֹJiռD`VSOyB`to>:e)⣳J[v 0k|,ЩsԘchنFǖ+-sǻ` 42si*X_ 5 k54%'GDCC~Y, uzsk96= r|xKםf-\*UUP(X^jy>ӓC2冺:s 7?xCh/"ÁP:o*5 -ӟ ^<P58wD3m+m"^hT7ROH!&- 1O=hO\ѥ2YI) ;馈C=jwC;ѽK;qq%%PrV'cai7C R \i#H|i3}Sb|C<{Q_v 533PXzi3EFn,>.ۜffn&аQFP`P o1TˬdpR3SbŽr\<{lP?hf W1;(k.#}(NETʬS…K8:5,&'g/ZCk`^+el ؔzI+Afe͟5.4_a13;EBaW:! C_?Nb(sc*_=*U,knb<96$7#id5=+[L U\Iz])Qث(VTDVzOb?׸@Fs@cr׀ Ju.Xo:gya՞fїl83S;pXґ.Uޑbhrn!wdk@#ujD v±s %\t.pn\!'a6NV/^|taJGBCJtk>(w&<J=|Hԧ }P,ڃGk@>Æser'WKverG@WW@@f-#&t ]P2])Xjaa [ }! X  'k*%dkg[L| ҉.]J; Z Qe\mb`  @'o?bhùsr֞;0+ @祼ĉY Pf-_ Q26A$(kU\u.p\aa'*UjNC>y{L։.}J7;wG04kXHPCO:1ĪGlL)Z8i'$q.MI;fC*ֿƗ$쳅=c'q `%(/"2HUSК6N<݃|L `X)M ?wXoqJNK sм6 Z(}/jOq=WFm>wn2Ck@"=UB{Dl/叾sN,BrڢJ΅+v C}Cq 2JfevDürUSBɢME  z\X}{ aT35m@%=]r %׷9yc m CjOY@u,%:*H/~nn q{RK+3dVj{v\iS(4(G/N bRBr`b1nD$ КOO=bs'oR= kTk^+nնo/O[ВlO"S+t R\lI|%m`[/7X1h;k4?m(zaf 2Ƥɰ$֯uW^XVFN5oov{kM*Hڶ^ZFY1i2l'9o?{?|Bs5ǤI+5m v_?k^P׮=&"b0AkbrgDD$nx4nHfRW}Lė_cm'/u.69,w㆒(X1=Xda<Ǽ&?MǦfpYB}G7fb,2lmӺVuc`+ d06/T{#=pCr+,.٤S˚-yf‰z:ov*+PUd4ܼ Цr}dz\q(S`b[eCmoӓ45# Y稣#;gKdZiye\BQ KFhR(+{:CH\ Kۅ&4yzIx1 7,s;j L\ټrMe6=\"ӓpCJ,-4uc`"fai"m55# w,LsN yD?#hPV+{CršCr,7)+VXȸPaiн{S3?ӱa39~uz -i`QB^諸ZnǠ ̜[^gOu7_';l8Kl)% QQ&@p/=GF:{)&2633^>nbQD! [5X{U[ % Q8 -ܛ稢ڹ^F9=WVl,sv*M}n(1V5A~mtKhѳ>'4D͋B¸8=G9{9w=VMe~ݫT\_\iâϒJO9;WZe6ֹW 06j{7sTQ&g/UF ӂ4Qbh_'Lw:/wvv(3@?}'P44D͛½{rrUT[Oi$P|-F+LGUX'UP2 $U%vf">8> ɄYd$JO(Q5M}#Y"Ma虿, St.P14ty),u픍m?IGXgٍgN}B_/Mkey/P`8+Pwؑ2bvƶ_ f£J zhN~հmϔ QچYsO?_#@c|=+bͬRgOO SR@d66P򍌄BwUttpr lka`ҥhR@(,~MZ0G$Υ$jEr}hHNrM,(^Eʸ]ĩ>Z[xˏKwUw$(\cZj^ X fϊF ?rT&\AO =5qunBi33z5? V̏$fw?`>i.J1C4iQy-.kK%2?Pi`ᑯ = p;N̏ۤsZ&4EI#mVl2{; g.j5egmIPX ʏ|U!j8á@D3?n 4GqiQuN`\4b(:^VHGYz_άymM֖,;(dHMMG:"8á@lƙi4k좤Cڬ8]lzꕽ/\ GS-mln)&@48 /LpCp3?nT[PzNg'W F E+_qxqܹ:ծk^{-k(d[@|hx pCX3?& ^cl1z $ )Mb鈴-#uFcv$${IW$ŨGb1$aV1PجrQ^*"8G= C;&'z Ca;f(M:I '[І 7>en#6oM=W)m,L H C;턵Yk 1;[~qe|x M_y fn*ngƪȴD(Y/5 ia(#axu e⣳C73xCnhsǖ_b^'LWZZq&}$)mlLX~(سGjVSB^^pbb|FCX݈sXoñ$V:bntƐnb$b@r/aCUXKRK@I"Pas`CެPz+vK >sWrr@Ohm9 I8fUrF҆ZZ;K?92Ti1Kw%ٞՄW▹) V0(zBk$XU^ [l40T bt=nai;l)w>*%< 0.K337hXWlUu=1 5>xF>2k2\hlpvzP̰;.t|_0t4k CAA#B)6-lfn.H"wP +.4^o԰1yE~QЮm8Q'C_}pya(0wD}o]U5!8X98ȬSƅAhf< g/_/8&&9 w%LWXY( ̄ɉI8=y'Pp!߉(_/`.Ii)< 6ϊ}p \E|ˈٵ %wACEO/J ՠpW:hOUndde?zHCw׀Rڛ #ȁDooΗ.jRm#"*eeNj^6T柂6: g1h|nXP҆naѹD2Z8JJs@zMv5¢ ʧ5{R-,С Y[a{L #ȃڒT+u>pAn/ Wka d-{L|e$ Z҆~#W, e%bk:C6<'W\@ՓJ QUڕO|`Ky߉YKH04kr؞vcm{\?Ms7пUZ#"*e.>z{M/X& 0lhInO⣃VZ;Eab܉]DNtRGD"Ǧ$(Wx#QJs=QaKQ1@.ϰrw\}vy_<4 6EvaMSo8H-=iIڏwY}ͧMchMoH@gJ(wKʮ qG6?-MZ(]04>waT54u|SZz Jfm Cun~l1wH@gP"eW%_[s򏻏*}mBaH`>|&׬/~1`W ?Y;: Zz Cfm764faIL,H-Gߘ0VYjzk@<^JzGzTpdki?Fq֖PV::stcNCV܂[1Ma]Ax{Ҥ-bh{i#Ti UnfgJ7scS z9mخ=hXds-,,dԌ@UCJA!tϪWpS5nJ Ksɳ|Oǻzw;"k /m+ t#bx )ȴF.bhUM-,- 'Ϛ\~?7Y t_@G/:^s14- 3W 7_?̿YWzoyECc#(c!==|^CJ:cƪW_Mׯ;YXZN5)xc(d5mG"cV/OԐ[o0nbAO(5$cK!dEˆս8mVx~&y`7]ЏU:| Ɩb/e6|o<\A?gamqSB=ŏ O?ij?6A@C_lgʨ9[zc:&G*v67.Y[4zNױ_}(G}q?Io7 F_\RG-qoo8W~K7߼t/6&~߯3\& $ʼn4Iry vD]J#R(nؼ+2 K!v~' ` kR4qLhq*|NH 볋&1*ĨjbI&1*DO%$DlX/[{W]PD$NQkrJ# δDeqx X)7XILXqH} HO0$& 5a CMbgH HwӍUJB'aºR|WKB`$\H걕'-$Ms44xw8*$& 5aILjPĄϊFgĊ6 x6X@\I(&1ԛĘr$Ɣ/MbL$)$ †8=&V*=i0K|NTB$&mǡ744&VJ/ͱQ c&2Eb.?8,ɖD pz̻$I)69J5hPĄ& 5aIL a(v!%8ʘJQ-qx p8Lc[[v 37QI8m3TUıIQ)[%Q .`| ݞu X/c~خ6;kƘ7Co^7J۵9m,Mw-{&+hf3kXB;06`{ٶAVG?g{]`Vҳs?c54̶C7^:ȺImvSvlʪ۸3ѫs?cI|ښV֮GKZ7؍^;۵6֦g~ۻ=VakCo?wOZٕ6֫g~w=j]aok7!n""i&|%aM$ O6ŨG|%/I&'ꎵ8)sK`[< b[[b Ɂ@$>Vc 1q#eOC{sa,IR3v52x|dX}f0aY/Gmy0y `xγ.od~H'La5&,`BYeĞ,jӰb$#5mgd۬B$Jd;irfH9VyNL|x0p?[?6%@(tu),Dc,h"Ld6X|س;  vx@XZ0\6MTk=ɅX$?3߇ǫ8JW2MH{JfSS }f,Y(JX|loēhi.Rg"ܩ{na=.%%s\߾<:\fcc/JN֙R4f,~޸LŇ=kYe)glDKak=߅y$tR f<-ogmg=-v/Ny [ 6_WV3eg-k ;XDKߔL5&Y&ah("Ap 쇄}e4p)aD DŽ/Bk4IQ̉bXJY|.5-z,a!3ƜOOKX8T)O}˘+cfM+Kd,c3v/9cv~zchC s#*ccd0Vf6c(.xċ6i"S̜R&PL{{ef0ox;(|i" P@1|?,ɉ}F_Cpm>CX@%w>NcٲF&ۍ1K[1EMdNn&>Z-M(-9ON^ZavƟyưA0tvb_qRX"+oEXfmNa ċ2|Sr&Ole_3t8(|^ aw?dK pbN_/F[jY04% X_3knd7MX߾]xa9̂S?t4azşŰ lX QoC.ܓXz%;X_مF~'P,]?L(ac"y1EE:e?H`PZg %q~sgCJTbL_ e($H$al$*5FfⅾK~!K5j7V$t$x$ ͓ Ɩ:ɋly%v\85?3deLf6S Cx3{ыg3?`0-`5$`{lP]3wdnqg8,6#ܖ~V{mʶkčqmklgfA9ɘ!d?e;<pЅCzqͦk ",AỎ,ڏVLgue4 潌g]WYH3cݘs.wmkD f2 2f tA);\a ta C4oɆ[6& lt6*̙;sdALd06ŅqDi@CX˛gыyel`0/Ri: [0 `(`kn? b؆~*Cc?P˾ч>DZkf3CAƬ0Ⱦ'SSX !{F ]ž+6+ c?F5sٔɖ@%SYs9 X&-.JXo''AغZ"*';܉yFa< Z$NKb'$>bo!rW. )NvG 1֛J#Y*rOϊCm+d̃1!},c6An2]>=^5ciq-ռ</y(ӄ}Tec4J%)P2BV̂?^ܿj:FiQV,RQk(,#-F䏗bh+R0álO9#8,?eڛp?GCfE`3!CmU!`e,tЩvfY"L ,ށɡPs[Lu=ݘC>y ƞg~ʶgX^23Ü3ٔ},'M/ kEI̦exVܟps&:T 31jjf9˂ieB` oSг?) &™ ƞg [ *Y 7evD.,BpS^̶z0+o,ήؼR?/;N5^ΖôPXʖ:0(,#Lr݂o_)>Sla[,foW,$-M5J%)2BV8?D E!af-g[`Z(,e@/.L1Up=ƞg;~? *Y$?hت&XFaN5"PGNi;i%҄Y؁/%I\k"LD} w7h 9◦"QK[4gC\6ZRƻ X76ᆡ0yztӄuOx5nc̛C 5?Y%f$1T*6-g `aٔ!bhn>~vM}+4v6Y&xdWXN> `E'8^l 6BrcJ;Bn q GU)ֱzYaٜOa`&xʙ_K>ήQZcw ^Usxd697:k" C̡勏nYulond޸Nkig:֔X"Kfyd%5S/.^c86s*HJdPXcP3ztt X}wmlcm;_m-M5 h;=Ⱦ":k=ntρ,_RX~X`P5_:<ZN[ÍlENgػ5g'-Mcҙd?¡Hv^S/qN@ b#VbR;3c!1=fh|K5$\bkpiؼF`ޕݓ K s& |1׆ZpjVJfe0^faq̭CFdaPϊx\/P8?H6^mEװ^ǟF&0.˴7af)F6׬b3wQ[cD$"Y;lK̼̀@!P bg&H%6"ckج^? hocL% uˏzJIsm(kV%Kώ0u>羦m;p /aPW(q:x7C#Y$Ya{op/U; ƬZc-Q,{S3g;fq>YV) w]k}02{'ŕ(+J(g߾ M,RmEdkؚ^ve)dZc `fۦƒЁޜes/%m̼m}m+;C7)FIZv3UY4O*hM'ɽ6 J}B("yH'd$$MOP%\Tʑ،؃29:%=Ll (gT}|yCwuo2JʇV xS3^)v`%~++lc̛C]$wsVpEa( p_q[ϊ.vaC/q6p3qD%ﲢRb:1'n117AŨSa} ~VkPԧK0[+'2'ݛ&.e*t4ə8ffs ue0 F}tjjV܇p5.x7cXKUpDIfwYG)Rq$ ^١c+_#>;N3t>HSYrAǹ 8? poxT.~x>AKoW+r"(x{3oRVk5֘c+Yp7ұA=a} `?;'1l&K։+'2\ w7l4JBavч$XdKCqy^d)a;4)Ƕ$;Mt؈Xb=뀉>AXef aX,3syiC}Fz=F9w0vǻÁݶ;J0t9?J-1й+լdaц QHL6JNtÁ r9tȬ .9JǗ!*D\`΢TKX ЧOC粰HT&jCt6ۭsLaIrj,C0t9ϑG>|\O! }U#5E8zj̱BWZcsY|$YiC4-d:isAIV0tcRo=aq%[)hCk5Fh هڗ8)b d'a.P`i*ܶ;2GrrǕǗ%|` SKak9e,A|\ɶ*Q:ޗIcJ`'UB HQБm.g[`}->_?"X.4!$D''!9Y$ɑXJk1".:G^c N<ɓ~)r\qd%%/v.G$^D>}&׷GnʃS w;OMyd<[ vйÛOItbɄZ1MchKPg*,$Ljcrx R31`QZEYp=2wxе,-|$.J@Ŝ ܰ Ot4ba.lMϱvqr Y 4iml?sBe!:s '3 }5e̡n0}dSauWpcu46T 'M>"j$TJ]Tz8A8kiJL8Ѩ_XВpډKNo׆J?5d9o.iW&Y=qzo?jC> D ьt'T>։1eGƘ7wȆM1sK.d>>FD^őVi4syt-BnmS93G24ÇZ03Ã+˧SCˆjH5Xʘ%oEݧGͰѤjDPi꣙.N9nSY(Зp5ÇZphxM SʽWeY0 tCFNq,Ҍ>,\FUCY..갨O3P ĩA# }wľ^ vȟZ䤥 wfA,Mn~2i1T -g2&&h04%VqF _F]\ȈGMؽo+f@R1]*Y%Ђ)3\OkwȆ1+K$B/]i/A7%*.l.*n*EC_M/>aZ~w4Jڱ_96C$5X7XyǦT@\5:cMOԊx3RPl !IDq*8.ل#cJq8PF%]=9oM|J%5`#mc̛3Nx"WX%w6d רһf $`zaMr\B?Ownl:azK6}KaH%].n}|&ٟ>c Wo؝ٯ0Kqwnv&j+.Z9 Kӗcr1':Kܟ\ce$ ۉ#.,IqIzl|)u0-F@l@VX+M mG'tx1$FPCMbT 5Q1$FPPcF&/ʥdp$һ::g Ł f51`$7=9)'I<->Xr"q{|oPĄ& 5aIL$@/| Gc#HPTI2p&L  H)8X&M׎SCa_c,f>$h:q`"Vɭq^+ 0Ԅ&1a CMj>CP} vMr%s4;!K O8'&8FQ ;n(ώɕ aլ4Yxv\8!DROJMbL71I)_ĘI'XGlEN,/ $vݰN$O⮄ 0xa3JN@v$%+b9Ʒx /7PORtMLq(J s# & 5 CMjP0YðHR oK7^O/b`ŸѕnI84 7H[a`%٘W>I@2=YJ5\J:(`ylF#sX[LYkjX{ưbniz7/o䉱]9miic2g3g$$gdghIF޼m%u~dykǜZhK[5&S}Vy沚5hIF޼nR?P]cvsjd ښgnI(kϨ7(cXqo^e|9mimc2g5lIih7Zzl:J[ZLYg^Ix=ژ4x'WORwbwlÄ{Kӄ!XJ%4U=6[it[ ݞ⠧D gH"$=pL՜ؼ$ _|ڳY?7;= f׫IŒ:3YD}fLqe-Phtp<rT,ѝyT_Gnv ` YE.O vrzxVնJ++,>z[YYB)'j3c„:Mny>ͅI*UΘь ,,w'ys˂D+ "2ZOFOn{+kSG :3ץL gƄSV,4m$M <*'\v,йy-kC{6INWq~~P#?Ҝ']?ὕu(c*:3S&h3cBdUX|<+Hv<GVvT;cVz]:G锷%{?tf~2q>3&_[sۣۅ|oJ+$Uh{Θ7I\$@RU%bHp%M=I(OcDq+.|scvlJv"/aMi'b)D f뒉NhxπyUś:+da9Z٤S*Xa C[fó PiPӖfXky6E2w{0|r_s3n[l{ w>'n2C{\rxǓzL(vv޼sr&' M-g5K \=12**y(l2eN ղ֖Sllpkq1gSdB`䆍2C{̘^^!;;o9U Vʨ ó,:g3P< SRxЖ%(@BӖiN6vh77EuW֑ y-kyr5A^!~у[V|oyڒ D?Nۧ'UF$O†)stbhgm4?Uh2"wR>(\؛*ww*orxaQrs& Hs3 S6*=f;;ꄞZUkN4Բ-S88~<ϦM Gϵ ޼]㝎[fuQ\t)Q AaÔsrtbmlZd[YzPt ÚB|q)U"$c!B$"&O'$`;clsx8R]ﻱ=v{4I)rNBb|aM0' &YU,ƕ%S ]A4$Db e_w{ޘn P,]뀡@Wy7c o⡦Il;TOMa蝥KUWww+BC׾XL ]+{$ XglLJYP1TZWy7;333 -^Z4iP`*%1p0aU#%XqK2p8V咅0Ky'Jr%W$t?6u`IR`z41trw@~Cز`NxqoHr-Źqbm ̜<( O󙧒mg<:h%ѣ-(nѰݽҊ[ "Yǚaj9 &0t 0va! 'e,7 Ku877k  2s`0XRi~R"CJEយ>J++X ""F30 (_{ȏ`h۲ڋ 6^ێGƋqޓ/t-g% E;K>Tm0:h%GC[Tyh/;YieAd]Dcme.< G04{Y⮋ ^׊11ω5~융/t-D[8 f2 %ݟTmh] '$ ]|0E-w:pLd,uK+`` k4>|;- Ёۅƴ`蒀%⣗W_6`h: f(.V۪/t-Z[uSd2W( ~Sm%t&݉idęD Z@̔Ҕa:ET 34儭EhTDݧF'IpLV%q*l]xK1֒2>MZԮqly7 K5WG[egLnN)qCŏ%g*Jh%짹ܨrYIZF$P[K@‚?CKQ}EE Nw.[Bai#j hxl9?^_kAh2 7KɥF$P[K8`F{}.[OpBڵ:.{yH"L Ar(<(G[/@WO!J=: iM$l^(]jkiSoe!w%mB=Oөv[<$ Ҡ  JV)\j2wǭi$]s2+/f}5$> ݤ9~ȷI{۳OP9[yYB&G\46׬(+f@o>xM&m?.3D'yk65&(BX0T"W@翼;هK33 ˁ`߲sn;C7)F|4 {gN|oQKKl~]l' SOz9>Rp*Ef.[7u//N;qnq%%PV}m;C7)Jed;3E;Zc`E_ R 0jeV(/o_I1T6@KH~J b% $&Z8PD$<H5vB"Y!@S˽gv*x3 Q%(WI+4 7.-lL;ǸR ye%AtcD启=`"VTֺC]$wgȘRv63V܇pibxc\] daFvwf)Vbiff.+.\Z֌M_,vq%z){3EZ rrӉ:7ZPWqwǮh!zqo²&hV܇piasq1aC/eʿr%Au%&IqqѤـO C/e_\9Q9Qp![t4Te>Jieaş.\Zx?:sk AC  CjK:GJ++ kTq|B:`m 1fᄤ0D[s $ ;v)q&XK\H|l4 X)!Ol ;c&Q;F"DF1tW=Ryji"sƝ%d:w!0xohM1t9OGF:Ч1fu S_#)Y49D5+ˆ6tyHhGZ ldz: &*!!=5Pk(_T'P6jL0tWX$tJ븻b)f:C_Y?Ze-q&*JCE{Gk;Ca҅Q$CټεCzGa9J+;MNNXt.qn~B&'kUJiҥ4$Kp'<$ /irABjJ;21;ia倘J6__ks>s)d'aNG XVwv$hqX`l>x)?ClQY;J 97Bf?PϓWaNiҷ4dPzGqCoCD>m( /INNQD"- Vi:%>:؟OטI$Cy%p((B8KyG,ʙKZs4$%]خaMq*zPK\\@'uxg{+7^/Oy!>lŒ6w(Vhԩ2ssKss =Qn+/CݫiF슍M-BnS==1:^6` tCseB:d@> P)zoӹP{@մyPv-BnS=C1\ǻLvo"}>w>ĖY5+vnIIN2U8~l*MOWK)>9orY5&Wr8Sr5iac絇w/B?VӘ甿]XPɕK5)W23?}2FNۅdҘ(N+9n~!Wwe0GҔ:s͏Gva;gmnQG>,5o\i\k&0cm~qg&=Bӏ٥rv7j+9W.-XC]0CQks_ť5jo2|+X# ,h 86$Xq.X*;O—u69h߉qbY|i.UQĵ6R CŶ 8'@1 U&1TJMbL71I)_ĘI'8;n/lkN$NZ~"Mđ`'Ho⠤>'Q⩈'$MUJfeq@('MjP0Ԅ& 5 C^cl(uZCL.&AC:ɖ}ұ:ثgiS%aq*lI <G{jL@ud )ph-^īɄ& 5 CMjP0P|5}0a#89f/|%-IVI]4)f>|OKM7~_\d(0JqDR _KU& K$TchI'&1ԛĘr$Ɣ/MbL$6#D,1~aeq=;b#|"D}5*qVz# p0J=U#=UR 4*'& 5aILjPD?~-r'JSIL/u~T$$qn@r,YĶDD#2y$UмlfMNB0uŊU<۷>C[WTѳ ok 7ٮe[kr?E FuEk۪6=;xO`70uŕUzvϏgмBMkDx$<1 D"\bT~6$@)Lɕ2q0>RjV1   Gc%;W >} )g.,)`XZ6yi6ihrc[Xr W\RB4Lѽ ТxfVd,w#v2 6܊X0li-MchOB{yRT+l6VX|ƍSuFOxomJ\2QcALչ Т +K xr߫Ysh) W gg2rE]֦MɁP\.%$DcAA Lѹ @ɢx+KKxsMWScQО&{uR@$T+TJ9gi{ t]O{kӡP\טόSunc`WQ<+KPR՜9J|JI.;=ػ$$JBQbq[ϕ v *ik~y=Mo%}ٹ3%$EcA3LYsEEVV7^=}6oZО~{t\V(m8l)omWй󔐅`Jε(~5Vܫ;GQMr M H۹YϦ.֖$ESGP$: 8(Iɭ7]w(jq|?N|Hz _MGڏƠWRۄSmՁ^[JG`'4 b3kإͬŽ-C+30tC*Cl;{8%[=S(_s3n[/Od0nsu;׷>\Ξ+X[Z9Y-iSlp+ѤURw6W33^^pq(h@ldl/J?Vfd!5uNhN ղ 8*Ӻb34` 7׷8\MiBӖb';{ܪ22$90 R P-ۀΞ3+-egS6-rW9?KmN-%-'QX+Ϯ=~ ꉡnH0'tN4Բ ?wi]jmizj [` xE˝&Rѐ8 R щZւ>Ξbmizv=winAյ4 šӷJ@q'ױ'քa&hNROyDc2oqzH\'"/XI@ Dm;9a|ib( e Cti_38X y#ФDƾ}yk\nZSEy?j̦xũr<|`w0 wQ& ҵ>ߡRB<ФG(Xطy%I7w` ղ *El& so߾e,{7P-ۀYS<=40 w K kA~zC N ̀oEXm^q曻Oa ղ *;Dl=3P(OvtyO?`#~wuLGp.11 Ctw.Bݹ`X߷yYsƛob4Բ *;JlݱS ]F %X7~c'O6(0 6vi ?-$6{(`{-jwvCv yCAfa OwT. 7J8z#MsKffH ٣w[Д9%6vI(KY2 ?P[p6И ]{,aYmōn}^y-/CAf! v`;>T{jH{ 6G/'>:Ga:knW O .}{\6aq~) ֖6AnPYXGBaOwOb6E#G">y:GeNYQN.ZgH#jL 5HL|Md|<4 cˆ8& O/qS_uy[%CB_y|MuV"YCAgEI c k%Ms뉕êDfk39WGww=qJ1TrSؾ}#\{%{~Vn9,|R-MtQ҂}27R_5o)jՇ?թvΎ[bke 5@ԕ#8e3չ.Rvܗ1`l=`h߾>bKʶ0CˌNkuv0 K:ũBNFjK7 U+XY0C۸_Q܊bגtj sō\mښu[}=C@WG D  C 2wtSI1TϚ,g_KtuvuW*sczZx۷5ǖ/T~g*Hռy#ᆡj,%E|tS*g͒[Yy_KO|4(ah Zo5g6tkRْ3ئ*UJyG0Tp(KTR n~m˭lƹג:Gca=M"-0x#P#%/mVE-gyUחScP,L|tSIѐl~g=/{%Ku2l-ahZ}&R511ba}lV/KyA|tSyJ1ToCn_KoscRKPTF$;p8$6_>b;N̓c=+Nؿ=RjV"$$Iz bO@ 8IchאS{YD:SF+;[+xE(Z+gp@I`G4? ݤ*F^4C.^$%`kfqY𹰁#c|Qx5^p*(Wˁb;[k@ɾ}M;C7)JRy}R'+gO [0Fzy NEݻѱ!?_C/WTeK``3f@(?|3tb(H^t4,-]Ə<(ahWTQ뺽ǹjrőw XrFwI1T9*g1j?A$^EKw8 YۆM14+Rp*w^5sF}N_"`+( oIPr{gAnNO C/mH9P&J.2F_qﯭ533[; nDne,+>nNK㏷6ʯUe,0h6r!|ŅKk v #qr+`Yqs2:ׄ?q\x\5;ia͗+]\1 }H, >|?:so ACې[Ɂeík2x-#a:I*J!|ŅKkο sLג[)eiu~Cт]3qbK|O(^ē{IID|ѱ/9@ VT$,vr8R{q]kWJT 1 <ݯM91"+4aܜꆡ!0xohG1T &\ċ5Swոyy(L=||.d$ ][0.pV+eKNN9qDN vCۀnE|X>u6йyفL}<1@Sڵ;krrDPG?ҾĹ2'W!ĦNN); n WbT ss12.ORɕ.bI' T85cHdG~;n[sV{S^_.,wqL041 j<(DMjjPzP#m;ׯw6#2C5B_e2(.Z%DV"FZ՜4nSC0OvOʒ?ɽ9̚zg;!aPM;—j|nBfɿWr`7t.X5 >ѻv{5PzT#m$'+7w[Qe0j:^.<ǯ'i$I Hh^Mj*.:Z]xݻñՆb<"Z=3Icxv!'UOb(*#K|SOTK`&qp& 'V8>P(D}jN1+5lǚv5XN;{)|>\̹y߁5Zg~\Q; I%͏;]F=Wv?Ꮞ mH\lـ7M!k;{ʛM?fۀkl&RyK; 61jL)6/g*g'q=E<"GC*nƷ8r;I,ΕhI|ǘe1b-턛plM*ɮg#&P!.k0a迴ĘRocES41OD$6߱ݡ#IS#ɍ/VgJq{|-AIOiF"lcc>&5'I+|N|%>I$M[W$=l8L7 CMjP0Ԅ&RJ}}i3:!HHQLr$ ⰣR%mqGQqgl49ܛ'd N$T*V?z)/UKKu  nePĄ& 5aIL a(vW8b4V.?ĢX"? G5"J$TD$@$ /Nd6Jj@YPi| hII)&1\41KS~0G&DH|eqFIONR+eK$K="i?ŤԷl56Q &RW7k c&!rE{{|d=MhPĄ& 5aI4J1iaZ%$b(ɇ$^s$:1(&5<D'ISsF5$6'%r"Y?&QoUO ì(OR86p}&[Y[LYkjX{zvo+w^-MOCJz[|9m5ic2gm[g֔%ggԨ0kU+mm׌9۵VhY5&S}ֶy벚5zדЁ >~'vm55c2gmm[֔gԨ0ko~/mm׍vխm5mc2gm5om)io7Z¬ w]t>=`+m5c2gmhzkcDZ7BB&%toޱ #v{LO$$q1 גlص974'oILiL%o;P!ȉIl 8Lmz\,)rXZŔa@Xn>S(x9XYЦV-!"!kјr%IS.`zjJuEQ\Ƌ#m?󙑑c3G FUZ8{7s`|Di ]7u)qV%s_G^bRW;$ ׍"\cYM$++ph$Si<ǮJ?^Obpb?Gۙ;}HC,e?>8ϥk(B2Pi蕊"kkk--,fmW+(Hы[.9TlXEEtjl՚7;kWT˻kn;C0%M_0n8\ƝV DCvD$ ĤE-KDRM5p WG2ty,=ּƝ_~u͋cV3rWVWg|++=]=ghݎʼU)19z1tC0QJs8𱫣W{e Q#*Kj=9$ԟgl>IZ9⒰2]MJ8c}i($ $\(I}R0 G,:ŅQ Ų\?vB y` ECh[])0(PW3>2`{i{z>۽ъ1ep@9)'yhi/Ko2CϿV祈u s%e3CW<6X:6 "ܪKy) }-o5,JL8j>Pi|cK˒{m}%7g7g@9u@:&8 Fƅ M /GEz zNR^Ļ`_R*mu)ztraIg^]1˾ߗ`{K_ZVkg^޷V*`@9u  #@"^  J@եM?ͱ7-<CW~RҲeOϟ{(r͛Ӈyr|.2C1=C&D$DDF zہ6>flX.ʖ7Z5W֟y FC,~_e/==kw_wY淛҇ہr|.eb{F&ƅ MH I/GEedpa!t[] (0(5sâ{μ=P,~Kk?Wۛ?k?>|"( Ƿ~Ll(q}p7)=I) 3N!&QpjQB1yl%I1,1q:^̸ؓ9YQYj5A>:1Oم#LML)#T>ny)c/\*m0( s'a }gx eZn#:!%IVK$^.٣pm8V~S; 0u07~w.thT0VcC'vu/]/:"Kekؼ}`J+Xa(@X~jݻPNHI/AHN3x0E7(8Ν Fj4A>>:1tRjx…:Flm}ܚoL#FdI]ie}h`脔 ~~%0hZ\N\]?1^~S;O  "7w~ 8 h5 h8)uxgMML]]#"TOf1".6J &2CSg}ȏ`脔i~!%0hZ\o虛4E~S;bia"7w?/Og? Fj܂|ubԙޮ _+"(Nekؼ`QJ5  I]1u$$op(ǞEl"{x'%y>DUzp2>nB1xJL$*fbrr)VZ{Li$ JbŞf!ҏE lYU;Ƿr`zEeG_X,V6tAKO^lXYiqӃq/M 7n~lVn衺SVSSd0"[k 70 Q۵vVLٸ~V/QKP@%'r1 ;?n:x1\7n8~)Q$[ϭ<] |Qo]T5nYeY)@)Lpp.&?y)xad~y)ڲ8UCS*- 5n ȼX]LQ[ÀVϙ}Edܮf?*A)LO.WɆEU?n$Nlqvp@ǸV]LQbǁހVYu?QiÝwjl}j^kڲqe{BGP@%'~O6,ja-ֶUU?n8 _R&bCo 8 lSݵ>G_)/_9/3O/M۵vKe@)L  H{p 4ɫ? L1卟m׋w8 ߄R&a:cI<%N;]8(l7nHd׉Y$'I;!E)Z8_"'|i>8"ys&KI |r'fMWxA0Ucy̔K\jpڊsג  ;8H1T: A.5ےshSVZwd^|cØ bh5qt|Q5^.$c8j)/kRS:&O*(0T31ItqTK1tݼ f'_YBiAZܠ`o{2V7b襦&O;/Z h4 RSZϧ4PJ5gDQ_ryl˖C6EƵF ti愙V^.^$L5*QjJk#A)/ǁf9ؽ*Eu֙|$<ءM"#bhWF tk愥V^.$@?zSk%yrX C5*9/]=nN&aǶ|~hSkZ\^dp|/c(̑ d9|x"ĿH'xT}SKVGOh*iaX))A H%EZo5 T$J^ t#s0H/#-x`VP`i9ٲ䆊cR N-\sPsmZY{#cM=Ј '!H`~s3SZMlΎR 5-'ȖǤ*;[Gha~6,Bh:mJ]풆y>D:;ݸIG sYF5o_\e9o\3kZHP [w0<&Ј /!Iw, 673sP+a6,CP14/%QӍ~Ҍ"1/ټ9f`YPմP[嗷B|bhDP$;[D˫:`^4Uch^JbO _?82$R̠/=HYP`i9@l/axLABn(lyF773wP;TmلPv K%`o܃uf/g+G6û$΂cMY @d_y0<&Ј8!Iw52$A S 0pv4#-MRu39S)_M$W-%@ {I;bwM *?R E cc$11F Xcy覵ed.FRO+:&&S|8:bivܿC=\)P]qLo! =B6^Ҡ҃e2ܞ©١~z() 3~UͰr!u_1ŇC L`Dr; AV Err P#Z$.Jū+;F|}u&&&M%zJ~yM0<'"P1~)'h2CB' ;O|8:4`^_߄v.?@??@i\nPk+k Err)P背 :!+B' [˻N|8:4< '?p9ccu;Z[){KvF|JkP bpC[+M$zv;`?O } %? cc?%t&V`kOjѓOIq<Έ'QݓQ8̉ߑ,JHnKW @x5pQO'p>ϔ׋eSo[:t.~QoG1T: ~\pxc(vL=| xd1 Q+-/5uXg@7C0U}HZeA, ꜆M?sb@^;0L m?۰.)O633@}BOC|{7̱p-8t;e-.-;]^1tֶvW.R(yh=JǕCOаl\4!X~6/n7Vbh{F|NyJ33sizػጭwv՝P+5"ַt\8t;e㪠 `~J\(*{pנ^PRx$3)<$=TׇDZ҃pƽt'oXs)0iq%\@^i4g $ẓq%.8ē.|.`/A0=b m\ }K ⱴIR4`X) O 9utCy()JM#ėVrU^ } ng8WTh m\ %b%!$ȻTʙWAkiavlKށGwG>T1tv`Ц,Š4B|5׋mK#fZ^g}ǻXU9 m\3PS+m< &Ela&ꞩK8 `W ѱ4; V&)J@cH!WV+,az2%3ڸf HX@v+džm%# G@cciv^F(*")J@cǒC|} h[]ZIJZkA=]ǔU;cb&Ec(y^xx!@cGcJk%\XQTA҆C|C _.VX(`z1Ը5 a1v.OR;cÒE(ܹO^o֖0W i]hGbJk ZQTGR>L'/~ж%L1H"DH!vˑMsrJr&,); I$,+µt((Q˧?t7'P ;1C;k333V9oX/oW]Ϳs֯w Z 4hÂ"Ƶ2Cu-_qaqZӼ~9$7'7҄lPF-.yRة NIh\swymkR 4l BP2Cu-qa)*}y M#RMLLMMLs;)%j_ U(zC˿r CaFmX*_&S|0zJ̋7>OB7I"|4lcZťId'LŸx8J8ZGMH8@_(;ޚ !L[3?jd7r)J-\h\j|biznvYT~Lv׋ >Q >1$Ssa'Ej[C #"zsy9'q;FghoKwq=&9\5FONގD`?+NNYgkB\8-98 7FahIahI>.Y݈k ȅ+hb\w\S_bNVRSJxb >> >EH5vIC xeb"BcN_IcO~'='0f7)Ǝơ8xD@¼Qv xx(1@ORs^4v,Kv1SM F Rl߈V]"c+MBahIah}0qReHT%/8g&mz '* b!,b#{"aI"GGii*Is?#, $UTq*~_W5^Ndv۷ƞmo.^윩1咓'Z[{oOilLV:壏׬۳'G1'O.imi͋u/m>qz^˗G@D"I= eq=N<HBNt#hI 4DsVc*N42+@Ť7zzjYBТ"3Xn2;z:oF&#Yf}]aJCVuuX[KDd4:Z'$-* R(5xq`Z$JT`9{@{q#Fp55e$%y|fHL_Ah||T]iww 7 Pǻ.[u =thVk@@(V047wŋkD޽s]7s 䶷ު1"II!:92(33\5[ cWZɼcu Cڤj"}EEcfffI/)4Ri@{뭍#F >))Z3#GFffXƵ{A03>>bٲi]CiڄBEEE //^ky뭷FE)))I3#GtF|[u Cjje+NxtM4˵*+6ouqMM璒t>3r"Ah0z/JS-k0$9$Eq^>? mҪ$̠$^Zs JI=w% X#1qK/an;s uI9\F%<RmJ#f̝>dC9ܼ?9--ٌmt4ǯPVyXJ~ܲ(]ikjʍ'ln}vo2C󜝭u#>7ou|)f3f LUUC$RvwP OI [< J+pumoM*!Ct͛ϟ_}KK3&o1wk~|Y10t޼䔔zr˖(@]i%^e867owvWWm޼׶o1#W0mٲ̗l A#FD2o^AJJ^4|,ZIձ@l777;;;;߯wo[f̘פm 7o^JJ^4ܲefR} 7}n|۷1c`2n۶wN%Wq11b (JI [9|;**\]I1IDB0Iu!ˍ0Σ;,JRvq:/1w!KqV.O'up8ꔜz/}}q>9gYa 'M"DZ>J h2.bhB|p9j è(6iR0vٲ[ZXCgg<X^gϞ.aep0KNo2C1qqC"#Q" b_cKKQCCb}}™3(ۗ/TzWZL2ӽaM@9~|BW0P_O04!! 2[5*8=}8 ( Ǐo GGGG MHH/GפmDAA-[&oiiihh?s FCݳg#iebFG'ť MHHL/G t O4Cg@A熆{Μ%}|+~s0axqP@JIo|'N>RMP|$vJC$q!'rp& W&KK)>yzr(Z-N\ˋegsʽ~q1׃^qzrI~~ٳpC'LSiiޘyg<څ EScb\@,-͂A0 收?h` &x{ۉƵ|FJ@;7+zag 0!IVKK$AA.'ǵ<8ĉ%Sbb@,-͡9(fåFj@9i0ooҸV2%8 O={v70 R8 l\wwۣGNj$'~שּׁ̗,󅵵1ee!RXD-Aio/K@O>b4@RdkkCwkwݛ)/8fd^;ݽѣ S~7BaO/v.+ƪT֠KWW'<O64LeKj[[˪TqdKUSzV0 ի&k}jiyֺXoϿV[;lX0p \'“ w,ZpuxGq<8{3zqիW溻=zTIZ[[[VV@),,TT.]]]?x1*EÖ[[۪*NobC 8 lꭹS}"T*3O>T۵~l@), ~.]]>xa?([Z~Z/1va:*c Iǥ{x/c(.9DD'5IM$p=>`! 0W".A%=2^ݽ$#Jf@*3H(vD{NJjH&J$71K8&|𵤄C:; sJyC 3\U=yKy3>;xS<$=+g txA^^v$N0Ƙ cr&N 9l<ʐQjjǻR^P`Fc5g(׭nffrd^[|`Ku3gVxy9גgpdnn3>\؎i(55cDC9sK(׭`ffz.[u;^4skk+//ZRHGZ[7+RSS%BPF5gDQ ұk%ݱc[ڔzҥ3g////ZRRp$j49s戗...R4\nɓ'InKnkZ[zyג @:|]NXXp`/wx+q`F4gS⥋(׭ɿ]lս7uHO'ydYZXRǪp+I½aGKOl$[؃n;.:q$g%R%|7W1м I2"ImiL+C&;P~~N"8yOOT*?zt#U11~}@iFP/DaxL ^Bn4{ɴv KquuF??wiFQDDoW}ȑ11gAMpe/P(XƵy-!W^Ʀ_hм'ѣG9 5m4Ph[6lǤh!6^k7Kӧ ninnպ՚ܩ@=zx$YP`i+Ǥ@'64Uc(vv#ɑs&ɱćG*YAxg"u{Bқ$VDɶ>>04O8U#H!z2ы3aғpSRal?tb5Gee%EԸ{7gP}Q9!׿Ry|\Nm Pcy{ ~ּ7ԥ+5u;Z[)CLMMmもW*B'ÇZ[.>Ll~;Ƶ2d򽃡 E2_^Ц ߊ->E,>|Õu&&&M%@ U$1{ɴv R/++'h>?CW*O+7jptt(JXƵׄ'?`p9~>¯ E񲲲QGtWUÇ N|8::a?/V=ֶ@ee:~ oAʻ4uj @|JJ_rp[kmwGG'<|&qzJ"ufNL('R{UL8d(Ɏ" }̋.i mc-f%}r"4S^',8U.*rnwE.h͚ű(!4/_fvqMĄtHSa)PqM P 5,쁻TԽ^oćwLҡI__9Skkkqrɮ]ij%,- ;ߒeYY4!l\+ mo_'lXw˓LGFD6vx^!OWaX}   Mg? &VT&F@qCZɼL+1q HXXqR;ccpl%`_qXÏ&Z`W ѣci<F("Fe\_ƅ WW*j=',,_~RRJv MdL2  :zhl={R + Ih mll p?))Kv& M}m9s{P22 --\@ > +ѹ4{rRMVTԑd#H@L\"+z"ElRZB4NUx ;Hw\x@1KNz™7;pYHDL)1Z%0[㓥p+UnTr7Ena_2^"RAGҏ \1QXpd\ess04>%*-_EPz䇀8CZ %85dZ^\5ץ~M__bժXC->޵p4*J|0lxq2S@쉁0_LҡqN{1Tr>X/~͋V iĈ?^w1DE,_>.^\*''@sB'J:je4Z7qqa4i jn&zj~55\Ш˗OǦ4vc0Pv4q^{mc333h5lؠ c8{1Tq_ oLLLssD$󉏏%**jtőQB@9]zky?qq)*5|J..;vgǧԃ5r_Pz({n/-CZDl434*T$uFP>nlR9>BR֞4Ji'R6I*vco%%!)9t) 8L>H8J1.wZ=wgQ>ӓ'ӟriȱc9gBn|Ld:1=[ &x?vi%^yG5<^8Jر-7BKd@in۔G>}S&>ǎ;|ܪϔko n8pȑOiȱc>;K=q!$LrM꥓=qe% /=2RrdCr,"=űp&UԎ$mɾ<.O^pUwra'c=yIפOzRIO>I}sv8IJ,Hj!~yYT鎒4"&x{Q$! OҒpqV<./豖Jܥx50CC0C>}.uJ$xID))O\bʼn;Ғx:_dr'qK 3$PEf'RgIBahahahߧC{"xP; F1Rzʔl)+xρAq$87< cI*‚U"J29MJg]ȸ)D"ڞIIi}ғ3=*퓞rrN0"Dzc09Ca$3J78 c%Hi-RL`5$ETZ\%% ZN$eΒj(yR3lGz0>X> > > ÄJ e8/Ԑǻ!JDŽR/(B1MpA/&)Nb0.T*'.?KX3) W 8;h!,>Xc_YUz[ n/vۏN<5ְ2$3NW0%WZo&m?؜j]o؟f[ܞS醛{1k.n]'5iom?6ytmyk95@;kO~D{&^u_IMg_;{ml^c]klؿhͶ9{N7d\݋|vkoc k5oXm͞S{ 77Vb_mzdǎ567G׮5߿f۶=N9xwq %ޘ&_1JQnB .CupwY{~S7q^(Ǟ`%щS$Gp\/N'g <CLy&˝J[!kv&|mM@Ʒ.t%e~fXYt_h>{_2 SٲL2{駮CYZ747|͢)|PJb0CZ長.5i:c3|]c T2WV Ou]״dcvhj]uKH 7/\;e9_\SZyhZ֐k/ `8ubDz (M&e|fؠ̢pAhmat,>Rm5`6>5&`]Tu;^ecZ7i4 i慛NImyWl!2Y-,RmSQWd8uq!4OʊȱE#]UX|}ÀhNRZiݴ i 慛r5Y*+ ^9ߡùoH\SRVgFY)F~j倁S5,3dXaV[BZy)S«Jj͢iƍp4ߺxqD:]ߦs璲t>3r̢"Ahd,@{_~T GMRA"BH8jSzjI2則-"U7MpVD4"%xt-y3|P FhCb>ܩ=\Q\X=4LިÅWݭuTDNʩOt7Uo+R!rwP Oҋ[=(QJs+"\lGj{G+'th6_]2112 ߟR'O{ْP&f_Y* fǀ#ebhc8 *9%g^ rdbQsWԍvR['G & ]r)V3$8|u_ |Ju60߶w:Yq _{|=z ڮ:@ȫP2bL$(V-n>Xܩa`W/{Șdpafgwg~ySm{g۩Zq CF'FzG0tުy)9)zpˡ-nH1wj.~&~]ڏɸWO;oN~y 7<( FʼURrrbC@@S+\ݓ&]G֟ǩK8zGm}y|$&[x$`]A~D$T*=DD)2+~p4@\Go0PR(:8.cYzΓGbhB~S`Pl=|bw{q{8pY+r+&^ruF::9.ŕsexcDoJB[3c_cE $>c(}3彿QgM2`V0P@5A 0(SdZbD߸qexgv؁q[f &T?˖W7\gҙW` Ų|9\( ǿZL w,0C=CR:8/c'aI g~žƖhؿ~O_e|lsӹz( ǿڪ?weO7˿>7oeq?h2.%`Cb2<6<}b:~n{]ȨI3'u C{([~niPg0bw~sM0+xP@u\ɸ7nF'&ƥ upv.?_ M8QP56Ҫy[~a={|=P,Ο_F۟}t ^_}C&P^Le8+.xwJ88O$>^=.YʘITF8Y^%=/N{D+KfVxRj@T%^bgs1pANv)s{skC;jzp7,&K+) @i>c'vn,(\7Nɼ\frJ5'( skd&o{ ̟xzJ/L.so%#bief48S|~J:(^'N`'^fj 0&Cx 7p2˿͟5Z ?pd!.jefYLyP,8O8 Du wщfp/3 }jQa $ ӢB0^ ;q ?+@~C>S;٥\<=\M;%I~SI bie <8>NO?g `W щfz#|ݔj}}cD\LWme^ra .dfx}J9z@ =ͩK+ˠ P,m_zyBZ7mPxN4ˌ @Z }2v^qc5֬ׯa >/.-u_ vMC7$%0P,P_89j܂ub褙3ˌB@Z }2L vRA7Mj xJ;g3ocϥh([)=h^Db1EO*ޗDŽGr#I+ғU(&|ޗBI iҚS+WHQ" g3>>۰t%gz\G> V+bl8p.?( }pmÓ ޤ3cU}h;xAud&o{褔rAѮOo+kK1eU!lA) D-AiW h6O䗗bhEv>_K6n7j_z ¹sP@݃KO~lؿe-?lkgCva:vN nPN\`GBi:aH$Cjw8U)$H_SDD 9/.ď$ qTvJ1t ff'^E tV_K*t8V7b(F:Qg06<8rjM_4d T. jTs(^x:J1ty+E ҭco9Ժ)-/.2>1ݹj3NPX{._~egs?3CO|e9 8i<5GttẝN~}ڕCݛ^}׉ t?8c!ǧ_,-_j\G#r[%cM[)noaxLqs e4 Ԙ[jݬܩ@F{C^$`PմE\UǤ$6uC-K} fnauSks%="Ls9zeOb@- @aw0<&Ј8/!7=K- o;I3:1o`F;5HT/L1ZW^<昤%X8{Ǥ$6uCȄx/g_a#[kݴj:wj.A !z#I)(ƚh(n]j~y7cR4r]1o`dMN $*mvw@@Rv|G\9)KRIE(0ִE@tVʻć1)F MJxIFb"'togq%>ǒG {ObTGqSiUNJG\TYh#b;IU'- Mq0(>I\Cу-wٹ|/W Si%ǩ+Uܖ7|+Vqu:ML8gpt"\盺Ce&o{B WM9SԚP`T)fap[Vb~yG': =ܞ/obb(0hP}c!ze+N9ʩ5#ذO1>5 (쏵TY 5+VUޮ311YAէD_+-:Z*u&:Ս*DlywWiԚl`wmg,UTY+,-Uᶆ'>J0p +tC5C_vc!z+rsSk4>nxӠ APUA*R+nwN'hx0wC8V7b!zw=OSkju _Rox~U-rmwG'& =οrㆡ LdI9q9R "RIN  C0|l=Nz'K@8Wr&)vmbG,^7$Lqq>9T;%6gFc(3cm,]'K\WYZ"p%вhrVqb("O{ CqwgPx7((V^1t9vv׉j5k_Z/p вxha8 ι;+MCWf;=d5ֈ52 H?OC=ub4u<|=HSߡ?Aò2hr֥.bh^ }w8{xIM:e3vvծ' [ZY)v`hYU4tㆡɇIAsR {'W5py׌1Êͥ%9ɡJ$@z; "U yRp4a`: G) }.w/g甌B.zvf>{ЅOs+}4{9.=uXQGS>Lq`z/= ؜ \_l{'dZZ] +΍Ŧ*CA+H')  ӸpugJZ7Mahcs#HXLm~w (V>?3ЅO/CGƦg+UC +*H!" XF`hcs3HXLhݽ msA(,>\h2fϩS f|;§CGb˕*աV`Њ: `G=>J6I".SI'pFÔIbK;pQ5EBZYMRW%&HLq4J/-$)/'_W%3JJo#PGwCOvG[(!3s6{AT.l .S@9~yv ve,#0TG( [^'6 B?zeC->5#6] Ta8yx+<JN[8QYf#G)N9~'tk*av$0A419 gp>^RrI:Iy,r=y"!wSnD"?Juzn;J\hPSd&2l 7\Q >Q >1C18!lRG1Z&EpxW=HL:Aڤk\]Z;w8RܑcRZ<¬)޾4R&Qµdahahaha N`HgmQq mǕo@r%)AZth2$R$^ׄ(QW}ɤ?vȱIx@K\ahIahI>.1JI~;R{rHZ+չ҈\1aĩĞKR$la_)>M g 3Qq:ȬqH+8J[7}҃R'=)'`ޣ>9!<8_ 9\HNB}dG:<>H'ep%”"b(<7x$0C( +_q W/)}ڇ}҇}ڇ}b\"\8 btin; bqgQq<^II#yw(MxʓOi5{鋓rK$ `,J61Tx17Zܸ'$W6廂Y2vXw1m2t/zvSc诬*˻͊{ꮱ,q; 4`dLFO{1W*[|IMwگ&[MrNY`0_io2|0W*~hE؜SwdO70Cbeun֫vS&h?k֜b{ 4uqfأ[Nmv* wƶb 4P~F% Pc&A1RbO!āR)G4Dy($g\.R ɐjS:Qx^q&9uIz=lk KD8G1͛MaL blO54/2+z%cj2Xacئth meYn:7YoLUlfD;X@»ƥcYdjԩ̵Eb`t~57=ܤ#FE&#+0pah+[Xy†Z03~y6qMY%㪊3SxL'锋"rb!%Y dT2 1mg07~ nґIfZf M2Ǯch+4i,߼^’~[^l!&rmLgC@9곸L_?@"4CL\Vn"citC2_!ucl-ngu*gh-5$/[l(XSK¦/{jx!p,Yt-Ө3LH 6_`;u;ۮ2MliZIKh^dӹ{bY%RT 3$3C1NlDNŔR&jCȆ8$;`JIRTZH+'F ; ɶ>qORNl6G`"?U?ҿ^eWݙ;o~x0t0za9T꼘=vOJIf7b, %84,m8gʓNB8V 9DCJ+.'Os.' 8TZ^ʓu ]J Edo rp#`,DR$|tDDǨm4ƞDGd'׮Ȧ1qz2u"sNaCY,Xe<y}_Ҙ3/RT5~Ʋ ( _ zMOL)b<C2uMf,0P,io '̔Yx<'od Ph X~X#+HIE6`Z?67k30L=/cYDw^Icp0kmpN`2|Ŷ5=ɒ|V;71#[ d2C6;1Mn,Ǘydzd&aՠ$hѯ{q"Ke|Ŏ5=ßY~ְ` r ewĜ mI/i,EgBYb K,g3@s q"݂JIf2&ƒ ŘlOeS5%H%ZR)뎓ٱSc*΂'$;$Jz$΋QxC&v1$b& ˓+9t(.(1Wf1vc诼yt101-0$^(xKCK  ݭx2&~V@CCLa诬d 2wp_[ҥϓH{^MLb. V,ك`r2@R3XAeaBC?Yke;Y5 W6(&+“8 ņ]gcYPoLgR6ē} 5 ,X10n l]! djfVP@jOɟ952;l-@w=&'? `] RcY$P/TN)șd3 ba3:.;PF275+( lP\`h`͡lXcz-4e&^13[*ۮwnIQd.eOp?*e@rCYvy>5u$߰SI,ĊY PB|L VP@j\ɸ}<cYӆ :M %OYݟR lvg>eZ+uu]߰oX ca(BVLmԲZIf2&H˸vIHФ4Hΐ MDĮDrNɗ"UCΑ'GNV"҄!\a%T\ ׍ŒK=+vO?"EijRt9߰t0͘p(ƾ ^bo \xpsXu,e~Z.( gK99?gVd,srzݮ/*bADYahd`gjdm`jL7lx|#2d.( gK(r4痗ӿbl-v}eWxe.Ayu{g 7q:4Y2s"~ lB)c2d?vr==)JCAіrY8zL2nחج*6ΆY2C'>K9 \ɒY4ζki+My\^a/Ae3V1}psrL;3n >2;be6(sY=S",0n@Gs&f]y1'6ØCf-vv=F }QvٻO'=I1Co/X e.kA}psN Ncɤ(aw4CdՅϯW'-f51a1H)֎`XľLNS؟Jp)$HIca,G+D{-Hb[}L1'x%㽤xłݼ#w6J=Q JI`hg1Tj# f>n71_wf}~)\_Y ~f'nL1DT JI`hg1oajnc@492?g93X?`och wgl1' 1+ȳe _+@Գ1|"JI`hg1_Ôk8}92dw fk0pgSx))a [$/4OZI`hg1_Âk6i1oٖV)s3=G̥Kj.q?Sa[nageLzGg5,vC<`Cwufkv0+JY4!. %Y/NpM켔H3q"\$zcpmy2YD8KWP!8nNN$qLNdJAylV9ŋ@JH_ q>. >^øH~o&^'3O- ^x喱_~>xPϟyeEv12i,0˩HcNB^ʲK ZBA҃: ,cȨB`5&˛e%.PHfܘYOeCDt}˖3')S~ʪ`(0"6[dRg0elUXy\y!c^BUaH/FÔSY2^SGr)ۜW P`E,A0]&\J_>[)c+ےB`LP6G1&'HT0elUoa~ H~7u$WOّ$SJ@Ά,b@.xr6"BIO "ș@]ΉS'KI)D1ājՠciMyaq(i(\ Tn1?*DOwq?KJ6,ۿ|ˇ.`/_R T%=dv "D[X,'VXBβaV9I$IZ_ferNіI&v*4h7ɞ;ɲ©xDr{ŀQ\ch3/1|E$ANE/=.K9[z1iv\YStfhw3,@-.y|A)dVs.~+Of+:镧YXW\I`z+1 hr7KW zǿlyz CtP< ~jaO~VR­\I gg8ڸ_>x3,m,ӟ#\j kʘN&kX$?yOf+UuCP)wy@UP +f9"41Ӭx,ς+Y~..bI0 ݼWG]iid?åYqr.Ѷ=-g:^gXm7WfEIFf rr\Op9bVvLu\|C)J@lrVhĚY tIm^? BYO:iXyE 7E c9sgWǾCÕ0hcХyBQE*.P{i#CJ{ `–)JD[!H'Y'` $r{C!<ǓnXJOԋ|%(#{;0T(0UW8 յV96V]"g\빝ґL:h +31g&+.ԑ))TZ9Ly]˻F(i˫~+!t?6`~g2K* G2ЙLFcP`L͙ 'wZ^.rZ(o\'}Le}8A&=77e7٪ lާꮮa~%r$~t}7 O滒 tS/uf={p-6P; 6v{vSf9;R{Lyή_`gΙ;^<ޭ&g&᪙x;83B;.1͋u g/aϢ4 s6_\+;e8)1v4&R-9EH+c\`㋡}ң'=}ң'=}ң'DgpK\-8爷Oz@9Rtb`%N>"Dxe$9҃ݱ%w/fD`w*rі0q^ @8&z\IahIah)Ju楡!ۄ=1t\ ;i$es'3B'rr; EC+KqQ',E0'qC|h*ΣNSG8~7C0CC0x/xq6:9*]PtRM8LSF6kax,Rid&Rݝ 0nQjžI@XC)Rw)+).,@gchiIO>I9'=)IO{CD"b`"$N6Uȱ8)g؉Kܥ $'9k"sq R)O('!͗;PI qahIahI>.BJ/I7ى.MRRm®GqYZNW,Ax_Z;I5S܄dPs;qX*sVNHV2ќTUW9$S!vnbv52skl"NwdD2%c2C*,v$W~6|9;O*FxÖȂ8{qN#vvb-a;%<'>S3бJa2$5IW$YȋDV-掼aGMMتpC{>3?Z+!q9!S]etiZ?9ZbdKdf?ޖ5;0_$hjb*<磣F Fx%.WƏС&m5C7DFqwz&Y/[{Z42Q..Vah{ڲ*g[&M3F':z٪ c9 sbS]h^:i+CRl*x7u }7 WKbefdP`:D tЮ`h׷e5Lw`L䗷W/j~HQE]@Y2=9+"li; e(*=qu鯵eX/˂ 0tU >y>z ;ռf; [`ǼEλ}k!1tCdwCluW.mӴ~HQE]j`:1[po@SsWN?ݖ6;p6G`"~(}_0zQE*?@ aPlWzOJiVx&owC&y %Ca"}"EػH|#>3u CLVP~];{pZ W5v4L+@[|2#8Sr߀9[rNVIJHc=cDP3n=-HLt}eo= P,3ztCźSOp'}"EG/|y~n= (Ήπz'zO UՄCub\2v"Cpd'9RZ(T$HJ93q cO-)Dq"eD[\:.,"\_'t2IUi>*"7IC0Jp(yڰu;V1P S3m?:o&$NX=(L9@З tRvIп(fCɴy/_ٸ%Oή0tFsd~p_?i_&OVS{f$+30{{P[R R&41 @oẽU(yڨD CС;%kiيO{2`֬b7%X:)LmA- T93sP@jÒ2&C:~!P͢Ux8VBNyރ s%ODzOK(СwJ[nnHLܙ2"9-(#Unj XA $41LC#@8 {K[0]ۮU(yڸ /v^~ـC5wJ..0yodG Czf$+3KhBߌ@Z+( as2&C:̛Ep25C?'wc6>H' `ݽ)J6eοԯ0tf蝒;kiMf 7IrI2 Eaз0PV HmXP$`_xfM8ުǦCGBG-7"ɞ>.Ju&C%[Ҭ&Lt({3H:%iIA[]LIJ]C=|4[:=y9L4qHnbXU1甹AޒS@D#栻N`6BE i%^qB% ffK {n.?VֆH~JC hBw~𥘘ssP/QKP@D+࠳N%Z^QQ=תi>)\Z/4﹋]!2_a>a!7 W]ocenP5( ns\ 0-ƨ CZ}5aP)p؜C}l_ p('I:%3E1b//qB^ YJX?MyQiJ_gu8kT._> Z\(+%F`c8?(9lF7y/_8 icS'\cdfcnClNN ՙJ/ TWWPVJCЏnj9yNΌ~yGP.b6!%!)-坾):_^.2~ʟ W ~$0 xssp?ϩ/TVmv"x8@'yf f&_-. iX7J4䗷%9~yl/n~+9e[)P`Dz=y/l,*vpHj1M*LM |5/+99nsC\?$`Par uCIk QVЛE<޸0lQW;_5mW&׆` ?ͮJreעБBIEP`(NZrqG-zhm.̤05_6xռ> /;laC\ٛ\Wg2)hQh(Fcil[M-L͜lj(,08A 3)L- u5_@r&fÝO.4]PqeO$TNV%1yg{&ɷ ށ)I14)Bȣ Yt3!:A SŲˮ]@7sʕW>͆wIeE@U|[nl^P '~MRYS,QR'bϟPrl>3sǻ M\I),9~LɸV(9G^>.Ȋ{cU ۊk=b LueڑM; ߪ#Q)-oWeuo%^lۓEJ ZÒA;0R(,U5J[VV`(d}2CS]]H#_>Oг2$^ci τ wns2VB$nP`PV `rݐTSLٕ0ĢnPT׈p{RWq82dR0{oQT kK3 ~U-Җ-s:[':slPTp RW1N )X3FVr\"3 p_Җu[04>HVfs:Ns4CS]SI#_)VTj,5v~MJ4W+mYm݅aa)O"eI'1_r (sh'$S+dO#&OD8g T 8`.(ő(>+QbwT˂T˹[ș΂k{"û{]ݔ'047dKd)).?|}T*=|qt -Iev`%"gƎO kEC fW$Vc蝒yރ޾_ALEA|L R fmq9ɏuf; KD h"- `in1!;+ÓML[V;%޾ELE#TnB{ Z"r<Ό`ga #HVD ꜆VJ~[c爗{CzrwwYW@7&:sF9EO. 93v-x"mRW0z٦%mx H-rO0* ݴFc蝒;yy@oGLEEA =|q!Ϫ*SΔ3cY'N@CiE!MsK}o(~uÎ=\S {\"l.cW(qQzt#,9S]GYCqҳ7?84=)GEAq@£  PHA.d7 8۝釞JFdczu5ujBȹ_tHdKd6%&6 r!3S0LK;! T?|3qӑcy]+ 5CkBCO@#=;rd2C˃b S r!s`:6_qn&[3Ч#ƺ )i q*}95Bӽ# &5k]v-(4lJiN]#ȅgɴ:~ygNw` >?FKlOGAvex~WlXSI4ti,zRK3 7kMahyPaSͩ\< N/ ` ˻ER k4ՄN=w{G>U ek!x  `:?[NQ**4lJljNmBt2$v':X:ox ӑOu+zv kBkN" ޑ{{CaB05b^$'y,U$3\ gψG2IvwOIa&\Y伓@ %-D w %R ][8/^;y|[C^|.~Bf-Ǎk2@{Nw>#ozP\/9{ɖc"[r>ou NZ g2>Urygo//MVqSk&Jwg&r矑~,8 v-:PGމΞky1ڣg2/|})YG?g[p/ wiJ>Gz(:<.8ODJ("喤BRIZ% EIQdoq;Y iAP=$^Jk>Q >Q >Q CcצOC-)>xqV%I!*K$+ DŽő$ݞINim&\7ɝ'IRAKN CIR_VOx}҇}ڇ}҇}'҂M#1Ӑ'gb'ɪWtꤰI9'=)IO$)knQ+(Gr|<2"NzaI:9va#:spzܿ81,@ǞZ<Τu+ S5N~e C0O0C0O0qrN3H]t$x7yKv40MTGI|R {R&>}#7+@0T$l㖔7q=)ODUͥTɊ^=z i%vn:vu1eӝ%Huזٶvj&!^2&0.t_L~][&xĝnڒ4ПVvfM7RݵO-'ԬY]%0N d\+0{]8Pݵ'/ږ3ԬWni?<ӝ%0Z˵ܰ-gͩY{ 4Y{%'o׵7)ۛ7(oY^{_KսTwmovj)Mwz׷nXR!gHҊEq:!JɖMR/S,FIVqvLr69ZfҰN숣1 xAHm|r6a_iS$u w%6d2_ٱne*~z )_ײXfխclPá]`遜rn. yڊ ԲnbzM2r3MF`hCf1a8nύSY)7eFo*2Lq '@977#+]J1PN pm@ud. 47$ֶL KJ0m̈"k Fg1!31ayu@oUYY+ؔi8]H ܹY!!~զ4<ܧNӯkזZk:eP0=,]ie6dN 6i[\ؘ8ssBAme3Pku1BM˚7Vf eY m\kjwLXKh]p$t\x+=p(6e$aӗ{OmC5ryleEըX}tglȢζ2C2|}[(vZ4|sKgJm]g8]WsY!Yトj~]kyl%SNe/IkUY:ve, FJksb":yr*9HHAK憩'T|(L [8NRdL DaT>="_KTEЌ :*l$v 0ԄJf?<ŞLOoڐabvc%;6Y%b(c(3!Shfh$3C%}QJ^2&04#}uJYmYcML&&xh~т:a ;O{$:0j nH 3 FGxmJ Ʊ)Ǭ̭$.LJ}QJڕdbCIN҇q7̇î8 8J_)ug,r\o-uDʿ8ND`ȵģLjbRYE %UQi{- H ]=J !ɖݿ|2sFi,A`i(Bg9%_*'fZNj~8_-/^2&0;ZOFW4j?~;+͏ z:Nm =K}E_gU@IV W&5AW Z`t sn2cw؁dk[&\j)C0u@)#iϤÛEgUUAj"&*[9388S:r~yguqzN.TFXSƤW"IoAh.?|nná[P@ZU J{ xB=X.ey?׵ve2Ckú lp lON#*J$<^ ,5?zܦaDP@Zt\ J{ .|>~yle=_qc|+#0Xwu*+.B))C m = (гkssM<FE_5AW bϙϗTWHpn89H.I pF>]$p&r=d'&?'+JSuh0)bO1;$$4q); =UJk6=F)JjVy_w`C8&_Ώ|iZ qz /oYƒ82ga.08pn\mYAMPd4fc.eK-)Jj`W:0tNm?a+Ą=`=lb Y=( 3S@[P }Uj+XAM ʘE81 A38؉ux̛2cuKZ])n^6zmؠ Cuwv8|,[ben03~0<KKst"8|˯q85Ϯ,lVl27[s }Fenl5( Wn\EJSL:ԧ+ g~^r}jj[uCߟ_ާ}4Co|YUlV̍MD<t6ijV E`ǭ9sM鯽Eϫ߰^Z,޹`UCz:?m'[2Q+"7V)*F*P@ĭv9c:M_-:T 5gԡ>ݯ,}CO{_~GZ?~eHPm~7oRKUU6 PεDgvN`fj%]lE SX2dTXp ~Li*Ҵ29Ꚗ`wp3:3;'iϫ.ؔ7(.;1<.%CtFOv2tJԀxPV&P#0Vݥf*kG L;^rRdy*ivJ1Tڪzm5Ogɐ# [[X׌s55b/+ 5 oZ:jV $윰_{CI5"r.9N!oZģI w]H$©8ZDxcUqNqx7.Iz%hs%O0 D{1*YbϟŒ-ŕ.ϟq Lv9 vD,dVq[ bFrʭ:1Ԑiyψ2dL]Л=0Q52 "4fnvk˩Ca!,iUv "(ý J,N R IN*)y9 Q8ex(\*#[GS U-5W^zeO@ -T2:=*K`˃h%dDuUW0ף=CLn+ _js`EPբ9ӣRԎb~1]q^ABF(]YJ~C(\u!cpwinʷ"reO$,.9 @I1tzTUovmW%nvM ށ)I1"\u3#:;A'MoQ󅛝یC\Yx*x$EPE#(i4N;K6+NȈ9o(TY"I=.qmN|=F+F^<)JIZ=v%JlKqeSOv/޹]jbbs:No4Pi`(`j@jK?|@CA$.Ee*+WU [`Yr]:~ypm{e;PM= :Wd{UE$N0\˰Coc0ypFY 8'c$>. mSpQ'_{O£;k0 j* gA˹n{8[0+IzKÅiˆ'fpx'-) 5dUMa蝵%yþ[OLEA|MQN"ࡲtKlg挵OHVDBsC;+MMCG[WNzC]7hPw+VtCÃBOOC|g̱O̘*-) LN675*1bh vޠ0Vڔ?3g5xbFZ)) 怡 gwV&盛anU8)Ҳ֜9`gA^=w^݊;zFʙ9{,m4jiaNa(4 ]0D2_٪2)Ge|؉M:[w݊:zF/ΎtKlg朱O8H+"u 9` ;+WcnU| 0S &yB"`yDX '?.I gÙb"$NS: -%҂x$'M\IS\$H+G)_ˡaS )ȅyM'gpm7o$N?Trߔ%V޺{<@ill}^ 5)cЧ NZɼ8 - 4l*Jl*ȅy4~aj'%c=!yɔWRkenyu^b{:-rl^07' x$%}ıý0R|Mي'R=~.>q݀˕vt^�Իdyp}xɊ'p%N+~c>j6R\ e]/uCtb+e>.$Uxy|le{/YObt'0Rnje uCti?fŢuoA󻥕qIM$5 ~ W1tM:s0~ֽB=GZE tW'.pS7bw7>p|ZÿmՑ׏eO wC8~y-͢uoseEa!*{d2C} xEeG HB} }  U=6ed33(0 觎8[R{s{s]]է:u{FӪ{)S *.TxTQP+{&2{kޡ ?\{]z,. g ]S=JѡЭAn>Ub%1.P}&>f&CM RFB(eO^iog0mΕIL-PsrS?M1}6ߚ7ܾ\zqZύ%[ˇc}@닇6קx_ IhZ?m_.]zqڴs^v}צOt#o/qk7}UY}e/]_צmtwE~B%=%B-|?Og!@YirыײRTRgMq .;{,f{:4S_VPݍ C:b<,"̱o<կmwv4.ѭ3s>ѧϊ{ZQ?ґlEnjq))fmt{KJpeK;7nR8o_N]Ի[#gӬȀG$VAü,rY\^+& 7u8ʖ5 cHnZW3x.oѭQdgNӬK֏ OIyYfS(QɅYHMn?R )U:CƎ ۽aN\ٲ&&АRx%»iSF9٧Y3.zGBKyYf H-w(*k좘jw7|+[Nc6O>D.(2:y'.{.oz[Ȝ,{GLIlyYfV톷a!xQ=/04klVLx7u8ʖ+5+u\d!B=.rFW|>p{Z:~d4"7o'յr f"*"'!_5Yy$v@.|uE6*(x\pZ _.f$HIM R7A5s 0 ah&skWa}YS{U 9ZZWoQrC׏tto,OuOYѪSpҢ"7e-…Wc-?so0g+RVI]븺7Y~gPհRȵ֎hT!^B#wo\ 'EqѪQpҢ"7e-ܡMbWv>vլY&7]~g~հB Z\'#CVGv CvTV U!+ݪ"7e-47,{vŊ.^^8T:SОMHM=vլI]w.pϞaaZ.<5ހJt%[?rdƍY?)V U'OR٤}T~LհJmĵ֏yjG.S;^\OTkl7ɑR2Muaq*uNbP5ߖݻ&FlHÇ< gֺƷ=sph\l?(/M-7w-`(#_1Lj(-.2}\LZۦBpU"jX{CZ7dpf|k[)[``޷EizqBԋGjZEH w({[W ImFyH\dd vᡇ\vɻkb4޷EL?0W9_1$,M3.VfZ 5Mz^M;Kh 3k [~{>3{pn"2>"l{E;L_C]w_/uxV_aۅp^`'|ŐmRߛGnEƵk9B+M1]mQV]nHۀ άuom{|yWD>X}?vBr 5Y-^Dt2Y Z(!oP+";gV RO 5c/ ;cGZ,KI`Pa`AMjRuC?kkY޾~|EpkG# }n W.Я֓~ׅ')YV(9͛dMIl̲Sa0T7^rzPˮ6XbHؒYl)\䣽/z #;4L:aUU//t5̴̔DXl2a34&wvse˕A-:0ID t֫@) N"VL !6R lh.SK&gBP^|Aʴ"eVVaNCou4hSZ'`(88ǿ^kons.;3>зw8\ A9=*^Աhs/;1ҿPzfʷ~ºv#_~on_yFϺ!3 }{G?X•BP&bMj PZ6>a譣˛ժ֦^m+sOSZHa3R%_onH؇ Ba;fĕB*WIͪk+uV4q(G/0ѣjjS' m@З$}‚@?,swR%o$rj0jRR;:\+&1:ٙ] gvނ"a(`JbDbK.*!cpj\3 EUx`7c5r (/ LIݰz/<ʇ oP67)V˙Y|hU-T;6n\#c2%kO)\7B ذz< '֭f*UX1Wլ,a(Z>.}רZ>P ~u՜| -S@Y f@in!~9s5ia(Z>^T;k\ZRP=8ol}%6$4_Y`Pe!zi/7[j]W )RX Wլ>CC}\}wL8KgVGWKVf2"k.7>:ATPUX 3ۛ y ;KfkK>\dC 5VO~aj+rbJoX_DQb(qғ\1`Vc CvwBNSH]|Rh,.v6t'UZԲQ󄷎:4n5"s?rɶN|ȩ9r^7:{,agVýtړTB\d+}ή#9<"u#p1.p@\Z5 oh!qbE"JyCvoh=wviTI٥]gT _s]h͕eQ*8᭣m7u+QhDXZ}+W0&PuKO2_(M0{3+WR'vHO@僃 Ժ#zV :E\Z5 o= h!-Dbaa~ }8agVPŇOR'vB\d-WO}%+X;%֍ D`]rejY(NxE@ isJ+xxФRAh603'#%S fYyFmK՞Iqq*}-?GfXa%|g;ۺha 4 oh!mCb%"" ˜\Et<"Sp'k=5/\PI84a%/Mݱ<8GQb#KUVpzpg7˼WB2 C+ʃYi&P{贶D]}qCϭuT.(Z @;4p"} ׏t)`o|Ӫ{ƣ!zO2ĖX%3 p*][ۭr)ڡA3۸wZ04bY{RsZuZû/ZXBFu(SX;3;2W:wa蹵+ *Z0h1gvu>޷sB-c{.=6ɂ~i|+Ӫ{4=6g).vo7.0ڵ˖-Zd Μ޽ atOO}MuvNhb.Hg<"֙isiWqCϭ=RlWGР]Gn?qUYaK0؜.9/04bѽ?)> jOd?,7-%1%3-vm5sV.Z(h<ޏcdAdGoI\2_@c473yUp4)ӗ=̠Ltj^ˬd>a p_8մ[]!afPLdg[[n 7qXFٛ?픽s{KlKfLA.~N O8;;1'3P?ZFdXyKnM:%iu^Mq^Dv@_ S$Pڛ CmjP{a=wzNGi2t c䣖+LU~ Rl! 1 d^g0J| ='E0*U?#0ljPڛ CMX7E^Afeq ~{tj9MdgJa(54l=HР z\<[%=2g&pgՀhCߴ7mims;eo޴7n7mY4 я%: KSڝi1d(,XKrO`.xA ĺ^V:8o ;ŧb}~"lF76 a0Ԇ6 76fA\K7g_ϋLTP)+BDDp#^g3P1d#ePm.l97JP&luʺdq %-xzs.3ۗ]DcJù(R۳{gx{!7}yR7ܐc'^n=Hw3|7/|,y'߽/R۳{F90 y}G\U7܁}?Q?85ogHmYzJ7zOϝm?Ӊ+W=|"=gϙr{Ej 8s?]?ubgHmý3kC3dL2 zFy\؃rvsM95:HvTbJ2K92#&(؋W^p+U f-rTpǾ^a۳,*Sʱea.':3}VA5)WHo=91lou{ߗ;YL}XjV>ߵMD'{wkr>gj\_34u\"hWux/$8ouM ^MYzT+w"'gtk[S$@hP5SZ%,[v{5T2!A%yS*S(QPh£4}yZЬEcc}zScɄJCUQhPU3{.?[FȜ܌#8[)qu/֣]ڪ|xXhHP)T\KhQLjw0|3ϔ/[AO>٭-:}?!4(~͚)[^Gv{R𰰐 TYbÈ}ySi޾z+/'/wkyg܇{AkOi{Yz 5\E T/8vaxA>7l&ަ/bf {QжbFL$Qk "ٸV8' /bΊ^IPֳU$T ah8>䤾vQE@ ;Os|g΢{ CqtwPTgEf88~xâ"KzzԶ61<7ާrzbzsG]}Ϥ:>LX3V*UU4޶*2˧59VHR7,j)wt<ހJ f4P$~{eDn% >vLII>LKmn]0tN;U3DU 5f-7E0􎑧Mt>e]D{ پɊ玬t֤ԮZC{WMˉ= *kd/A9#mi;'qlT ?qҬޱԶz*3-Z^Оۯ>ܑ#W~zRjX͚FU= ]?gNw ]>mZΝhՌ8oarSd (Oqj6_0 ky C{bsG]}I>Ǣk+pj)}{[/a9뻷iwEf?Y;NsJ қ:#2amX&E(3xevԴ-hrK\I2y*05=k()F1ֽZdvtPy ~gaFw*J5(L[ڵcg}o wsrf}"l__rt|`(o;;A/iOE}u$+LQc joVs*]Dlyk][{>n8-2>x~"l__~"62a(otuo7 C2-Z>ﯮ|Ű2=Rqڦ9ӵh[8=epZ`y}}iʼngvTWN h8ZPEH|_=a!=x,[}{ I0TfqZoܭU\Hd}.Eؾy3g}A]8~ꊏ_EM^?0W9_1,,GEj۳jUM' +ڵM s(o糳wW2>xyEؾtDV_y%owu<~{W #c`(o]t0g2훵׺Ʒ~  c/}}"ß9P.ꨳy{m({X"$ uξlȮvd*x7ŊPIeZxnB+̞FSp3*e0Pc* Wf` *[ ʎ~jE9:Z8ǝG8ՍYGrs+Y‘/y\4 r"m+)KN|ܢla5 0Q;n} #FV.ޯǢ^9qh/_M~rvprRel%KI-Lb:3zԩT`[:%AUtS׈ >nѰBDx,a!kG ~@.#\+_\"+kEzJ(~QXĺUֳaBvE)ɪFd@0pdDxpʖ0t浣c6W6X+_\"+WH1WE/?ݟⱕ,Q,!6Ŋ&֍AwX϶uGF)2ؖN*)KkDV>nѰNDxX0tUߣ.\PT -c˅ ?=7/8v.ud;JL(`Glo]ݲ;8Б?l C.X7ᾼǠNyCo^siRFzEf0|DK M/cg-?;-;Odwu__\'P-xJݴ7; }nXWʯ"n^Xsiߌ֥+̔a-ʅB^j,[agT/YWЯ/.SbmFenw?f@U^{fZy_%^eM[6uh5jE_? Gv.޻}%2 27v6mYݲ;&AOdsu__zd V.$lz;[V,N\?YYK˔YZyՇx, Ԧ<慛;H(}_id R.27v6onYݲ;ȟ:( Cup`4؛z,InY)tᣈ#ٜ=rX7ɈP &v!8p|oY*BIDfXB}+|թ Tl 'sdE@H+;.rfp }du!l4 V s,3} Cq)菞}yY>5rU= U[&)Y>Њa%LN`} CiUH8Hy{lkOmozO#+(,̹SZ]6UC+Y29& ݿf`"?盿Z8CRkE:=# +VbD*Yb/?U\SZ'"* C}BLZ_3Q{oγ;2k֍^ӟ"+W٧7E}J8{̹sSZFfԩ0Z1,lɬ55k)Zyt=r>#)zg|wNys̹)1cϲ˄aаbX%քwuG~]%'%` vS6!e3Ga)h"¸S`PV@eq/KBC|~Čn *T"Ԫ0'<|qJ]a譋f6-4Eŋ9Mt!\"5w8gtfZ5r|Wa.9/& mG7ᾼR.o_Mۗ(W03M3FE捍C替 m& mXQyDd[;:or_a譋˛Wk8Zܮ=3d$'CUyc!P ץ& m<6nPӨ* b~znqM@l uhZm3Ѥ"G"מo%'@yc#8 ץc& m9]8[jFwƵ;,S QӃ^6^7# y/<{DqPx ٪0 vV~E1]絣8uV#,UB 0+BN}3 Cxy6އSZWi[N/- *^xWէC2ս?HoVI7n [0@0u톱zuiYn!A%G~9sYo*T5?qEo#`OrupYTq `wͬ… 13 Li0W )*!AJ` bto0+];Mi,N7꨹B#?~qޯc5CSZnիzSҡChsBlBC-ssŋz8g>o0+W\ݻ|]ݻ9CSZ4mh.) 4!6UBBewj \}o+ߺ:jӾY{Cx WGe -ia)\ uiT SIgf% *f䠣 :ZV *{ʂ'^)\ĄW>SU~$PnA;;uu }r.bc~ĂMJGcN3Mǜd_ݗ;uF}P|[X2pZdD|LYiTg+_p!V bcBi>;ԵABl^~0_l\R&RncZqeK bCgl,کh¬5k C~bPז џEbڵRPc˔i_xlUXhɈEjz:X *nDhxr7'\@{IkՌŊ^>fVpanU~ձ C#y.R,ŋ9q<8+/NkKd5ul]0e'UI NO6:.ϩ/w(*:ч=a3_RZWɜvM÷.nwzj}_H%jƄ6 .󔏎(kaT^l)kgLշ.wzJZٯS}6w ;ŜjϙkC#*(ubB… TV\'ch.wzj}?)vNI Cmꨍֹ#k+W([Hм3q0# 0"`hJ֙s"Ӯiӭ޾|V'%$ԉ屍]{*_jC#>l(6&.Ė:%sn&2횶ۺxkޡ˷k~RBRN:_a(k󑀃üv:a2y5A gƋnFl.VD8(c&(\t˲E)1 1I`/Cھ|թgf`wo<۟ L  {_γﰁi7A+.{ ,E@K=gOV2`uMQSj_0E3ζg>xQ2CUv(-`L/uRa_7nۛ͟?$k暻`H䔡-z2Գt~n@B?H4iJ#eVt/Vٻr; yaes? Vn9!pP{D0ٛ?픽s_7;1d"ܹySgJlH0 R^77]J=wFjbxf_a\˽*Z`60ljPڛ C!Hnݡ `b649 5c\JYo։ Z()&7Xqh )/m0epCop|i}ouljݻgo-}ۢ n|7n !-v'n.>7}ݹ||Duׯ/>qݻ=;ѯExXƍß~z E}w||Duׯ8qbݓϞ]"ߚ q,W,ʇ}r>tD+Ϟ="=3g޸qO?,/ ]~ĉw>{Y$-9y]E㛕|ByiQ.Ьf11AwԾ}) /$8oux._ݭ[2ӧހ뇦TTiSSJ򄹅YYbb}zSwNmQ3&gѢGnrJ/q3uSE@hhSRj~*r2!!%ySB^`hVؘ}oTon::ztr1iHHm{._ԭ[#dΟӧ#׏LIIZfe-w(*+kQLL}oj]cǒJʫРUfp={VƨR[,]dnm9>Od.z?BLIiHo=z>ʇxSz^`hVVVXDDľ}tю;*Ut{CWZ%^rUv+yn0E.T~4,2Rg2#v7.Y( /E`Qb%Zqk)<8@`ezaZ O/ g/""YPOFL$,nО=+V8Νs\o<}#8؉^~#GWx Cׯwt,_gEV9?`Q+ v^/7;<C{bEs]gҤ:>LXttS: t̘Z^w^EV%FEZXvm Jrv'- 3vŊMzu֤II>LX~}7SFܼgG,Yt^P C/Կ}.ZKTT?1kcƟ>=T:fLО=XzګW&M -?ih= /A#wo'qѪUã*IVrYٳϝ;rӓ&QUtC{_N\C=PP]V" … /_>/yK~ݝ0E@QQU~ VYӧw:Mo@c ٳ+Ν;wIo~Utȑ{/vC=]~XjUlժU`wE@QQQ?Y)Ԇ 5$/svLX%)|>2&c{dqd$bd5-hؘ8y[$ۛ P(B |cV~N&Iʵ z:+:RS=͙P޵cg}4o儀;l|௢QZ^My. ~HWX25".\'w׮6C־}%k|뭾<8:..l|0OE@msS7k8_bE]n&ZUEH/a(n؀g}|뭌  >"/TL X1$5ǢJBOK[3xp+/A^׮6࡟j>Nzk8I\\$2>`}񾧞Zt_\w? X1,5͛rԨ114KLۯ_'/ah׮m6lLʹ~ h;xpZ`T/8up矿0 p^`+Zټy}͛7ڷo߹sЮ]nذT׺Ʒziϻ|pO8nd%`QP3f2)̉&^6CfN>q SNlԧ&A=\b'zT:ZSkd.)^C.JtE iӜ6.9w'dV:2ŋ;q2Æ9q.lKX1ߋjr9f&;wӧ;=勋Rdd*0v'+c+YHBB9d/SNHh(2ؖ.MPHзypnZcرMի j̟|(9%&$k/^$1 2Æ5SBh(`[4YU"/?aBڵ篋Rdd *y]'㱕,Y,!!ŋ&& ;lX:u"BCKlKQم вelreP{<o_F?kՊJK ڤIܝ;O>"<Iv% /^<11aÆթS'2qKHEyS̋q222y]@4$*" U0d;NV(ZWlb]Dob(25Sq4fe[[fBWQ(#lnS/J?{>g\TcdGt Cw΍Im7o:vtdd8"3e\9g>bgm^9[N#$(0纸E_=<8Ǔ߼9lΤzKEf|DK M/cg-cZT65y=7Շ<}<;@]Ӥz׮v77#uő2Erͱyjțkצ# }>\mKvO~摝;'fd.]$2StIyږ׷\]kN C{nw̹˖Mmܸ~\\/_ 'oϹƨ֯*ݼyaΥK߇̔)ʕ A֪bg;|ş?q" -7a__ .vmF>\gywfff.[qqqq= yΝ;322J.̔)Sʕ+ӕ7v6oܲ=Rd 5]2-([% #(-5w3ئФumnN輄+^ep桂Ew~*DE $65I=2Ljsh̙% zS9r"Fb9oTC[fӢeˤah``jN=.ҙ3N?$/tWwz#GU)GJff*,[& CC_~=yсNu7 ~}qddȑ)U v(SxZ;cF+6o=%de04`0ԛ?H} `"#+V/xq7nef$"lPa0o~Wl4eu C_Sdd#Z5STɹs( _t5FزekzUjSRZ#h+ CC+V [d2+M"E| ^~=22rȑb?Pf||<>sν}0TڔXh+ C0 9"dW kUTCVq$? KIT.;bUZ OIXbX+أX,Bq =L$pp.? FCor4khBgYTUΟ.wko\1ÙAyo ( Vc"_DHMQ^`[Û5+ߦM{_eˊvZ7웜\yƌȴjUq޼8dfDa0];oH[7kVMhݲhܸQQ }u+Rl׮~͌}ȴj5o^;d  Ci|˖Qʏ*_`[G5զM۷裏6n\X"aaaActuk׶3z"ӪUy 0 }4RШ AA5iRӯ0͚֭ŷi8'>""|o-g\c KK\̛o&99iƌΛ7ok a?zM2ah˖ʏ*_`[5k֦MhFDD?gzڵ7Ľ$Ϙ1Ԛ7o2|/ 圠a 7وUX^ cMTft-.&MKP&bFl[aK9PrSDЪVk^v ,0 LIq4l+oUs mۜWkwWNU+ի11ѣڵ {,GX"a(`JJ "Ex/z);7p-$VWի} bMH(? Ra_}ˢ2eDk֤.\TIի C=67ffxPĆ aKe7n;oݺU_%$w1WիY@}>7=# `(`JJ cʝ:sʅ|LL5e'Zv4 Yiaa%Ve^}:0o*Th5zO }㍧]һ9_`(`JJJÆ +7-X\r>АOZ WҙWab=bSH=B'֖)/8X'5 g/8G&IPr2P5*]ٗг=G{ MTAG bM do2䐞 Cq \ h9<\_yIӾޙKб?7)G)E;wF gC/R[FFtJb8 /tEE)0m 5O0ΝՃ5HHgzYkfl,[֩hC_yerpp Ƈ2)Ci|FFk4=޹sbР џ}EjyDl>8UaaA&#R``hP}vM4 sA&$~4)R*P~ʱ2 /<j(fQYц 汚gzΝA%$$|g4iRJ(+/BXXɈ ]g)b JP źAO,圕y5ad}Vdd&2W*X"e%NZ%b8™IDb⡰O- NꄆNSH]gm_r33 ]ѣǏ~ŚnGgmsCӧ=CN4nL.^H)J˗/1}z]]֭kܣGUe:`@Teܹqgv~رv~S4~8]8cQ>ʕ+X+3#";u[׵GX M}/_zEisϜYXwK> 2Æ-Y;֭ѣGce:`@Z5jfܺuxÆ%ED N:0;{3vIƞ{n_O۷xb'UEA `ܡC\cmݺ=zSt+tSx񤐐+WNV.J@ӧȗ(JSN4>s7]xQedd7^?pͺR- ȤDRv"\{R%3 2څoڼ`hlle?h yGG50c/ܹ/^ر|-%vffwdڵukXKl haǢ T;##+˼Al))Nvo:`sk+W.[h<8wG{C#>lRRZ*TH,\Qoݺ,EA;|p7 '̜LvMn]\P0@* ))_N CSCn{GݺuKW4?_ 'D]v[nCyYY#3a~H":#B3 `TPcZB^2C |6-e/~8TOb'[-s^<`Tp0*ıCY[fS{EɷNׯ~ݾҩ7p`~_~ڮ__ks8oSn:zoY)7d_ j$ldY|+WN3p/W1|wyRS ˗\N&o(\3Y`%{fĄ;3L>Cn7.NEP"$ lǪS9TlbCaN Jrϰi,7m^%?O$9z{fNnk͟){spD^ó+S<ʌ"J9LbXg7Ʃ s2"FDJP3= љUݒrtljP{a Cmjo6 W;pr[WYjckxh2pRЈ-CƩ;YɊ[SSd?iWgt+D0LwךQOM{do6 a C͆6 `G2uMz&@沵I P,}VTCX6^U?1qp$UD2J}ᅵ u2!8a(#0GXg lk9`C]z,􂴖g".QfyQO5'e uΤ̄1qXA̫fØAx%</>4al&w9. ١kÞbiF f%~mߖ[mߖSCބMl叟(?T6`4#f+7 fV^0-N,sy\n^o&,BbtcVōh'["D 1quKmߖ[mߖ? )'UbfNt,ÊVțUpAخ&˥I&;loD!w!'XFtw630Af$xwyZ 8,TRظbAAؼ '?ߖ[mߖ[s@hCCY!/|I؜`fbCؔ"ӃJx1e K8"&s<%<}fFXpRp]^(B,,QxIdf^ 03طԌ?D4W 3e !̴7ߖ[mߖ[-?P U)(DDYyrg!bpw yei+O3c}\f B @7$63|5a3kBD\7qoCmNhizqF'tVvu&W~f1Ly-o˿-o)҆ [)@` YOلO#DT@DJrf9g),{ %ol,l{Ep[4O1q<AAsL DƯ& MJnPȋ>QL@Xɴ0O0 )!?"0w;V)o˿-oN8jM6.fI!e``f^&\.\NjPf--F`JX^!Dx7ja0 qkM}l3a귅szg'N0,x1x,ݶfdMƼ&wi@#bf!I}ҏ}",a*x*lߖ[mߖw*L xeA` p@"Յy&&LBDetϏTA [U Y B.F"K﹜v!Uf~ꖆ,}/>R,%@ ޱ7-g~o˿-o? n)SK1,KYf(`Sna"-X֘BɈ\"ЫbCe6hF!`Yx4$,t|S<3Q0YEFKkTm/o5M 8a-t|+W5eZx8z)h9t 3nLygK,[n˿`G^ʿr/舮\fdAw'I#(]qQ^ ߖ[m_&~/DZӧO>b+oݺUV-+Tprʶn-*W F{ ta77SL.]:?oAAe_*Gj07m6 (u,7O8!7@6mZs-~P… p0$~ׯ_4 ֍041!ƍ'%5WON=ztAg˖8W2S.ֺ۷c?zuŊstTq8ǵh; 0?w! W-* -WjOpppذTYDcacƌ;v Nvj8pVjl~*UNicƎ"0-ot1kCb6b< Ό&Uw´6( [P ]ٓM%`I] yFQ"#L+"p>$ L~wQ4yŹgFߖ[mN5mTKpeeeeaիw+V#}݀8׮]%[={ W^@9(Z^GQ\zOvTUR8 l"+*7W &SKQ pd (n䟽"ԜLX~BGg -!@COPIEC–uwo˿-?@K.>T~u Ν;۷GTl23,y'Nn^n߾ _]_~ٳϝ;3<_z%Kw%ڦN8`@m۶*|VLi@ßj-AOķ-[6#O?\jJEG?#K?.ʣ~&rg ߿ߤ\}XY}vr kV~E3gؽ{gvmV\J \&֭~ >8𫤤];&wPNK{E-[ Zkڵ XC[DDe(cdz mۏsJ[/'E  C8;pl"f'9ڒ8Z U7GyrQigzU|N6w/3˿Ȝ," kL^ 2%?G;^bՂ-o/H tcY*ۿo al{꫰rA!?=ZBgfnC8- |MWU'fer-W,NNآERӦMTjժEy6e?AiN /SO=ݤIcRQRk 8ך gVPEo>{:v%ܜOުjUrrl"UqF?|?N(hɓ'VÆ Zp _yPR)rWئMkP6?`@ж]u/BÏm5Rݺ.ϡpLW]`?z4))]\飏>Zn]HH:3/v*b[fy:ujô6JzpQU3 *xMZfaĦVl%̒LOR ( w /!.stρxQ&A/d0@ؗ_~Y!͛7p bpEvnذAx q՞j?P _q)E\v-l C-[ZEԏRSeOYbjCa}aeQE~`e *iNnz)]STcv-[z 6|t--ΝSq}{QyoHK#0߄xɶ9& BcU&?m\ Yb5Ǥem3C [ʿb+Ys !a!gTk8LsP ,o72?S2gU yE(lߖ[Y Oy*U)Ν;m۶A*jN4hoto|*U*eggkWd4vӦM_屵nJZq2=Nxq>ٳ/֠Mֺ֘c=% Qt-Io|ry'բ<`8lX8_)~^ccG 8BZ@i5k=*]mgnSLV[۹rlpsU|Y.MKKOT۷/ʔSvܩeHҥKZm UFAAheV%8[cp(tL"6Xt `"P Р&v4km0%VD2o_Ѐ P=6֙\0"DHG1-LXƖ[m!~B,<`S~0\l(W FiܸQXXYyАIr,S4o޴Q\OAi  a[-fB5k)¿&w=uƶh}D}[1bRRs-&8$7g !y 6mRefqxxET3Ht Tz_tf/yǣ9OMbv$ޝPI5埙ĒXq/´HȿiMϟ7!sSQG7.)kXˎ|f}F!Xˈo˿-,; 5U .3]65Z?gj\6Q ^YNY8)75bFeޑ$FLAxfFX-dAT ذa/8%f]b/?Atb+5f!BF综*aƺhaâ&\"- 'wږ[mߖ0THɅ)b%Mx Drf^ >Mmpg`g;J7xB1y95Bb"oܸѻw/6Uf>b`ND4H+ ",}sz4W2M3is=E/Am˿-o0TX3ٌI$ˮpՂBl~5],jY"6+"*?7y23K1vbFئpb!FPVMl*٘A:r/ +AZ!<@ycam󒁈 gg̢H,g!"7A`Wm:eTD  FE4IBD{˕ *岘7 L6fb,fw?ѷ9؋%-o˿-o \-r"Rdm[^O\Kδ}YtBp+rOExbA7>wf5xL<^lV q"C*"s*0^U%bj{aolߖ[mߖ?P*gf E*tMs c%iaCv݀9{~jgRe4l {-*nCx͍X:ṅq,X/-"yA"44QL>s'()cs2/ǘl~$؛ ~>؞F0o˿-o˿-9 ٌ |s'ͺtlg %Xk-&L&,b.""LWD8MXf$OeMsf6\b| ƴ"VxcOy/LŏCމI9>0$T|Udմӷߖ[mߖ[Y ug}/ s ,ABn(lo!&VŮł% <Kx akw*l!Hұ0VXxGXC LjS%/5Flߖ[mߖKPLyVBcL%f GW`vze2HpXZg,X<|~Vxa.BsLx'f`b.BP S,@Vr|[f2ؘWBX> b<% TÖ[mߖ[mICw4#t&%vWq3 5 W1a_J87&X`8ueN= O„v<[He“o#L43[mߖ[m_` ?eZehVW] X 6,^`=x3<BB/fnF=Ě)))?02\ F'Ne o0tڴiY uє)St3p9s袣Gf<yyfdMA?{Zn̾p݅s`;hApV KOlʫDR8Z 6{Ux">;#Wp1ddo*~S{_ ?wyL-01[0tҥÇwf͚SNBTY˺u׿籖,l2d0/^X$',, 0N >M6e˖*|+VHOOh9s&*—8,11GEkʕȌ5 IǓxSa| Ňm۶xs vI*Xk31Cz!|;m5k 3~x܎ߠAk\eӦMޟ-|;w`t/R 2#bVИ#G"|-O)66K^]~=2zld h&33-Z@  ũzbBkaQE#FȃqAbԁ0fa4FHK/a(j<2xpqxh!fkC7n܈1zrWWE(.qE\QEtJ@mzf͚W\ZnR kX'l EK@?£K1:ER?0b3Jg@6'%+q~@hyydΊ0 ^tT@APuyYZ+/e&|1"v~xwޭO*ǗIW_d r Zi4yn̄7(26l@?UTٱc4t@ VV8!x@ბ+7gm#`b.oe[ 3[m6s C}[y20a25^7</%H#\ c8(2[lA?{'u;}Q ^ 0$?8呸F 5>.u6m7 ֭[t@^2s=_"bmXg$\9pb,Ak. WTPPtK+qV"pb/ta<όJ-E,{Ei߾}mAAA(;ZWǁ 9y@̞=|<*Θ1>+`d|qQy媈Stt:W:qAdн[nEB v h覅/.Jy9(Z`c5`f͚y CqWB*}ԩ۷#5gΜZjp8Wggg3V(\b"jW)Xǎ9sƍv%t/@62;w"c`p0D(66CM6囋F!@^s?']v-ZQFݺuk۶7gJPt/Adi 3s{/^.q-k-]:oM6(Tyqx"xJ={ ݽ{72 k3׿5:~1\k׮[Z7`B;}g&Jy UUDk M@)i)` `Ș#$ Oy{/,\SβyP %%%A1 ^2Sٲe{=~'xɓ'cJo|~FTbR}Bu@; Ő k׎w7= [^J*D| <Jt -[Z>dK.3==P /]]0f͚Æ Ct/2=zt+Fք@yNq@v۫W/>uT'M5 =}7aΉǓ7hO 㑙7o?VE X~tkQ kC o+2e f]`۫hŋ{1Ռ-[^PƍC.2@qap yWYb C=Dw޽2~Lz<9ڌ;C-yS\IPkۇ!ҹd*Y;(rTbr%x^aɱPܚ9V;h Gbi? O 2eQ% 43(G-՜+0B ['gffnݺ/رcMjj1EV/1Fu"Ӹqc5(L2@; @P۾}2(R^Al 4̩ ӴT+`>6mZttڙr!4a+Ж C@C|Y=?|+_K,1G›ŗ^zjgΝ;vd/20 2 0M3Pq'|rСȷiæ6|訃B~Ln* CT30@] PO2׻s^2OM0 01KU(O{A3@E)qLw9G*$ܔZۣG>}lذT-K%a(ֈ*QmQ8Z)QKFLO=G2'0!`Kva%p7cSKPAq8M9%) 'gq&}qAЍ7_>'p|OZbbbjԨ 2ތ3 ?b*o|DDu""\ʕ+#_bE<V^`(N 7/###WEׯ 2`Ew 4t@B h/c=σ: `{d{⃤\r(W܀GH-Z4 FsJZjݺ5#ϛ@S%\ 3 ~L_Գg^z ^D?#c^Q\ 0СC1IU5|[nusjFnt:vezla k|cU͜jGEF}vM؉|T`5Г3L@J- ĄdKdx-NhSC],[L5jj@ *G}ynjDjRYf4mMuTܹka¦l7<|3[ZP7:9 ={F/ EC+?L _9A@b%Eg.L35 4)͐ aǺ`Avub \Nl-ʗl)!lia9YY'jx}Wu=F+dȩSb m-N1nF}܉_ ͊ Ǩq}#+k kC?> HGCLn8a1{$ 4+aS#:PB DaQԺukOIh8mڴÇ礦 |\UVD Җ={v t/ح[7l؏)%^S~ڵ@-Zp$&]onϞ=pž}nHZx rlW|O[{OyL ~\|9{/^^Ij{qšCLZǏgB%4u޽^a([UZ_A)|ۙ N11d"X;QenJ.Oy!#H2# U4݆DzŚNx_@j,B; a(D~MUlfmHc-7 {-ZE6C$36WEjE#;&͘o0tƌRRR"!F+>}{7=IUI%KD:6 R8M \:{ln,EbWvN̙3ziO^UK&L.Jշl cy `=h^~ 0t޼yށvUz{*ߏ?g]tQa~&# E*P 2|^6W^8jj*`k۶m@o0c Mfe߿?:C݋Imh ūv6w0EQ4 us- > +"ZPt Wz75sċĉh}b TFFZ06kaZڵh"_ o(k#;kn~3 YΏ݌4%,)G83H&`g%ILBFCD*vbTk Ux"s$ Ŕ"M_ZD걖{P|8ho=xC0 *UgI-$P ""@jCuxr3ⓦCϢi0TI+!c܇C5j ӑAϢԼիN:<6DL 0B8;w/zyZR1~4GP{cQlҤIpx_E |-`6qQ5kLW>}nLU'2e 2ZZ؏aQ |:NzVyfn|3]UIyC1w!rFieFq)rC6FDbWdDC:Bk6!@I0H5;!Es70t̊Os`PV g,e(_e=j,1 @GB Pd>j,%$$Ǜ(MA5kl޼9s4ZjhILL=U+/A4h\۶mMȦMvM| 7ߡCV+/A{)@KOw$kVyCM}Ӈki-)<Y+'% N$?bDVAnrIDN.ezvV )AFfƦ Yz%Z蓃-3;h*0dp߻0N~v+ _a CWj'oy t^19G`Z@VYZ gFbtLdv !k^E(ț Tl +gB(vVyz~=/<6 aljPɆJ2YfWE`qD !^hlj HƝ3"Ŀlkq0O#v!NfPT8Wa$Mh$DP(6dP0N6 aAmZ$1ߧ̝{  zv79G4 .SPz`g'aPpYuYd /Wq%vCah';-?P;3?T;3=`'&^,fG4b#Ū1V#EKg%w^Зں!&6hnZipg͇Y²m~fe/P8W o mjP;0Ԇ6 ٻt^":kX{g3ޅE(l>O}LM&%e) 8pȐ!9 X755=lPiĈE`[ÇZFV,5a„I& nĉSLm Y:š"0jOf͚3gν\pEŋp|^e. &NK0d&&pO "Z&:}&{s&jZA*hM2bVD JL% Ξ=[9rd#ѣGUQvv tUT'|rݺu)))^6|6l͛EA;~=R+N;tCt&F^]4o޼\?~|ɒ%h=b;qmd۷oG_[R 'x‚+NЪ>Dg{c3~xH/wHɓK.<#LL6w\"|$TG|&Lн{wi/a(*nڴIӎ1_5=R+m6tґ#G_;eU=S ݋7_Ⴧ^REm+뢟E)> d\Н;wAB3|3=X iCA/!?c /a(4 :YJZ` ^9[kCw ?(QFq ` >ua !N4>ƹ*%2[lxMo0t޽=x1$BpBlt-R*UK'A\ej7U l~*"Fx%Pz;N<چbCZQ#>"b{ذaj'> DE'0`݋ & 8J..U `$7Mo@ֲ\7-E 2932jJ_d2Qb[.j "U"z/s&sj%-Y {R >xK.#a‡_|-vU [;cǎ j{(0t~a_}ѽjM7'o߾*`/N2_ցb ?C҄*7|PZPV!P_1Ls$53 Z\Nu${(0w^".`Wc/|0P G' 1gd^ճGKQ>&ĊVa(z>ZWhCљ`F:ޕ,\n2@~D.=j(PY+W0$MsTX-_`ӁЫH Z"(\)v mIHa`YMR"xGyǀ.TSAN-Zy/aA_i4=jPՋ9-/YGXJ/@jd+ BvW _:uiZ" N#"/ q\]ga!a(c$8N `"*fbvOʼؔɌDisP[9%x]Us)fo8> D1TT2HBg ֿTRK6z7GP#nU0$!3q+O۱?O ) aTzw!{h23gD)қb\`VSN0<Ry|e]] X@MBdιsu=T"o0-W*']Ig&4HEdBP1@S|=|7A)^&Խx^ʺoBU*zKԀv};3=z7sԄSS xq{-[Aq\gwӦMң@j0F Ϛ?_"x&/a L4  ,$_ B_2)%~^^ƳnUx yn/ӳUšJD eU+A悄;w޸q#={G]UUf#-Z#uB4G$T!v܉Rd@|}#A~ v xw̘1^lAG2d.%e!2E䁬3 MMMݶm4@£h%dE(AKTuxVLAŔ?d CLP];v/E@VQc\7 )B<\5zPm~"آlfΜh<0|6D8dR$彬%DEHFYFkǨ"L 1.q(ȋ iS@ bz8,2ŢS%ІgCrpkb?df kD$/;nL2n,yC3C7>'{0>Yd=O K Y"J_=iX`TaPO Cu@ 4(_G%|u릱7_ }1 ^u` 0T /W2mH[P7L.OlkWL d-a ޽{=P6(;Q/CQ ={hPm/+`zoBZ ztn0<2q`_q`,QG=/u_Z龅 1~tbɜ`rb ZtTVIgE+Z>PL!DGqdN020bCE=Z>8 +nY+Ey&aK4ecc&a0ulɦ|BAϬF v-mRM T䊦Ǖɖ*065K[fYlr!Pe ߪ!Ch*QS0z;7KJmb2W L~{K_#FL4)---_1ydoȯ VyC 6?sW_+fΜ \SzdVyCO]/jmb$d.Y''lFy!\z!^p %3b>`g|Ku|+9b''9avU#] ē6NCT0N,KLS1~K&xbkNƚĬfI}V?S/+&|ə;㿳C # =EIFZ*RQa\!HimljPɆ6 yW*LsН\:BSpHHtb7p}՟CO*k.b:ӑZrT |nX~6Ԇva Cmj'ދPGB'b [T;V.2bo!vhTOrYQ F/٧^. '<^K0WL$8A Z:`~(bm(+JoKCoiɟi?i;3 Nμ z^|gv!sM_Wa;T^nU~fn*Yg:W$3et[EL/ -ۤJ|6a+*wPZ6 aljPɆJPR˳$1;j2BF"6#ZYi.3=e%iF$bsLg|,-Փ܅/XيW"Db{R ,;wnC%K̞=43##c[7bŊK8[nnjڵl-`C=֯_jժ[ ٶlr n߾*pHgϞ~xl-`wڕ[vȑ;w>|8hϷk7X }cM懇(4iҤZj!3~X 5kVhQ4p‰{BQ` E+WNuoHHc0(]tJ^zy͚5 ׯAa˖--7mt͚5@ɀ 4|{CCC~<2eTRwϫV*BK܆ [zy΍7hѢH"8lCp- ;y1{07H߿ }% E]{dϘ{s X-( 3|0l߾#*sq <]L<>1|իI` ݴ0rJR&B(|eLQA"`d67zD^氟l1i6f0fajZ  M JD哋{^tRz Ěnܤ5kbUVSR}L:uU7\ ]~=˔) 80&&&))IP`m>}իcmCpF2d0ܺuT t䃂 |F^`֭[ $i&Vq;:*o վ}{} nc3Y7w^͛7( BuI7k5b6mΝ;@ =zVZ&L= C17@@^Pԅx(t ̤؏'Ok0!!'۶m[>XL<bի&UMD*t;~xO<sznZZnK҂ME\xHpq Qo uaP4"1DfݸT}0ڠ/k.D k͚5ʸ3`E X꿸733SЎ;B_ȼ3?qū "::_ 2k\R;vx@%6sWNBƍCP{W*^8Ƞ{]C#d 1@)1%kbOvXMK^gt+ln~B"VDgrVs7&z2'ȋh& C0=flqQ)Џ^iii8{0Nhk) gϞwtIOW5kL"1LėSUUQ-Ϝ9mUWʚ3C1?ƌrȘ0T?;|9N'߿?&^dZl J%w @,BU={04F dP|S{7n2Q+lN=СCq6Eѽz_2SRRuc3Y+0}wGҥš0G;"#G}Ⴠ nSܑw^1J1i-|߾}q˗+}-^jK(C|A6{ wCԀހ:ti&^PvQнq%Pȶ>Ápr{ZymwPۧOd6A O~رI&A<UA?$\IP\Ey^fS%ɾ/dK^/dl^{SG`1or)2^MœWJ .Buj?* ^6}^03nW`ƍ+0Ҩ<&zWU>2ꊸ53n2,*mbHZ+dP-tИv SLQ MNN_<pxt6ڴi !2޽{#DR5(Y+/0'b\*|`=./s0eM*O 9:VxoѨXnBDfȑn\fE]Ig0ڢT **p]Z>PAUTaҥɓ'*M<F JN R2/BG#BHThhZ>PA8Off9k,F kRs!eBڴiS}q0nղ{q/jU=p^p-`( R|`\k!i> RHxCs^4'53܀ACC|`ᦅ&0dB{10cFV2$g&T3>W䌀ٞQDeL,"Yɴk EK8ZdbS䕁/kB C,Y/< <87J 23gtS;+vHGF-#c .Ԑ%+_Z>P y8'dHt@J!ojC1Y@pʼn'lIܲ2BUIQV),MU 3  ô` E(!!|r6lؐhGm(݋+Θ1gˉmc3 0 xa\HxSp"祏IIIN@)CEvM*W\ǎ_FzCGZ#G` ܽ{(O P ѣG!fT% @Q)6ѽ"F_7ҕko0'lժ`ÇGaA91x t8+\}>|8^Lu@N- p-7+vbUl)9;zsEf #N)Op9_}o+ Wn/e{XJY?¨Z{Af͚?*&L0smhNj׮V.E"LTѨQp  17E>555|-[1bc&۵kMϟFGκu*נAOaE>###$$0EáRŊ- нcƌq7 )SХ#Gw}…l=>}e"Ihz+،@ *Rw.j/>%ْcP+0 s 2xSpːUxvfZP utYMyXCG%B>33O/͛s 8qszV kC1` ¬f݄yXǓULR`x---M1{!P~1m(k愇 ?]3'I L%^J.Xٺ!2_5g)=k۾@ U(1Y e%fi~jE *O0f͚]tQx=h5jP#j33caWP |:BNN9** k$@| Tݷo_.Zx1e</UL UL4CU jN7W^E\ U0#T]0|TE3Y7#T{N4I ;P@|ZNA>o$\ o0TG >#gnm߾_1bE+Vw7Its@ (^a0tƍx< R1 X^˜UP!O<᱅F`}XQnFmM:KDTGg; (xѺc!ЂMN82zc2W}Zh,XyLˌnvڌ  VyCs233} Fo&=PZy -wmՖvZ|9Jf k74Wi|F2յY+A'@͛7ر WZeP$gcEuKm%v#B9*Y=iRD=(,Gd$xbN+e}a>|NϴNLNɟIG&<+  2j2?Y6*eh+G1Q0'N-~wgy&`.++kŊr?oqO={ :wܙ3gr|Mڹs={xυ }W_}+zW^y% @۷r\7|6  lLCbkՍ%!3hvSYGxQ|gOq)eJVAi"<]]-ѳ!KMa4՜̇!2Ù `-|9gAЩSV\YV|9sI&yKgϞ=rʔ)]v5k ;vlRӧOݺus Y7:k֬*UhE3fyu:*IIIBx=X-M6T]jdPP޽{ZQԼyVVb˗뢹sXcz'Zn̑#Gڷooy {ҥKqu\ C<әYKVVMuTxxڵkuE-[L3b=Sm۶Eɓ:u<޻w"@\222RuTJ~a]> *ʕa>ܡCd0+NII @-(jݺuѪ{ۺu.Zzu7EK/E[Ky!|jaɨKh Ŋ ~|Bn[R2ceS%bM kZڅ FCopD%7( ('==}˖-zxUرcCBBS~ *v)=33K6nܸ͛#Z>裇VaQE@(a|I $tr|||`(x|z<tOdǏSwjGQ,۶mSEӧO/[&J.\Xc9sx|!j…q0.1iX` 6 'ăSE+o7Y#Uχ ZK܆fk<.],xGR-X ,,l%!Q9+&T#W?rlCKFɩlPBH"I.Dldktq)7ky?{'sYzzz]&MQ{Puŋ %=0KCO:aHCMU*XWPڷoO׏;cRjHgzE[*믿jbԧOHCիW*0/i_3 VSN%Ze̙3gX*P'Njw߱[p!,_~ѧ2U4?0짠 2ふ!gF/랪3nN^&%]R)5\GTx #B& 2IUΝ;d1^j5xgx^z/W:t@b9~xHXA솪rC’+zRjS-7EMM~TR"e4*o0f@$vFJ$M7*Vk|eIu+`ŒEDG@!MNMZzѣ UL0UN!Qz 4'm={4l -[VR1cƄЗ(TPN-44VodP_gXy睯/U(Ͱ^&nc Fm\ʞ~Fjȼ8bhpq'N$r*{aÆ0# KL>o*8o=rHE`СQo :uOFaJ!烢Q ƛ-RCbLG0(Nr=/$Bڸq㧟~:\~K2ҵÇb@Xt҅ o• oPR^L% 6XvZ&MX+J&(>S4 \z fZ@FB U%|7|\ MP*II5d %3|6x‘ڸ/2{z:12TdZaQ=0bF(l\^P-LL7ǔ{B{eZ$d GsaGUk֬ 0>䆭[Ϗv2g2A&&dmڴi4>z7mDlǎK2WgϞg8lor*cLJ-5oRҳn|ro& U2jFCK/ӭbfd,}JD̮̓_h8ņ4<-c"HPjet٭[7~ ReD\l%&E1tUIjHĽؑ#G7 uTRlܸ%- '7*GYb^tH u`5ʌz<~xΝ;׸q`3{.//Tm6:9~g(i̋!-֠XWЬO ve&NP63oHƓ>ݻwCF/$ όQ 6)Tп Msכ5k\Q|>^rk׮M=ztT$*zէ13n= V&KtcSMAcI$LS/"f+QMP%]'UthD% ~dDt(ګ8!exQW2YPķzV d)`Rt̙! 34ܹsKel/R`ÇZA6DC0)JƄVZ1}p>ƎNÍ`(OXݻgQ41YNCSuSeFC BlFA͢`t…J &i`/b~Bю|MǍjCpV~2Fzw ᇹO 넥KF;w Qe* z`R Q щ'hWZTU0e:m ejo</ 2@HuԩSUvw>Uf4"+WnV!W_e R+O(l(t*a4BY-[v{J+2I n2(/Ue0)vR`֬Y=zH VR >SȆc1] rҰ#ɍՔ Qҧ) VIIS\wUIOuwIZ^Ο$FA6Zs=ff7L }*Unʕ+3ke}b>-FjJ*eYc!=er*3=TE IA&TsP|j@vxm # kڴi1j̘1\vI7ns*=TEm6DˇTYR?X P"PY'۵kWl4qDF ʌ֫WT'D:kԨ *V!70`@N!@cǎ,T'_(2-ս{H yyyG}4`TP`:t6m{|BiO>9c  ,* <,y2U44z` Q͚5k֬x*MT0 ̙Cs4eEf>:thE*nƌ$ӳxc^7 [5ȺT^E쑚4F7pho6U5)֌nq\N)s_ 6%zΝ;?䓤l5'֯_z={T 5صk/}d uVZ3)o>|R.Sei7Ԁ6oLFjLaaaʨ#G0:tkSei7Ԁxh7,*** -#fRzXTY 58y$pQrpEJMk^pbnMP+Fe+W0^;Ǭ QivCcJo#LQwɘm]UuȤ"Dvqd/HjH =Zc*Y*)V & hoIŲӑ%q3_vLfBY1n)ըS]:'s74Y5Z0Kv3&&kYs4lz4k]X5&ٌxY"c$9YLmҤ{?e7p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p88b5cJZ%tEXtdate:create2020-01-23T09:15:34+00:00x%tEXtdate:modify2020-01-23T09:15:34+00:00%GIENDB`termenv-0.15.2/examples/color-chart/main.go000066400000000000000000000035211444632052500205730ustar00rootroot00000000000000package main import ( "fmt" "github.com/muesli/termenv" ) func main() { restoreConsole, err := termenv.EnableVirtualTerminalProcessing(termenv.DefaultOutput()) if err != nil { panic(err) } defer restoreConsole() // Basic ANSI colors 0 - 15 fmt.Println(termenv.String("Basic ANSI colors").Bold()) p := termenv.ANSI for i := int64(0); i < 16; i++ { if i%8 == 0 { fmt.Println() } // background color bg := p.Color(fmt.Sprintf("%d", i)) c := termenv.ConvertToRGB(bg) out := termenv.String(fmt.Sprintf(" %2d %s ", i, c.Hex())) // apply colors if i < 5 { out = out.Foreground(p.Color("7")) } else { out = out.Foreground(p.Color("0")) } out = out.Background(bg) fmt.Print(out.String()[:]) } fmt.Printf("\n\n") // Extended ANSI colors 16-231 fmt.Println(termenv.String("Extended ANSI colors").Bold()) p = termenv.ANSI256 for i := int64(16); i < 232; i++ { if (i-16)%6 == 0 { fmt.Println() } // background color bg := p.Color(fmt.Sprintf("%d", i)) c := termenv.ConvertToRGB(bg) out := termenv.String(fmt.Sprintf(" %3d %s ", i, c.Hex())) // apply colors if i < 28 { out = out.Foreground(p.Color("7")) } else { out = out.Foreground(p.Color("0")) } out = out.Background(bg) fmt.Print(out.String()[:]) } fmt.Printf("\n\n") // Grayscale ANSI colors 232-255 fmt.Println(termenv.String("Extended ANSI Grayscale").Bold()) p = termenv.ANSI256 for i := int64(232); i < 256; i++ { if (i-232)%6 == 0 { fmt.Println() } // background color bg := p.Color(fmt.Sprintf("%d", i)) c := termenv.ConvertToRGB(bg) out := termenv.String(fmt.Sprintf(" %3d %s ", i, c.Hex())) // apply colors if i < 244 { out = out.Foreground(p.Color("7")) } else { out = out.Foreground(p.Color("0")) } out = out.Background(bg) fmt.Print(out.String()[:]) } fmt.Printf("\n\n") } termenv-0.15.2/examples/hello-world/000077500000000000000000000000001444632052500173325ustar00rootroot00000000000000termenv-0.15.2/examples/hello-world/hello-world.png000066400000000000000000001054171444632052500223000ustar00rootroot00000000000000PNG  IHDRUl̎Щ pHYs+IDATxw|G&,c,@!HHBI $rAs2dLlpm;==zvgvf?vwvgO] a0 ?qozCT|G۶mZj)Gg۴i-se3386sMHsaF)0`z"R,ռZ8/Q.f\' O-:ĚjkVy潚 \;u{Y1wf̉x[ |pd>+ TBfhpLH*͛y@%aH jdg J̭:+y"|3; ivƌ? Xq Kb^-gd.>Y-3 L#N>^Ln(qY7sYNf6PgϢlF"1Onv0sqfjxo01/a[PofQF L6sC &#YCvC!Â*3\?8( ?[yhq\t_dIbh.yjR ߄&?i@lGjo|~{#PUmHeA8ೡvOόpb=<_d1Huh)$:P!(4a!;gl$/g{{E쒌bDu'-s4 MrAS\%QǍ In-d %l{#jkӒphX"ޑZp>ry1Ʒbt4d-tM^S˶ 6l]<\v$\r qƣ9tr&7 O=ȉֶ Q< "@plhIEn 4T+]3!+:r1'3]2]`J#E+J:_ۘ` |\kG`@,1ȵvmpdQeMoX{܍&\R8 q%S%YX&rR4Nb(\Ac29a*AdGz$伈yVEh@ZxVZ4}1\bPC6QӂuXK%!߄&?1GIo%%&&ZrŊ˖-Cٮ_]o:sL 'ǏGJdr~at Iͨ1BddD{ջwJll۠)^ծ]XJJ8 !o\B(: KG[VV@ WIS1nh;SOG74C-// &[gk GNbd4/-+֙ 'Ik.3//oeSJ̇ #1>[_ y O@ -բG| 7O>Q^)er]ëϒZ~)oAzrQuҫW\G ՑRͺ'dޝ}"ˆ+,L+W_H*GPP!aa|$Wousss_Ϟ=W='8<nl׺urk$uͿQF 6=Dz>|OD`ljO=stO11"f>N6ǏS rSMƍ܃dݣm8A9bc;]s&7n2uD8S@O9Ql4hҿr|4訨k׮;9A-..'O,g ?>av_ʳg>jG>AHD aDhg#!煪 ){:}H, "E;z"(/>E"%<R\q@~wӳmDDxvav%xeY?YY\Yݒu{ϥU^^!An=t@}Y$_l%KGn5 {{{9aX=?\{]bE~AqqQӧ p///_?Vwܸqv:|<^Ϟ=пu6de&ƍd%:Y $ӣY:^Z:8_؅~v6j!C(d7o,cOMCމz*֞rY)ӧOo{ӯd2EX?w#{FMML;1S/ok߿kK\+uBeĪɠhgvG3-B[]SCUe7oݺuh{?ߍa>؎L`?C ^U|23SdҴ}ҤIB,סC(\|ĉ:4XɔJO<\SN4ܯ_s% s{t(.)fmUWT4$_|̙3B, NϨo#ADej&?776=;vL{{sUe={HҥK2_|Q{a!DI kxՅ رc:rA{gϞ=[~Mܹ􎄃O)#Gg#GPj*y4v/_Xg#RP9ƠnMs=g'^VvyYUfirJm?K? MIF;`O|x" mO8(ժUw~N.zwuHV|i7sܹsS7dG P| Te=(3*<("StT<$?ɴ˿sXXb~@}uaP#W?te.Bt1LR$Q]AN`%]v#)HMMJӡC;3{;vt=Ik!\cH1+LJedR%0a P?(E#O3D9Wfᑅt(Pfŕ>e6ed5;9dʸ"##b޳f͔d')sU꥗^ *Y.daunI&S#"eE6\r_mjO~ui*e˖3tR݉DhC6/( /KNU&}qd ҝ}-2¢EEu L(jzzcý 2{ 3~.YeB/(8uDPcr !?2'O+lٲY%U]]5uT¿Җ-Βҿ?f6}i1s^6774 7ڽg7*avQ1iټyvwMF){PT~nK'T/g9&3B,>zhP\\$YN(sH흪-㾀䀀.Y+ώ4Ϯ*-ׯ3p`6r*@ խ0>!x975.r41e Tiϸ"7zg}}l:'JP:h"+_ g'Ȗ̍ŋDd~Hgh,U3atrfDF׈ӵm-|AA_3Ŀ%y4%"OD( Iаo.akG;B.w5x~4gdkBZHO$]v'%0(x-1D 7򯦶Ƭ_+m)^ѣ_LȈھvZ $zTi_~_rXP9f5IÇA2j&ȐQd0Jʨ(9]73RJS2+Fڹ6+OH u󊎉^X |InAMFj+*E!%AjOU&6J4îʕ+j>4Eipb0wP<5a$ғܯ(Cݡ]wElޔNi Nno-bENAn?q%eHkSl'6۫_~gjP5 .|m[Zϟo.=E OIod?< 333Vnܸq(y0􏈨>pǏFmK"MҗE@ \PʧBCC.%d?:M8A/DԀU㢲vh9'MHɂTsVVĿPN8=.b4f>H/]O=JmEEޥ@?Մ-Ϟ=KgΜH(-Ai6Z7cG,ݻ4drȠd8:͛UT#Dӝ\o@5PkRt2ˈ@??9$hH%wtP*3/Pr mh& c\ٿYmw)FKtPY5x\\WȄY*AeRDkvꤤɓ'+E;l0C(,v^V? Raqq1 j#n5sR'_?D%?P2'^# W tڵk_]fŊ"s@=3gȯ.vA˶yN*;*zU HtGRc(i=frj 2z뚚w+mtXWoر??x5o7jᴃ^3S"8Pfp=NmYBCmʋl۶ puFݚ6oԥkg }Z=7 tqʶw'{FFܬ;>߭ O adE6RA7& w"Զj!jW_}_⎞s bN> iooFT4_jf{\Qè_v?TTZ|ե3["jBBQ@A?;cq"4fCe#iQT@R񓘥PńTĥ)(n̐yy)H2I,&?84f#)nǮX@c.R,[411!>>NIe>JJY+++umo[/H?e 4c7pFLFBBGGܖ3L+-  j ,!qEFN]%vZa27@=U= rw[׻̃I]r>M7{dn=DuDmBEF*%p@E(AQ9`ã nGy7^@_|"`y'az4RȈ|o{1I(ſ#C,m/[CtFI~.TZ:p(ۇ!#U?3FIASHHTݔ rLʗ Hփ$u!;'7m `tѣ;ӦȫH8Y,x4>[K%ǎ>نt6l/()<5Ҁ;1#E~Ŀыgn4j#^ 2{Z*RR r #US)Y[t2"OF9_T{DT+UK,DYY矧J^껤r/2ꏊx\О%wżJŧcDSgQ߽(? jPJn=eƿՃ]Y_wIN?۷uϟ-FKtta՜NŋO>C>T'-h>Xmއ!C(o ' }ɔpV:E:f)h_낎'(1®AC)q:)lڼ.FNqTJ k^0 ]нe` 6Q*sbϞ=(Ŀ$ˠF.?l.~=k^S=4T@=H/fqi&&AFLg^`iN1z>j ވx# B ⟀G1If+мB09δ6U%ϯ ?2ӎw4)<$Nx)" ]c̄gddݽ<̈́|TM'D#x?Rjr;9IdQ jwq_mZzlys-^OO"hd׿^fºu\L}ٜ9_z%|^)8;@r(Si*F~5eD65]]cV˯">B?nwE+}<ai'4Jn I ߮dMڇTRVVlGyп)˕+WRpYY_gffN͛v!Bl27?_fâ(psķvB?!<ҡo߾"kF /??_CCBgWAMSPP#dͺUOJmʁlai;?zu };kXXϋt%ի4!-[6OfS\gҤGZxlICQ3x5=zTz)5*}k2Ο-RޑR8-|҂ 7QĉjkkPUc_E}@z#St, Dp))-9L$u6XJ F 5+=iM&Ó"%IXefoIIᅽ] @C>FVV5ez}MBsR%n9DP2i޽[ ~o(LB/!SNUeP5T9h,.HaC9e~Q30&??!!DWx `mj"PB,9* s$̓n뇼\t[W$BF#m9 g)D/(K'm:4M~:M.=kOu߷w߶5N-P;v4 +DMɩ)[_O1t;e9fBT1ETwdff-ѭ[aJZ(.TH8(yB0ۋPx]MzVSiI"xF %W&~Jhi'E6JDRْ<=ة1Iv=Wxw=#N~"ĽwG(iKKOS79^brRn℠F.!>e5]uw Y\Ke5>—ȈPxe!L2Kzh^\0==M -&jگp#WZ)f!o2Ŀܽt"J'0߅TyH dz{nohva*Á\3ZAQ4JS!DVmSQF3sP-2/R 2:'b/QoC2z c!{4egsaF2tMg4 c`7g.jTMo4{ز*mwgRRD$ V`+aEQv*Lճa*AS-J&5y;)$!cBt#?O*2I 8hʢe@"ɻgW`nTrPEʓJĮB6Tr 'ᕪR~w{YjTϨ Mo%#(9쏐RŘFmf6N "-)Iwl3Yh􀸞m ~n+# XcHoc'sD7yCJv.Zun=@6M~)2TTJ@Js֔'a5Q{ q<Q-n#OV*YXbCi+۶SjQ<''%GlB `RmTGig&SSbi)-5㠐%< 7JQie)`䤎b2Ԅ&7¿(w[SR*UCq8DplDPPϋ^(5yR|Ud`'DB!Hᶞ;ɏ ӐՁL r)HN ~_8L"/yM'0&T߄'4GMC!iFEɠM\ڄK E1lה[P"12qT&.L)\ąQ TfXS:`J s19zwM,Lj4PEo 䠤n MoRe,T8PYK\' V@3v'6"4r}&ٜ*"d|ʴף]!݅ۄxv s.PzYbl'i)^$B|%9D HO(VC~b!~ Mo({Po*M3f#R'rCxMJRjHSLk(ņ#WBzdL\N7xbZCu 2̝-6b #4j6`pbZ(: "TMjSK] MoBD/D)L(a "DTj>e =2 AwMZ>4S JpNkB39B*⋴#5vt} 8yƣ mTeyYNz`i MoLF!>DjeuP$[gǮDEKA9ڷ7pPIdx k'J!g#O3;3&Mn؉=QCE_)7 /Wmw*ƮJ' 9f8Gr\8 ^O:Rzڋit`;F0 ߽p|E.JX[OV&yVmRD#a΄rgЮX*m:9eRzi'#ZB֕rSP q巹Wr'ބBMq1L&_ZuEy+PA) l2~RsLmOrOl8q8'Č?'Qoi%3U6?>2aވeFcġIT#'=7y4ٙrzD I֦GFu1(̈́aJ{bT1r?0CVeI~Sv"ۧ2YiiA6 %_2'ߔjD;:.-L$_cƒ:Gq|yP}¸y~5*KT؉N }(ȉTv{#gm?:*V9SwpΡ1qaGodx%W{ ?3⟬_T G Pm{Jxj+\RorK&M#G( Z}ݾ*TKoʮ-?Nswΐ=EZ T؎YGz|T[0%P)!=)$ rE[* ᎀz}Wwp?|9O錇;.qJ Q#'=zt]b {pO]d](Σ"H}C FIr/TDMSȎ]ٴ(֕+fzTtͮPL&w\CfX*bɌOx"/,%RمE*!_O8'p2^RP )x+]2!&I\dÿG VMP.Q;s^G%jui”,>fA~9SQ3yu/N2^7͚rSU2bcKzR'UWQ ziw/-Yw|ЊL!si + e겒Ή1ϊv_Y،9~^8NQؙl:3W.m=[ӪЧ=csKW^Pu'ѓ˭}tnp. b &eӆ ӅxC9zvX?m輊lăS-1j—Loڙc&xa[z#Ց2YG GM)׻8=S_=@]Qn8>nj^HXFxkSOuN?<^ƤpҿZ&V2wgXl"*v9;Ҫڜ~DRaˎ}'IɮWSm=ma18fyɆ~w峗~enf倉H||r{.r|W'vL884ӳ.F-9|ܗdOSrg.RFIR:T‚Ws3.VgO"jrU[|EX%oUu@9GtcB>[l6J+EF/#:1ZF}ۤY #@a\rͻ Gzxw]U,*=JKHR{t3`½GνT|bκ- yz{w4p:/g.\B)ܡv<YT&-U1%RsΞ8>!QZ-;8®U`5`˷>$bͦACPO+=GY4-=8$Ǹ8gj+i,|')vԯ;sTP}߬?['?Iwk7MK+r04zڎѵk*.~C?F0~n^a,A# S?7wY~-Z{y\I13i|i)J'3oֳ^ 1DV MҖTTL=\~Z>a +/^v>ubpy+ݕMޗ,hПd^m,-ջԼ ]S)-CRoU J-3 0.|1_忼Ňf皗-N|*!z94_AWirKzȬ_<|:oP7yWHwgF>y|rf#Whw?bizT4wz}podT~kyTsw[޾f\nuW;"/o,%A%5+S?o~4[SB>g.Xj4DZF=k \/?[gИ>s^m۟U_9'uضP3vPnjz{K %p#pɪ7\+}Cn8||qWLXdbA9gn}|ʍo|_o-씙ç@EO53ծ߃b)9|Tݜ kkCMk6 ׾}oͅ#*~r]EJoOuC/,J+ParZoΎ k9>Z ,OaJ`w^BES4߹϶*uBvRi\sO ?;g%E}t3P)vꃍB)ܰ qֆJD@zv\D\ EF!{r lrmFXIa'Yy! 1Cnk 4&!_=dp\).Ԫ i5wկC*ۙ'g:)m\}q-Co:ZW5 љ[;R: <tcܝ~Nu.'i-US:NT3PyCMqnap{O= :`Eo&Ö3:J\.r6|7bمDJݥP;}]ZtSj#QHc:~z}/ofTIg[#ڸFy4nS'_ᢑ[V>OHFOZ o(--?[+2UPF$4޳NQZ|hҐ:j\#LOP`Br?{]B*֡Sjϩ3xC&+I{hr“{yz{SzW%rsO2/ I;_KcRq'ZpNPvYEf~Xn}yu˥q׳G05:SPPP=f[:]G:arɽ J{59,k7ޓN(\}v]Grca}9}(K6Rm~t)x|~bwz ;{{}l)w}Y6-$d!Hkה+n4^R`a=={kPB)Oۄzz5=Q"6.2̪.y;o4.6Ύ.ČmVCBVLAG^¦qFD~~b4 A` Mͥ%B(G*ٖgܡȣr/OΓ`8-ݻ|=z]FN?t)<f?6霞琥k_TA?c5f1h= }_w$]/`>>]](J/n_GCsg*^_S}GX`ϥeD!l? /׽!=_{녣tÔKwLDOGӣY+\#F1֍G":u#o}'Cg/]y"QO}|H>y4U+>yi3Ju[IFI4Uq7❯|(EcQ^p9qh\xy j+i@#I}Q>!4Q Jo (ι 'uK훞'?ꥷ/M~2\UG (/WBJ2ʤq WρVچ;'(T^Y{f)>vڴ fu&gW&z't9[VI|fUZ>8C-J~E"TwQ-hx|J!1:f;M#Ec6 ׇfM[bƫаA6WiPr0tqQ)neUl-1WӮOwYPl6K오T3i>~n9JD H$_or4<ȜoTߍ[ԗ2}Jt#,*+)?UMQ mWz=g[mhog: ŌݤgKoAA_1ct5oRw~$ĦCx8Yك?_\˪<~2v_{OHsϿ: ";J㥗2l#Ҙ_8{?zPB}~}lZ;GPt [0(G;s)S)/*hFȢkswqY׃ҿ+J) %r g1ͯȒcsS!<%Ssg~ELW7]}VRn/띙([/, (Jp6Kzmd! רgzU!}^9y\A}-|=ֱ'g( Tv"Czʘ?auT>B=bmkר0\4RǔH9eK:jR2妪*u)#WKڻW/\s?Q@1W'B$*SSq]OS=-&yT9Cqh+Et|o?mlXܗqjlӥhnk_'FusT~Hw Cgy[U+Lʞ4&k~>1iZl3RāTMqqCBdߎ5(gDnք[N`Pzt>/'a[ĬK~ 7 o8񯽇 g9ØXr"bBiF_߼i'L߸Y8z•_z_{Ky啷H?zgd ǎ($ڍ}\e{#WZJ\D_;XFT%9 qCayj;GSzԾJ`Il!cNGϴ8G\MP"u J*fѯF3qhrc̬|}IwY13p*%ǡҩK J:4B# a8DV p9k9>VfugLTDctRG F:L.^8ȯ!?Ok,|#Ҏ;M䜲L:"K~:*ͮrW*[^u6g;Mݍ}'⦡Ą21e5:6JDPgѶo)BGFٹ/r|cGkKBn#/?}e%UcN3 . zh;4"BY(^ֿC>vzOߤGYtۼK:Ff/]M'݋Ճf쵷F<)6,uС7GINLTFwߩ l {s _&N#G*y7wno۲Yiyw(YQiK}ׅKV~ڕv Ɇ]2-kgH2ϴ`9YY':OtTjLS';*JF]VKσec0R~?mRRWl}$E 8z̄XtZ.;ej_7J,1kNbzF! 0=gr19LҿD6MHPi{-z _ 'r5B'$F"'rC.*Qĩ^qwba Sԥgo3g/Hu9s姜q2<+QB'^2v"!r+]`צ0__׬]:Aŵ6?@ JS1)% 3[eĺs=E$!»W>]/"$R_?}.T>ӳL|dZ|m@գSuH,)^+_L>ܩW=c!CpETm HNÿQYf5;#]j6PА/4M4O'#ߐ`ixM퐜'ȅF5ktߕ'Pȡ]"1OH&F3CBCyyyoĩw͏D+Y.]̽S=087?z'A/I=)_9c;vJ$bI{Y?\ǚ!}΍`Wx"kLiJzX 9PԦFw3(3S>Ŗs띙q"`$葙I{[gW%!:9qL; ~ t(rֲC -NܘqmO>Hc E'/-A[{kE[uskKVQH"jjyPDj C:v`4f# _52-,g%S|OnؔҰ1WX4Ee5o+?׈WW| g'Mń;`D#Zh)Os\'!zj*Q`vݸ]ek.AGKSl5WxڳJs7l'ck}{_`Z?G/:&G?qJ ClYv+o ]OGN\PRWўL{)=$nCIwΏ舀&t,f<~>4NmZ`TC\.#(NBBXNOquDykR3=R`MZHX@ɴ\OkOsǹQ95Tg2.RJxv_g56wOq\ɬ// 7$˳ ϗeC Jho2%gVq6Tzy[xs4 F7Qs]0Z_:Q7T OʼUU9?O6ϙG+~b';vk7J#i{{>Cbf'ڨ/D+^.ʼzvxz{]o_tsP\Hdv]} 'Ԫ (qow}H4Έ]ys PCT0P/!~.9-sBB qDVowO;d>}.C &6/\v9(wLu 6|zw?W]g6F!GŞ!qcg>r_Z:I4/³vM\gҙ7hߑ%QW6}(٨uz2y>n`YM\'[TjV&]^;i^_Rm˶Y!TtP\-NWO1YbbȈ*,):ilC_/=㣳/._WzrԿz?h͔\䣻Ŷא'*͜[s"P[R6^aAe KVvij? -z-MsFdſ>S_fk ߾KoCxCߏsKMR+|Ԧ˳h"%\nҿ+_\¼_[× >5Z'Du3ݳSO ybN9nfDFX4E0xN9K$EWTnPt 3+winyȍ{6T.J0G4pɤ;#:4[#m:}uY>aH6h =jo.-!y˜`'%TK⇷~l\t; JA~tʕT(%q™L-W~zbV_Pc 9^.᦯e ?/0h_r}!^Ax@zL`\f( G=pD_OEfRUHtR˓֛6e*aO~.) 0uh9&9I™ďnb(Wi¿J?:Lߑs8FC1¿f ۴mCu[jp@3&c#"幡LAedIVHTzxjNL\y7"&?/@h'mdxS -B5dJ;&iyU^v_Q*.9Im@jOhI@\aqcMܮkjo"6L o<'ry1c__1&pyOd"#,0"S4^*"/*!_#xG8c3C̈7\5EfPf6TߒrRXIA`X%Nh5N6T1S"6AٵUVkPG .I˛X@m^ju=otR08kA rUT%yd :FLS]lHWFMd^P>9>׵qY@K8.^I2ϿPnupZa rWo~f1~P{ؑy}A;L|IJwT`{L n(6nܒw[krG^3؉o\Ae) Jƀ85*1)y/WU\<ȒWZʇv~m>lK HVk2dkOS[J{Hڒ&SAO7e{7Ϗ^V&>rf=]eUfg._zW:(߲CmڥP{jt(61nꃫM>)&*0I+MH1tB)T<92PR OA@dBFSD$ eHD3{=hRz -ە(C MoRRr;6ud ͫj8} )O)FIKùǃ@8ֆYehӏa gMMyH1Q>SG5T['nRa'PB^ny,Sf'M#H}om9(l?Nn C!LN mHN?/CSzCQ摿H2LO8CR\jbmka;b:*dž?tFk=ecCzɨFCx?)s[?FϮ\xWSפF\##rC">FOL+/rܖ;R;ʈO4gHyE/VJjðYtcOk$Uk|%!?st.zfiwהw GYB(['R$&wi.Ql ˣ?x8,s$#~}oS3xQ9_0wcv)$S"B))LGJLH̹PIΝvZ6$oLY!<&0(+&vs*V?`PrSj)DcvnԵgԔeR9`s?چl)Mvq tce:%GvU>g ޻Sb\V.>q(*wO=yr]WKذNarRor(d`Լ^'\鸾}4,گl_=]TՓrG~{y9#v%"hXZsKKô䙿<9+7M:,ζׇEۯŤGtK;n{ӿ̚M=jƟ 6Wi̘?{ yUr_^grnFſlu#WUfMzuŇY C:ɜ\/!qP)n_Z-tSorznyqnsvqa] ?nN9)r%LU-0'XR"x󣌅#2cbbtl>52.KU:l~>?/?LW8w{Щsy9wj@#:vK9ar3ݮ;[:Df]~V3Kji瞗Nj_P$k ɢw; P; vpZ5wq_Q^=jjBҴUm=z)ܣ}on\"&0P~ҭyfO7kVڳ?JIoT{[֭8. Zn)9'k˳G-1{m\)ǧ닋ջxl}ͤ27IQZ[ZREҡtPwjH=ݼek@{`tb}$/s 4sjbcϴ pM}Hkl=f9#~.Ͻf(|EwpCl6oƧm+O0~-nis`gb>1ǛÝ0f\M]HgM2ˣ53"4`H3/xk5ɩ~O5s6\ҙDuZ謦*ңr^Ym~vqmMMO߈ȉ>> 0 ?B%ɇⲪgi-^y#$Kn隼ai򅼙nB8oO9yKkDԦs/;tC۴Kܑ REiO 6?!{C+2NAsm8?ԆS3 =mqh{"vXJYZ#33{DK㨬n?4[PϜ^Y!_Ddw$ϣ}fBȈDuF(DfH_g'D}E9-E5?4˩;l֭-}NO};8̩/g- 4x|6mS^:+|Fɚ#E4+!amUHWv?$BD"Nmz}k+v8XjVn]--o"=n4.韐(X?\،K^K=r?D3"1FT0Vx8hϔqzM$m›hҳ/h˹BG:e9w;cM%WȓXHKO/Y0H-,_ٗin.*"ڢk76ҿBM~+W^y{3#GnU"lρ{40(؁\\vs.]xۍ +qypv$UV ƳɿC%Yvƀm>]"l2m|⇳n\޿M[ rw4#[^5?7kce}Fsmxof͚i{i_.#B*!>yx_f:LVr(~{;=rzwgnGgp>4CDW!1_::&:6D{jުR͹/*n[q{־w<}jAno߹y'[~xloٹWs^BC-991c4­DhOv3yccOy!l͚=/u퐈=rCޓ1# VAW CMbLm#Tc׮#UF>wεrd/_LH_`llT1f`?aY;鳑-KVobGzN=ʉq Wccg|B}|qf !ΑΞH݊?;%$!8F"u!]5!:':p ~JԮ= ;#NgTq`{8gm 0"S+6bK.ot&-[@~yrT>B?ҿ> ͹_[/AѿѮHza袝>ڊtYV-n^_#^th=DŬ`P"Sѭ52wߑ5̯MwFtQߢQ۶qm{/4"e6Βt]PF9ȾQ'/:`ٌm!W L˯"Zqg/"2{>!00:s_?*; S},,?MB(Qy-z6@ q"CöEGzT"g('& -pk#/yE*qQڴXh )+,ذIKHHqʿמqiPعBP}"]#%f!oL˯_h,覤)yt(ߖ|ߑrkϭԯ ѡ^Gm{m^-eY?[#_}(Pľ5_jh4o7=ZDT7uҲ3O?҆+oɜ""3^jikg_nIt՟]2;[Q>i¥DL:Ύ*:Z(GltCG`4AiCE)5[<(WlL ޜ>asm9DR?Lvg4{;Ź`{km&WPlL60Vl$C`#SlyZ4otO8~r6E23yy},AkMp?8yNwXZά1FݢȅR ŧ/#ſC9E4՛ пq7@J_ GN\pK\e˖͛7vYsƿS]߮"0yIE(Wqw8-F+=*ggfϰ~/&tw M&,rv^w Wo|F? J?g$lta 6r``J=􏗳VNr=9$s|]3퓴哣H}up~mO?ǧznݪ9=tηCSo t\V sDՑ^CDJwG7{[uUlJ׋< #hcJܽ?_6@9"CO7 nd4z!Cb7|quW9P{ݎ3p6߃Q/k)1dzN}od{&v)ںV9ΓϘsQgM_H( i{Ae,[0{uj ޣ}v@%k=M_Utxj^\Y0Ik|b|tQj?{~MtٸADiB?.uȾSK5}"Y\O58tYvnYwg}vl[WpH#)':?ҿYL|[7¯l}wż(0  'wKg{M͵ia>ÆOoh;Q@bdcqhilp*v~7`?nƝ>9"Rr= VQ(u.#I :L9߭4:{0wq=լٽ?ܟƿR]HrMOqH+Yf)w;`Tt'u1W=0 {x-IXP^C\OazeCrMX9ϟ.xaD;֠^eYUsڲ:~O Gt3lG9t0h؀͟CtdrW.lc 8A>?9=awמIQ`Tz~a\T9fXZ$u M#n[#{yc|KF:[Ӿ`JuR GY ]"` !rvrn+W ϹكO.>hlHƾNΆnIOmCxmݫn^{[Po%cXEceju<{ynvx=Ȉs2myN"D)!^9] w)"Vn;Ч?c:3 0.^ZYn#CG!O+Mjt}7ݒY7'GخS.E)?O5sV~pl> j6̦S_^+=vsbt(QHO;ܺis\5H!C}9o*w쩲njड6{gO:8+N.2vj. {+sEknyQeuØ]F;6 겲ӵtHI5aZڹ" F}Y#?SWhqΘiph_|=?y _˫7?!ieoߛvcᅄU4vn\!~}RӃ\#:r}֤3Y,8b0_O Lj?;^^<9)?`FF?|7.p"gC2ǵӉoײGoϜg\BdW4nw!;ѳ?\TC }zl'\XԢw3"oʈ\^wԈtL.~מ/m/o;>־i).csLRGzk,*=Y>C[;`-_D T"vQa}JÔ&ϐS?DS}4 ^?_]abDwsS!QEvdg[SlVm5iKIZ jZ*T G9aPv?j>3", Kfc?=2)LlrT_y(nuM0ze˄eo~O~gGoŚrE!r.xq+ƛlrk73L|)_zC#1RdW$הUQ-zaSjN{qܤ/j˓>_5mG'w+9s5"Ni wNXHφ?6Rg1~^j2IVТ+ʅh5󋄾VzO=o;X? Vg?r7g_SAMW" 74zUsK|O"n_A $\ Ch'f֯ͿR2vs͏Rm7:缴wXɃ] I^Gdiځ_}Qh^7` ~w;?j(ͻ mdpED+o"x_z{Olܱ}aL]߱ڭO(k˷fR( :P^l |\vT4s'wZǮ9Xߚ@Dhf6N?i }6.D6J-ߛ Eg)[7@NM{hE2]E?]OE1͏-]FLX׿0ʈR;t u&yeyH&`NjQQG%;f>OÚ!f1dcvKAo@Ǎp/G|Znu0dY*6×+%U25һo\|bZU7߮dD ZMqPd*g9H[;v5Ŷ:(I`\Vk)s?&0 JCsm>p?ߍ܆ H $5rJ50oSjV6Lj䷊qT\4Z+DxpĸKC:F#-e6E1;c.QLqK(1 &&9Wz*JНRuO'':&KQ` Mo,sLS3"$%  "]q1嫤j= G Z9v>td"LώC,-Anw([Sz\IF]X1 fyBe?‹k0{HJ&AnAFc{ߤc+rdR%%OtaEG/ ^Am.E ǘkP;hRq+B\C )g]'i$fOA0%1&7C߄'وuʓFe/d]$V2١JDY6PTC<5O1D-fqiQQit> hTnS"&7 O=PQ@>E HIiK2z]QW@J)(3 &YAS $`& V-)w4FxJl8K; $*ܮR47 Mba2'm,zDq~05BI]"eqnMkU_3Z4)>/$R)JxPvHm\NyVegMo+j7PvIENDB`termenv-0.15.2/examples/hello-world/main.go000066400000000000000000000041601444632052500206060ustar00rootroot00000000000000package main import ( "fmt" "github.com/muesli/termenv" ) func main() { restoreConsole, err := termenv.EnableVirtualTerminalProcessing(termenv.DefaultOutput()) if err != nil { panic(err) } defer restoreConsole() p := termenv.ColorProfile() fmt.Printf("\n\t%s %s %s %s %s", termenv.String("bold").Bold(), termenv.String("faint").Faint(), termenv.String("italic").Italic(), termenv.String("underline").Underline(), termenv.String("crossout").CrossOut(), ) fmt.Printf("\n\t%s %s %s %s %s %s %s", termenv.String("red").Foreground(p.Color("#E88388")), termenv.String("green").Foreground(p.Color("#A8CC8C")), termenv.String("yellow").Foreground(p.Color("#DBAB79")), termenv.String("blue").Foreground(p.Color("#71BEF2")), termenv.String("magenta").Foreground(p.Color("#D290E4")), termenv.String("cyan").Foreground(p.Color("#66C2CD")), termenv.String("gray").Foreground(p.Color("#B9BFCA")), ) fmt.Printf("\n\t%s %s %s %s %s %s %s\n\n", termenv.String("red").Foreground(p.Color("0")).Background(p.Color("#E88388")), termenv.String("green").Foreground(p.Color("0")).Background(p.Color("#A8CC8C")), termenv.String("yellow").Foreground(p.Color("0")).Background(p.Color("#DBAB79")), termenv.String("blue").Foreground(p.Color("0")).Background(p.Color("#71BEF2")), termenv.String("magenta").Foreground(p.Color("0")).Background(p.Color("#D290E4")), termenv.String("cyan").Foreground(p.Color("0")).Background(p.Color("#66C2CD")), termenv.String("gray").Foreground(p.Color("0")).Background(p.Color("#B9BFCA")), ) fmt.Printf("\n\t%s %s\n", termenv.String("Has foreground color").Bold(), termenv.ForegroundColor()) fmt.Printf("\t%s %s\n", termenv.String("Has background color").Bold(), termenv.BackgroundColor()) fmt.Printf("\t%s %t\n", termenv.String("Has dark background?").Bold(), termenv.HasDarkBackground()) fmt.Println() hw := "Hello, world!" termenv.Copy(hw) fmt.Printf("\t%q copied to clipboard\n", hw) fmt.Println() termenv.Notify("Termenv", hw) fmt.Print("\tTriggered a notification") fmt.Println() fmt.Printf("\t%s", termenv.Hyperlink("http://example.com", "This is a link")) fmt.Println() } termenv-0.15.2/examples/ssh/000077500000000000000000000000001444632052500156775ustar00rootroot00000000000000termenv-0.15.2/examples/ssh/go.mod000066400000000000000000000015251444632052500170100ustar00rootroot00000000000000module github.com/muesli/termenv/examples/ssh go 1.18 require ( github.com/charmbracelet/ssh v0.0.0-20221117183211-483d43d97103 github.com/charmbracelet/wish v1.0.0 github.com/creack/pty v1.1.18 github.com/muesli/termenv v0.13.0 ) require ( github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/aymanbagabas/go-osc52 v1.2.1 // indirect github.com/caarlos0/sshmarshal v0.1.0 // indirect github.com/charmbracelet/keygen v0.3.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect golang.org/x/crypto v0.3.0 // indirect golang.org/x/sys v0.2.0 // indirect ) replace github.com/muesli/termenv => ../../ termenv-0.15.2/examples/ssh/go.sum000066400000000000000000000072641444632052500170430ustar00rootroot00000000000000github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/aymanbagabas/go-osc52 v1.2.1 h1:q2sWUyDcozPLcLabEMd+a+7Ea2DitxZVN9hTxab9L4E= github.com/aymanbagabas/go-osc52 v1.2.1/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= github.com/caarlos0/sshmarshal v0.1.0 h1:zTCZrDORFfWh526Tsb7vCm3+Yg/SfW/Ub8aQDeosk0I= github.com/caarlos0/sshmarshal v0.1.0/go.mod h1:7Pd/0mmq9x/JCzKauogNjSQEhivBclCQHfr9dlpDIyA= github.com/charmbracelet/keygen v0.3.0 h1:mXpsQcH7DDlST5TddmXNXjS0L7ECk4/kLQYyBcsan2Y= github.com/charmbracelet/keygen v0.3.0/go.mod h1:1ukgO8806O25lUZ5s0IrNur+RlwTBERlezdgW71F5rM= github.com/charmbracelet/ssh v0.0.0-20221117183211-483d43d97103 h1:wpHMERIN0pQZE635jWwT1dISgfjbpUcEma+fbPKSMCU= github.com/charmbracelet/ssh v0.0.0-20221117183211-483d43d97103/go.mod h1:0Vm2/8yBljiLDnGJHU8ehswfawrEybGk33j5ssqKQVM= github.com/charmbracelet/wish v1.0.0 h1:Ca/Sm8NfbW0/hEtw+voxwgKd5iRq9v7P3X/cDVV8doY= github.com/charmbracelet/wish v1.0.0/go.mod h1:LatUnJh7kQXK5kvkvuwvddCSeUn8Yss02nDh54yLQas= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= termenv-0.15.2/examples/ssh/main.go000066400000000000000000000070721444632052500171600ustar00rootroot00000000000000package main import ( "fmt" "log" "os" "strings" "github.com/charmbracelet/wish" "github.com/creack/pty" "github.com/charmbracelet/ssh" "github.com/muesli/termenv" ) type sshOutput struct { ssh.Session tty *os.File } func (s *sshOutput) Write(p []byte) (int, error) { return s.Session.Write(p) } func (s *sshOutput) Read(p []byte) (int, error) { return s.Session.Read(p) } func (s *sshOutput) Name() string { return s.tty.Name() } func (s *sshOutput) Fd() uintptr { return s.tty.Fd() } type sshEnviron struct { environ []string } func (s *sshEnviron) Getenv(key string) string { for _, v := range s.environ { if strings.HasPrefix(v, key+"=") { return v[len(key)+1:] } } return "" } func (s *sshEnviron) Environ() []string { return s.environ } func outputFromSession(s ssh.Session) *termenv.Output { sshPty, _, _ := s.Pty() _, tty, err := pty.Open() if err != nil { panic(err) } o := &sshOutput{ Session: s, tty: tty, } environ := s.Environ() environ = append(environ, fmt.Sprintf("TERM=%s", sshPty.Term)) e := &sshEnviron{ environ: environ, } return termenv.NewOutput(o, termenv.WithUnsafe(), termenv.WithEnvironment(e)) } func main() { s, err := wish.NewServer( wish.WithAddress(":2345"), wish.WithHostKeyPath("termenv"), wish.WithMiddleware( func(sh ssh.Handler) ssh.Handler { return func(s ssh.Session) { output := outputFromSession(s) p := output.ColorProfile() fmt.Fprintf(s, "\tColor Profile: %d\n", p) fmt.Fprintf(s, "\n\t%s %s %s %s %s", output.String("bold").Bold(), output.String("faint").Faint(), output.String("italic").Italic(), output.String("underline").Underline(), output.String("crossout").CrossOut(), ) fmt.Fprintf(s, "\n\t%s %s %s %s %s %s %s", output.String("red").Foreground(p.Color("#E88388")), output.String("green").Foreground(p.Color("#A8CC8C")), output.String("yellow").Foreground(p.Color("#DBAB79")), output.String("blue").Foreground(p.Color("#71BEF2")), output.String("magenta").Foreground(p.Color("#D290E4")), output.String("cyan").Foreground(p.Color("#66C2CD")), output.String("gray").Foreground(p.Color("#B9BFCA")), ) fmt.Fprintf(s, "\n\t%s %s %s %s %s %s %s\n\n", output.String("red").Foreground(p.Color("0")).Background(p.Color("#E88388")), output.String("green").Foreground(p.Color("0")).Background(p.Color("#A8CC8C")), output.String("yellow").Foreground(p.Color("0")).Background(p.Color("#DBAB79")), output.String("blue").Foreground(p.Color("0")).Background(p.Color("#71BEF2")), output.String("magenta").Foreground(p.Color("0")).Background(p.Color("#D290E4")), output.String("cyan").Foreground(p.Color("0")).Background(p.Color("#66C2CD")), output.String("gray").Foreground(p.Color("0")).Background(p.Color("#B9BFCA")), ) fmt.Fprintf(s, "\n\t%s %s\n", output.String("Has foreground color").Bold(), output.ForegroundColor()) fmt.Fprintf(s, "\t%s %s\n", output.String("Has background color").Bold(), output.BackgroundColor()) fmt.Fprintf(s, "\t%s %t\n", output.String("Has dark background?").Bold(), output.HasDarkBackground()) fmt.Fprintln(s) hw := "Hello, world!" output.Copy(hw) fmt.Fprintf(s, "\t%q copied to clipboard\n", hw) fmt.Fprintln(s) fmt.Fprintf(s, "\t%s", output.Hyperlink("http://example.com", "This is a link")) fmt.Fprintln(s) sh(s) } }, ), ) if err != nil { log.Fatal(err) } log.Printf("Listening on %s", s.Addr) if err := s.ListenAndServe(); err != nil { log.Fatal(err) } } termenv-0.15.2/examples/ssh/termenv_ed25519000066400000000000000000000006031444632052500203570ustar00rootroot00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtz c2gtZWQyNTUxOQAAACAeuJK5oCCNOBE3rCybMAP/4LYHXvUPYiMMJJJiAW+02AAA AIheRHlCXkR5QgAAAAtzc2gtZWQyNTUxOQAAACAeuJK5oCCNOBE3rCybMAP/4LYH XvUPYiMMJJJiAW+02AAAAEBkzzk0pLmdUUrg3/juKDH9LHEm904/sUwuMZWhvzes cx64krmgII04ETesLJswA//gtgde9Q9iIwwkkmIBb7TYAAAAAAECAwQF -----END OPENSSH PRIVATE KEY----- termenv-0.15.2/examples/ssh/termenv_ed25519.pub000066400000000000000000000001211444632052500211370ustar00rootroot00000000000000ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB64krmgII04ETesLJswA//gtgde9Q9iIwwkkmIBb7TY termenv-0.15.2/go.mod000066400000000000000000000004451444632052500143750ustar00rootroot00000000000000module github.com/muesli/termenv go 1.17 require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 github.com/lucasb-eyer/go-colorful v1.2.0 github.com/mattn/go-isatty v0.0.18 github.com/mattn/go-runewidth v0.0.14 golang.org/x/sys v0.7.0 ) require github.com/rivo/uniseg v0.2.0 // indirect termenv-0.15.2/go.sum000066400000000000000000000021411444632052500144150ustar00rootroot00000000000000github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= termenv-0.15.2/hyperlink.go000066400000000000000000000004611444632052500156210ustar00rootroot00000000000000package termenv // Hyperlink creates a hyperlink using OSC8. func Hyperlink(link, name string) string { return output.Hyperlink(link, name) } // Hyperlink creates a hyperlink using OSC8. func (o *Output) Hyperlink(link, name string) string { return OSC + "8;;" + link + ST + name + OSC + "8;;" + ST } termenv-0.15.2/notification.go000066400000000000000000000004471444632052500163060ustar00rootroot00000000000000package termenv // Notify triggers a notification using OSC777. func Notify(title, body string) { output.Notify(title, body) } // Notify triggers a notification using OSC777. func (o *Output) Notify(title, body string) { _, _ = o.WriteString(OSC + "777;notify;" + title + ";" + body + ST) } termenv-0.15.2/output.go000066400000000000000000000073511444632052500151610ustar00rootroot00000000000000package termenv import ( "io" "os" "sync" ) var ( // output is the default global output. output = NewOutput(os.Stdout) ) // File represents a file descriptor. type File interface { io.ReadWriter Fd() uintptr } // OutputOption sets an option on Output. type OutputOption = func(*Output) // Output is a terminal output. type Output struct { Profile tty io.Writer environ Environ assumeTTY bool unsafe bool cache bool fgSync *sync.Once fgColor Color bgSync *sync.Once bgColor Color } // Environ is an interface for getting environment variables. type Environ interface { Environ() []string Getenv(string) string } type osEnviron struct{} func (oe *osEnviron) Environ() []string { return os.Environ() } func (oe *osEnviron) Getenv(key string) string { return os.Getenv(key) } // DefaultOutput returns the default global output. func DefaultOutput() *Output { return output } // SetDefaultOutput sets the default global output. func SetDefaultOutput(o *Output) { output = o } // NewOutput returns a new Output for the given file descriptor. func NewOutput(tty io.Writer, opts ...OutputOption) *Output { o := &Output{ tty: tty, environ: &osEnviron{}, Profile: -1, fgSync: &sync.Once{}, fgColor: NoColor{}, bgSync: &sync.Once{}, bgColor: NoColor{}, } if o.tty == nil { o.tty = os.Stdout } for _, opt := range opts { opt(o) } if o.Profile < 0 { o.Profile = o.EnvColorProfile() } return o } // WithEnvironment returns a new OutputOption for the given environment. func WithEnvironment(environ Environ) OutputOption { return func(o *Output) { o.environ = environ } } // WithProfile returns a new OutputOption for the given profile. func WithProfile(profile Profile) OutputOption { return func(o *Output) { o.Profile = profile } } // WithColorCache returns a new OutputOption with fore- and background color values // pre-fetched and cached. func WithColorCache(v bool) OutputOption { return func(o *Output) { o.cache = v // cache the values now _ = o.ForegroundColor() _ = o.BackgroundColor() } } // WithTTY returns a new OutputOption to assume whether or not the output is a TTY. // This is useful when mocking console output. func WithTTY(v bool) OutputOption { return func(o *Output) { o.assumeTTY = v } } // WithUnsafe returns a new OutputOption with unsafe mode enabled. Unsafe mode doesn't // check whether or not the terminal is a TTY. // // This option supersedes WithTTY. // // This is useful when mocking console output and enforcing ANSI escape output // e.g. on SSH sessions. func WithUnsafe() OutputOption { return func(o *Output) { o.unsafe = true } } // ForegroundColor returns the terminal's default foreground color. func (o *Output) ForegroundColor() Color { f := func() { if !o.isTTY() { return } o.fgColor = o.foregroundColor() } if o.cache { o.fgSync.Do(f) } else { f() } return o.fgColor } // BackgroundColor returns the terminal's default background color. func (o *Output) BackgroundColor() Color { f := func() { if !o.isTTY() { return } o.bgColor = o.backgroundColor() } if o.cache { o.bgSync.Do(f) } else { f() } return o.bgColor } // HasDarkBackground returns whether terminal uses a dark-ish background. func (o *Output) HasDarkBackground() bool { c := ConvertToRGB(o.BackgroundColor()) _, _, l := c.Hsl() return l < 0.5 } // TTY returns the terminal's file descriptor. This may be nil if the output is // not a terminal. func (o Output) TTY() File { if f, ok := o.tty.(File); ok { return f } return nil } func (o Output) Write(p []byte) (int, error) { return o.tty.Write(p) } // WriteString writes the given string to the output. func (o Output) WriteString(s string) (int, error) { return o.Write([]byte(s)) } termenv-0.15.2/profile.go000066400000000000000000000032041444632052500152520ustar00rootroot00000000000000package termenv import ( "image/color" "strconv" "strings" "github.com/lucasb-eyer/go-colorful" ) // Profile is a color profile: Ascii, ANSI, ANSI256, or TrueColor. type Profile int const ( // TrueColor, 24-bit color profile TrueColor = Profile(iota) // ANSI256, 8-bit color profile ANSI256 // ANSI, 4-bit color profile ANSI // Ascii, uncolored profile Ascii //nolint:revive ) // String returns a new Style. func (p Profile) String(s ...string) Style { return Style{ profile: p, string: strings.Join(s, " "), } } // Convert transforms a given Color to a Color supported within the Profile. func (p Profile) Convert(c Color) Color { if p == Ascii { return NoColor{} } switch v := c.(type) { case ANSIColor: return v case ANSI256Color: if p == ANSI { return ansi256ToANSIColor(v) } return v case RGBColor: h, err := colorful.Hex(string(v)) if err != nil { return nil } if p != TrueColor { ac := hexToANSI256Color(h) if p == ANSI { return ansi256ToANSIColor(ac) } return ac } return v } return c } // Color creates a Color from a string. Valid inputs are hex colors, as well as // ANSI color codes (0-15, 16-255). func (p Profile) Color(s string) Color { if len(s) == 0 { return nil } var c Color if strings.HasPrefix(s, "#") { c = RGBColor(s) } else { i, err := strconv.Atoi(s) if err != nil { return nil } if i < 16 { c = ANSIColor(i) } else { c = ANSI256Color(i) } } return p.Convert(c) } // FromColor creates a Color from a color.Color. func (p Profile) FromColor(c color.Color) Color { col, _ := colorful.MakeColor(c) return p.Color(col.Hex()) } termenv-0.15.2/screen.go000066400000000000000000000373341444632052500151040ustar00rootroot00000000000000package termenv import ( "fmt" "strings" ) // Sequence definitions. const ( // Cursor positioning. CursorUpSeq = "%dA" CursorDownSeq = "%dB" CursorForwardSeq = "%dC" CursorBackSeq = "%dD" CursorNextLineSeq = "%dE" CursorPreviousLineSeq = "%dF" CursorHorizontalSeq = "%dG" CursorPositionSeq = "%d;%dH" EraseDisplaySeq = "%dJ" EraseLineSeq = "%dK" ScrollUpSeq = "%dS" ScrollDownSeq = "%dT" SaveCursorPositionSeq = "s" RestoreCursorPositionSeq = "u" ChangeScrollingRegionSeq = "%d;%dr" InsertLineSeq = "%dL" DeleteLineSeq = "%dM" // Explicit values for EraseLineSeq. EraseLineRightSeq = "0K" EraseLineLeftSeq = "1K" EraseEntireLineSeq = "2K" // Mouse. EnableMousePressSeq = "?9h" // press only (X10) DisableMousePressSeq = "?9l" EnableMouseSeq = "?1000h" // press, release, wheel DisableMouseSeq = "?1000l" EnableMouseHiliteSeq = "?1001h" // highlight DisableMouseHiliteSeq = "?1001l" EnableMouseCellMotionSeq = "?1002h" // press, release, move on pressed, wheel DisableMouseCellMotionSeq = "?1002l" EnableMouseAllMotionSeq = "?1003h" // press, release, move, wheel DisableMouseAllMotionSeq = "?1003l" EnableMouseExtendedModeSeq = "?1006h" // press, release, move, wheel, extended coordinates DisableMouseExtendedModeSeq = "?1006l" EnableMousePixelsModeSeq = "?1016h" // press, release, move, wheel, extended pixel coordinates DisableMousePixelsModeSeq = "?1016l" // Screen. RestoreScreenSeq = "?47l" SaveScreenSeq = "?47h" AltScreenSeq = "?1049h" ExitAltScreenSeq = "?1049l" // Bracketed paste. // https://en.wikipedia.org/wiki/Bracketed-paste EnableBracketedPasteSeq = "?2004h" DisableBracketedPasteSeq = "?2004l" StartBracketedPasteSeq = "200~" EndBracketedPasteSeq = "201~" // Session. SetWindowTitleSeq = "2;%s" + string(BEL) SetForegroundColorSeq = "10;%s" + string(BEL) SetBackgroundColorSeq = "11;%s" + string(BEL) SetCursorColorSeq = "12;%s" + string(BEL) ShowCursorSeq = "?25h" HideCursorSeq = "?25l" ) // Reset the terminal to its default style, removing any active styles. func (o Output) Reset() { fmt.Fprint(o.tty, CSI+ResetSeq+"m") } // SetForegroundColor sets the default foreground color. func (o Output) SetForegroundColor(color Color) { fmt.Fprintf(o.tty, OSC+SetForegroundColorSeq, color) } // SetBackgroundColor sets the default background color. func (o Output) SetBackgroundColor(color Color) { fmt.Fprintf(o.tty, OSC+SetBackgroundColorSeq, color) } // SetCursorColor sets the cursor color. func (o Output) SetCursorColor(color Color) { fmt.Fprintf(o.tty, OSC+SetCursorColorSeq, color) } // RestoreScreen restores a previously saved screen state. func (o Output) RestoreScreen() { fmt.Fprint(o.tty, CSI+RestoreScreenSeq) } // SaveScreen saves the screen state. func (o Output) SaveScreen() { fmt.Fprint(o.tty, CSI+SaveScreenSeq) } // AltScreen switches to the alternate screen buffer. The former view can be // restored with ExitAltScreen(). func (o Output) AltScreen() { fmt.Fprint(o.tty, CSI+AltScreenSeq) } // ExitAltScreen exits the alternate screen buffer and returns to the former // terminal view. func (o Output) ExitAltScreen() { fmt.Fprint(o.tty, CSI+ExitAltScreenSeq) } // ClearScreen clears the visible portion of the terminal. func (o Output) ClearScreen() { fmt.Fprintf(o.tty, CSI+EraseDisplaySeq, 2) o.MoveCursor(1, 1) } // MoveCursor moves the cursor to a given position. func (o Output) MoveCursor(row int, column int) { fmt.Fprintf(o.tty, CSI+CursorPositionSeq, row, column) } // HideCursor hides the cursor. func (o Output) HideCursor() { fmt.Fprint(o.tty, CSI+HideCursorSeq) } // ShowCursor shows the cursor. func (o Output) ShowCursor() { fmt.Fprint(o.tty, CSI+ShowCursorSeq) } // SaveCursorPosition saves the cursor position. func (o Output) SaveCursorPosition() { fmt.Fprint(o.tty, CSI+SaveCursorPositionSeq) } // RestoreCursorPosition restores a saved cursor position. func (o Output) RestoreCursorPosition() { fmt.Fprint(o.tty, CSI+RestoreCursorPositionSeq) } // CursorUp moves the cursor up a given number of lines. func (o Output) CursorUp(n int) { fmt.Fprintf(o.tty, CSI+CursorUpSeq, n) } // CursorDown moves the cursor down a given number of lines. func (o Output) CursorDown(n int) { fmt.Fprintf(o.tty, CSI+CursorDownSeq, n) } // CursorForward moves the cursor up a given number of lines. func (o Output) CursorForward(n int) { fmt.Fprintf(o.tty, CSI+CursorForwardSeq, n) } // CursorBack moves the cursor backwards a given number of cells. func (o Output) CursorBack(n int) { fmt.Fprintf(o.tty, CSI+CursorBackSeq, n) } // CursorNextLine moves the cursor down a given number of lines and places it at // the beginning of the line. func (o Output) CursorNextLine(n int) { fmt.Fprintf(o.tty, CSI+CursorNextLineSeq, n) } // CursorPrevLine moves the cursor up a given number of lines and places it at // the beginning of the line. func (o Output) CursorPrevLine(n int) { fmt.Fprintf(o.tty, CSI+CursorPreviousLineSeq, n) } // ClearLine clears the current line. func (o Output) ClearLine() { fmt.Fprint(o.tty, CSI+EraseEntireLineSeq) } // ClearLineLeft clears the line to the left of the cursor. func (o Output) ClearLineLeft() { fmt.Fprint(o.tty, CSI+EraseLineLeftSeq) } // ClearLineRight clears the line to the right of the cursor. func (o Output) ClearLineRight() { fmt.Fprint(o.tty, CSI+EraseLineRightSeq) } // ClearLines clears a given number of lines. func (o Output) ClearLines(n int) { clearLine := fmt.Sprintf(CSI+EraseLineSeq, 2) cursorUp := fmt.Sprintf(CSI+CursorUpSeq, 1) fmt.Fprint(o.tty, clearLine+strings.Repeat(cursorUp+clearLine, n)) } // ChangeScrollingRegion sets the scrolling region of the terminal. func (o Output) ChangeScrollingRegion(top, bottom int) { fmt.Fprintf(o.tty, CSI+ChangeScrollingRegionSeq, top, bottom) } // InsertLines inserts the given number of lines at the top of the scrollable // region, pushing lines below down. func (o Output) InsertLines(n int) { fmt.Fprintf(o.tty, CSI+InsertLineSeq, n) } // DeleteLines deletes the given number of lines, pulling any lines in // the scrollable region below up. func (o Output) DeleteLines(n int) { fmt.Fprintf(o.tty, CSI+DeleteLineSeq, n) } // EnableMousePress enables X10 mouse mode. Button press events are sent only. func (o Output) EnableMousePress() { fmt.Fprint(o.tty, CSI+EnableMousePressSeq) } // DisableMousePress disables X10 mouse mode. func (o Output) DisableMousePress() { fmt.Fprint(o.tty, CSI+DisableMousePressSeq) } // EnableMouse enables Mouse Tracking mode. func (o Output) EnableMouse() { fmt.Fprint(o.tty, CSI+EnableMouseSeq) } // DisableMouse disables Mouse Tracking mode. func (o Output) DisableMouse() { fmt.Fprint(o.tty, CSI+DisableMouseSeq) } // EnableMouseHilite enables Hilite Mouse Tracking mode. func (o Output) EnableMouseHilite() { fmt.Fprint(o.tty, CSI+EnableMouseHiliteSeq) } // DisableMouseHilite disables Hilite Mouse Tracking mode. func (o Output) DisableMouseHilite() { fmt.Fprint(o.tty, CSI+DisableMouseHiliteSeq) } // EnableMouseCellMotion enables Cell Motion Mouse Tracking mode. func (o Output) EnableMouseCellMotion() { fmt.Fprint(o.tty, CSI+EnableMouseCellMotionSeq) } // DisableMouseCellMotion disables Cell Motion Mouse Tracking mode. func (o Output) DisableMouseCellMotion() { fmt.Fprint(o.tty, CSI+DisableMouseCellMotionSeq) } // EnableMouseAllMotion enables All Motion Mouse mode. func (o Output) EnableMouseAllMotion() { fmt.Fprint(o.tty, CSI+EnableMouseAllMotionSeq) } // DisableMouseAllMotion disables All Motion Mouse mode. func (o Output) DisableMouseAllMotion() { fmt.Fprint(o.tty, CSI+DisableMouseAllMotionSeq) } // EnableMouseExtendedMotion enables Extended Mouse mode (SGR). This should be // enabled in conjunction with EnableMouseCellMotion, and EnableMouseAllMotion. func (o Output) EnableMouseExtendedMode() { fmt.Fprint(o.tty, CSI+EnableMouseExtendedModeSeq) } // DisableMouseExtendedMotion disables Extended Mouse mode (SGR). func (o Output) DisableMouseExtendedMode() { fmt.Fprint(o.tty, CSI+DisableMouseExtendedModeSeq) } // EnableMousePixelsMotion enables Pixel Motion Mouse mode (SGR-Pixels). This // should be enabled in conjunction with EnableMouseCellMotion, and // EnableMouseAllMotion. func (o Output) EnableMousePixelsMode() { fmt.Fprint(o.tty, CSI+EnableMousePixelsModeSeq) } // DisableMousePixelsMotion disables Pixel Motion Mouse mode (SGR-Pixels). func (o Output) DisableMousePixelsMode() { fmt.Fprint(o.tty, CSI+DisableMousePixelsModeSeq) } // SetWindowTitle sets the terminal window title. func (o Output) SetWindowTitle(title string) { fmt.Fprintf(o.tty, OSC+SetWindowTitleSeq, title) } // EnableBracketedPaste enables bracketed paste. func (o Output) EnableBracketedPaste() { fmt.Fprintf(o.tty, CSI+EnableBracketedPasteSeq) } // DisableBracketedPaste disables bracketed paste. func (o Output) DisableBracketedPaste() { fmt.Fprintf(o.tty, CSI+DisableBracketedPasteSeq) } // Legacy functions. // Reset the terminal to its default style, removing any active styles. // // Deprecated: please use termenv.Output instead. func Reset() { output.Reset() } // SetForegroundColor sets the default foreground color. // // Deprecated: please use termenv.Output instead. func SetForegroundColor(color Color) { output.SetForegroundColor(color) } // SetBackgroundColor sets the default background color. // // Deprecated: please use termenv.Output instead. func SetBackgroundColor(color Color) { output.SetBackgroundColor(color) } // SetCursorColor sets the cursor color. // // Deprecated: please use termenv.Output instead. func SetCursorColor(color Color) { output.SetCursorColor(color) } // RestoreScreen restores a previously saved screen state. // // Deprecated: please use termenv.Output instead. func RestoreScreen() { output.RestoreScreen() } // SaveScreen saves the screen state. // // Deprecated: please use termenv.Output instead. func SaveScreen() { output.SaveScreen() } // AltScreen switches to the alternate screen buffer. The former view can be // restored with ExitAltScreen(). // // Deprecated: please use termenv.Output instead. func AltScreen() { output.AltScreen() } // ExitAltScreen exits the alternate screen buffer and returns to the former // terminal view. // // Deprecated: please use termenv.Output instead. func ExitAltScreen() { output.ExitAltScreen() } // ClearScreen clears the visible portion of the terminal. // // Deprecated: please use termenv.Output instead. func ClearScreen() { output.ClearScreen() } // MoveCursor moves the cursor to a given position. // // Deprecated: please use termenv.Output instead. func MoveCursor(row int, column int) { output.MoveCursor(row, column) } // HideCursor hides the cursor. // // Deprecated: please use termenv.Output instead. func HideCursor() { output.HideCursor() } // ShowCursor shows the cursor. // // Deprecated: please use termenv.Output instead. func ShowCursor() { output.ShowCursor() } // SaveCursorPosition saves the cursor position. // // Deprecated: please use termenv.Output instead. func SaveCursorPosition() { output.SaveCursorPosition() } // RestoreCursorPosition restores a saved cursor position. // // Deprecated: please use termenv.Output instead. func RestoreCursorPosition() { output.RestoreCursorPosition() } // CursorUp moves the cursor up a given number of lines. // // Deprecated: please use termenv.Output instead. func CursorUp(n int) { output.CursorUp(n) } // CursorDown moves the cursor down a given number of lines. // // Deprecated: please use termenv.Output instead. func CursorDown(n int) { output.CursorDown(n) } // CursorForward moves the cursor up a given number of lines. // // Deprecated: please use termenv.Output instead. func CursorForward(n int) { output.CursorForward(n) } // CursorBack moves the cursor backwards a given number of cells. // // Deprecated: please use termenv.Output instead. func CursorBack(n int) { output.CursorBack(n) } // CursorNextLine moves the cursor down a given number of lines and places it at // the beginning of the line. // // Deprecated: please use termenv.Output instead. func CursorNextLine(n int) { output.CursorNextLine(n) } // CursorPrevLine moves the cursor up a given number of lines and places it at // the beginning of the line. // // Deprecated: please use termenv.Output instead. func CursorPrevLine(n int) { output.CursorPrevLine(n) } // ClearLine clears the current line. // // Deprecated: please use termenv.Output instead. func ClearLine() { output.ClearLine() } // ClearLineLeft clears the line to the left of the cursor. // // Deprecated: please use termenv.Output instead. func ClearLineLeft() { output.ClearLineLeft() } // ClearLineRight clears the line to the right of the cursor. // // Deprecated: please use termenv.Output instead. func ClearLineRight() { output.ClearLineRight() } // ClearLines clears a given number of lines. // // Deprecated: please use termenv.Output instead. func ClearLines(n int) { output.ClearLines(n) } // ChangeScrollingRegion sets the scrolling region of the terminal. // // Deprecated: please use termenv.Output instead. func ChangeScrollingRegion(top, bottom int) { output.ChangeScrollingRegion(top, bottom) } // InsertLines inserts the given number of lines at the top of the scrollable // region, pushing lines below down. // // Deprecated: please use termenv.Output instead. func InsertLines(n int) { output.InsertLines(n) } // DeleteLines deletes the given number of lines, pulling any lines in // the scrollable region below up. // // Deprecated: please use termenv.Output instead. func DeleteLines(n int) { output.DeleteLines(n) } // EnableMousePress enables X10 mouse mode. Button press events are sent only. // // Deprecated: please use termenv.Output instead. func EnableMousePress() { output.EnableMousePress() } // DisableMousePress disables X10 mouse mode. // // Deprecated: please use termenv.Output instead. func DisableMousePress() { output.DisableMousePress() } // EnableMouse enables Mouse Tracking mode. // // Deprecated: please use termenv.Output instead. func EnableMouse() { output.EnableMouse() } // DisableMouse disables Mouse Tracking mode. // // Deprecated: please use termenv.Output instead. func DisableMouse() { output.DisableMouse() } // EnableMouseHilite enables Hilite Mouse Tracking mode. // // Deprecated: please use termenv.Output instead. func EnableMouseHilite() { output.EnableMouseHilite() } // DisableMouseHilite disables Hilite Mouse Tracking mode. // // Deprecated: please use termenv.Output instead. func DisableMouseHilite() { output.DisableMouseHilite() } // EnableMouseCellMotion enables Cell Motion Mouse Tracking mode. // // Deprecated: please use termenv.Output instead. func EnableMouseCellMotion() { output.EnableMouseCellMotion() } // DisableMouseCellMotion disables Cell Motion Mouse Tracking mode. // // Deprecated: please use termenv.Output instead. func DisableMouseCellMotion() { output.DisableMouseCellMotion() } // EnableMouseAllMotion enables All Motion Mouse mode. // // Deprecated: please use termenv.Output instead. func EnableMouseAllMotion() { output.EnableMouseAllMotion() } // DisableMouseAllMotion disables All Motion Mouse mode. // // Deprecated: please use termenv.Output instead. func DisableMouseAllMotion() { output.DisableMouseAllMotion() } // SetWindowTitle sets the terminal window title. // // Deprecated: please use termenv.Output instead. func SetWindowTitle(title string) { output.SetWindowTitle(title) } // EnableBracketedPaste enables bracketed paste. // // Deprecated: please use termenv.Output instead. func EnableBracketedPaste() { output.EnableBracketedPaste() } // DisableBracketedPaste disables bracketed paste. // // Deprecated: please use termenv.Output instead. func DisableBracketedPaste() { output.DisableBracketedPaste() } termenv-0.15.2/screen_test.go000066400000000000000000000142251444632052500161350ustar00rootroot00000000000000package termenv import ( "bytes" "io/ioutil" "os" "strings" "testing" ) type testEnv struct{} func (te testEnv) Environ() []string { return []string{"TERM=xterm-256color"} } func (te testEnv) Getenv(key string) string { if key == "TERM" { return "xterm-256color" } return "" } func tempOutput(t *testing.T) *Output { t.Helper() f, err := ioutil.TempFile("", "termenv") if err != nil { t.Fatal(err) } return NewOutput(f, WithEnvironment(testEnv{}), WithProfile(TrueColor)) } func verify(t *testing.T, o *Output, exp string) { t.Helper() tty := o.tty.(*os.File) if _, err := tty.Seek(0, 0); err != nil { t.Fatal(err) } b, err := ioutil.ReadAll(tty) if err != nil { t.Fatal(err) } if string(b) != exp { b = bytes.Replace(b, []byte("\x1b"), []byte("\\x1b"), -1) exp = strings.Replace(exp, "\x1b", "\\x1b", -1) t.Errorf("output does not match, expected %s, got %s", exp, string(b)) } // remove temp file os.Remove(tty.Name()) } func TestReset(t *testing.T) { o := tempOutput(t) o.Reset() verify(t, o, "\x1b[0m") } func TestSetForegroundColor(t *testing.T) { o := tempOutput(t) o.SetForegroundColor(ANSI.Color("0")) verify(t, o, "\x1b]10;#000000\a") } func TestSetBackgroundColor(t *testing.T) { o := tempOutput(t) o.SetBackgroundColor(ANSI.Color("0")) verify(t, o, "\x1b]11;#000000\a") } func TestSetCursorColor(t *testing.T) { o := tempOutput(t) o.SetCursorColor(ANSI.Color("0")) verify(t, o, "\x1b]12;#000000\a") } func TestRestoreScreen(t *testing.T) { o := tempOutput(t) o.RestoreScreen() verify(t, o, "\x1b[?47l") } func TestSaveScreen(t *testing.T) { o := tempOutput(t) o.SaveScreen() verify(t, o, "\x1b[?47h") } func TestAltScreen(t *testing.T) { o := tempOutput(t) o.AltScreen() verify(t, o, "\x1b[?1049h") } func TestExitAltScreen(t *testing.T) { o := tempOutput(t) o.ExitAltScreen() verify(t, o, "\x1b[?1049l") } func TestClearScreen(t *testing.T) { o := tempOutput(t) o.ClearScreen() verify(t, o, "\x1b[2J\x1b[1;1H") } func TestMoveCursor(t *testing.T) { o := tempOutput(t) o.MoveCursor(16, 8) verify(t, o, "\x1b[16;8H") } func TestHideCursor(t *testing.T) { o := tempOutput(t) o.HideCursor() verify(t, o, "\x1b[?25l") } func TestShowCursor(t *testing.T) { o := tempOutput(t) o.ShowCursor() verify(t, o, "\x1b[?25h") } func TestSaveCursorPosition(t *testing.T) { o := tempOutput(t) o.SaveCursorPosition() verify(t, o, "\x1b[s") } func TestRestoreCursorPosition(t *testing.T) { o := tempOutput(t) o.RestoreCursorPosition() verify(t, o, "\x1b[u") } func TestCursorUp(t *testing.T) { o := tempOutput(t) o.CursorUp(8) verify(t, o, "\x1b[8A") } func TestCursorDown(t *testing.T) { o := tempOutput(t) o.CursorDown(8) verify(t, o, "\x1b[8B") } func TestCursorForward(t *testing.T) { o := tempOutput(t) o.CursorForward(8) verify(t, o, "\x1b[8C") } func TestCursorBack(t *testing.T) { o := tempOutput(t) o.CursorBack(8) verify(t, o, "\x1b[8D") } func TestCursorNextLine(t *testing.T) { o := tempOutput(t) o.CursorNextLine(8) verify(t, o, "\x1b[8E") } func TestCursorPrevLine(t *testing.T) { o := tempOutput(t) o.CursorPrevLine(8) verify(t, o, "\x1b[8F") } func TestClearLine(t *testing.T) { o := tempOutput(t) o.ClearLine() verify(t, o, "\x1b[2K") } func TestClearLineLeft(t *testing.T) { o := tempOutput(t) o.ClearLineLeft() verify(t, o, "\x1b[1K") } func TestClearLineRight(t *testing.T) { o := tempOutput(t) o.ClearLineRight() verify(t, o, "\x1b[0K") } func TestClearLines(t *testing.T) { o := tempOutput(t) o.ClearLines(8) verify(t, o, "\x1b[2K\x1b[1A\x1b[2K\x1b[1A\x1b[2K\x1b[1A\x1b[2K\x1b[1A\x1b[2K\x1b[1A\x1b[2K\x1b[1A\x1b[2K\x1b[1A\x1b[2K\x1b[1A\x1b[2K") } func TestChangeScrollingRegion(t *testing.T) { o := tempOutput(t) o.ChangeScrollingRegion(16, 8) verify(t, o, "\x1b[16;8r") } func TestInsertLines(t *testing.T) { o := tempOutput(t) o.InsertLines(8) verify(t, o, "\x1b[8L") } func TestDeleteLines(t *testing.T) { o := tempOutput(t) o.DeleteLines(8) verify(t, o, "\x1b[8M") } func TestEnableMousePress(t *testing.T) { o := tempOutput(t) o.EnableMousePress() verify(t, o, "\x1b[?9h") } func TestDisableMousePress(t *testing.T) { o := tempOutput(t) o.DisableMousePress() verify(t, o, "\x1b[?9l") } func TestEnableMouse(t *testing.T) { o := tempOutput(t) o.EnableMouse() verify(t, o, "\x1b[?1000h") } func TestDisableMouse(t *testing.T) { o := tempOutput(t) o.DisableMouse() verify(t, o, "\x1b[?1000l") } func TestEnableMouseHilite(t *testing.T) { o := tempOutput(t) o.EnableMouseHilite() verify(t, o, "\x1b[?1001h") } func TestDisableMouseHilite(t *testing.T) { o := tempOutput(t) o.DisableMouseHilite() verify(t, o, "\x1b[?1001l") } func TestEnableMouseCellMotion(t *testing.T) { o := tempOutput(t) o.EnableMouseCellMotion() verify(t, o, "\x1b[?1002h") } func TestDisableMouseCellMotion(t *testing.T) { o := tempOutput(t) o.DisableMouseCellMotion() verify(t, o, "\x1b[?1002l") } func TestEnableMouseAllMotion(t *testing.T) { o := tempOutput(t) o.EnableMouseAllMotion() verify(t, o, "\x1b[?1003h") } func TestDisableMouseAllMotion(t *testing.T) { o := tempOutput(t) o.DisableMouseAllMotion() verify(t, o, "\x1b[?1003l") } func TestEnableMouseExtendedMode(t *testing.T) { o := tempOutput(t) o.EnableMouseExtendedMode() verify(t, o, "\x1b[?1006h") } func TestDisableMouseExtendedMode(t *testing.T) { o := tempOutput(t) o.DisableMouseExtendedMode() verify(t, o, "\x1b[?1006l") } func TestEnableMousePixelsMode(t *testing.T) { o := tempOutput(t) o.EnableMousePixelsMode() verify(t, o, "\x1b[?1016h") } func TestDisableMousePixelsMode(t *testing.T) { o := tempOutput(t) o.DisableMousePixelsMode() verify(t, o, "\x1b[?1016l") } func TestSetWindowTitle(t *testing.T) { o := tempOutput(t) o.SetWindowTitle("test") verify(t, o, "\x1b]2;test\a") } func TestCopyClipboard(t *testing.T) { o := tempOutput(t) o.Copy("hello") verify(t, o, "\x1b]52;c;aGVsbG8=\a") } func TestCopyPrimary(t *testing.T) { o := tempOutput(t) o.CopyPrimary("hello") verify(t, o, "\x1b]52;p;aGVsbG8=\a") } func TestHyperlink(t *testing.T) { o := tempOutput(t) o.WriteString(o.Hyperlink("http://example.com", "example")) verify(t, o, "\x1b]8;;http://example.com\x1b\\example\x1b]8;;\x1b\\") } termenv-0.15.2/style.go000066400000000000000000000045011444632052500147530ustar00rootroot00000000000000package termenv import ( "fmt" "strings" "github.com/mattn/go-runewidth" ) // Sequence definitions. const ( ResetSeq = "0" BoldSeq = "1" FaintSeq = "2" ItalicSeq = "3" UnderlineSeq = "4" BlinkSeq = "5" ReverseSeq = "7" CrossOutSeq = "9" OverlineSeq = "53" ) // Style is a string that various rendering styles can be applied to. type Style struct { profile Profile string styles []string } // String returns a new Style. func String(s ...string) Style { return Style{ profile: ANSI, string: strings.Join(s, " "), } } func (t Style) String() string { return t.Styled(t.string) } // Styled renders s with all applied styles. func (t Style) Styled(s string) string { if t.profile == Ascii { return s } if len(t.styles) == 0 { return s } seq := strings.Join(t.styles, ";") if seq == "" { return s } return fmt.Sprintf("%s%sm%s%sm", CSI, seq, s, CSI+ResetSeq) } // Foreground sets a foreground color. func (t Style) Foreground(c Color) Style { if c != nil { t.styles = append(t.styles, c.Sequence(false)) } return t } // Background sets a background color. func (t Style) Background(c Color) Style { if c != nil { t.styles = append(t.styles, c.Sequence(true)) } return t } // Bold enables bold rendering. func (t Style) Bold() Style { t.styles = append(t.styles, BoldSeq) return t } // Faint enables faint rendering. func (t Style) Faint() Style { t.styles = append(t.styles, FaintSeq) return t } // Italic enables italic rendering. func (t Style) Italic() Style { t.styles = append(t.styles, ItalicSeq) return t } // Underline enables underline rendering. func (t Style) Underline() Style { t.styles = append(t.styles, UnderlineSeq) return t } // Overline enables overline rendering. func (t Style) Overline() Style { t.styles = append(t.styles, OverlineSeq) return t } // Blink enables blink mode. func (t Style) Blink() Style { t.styles = append(t.styles, BlinkSeq) return t } // Reverse enables reverse color mode. func (t Style) Reverse() Style { t.styles = append(t.styles, ReverseSeq) return t } // CrossOut enables crossed-out rendering. func (t Style) CrossOut() Style { t.styles = append(t.styles, CrossOutSeq) return t } // Width returns the width required to print all runes in Style. func (t Style) Width() int { return runewidth.StringWidth(t.string) } termenv-0.15.2/style_test.go000066400000000000000000000010361444632052500160120ustar00rootroot00000000000000package termenv import ( "testing" ) func TestStyleWidth(t *testing.T) { s := String("Hello World") if s.Width() != 11 { t.Errorf("Expected width of 11, got %d", s.Width()) } s = s.Bold() if s.Width() != 11 { t.Errorf("Expected width of 11, got %d", s.Width()) } s = s.Italic() if s.Width() != 11 { t.Errorf("Expected width of 11, got %d", s.Width()) } s = s.Foreground(TrueColor.Color("#abcdef")) s = s.Background(TrueColor.Color("69")) if s.Width() != 11 { t.Errorf("Expected width of 11, got %d", s.Width()) } } termenv-0.15.2/templatehelper.go000066400000000000000000000042111444632052500166240ustar00rootroot00000000000000package termenv import ( "text/template" ) // TemplateFuncs returns template helpers for the given output. func (o Output) TemplateFuncs() template.FuncMap { return TemplateFuncs(o.Profile) } // TemplateFuncs contains a few useful template helpers. func TemplateFuncs(p Profile) template.FuncMap { if p == Ascii { return noopTemplateFuncs } return template.FuncMap{ "Color": func(values ...interface{}) string { s := p.String(values[len(values)-1].(string)) switch len(values) { case 2: s = s.Foreground(p.Color(values[0].(string))) case 3: s = s. Foreground(p.Color(values[0].(string))). Background(p.Color(values[1].(string))) } return s.String() }, "Foreground": func(values ...interface{}) string { s := p.String(values[len(values)-1].(string)) if len(values) == 2 { s = s.Foreground(p.Color(values[0].(string))) } return s.String() }, "Background": func(values ...interface{}) string { s := p.String(values[len(values)-1].(string)) if len(values) == 2 { s = s.Background(p.Color(values[0].(string))) } return s.String() }, "Bold": styleFunc(p, Style.Bold), "Faint": styleFunc(p, Style.Faint), "Italic": styleFunc(p, Style.Italic), "Underline": styleFunc(p, Style.Underline), "Overline": styleFunc(p, Style.Overline), "Blink": styleFunc(p, Style.Blink), "Reverse": styleFunc(p, Style.Reverse), "CrossOut": styleFunc(p, Style.CrossOut), } } func styleFunc(p Profile, f func(Style) Style) func(...interface{}) string { return func(values ...interface{}) string { s := p.String(values[0].(string)) return f(s).String() } } var noopTemplateFuncs = template.FuncMap{ "Color": noColorFunc, "Foreground": noColorFunc, "Background": noColorFunc, "Bold": noStyleFunc, "Faint": noStyleFunc, "Italic": noStyleFunc, "Underline": noStyleFunc, "Overline": noStyleFunc, "Blink": noStyleFunc, "Reverse": noStyleFunc, "CrossOut": noStyleFunc, } func noColorFunc(values ...interface{}) string { return values[len(values)-1].(string) } func noStyleFunc(values ...interface{}) string { return values[0].(string) } termenv-0.15.2/templatehelper_test.go000066400000000000000000000022271444632052500176700ustar00rootroot00000000000000package termenv import ( "bytes" "fmt" "io/ioutil" "testing" "text/template" ) func TestTemplateFuncs(t *testing.T) { tests := []struct { name string profile Profile }{ {"ascii", Ascii}, {"ansi", ANSI}, {"ansi256", ANSI256}, {"truecolor", TrueColor}, } const templateFile = "./testdata/templatehelper.tpl" for _, test := range tests { t.Run(test.name, func(t *testing.T) { tpl, err := template.New("templatehelper.tpl").Funcs(TemplateFuncs(test.profile)).ParseFiles(templateFile) if err != nil { t.Fatalf("unexpected error parsing template: %v", err) } var buf bytes.Buffer if err = tpl.Execute(&buf, nil); err != nil { t.Fatalf("unexpected error executing template: %v", err) } actual := buf.Bytes() filename := fmt.Sprintf("./testdata/templatehelper_%s.txt", test.name) expected, err := ioutil.ReadFile(filename) if err != nil { t.Fatalf("unexpected error reading golden file %q: %v", filename, err) } if !bytes.Equal(buf.Bytes(), expected) { t.Fatalf("template output does not match golden file.\n--- Expected ---\n%s\n--- Actual ---\n%s\n", string(expected), string(actual)) } }) } } termenv-0.15.2/termenv.go000066400000000000000000000066761444632052500153120ustar00rootroot00000000000000package termenv import ( "errors" "github.com/mattn/go-isatty" ) var ( // ErrStatusReport gets returned when the terminal can't be queried. ErrStatusReport = errors.New("unable to retrieve status report") ) const ( // Escape character ESC = '\x1b' // Bell BEL = '\a' // Control Sequence Introducer CSI = string(ESC) + "[" // Operating System Command OSC = string(ESC) + "]" // String Terminator ST = string(ESC) + `\` ) func (o *Output) isTTY() bool { if o.assumeTTY || o.unsafe { return true } if len(o.environ.Getenv("CI")) > 0 { return false } if o.TTY() == nil { return false } return isatty.IsTerminal(o.TTY().Fd()) } // ColorProfile returns the supported color profile: // Ascii, ANSI, ANSI256, or TrueColor. func ColorProfile() Profile { return output.ColorProfile() } // ForegroundColor returns the terminal's default foreground color. func ForegroundColor() Color { return output.ForegroundColor() } // BackgroundColor returns the terminal's default background color. func BackgroundColor() Color { return output.BackgroundColor() } // HasDarkBackground returns whether terminal uses a dark-ish background. func HasDarkBackground() bool { return output.HasDarkBackground() } // EnvNoColor returns true if the environment variables explicitly disable color output // by setting NO_COLOR (https://no-color.org/) // or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/) // If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE // If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset. func (o *Output) EnvNoColor() bool { return o.environ.Getenv("NO_COLOR") != "" || (o.environ.Getenv("CLICOLOR") == "0" && !o.cliColorForced()) } // EnvNoColor returns true if the environment variables explicitly disable color output // by setting NO_COLOR (https://no-color.org/) // or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/) // If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE // If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset. func EnvNoColor() bool { return output.EnvNoColor() } // EnvColorProfile returns the color profile based on environment variables set // Supports NO_COLOR (https://no-color.org/) // and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/) // If none of these environment variables are set, this behaves the same as ColorProfile() // It will return the Ascii color profile if EnvNoColor() returns true // If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0" // then the ANSI color profile will be returned. func EnvColorProfile() Profile { return output.EnvColorProfile() } // EnvColorProfile returns the color profile based on environment variables set // Supports NO_COLOR (https://no-color.org/) // and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/) // If none of these environment variables are set, this behaves the same as ColorProfile() // It will return the Ascii color profile if EnvNoColor() returns true // If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0" // then the ANSI color profile will be returned. func (o *Output) EnvColorProfile() Profile { if o.EnvNoColor() { return Ascii } p := o.ColorProfile() if o.cliColorForced() && p == Ascii { return ANSI } return p } func (o *Output) cliColorForced() bool { if forced := o.environ.Getenv("CLICOLOR_FORCE"); forced != "" { return forced != "0" } return false } termenv-0.15.2/termenv_other.go000066400000000000000000000014021444632052500164710ustar00rootroot00000000000000//go:build js || plan9 || aix // +build js plan9 aix package termenv import "io" // ColorProfile returns the supported color profile: // ANSI256 func (o Output) ColorProfile() Profile { return ANSI256 } func (o Output) foregroundColor() Color { // default gray return ANSIColor(7) } func (o Output) backgroundColor() Color { // default black return ANSIColor(0) } // EnableVirtualTerminalProcessing enables virtual terminal processing on // Windows for w and returns a function that restores w to its previous state. // On non-Windows platforms, or if w does not refer to a terminal, then it // returns a non-nil no-op function and no error. func EnableVirtualTerminalProcessing(w io.Writer) (func() error, error) { return func() error { return nil }, nil } termenv-0.15.2/termenv_posix.go000066400000000000000000000005201444632052500165120ustar00rootroot00000000000000//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd // +build darwin dragonfly freebsd linux netbsd openbsd package termenv import ( "golang.org/x/sys/unix" ) func isForeground(fd int) bool { pgrp, err := unix.IoctlGetInt(fd, unix.TIOCGPGRP) if err != nil { return false } return pgrp == unix.Getpgrp() } termenv-0.15.2/termenv_solaris.go000066400000000000000000000004711444632052500170310ustar00rootroot00000000000000//go:build solaris || illumos // +build solaris illumos package termenv import ( "golang.org/x/sys/unix" ) func isForeground(fd int) bool { pgrp, err := unix.IoctlGetInt(fd, unix.TIOCGPGRP) if err != nil { return false } g, err := unix.Getpgrp() if err != nil { return false } return pgrp == g } termenv-0.15.2/termenv_test.go000066400000000000000000000237221444632052500163400ustar00rootroot00000000000000package termenv import ( "bytes" "fmt" "image/color" "io/ioutil" "os" "strings" "testing" "text/template" ) func TestLegacyTermEnv(t *testing.T) { p := ColorProfile() if p != TrueColor && p != Ascii { t.Errorf("Expected %d, got %d", TrueColor, p) } fg := ForegroundColor() fgseq := fg.Sequence(false) fgexp := "97" if fgseq != fgexp && fgseq != "" { t.Errorf("Expected %s, got %s", fgexp, fgseq) } bg := BackgroundColor() bgseq := bg.Sequence(true) bgexp := "48;2;0;0;0" if bgseq != bgexp && bgseq != "" { t.Errorf("Expected %s, got %s", bgexp, bgseq) } _ = HasDarkBackground() } func TestTermEnv(t *testing.T) { o := NewOutput(os.Stdout) if o.Profile != TrueColor && o.Profile != Ascii { t.Errorf("Expected %d, got %d", TrueColor, o.Profile) } fg := o.ForegroundColor() fgseq := fg.Sequence(false) fgexp := "97" if fgseq != fgexp && fgseq != "" { t.Errorf("Expected %s, got %s", fgexp, fgseq) } bg := o.BackgroundColor() bgseq := bg.Sequence(true) bgexp := "48;2;0;0;0" if bgseq != bgexp && bgseq != "" { t.Errorf("Expected %s, got %s", bgexp, bgseq) } _ = HasDarkBackground() } func TestRendering(t *testing.T) { out := String("foobar") if out.String() != "foobar" { t.Errorf("Unstyled strings should be returned as plain text") } out = out.Foreground(TrueColor.Color("#abcdef")) out = out.Background(TrueColor.Color("69")) out = out.Bold() out = out.Italic() out = out.Faint() out = out.Underline() out = out.Blink() exp := "\x1b[38;2;171;205;239;48;5;69;1;3;2;4;5mfoobar\x1b[0m" if out.String() != exp { t.Errorf("Expected %s, got %s", exp, out.String()) } exp = "foobar" mono := String(exp) mono = mono.Foreground(Ascii.Color("#abcdef")) if mono.String() != exp { t.Errorf("Ascii profile should not apply color styles") } } func TestColorConversion(t *testing.T) { // ANSI color a := ANSI.Color("7") c := ConvertToRGB(a) exp := "#c0c0c0" if c.Hex() != exp { t.Errorf("Expected %s, got %s", exp, c.Hex()) } // ANSI-256 color a256 := ANSI256.Color("91") c = ConvertToRGB(a256) exp = "#8700af" if c.Hex() != exp { t.Errorf("Expected %s, got %s", exp, c.Hex()) } // hex color hex := "#abcdef" argb := TrueColor.Color(hex) c = ConvertToRGB(argb) if c.Hex() != hex { t.Errorf("Expected %s, got %s", exp, c.Hex()) } } func TestFromColor(t *testing.T) { // color.Color interface c := TrueColor.FromColor(color.RGBA{255, 128, 0, 255}) exp := "38;2;255;128;0" if c.Sequence(false) != exp { t.Errorf("Expected %s, got %s", exp, c.Sequence(false)) } } func TestAscii(t *testing.T) { c := Ascii.Color("#abcdef") if c.Sequence(false) != "" { t.Errorf("Expected empty sequence, got %s", c.Sequence(false)) } } func TestANSIProfile(t *testing.T) { p := ANSI c := p.Color("#e88388") exp := "91" if c.Sequence(false) != exp { t.Errorf("Expected %s, got %s", exp, c.Sequence(false)) } if _, ok := c.(ANSIColor); !ok { t.Errorf("Expected type termenv.ANSIColor, got %T", c) } c = p.Color("82") exp = "92" if c.Sequence(false) != exp { t.Errorf("Expected %s, got %s", exp, c.Sequence(false)) } if _, ok := c.(ANSIColor); !ok { t.Errorf("Expected type termenv.ANSIColor, got %T", c) } c = p.Color("2") exp = "32" if c.Sequence(false) != exp { t.Errorf("Expected %s, got %s", exp, c.Sequence(false)) } if _, ok := c.(ANSIColor); !ok { t.Errorf("Expected type termenv.ANSIColor, got %T", c) } } func TestANSI256Profile(t *testing.T) { p := ANSI256 c := p.Color("#abcdef") exp := "38;5;153" if c.Sequence(false) != exp { t.Errorf("Expected %s, got %s", exp, c.Sequence(false)) } if _, ok := c.(ANSI256Color); !ok { t.Errorf("Expected type termenv.ANSI256Color, got %T", c) } c = p.Color("139") exp = "38;5;139" if c.Sequence(false) != exp { t.Errorf("Expected %s, got %s", exp, c.Sequence(false)) } if _, ok := c.(ANSI256Color); !ok { t.Errorf("Expected type termenv.ANSI256Color, got %T", c) } c = p.Color("2") exp = "32" if c.Sequence(false) != exp { t.Errorf("Expected %s, got %s", exp, c.Sequence(false)) } if _, ok := c.(ANSIColor); !ok { t.Errorf("Expected type termenv.ANSIColor, got %T", c) } } func TestTrueColorProfile(t *testing.T) { p := TrueColor c := p.Color("#abcdef") exp := "38;2;171;205;239" if c.Sequence(false) != exp { t.Errorf("Expected %s, got %s", exp, c.Sequence(false)) } if _, ok := c.(RGBColor); !ok { t.Errorf("Expected type termenv.HexColor, got %T", c) } c = p.Color("139") exp = "38;5;139" if c.Sequence(false) != exp { t.Errorf("Expected %s, got %s", exp, c.Sequence(false)) } if _, ok := c.(ANSI256Color); !ok { t.Errorf("Expected type termenv.ANSI256Color, got %T", c) } c = p.Color("2") exp = "32" if c.Sequence(false) != exp { t.Errorf("Expected %s, got %s", exp, c.Sequence(false)) } if _, ok := c.(ANSIColor); !ok { t.Errorf("Expected type termenv.ANSIColor, got %T", c) } } func TestStyles(t *testing.T) { s := String("foobar").Foreground(TrueColor.Color("2")) exp := "\x1b[32mfoobar\x1b[0m" if s.String() != exp { t.Errorf("Expected %s, got %s", exp, s.String()) } } func TestTemplateHelpers(t *testing.T) { p := TrueColor exp := String("Hello World") basetpl := `{{ %s "Hello World" }}` wraptpl := `{{ %s (%s "Hello World") }}` tt := []struct { Template string Expected string }{ { Template: fmt.Sprintf(basetpl, "Bold"), Expected: exp.Bold().String(), }, { Template: fmt.Sprintf(basetpl, "Faint"), Expected: exp.Faint().String(), }, { Template: fmt.Sprintf(basetpl, "Italic"), Expected: exp.Italic().String(), }, { Template: fmt.Sprintf(basetpl, "Underline"), Expected: exp.Underline().String(), }, { Template: fmt.Sprintf(basetpl, "Overline"), Expected: exp.Overline().String(), }, { Template: fmt.Sprintf(basetpl, "Blink"), Expected: exp.Blink().String(), }, { Template: fmt.Sprintf(basetpl, "Reverse"), Expected: exp.Reverse().String(), }, { Template: fmt.Sprintf(basetpl, "CrossOut"), Expected: exp.CrossOut().String(), }, { Template: fmt.Sprintf(wraptpl, "Underline", "Bold"), Expected: String(exp.Bold().String()).Underline().String(), }, { Template: `{{ Color "#ff0000" "foobar" }}`, Expected: String("foobar").Foreground(p.Color("#ff0000")).String(), }, { Template: `{{ Color "#ff0000" "#0000ff" "foobar" }}`, Expected: String("foobar"). Foreground(p.Color("#ff0000")). Background(p.Color("#0000ff")). String(), }, { Template: `{{ Foreground "#ff0000" "foobar" }}`, Expected: String("foobar").Foreground(p.Color("#ff0000")).String(), }, { Template: `{{ Background "#ff0000" "foobar" }}`, Expected: String("foobar").Background(p.Color("#ff0000")).String(), }, } for i, v := range tt { tpl, err := template.New(fmt.Sprintf("test_%d", i)).Funcs(TemplateFuncs(p)).Parse(v.Template) if err != nil { t.Error(err) } var buf bytes.Buffer err = tpl.Execute(&buf, nil) if err != nil { t.Error(err) } if buf.String() != v.Expected { v1 := strings.Replace(v.Expected, "\x1b", "", -1) v2 := strings.Replace(buf.String(), "\x1b", "", -1) t.Errorf("Expected %s, got %s", v1, v2) } } } func TestEnvNoColor(t *testing.T) { tests := []struct { name string environ []string expected bool }{ {"no env", nil, false}, {"no_color", []string{"NO_COLOR", "Y"}, true}, {"no_color+clicolor=1", []string{"NO_COLOR", "Y", "CLICOLOR", "1"}, true}, {"no_color+clicolor_force=1", []string{"NO_COLOR", "Y", "CLICOLOR_FORCE", "1"}, true}, {"clicolor=0", []string{"CLICOLOR", "0"}, true}, {"clicolor=1", []string{"CLICOLOR", "1"}, false}, {"clicolor_force=1", []string{"CLICOLOR_FORCE", "0"}, false}, {"clicolor_force=0", []string{"CLICOLOR_FORCE", "1"}, false}, {"clicolor=0+clicolor_force=1", []string{"CLICOLOR", "0", "CLICOLOR_FORCE", "1"}, false}, {"clicolor=1+clicolor_force=1", []string{"CLICOLOR", "1", "CLICOLOR_FORCE", "1"}, false}, {"clicolor=0+clicolor_force=0", []string{"CLICOLOR", "0", "CLICOLOR_FORCE", "0"}, true}, {"clicolor=1+clicolor_force=0", []string{"CLICOLOR", "1", "CLICOLOR_FORCE", "0"}, false}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { defer func() { os.Unsetenv("NO_COLOR") os.Unsetenv("CLICOLOR") os.Unsetenv("CLICOLOR_FORCE") }() for i := 0; i < len(test.environ); i += 2 { os.Setenv(test.environ[i], test.environ[i+1]) } out := NewOutput(os.Stdout) actual := out.EnvNoColor() if test.expected != actual { t.Errorf("expected %t but was %t", test.expected, actual) } }) } } func TestPseudoTerm(t *testing.T) { buf := &bytes.Buffer{} o := NewOutput(buf) if o.Profile != Ascii { t.Errorf("Expected %d, got %d", Ascii, o.Profile) } fg := o.ForegroundColor() fgseq := fg.Sequence(false) if fgseq != "" { t.Errorf("Expected empty response, got %s", fgseq) } bg := o.BackgroundColor() bgseq := bg.Sequence(true) if bgseq != "" { t.Errorf("Expected empty response, got %s", bgseq) } exp := "foobar" out := o.String(exp) out = out.Foreground(o.Color("#abcdef")) o.Write([]byte(out.String())) if buf.String() != exp { t.Errorf("Expected %s, got %s", exp, buf.String()) } } func TestCache(t *testing.T) { o := NewOutput(os.Stdout, WithColorCache(true), WithProfile(TrueColor)) if o.cache != true { t.Errorf("Expected cache to be active, got %t", o.cache) } } func TestEnableVirtualTerminalProcessing(t *testing.T) { // EnableVirtualTerminalProcessing should always return a non-nil // restoreFunc, and in tests it should never return an error. restoreFunc, err := EnableVirtualTerminalProcessing(NewOutput(os.Stdout)) if restoreFunc == nil || err != nil { t.Fatalf("expected non-, , got %p, %v", restoreFunc, err) } // In tests, restoreFunc should never return an error. if err := restoreFunc(); err != nil { t.Fatalf("expected , got %v", err) } } func TestWithTTY(t *testing.T) { for _, v := range []bool{true, false} { o := NewOutput(ioutil.Discard, WithTTY(v)) if o.isTTY() != v { t.Fatalf("expected WithTTY(%t) to set isTTY to %t", v, v) } } } termenv-0.15.2/termenv_unix.go000066400000000000000000000140321444632052500163360ustar00rootroot00000000000000//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris // +build darwin dragonfly freebsd linux netbsd openbsd solaris package termenv import ( "fmt" "io" "strconv" "strings" "time" "golang.org/x/sys/unix" ) const ( // timeout for OSC queries OSCTimeout = 5 * time.Second ) // ColorProfile returns the supported color profile: // Ascii, ANSI, ANSI256, or TrueColor. func (o *Output) ColorProfile() Profile { if !o.isTTY() { return Ascii } if o.environ.Getenv("GOOGLE_CLOUD_SHELL") == "true" { return TrueColor } term := o.environ.Getenv("TERM") colorTerm := o.environ.Getenv("COLORTERM") switch strings.ToLower(colorTerm) { case "24bit": fallthrough case "truecolor": if strings.HasPrefix(term, "screen") { // tmux supports TrueColor, screen only ANSI256 if o.environ.Getenv("TERM_PROGRAM") != "tmux" { return ANSI256 } } return TrueColor case "yes": fallthrough case "true": return ANSI256 } switch term { case "xterm-kitty", "wezterm": return TrueColor case "linux": return ANSI } if strings.Contains(term, "256color") { return ANSI256 } if strings.Contains(term, "color") { return ANSI } if strings.Contains(term, "ansi") { return ANSI } return Ascii } func (o Output) foregroundColor() Color { s, err := o.termStatusReport(10) if err == nil { c, err := xTermColor(s) if err == nil { return c } } colorFGBG := o.environ.Getenv("COLORFGBG") if strings.Contains(colorFGBG, ";") { c := strings.Split(colorFGBG, ";") i, err := strconv.Atoi(c[0]) if err == nil { return ANSIColor(i) } } // default gray return ANSIColor(7) } func (o Output) backgroundColor() Color { s, err := o.termStatusReport(11) if err == nil { c, err := xTermColor(s) if err == nil { return c } } colorFGBG := o.environ.Getenv("COLORFGBG") if strings.Contains(colorFGBG, ";") { c := strings.Split(colorFGBG, ";") i, err := strconv.Atoi(c[len(c)-1]) if err == nil { return ANSIColor(i) } } // default black return ANSIColor(0) } func (o *Output) waitForData(timeout time.Duration) error { fd := o.TTY().Fd() tv := unix.NsecToTimeval(int64(timeout)) var readfds unix.FdSet readfds.Set(int(fd)) for { n, err := unix.Select(int(fd)+1, &readfds, nil, nil, &tv) if err == unix.EINTR { continue } if err != nil { return err } if n == 0 { return fmt.Errorf("timeout") } break } return nil } func (o *Output) readNextByte() (byte, error) { if !o.unsafe { if err := o.waitForData(OSCTimeout); err != nil { return 0, err } } var b [1]byte n, err := o.TTY().Read(b[:]) if err != nil { return 0, err } if n == 0 { panic("read returned no data") } return b[0], nil } // readNextResponse reads either an OSC response or a cursor position response: // - OSC response: "\x1b]11;rgb:1111/1111/1111\x1b\\" // - cursor position response: "\x1b[42;1R" func (o *Output) readNextResponse() (response string, isOSC bool, err error) { start, err := o.readNextByte() if err != nil { return "", false, err } // first byte must be ESC for start != ESC { start, err = o.readNextByte() if err != nil { return "", false, err } } response += string(start) // next byte is either '[' (cursor position response) or ']' (OSC response) tpe, err := o.readNextByte() if err != nil { return "", false, err } response += string(tpe) var oscResponse bool switch tpe { case '[': oscResponse = false case ']': oscResponse = true default: return "", false, ErrStatusReport } for { b, err := o.readNextByte() if err != nil { return "", false, err } response += string(b) if oscResponse { // OSC can be terminated by BEL (\a) or ST (ESC) if b == BEL || strings.HasSuffix(response, string(ESC)) { return response, true, nil } } else { // cursor position response is terminated by 'R' if b == 'R' { return response, false, nil } } // both responses have less than 25 bytes, so if we read more, that's an error if len(response) > 25 { break } } return "", false, ErrStatusReport } func (o Output) termStatusReport(sequence int) (string, error) { // screen/tmux can't support OSC, because they can be connected to multiple // terminals concurrently. term := o.environ.Getenv("TERM") if strings.HasPrefix(term, "screen") || strings.HasPrefix(term, "tmux") { return "", ErrStatusReport } tty := o.TTY() if tty == nil { return "", ErrStatusReport } if !o.unsafe { fd := int(tty.Fd()) // if in background, we can't control the terminal if !isForeground(fd) { return "", ErrStatusReport } t, err := unix.IoctlGetTermios(fd, tcgetattr) if err != nil { return "", fmt.Errorf("%s: %s", ErrStatusReport, err) } defer unix.IoctlSetTermios(fd, tcsetattr, t) //nolint:errcheck noecho := *t noecho.Lflag = noecho.Lflag &^ unix.ECHO noecho.Lflag = noecho.Lflag &^ unix.ICANON if err := unix.IoctlSetTermios(fd, tcsetattr, &noecho); err != nil { return "", fmt.Errorf("%s: %s", ErrStatusReport, err) } } // first, send OSC query, which is ignored by terminal which do not support it fmt.Fprintf(tty, OSC+"%d;?"+ST, sequence) // then, query cursor position, should be supported by all terminals fmt.Fprintf(tty, CSI+"6n") // read the next response res, isOSC, err := o.readNextResponse() if err != nil { return "", fmt.Errorf("%s: %s", ErrStatusReport, err) } // if this is not OSC response, then the terminal does not support it if !isOSC { return "", ErrStatusReport } // read the cursor query response next and discard the result _, _, err = o.readNextResponse() if err != nil { return "", err } // fmt.Println("Rcvd", res[1:]) return res, nil } // EnableVirtualTerminalProcessing enables virtual terminal processing on // Windows for w and returns a function that restores w to its previous state. // On non-Windows platforms, or if w does not refer to a terminal, then it // returns a non-nil no-op function and no error. func EnableVirtualTerminalProcessing(_ io.Writer) (func() error, error) { return func() error { return nil }, nil } termenv-0.15.2/termenv_windows.go000066400000000000000000000073531444632052500170550ustar00rootroot00000000000000//go:build windows // +build windows package termenv import ( "fmt" "strconv" "golang.org/x/sys/windows" ) func (o *Output) ColorProfile() Profile { if !o.isTTY() { return Ascii } if o.environ.Getenv("ConEmuANSI") == "ON" { return TrueColor } winVersion, _, buildNumber := windows.RtlGetNtVersionNumbers() if buildNumber < 10586 || winVersion < 10 { // No ANSI support before Windows 10 build 10586. if o.environ.Getenv("ANSICON") != "" { conVersion := o.environ.Getenv("ANSICON_VER") cv, err := strconv.ParseInt(conVersion, 10, 64) if err != nil || cv < 181 { // No 8 bit color support before v1.81 release. return ANSI } return ANSI256 } return Ascii } if buildNumber < 14931 { // No true color support before build 14931. return ANSI256 } return TrueColor } func (o Output) foregroundColor() Color { // default gray return ANSIColor(7) } func (o Output) backgroundColor() Color { // default black return ANSIColor(0) } // EnableWindowsANSIConsole enables virtual terminal processing on Windows // platforms. This allows the use of ANSI escape sequences in Windows console // applications. Ensure this gets called before anything gets rendered with // termenv. // // Returns the original console mode and an error if one occurred. func EnableWindowsANSIConsole() (uint32, error) { handle, err := windows.GetStdHandle(windows.STD_OUTPUT_HANDLE) if err != nil { return 0, err } var mode uint32 err = windows.GetConsoleMode(handle, &mode) if err != nil { return 0, err } // See https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences if mode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING { vtpmode := mode | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING if err := windows.SetConsoleMode(handle, vtpmode); err != nil { return 0, err } } return mode, nil } // RestoreWindowsConsole restores the console mode to a previous state. func RestoreWindowsConsole(mode uint32) error { handle, err := windows.GetStdHandle(windows.STD_OUTPUT_HANDLE) if err != nil { return err } return windows.SetConsoleMode(handle, mode) } // EnableVirtualTerminalProcessing enables virtual terminal processing on // Windows for o and returns a function that restores o to its previous state. // On non-Windows platforms, or if o does not refer to a terminal, then it // returns a non-nil no-op function and no error. func EnableVirtualTerminalProcessing(o *Output) (restoreFunc func() error, err error) { // There is nothing to restore until we set the console mode. restoreFunc = func() error { return nil } // If o is not a tty, then there is nothing to do. tty := o.TTY() if tty == nil { return } // Get the current console mode. If there is an error, assume that o is not // a terminal, discard the error, and return. var mode uint32 if err2 := windows.GetConsoleMode(windows.Handle(tty.Fd()), &mode); err2 != nil { return } // If virtual terminal processing is already set, then there is nothing to // do and nothing to restore. if mode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING == windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING { return } // Enable virtual terminal processing. See // https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences if err2 := windows.SetConsoleMode(windows.Handle(tty.Fd()), mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err2 != nil { err = fmt.Errorf("windows.SetConsoleMode: %w", err2) return } // Set the restore function. We maintain a reference to the tty in the // closure (rather than just its handle) to ensure that the tty is not // closed by a finalizer. restoreFunc = func() error { return windows.SetConsoleMode(windows.Handle(tty.Fd()), mode) } return } termenv-0.15.2/testdata/000077500000000000000000000000001444632052500150755ustar00rootroot00000000000000termenv-0.15.2/testdata/templatehelper.tpl000066400000000000000000000006311444632052500206310ustar00rootroot00000000000000Plain {{ Color "#ff0000" "Red" }} {{ Color "#ff0000" "#00ff00" "Red on Blue" }} {{ Foreground "#00ffff" "Cyan" }} {{ Background "#ff00ff" "Magenta Bg" }} {{ Foreground "#00ffff" (Background "#ff00ff" "Cyan on Magenta Bg") }} {{ Bold "Bold" }} {{ Faint "Faint" }} {{ Italic "Italic" }} {{ Underline "Underline" }} {{ Overline "Overline" }} {{ Blink "Blink" }} {{ Reverse "Reverse" }} {{ CrossOut "CrossOut" }}termenv-0.15.2/testdata/templatehelper_ansi.txt000066400000000000000000000003611444632052500216630ustar00rootroot00000000000000Plain Red Red on Blue Cyan Magenta Bg Cyan on Magenta Bg Bold Faint Italic Underline Overline Blink Reverse CrossOuttermenv-0.15.2/testdata/templatehelper_ansi256.txt000066400000000000000000000004251444632052500221210ustar00rootroot00000000000000Plain Red Red on Blue Cyan Magenta Bg Cyan on Magenta Bg Bold Faint Italic Underline Overline Blink Reverse CrossOuttermenv-0.15.2/testdata/templatehelper_ascii.txt000066400000000000000000000001641444632052500220220ustar00rootroot00000000000000Plain Red Red on Blue Cyan Magenta Bg Cyan on Magenta Bg Bold Faint Italic Underline Overline Blink Reverse CrossOuttermenv-0.15.2/testdata/templatehelper_truecolor.txt000066400000000000000000000004741444632052500227540ustar00rootroot00000000000000Plain Red Red on Blue Cyan Magenta Bg Cyan on Magenta Bg Bold Faint Italic Underline Overline Blink Reverse CrossOut