pax_global_header00006660000000000000000000000064143772244210014520gustar00rootroot0000000000000052 comment=83f990ba57917c978a5f714abfbf20fa40011d9e go-pretty-6.4.6/000077500000000000000000000000001437722442100134675ustar00rootroot00000000000000go-pretty-6.4.6/.github/000077500000000000000000000000001437722442100150275ustar00rootroot00000000000000go-pretty-6.4.6/.github/ISSUE_TEMPLATE/000077500000000000000000000000001437722442100172125ustar00rootroot00000000000000go-pretty-6.4.6/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000010611437722442100217020ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us improve --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior. Code samples if possible. **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Software (please complete the following information):** - OS: [e.g. OSX] - GoLang Version [e.g. 1.10] **Additional context** Add any other context about the problem here. go-pretty-6.4.6/.github/ISSUE_TEMPLATE/feature_request.md000066400000000000000000000010601437722442100227340ustar00rootroot00000000000000--- name: Feature request about: Suggest an idea for this project --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. go-pretty-6.4.6/.github/PULL_REQUEST_TEMPLATE.md000066400000000000000000000001151437722442100206250ustar00rootroot00000000000000## Proposed Changes - - - Fixes #. go-pretty-6.4.6/.github/workflows/000077500000000000000000000000001437722442100170645ustar00rootroot00000000000000go-pretty-6.4.6/.github/workflows/ci.yml000066400000000000000000000024601437722442100202040ustar00rootroot00000000000000name: CI on: # Pushes and pulls to all branches push: pull_request: # Run on the first day of every month schedule: - cron: "0 0 1 * *" # Allows you to run this workflow manually from the Actions tab workflow_dispatch: jobs: # Build and test everything build: runs-on: ubuntu-latest steps: # Checkout the code - name: Checkout Code uses: actions/checkout@v2 # Set up the GoLang enviroment - name: Set up Go uses: actions/setup-go@v2 with: go-version: 1.16 # Download all the tools used in the steps that follow - name: Set up Tools run: | go get -u github.com/fzipp/gocyclo/cmd/gocyclo go get -u github.com/mattn/goveralls # Run all the unit-tests - name: Test run: | make test # Run some tests to ensure no race conditions exist - name: Test for Race Conditions run: make test-race # Run the benchmarks to manually ensure no performance degradation - name: Benchmark run: make bench # Upload all the unit-test coverage reports to Coveralls - name: Upload Coverage Report env: COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: goveralls -service=github -coverprofile=.coverprofile go-pretty-6.4.6/.gitignore000066400000000000000000000000551437722442100154570ustar00rootroot00000000000000/.idea/ /demo* /profile/ .coverprofile *.swp go-pretty-6.4.6/CODE_OF_CONDUCT.md000066400000000000000000000062201437722442100162660ustar00rootroot00000000000000# Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at jedib0t@outlook.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ go-pretty-6.4.6/LICENSE000066400000000000000000000020501437722442100144710ustar00rootroot00000000000000MIT License Copyright (c) 2018 jedib0t 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. go-pretty-6.4.6/Makefile000066400000000000000000000010711437722442100151260ustar00rootroot00000000000000.PHONY: all profile test default: test all: test bench tools: go install github.com/fzipp/gocyclo/cmd/gocyclo@v0.5.1 bench: go test -bench=. -benchmem cyclo: gocyclo -over 13 ./*/*.go demo-list: go run cmd/demo-list/demo.go demo-progress: go run cmd/demo-progress/demo.go demo-table: go run cmd/demo-table/demo.go fmt: go fmt $(shell go list ./...) profile: sh profile.sh test: fmt vet cyclo go test -cover -coverprofile=.coverprofile $(shell go list ./...) test-race: go run -race ./cmd/demo-progress/demo.go vet: go vet $(shell go list ./...) go-pretty-6.4.6/README.md000066400000000000000000000110721437722442100147470ustar00rootroot00000000000000# go-pretty [![Go Reference](https://pkg.go.dev/badge/github.com/jedib0t/go-pretty/v6.svg)](https://pkg.go.dev/github.com/jedib0t/go-pretty/v6) [![Build Status](https://github.com/jedib0t/go-pretty/workflows/CI/badge.svg?branch=main)](https://github.com/jedib0t/go-pretty/actions?query=workflow%3ACI+event%3Apush+branch%3Amain) [![Coverage Status](https://coveralls.io/repos/github/jedib0t/go-pretty/badge.svg?branch=main)](https://coveralls.io/github/jedib0t/go-pretty?branch=main) [![Go Report Card](https://goreportcard.com/badge/github.com/jedib0t/go-pretty/v6)](https://goreportcard.com/report/github.com/jedib0t/go-pretty/v6) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=jedib0t_go-pretty&metric=alert_status)](https://sonarcloud.io/dashboard?id=jedib0t_go-pretty) Utilities to prettify console output of tables, lists, progress-bars, text, etc. with a heavy emphasis on customization. ## Usage The current major version of this package is __v6__, and it follows the standard outlined [here](https://go.dev/doc/modules/version-numbers#major-version). Run `go get github.com/jedib0t/go-pretty/v6` to add this as a dependency to your project, and import the packages in your code using one or more of these: * `github.com/jedib0t/go-pretty/v6/list` * `github.com/jedib0t/go-pretty/v6/progress` * `github.com/jedib0t/go-pretty/v6/table` * `github.com/jedib0t/go-pretty/v6/text` ## Table Pretty-print tables in a terminal with colors, nested tables and more. ``` +-----+------------+-----------+--------+-----------------------------+ | # | FIRST NAME | LAST NAME | SALARY | | +-----+------------+-----------+--------+-----------------------------+ | 1 | Arya | Stark | 3000 | | | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | | 300 | Tyrion | Lannister | 5000 | | +-----+------------+-----------+--------+-----------------------------+ | | | TOTAL | 10000 | | +-----+------------+-----------+--------+-----------------------------+ ``` Execute `go run github.com/jedib0t/go-pretty/v6/cmd/demo-table@latest colors` to get: Tables with Colors within a Table in a Terminal More details can be found here: [table/](table) ## Progress Track the Progress of one or more Tasks like downloading multiple files in parallel. Progress Demo in a Terminal More details can be found here: [progress/](progress) ## List Pretty-print lists with multiple levels/indents into ASCII/Unicode strings. ``` ╭─ Game Of Thrones │ ├─ Winter │ ├─ Is │ ╰─ Coming │ ├─ This │ ├─ Is │ ╰─ Known ╰─ The Dark Tower ╰─ The Gunslinger ``` More details can be found here: [list/](list) ## Text Utility functions to manipulate text with or without ANSI escape sequences. Most of the functions available are used in one or more of the other packages here. - Align text [Horizontally](text/align.go) or [Vertically](text/valign.go) - [Colorize](text/color.go) text - Move [cursor](text/cursor.go) - [Format](text/format.go) text (convert case) - Manipulate [strings](text/string.go) (Pad, RepeatAndTrim, RuneCount, etc.) - [Transform](text/transformer.go) text (UnixTime to human-readable-time, pretty-JSON, etc.) - [Wrap](text/wrap.go) text GoDoc has examples for all the available functions. ## Upgrading from v5 or less to v6 or above If you are using a version of this library older than `v6.0.0` and want to move to a newer version of this library, you'd have to modify the import paths from something like: ```golang "github.com/jedib0t/go-pretty/list" "github.com/jedib0t/go-pretty/progress" "github.com/jedib0t/go-pretty/table" "github.com/jedib0t/go-pretty/text" ``` to: ```golang "github.com/jedib0t/go-pretty/v6/list" "github.com/jedib0t/go-pretty/v6/progress" "github.com/jedib0t/go-pretty/v6/table" "github.com/jedib0t/go-pretty/v6/text" ``` I'd recommend you fire up your favorite IDE and do a mass search and replace for all occurrences of `jedib0t/go-pretty/` to `jedib0t/go-pretty/v6/`. If you are on a system with access to `find`, `grep`, `xargs` and `sed`, you could just run the following from within your code folder to do the same: ``` find . -type f -name "*.go" | grep -v vendor | xargs sed -i 's/jedib0t\/go-pretty\//jedib0t\/go-pretty\/v6\//g' ``` If you are on MacOS, you'll have to use `sed -i ''` instead of `sed -i`. go-pretty-6.4.6/SECURITY.md000066400000000000000000000004641437722442100152640ustar00rootroot00000000000000# Security Policy ## Supported Versions | Version | Supported | | ------- | ------------------ | | 6.x.x | :white_check_mark: | | < 6.0 | :x: | ## Reporting a Vulnerability Please create a new issue on this repo describing the vulnerability, and (if known) how to resolve it. go-pretty-6.4.6/bench_test.go000066400000000000000000000047121437722442100161400ustar00rootroot00000000000000package gopretty import ( "io/ioutil" "testing" "time" "github.com/jedib0t/go-pretty/v6/list" "github.com/jedib0t/go-pretty/v6/progress" "github.com/jedib0t/go-pretty/v6/table" ) var ( listItem1 = "Game Of Thrones" listItems2 = []interface{}{"Winter", "Is", "Coming"} listItems3 = []interface{}{"This", "Is", "Known"} tableCaption = "table-caption" tableRowFooter = table.Row{"", "", "Total", 10000} tableRowHeader = table.Row{"#", "First Name", "Last Name", "Salary"} tableRows = []table.Row{ {1, "Arya", "Stark", 3000}, {20, "Jon", "Snow", 2000, "You know nothing, Jon Snow!"}, {300, "Tyrion", "Lannister", 5000}, } tracker1 = progress.Tracker{Message: "Calculating Total # 1", Total: 1000, Units: progress.UnitsDefault} tracker2 = progress.Tracker{Message: "Downloading File # 2", Total: 1000, Units: progress.UnitsBytes} tracker3 = progress.Tracker{Message: "Transferring Amount # 3", Total: 1000, Units: progress.UnitsCurrencyDollar} ) func BenchmarkList_Render(b *testing.B) { for i := 0; i < b.N; i++ { lw := list.NewWriter() lw.AppendItem(listItem1) lw.Indent() lw.AppendItems(listItems2) lw.Indent() lw.AppendItems(listItems3) lw.Render() } } func BenchmarkProgress_Render(b *testing.B) { trackSomething := func(pw progress.Writer, tracker *progress.Tracker) { tracker.Reset() pw.AppendTracker(tracker) time.Sleep(time.Millisecond * 100) tracker.Increment(tracker.Total / 2) time.Sleep(time.Millisecond * 100) tracker.Increment(tracker.Total / 2) } for i := 0; i < b.N; i++ { pw := progress.NewWriter() pw.SetAutoStop(true) pw.SetOutputWriter(ioutil.Discard) go trackSomething(pw, &tracker1) go trackSomething(pw, &tracker2) go trackSomething(pw, &tracker3) time.Sleep(time.Millisecond * 50) pw.Render() } } func generateBenchmarkTable() table.Writer { tw := table.NewWriter() tw.AppendHeader(tableRowHeader) tw.AppendRows(tableRows) tw.AppendFooter(tableRowFooter) tw.SetCaption(tableCaption) return tw } func BenchmarkTable_Render(b *testing.B) { for i := 0; i < b.N; i++ { generateBenchmarkTable().Render() } } func BenchmarkTable_RenderCSV(b *testing.B) { for i := 0; i < b.N; i++ { generateBenchmarkTable().RenderCSV() } } func BenchmarkTable_RenderHTML(b *testing.B) { for i := 0; i < b.N; i++ { generateBenchmarkTable().RenderHTML() } } func BenchmarkTable_RenderMarkdown(b *testing.B) { for i := 0; i < b.N; i++ { generateBenchmarkTable().RenderMarkdown() } } go-pretty-6.4.6/cmd/000077500000000000000000000000001437722442100142325ustar00rootroot00000000000000go-pretty-6.4.6/cmd/demo-list/000077500000000000000000000000001437722442100161275ustar00rootroot00000000000000go-pretty-6.4.6/cmd/demo-list/README.md000066400000000000000000000033451437722442100174130ustar00rootroot00000000000000Output of `go run cmd/demo-list/demo.go`: ``` A Simple List: -------------- * Game Of Thrones * The Dark Tower A Multi-level List: ------------------- * Game Of Thrones * Winter * Is * Coming * This * Is * Known * The Dark Tower * The Gunslinger A List using the Style 'StyleBulletCircle': ------------------------------------------- ● Game Of Thrones ● Winter ● Is ● Coming ● This ● Is ● Known ● The Dark Tower ● The Gunslinger A List using the Style 'StyleConnectedRounded': ----------------------------------------------- ╭─ Game Of Thrones │ ├─ Winter │ ├─ Is │ ╰─ Coming │ ├─ This │ ├─ Is │ ╰─ Known ╰─ The Dark Tower ╰─ The Gunslinger A List using the Style 'funkyStyle': ------------------------------------ t GAME OF THRONES |f WINTER |m IS |b COMING | f THIS | m IS | b KNOWN b THE DARK TOWER b THE GUNSLINGER A List in HTML format: ---------------------- [HTML] A List in Markdown format: -------------------------- [Markdown] * Game Of Thrones [Markdown] * Winter [Markdown] * Is [Markdown] * Coming [Markdown] * This [Markdown] * Is [Markdown] * Known [Markdown] * The Dark Tower [Markdown] * The Gunslinger ``` go-pretty-6.4.6/cmd/demo-list/demo.go000066400000000000000000000126451437722442100174120ustar00rootroot00000000000000package main import ( "fmt" "strings" "github.com/jedib0t/go-pretty/v6/list" "github.com/jedib0t/go-pretty/v6/text" ) func demoPrint(title string, content string, prefix string) { fmt.Printf("%s:\n", title) fmt.Println(strings.Repeat("-", len(title)+1)) for _, line := range strings.Split(content, "\n") { fmt.Printf("%s%s\n", prefix, line) } fmt.Println() } func main() { //========================================================================== // Initialization //========================================================================== l := list.NewWriter() // you can also instantiate the object directly lTemp := list.List{} lTemp.Render() // just to avoid the compile error of not using the object //========================================================================== //========================================================================== // A List needs Items. //========================================================================== l.AppendItem("Game Of Thrones") l.AppendItem("The Dark Tower") demoPrint("A Simple List", l.Render(), "") //A Simple List: //-------------- //* Game Of Thrones //* The Dark Tower l.Reset() //========================================================================== //========================================================================== // I wanna Level Down! //========================================================================== l.AppendItem("Game Of Thrones") l.Indent() l.AppendItems([]interface{}{"Winter", "Is", "Coming"}) l.Indent() l.AppendItems([]interface{}{"This", "Is", "Known"}) l.UnIndent() l.UnIndent() l.AppendItem("The Dark Tower") l.Indent() l.AppendItem("The Gunslinger") demoPrint("A Multi-level List", l.Render(), "") //A Multi-level List: //------------------- //* Game Of Thrones // * Winter // * Is // * Coming // * This // * Is // * Known //* The Dark Tower // * The Gunslinger //========================================================================== //========================================================================== // I am Fancy! //========================================================================== l.SetStyle(list.StyleBulletCircle) demoPrint("A List using the Style 'StyleBulletCircle'", l.Render(), "") //A List using the Style 'StyleBulletCircle': //------------------------------------------- //● Game Of Thrones // ● Winter // ● Is // ● Coming // ● This // ● Is // ● Known //● The Dark Tower // ● The Gunslinger l.SetStyle(list.StyleConnectedRounded) demoPrint("A List using the Style 'StyleConnectedRounded'", l.Render(), "") //A List using the Style 'StyleConnectedRounded': //----------------------------------------------- //╭─ Game Of Thrones //├─┬─ Winter //│ ├─ Is //│ ├─ Coming //│ ╰─┬─ This //│ ├─ Is //│ ╰─ Known //├─ The Dark Tower //╰─── The Gunslinger //========================================================================== //========================================================================== // I want my own Style! //========================================================================== funkyStyle := list.Style{ CharItemSingle: "s", CharItemTop: "t", CharItemFirst: "f", CharItemMiddle: "m", CharItemVertical: "|", CharItemBottom: "b", CharNewline: "\n", Format: text.FormatUpper, LinePrefix: "", Name: "styleTest", } l.SetStyle(funkyStyle) demoPrint("A List using the Style 'funkyStyle'", l.Render(), "") //A List using the Style 'funkyStyle': //------------------------------------ //t GAME OF THRONES //|f WINTER //|m IS //|b COMING //| f THIS //| m IS //| b KNOWN //b THE DARK TOWER // b THE GUNSLINGER //========================================================================== //========================================================================== // I want to use it in a HTML file! //========================================================================== demoPrint("A List in HTML format", l.RenderHTML(), "[HTML] ") //A List in HTML format: //---------------------- //[HTML] //========================================================================== //========================================================================== // Can I get the list in Markdown format? //========================================================================== demoPrint("A List in Markdown format", l.RenderMarkdown(), "[Markdown] ") fmt.Println() //A List in Markdown format: //-------------------------- //[Markdown] * Game Of Thrones //[Markdown] * Winter //[Markdown] * Is //[Markdown] * Coming //[Markdown] * This //[Markdown] * Is //[Markdown] * Known //[Markdown] * The Dark Tower //[Markdown] * The Gunslinger //========================================================================== } go-pretty-6.4.6/cmd/demo-progress/000077500000000000000000000000001437722442100170205ustar00rootroot00000000000000go-pretty-6.4.6/cmd/demo-progress/README.md000066400000000000000000000001701437722442100202750ustar00rootroot00000000000000Output of `go run cmd/demo-list/demo.go`: Progress Demo in a Terminalgo-pretty-6.4.6/cmd/demo-progress/demo.go000066400000000000000000000133231437722442100202750ustar00rootroot00000000000000package main import ( "flag" "fmt" "math/rand" "time" "github.com/jedib0t/go-pretty/v6/progress" "github.com/jedib0t/go-pretty/v6/text" ) var ( flagAutoStop = flag.Bool("auto-stop", false, "Auto-stop rendering?") flagHideETA = flag.Bool("hide-eta", false, "Hide the ETA?") flagHideETAOverall = flag.Bool("hide-eta-overall", false, "Hide the ETA in the overall tracker?") flagHideOverallTracker = flag.Bool("hide-overall", false, "Hide the Overall Tracker?") flagHidePercentage = flag.Bool("hide-percentage", false, "Hide the progress percent?") flagHideTime = flag.Bool("hide-time", false, "Hide the time taken?") flagHideValue = flag.Bool("hide-value", false, "Hide the tracker value?") flagNumTrackers = flag.Int("num-trackers", 13, "Number of Trackers") flagShowSpeed = flag.Bool("show-speed", false, "Show the tracker speed?") flagShowSpeedOverall = flag.Bool("show-speed-overall", false, "Show the overall tracker speed?") flagShowPinned = flag.Bool("show-pinned", false, "Show a pinned message?") flagRandomFail = flag.Bool("rnd-fail", false, "Introduce random failures in tracking") flagRandomLogs = flag.Bool("rnd-logs", false, "Output random logs in the middle of tracking") messageColors = []text.Color{ text.FgRed, text.FgGreen, text.FgYellow, text.FgBlue, text.FgMagenta, text.FgCyan, text.FgWhite, } timeStart = time.Now() ) func getMessage(idx int64, units *progress.Units) string { var message string switch units { case &progress.UnitsBytes: message = fmt.Sprintf("Downloading File #%3d", idx) case &progress.UnitsCurrencyDollar, &progress.UnitsCurrencyEuro, &progress.UnitsCurrencyPound: message = fmt.Sprintf("Transferring Amount #%3d", idx) default: message = fmt.Sprintf("Calculating Total #%3d", idx) } return message } func getUnits(idx int64) *progress.Units { var units *progress.Units switch { case idx%5 == 0: units = &progress.UnitsCurrencyPound case idx%4 == 0: units = &progress.UnitsCurrencyDollar case idx%3 == 0: units = &progress.UnitsBytes default: units = &progress.UnitsDefault } return units } func trackSomething(pw progress.Writer, idx int64, updateMessage bool) { total := idx * idx * idx * 250 incrementPerCycle := idx * int64(*flagNumTrackers) * 250 units := getUnits(idx) message := getMessage(idx, units) tracker := progress.Tracker{Message: message, Total: total, Units: *units} if idx == int64(*flagNumTrackers) { tracker.Total = 0 } pw.AppendTracker(&tracker) ticker := time.Tick(time.Millisecond * 500) updateTicker := time.Tick(time.Millisecond * 250) for !tracker.IsDone() { select { case <-ticker: tracker.Increment(incrementPerCycle) if idx == int64(*flagNumTrackers) && tracker.Value() >= total { tracker.MarkAsDone() } else if *flagRandomFail && rand.Float64() < 0.1 { tracker.MarkAsErrored() } pw.SetPinnedMessages( fmt.Sprintf(">> Current Time: %-32s", time.Now().Format(time.RFC3339)), fmt.Sprintf(">> Total Time: %-32s", time.Now().Sub(timeStart).Round(time.Millisecond)), ) case <-updateTicker: if updateMessage { rndIdx := rand.Intn(len(messageColors)) if rndIdx == len(messageColors) { rndIdx-- } tracker.UpdateMessage(messageColors[rndIdx].Sprint(message)) } } } } func main() { flag.Parse() fmt.Printf("Tracking Progress of %d trackers ...\n\n", *flagNumTrackers) // instantiate a Progress Writer and set up the options pw := progress.NewWriter() pw.SetAutoStop(*flagAutoStop) pw.SetTrackerLength(25) pw.SetMessageWidth(24) pw.SetNumTrackersExpected(*flagNumTrackers) pw.SetSortBy(progress.SortByPercentDsc) pw.SetStyle(progress.StyleDefault) pw.SetTrackerPosition(progress.PositionRight) pw.SetUpdateFrequency(time.Millisecond * 100) pw.Style().Colors = progress.StyleColorsExample pw.Style().Options.PercentFormat = "%4.1f%%" pw.Style().Visibility.ETA = !*flagHideETA pw.Style().Visibility.ETAOverall = !*flagHideETAOverall pw.Style().Visibility.Percentage = !*flagHidePercentage pw.Style().Visibility.Speed = *flagShowSpeed pw.Style().Visibility.SpeedOverall = *flagShowSpeedOverall pw.Style().Visibility.Time = !*flagHideTime pw.Style().Visibility.TrackerOverall = !*flagHideOverallTracker pw.Style().Visibility.Value = !*flagHideValue pw.Style().Visibility.Pinned = *flagShowPinned // call Render() in async mode; yes we don't have any trackers at the moment go pw.Render() // add a bunch of trackers with random parameters to demo most of the // features available; do this in async too like a client might do (for ex. // when downloading a bunch of files in parallel) for idx := int64(1); idx <= int64(*flagNumTrackers); idx++ { go trackSomething(pw, idx, idx == int64(*flagNumTrackers)) // in auto-stop mode, the Render logic terminates the moment it detects // zero active trackers; but in a manual-stop mode, it keeps waiting and // is a good chance to demo trackers being added dynamically while other // trackers are active or done if !*flagAutoStop { time.Sleep(time.Millisecond * 100) } } // wait for one or more trackers to become active (just blind-wait for a // second) and then keep watching until Rendering is in progress time.Sleep(time.Second) messagesLogged := make(map[string]bool) for pw.IsRenderInProgress() { if *flagRandomLogs && pw.LengthDone()%3 == 0 { logMsg := text.Faint.Sprintf("[INFO] done with %d trackers", pw.LengthDone()) if !messagesLogged[logMsg] { pw.Log(logMsg) messagesLogged[logMsg] = true } } // for manual-stop mode, stop when there are no more active trackers if !*flagAutoStop && pw.LengthActive() == 0 { pw.Stop() } time.Sleep(time.Millisecond * 100) } fmt.Println("\nAll done!") } go-pretty-6.4.6/cmd/demo-table/000077500000000000000000000000001437722442100162435ustar00rootroot00000000000000go-pretty-6.4.6/cmd/demo-table/README.md000066400000000000000000000573771437722442100175450ustar00rootroot00000000000000Output of `go run cmd/demo-table/demo.go`: ``` +-----+--------+-----------+------+-----------------------------+ | 1 | Arya | Stark | 3000 | | | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | | 300 | Tyrion | Lannister | 5000 | | +-----+--------+-----------+------+-----------------------------+ Simple Table with 3 Rows. +---+-----+--------+-----------+------+-----------------------------+ | | A | B | C | D | E | +---+-----+--------+-----------+------+-----------------------------+ | 1 | 1 | Arya | Stark | 3000 | | | 2 | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | | 3 | 300 | Tyrion | Lannister | 5000 | | +---+-----+--------+-----------+------+-----------------------------+ Table with Auto-Indexing. +---+-----+------------+-----------+--------+-----------------------------+ | | # | FIRST NAME | LAST NAME | SALARY | | +---+-----+------------+-----------+--------+-----------------------------+ | 1 | 1 | Arya | Stark | 3000 | | | 2 | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | | 3 | 300 | Tyrion | Lannister | 5000 | | +---+-----+------------+-----------+--------+-----------------------------+ Table with Auto-Indexing (columns-only). +-----+------------+-----------+--------+-----------------------------+ | # | FIRST NAME | LAST NAME | SALARY | | +-----+------------+-----------+--------+-----------------------------+ | 1 | Arya | Stark | 3000 | | | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | | 300 | Tyrion | Lannister | 5000 | | +-----+------------+-----------+--------+-----------------------------+ Table with 3 Rows & and a Header. +-----+------------+-----------+--------+-----------------------------+ | # | FIRST NAME | LAST NAME | SALARY | | +-----+------------+-----------+--------+-----------------------------+ | 1 | Arya | Stark | 3000 | | | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | | 300 | Tyrion | Lannister | 5000 | | +-----+------------+-----------+--------+-----------------------------+ | | | TOTAL | 10000 | | +-----+------------+-----------+--------+-----------------------------+ Table with 3 Rows, a Header & a Footer. +-----+------------+-----------+--------+-----------------------------+ | # | FIRST NAME | LAST NAME | SALARY | | +-----+------------+-----------+--------+-----------------------------+ | 1 | Arya | Stark | 3000 | | | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | | 300 | Tyrion | Lannister | 5000 | | | 4 | Faceless | Man | 0 | Needs a name. | +-----+------------+-----------+--------+-----------------------------+ | | | TOTAL | 10000 | | +-----+------------+-----------+--------+-----------------------------+ Table with Custom Alignment for 2 columns. +-----+------------+-----------+--------+-----------------------------+ | # | FIRST NAME | LAST NAME | SALARY | | +-----+------------+-----------+--------+-----------------------------+ | 1 | Arya | Stark | 3000 | | | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | | 300 | Tyrion | Lannister | 5000 | | | 4 | Faceless | Man | 0 | Needs a name. | | 13 | Winter | Valar | 0 | You | | | Is | Morghulis | | know | | | Coming | | | nothing, | | | | | | Jon | | | | | | Snow! | +-----+------------+-----------+--------+-----------------------------+ | | | TOTAL | 10000 | | +-----+------------+-----------+--------+-----------------------------+ Table with a Multi-line Row. +-----+------------+-----------+--------+-----------------------------+ | # | FIRST NAME | LAST NAME | SALARY | | +-----+------------+-----------+--------+-----------------------------+ | 1 | Arya | Stark | 3000 | | | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | | 300 | Tyrion | Lannister | 5000 | | | 4 | Faceless | Man | 0 | Needs a name. | | 13 | | | | You | | | Winter | | | know | | | Is | | 0 | nothing, | | | Coming | Valar | | Jon | | | | Morghulis | | Snow! | +-----+------------+-----------+--------+-----------------------------+ | | | TOTAL | 10000 | | +-----+------------+-----------+--------+-----------------------------+ Table with a Multi-line Row with VAlign. +-----+------------+-----------+--------+-----------------------------+ | # | FIRST NAME | LAST NAME | SALARY | | +-----+------------+-----------+--------+-----------------------------+ | 1 | Arya | Stark | 3000 | | | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | | 300 | Tyrion | Lannister | 5000 | | | 4 | Faceless | Man | 0 | Needs a name. | | 13 | | | | You | | | Winter | | | know | | | Is | | 0 | nothing, | | | Coming | Valar | | Jon | | | | Morghulis | | Snow! | +-----+------------+-----------+--------+-----------------------------+ | | | TOTAL | 10000 | | +-----+------------+-----------+--------+-----------------------------+ Table with a Multi-line Row with VAlign and changed Align. +-----+------------+-----------+--------+-----------------------------+ | # | FIRST NAME | LAST NAME | SALARY | | +-----+------------+-----------+--------+-----------------------------+ | 1 | Arya | Stark | 3000 | | | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | +-----+------------+-----------+--------+-----------------------------+ | 300 | Tyrion | Lannister | 5000 | | +-----+------------+-----------+--------+-----------------------------+ | | | TOTAL | 10000 | | +-----+------------+-----------+--------+-----------------------------+ Simple Table with 3 Rows and a Separator in-between. +-----+------------+-----------+--------+-----------------------------+ | # | FIRST NAME | LAST NAME | SALARY | | +-----+------------+-----------+--------+-----------------------------+ | 1 | Arya | Stark | 3000 | | | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | | 300 | Tyrion | Lannister | 5000 | | +-----+------------+-----------+--------+-----------------------------+ | | | TOTAL | 10000 | | +-----+------------+-----------+--------+-----------------------------+ Starting afresh with a Simple Table again. +-----+------------+-----------+--------+-----------------------------+ | # | FIRST NAME | LAST NAME | SALARY | | +-----+------------+-----------+--------+-----------------------------+ | 1 | Arya | Stark | 3000 | | +-----+------------+-----------+--------+-----------------------------+ | | | TOTAL | 10000 | | +-----+------------+-----------+--------+-----------------------------+ ... page break ... +-----+------------+-----------+--------+-----------------------------+ | # | FIRST NAME | LAST NAME | SALARY | | +-----+------------+-----------+--------+-----------------------------+ | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | +-----+------------+-----------+--------+-----------------------------+ | | | TOTAL | 10000 | | +-----+------------+-----------+--------+-----------------------------+ ... page break ... +-----+------------+-----------+--------+-----------------------------+ | # | FIRST NAME | LAST NAME | SALARY | | +-----+------------+-----------+--------+-----------------------------+ | 300 | Tyrion | Lannister | 5000 | | +-----+------------+-----------+--------+-----------------------------+ | | | TOTAL | 10000 | | +-----+------------+-----------+--------+-----------------------------+ Table with a PageSize of 1. +-----+------------+-----------+--------+------- ~ | # | FIRST NAME | LAST NAME | SALARY | ~ +-----+------------+-----------+--------+------- ~ | 1 | Arya | Stark | 3000 | ~ | 20 | Jon | Snow | 2000 | You kn ~ | 300 | Tyrion | Lannister | 5000 | ~ +-----+------------+-----------+--------+------- ~ | | | TOTAL | 10000 | ~ +-----+------------+-----------+--------+------- ~ Table with an Allowed Row Length of 50. ╔═════╦════════════╦═══════════╦════════╦═══════ ≈ ║ # ║ FIRST NAME ║ LAST NAME ║ SALARY ║ ≈ ╠═════╬════════════╬═══════════╬════════╬═══════ ≈ ║ 1 ║ Arya ║ Stark ║ 3000 ║ ≈ ║ 20 ║ Jon ║ Snow ║ 2000 ║ You kn ≈ ║ 300 ║ Tyrion ║ Lannister ║ 5000 ║ ≈ ╠═════╬════════════╬═══════════╬════════╬═══════ ≈ ║ ║ ║ TOTAL ║ 10000 ║ ≈ ╚═════╩════════════╩═══════════╩════════╩═══════ ≈ Table with an Allowed Row Length of 50 in 'StyleDouble'. ╭─────┬────────┬───────────┬────────┬────────────╮ │ # │ FIRST │ LAST NAME │ SALARY │ │ │ │ NAME │ │ │ │ ├─────┼────────┼───────────┼────────┼────────────┤ │ 1 │ Arya │ Stark │ 3000 │ │ │ 20 │ Jon │ Snow │ 2000 │ You know n │ │ │ │ │ │ othing, Jo │ │ │ │ │ │ n Snow! │ │ 300 │ Tyrion │ Lannister │ 5000 │ │ ├─────┼────────┼───────────┼────────┼────────────┤ │ │ │ TOTAL │ 10000 │ │ ╰─────┴────────┴───────────┴────────┴────────────╯ Table on a diet. ┌─────┬────────────┬───────────┬────────┬─────────────────────────────┐ │ # │ FIRST NAME │ LAST NAME │ SALARY │ │ ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤ │ 1 │ Arya │ Stark │ 3000 │ │ │ 20 │ Jon │ Snow │ 2000 │ You know nothing, Jon Snow! │ │ 300 │ Tyrion │ Lannister │ 5000 │ │ ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤ │ │ │ TOTAL │ 10000 │ │ └─────┴────────────┴───────────┴────────┴─────────────────────────────┘ Table using the style 'StyleLight'. ╔═════╦════════════╦═══════════╦════════╦═════════════════════════════╗ ║ # ║ FIRST NAME ║ LAST NAME ║ SALARY ║ ║ ╠═════╬════════════╬═══════════╬════════╬═════════════════════════════╣ ║ 1 ║ Arya ║ Stark ║ 3000 ║ ║ ║ 20 ║ Jon ║ Snow ║ 2000 ║ You know nothing, Jon Snow! ║ ║ 300 ║ Tyrion ║ Lannister ║ 5000 ║ ║ ╠═════╬════════════╬═══════════╬════════╬═════════════════════════════╣ ║ ║ ║ TOTAL ║ 10000 ║ ║ ╚═════╩════════════╩═══════════╩════════╩═════════════════════════════╝ Table using the style 'StyleDouble'. (-----^------------^-----------^--------^-----------------------------) [< #>||||< >] {-----+------------+-----------+--------+-----------------------------} [< 1>|||< 3000>|< >] [< 20>|||< 2000>|] [<300>|||< 5000>|< >] {-----+------------+-----------+--------+-----------------------------} [< >|< >||< 10000>|< >] \-----v------------v-----------v--------v-----------------------------/ Table using the style 'funkyStyle'. ┏━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ # ┃ FIRST NAME ┃ LAST NAME ┃ SALARY ┃ ┃ ┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃ 1 ┃ Arya ┃ Stark ┃ 3000 ┃ ┃ ┃ 20 ┃ Jon ┃ Snow ┃ 2000 ┃ You know nothing, Jon Snow! ┃ ┃ 300 ┃ Tyrion ┃ Lannister ┃ 5000 ┃ ┃ ┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃ ┃ ┃ TOTAL ┃ 10000 ┃ ┃ ┗━━━━━┻━━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ Table with Colors. "┏━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓" "┃\x1b[47;30m # \x1b[0m┃\x1b[47;30m FIRST NAME \x1b[0m┃\x1b[47;30m LAST NAME \x1b[0m┃\x1b[47;30m SALARY \x1b[0m┃\x1b[47;30m \x1b[0m┃" "┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫" "┃\x1b[33m 1 \x1b[0m┃\x1b[91m Arya \x1b[0m┃\x1b[91m Stark \x1b[0m┃\x1b[32m 3000 \x1b[0m┃\x1b[36m \x1b[0m┃" "┃\x1b[33m 20 \x1b[0m┃\x1b[91m Jon \x1b[0m┃\x1b[91m Snow \x1b[0m┃\x1b[32m 2000 \x1b[0m┃\x1b[36m You know nothing, Jon Snow! \x1b[0m┃" "┃\x1b[33m 300 \x1b[0m┃\x1b[91m Tyrion \x1b[0m┃\x1b[91m Lannister \x1b[0m┃\x1b[32m 5000 \x1b[0m┃\x1b[36m \x1b[0m┃" "┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫" "┃ ┃ ┃\x1b[47;30m TOTAL \x1b[0m┃\x1b[47;30m 10000 \x1b[0m┃ ┃" "┗━━━━━┻━━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛" "Table with Colors in Raw Mode." # FIRST NAME LAST NAME SALARY 1 Arya Stark 3000 20 Jon Snow 2000 You know nothing, Jon Snow! 300 Tyrion Lannister 5000 TOTAL 10000 Table with style 'StyleColoredBright'. # ┃ FIRST NAME ┃ LAST NAME ┃ SALARY ┃ ━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1 ┃ Arya ┃ Stark ┃ 3000 ┃ 20 ┃ Jon ┃ Snow ┃ 2000 ┃ You know nothing, Jon Snow! 300 ┃ Tyrion ┃ Lannister ┃ 5000 ┃ ━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┃ ┃ TOTAL ┃ 10000 ┃ Table without Borders. ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ Divide! ┃ ┣━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃ # ┃ FIRST NAME ┃ LAST NAME ┃ SALARY ┃ ┃ ┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃ 1 ┃ Arya ┃ Stark ┃ 3000 ┃ ┃ ┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃ 20 ┃ Jon ┃ Snow ┃ 2000 ┃ You know nothing, Jon Snow! ┃ ┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃ 300 ┃ Tyrion ┃ Lannister ┃ 5000 ┃ ┃ ┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃ ┃ ┃ TOTAL ┃ 10000 ┃ ┃ ┗━━━━━┻━━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ Table with Borders Everywhere! Unite! # FIRST NAME LAST NAME SALARY 1 Arya Stark 3000 20 Jon Snow 2000 You know nothing, Jon Snow! 300 Tyrion Lannister 5000 TOTAL 10000 (c) No one! [CSV] Unite! [CSV] #,First Name,Last Name,Salary, [CSV] 1,Arya,Stark,3000, [CSV] 20,Jon,Snow,2000,"You know nothing\, Jon Snow!" [CSV] 300,Tyrion,Lannister,5000, [CSV] ,,Total,10000, [CSV] (c) No one! [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML] [HTML]
Unite!
#First NameLast NameSalary 
1AryaStark3000 
20JonSnow2000You know nothing, Jon Snow!
300TyrionLannister5000 
  Total10000 
(c) No one!
[Markdown] # Unite! [Markdown] | # | First Name | Last Name | Salary | | [Markdown] | ---:| --- | --- | ---:| --- | [Markdown] | 1 | Arya | Stark | 3000 | | [Markdown] | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | [Markdown] | 300 | Tyrion | Lannister | 5000 | | [Markdown] | | | Total | 10000 | | [Markdown] _(c) No one!_ ``` Output of `go run cmd/demo-table/demo.go colors`: go-pretty-6.4.6/cmd/demo-table/demo-colors.png000066400000000000000000006171071437722442100212100ustar00rootroot00000000000000PNG  IHDRE$;sBITOtEXtSoftwaregnome-screenshot> IDATxw|F&M6-]Jٳ C(PDPDPD!""eX{-f5ɍWB)IhE}{7w!B!B!B!B!QQQB!B_dd7؟A!B9 K8B!Ba؟A!B9+ B!gB!B 3!B!gB! B!BYa!B!䬰?B!rV؟A!B9+ K$K'DKG!+;B}C Jfݺu111v2DaÆu҅e .YFɿrڵk DTYxm4/_hOQСC۴i#H֬Y\B9!PkӦ?5ZfMppG>}ٳOn?^zŏDT(JP(M6g:tƌ"Ν;O}J4B^A*+%%LJ 狓?55yS<<<*_zl8׷IIIYlفfϞ}"BU%x}! et!HHH[V,7hʕ+eOiʏn߾lbΝ;yyy!?BUqׯ5j0^y<<rss4 _)j˵|B/|~!B!䬰?B!rV؟A!B9+ B!gB!B 3!B!gB! B!BYa!B!h˫J!B!B/!ʃ!B!gB!B 3!B!gB! B!BYa!B!䬰?B!rV؟A!B9+ B!gB!B 3*;BΊi>Hx:^j~srv!!!3gdYkךL&J? yFc||5 1"""i8[bӧʠArybb |}}1c d+W7n\ T$+V>|kB e9KOO߹sѣG gի׹s҄G[9rqEС̙3FcEVNTTTeP _$ɀٳg;T*UTTJR(AAAӦM3gN~嗝;w.tҚ5kj*OOO__ߨ(H$dQQQ2$IH$L2p@50< $]j4rʮ]ΰ`!CX:nZ8~@~WJU@Ea9Yzqѣ`KFh4_bEppBq`Dccc?,;3f8a,˸V!^T ƮXp% @Ptܙ ™7nH.sg2l}OV?xbU!%&&FPxxxo۷ok.Zݸqcj֬9iҤ%K$%%UPRT/i3!!r:uIJRڵ={ܔik)Sk/?BJ8.##Zj999Ю]ol6w%..ΒH&}o.cWnn9sh3f̲e˄Eu8.""bӦMv H$a"""wQQQsNa@&o}B9AAAZ6++ɓCdz^cx$HVX1f̘֭[={*Ћ3qpqzz۷ Ñ^Zxחy;x{{ ccc߿?rH777?su vA!"KߡC__߹sM۷߿(''<Ϗ;֭[^Z Bl6d‰۷dFZNLLB0LBBAڵ[h… .\vڈ"Μ9sҥ &B gR9|pNwYYYGyvz WirgBիWo„ 77oTjȑ#ժUVZGV ۷oƎ 7C////u07oޜ;w&GGG/Y$::'N duy7mڴo>!I-h42ĉ.]*r!?H$jS}gΜ1OصkWZGu:ݲe˦NP!@E!\AOE&$@/< d!>M,@"%d9y;cpggM!C,2BɥRΤ 7B!rV؟A!B9+ B!gB!B 3!B!gB! B!BYa!B!䬰?B!rV_TTTƁB!B gB< * oB!rV؟A!B9+ B!gB!B 3!B!gB! B!BY:x!3ڸas iTBBU%j(fN>B!rV؟A!B9oP(u$IW.)!8`n=5~B/SɋE|Hyw횇Le^ѲƠٽzFo޼Q ddno`r;E~(3S)'I+r.؟A~I/E"NЙaT*}&QV,(3q0JRNMڵ%c9WW]hAtv<(3zwmp |EtkV?ln=FIgg Oto 99d" /ge.\!rP)cVÓaclr+~ ToX(+r,Enae. Vn\ۼZuZvrY!rNzn x?&OBgvBg&f//:7GHΥrs>Xr)0Pۼӹ^䒘Tf//[ss\c.A;ownYʓh8q/P Hyxsqyj^cPN"!MF H%CGMQլXZ4-I~h M;snC*d]d"L&+n'=P>`<=YuuVfQSKoR9DggSSkMº=d.mxl&xYhڴ݈W=L@ą<1o]0nntnǁÆ7ް4Y7(OmBj}%-XXMzۙ-,PE df_ҘOi4.rw7`Be)A,߀Gz=IoдhIeի#ڴeC7F,CXRDټT*_׶u[:7? !ѴQ_-[vyERq40vjvVJMS8sZgf(k*qͪ];mgDJoZNBUE CǮDt^֓&#Ss~p%?VqIש0؟ALIe0ԭ'sjݝEY Kď;&~b2[[fOOb:kp]D<3ݍ(3SʓU((iÃ'qFl[ ycnD=3~oBU׏wn3U('\a<xфM~SBoSL "+RJwlvwx>^ t7f//2F*P9jJeϳdt?|Py`ϺI #* ,'2?`z}d2F\yI<ljř_ޤK0T:kiGH&lʛ(#]z&dȓdN^ ~,Ji4Z/A2~b~@^OM1;3 ۵'uoMtvF#a6 IL^ۣII4k( C elgT-YϺik)XF} !Bu q{wR9 c=N"^_c߯?ܹX}7<@ڰp]pʠw?t yE瞑g1{㿲fL wfd'vq| ICoiJ&ar:} OfavmWߤj6<@FT`=`Suz$tyRZ. NLtN3{ x x^OӬ`JWb1/fau؀b y;=<N&cr`:曕ڨ/ʺz=-'z g(ERRE38Su!\^ ƙpd2 inqVKLċżaM8Gd,.B8"pR1߬F}I鄣U+P]Q~ϠQ9E҈|QjOw )MXx~OF`'# zR/zmԗH PEl_;B!rV؟A!B9+T WʊE!x^r6w" =m*wwfl.>{oXkCaI7l׎fƍ/)Q~@C,i0vD@.j#qS5%_j5}/D ի )wG_"j_EiM=O3kKEiĻE dL'Lhl}N"TvZ/;Pv]1K~J 24lӦ#JPA^6ӫ8sځBR~TZӧ@vx#xksKR/ rL.xoI2W]fX$IN-NO#["kڲQq`R>(Ţf}7qJ6C'׸+tvV44]GeK-%yk_}S_}A痴}f}_.wX]Z$`^vڡDfko~⮔4~9#C*$ı2x?Kv(N;zw$dNfMYo.!y A)䠁ÏD jkv~;y05qܱ@9q~v| ?s IDATm kBeś*tJ0`{ȢTvZ/;Pv]I/onnjƂ@j@1{xrr+I`)e"ɪmѪmѩsxRk|0 w,]={}7x^9!$ON?|=Tg=Qx^֫SUzcV+!m`0|}@y)B\nS/VmN,7hh3I8#L2(I~yFM u]/ Cy % C0 `Ag}|8L޲#јUuN>OjUzxj;Xx찕vosN"uDCDYT]%$%%<ǁyKN $) O6lgd,sV|{(O(s;qJ_P lbcK `[rV㩪`^Vڮ›C?c'w.8n?~<ϲv%q`6FcYU!'U ՞Dp~DU1zd2YƳ"#l1$zċD$IIN˺)>ɓ .Bf@4TӲufKَzڏlWWOpz9Uf@ZZiNFxzR]" L&gӹXᴛ۷YTR] /oTJJ%TR]"Cò#lSUFJOq?]!*.<aVJs0J+p.{OEG@8ִi %JyTE焉kF$1j(F~\xVe+Uxv*1œ3;cq w2tܝ;ڿ3O/on4Q4Y:ݝl(^xTvN;@Iڍۧ oW%!T8De20Cp}N*5VӻnO~iSS4ʀe)gjؿGtaW.[II~咦E+ݟ۠?ulߔ+W_؊Gs{llZ/;%i7cWWx*QUyDEEEFF"ɑ+G]RnZxss!q ;Xz HšvC%t_XF; aqOh筥 " !2 :5<?|/K?eauϻQvpB)B!BY9}rYeBȊ BybB!T B!BYa!B!䬪Bx*+TSBbbeGBE$Uv/Xs@UI֟g/jRRK_N0̲z[S?21;=];a0.Z;:|; /:|ᣆ3råIGc`琉Xx__˩zhZ_?};fꅗvYQt vRԭׯkkKZa]&P=:DӖQÇ*fuwsrᣫ"8{uVn/G)u'M>ig-›師w~,mB۲׳RiKֵLK_T31z,JΣG\aD"5cZ#*7S߭[w􋟯'?JsB4gyr* ٹhWOͶi;=%5rUa.]۲u;w@՞8uh4Z]aw0L{W":E"Hjnf|8=cw5؉iiXmYDvv *1~!x]&թc+W 0v̨j6nCc#xof[wXj={t# M?ڤ1MBZzu\.ЮD"dk_գ{@GhѼ#Lfl޳ 4nةC{?__G,BRjт]qsz ǎlڸ>l忯~0Qot,>:ΜۊU'?z4ṁɏ$ɢ%K 3g1OvΝ{oʧNʔ&](JxqBSHssi:[`= a򣉓4Uxc\rYӦq+Wڵi wIKKt q%M!.7-777,4ԒئUq540 `ܯܰAG&zAdтuk:ʔq~s²eq"y6|} :uj{^Q}tSTBڴ+W$ЦMO9 z,)I%M!T`9ohxaa7o9x<=WϞ;vkb.^ W6nj/ 5rUިn豝;v1-Abcn޺uiS&o_|5>lۦUU9޺}AB =#C馤iƭk׭eɢcgeg,[to/ʮBXFtԫgXKz7n^rڔ۫W+޼۷ի?hZF?\F!wkO?~[{Hpp|p~;`=/\3*bOT~9zut12x{ C{^Yyx(Ǽ[p^OVpў_E"L&MHLp16/OUhghW/E$?~-Y F37i |Ni}}| ??_"i'lݱQ[oj'%D"{'Vkf3}6y>''x(Y:BҥKK~H5E>dHԴ˗{t{eǮ]-~i޶MIuNy"kQ&'/aɶ{~Z؉ib4V^Z7?y Nd6ƚ>z.myzFRg[wt9 4 dG=kF`@9vb}I_ܔ-r9 _͝tcIIGJ/$tZꇄ(ݔB0V{N298&-T^5<*sc@,׭#"7nE"(i:BGDgΞDtлgKփ[WM&cvH2t왇+2Uڸy˙ 7Wä́7#ݽ{?#3h4.}KG4nwf5k԰3K$1صwt³...]WXO-cӋ; K32||7l(":uGh4 ѩT-k7ڴn !\$N o//D2v̨ 7;ɉ;WPZts+bl =wjVJ!StP9~/sffMnJ{G[d`xv!OHW$j;7<{l l0Xl~}4ݼ9B*lbzt0_Vv8!rqLrJS1~-!ٕBȣ!BgB!B 3Vaʎqu}[Kߨx;]*ѣU (7lXd:A֪UQOзOFʸc͝:ա#5r8<;y]9N^í[w[ q NJhG7 m\F;=e6F=wd4լU}[~9 ϝ1۵i[D!Ϝ=h"h߮#%M/K#}is?제{g0 7o}k qvƭM?T ;^"͚5R;Z^p5ТyXYW9LӒy؊\K󽖸H\$/P㹝"QxxgDN^ v^VF)Vq֝Nj2Of/7լQi8ڵm9h%?-제@>=i苙si8_g&R/rk@윜o9^".efgeڴT*p1+bGLxz?b$U7:~b|c/?ZjԻ*H\8-;?ߟ_Zӟ=sɬlK+4yGNܺΉ\vmbMtm?nm7蠟gΓ}~bTRw(r7Lu7 W7hێ=w/3c޾}zdt@VW jW\+ׄ{;)Qw3ͻfffHN7n~Ru޹1{df9vKWvv ]8vP͊Bصkڵ4mNz̈́wms IDATԴwc%y޽ sνj>}ҥp֝pgWB}* EQjrx~Vxp񌌬Ǖ4݁x6ٳS:vh#\[NN:--s鯿sEisN /D@\ܵX$ccdf=\v&&!b/r彝|hҤQxxqM4 kKиQ)LYO>QHtS*6m~ݻGg=E.˲nK6 Z]g*jE  |VݽmDϛO-88mڵ4n`媵?.+<(u$IVxɪ}N2mVoDzvnAk޼yΜyQxxhVVNPPJU[1ൾP)w?1:zW>\5q%JW<d?{&vX)!1iFZN_H,zk{o"ܻWQUVcO 5nj~ߨԹE)زyۧS'֮]&Ntޅ*2/UZ*uquU+<;gV=[?=d*禤e3%I>uC~g@}9kq$wԾjd!?WW f;忝iE϶v/1$i^Z@LeOO*VU}OJѲ,[;p޷_+I,Qzvvlڼի[{fnjլ1iҸ5/|@yo'/l2~Sڵ֯|şEʩ]̯,SǶOfIIɿZfJww?ݻwρ~ZUR*R| |N_V/h-:<{6ٲ%ٱ3f^e-'~DxzR/<|AxۮmKa[N·z T E7f_h/svnj wܿnsyb2 ,n֬]ۖ0 2Zn/+}J"ƒ;L& oݾۭkg!ߋw7護y/5Mq ԩEQPz`ۨ^9S|e_﵋ž>#\\PM{xdaýR&#'W 9rbz@CDŽ_$%z,J`Yv}6ca3,m[v~pJPP __LHvI*N6bSM4E]]'edg(%^ )^C4bXN_V";veYHz\6bWh7&IK픠LK7Lg ̜DF;Ä4Z=ƍ!W >>9\vVwXwB"b/QĘbn5Qcb/&znb,&&cFQcGQA@,, [2cpE`GgΙg9jUSjS9م$.]]DDy}/65ZC߾c9AZcUUK.Rfs祧4~N$I5Ψ97q8$}['/-]Hl=ܙ zEQ\ti3,❼MKm6VԚ-mޟzElpÐqq!o"aY"6gr\K.( ϿxxWk>^÷^j9{mxESmuj:ul~w[q}_n?Ӷa~q M[¹N'r-\pCɽxDDxJJO>R:M7?vů'4źg|adT.$4o__8owWd$en ص$1 AÇ >}//8q"kio|aqiY#cܒԾXƍh|a^[AqF8uTvjjStI Kӟ7=[PPL&s?6oں_xsǎ 2bk;|㽽_cuupp`aԊ9b,+y{LF!:uJyǥv^}./m{A[UqFaŒG㩱׶"s+* ,zRRLrzG|fАEkM#c|n(u=k=m싎l:t~RZZ`b%/׾0СKʟx9^{Qå-k{VO ?'/_ƛ#Lo\\!ӗ%L6h`<Ͽ>2eλw栁IxiSM嬬4괚?t;?ь.35A[{ͺ؝;q\a|k}iԙٰ⧖<9pkcd(*<5>^W_([߃ _w]%%e^iࡌ}r>rС^=j]wޮˁo8|ۼ=M e`J M7N.3Z[{ȘFZ2oM7m4m4I{DTBCRrVsV.1Წ6C5n(R]F7>]m(Mji_<&Sm@ΗOJD6riqO|-VR! %?t/EQ\3?8?!!NlG~^[;{m+)ɗ՗]6r r#͜+T34m6ܪFi_L,Z-PEMA@t$F7>]m 9AMji_<灁/A m@&0zxj5j竻ww}Ix띵yyRdkV/qJp\v7<|v/O+r4no>yBivh^/%+qO%vq}̡oV̧qWz?6OB.U^nصko||_fu|7/m+$cdacƌ?!9+.>ǥ^E!{ࡣ2=fҧqN8.:iB{#G2xŞ/,zn߶()wZNП" F(59˃Bk>aDcuּj]!B!:/ B!:+\w$o=n7Wb[B3f3GcBAM~{w/g(PwE}ٸ>ǟml|bC'r¯+:ovs,韖Ҧkiv۹kWZjjPg;={%ԔWVO{]k,¼9L7֝qxxIөcEnڲY}e㾛={Q7[+g-["ûҩ6}lcOZZƎs<3djR]׌/33OHzI^w>+GWhpWli!;.8D^\W\PP}c2 8LoXDZEY/_l ܳy_|5pZ]l{N޽-nrgv=mZ+iwWI/~JK7o'<@ *8BW'g^TD bÇ OS[jL"2BJ}ӯx$)4MdZ2OkݻDŽ*&'ܫg"˱ӯo 3OD!onT/Oq/dJ۽ Ce80tĞҢZuxښliu E6lysINMRq@VV>鈋33SUc--"%HprR\OwH{A*+##"BCN79Gr@P``}`0d\2VT*0TVJ!ehfA N:պց"#"RSy {6d\&>sƽhЀHׇeܳ"N7d Vs!wy<}^mMә-fG^g9uH:}iRqN~>]$Z,_?AO" ~v0T'N x\.7N^K]&֬_Ŀ>|cIi<[\R &ŚCG>?039g]h_2Ofͽo /qW<,l^u}xsΞ/XS߿^^?,,*.5?+VٻoIk C}Ï/,2[,?vPvy5q={ڼ\ p<3sİ/VTT;)BKP~$Ar$$(Ξ I{BO`: L cON<'RTsҌÆ o¬zqEG@``y-70޽z_j|aCK=XĞ/o͏!50=W_ճg||4RS<Žl֬'-\ 8rA 0|ؐ}1:v \=}^mM437M!ILKMݷtRIliʏߓ1[)@4 (J^B|qdAh6N L4-[z'&IKϜqm wN=$8|5|dx-Ͽʬf4e2 o~狊{ zlٺs59_J@>Ik?xWfl߱#_= 9y'm7ߜ?׎I֬4yZe4M;]>x:xR4gW-2VW<ߢxhHH;TW+匎] >Y Apu?!ꝷ{REl6N$,n'O8 ?[Qa&W߬^6nh_k]|h{O?[ь}d11?s'N\2Ow" Ͻ}S7`q'֬ۤ[w^S ?#k?}ʬϫuÆr'Λ_:pPXhh㸤^s#UpPEQ-WVUC^T*[,XX"NJV+RǸp85[,˟z"4$DR:ۧ u%ө߹CkyHihZP 3g~9U[C\)y˨z=3mL>8QQZ?;wd=?l<矋c˲uutmOjQ}?lȠyzȠA,6J ^ Z㯟8>:*"!>}/} =jzkz`!4MSN^ EKS֟!LMny¶@ʿ5i"ѯ/"BXJii[n;;f{QLn4UJCF *y $ER,=w݇o}GVv{zS?`Mhh˯u۝3>^p8 QPUe(`0̾N!^~ӭ[rİ%eV5,4ֲ/ri)(L۹.u)ssvli: hSRfޣk",՞~,LyEE@b IDAT_T* L߹Ob|$4,ja?]a= 6d'̛sτIJ"~բf˜5wAef!)FC<gE C}th4J^}ǎ "00v BHihE!DCr399Dx80)Gt{ktA5; 1155&4V c[g;XH֟/,B̻jʗ~ i˳^~DFD<74{#V,CUgS%e2Wv? +;;2"R08Bu(; cJ Xh$8<臟~fs#V}P`4LƄOT,}fɃ>!=[۽Qw$IWTf{k9,y;fH[i_eE/ވ!4PJ].s9M_ }\, -#tuϏEǟ#Gjk~"Rsu*;/tn =GÆ v:>NG-:zoz_:ǟbv%]wr8﾿޿ˏeZNR%aCɬ,cnP*cFz5ұhq@/? ~qЀy3ݞWPYUt:_;nҷ4]kԎVS?K]>@ɪo)`q?\.7_Z;MqI#G^tty= @ ɤN oAoH,fs]][b קL\;z4] sI!-OFHuFb q!!rys)}K]t}&"}=xn'ƌnI #%%CMQSc#$o<[0[vn8F< vی DgSi<4E]՗M3j;&d+yF_3rK:Nt޽zf䃋׌6jH{dko>svp`f{`+k+_H-{Z_;zTaQ rǷ.c21\s~R\y /~j i#A~S&a'J1t+o}⥗c|e+_r,|Ex;z=/ 00RrzOmKz\!@Vr&={yӹg?y7W=Ȣ/7|b4Ukw׬J_Ͽ?K3nAKRvkXo[no]SM6M6{ASF#Y_.;@@5~$ =֬iz^,([ q=iz1]:b]l1 @"R>iZ- wuXV㛖nwV0Pt|i_~>8 r9d OF]IҁQ8[G &VKy>{OuW)ZPYv=4NGDMMmFyFV7xuh4_T$eٮ0PyeӸ>?qe17<[Q5XfTm6,V{E ^z*8c~ZH0 ;3_>vՐ~8Bw\&/kcM&OpϽ5\l˕x ZE\,[}cW [Gj#GFFoݾW.  "X7q8\SA!tZП׶+{_ 9vwqBuZ6 |{/B!r[<B!BW3!B 3W1Q$Z4$`*kB@lh.BcxHr4#8h`ŨQ5z<v$xKz,KXV{qh>+7.2M+ҦU# [xӍ CA+2'{!:3=h|@K;s*'ɬޅѤ(FTe3,%w~tJQ^k NF;5G/y $,2+>Q$O^n2 a27@ԎTdVK޴$EE&yI/ѝ#YWՀ!"Չw!ٳ3LN */=|pd͜J-GNspojҳ z&wr$9eXQ/%$#AB')(<02ZƱqI+Yx:`O`)GWx, D) HB$Io Uwl^dqee)v:rr`EmϞ7L5;f2\:=,,qBS#DRQ$],p:SrAW)TKYUj-+: @LEc ⹱}r:.\8BW'\u*GX(SaaRW*ˤQTYwlbQI%ޱCSk,+Zå%7UP|^rVy * (b qZ؟0fҙ] uuĀܜ,]ǣm6^IRQUqx:;~!Vl*qɌj){WIxd"0"-KruXz"y\xG]zS2Izn2r9XԅEնPO9;v^;S!9_B!dX3B_7d,tڣ e,݉ɼ,$t1iN*J8WP,V6uvgtygefs?|SRRۖ pFaJJQvVBKR*CF2jHR dIXD-eQ9,#;'-(ȕ;xG#8XYYIlZ $+ Cx|( Ǐwt-(EUҥՊ#PXuz\p:'Ic@P#tgB!BU r_B!RWB5 B!:+ B!:+|Ru>&Mի[+ ^t.8Fsĉ˦{ۗۺ!U ,Xe˖"eP`aÆs}G%%%#FʪaΜʉ'ȑ#OT*-g}vjE9ݻ>(UUUYYY~lSL ?3dȐcǎyZG۝Nxxk aͻvj]Çob#oϴibcc}Ϟ=3fp//|ѣ6lƌ?ׯ_CI̞={Μ9j̙˻{˗_[Bv;1{ymܸq̙y_->OJJʶmX]vٳG@RRqjO> iiiF*Zm5MFFFyy91{_zyԩ˗JjujjBaaa999III111gΜ)((TItttZZZeeeNNTH"AJKK3gz? wPUUװC5 gΜ0^e7BaKq\FFƚ5k͛c* venǏ$B33>}zԩKD`iiiE1--m!!!t:,XгgO)R|IwMѬX"== ->>W^4hPRR+2`>==}֬YK.?dɒHOÇ?ZvȐ!-j"F}I~&MjI&=<Ϗ7nڵR$-JMM׿գGzB vGJv9j %%eٲe񱱱K.:tEFF.[LbguM6utPGQ… 7lC5:&$$|Gu]<U5w7 ÇNOO_~/by&L 9r/<%I6m侜<E[.11QO:uӦME{ƍo?4]S4_>!!Y~tVZtR뮻lv#ؾxnwׯ_߰ofJJ 4Vx oO}݁6;Bmݾ~x_zO>ɲ /0e"Ba߶mZ-1b^2h4qqqjz̘1cƌ 4M7֭[H{dO{O_[[qFj/剈 I=Ș/Y|W\y܋TY/D$EQ ½tΝχn4bۥ&8h6+ӧҥK?# V^}e˖8p ryӱ*++O:5f̘۷[KAAA q7ht;$$f=Aӗ6\<:N@p8B'Dm0 ֭駟x(_ŋϔ}'BSv|nw9;wBXx>+=߭[73ͮWXbܹk׮T)oډL&[bEg+'L@s礥F1$$w ø \>cƌ?{cs0$+ƍΝ+W ,++;~9sIO~ܹ2iizO1Lٳg&IR~M߫gϞm}H6,++W_kΟ?w߭QT~WT/l&Irƍ& yx`͚5,VVV[5zO{J{O<ڵk].(=!!!}pw̙+Vx,3f̘ٳgr (fҥK_BvFyZ֭۷o ofŊz~޽>n󲲲7|'())9uꔯB~Ϡvhܣ4j^5k֝w{ 4|rэ$ɀflܓ hO .o$66vŊ ߻j*5Bؾ펤iCJeHHH(\}kݾoެVEw߾}u:^;v죏>{,J4iVϖy*OiVFdcǎy~ذaކ! lw$M .t7Om"B3oѣGsbŊڎ.N/5jذa.ܹs< 6-!tY Թ!/!ΧB!?B!ꬰ?B!ꬰ?B!ꬰ?B!ꬰ?B!ꬰ?B!?!B!ԉL6 j ؾ j 8&B!B B!B B!B B!B B!B B!B B!B}Ozڮ!:3yÌ+!PWڜtSB!PgB!PgՂjkA( Z Dad^@vC9Os(߀ \c=wY[#jeZ\-V"u :*rDEXo}5-kQ5xUc\#)a-cz#ٌӿ:zI&MPw$! "۔E`Ң QG2eHA55Dp>q qiX>Yޛ [If[W!'3;&8 zEp^(5۬EGATI}&BZd8 )CuV |@򄦙/=FD`)ugDSGuE?:::- qs Mpڭ!o/߳stI=Bs! S+|dV}GfZ *(&Z\W~z(i#Vr&w'AC6oǾf-׵zk:*sALuT38Uy"ԛ@:,]Hm3mFedPӦGs `I$<X ]RgV{VmLBh(RX[ȳVzD) } 0JNpu&OzUT h<ګnH܃Vrv% DQYXgn$F\guT)>w ardތ>ԕgZP$!Liu3P_JVE"9^~e.k'B(5ABd4a"F3+ΰ*F OU8YpuAB6\!uYbJNU9jm' F2ʐv>M2wZ ZF*;T^ΗACC$O$Ő%n9w)C{ʃKrՖRr( AҪ2]nqՔЪUdJGU9huX :a=ԗwN5RH"[ !'؟AVCxj"G<8.8m*I1ͤ請Q}j3I+'$-u-QtY! IDATɚءǿW5^FM&vVk!qڸ(eA:4fNK޵޺4< i SV[Q".n8(EEI2*u?$Y%V*ZOm<27(fKGcf[ Fl}e3]xM[fnC.3 )F&Eherx{giU9Sa @L%N;IA4UG7 Vr\R}js+;AT64$g֗!u0b"$@Ki8&{*OpuhC FNP ׈<+8RXQ EhOyH@.`#.gkrv0pFcPWv*dbӊ"  U (=^L)†βo!B< =F)tI! LZ+]9KELC+ ZJ A"Ϻ<HKR"(A"APA5yZ)ӄG$i9AtTu[PE5emt[A1؁AҺ0su=Wh= >S$q53u$%'4+8{m@qP2241(&f]xDB sBwDZ(-s 5Ş٪Izwk\6VO @H/twZA7VDEZ#V HoN㹲GطS!PWŨ!]V&J]͙.2"dJ )B$=lȹ@$DZ yZ/sԺ#*<ܕ+@r5A(B}IkA7s JFA5ΦA2ʃ{D~4xdA˂Cu* gPU$p9B: S\hB‡%-Ǿe`4RR@ZfeD; b!8ٺj\;mIJ=p6cj?/kM6~% NWB5!kQtɃ{ȃ40mÆS`U{ɇdR'' &Ӆu|pN3-׉<>/DAqt7*H"Qr(pDV7 \_RN s`9O{ɤ+J:9{zJ@2JJHʔ$-'(JbIMOND(V)=g7Օꐐۀ\%mU|=>q9\ CyD|} "tf˃b ! ;3ڐ\?-F`$vs' t/YmV>dHPʈdJ* <wr<%QUU}C\hu"$MQE .P5__Q_jB9i_>b(/{@-2 IQrOYìf hQ@/2b}+ӄyg((OOx l(I* bIݾ! S:/ΆQ9{|̅b\'SD`Ҕ8C}]p /Zeٰc@4ھCOB1.ۓO|OFB2JiJ_꡾LIZBm A!BuV->sۮ!: ࣢_|Bu !>B!ꬰ?B!ꬰ?~ٷ߭!DTGUξnGͪΟ,ړ6ya>Z^7\Њ q =_dx$H >sVg$-g,FQސwg]И^#" m?s5&pչV̍F]vƢ-6Q}٥eCZqn0Nl] M)EΕv.k)9ȹ C3j cdH.q/ǁ/%I{)Iyvh^^CK[UH:(sg`,<Żaqyx!K3/5՜6nk鉺̋I7E=G n0=2o@k}mk)iS] K_ 粈$3NRb^nς(iR+/K:{ }}bhJPzO6k1)㇠53)&AZYU_xiā}ŁUBי1JV?].P:4зȷ C@]-NlM|uRIS/چ 2[gݦ4<6zQ%pwQt괧HL_^Ӵ2OWȍcTYS! ̈́BGGZٺdşj%sKv0?]'|BmOF!{p;?A +Z˝" ;m[p{s/yuW]/L9#ȼ=+c]^N7`Xp٬mB{M:i~0R.P:wyiAWǁeVF ȋ4"m]eз<ٹم wvG]y_ \kk@yyw,VQf= B.^1u+13Ƴ4SKS/O zuI%ٱyN{Zː=0zKpm=+nⅥ)%|J^ʳqhH>mv𬞙^V)-̸}ԭmXÉvt ʺwl{0 9.?ZB/ʋI55s:ӛc0؊]|G?\&aȞC2bOI_g{vֶn^}3@ a%@L).KZxkGk=z9~2tYт;r1]ӵ1Ί)rJJ%U'qӏQTT24z.q?Zgi~0P.#ԉu+UIg)ώ5x gr/QW'ئT+1Vƌܸ:cF{ rm[@(++ώ՟5d ZPwTrCz/ ( L2d%Rv!3oZ94;}MLӔ![۹d^,O#|[W@CWWJS CV?*'}z@ B T2 <.N-̽' 8wwgm:6$meie=vEӨshM̽GZ;6)PL>+QYFU]0=1I]tqڍ?};5{'.)bc9_j\+Qas)7 5% R$902uw0;B^_=Li cl!,?)~8+D 'Ve-C|G#Adi+H#OY[Q$˸j:ԕws4풵{ro,xJ,xhQ#-0O9ڼPN]x+C'k~`(]20oW^d'z4ܿ ']9K,7 Cc5F!X#kM:WwgfȈ5 3hϿB?@rY~C ^@6%bs?q,jj^`0U-RMF"} Cǯ17hϿB?@rY~C ^@;4K|il[8?868;zưwEdĂh~2@ ^ 3&,lNnU;':tdue'V].#~0o8@ @ H >(6@ u h O@4}@ @TP@ @TZCFmhGyf㬬@  $ۄiŦD3GgŘat5iW&LeY)~ҥ2!_|Uv#JW}&Mzc7]tiҔx DA#'t}Yki}p8wgLVxgk>}^a6>x޽?~iP~ |+5gʆvJbU+_~Kܳ ܅K~ϖjUky-|>/ ?gvAa?pw'W`cxfv`ё֪vkójek~oN{Яϴ|*v[ Y?pwsMII۸yƯˏ;N{ʇK`fċI|q 9jAINL&?u,M?]m7DNw?WTdqw:s39 9!}$IK._z~WwueeeccKېc^mݻgBbw;ӧzzyzk۾̻_jf) On;r8ƌz90lllzɢ";9;9w2h<=nsBTs/kZV{W7:EK~ӟ5U,\>J>_ "#+B۳&swNn~Nnރ^8<x1iù ƽ26=xv-}<~Ӧ4 rg+ ?JIKȜhך0cq@]!'&68ݹqvaQUΐgYT&o=2^BbxX4}/!G񓅅w%4m޼%B g@>Y5szrJ݄ďͯވ'KjZ{ݻui5>Rt)iN)#Eb(%nݴ~;K(2Iwrtl!zѿo?i5C !8]wR8qԈC&@d7n& IDAT"HHLl<1l6?ҕ{~]kAAakmވ'K`/fw7nn5>bxْA?x'8;9IeRNkf]뇭A4weSREBӀ~}n܊|:N<Ç^vC*K $IZY geމ*J5-x?l%Ir9KIT[ 5C{ s};[SgVV&0n?g>~ :NGier}EN+J2Uo!z/ˋ]Խkgkkk&DǪɇᅬݳX,~}:sյZBl)B$q~ht: 3[nߺyWBވ'Dt ۴nw?lMP*{qcFiC"p'oBM՛dDѲϜp!/? @՞xCM^NҹDtxÆ/>߸y{[1 ciR4699 G *Hiu=־]?ݳ{:P$AޟT*_WF ؁aD #~ܾ۴H7c'MOrrt:] 8Q6oaݺ`vJjzee%0`MY&'7wM;yWW55RCQ#'=x8fk7n֙jZClH,.#Gݽw0;;B4xQi \tK=Og $mwDP*UZe:vbVv+WFr:-!bhu:o`ȟK- M[-Ac\.ƍqILsalŪܼ<kؐG9>k4L_QQKޟ ݧw*Dr5NˣdLgH-~0֧mvٳoJ|IʻtFQkڅkZ0UG ^LZxB۵:x`VVvVvuVwgؐR.-h4\yJ&A̚3_sc't:]ɩ8F{e0<J X/XrП7o@yt߁CY 3KJj;wO?<@m|cx<<~4؊m\.;WδF7Ir6o{yPn-*.vvv m׎%FG~P5 r/TKe1ݺv[[ce?urtxL!tŤ9wb/x|~>'NaC}DT7W)M5gDR>_ĝ1yM[ A٭Z~|mpP@t[zֻgφ}ْ>bw+Xbo6tR8UF~ԙ$Ґ#}^Jx!9놠iS#__Po{mޘigg{¥BF} /(J",]~~`rJ׶|NV_~ʵk CNnklYVvv+Xb%??ys9B`eu^|۵ZݱN>k@T `ݿ ^x Lag &tW:Mau0 0Hm۾̘VuQTrg':3lr 06jY 2@@VU Z&IՄ,.) `Q*U4MUl@>-mgLLNR8Օ1a!RfNt;vT]BaQqqhDB! bHTj xuiVQ&W_E 8Q=y: H}v Y4`乹~NLZ&)?q̞]?j%Ԏ: 6EJ~0oq j?h V!c@ <7ωvC zs;5*Z2&LVC5NAGJe10MlEs[@ /(d@ xA@ RAEg_sr i陆>~QS:8ztRhӦVO5MBҞ۷y ä8TGiU.]z9U bnfڿhf!%%[!g7-coP[h6^OF}ߡ۷JUn]^BPP gc8 N]w[+ Gw҉f=~ss ۨc'%R _yj5U!u?p[]LOxxw`ѧZr#'bb4[KY*Ʀ[Ώ%Kd(З:;94+Fm1XYg9]',)*[G{I^j##0w2AA;~x;&S+lQ[<'+;g8o{C|cN 8-tx⠾űa9v}RUeY"%%m;t>l_Y1/x{.h9@ǍimT `!.g8b3Ǐރ8a|-dADaIܽ{l~G> ;^lr?xK{p:5j4׵ZV-jqOOĠI ZeDqfՒɏNtk%v;]}9iCWV*n݊tZiY^$$.^MIIA7u%9'wޟFPoiEEӔed|"6loL mcnjG>ı.N.΁=in*cǎ<~ cF UY$TUk5(\z/!]Ić7n@rrH$ >JN}ZvL|ܝ'MgiivVv[ KMs] 6zXYiR. Y]׳B"hdd89} R2GxxLӴw uuu>y\FfV^n~^XP=f6D_XX廝Ɔ-~cGFF4ݡC0G]m-xߧۛEbaXX+_4o};x`YMQT۶ lؒ5T4׵Rp֟Ѫ1G}F˷pBV8xԸŷT+|k;m=jhھ]|~;"7`%8{yy\|ur&NxR]:Gye~Sm?򛯟Orr*ܼٱTljB*+utPZV&uϗ/^r)M&qcG~uGjZKC$ FyY7n{I߷5v=$V1t)<|'1xIg}\DG ǂR\|9>88EU8)K[єCp<]]/^~#%<=؟g_f&ǂR\*g?Cilu Ze;<((g0RAT}2?{R`V[OcדVdϦpg8N(B=a+Glٺ\>c{+yK}];ۊEB3Jݔ`)rZ<pΣGUJKl|0K`& KKJL6)!!)q;Ks @A8Q蓚>xpƮ'ϟiÝ4U<.0>iNxe҅\]j뺴\*Qj#4z&vnA===$A p1#A4WTnn.r\_ZmIiKCo@Phcc!a8qmB #4ʶtp{}zKd/K63$Tl0 ~9_A}ɔ_PTG^xws>)WS6v=1~(JG5ku"ѣ7kZ3lvi^ ~';VaXZдNy:E9S^!|m~~P$Itt/lH-}{HOϔ+ 57f?1aBBbdDÔ e[߬z_?WZ'Z3[T\L6a_/fչj7](ykʫS6v=1~rӰgQ#T+enۮgHR\lp;۟)ʸ,/ 4$GU)utlF >r\R14sfL۶Um\]]:th/״ʿ'F~b$6V)i(?ChC/*SPXz0b쬜2FǟÇ6OFWHHK@ќ;w>\R/Xލ1gۥ޾Tjo݊5##\~幹$4K<.5uރF{>r XKV Ǟg\ 9<FA7ñѣ | Ǻwa2޿`״ƎojCr//֞ؿ4!s 7̌{O|p?QXXh?Z%:8^c}<\W;v<"9_\}ꓛVUT6|׽[[ZV`Od׮Qfo=5B>׭(Je6~g|~!ed> go24Fuww7OǦ͘jo݊sws]vNG]x~0tܳy}3`VKhw;}777R9]O\ٷcX݋c$Nt'xADx][arjml<.A&rz5yĐNa˖?cin&dbe_UM?aIh%(ah#RflJtB:VTVtTL**+1:M5>hTjk2UD"L14_4 !+&\ h3"p$?1y6?&<kk*7 {#5>h< k2U깝\V3~Aru] IDATZRZ~6Jڲ󫽽=M}cUk_b͆UHOd~Ïɭ ڥƾVJj{_s"A:|>u/Tzb^ք~)3Ϭ\n4v=1Ro'4VSPPt5?6Aܺp<=}Qu'oLgnM.5u1*Zu,xB T?NY̋5ߚ/@R:9xfh7뉑z[g?pIs>=32SյKNɩED_~Wܚ]j1z/D0N]u;Kx{#8rt|%@ ,NZzƍzڥs'FdklS򑖍M xx5 5 Mam;6=hW':~p8٥X`^+ xzm&MVXfo{դ"l'NTU{w׫W0?+#CZk9[oUIA}cs:ʲ&,[QjZNG]ieIGW݆`x<MxF5E /ov+*UߞᒥƯ*.-aċe3b_/8x8GJZ@IbH7 ǹ\p$WTTMHw)}ېĤwh.0$ĤX(ryE\|RĊcc:Xo[3_Pp?fC=]P F&Ho޾hBb$ puqa7Ie1ryEΝ:_\& E|>}Lʚ׮moSuQ\4"EC۟,O9SH@S+[ &AӴFCt:F666a1qXQ:;9&=|ھ_6]hvPTT(?BȈ@w'DEK稬'IIqsu I9 n\t#~wҕ>JNoBiԴBvX$9J(jl"L.ST5'Manּ6q?1UG ^L,H,K0$77 r(ed ߴdB\ vEcm5oǿ77/DR~+&nϯhSҦ;ڍ[ 3V{X|EjZG~~yK4]QJZZFFE/_eH7ⷷf$'W*oͺogظkׯ8wۅEU~"g[p+φWc#u:9v"iУ[W»h6UoV N x>l ( SƫG`˳o-Z^8wnO+`iu5s7zc$w5p;;ۮ#|}#g=w mݺvf??iU+!i??o֭Փ ːno?mC,}ѢdQ={i:*Sn]\?yH(͆l|56"!{|yP7WWVqcXa/w qT G O,VUxz(ۧ`{PUq6NȊޕjhNom $I2awnp`3QrǾ;cL0|??g$eORޘÇ@T7nv'Om ?6'NnY]o m}o9U^afN{&>k䔔 -_=MfL}otoh}O[N竱op8j?dqΝ"1yo{nZ?٥eeE;9:6AN _d7Te@ŔV {k'dpN]YV{ԩCMNɩE֐?~.ػ`Ii)gd~q̩o?E?N@:e*z׬9(|ʵR.\4d&;;8RUth4Ǐٟ'X&$I++㬬;2YEiFPL*onnގ]jX$R*VA2<%5]^Qyٓgd|Ymߺi3ywg|tV&W,^(T*S)њ`(,OVE8wmӆy1 #㱻oZBl)B$qn*I~f.Q˗~%*JVd%Je"0(_hc/ K\eA~wp[߾a-wpR$.]W\RT(|zxX 8m}#zG K |VYy}<=9z}*.*&틊< j)q)Sw̹=bo2T.NN_oI, 0ZSrC)(,wo?*2¥+MOrrt:]}2qrvJʜ5γh$-kw~sЀBBj ˤMxc9.QQM|>FGGlmmm/T,ȓ¢zop)*.?cw0ήT˂@T*%NzON[jz{GTd[`sElʥRaegWM6BJ-qvr***N|@^|~޽lζ%f (EQ4MިNyNY\RVع{lzSuQm Z|)K2Y]q+tDA g0[cx<wY6 þ|YxX\&S(nIQqShv\.7:Jե+Wޟ5}hiF>\0o#q&޹FcA_'GGbӛ#/&*";? MQV'|D* n'܃-#؉NXvR*[wt_0ItuqYd}Kaiȁ}nS^4k|?_|@> fy4^=W]R@,t~ࠀ^=ߟѭwϞA,;{æ_`g/|oL~uk7<==>#V;ISg$gKCh@ NQf:`Ww_&+ r]g14U_`\ 4M=qjwKΚ1M `=vYͷW]UkxтCj W^mRشn E=1jۻmL;;s.ސ._dB>Rl$]zm7j7\FQԆM[̝ןK%eBklX[dS^&''ax{y{V;vԉgO0x?Opy8V04+^OG=Mil۾̘^aaS0rNQ:%CQ\ h]͈2$?lCTC5sN۱G0 L$ 9󼞽!j[ BzhbñriJey\ yRp8Dm> V@Bg_,9kPe䙤JV5nT&-8ufϮoLDBaCMl&q,X$2i$wfe)O@Pw SuQ \f(M̆tS&lwsĺ=D&7fHO@Tֈ3fq2ܤjwfe)ORYw LSuE#G5$syvm@ Z Zn:%$ @ 1?szRa+ @ VAi!^j=@ >4@ h8?@ @ Z*?0̆d,&@ Z% >jңa>0ο+9wh0w.M ~h xFҳSp[4~NPƣQ Ҩ0b*CiȠqu<ʽCw'B,#DE .lw,p ?TN`Xi 85_qqC1|Q Ҩ [ q*/W+9eꁵugZ-[gK'=>Y9Νp+mFGe=>i$= ]k70`- e?G\*&'F'N >thةSl5iP$QR&0R~<Q̏,D(nIRd0V@0@`ЂT7h)?+8~[WU <^dl^?`Sd ¸"NF#5(%SZ FCȀ1]` *%{b<1ƳŬ]u` 1 04?ì*IO'e,A9Y$tl^Z܆n=wm⪵6.٩HCW2)/Ȳ:b3/vοiָ#{Ƨj,p ]?j3LE..442F5@  aˣ$aG)I'{U"MTƷy6䤯VrK ϼp0j)G ^ty*f;6qF|pZQD~#0dtқ|Xhqk$=y6 һ1k~t  a[rU ,7wfg^< J7݀Qc#]-} MlVT㓜61҆!Ha ߰fm-QrWMZ `8qqAGc.lbFh]hI2jS0-IC#m@2O:%pEXDo!DcAR ¥Ba|#5K%ìx%!`୹1l)7lBJyy.` )KdN+rϣ4H,ϣEW!ׅKQ6Tq8*e4tZj}ᇓ'O>ym$|@QTqʹKҊYoV_O0aժUp/+Zv̘1oEj֬oVL}j2 sرQH iӦ 4hРe˖P(7o.o޼ [ E֭#G IDAT;u̒iذ!EQ7ٳg``x{n޼H$m8.))i۶mE[:tرc hذa׮]#,, oov-[Lզ㏍50777OO.]*qFFFJRBp?ϳzxxtҥaÆww-[FFF Q!M/.qܮ b}fu|etƍO,͛<fyĉAAABL6sLt~իWW*F#J^jv] uYpaddd .\جY3;>z9s 8֬Y֭[Ϟ=[Rhbʔ)E+(}׮]sOӦMΝ[NZj͙3e˖BJ3gѣWϙ3GP|ܹsU*󁁁o¦츸8a@zw׮]{֬Y۷/]3fh4k___xmqI&>>>*'Ԯ]?ҥVܣGݯՋri8j|qv_e2:4hݺu bΝۼysrrf͚u6jh 9rk׮ׯ_&Mܽ{7==I&MZnݙ3gΝ;#G|wQnݺ=iҤ{Ov۳CQ[  h4/i?qӅ{Fq93fLffO?$FWQ3fXjp_FFFb322j: O?eY6>>SNǏ/ENd///B!Hbbb4iRp\[σ:vx!xʕ+G^|z7!l8nWU&,ˈe_~eƌVoӧmT*5L8py* ڴi#Q* C:tUD"iqz~B!rU8A!B* B!\gB!B 3!B!WEB!B.dСO~ B BD!B< B!\gB!B 3!B!WB! B!BU|!B!g2lPŁBmڰ BBU%k,fN>B!rU8A!BoP(:y$x8`:+i;w55l (_S:@%*9V>qLLCF!TB"2EYQ`:e2_5uI$%*s6J׵koYLCF%|ZgJeii^۷J.Jy7 E+ I8EUϭIIؔ2e*Pnbcp5;-$kwmE潶l46iʉDʋ˻!!Q=ٳ3'sz])0T˓!$4L&l_77$,y-e (Z:$1hZ aF6/ p>*_nd}j XqsK9:u}OZo Iٕ9`~n(?~SXLsYLݏI2mHG}E}(qhv/B9x^n^,Jy*'{_kV'|4Uk;oƚdmM̪҇drTHv ^VӾ#O*OQgqJ8/a2h4&!Qf<&Z{XY]-NO#S:(yN0 2QDe=rE/`]ǣO>3c4tV&Ryy6Bd#,8++t;J<]Q\=OFMHEq8)Xظf-QfeZ L*JK3f y5;h/P6kf^W JB!Dq)oOC01tzihj٢$NKiV_N,޻k m A W0MnDszim""DڨBOv6h<)H e@Xœ$ŜTvA}kj(N]QJ'΋DpKL&kƸ{ 2/+u4M/A{)CRQ6Z(o2T//d"XF,Y S#G"1kFN*7XEd!xNMM{c<'S Mg_7k^CE)(}$!Vulxs6qEA+Ξ16hؙ 'y\oѪڲ%T:n'R99ݵ{xS~36}N"!-f HV*yK\zwx$&4iFy񼧽B 32X)h<qV+%rI}pƠdIsr@ i UbS\v;y<1 +NxxzJPr3׬Mdqq꣇,xqJJY7f88F0ǎm٤>}2V7cǎP\ HV"%IO}WFXX77Zqp_ڨ17'fV,&xL3m)IL^IB2겸ngF6ϴwB 3Y}|Is$wڢL&ChX֫{V;B lN7b5jXu:y"AÌg`>cm),^&cUn iV߲5Oa)ehZrynN]r#Ξ܎ɪ@|1xܦ:{&7YCX0"% WhӮCnK3f NNN,6שKX!\(-JX覼:u)WxoC'N&g SʋX7a#I#qFQ~C !7<ݢٳ+|FӴpX5d9gNt;qH5i.'1aj)(/W9o,uUJV; !V/ynqãYpz7ƹ?vf7mEN0GZ,J?BeBT8( 7k7VtZ͎m[7ikljgrB"ʠ33 $cbs@A#c`8XTL?kaI4/œdJHrI_2DӢ^}@8_&NJe@蛷fn&-f^$ҷi eV3+i4:jQcS'L˴;7% 3љL&ݼAk{b^06l>t/PE2/<_p)<_{ 2ҁ 7 Xm-\'=멜5ZM,k{P99T¨BApy`jGݹ].]sÚG>knٿNBUE SǞ݄B ^֓3Pϓ0l^f3Ogfi:yy{˛` J,(e<ȿDqhYQVu:N,i6`r8Hx,K:=3CW*N"I5l:B3SS8z;;zJ9Z9zT[DhMr<OvMqF'&Z==ˋUS:-/թ !]Dy܍(#CXʓU(iÃ'qz,G f{necgm鯏ghE*G;MALA*$Ւ Io JM'pR)<>8 YDDfӲjwj޻ yԼA@HZ-9'3 'j;wdR7YHgeRFa6V+0@sKݎ^L[V2N{}q,''8ncfOӌ>LƳg23'sry u^N◃Py B!\U ~qŁB$GaIiܯN7 .$k< `GDϔ,@r%7GuɺlhτL_AdV%!T sZ{TgϔIֱH|Y3 }d ڲQq V?yƋEDi]kv/TMc{KR{+_Ws^i2 !9mVBķ.o\8 5s2/W>%{B@r%7GA#j|3xpD4~[9=>! .]U8Y+i<À" SunCI~ED4#={A|&ERď*(;>KY AxmݤxPf6͎m)'+.], ø{hLyj˖G/K/ ogjݏGKGq^,z+ڶ6R}{m[5 ݾh)*p洧 wRc&_9$Կg!T*ps#oO 'm[B$&;u?0dD" IDATǯUA0TtO1e2DR]%e7$巻_ÇqwkWaJSzypba#wqO{!-5k +^&`Y >% C0 `UPza>>Lh^#٬SxݣSO*aJnOO9L%ar$dmU,&_ .p'OQ}zZ]{rhVeU ~)-9T~p.8OW͠?k7w.{ "۽]׻ FZ=z..$iC$~0M׮i ܞݽ'x0T'FZrذ1d o͖?,XۙӶT($䷻_,j:}t#TeT}ܙ|oȅ,/1RF(F|o(>5EV~g2߭dw)ihn|Ev >5:SN"?Yύ4(2#[4/]<Ev{r~ތx&>e /EgbqT~(.$J~j%jB.3dDd?kz\AƏf}}Y,z77>+ԟ;:mFx;u9႟ɺu)%$v<ž?ݯ$x_E='37bSMeek+8Ç>~p/ֳǓ\M]ٹ=!4?L0꛷,YyRb㩪`]Zx {VPdz\=O<=ATIed^^qOOSGn&,ec70 Ys@u,󿯭~Emݾ3)9˩zU#ƌ{m~0;ŏ;|;rɔ|1t:o?dĈ1]pӑcF7lytP1TO?1y/j`W=9UMoO?ݸժYN:h<I@5Ȉfp5 +,i)B'Ydnd_ZΝrEU1o~=Nx.:c $ɗʍT/.?,ĤQ i3cgI̸r5* ١h^Zrr ,ߞr50Wlݾ{Ylv1RZz-ڻ@BbyKWtl/D"Q]=1blhz9Бc_~+~]O֬[4 Idђ%7n y&Ӭsy˗ߟ63Ν{0'OUNcZhkdP%p1$I^tԴI~۟+JHL:m.G_5j8jttV-`RSS\8"Pua;Zmxh-U#GTT3Q`!\&[՗I@DxE S'Džߵm4]! ˲‹m۴8.2YV-|}'unz@WM ir%:H 9}ڻoXhI%M!T\3>z|7EDo޺5|Ƞ'C{yz@=vQ׫!MgJ 5?Ɛ3a\Ø:{e쨑Abķn]6s;)}s};[?N7owq :Yx(4Mߌf,?iJfV˲%J!s?Zzu-Ap?*XqsFf&ݷo^D@D[o@kߞ؛ƍ~cJkc'N:I\~XHo..I?OAŏ˖9{Vj>_/蟍/] >޺0 )O[gOgdTv=}MҩÙs m7o޵}ק׉Sgt:9vG.BH$e>xrNNnfKic"h┩kd2En.wv._~w&U&3 G xL.+ize !T,9ֺesBa۔|hcvm[jԡþtj4jת,MY%&MZtld2d*I?O Y+J07l޸ykiJR}'_0=#d4IҒWv4}}Б#IXGڧF4]u~ᡡۻŨM}WH?s~_B "[Qު|:>:~߷OXhS糳}}}#\AN/_DܽW(!aBSRS/_ڽk]{DFt޺Uߛw`y"[QaɎ-]R@*͖B9}\1p@Sg,VkQ/[>z,[2-=MV}'wr5 T d\(GUOٷ6qt#iW{u:2"\Tɔ7ge _C|ɊjDX,bqApM!g c}zxpsiM~%?{Ւʣp?! bQbh{󦿟X$#^pAtnIIб+{tg}c='] 2tgpJ5;{QbŒ?iy.G%gD4-z~pԟ .OhOՒʓm<,kܝuШAd %MG\M5pwpwսÇ㝿UfwBVX,w\UW2yꇶ5v0LP:VoﴴkP~Hrlه/׵iֳ.V۰iKD0!}wO0+cؐAKG6id4fkZkժYfM:{D"yͱ{RbXT*}grBK{O/ܻ'lMKOnҨX,ؾ=fd˯:wl_Q-kȠZ6ww!.]ٸn@o//D2q6m)]:B/'>sюퟜJ;߻uGH۫ǎ{HS?['0;[ۥSkUawX{ԩ釄Ĥy j#Vf|>MS25kT_ǯV+}{,]:B/X7n8t3/|֥yyx rAvEyyGHw'{`d>v ti9z=jY!L&*p~pԟL4",R|d8KP<{/CKg{#$I ={A8Ejķ2JJKO[KsSxU QM&k$I`D"ZUffo/2$.* /z}FoJfWu9l}\VLVtMrIV(n?87-,_Cr$/+-'sBnj{ƎThd*WՐ;ڤ)b ~wiV6쯁Yt^6.|YIi~<w!Pa0ݻvffƬ/!^..0IL?@IyxLWe"Bbc?=@TB!B%B! B/UTQos_YT v~ !\ƏU=ZeGQzF hk57jPT }toܸ?q̚ӧd^iG1?;u]9T!.~9X-&ecYvm_-j5rh@_ex_aQ&S^V-^9X$_ l!ڶii{KIӋʕ?;/߫ydhSΞСmYVΞРA|4v3+x)R]_Ӧ|)K$ջ!4H/yN<^ջ/fnťRP~ЌiSIX^keˣ(j-[4K<{Ĕ$1rؠ-"d2׮l﷭Z6>lA7m;u-%M/M4g۶ps4)ZF;vJ+oZ6yVdiaճg2+R]3&&lO|۶X k]C\l,v=l=xM~q~V.>=~Il0>o>samO}rvc,}ðKi#[7n_hذ~)K$,Fz&)YxY75X,tɂeℱ[Ϭ(R]K^j\ۡ/UqOfٵIoCtһwJWE\ܝ >lub=u\%T1*Rz>vs6`st36޼sW=DtF4S2ZlѡC[OƖXh<:u|~2EӤq3.Z 0OiٯB~(oA>>xyi֪&T={YAmٺ+""LH߯?ݾs_ߞK/-[vMxNZ>=vsG4 J5'C_:4OJT>4mҰuHۢygxx;u|Ap'mQh,w97((p>m۶Em۴,D*Z5!<(z=v8uEs`t>3\"t^[~2kޕ+1B޹{ߢ>xݢe'O ic>>/~;s•+ .NTU8s*=([_*J9ƍf!pȉ[Ǖ46oߡ{&%&{h?qo IDATɊlujjƲԴy>77Wh~y'%*bbGE]&I2&&'Sko,aBbN}m;8Zz̽Kw-ɔz>Cp+H$Mub@߲Cc ?ǃ /"CfaaxOiSvJ_Bn޺ӯo>Q?֭5""Bu[5Tem}T*sss G]Νy{{6jLdIKϕRRzR'V' ޟ!zYP*B{?)Qдi㈈p6mdJФq[viӹc;!M iڀWuXzw8yқ,vlfŲ +R*d2x>SQϟ56RCIEqwr6 N㳳 OgSǭ{u4n۪5?./|"1)eY$I֨p= `>#Ƕh?8:nݺ gG%$$EDfff֬VU ]̬,JIQԽm3ˏg}:OqWtƣ 履}^^]E"8K7kz0~oQ|[y'/_$1޽7oO8P9=j'Eժ]3Sf[G_snuѳԩлYTǥɤ _XL۽~`!8Kڮݪ-[ MM$IN~{ܶ{>׮ߘ0~>P/pQbm) U( {Bw6GvzЪEDբzzzܿ_i@ |k}m^˲lZ3_&IDYY٥dMP/{ZVpnTV?([-u7שSQz+P9uԚ=e>xԾ]kY|| A~{wpmS*s*R]Ly e[}Fu\ys+V+X\vbz{w߁Qmr;)@zWVFP.NjX+Rm(v}QAJh -r\ݑ OrJ6Bn~aQI/p8/I/G*}c"J<.4=k洗egOZp=xZoq(gs5ֲȶ<]I#Yk^yw8X{s noZawy:kaRtMɌ.}}{ hK/vk^L4DGFϕq l>R| >#ُN>"*UioM.e計АKz2)ܾl…` <ϯYs/qr<M\O-yiJ\\LhhR 4IR.\ԡG}ahFV?:w+?*/Yrx ~"/SDŽ;vIOۋ4B.37~Yoss'_z)ˬ~ B^aT\i1 @( ǥ^lV4j,%ݺSH j~$"T ${6 W^VRB0+jO.6lEviBg͜p7p=xZoQ%%&Z=kZ񲲲Ȉv>Ofw:Op 4V-ᄏfa]tEd2orRRwF9\p}!oLձc¯oKv65E%9_o,}W+ɛ@A6-I |H}&`R(T)kޣ:-seA3k,5u/VT,BohO\CtO-7/?88( @oԤ;ҽ[```^~;'M/xS2>ᲲrVcud&!DזorҎg;/ݥ ^sBP]?#wF0ѣG?7~ru;^(~ݏ}p;3˿❼YK.+4UPk/?ý.DE2²T\(c;IBC(g\gmCUft:KC$65 $$$i/=7B_H%%%tA*eU})qEXd &Re{4mxM^ ̙=fͽxrmu[-/p8>[G7-^WRRǝv]ɍJ{۽@"tܷ/ {{~LJT΅z!}֌:yǥ^oUřN5Sᆴ}}aop^oe[n7ф EqR 4ɓR(=ĴӴ=|Nn~A;+cŅ=RIs-9f9{YogϏy}O$}GԯoА>$t];q/1QFcL&4[mZ/lSN6d2 7 kLnNjƊA-ͽxt}C;E04=j=bx2w|QQ#sU qrk#X㹏>˰lpPGf6mgqco,zO=}|!5̾ȈC+~<)qݚY0O~A/2 =buC$%5//{gPgeE1_АG+##ý<*/߸z-We2Y>=?{㦯lv;pH=]:wL?~dwKJtZͿF:L[m~%/h>.pd{G#otj_ST ǩӎ:CBs/$<&)14jjgnikъUΙ9%eX۴4ݖfLVx7xs=)=// /J{sDDoI/i<8 ӹo.8~R_i{^O| ['xyTNs'^g?p;ԃG8er<\zLYԃޞs2tn] zLXeץLJ/h>.#F^k{ʬ5ݼy')G6P]f ,e^lv'i5n[X8o.b!@?UQ&" A7ZcEAh8׸x+*L1[JDmp [7~k(rޟ>R'~Gg%$I_uvC[ {m*ݻ\Ѯi_pe !fȺeB!g\UZ0tpYZS5\o ]o(kB!'p$q++E\Lu#\'^ZjꘘgL}qQ/ !ode"G O[ǥ^+UJv -ue?վ J?<|Z+ɫ -0_J6Wc{z 72zYeFͻm? 9]vwiz DEGNZ~Թ6pFՒ5ߞ|q}+*L̡oVQF6~euOB2V2lؐs<߇hݧ_428.59z,!]bBSO={dllLE \*M1GFF!L7`Ȑv8s.8.^˯;H3ѭ]P}БtA!>8}Ì2e~|5Z;B!j?B!j?sI鬃-\p!w:&uN~}j ??SU1Q(qwP7q-voEo2=teg?ٰ^pޓwh}ڲS>$}# ^Kh,xh.[V[|Bͷɟm2)x䳍Kd}Wq|koY5i_0HWH7}_z);U3O{v^.)+6?C:u;uC N{oSHx[6O((ad2VWWWI;֯O/\Dvtsw11+*?!!!I:VO^!RpjjĎNι@jlLtr7 ҏ н[r{VQaڻHٵ(RH?veNBCERi{57sUNS(?M_<4sT]6|YG5<<< ix?c9*RP7AxDC8pJqF3%îV靓s$<,,$8Sݺw~3Y` HOec#VӧW/Ry)ؿo3Y߯ ǎozkEaa)ݻQJ?~,s=Sz ?@.p-ۻWHptOtrI:]~}Z\񴽚V2W̺U4M/)-m* t[o^T*;Qw~Qp:E)VW<  6u쒒g~M׵HPԛ ((pMX5~{хܢ z{ h4%z?[M'o t/Eb Ԋ,Kʼn2c,$4,xu:o^oJSyE4,*.o9[j[t{o.?Ͽ >2{óŗKKkqaa<ϏZe@(UJz IDATL&N 29;ĩSa2_I@8%ߵ챱LY8VURv܅ y ,,!!9[ΖT*=ѧI :~EQEE+V`ͺIw;QZ,ð&*2o_J:'&DGTp8N6mŪu_/Zr$-]:dku:Jꖄ;qpT*]{ťee=7yaM}{fϛ8%v}'{8BLC$u^1 ȬŰ7Gx872Y-vK=xIןg?Lvv΅ ~-f+0 2LP(yAOL.r2WUԸ%%%!!]dCjG-K hiE>oiMJ=tH=_%$f˯6LXJ .ļ`m箔&NRiQ`z\o<_{knk?wy_|iYEV^zUJm,?}}(KH3&:jNn~M#tmuy{OW3h4p/Xm R56Oj.@BHÞ2 3kJ((:l8j~' /^c롙DA4nzNgl4]m/8aV j FkLr\ZC(@` Oz2.sI(@T/ǭcWDj|¤jgI#*R4_MTV.Z)cYV[^Nm/h4 C7,R(b\av -ueӸ?qe97<}TzHT^Q/>Y%t,V{El%^z*Y9kw cxI/ѝɢ}.} tޅg33x108`7[9Z+BmZg;n)91,H'&YQ{ipR]L;%$7,cؤ]PІ\ qN,5O|4OiK}66vK$Di""EIպ3ÆJS9RYP^<ȑ:C=8BiD)A"V2744áZ?Zj0(TKUF~Z!GDՋ֨5ƪ86a暣(+sڇ@[֣Y,k @+mVxkVk-0PYRX,Z + Qe5ʡY}fF;ψ4m h<;(KJZH8BKz\ x*3eyLH^HhcV+G %zs% 9\S[ ]p5ǩՙ#vN[c=(ȡ{J**e54W*ycGyE%Rz(k_!%&(`vβMe:FSa;хyfڬVd[Xǜ*&W4}"sⅳ#tm3ע⁃BIܴI#$fg.M)lU|>3#PFK2\0L_}%R9Ա!^%>ީ˯A,w,KȒK33<YR)]ݫg_(.Vi~p%1b GTKtǏTru5= ^8|DEwo> ]D+9(2Y3jsf_6Mcڗ{'%B(4|bK/BNHܰiݕqG/վk>^(m!nIu~GSoaOmz/]6{iH68B!B!Vp1 B!_5f\B!^A!BU؟A!BUx2j1ct ;sƿ(n69&sYrno̞=pۥBHc֏K#ק{9}ۥqqq&==ʃj}.Mhiv?؟4=iҤs}yyy>qDe#YRR2zFw 2aRi67lpAd4M2wܹ /('NX~cy ,N2eĈ<ϧ~I|Z>ywBN3L&LXlY9鍷zkhhhvB!W҄r>_΢ Ǜ]ƏSO=ĉ]rO>I7gϞ=tPqqq#?w'N|饗f͚nݺ{L: rڴiӧOcbbO26mZXX?`{z_קO Cv]},Y^Ч !va]{=n~V;+>s-޽mۜN'ڵ믿)))q\vvvIIZڵkZZBy=rssʼ|VٳF9|paa!BMj*Ǘ,Y#W))) "--{^҇fff&%%EGGgdd={Sy$=z())̔ Z$B~~w}7eʔ˖'$$K.SN͟7xV@@@@llѣG{l6[o;HMQϞ=YٳgnnnFF}{- ))))))6l {5 w'O"sPZZJv]Bm/|/S>j3ע'O7.88Xzѣ_~(ѣO>AAA`gϞ(Q* ,(o{N\\K/h.]ګW/0 ѣdYYYR|}&%%-_w)}^NhѢ+<<|… zZmΝh:tcǼ{/]hрV]hԩSEo _xVE1..Rc)))#qС… ]4M?|Ͷm --zǤOLLܲeg}}yy4+ƍٳF7d&00ܹsyyIc333'Mo>6mZYYٻ+Fǎ[Rqqq>uaaau---׿x1bi}z^6 Z-ӓ붋 Rs >~ϯZjnWUa}im_/hvcx}Zʕ+}Y/z뭮E jKm۶~iZ.$$RoPPb;ൢh4z*NsfgAڪgϮ]~;>}̜93;;ƕRT(n2z̛oR 8k0 x^y{- //鍊nZjUqq]wUkh_y.vK{=n~A+̵H&/gΜ z4M=SN5G>pqq1EQ۶mweII {w$??_ P˲lppkBC7Sy Zc4~ju:*Sy œO> /HFEEIzkjj*++;wv+Vdgg/]tƌk֬s%&&Jd]tO=})i<Ӌ=z:upe\VvAiؾ}mivc8#ɖ.]ڳgO^oasIKʂ:w̲A\:|\.8q=Ͷw_l4 lڴiƌaaalٲGN>]r„ ΝrSQQqԩiӦQh瞆ӦMX,NNdҹ\>uTע-[L^j?xvv6^^I^^^FF$==Jj}޾㶯W]-΢v \s7|3k,F|ee嫯#2;;{߾}K, l߾oLKKse3tUPO85kf͚bŊJJ~z)oR^y啪*6m$}yիWKcyZ=Sy>yYplܸcǎ1:((hÆ q\FFҥKrnS\\_/]4''G޽K.R[nU(ʔ[nW~{޼yyyyǏg̘rJ~mtӓ<ל3Ґ / 6m4i,u>}VZ~ivAQؾxo_8km_ۯjg y7on"hMkj :uI?˲u\t(<*{041 ^HJ2((m>EםlrnD.t[v{y)gC׉.On+Oؾ\}xj_q'~lgQQ}yҭ[AtM~kEt텮6ؾ Ox%PӸo.㸡CrtRA !VJ!g!/!}ф!B 3!B 3!B 3!B 3!B 3!B 3!BH!B6d^`!Ps!Psi"B!< B!* B!* B!* B!* B!* B!*Ipw!P[__y&LB'cR B!* B!*ƛ! -"D" J>bdTWǖ˴|џ? BGR"2-D.2uV`⸒D傇,ܻ0ӡWib,0BmgU!x`u-B؊UgV7 D*U1rVJZenL Z&:[)F0QM":И\CX$UA!I^MO!ΘqD[sȑ [kDJ HQ Ң+œՔwPUJ'1c+fݐM_\eTn &`*y'9*\&%N+9zԼgbn0$՘s WdTa;(4g?ZQCzBqKA|E(#*!+MU@Ʉ9E*&{CPnO; )6us eN3LM,걥 Y:$ {):L(bļf-?Bm gP+#}{9 seɎ)3#7r5HWKYS;ez^fpJdh5yCjQF-tArԻZ$$ B8$<]Mn 嬬mf7Q@ylX&V#TPR"NRqDmɗըc2QIVbVʨs<՗Uuab*T\l"jD\( iN2̩pt{*ΌHWJE нFW2ab2IDs\m!8 U~Te9>y+҃jBRF'N/N{9|Fa/gFi)j;T^Η h Z$2`XPtjХFo*eɑZAH %0P' IDATacux+]q\eɑɍNcO)C(EӔk(CMlT rS,(l"3)8J F.#ƌ-'r>d9gdFd ^ŨxQ$*1iiF1%U41ڔ>2nB)-x! >:UUG;.&X'%قKS}B2B -.7r?Uy'Q:ˏ ~uQ9?O([ P:O;*Y~LU6RC䲊@'52-;hSwY XO~K #H;)ޣ.wV;* SJ Iֳ_vBD`#Ei;SR's[_KyQG;>P\_[&WF-?f42AISˏa2 -#@P_K(& %oe!NUw2A8JNie \m-dy(]MFt ͼdE{ڽ(((pDt"Q o'%4@j dRj$g\Yp*9c,dE)٣yh@JT!fKzpޔl)B* 8 8N3#sc+ttjhшr#ODNP9i(EI9C!pD3LA|J7xW\ g! wV @͕pqd52 ^% 2Рpp6JWCykMnLuа&}'kKO;؟AVJA:AUyJidoe ]jƗQr"O((Jn#8@T9*ɥ|n)ChQftg".= @/nvTѢplrS'@mE X=穾3"n0tSYM>_B]Uo $])wPN UyRu@AX5("%@H@D gE{Yhm]҄"8Qy'L < !P{AKV`.nbL`u"BQ+2r;3 v#WX <)=.;b|HSS"O\o-wYzD6WΖ A=k?TVdo k|svc`}n5}_Ȳ> =7[" 01YfB0)ة;, -V`[@+z|I]e <<| `Be^njTUk]G[ܤR?Wq˲7US\DT;㧔ϵT_c2քHC>aJk !Iy{Ozy =>;qF䈽‡[joK1.ۓM'#j(ƇY(΂JBrC_޴siåGKQ+۶vU-\ͦ>,ͫ4#a4It(Yȋ+6!e% k YQ%en-HӾ45>x5_z`t+iEq?eorq FAg 0+D`3&Adյÿ"ÿ"{v&+nFB,vx„_ ׷!r> !p{=nE$}IZQcݗ Ns71BG?=rbΡ$=WWH5|~-OQi hLUivК/=v0nZ˕k8ii'$dǀskBp׺f`oۢ SSy-+btOn j^%_Ee &̭wI~ֹyAy+:HBG^ #q&0qM|e46u zxҗlFYFoy_ KBS4^;h͗;j7$ڗ\_Fc%PgR"ȍ_`JdEa%XiSL T ,xm&I /ȉŚvp:xu%;!i 1I/q6DiXV4 xu \c28P'0V24V;h͗}+r2|qSJ渕BJqq&iݬ`;,\ƥFo}:dL+wftX+_zъZ8 X~}&g:iXjy}b3NIMrޢGV (!I`>BY9J'Wګy3 `PZKfRdT PЪLJj>*YL.ivЕ/=hEO| DIi>TDcgcb eP^Z&m}Ie6o51$<h;I^woKZH:I;FH" zӺm=`S51q4V;/zʕKK4^ph'3*14 SO<#(0+J+D4sOlUum)yx ȗoi [v'mXF8=0iۢ,Ym ͹q\>K>'r%JJL-G[3:Пt z.'_^Ddĸn)yk ZzVge ,xh9<;6$"\'r|{lm@>ZeaW>UVx\UU 3[ol~vG6"!#^ *?xAv5>gVe,U䩍n@ցs("6eeE )mV,XnFGjRSjwUqaF @WX؂wW20jˎpo"F@QM Ểw ^`tl>xw%E(0]4V;ʗ$~r@ JQB6eQhQ.=Kg;˨fC[1N#sjNZ(|dEhT4J$xa%AqT"ƠKj]2Tį\D0]Y+w6bO0e&c1a任J5OkwB>؎)$N5t~n Nmht6xt SbUVÄq~/}Uv3wR>-G4`r@ EHҨmXyG>+h²IߒK{Usfq)+|!EtAA)%m4Ye`V.}؊PűvL}^"~N3[\O΃JgK3FiBi͗;!v˻0ENuȑaÆ鏺:=UR%s0rI;Iob(P=hh|v/=W1nj2t`id~0\@`݂ IR-}g7Fb$w$0  ;og*c@|=|8KϘ2XVu!g Vw t'k{! DXg*s@ >HcZ:ݣ5;jQA$ U+V/.]FE|鱃qvC Am4@ Pi3׷ ojEbJF}@ ڂg@ DCg@ DC1gzniiC  sghaDc3ůk?57;'4>T*]{F;hg]Jk7n IRv:D?0tcO{rе7F;|ԗ^@ WfL^t.NOA'Ow9=ܛTڹ@PFvpj}_GcUڹ?{n]k#G >@@ ,*H]z|/LV%Jݷgpڍ= \lŪ#_ Osr|fϘ?{7.-i\Xr9{7v-B#a۲̾DUc֣[WK i_s̸I$@}9WPA,k>S8;%%%oؼaÚs@hpF_۰炢'O㌐#&3?ٙ칌|ںddf/\Lo>WTO}ߗ) Hn߽/5Ѣhrҕs/ef^Owd2 ^=.?y̕7 .wr4jBqqèw,觃,,,[&p,tں4qs{7Jg' :"4xUmY7Gtw}ztsuV -[\~ST*//[]" 8(0c'GG_A=`cc:"]hHH?ڶsϬy?p0+;{3Y,ֺMHK_F$D̜0)9իYܼ}~2cjBu訦BU](*ݻ8GE?wa^~ENڳ2g̝/*7Ril| illm߳<%Py@Ԝ];TIIIXhFضuĔ6yg#]]\VE.ϝ93?ǂYR <,lӺU~>>^^׮ء~2cj=|PMwEVS_ZEwhߞ ڶvt鲃V{Vuk1)Ily+cxgMڮm:ʘDWNz1Ob eė/ 6>0g IDAT~ib=O0vL2۵w{vܸu{ߟ4\vkjA=)|}a-޻2f~|E |}98)8ۋJE**w#͜gV[f3@ 72:wރGeeo_U,4?֝{"ݸѻgwJ`0,,8ҢǔJ*U :`̽;2fMT*T]]Z 1Ocg[8uԙC 'R_JR+K8Lfs@ jwX_PpڍvmZYZY&vVP>u\|>t¥+\TKzxD l+՟ Jz)ʝ[7t&aKU뱃V{@XhȦ~ݱ1uf@Z^~#@ϦMNi ozmAa\f wza\v-;'g9T*^q>TP77:jBC/^ҿoߨ93S{ne%a$`c93?ь ";vptpLb1c4lSڵd0 ƙsO` Z$) !нkWg_7ѭKgQA*JܼO{~وPvm[zZ˔2$12&3+kMΜ߼nwf*1A=`@~Ϟt'wP*cbcbJe>lۑ_s~g<0L %Iڍ[?.]o>{ᢦ?k!透n۹GYYYT*a-Roܺ]W0/ ɬyB?ToA=͛3ٛn;ksX?| L&Ǜb )LzAkku^=mVr|oEIJD% +/~ݱ bʌc9R|P{ 7X;XL gŲ^Y娖JJDoق6$%%P.ؽw{NpP`yyy’aIɹ=<=G,kWc^HIL&+fNgv&mϱɯ^QAL&Kd$k\Q..^c.Uji i6ښ?|O(#Ǽ=X,֤c=n0i3W_ffwy%jϺ.pߧ3ZU4RF>rʌ^BaIcw&96m%tM Xf}OdgcX۷ԡCmd\XqvvYqJmu]";gd;w^=#]\fZ&]qOԞu]q܅OySH㯃6oHy*X_v#$אP(8{7JhTAX+HTZZEUnM.RvPLWt@  JWn*j%’V@ >,@&+OzCrMk4շH: @ ԟA @  ԟA >t33+0?<+gR3=CvC b/\][ a>ޞB6uoP4ռf3$cwA)/ Zivb$I4IIkm% BEtƴZDFZ>rărG&_|6թjyRY?lYG IbЁڷPyy$n}KV ЧUDZd-?ܹR37< q(IHHs]ϝ_PTǯKu\>}>88W(-ȢBY&ܭp:g]xW~~>NpӔ*_Pyi"x1s}'8yQZd-ڶ q㎩R37m۴JHH,q*El3]|޶Z/sݿGqqM;dfkHB\ Ob-ǐw_J-lH #=kڱᣘ3g/,[Ioߴիܽ3gLo\P)?XRo޲񓟍 /=Y53Bn-Z\xm'}i3T2ԙn(_޼ie2qB]gV^fYﵫq"A>gTkzw9`OUh)Ff$))y¤٭[{鲟M~g{-X }VCܴy{}+߯7t:mC8p:U) _H2BnOsҜD=1uL&g\TܵB'Ku\erĮ{ #ƒ,plȐDF\g v~d?tYY7n)*.>׮NJJ6U3%kdtzdv_OH]%&&TSXX*5nP/sԨ\@i芣O:7b`'G{'G_S'7?9{u3ZyX⬆ؚ_D4uˉA@\{ 11ᣘ¢ E׮NH|&/҇bfNuSO8s}By&r,!7xlTe4e)-뢵y&.DgB^rZciiѦMxlml4А\FеKG??_}#yQ JRݼu-;);k7ql<=& ٳ?,KBO>sܼܼɩ8?~oߞ9i>}IT/k--C슳,,,Bj~-kk~hHs:sfFwVavv"v&/|^Va-CNu}|<סC[ѡ}&%ebk NV]!$ ?skMKXY>U{A/vytLl˔o-$g.kܾcl" fK]vj{=yIIO޽?4Mc+Dbee$Ax2^UPPy"AʍЧEh W^egtؖ*7m -rF"P7w91(}{x\¢7]g/֮ߒ:c_^E KEN{\vFѮ߼;e=TR<ϐF+-e9V޲xط0* 0SHOO[%-ZS_ﹳz4m`Y_ڀHHLoMOS鲃VkתE vZk۪SWj$ `8֬_Xֵm`?ʍzwpquu>%Ug͜"vӧᅜ|7ʊʾˉA@pp0 Blt 77gG&sL֥%!!A~ܳg\W.S&}VD߶em@SʍTRlh.'5O)+4~*ٞF{*˨jx]n* $T!)M昰^X346?Eq%t݂ BDS+peM\_M{hJ|&5h3FZ޵o/W?-_wnRӨU( ![! ΢<{t:nei9}ڄm+.ʤre8egez_z_Qs ͚xG,~6w9yOP7jHȪץF0,6SoaznkLZfgTRrܡ9oE=_o1$I`mb KCk~dU!+.'' G/Z8ȑ%:A\] BEpP`lܳ"WF'M&Z9 AF".]=un̏$IHlkgghBB{5V9rNhPWMHx*Ukk0w9yw\d0MG iUPb6h`-[:B\j]Z/F.Y߸|+VkJ)l Z^\p66e啧@%"WW h4vrsvc媍Æ ,y얙moo'⟇7n~l3=\TTlŵ x" 0>[TXhhbczF=<8^i;|ҫW7jIIӧX,Rn:wg^$N>m܈a,4>օܬQ؈\;1:63fH(L+GiiL&ӌ:;;KŚT* ku $x{{rVz&u ñ&n/] j,$$(:& I+۶gC4ԣ ۷'$:1tCFaXKhrr'~5b?irU*!͛7uʸ'hznڽFYI,soC./Z-TgٚQۜ<.?3 ;[ڤ@xTXg1.իgg/bcÂq Kͮ}2eWY98(iJK_PP I_/ZTkN5޾Ϳr=BLs/F5 !={X*8ym{jꥺy'1v۟ɸh=! Dʋ@-X@cVȐyYLF5NN?L ;~Ź'R~ʧ(_%WTn뱛իW>Q(qn^WGR?5cNO,.*ׯqr~^q ŕ+7jsLwbr)*&LQ*D}bi4<=#6NIrHLy'c,82ⶑ ?@ў,͂S_8^](꼼[Xp|= :i]O>`N:޸E 1{|ޜSe7/ϦQQO3\]]](S粳s&NET] F69,i]tԎ`T_ǏYjya8W.)^$YGa7mwuusTˉӽue?f2ᡭZԳ9{@B̓㾈wnO3߸g/%"B^PPZ}x.UMKeO_x|Y5G^ZP^zK$cB-̨MVkvP/&Xˢ(+#ghn]S^.MNI=s&{'Or5*h믻۴֠Q*'NjB-*uDD ̾윬:C=1>..;o~pl܄JhgTko߼u`T_;w[pֺ?^M1 #ݳfNsTˉ755ᣘ/P(QO=zǹNdvf!ܞ/7XYLmXӊu0a!KVs륺yLFn|i*ަG6lM[UI1$ySKOL&WT\+-V%ee*O&T 殊޵I@_'§ LNĻ+ ]\(Y[jrHh AgT-'z_fvBzz֞Pq%I,1}'%xɓIjuP/Klv YG2tj1E`eլAHLftXeߪ%Nk beiIYsWE 0oq§ 6+ ]\ Na89LR,uM[N<\+KLnƎZCٗm\{ IDATb]))W.^ޞwV^2sͱdjAlC>7,9&lM'T0WccBsX-B5LJɬs=Vk?(7xy5hFt7 _jqQ0:\7=r5L&I@1ƧoLhBT躿B)Ti*5irj'&йsW^6U*Uff/2kZK~  ~|=gϞr΃3 &~XYU"եD INIݰa[mZjP(3J˚ϿpjVv#_iin@ձI}@ ?MGv,A D !e2E&<[C_;@ @ .?@ @ *?󆤗)1y 'n?_{  ?#/x`!p wiw f?NdIHV^sVΛuFZxsS9hgK/jl֫jk7nt8[ܼ}秕5?CB׮~ƍ{$11=u1T@ jR/S˱{\MMh[_!uκe3|>p_]0!8;6Xb哧qfvڹbЬZՆȎ[@366nޢ];w8n w5MCi3\ƛl=,.}q y_x$y{†t '7/>1bPXrCNU?,39TT,V|&˗Xu}fUJ]DzUqcQ}ECmUe̴m6Iy"(\/[a. 0ɹJ4Gn8tQXhCGJ6:oldt\^#߻ X|YU%|~J$*48hW/Z mXsAQ!W4T@|?cGX{ 8?"$'p '7ǙLBәL%H$Ob[i|FE?vwo`o_PؼY@^n Ba[*b$:&F* s||*GQM77fLNnnl3$w.|뱛P(\E=/( ё >|%KZjG27RfWmyc)u?1T@ j$%Ig4Ygi)3.DgBR]r B /*JPRr++!Ac4V#[g8;99={ԼWӦqϞLN y '$˵  p8яc (a눈 :ugό[=g +_z&۶nb25A- 8(PT%Lˣ<^V\G4_㕊Ke2Y#ؽRχ'% :'$[k^^8$tMZirt˨?ڶsϬy?p0+;{3@(,y(zߟN:]9Ĥqݹ 6I?xD^.{jw?\|d 113.LJN~*uּ7oߡKn_N%oڭwRGQwq<*+I/SΘQ*O5 ;_T,V7o̹\JHmg=yK:h-L +oYI<HGKn*rܙ3S?-8?.Nm:bq<곑..VuVcl'+'gڄݱmVGbR_U?Ыv-aaܸ֭vud\WtۛoΛ6y"%oޡ}{ "[kѡb<ܛܭ׷iUag]\:ٱ8;9QBCCBѱEh@dK8 D:P^,4(JXęٸT$]nakM F޽O;"?uttBG 1)Ily+_iӄ_vv]z̍T|:.W( ڴj_PtzBܺiݸIӊjAr{;:ј[?/pU\Q- ZUfpQbs9L8h+D/ER}b@x/_S߾kOH b ]2(a-Bioof#x dU\h윜윜џ0 2!M*Jdm2r$H$^kLP(ttt4T^yA  +}ιϽo#ư (ȿ-Mac0b. ˋyW;"<ڍ[LJUD%2b}jB`0L{]Юm՘ݻ`itˠ<5vbAA93uD&fWqQ`ggV\] IVj~LHFff^~ń\ |9y̓q yeyJ|V?WBzYLCU.h4&d2|,ư!g'g&q(%4V Tx XzEtRZUgLWZ*H$y7eddY[mʳ0ptpH2uaQ{=;whK8v9|E  AYA3ͥhNպ^64bPYp8jZ+ʤ\yP*P9abSXV4rIIlUesy< M>? sByMp؝;uڲm'UQ{57Z&b_#Z6$%%P.ؽwT|C8EZHnv*^Y8˙|5$P=rr#51g=&3++*icF'zaR5k5ɤlIL>a?EH05$.--//tK LFHJe7nݚ>e"5dgkKhGϙ54 Qzw1ooO{;;5iGS #&rۀP*)xv&}R?hOfqNM>u\xmHRf}ݩC{X`kprt\hfؾ0sBMNN?9elo/O{αF:yeȎV^'-n/~>;L5bul߶S4mi7mh[ltml+W_8~BJ%SzF樱 zz899"zӡE h,e͊Iq%A Tc,MA]_58^=LpmZ˭;w`5̛sПJ27/o՚a¦7S㯃6oHy*X_v#$H'vE Y,.i/I7oٲq\.};wjM[̜v?\K_w]kˁC,Z (ܛ߻ST9#G ?ʋe4VUJ$ɰ @a4M'R#!I$IC0*}>^Nk^.b{{D$AZ[Yp8UI+JXlccwLD"Q/BmiYqCD#Ʀz}5y ^%VIqBQYZV%BbJ5S"8SQU*ծk$k%L<.NݚYw 0+)i *Jd2V\nqqFb2VVVt:]96j)G Qyr.tMPԪ1ObEbaɹ Q9HkZx\nmU',8*~Ls &Q3/SQyUe8>d #2!^JnX>o#ӻq*iTKX\[ ==r1#*-5(HTV̀TTvUTLCćF]{LWt@  JWn*j%’V@ gn5 2v+ԏh{E)۷׸"dٙ@ @ g@ DCg>\H4`=n`QO?cq (DNUvVE>p$ '-/4 4eڕC﹨,/H^xͽGħ$ "G#! 7*SFhTxkRkUűo A>t %g3@ 44_z(q5-b_1vZD񴍞SPR5#A݀2 tL$oCX_0wrg30i0p+F̲d}4GE*{f[JS)KX^dևoSdKNWE16 ΓDOM+G  Dl)`aR F\8!("9W$f)B;>2}3e{˦FHB PBi"Olg׳T XPDz ilO1<ߏ;xRE˴-J]IGaWv/.9MBkyFk5TU4ap-"xNB5R̜Exרo?3B#%ZyNj,O2[e$Ͳ&Q_vBr#X)Y΋m Z1 c+3K,`O*Y$Ξ, k_v4؟?TF:f9%ah]3U9տ *%x`tHb}>C~D~ ҃]LXTC0~d!9 9쉧Dy*%X>KGhFj2$X&9uRXJPU:B KAé@bd9m+]< ׈r&Y -\-H *SfQWL8eġ6=,tӮYq;R$D4HJƨb[mRN:10uJEE3n==tQb+U:B }nz#.z2{ KWX7W_}3"B!F3!+@!\3!B 3!B $CpX8}={"Iw/Hz HVOU{˥QQQJ277wB Eþ}Q^k L gEp O?q,:uj^^NAQQQSSӂ bbby~6me2`/O:շ5M[o=3,<ܜl>gʔ).WD7tӜ9sX=y䧟~j4=ojܹK.U*~ܽ{Vz}tt_xI&eee[q]#aҕ}~Qk Ǜ g˖-x衇뮃X±H"<nJ?)++hll~WX~}'nNjժ[nerijjժ=={__|qժU6mz}||)60+ +{k׮أ !tųvi6X/pc;x𠐞$X)--mjjR( 999--jRRRRJefff}}=jժ 69sfڵ IDATB~B$JsrrSBU\oMM̙3 )))))/ pjǏ_[[/xyy@sssII#sK/tm_FyϯG\3Y~~^'Gs]w]PPГO>.2e3s yŠ5k֨T*磢Ξ=+()) k|'f)00P;vli=Kwꐐ7nJrnx{lܹBFIIIYt… xB҇틐e2=mל dyhH3W_}P(^{cǎ}uuuB>jԨw}בa={̛7̙30nܸίȑ#P\\|7fff\{~رcyw0dcbb6o_?.n֗^zIxkMIIvk4S^^;xGyD\TTt 7;v VZ[o ˫ڹPQQQ>,  lnnvlssF~ yꩧX3gCBB:wzruuu B"7ι]5j|ٻv 6x^^^A<<ǃa}iힶk0H/pƲ裏_|qŎERl6wʿcǎ'T*:upqGTFEE)Yf͚5+ ""B"43ɔ HYe5c6geee@@H$ٳg[nݺu=wkۛ.ܤ$J&߳gss<K/ڗvia uuuΝ;׬Ys1&D"z㪩̙3fڹsgrrG}a:#6mvODgFy`k[[篭4F]~kjjZرcϜ9zp6i=K:99fl6?p+Jeu:/+رck׮Z'O<~p8nΝqlNHHJ~zow}W?\ȿk.\K/$_ w~>3kwww{<ȇ~hپѣG b__/),,\npe<6mZn]eeF9tИ1coٲE* )Hl)7xG9ş~za7x~"IrA.c%?U 5@;x.1$PUȄbJ,,UX 8K H麑3-1) Pl& А44I~X]CNKO {vc+Mٍi)AU E Mfr8I% rrDXU^Uz9gByV/i:MQLHC5G.Z eƬڎZozcÑB@2Z< lF|GsVB9lj@LB!roX^ebLQvk{2@LJk:jluy$\-63VKEBhHx.1Bgi$/ ,Bgh7VjmH UFƤMv1jLZ&RAaeUHTkdLe S$xF_K~k45v؍JXhR$Ʌ@ $IMbR Z -5D' bnPKT:L+g6Զ[bE:LNXojXocm! _w]^ kWZt2,L-^ğ4Ȕbs<ꅔQ!@05x2IR֎puXOSbR4> Hg)V)#x6ÌЩ4)[aXGj]W+v،jem`f--V9- T)D @#,[jfʶ{x@T AMұ^2Ktx81-#&^Q;w(4%YoᚣƺAE$mX)9QwB+պ,T;'l6Am@E(Mt<1W:lbRLFR"CH1"Ee{e~k4gh⁧byVBK쌭 5bՁCv;N t6KRRR %%sh7o 7hQ 缥:c}I[iWdr/Ga 2Xpv c麨Դts67.ڬ43ZsLbc9;YwPL T[?+Y3L6Ih1^Q&HQgY]HlT(ѕB¬-+k]j*֕'< 6kہC^Qq^\7Bne-z@a~\oGKo3ФHJK.]$H1)jhn:='NB%$PP+Q`eP`3$9/%\Zk?UӘ?aJ6fe,"ٔt(]Xj. ]+o),Wq)If Jz;A@_rWte{'8yZ++l=[+TG?岼bZhfLeyL  u4(&$4c}H)1e4dm]-VI5R$j13fU,Ii^ W)"( H'b,4,3 cPS!.QjxMr\*&cԟ yVnmVvy wgb4ԫ1i˳M&@E- X)t,EJKYƤ* o+B6!p|~K#5G_PSB4='WbJ,+DDDIOT Iz:\9nRIѲHMd2]ڦkĪS8IC)/`3%?"o,:u< Ǹ,/i" lY{&3@!MD|ŤdCn6hlva98g3B]Ī@Ejm:#XVI\C>bw^.d-|>_~K F-8h(oSQycyxWƜhȘ8!Xx}uגx HTGDj"l-`[H$;=jbc'k;j/H9QQ^[6 fKz#Gk  7 L I'\ Sg5@!ɧ`9rܡqe˖yz% 䴌yh˳&Õ3 e93bδhIeЋ! s61%R;ks9[W+$bRll}FB|&Ӿlz΄Ehevn) gZ۝ 0KM^c܌5s6k0V1%^ w嵲VkS}#NY9}3RIm=+\x'=A7{\XjkeؓA! pE "E"IJu;z wMLw]y%{2蒂 B!6X}ŁBhȹ`n>BႃB!PB!PrxPK-~r|1X zGh6eT.pƒ:-,Վ_I|z=oofu˱$I^87!(`xsBN%*y\$v̫;˰„~Jg;{J6e0u7)};޿)}iWXy֘\#zdySοűCDNl]sWF\)\G:Xs͹Ud2bF1{?BGՇvc>O 5 %J!| UU2Zvը+ 4Nԝ&$HO SR$2mc}ƌM e2hڹwڅkG_rΪ~Tj:FpUh6fw^f,ӕve՝6ͽ:\srix`փry՛*X4)x▒Fkɯ24~AMZ:ZC~3%픾 aٟ۔z~)ñwEPzaoёoNz [ttk ZvՌѓ2~ ?S$.x;kߖIO;}>&XNuQZU\97s,~yݜhퟸK<ö\C=\W4R1j"~P ܻ@h(וwJllȚ6\~)I?\HM:mgnH%R;Ó9RPZSB&Yt-`&ԀUH!Y%m:X_(75P -yݜhH3le'|fO\~Ka)*?cj M 4v4-mL^$ c!BD||q}Y^ʭ)LLUe-cK*H C.NM<ó I ?=]B`FE<7O淙X=][~~>ʼnsFn9Z]9d#ScyNuRq+vd}KO_pOW{8,2WAh̄_)ןm24_>v0-f{;=f0X Xnu<̏yLmѲ /ȫ;Yu9Xӭ}C<õ\K-Sy ]+A 4u%u3æ;+Z#Qg4d p G-o.Q bn69-u<d7f//7!W9a3@*$+vQ! zpY.9N.?t9f@hfvL:".{M-U&+< |trTeqjپ;5l0'cUkibR,O Mh66w ܫgփr4w>BB.&PƋ\5c.՗ A͏.cIh.f6C\xWcfsXXK\-V%Ъ 3\]zOw;WNecA]1Co%MFW0-f[{>f3f"HD|5{mvlzvM u(QBplfՙ`/O#w#Iο]<@ryIGwޝqգ8B}&&p[})bJ-NK<ݜW+ܭtFo՟iɟ&!Yˁ3QЄW4˳UhMdeqKM{Yl<]z'B޹+7.[sM~ ;]v"l2Q΅;3yB!W vjC@!t B!Bh B!BhL)h!Hts֣y##"; 0h:}W~30 ߰j_SH=]'?h6[..K^_+\ VE{a+cIGT;3lƼ9뮹*8(34oO~+ϯs^:g,ob?gtdCFyG?䚫;/3kן}οlŤ#4 |95Ue"){&U7]O?o v뙧EVuͺ6~T[W74>!A@v+/z ?ߔ^#O:"+̻lB./.~SV5&:[ΙuV=u"Dӏ/̓)8(7 kjNqݲ' ^{Ŧ^#42 󙤐17_^no7l۾8Gb]}}vias%qQvTFcScm;vmݾ⣺DȚ;{X$D/Ok~=*.e}vzI5&>"ˣ"gΘsyАА1_~wS^r_{-,4TV-\0$ϷAɉhNINFnjR9}jDr39VY8CC.>KĄ)v;׬{Թg@⸄ӧ8VqY.ooI&8~d2?p(iX!oꚺڼ._ֻtF!vصgҿ\啙HwT]S{Ï ãqh7sN$%q99S'/Аq\OD;g?ntɎI_}q7_!VH'd/Y$ -5/DGG3O3]q² iӦN8nB)uՃtQhH_ѨUVeIII< %9$ɞnDC3޻M[HKMu~onX-\֭)Ip*#+nH7Q06!O7i z^.:[bԤQkh.(:_[GevBr왏<ݶhSooni۶]hQfVO)<{rN p&7[f~J _9nrGq)I^z5e} Fnjs|w=>@O>;:曍gdf]0L|x;>E(y ڽ%joYG0EZ[ u\|_xсCGz=ٷoBH$e'32;ZNCMӏO6#~ѱleN=ԃy;oN7,_luSYy90 ðva/>#~2b4}Kѣ Ʀ]{M|ؘ{w{$[u)E1Ѳ@^AAP`X$#.qA̙55jjk`W,\ϸ{_~['OevttL&}'}aY3T!X,uZ z?__?#iџooyw«닊{koWIOkn4E%6}?@B||]}n#42 frkтyJ4j~]pl6bywlwcα_le&&:ZXt:/fݿz[X.[;}enGNwƧ+--))kjnZ>dKz%K0Lt6n:zD"햛۶]Hxb]yTz{B,k9ǮZRaicS߸X4{Lm=X6lNj_r]Y~SYB75*W"yoԻtF!|f޽g#JgϚuuwHr[O=w7uCts9=&q+o\ Z58̜>H$ӧϘ6b!4$O>̿FO ÚMys/[ܸ3gTVU\}HD/|z͝={-}-/qnvE.R?|Lڵg_Ҹ!W>*aٶ¢Vz]Kz+uu>MS2|7{ual};{tnƍ-回o-qsp}qAbuyw7D>isN4vB}{\&9 rY8D*͔MjqKGh|}i__O//CTL'IR82An]w0̇|(T*UcS ij^Zm2N\փ$I9Q"a3eoA6nAegj\){V6ByyO=f@jB!?B!?H'_TvK--/GyE-ɓƋ%/XSS?A Iܸ|ɤIi2_~vnJW, ȍt1*=Mヤ;oo[O?o=q2"';W[o'曘s]E[fz^W^yynn^2,kcM,}CVN^FDڻ]|'2mͳOiCަ~~5$~Oju6ffͷ?n7ް n'_1cb{#))۷Esl6Oׅl6[o/t;ncz^D*Hz{'j?_=U D61FSSvQTT|MϮyO\wUDxc?0uĥK};! iYGqk{k^|u֖_ԋmnm]`ϛ@rXLv2# =4*|?Nz^Vb0eԄc2T1;6DH?P||ޘ /oW6@ɅSFرSjimu$f1Z[=XTT;Ԝ>S0eiz){[aaqc㟮[K*+\\Rj%]yԹO}yKGDmޥԒ%W;nvys@.S9˹o5L̜KgI= %Od678֦߳`Aeѷ?y*#ϣ<췸짟:tn:|}r^*R?[RِeemfƜۜ<7eO|Vcn`h1$#&B>yrڬY|IcUjv鱱1}K͸Ga8k9" ~ mmM?"_soTTx+/]zOmڴ+ Ir_lsryOJ}kN.&u_^^䤱—8 qܘ) .nԤ>Ϋh9Ǎ>_zԴIaMa11Q^xڴtX4m>?Kyi`] FC3$AĹ]H <-qTe^Rշ_M.+|򩵧2s ϖ<ڬ\!>e˶[Q^!$>.f}_vȉPTT|T69rPBQ:::J%_6> v9ԒWq\O{OJ@߷*-1=]Hww{mmm oQ7wTи߯tttG]_ IDAT3Ne$rKpLyjݽخ7_v۝n߹ (jwHAپ{_ߵL&S*. <ǟ%!V~rC VroTT 3-5)n_gJJ~j‡;"2챇>7K⫯\sՃz2ebJʸgãS$ށTDZPDE\|( R-v t$%޳I6۲e쒄MB=<wfϜ9SΞ3gS))`ii)yJTl6p,130bࠠoB~w#@.7o}e#E%K,q<22#ʙ0>zWI!u[E_c'Nt0FZ o~wPQYR) ۟`VUyoT\5!'>pk6^u瘑EiܼU>j^okS45y҃YY9/_yl!":&?*'**|)_\U=Ōsܹ ƍUR2TkS]Η_9%wqnT%0q_;cGIY5[MO?/\5cʼ_ y<2}_2r7 |%'N%eIu[eg&$t}S""N>n#OmB!GVqqݵxɛ_Y8ިxe 9ٹ!?c|Mk5DG=|fO>fmԹ J'..op?dY^^['OU_wpꬬ_o7woK-s\;N_\\;㻆u8s0]gvcZIZ\~AQIiٰav3Ǒ#GcdTxYi;UA̚9e/S$~>Ϥb^(yejGE)-W@jz1p@`YXO<>MIex2ӭ[RxXhƕ̑#o۫i:/]Jmۓ'?T@s' O_r="4d@ *2V7.W,7eyo'%yekTψ(5VgɃ:=0լXەȈ`o.~\qepI$ƛEŝ:Px^X)$&&۶}Uss' O_(Оqj:t(q_XU+INDJ_7yekafoϸYDDM:LUv1Y￿q䈡A079K]b^c?<s I|߯;v߳gxh\. ljZbv߸?X,]v]nx'oRszFjZ$'F6Vϕ]TTK ɠWMYeF 0)!37Tq W۫k5U:u .]IIM[xwq.:u[t:n] 8iRd s/_NoHEERxYt)0FUQ^xz!+'W|J|q!}+F:y4~ſ%aZ ͷ?>5ggϝ/᝼YK}\WTV-&ޞϟTщC='C b\C6tzچ[-V0LyEehhFyFXJfrp,2"|]$&'w=}6\oU8,<z"EDGR4u]wlCP M79K<^A8T\RVOZu<>{ܧg[O|{O|,DZ\s]P]$q}7`3Z渞0a}.ٲs'pN++ @lF*z*O}qq鍤FyFl3rx!p#_z>g7xziEşm0 ϸ~ cˌnmlYۋ8ҠmxT*忧N=gs'_ H.Cج -6۷^OK-s\t?ӼK%W*v!~T*}݄^N ; CBuKڲK2]GGE u1n%ϥ^*ٿrQ^Qnq5[Ωk]:yLIiٴďkw[PYirۿzQMչs׃ I)TsOq}7@0e\dSMH߇#GOHhIhh0AyC5OK-v\}穿F9EUT鵱e=c\j䤌daX.T؀}.]HIIiZũS&i|ܼv~?.Eݓc-1 ܼo(#vrrrךhlxv鏻u4MOx{ +Ço}u8wY;#}}oEee@SxkR rK9}&<͛>/q{54 ߯(UeEw>EdN~zD$5!qJK˞\.;;<|ly<9i>4sGfW8Ѩ{Ik[\l̩S  muh%}sQQ9^ؼ=K)*.U$m 5{W0uǰ̬Arzr O|Q}\o4;{>|jNu{R56/sɬժ^n7ER5# \ǯfI%}>!/pG[,KA=ܧfNJ=~~i IK}\;RAڵ!Cn:B$|SR EV[=( $̈́R* naqV#J0ۓqt*KCcM Ԍ4pO|*tꨨӧڻ/1 {e?ؘ-FFn IK}\2y N_ZEƒJ%REt<4/؞x^%vq}uQ7+M7hܕO|nq|{yOķ曢toW_\ԣ{f]Jcݓ:omu~?7=\7lcp<#@3T̥UIQnaiei9n#}xRw& nO~ٱmɲKk֥4܆z.5dj\݈! ziԴ^>tO?q=c6hvl+\ /?vh$FydĉWt?$&ł浳"H4hT\%Vf 2[Ç y9GSK;-o-_ <Ŷbc4RJN+)6Vb/ yPCãUjx|/v|//Zxj_嚼on;"IAcވFD"yŅ~Yt4jՁzsvݺΜ6E/`zXQ.G[3ڐpmC; 'F&+ =yBlx7 4$IfcL='gSDEEKJʌ];p)+'[d:" Ν:\j;}H$O:թCGeN<ٵK[+*.)IM |.]#z/Qn&؉.sBgҩ3gˌv"E:v '-'OY}xm{57ŢVRigۿ|lt1{I?r>ilApVV8+eηL6pT$t-͋,v_{/R鳞V{/3CCB A.]%1.&&+W3@ueee31JLS&>sx-}{θz"}z埿pi֊BCBu1< m}N߷/{&ݺ&1 qjIi8IV[R8yғo۫jt:k4a]t Icrk"̭,GBnEABp<KT -S_؜cO7Z}W/լ/-޳o22N= 3^ʞ7ߏqo-=Bkm'O>r(N؉Ҳkwƕ'>oZ{km{57ʲ̡ߏ1ԁ?s<76Gv&hz8;{tOq?ܜj볻eFaRË̥>hҺC[.;/R_rBQԘѣ=?:v V]NOϚ?q/<;wG*tqo2yƎ޽z/|$==7?=mIu5*$uѧ*z`]fϘ3ggdz~gk{͚aC@bN6r^l=v$I۽nGwA>}ʌFZC+[?߾潷g<6FŃ[`=zR2Sr@Ku]3va^o_3쟩ҫG+e _|k} ~k A]0/~3:svL:]|{ztdsq3fԨu,ϱZmpY\2^-79bD6 _sµnؔЩS+V9< 0qj÷EFDؿ_Aaf3f޸=wd276 /ҋ/WkcAaʪ`RBbg~LIisF]&NyaϤeH!fs TTVw=sE/-a@۷|4sڣw>"sg 0$oը=g鳍Ɗkg}{LJ( 8`0j-oooҲk7;T*ˌe՗ݏ[\lV<|Hpg>1k/ZB,ye!!s]vj xTA4-iSxZB~xrhH(MQ8 M\ibre: IDATvx~3,gm6' Z^Gi*`/o>[L&]⢧/>[5tm]%k7lpIzyт{(6ÿc{$w/9Y-jOh4&%45lp8~ⵤqVsn pSgΈ}cg||lP`D"yl/%8ܚsFy780.Ew TaාI٭GD8~W=>ܸpG? ^xc;L|-\o+ n~՗!!SgbMۇM=Aې-mzK<_Iam7_"6Ax9Wf#Stz77j Kq  ! LMQ;G5iqA M1K 1g-PIcpUm#{Ǝ9Ӏ<9jfd2l`+}ͷ3]_|0LIioqϖ-{P\R^i=p0kVn~?hR˫-|%=ߏ|Jc8<̜/?RaT)k7lQ۾E M}{}Ȉm`v~yϾt;Ə{]~{&$QGe%Z?s_vULV2#p\oZw{H֨5zv;XI6{bh[@Qk13[,fh򗚏]p?fcri鑣ZE{'IKuZmkgAi'7;je_X 4=s\AǦ7z*Po 9BAڃ ¸~QӾ 4\CyΓ    7gAAiP{G!N:A ػQ%%V.)\ |J 3tt"qy| 'u7mb l>5%&tTw= vi-W{ Ć1AijZI_[d9H9f]fE R x1 )8 *h-~#-gڭ8u\*UiU*p jq[  {1^lGu'Ps6^H[U&93%(񴌐m6A43Ya!+ sc.3QcI*daĆ1TEJAM0z"՜Qr%ၫFu\`)3,Ɋm6Ԇ"ׅc88a:.B"#d=UL_dg,.7X&;D\+e erR5YlA:k^HRrj#YbLY$@y_D 4. /]6\Brsp oAnM=s˱ pZH-tUVquI2"$Js.ABtV K]8#.)sR^^[@iIrք3;xc8o8JB{Qs98'K%G`w#\_^?ABbl q ^mǭV¢-H0$TBxRoݵCV3 He8\m1JJHC!Fg9˳>fngx&"-YUJH _^?AOЂ8cE)vÁbÌd11Wb[^&W:Z+i N+[2-,Fcu[ sF:ƿqAv;adC " s|qrkë(^B tK湅Y ! \[ ք܊:k.W]>X|<@cbGI  ;i: )FiD!`;k(ay U%Yg#xHYkh,`B5aQrZY!LT{+R$@UV8ܚP{Kw&]]@`kU$q{0BBd!he4@dsA#Y{Kr,=YZkrD#Orşm%vb',UD:8܂o=5u[2Րx8 H{~a|G[M   -gvYAe} V3  U=   H[@6zN:8/8*7D"y׭[r;?g띊aa )G=z+JT*Z8W nh׃-S_#m?#|7n|kN8pVmH:GQ(:th z׿;)))~O4h0 -[>ӷ~{ƌ4M7? JuEM6O?ݼy9s D/^\3K/vm7Fi~O6 0 h4h"۷\Ŭcǎ?~| H@K]Q`+H[3㣣}'x8qgD"7oA4h3gΔ5p8q믿>k֬͛7?/UUUSN6mo5mڴԩSCBBΝpB0w\3c,~nDFF@LLw _"Qׇ~t&/AVyUBH[ݺuۻw/0p]'''@ΝY2 ")))55s{>RzT*Ϟ=[RRM:u .,]4//O_P$''KT)`0dddt9222===;;[~Dݻw7w<_TT>#͏`HLL050sᅅN>w\``~i ի*GYYYEѣ ==]0aBjj*L8f]7?;vLNN.++;~x~-o˭w?!CJNNσ k@^.]$FZmBBgffz\oAO:/zP ] rCgڃK.7.((H9hwާOAw.kٞ;2l…8kO}#""Jez z^*;w3[ffXŭ\wޝ;w^re^|={2eŋEz 0W^QT}3gN1dȐOnݖ,Yx~qJx)SDDD<Ë/u<44tɒ%*J+W'q0Le'|{]`ALL̢Ej.]Dd=wXeѣz)FqF|-r ']v5 *f'&&f~h4=zxG]-[iy~V؄zУ%kߋ@t=ضmBXjwY\\,ƷnvZ,8p`ȑ.\]fffz۶mW^!ǭJHHw|kfee-[l7n:i:11q˖-ޖQblϟZvlo[r w~e-ۄ6-4T@tޮ7ME-V_#o4lٲ=z\q$IS+**(0`[gϞH$'N|t:;裏wzo>}^|N+..>wܴi'LJctS8T*|h4SN.ZiZf#HLO<9&&t:ĉ=Vn[o 4hԨQPZZz᧞zJѨTsfee5 ntx+'>[XX.IKK󱱚ܦAꗆ/5[Fts_YJ%qUUUog̬Ǐ/]r:uĉ}qI?$v߿ŋ~mظqY֮][UU%˷n*믿+VX,Ƿo.| 6}vW^-ރ?p7nt۶mرxn ee˖OYYٮ]-[h9({nT*D"ٽ{w{/,,p'|2}uֱ,{5aϥKu:D"1 ey+'>[XXs&--MzСCN*NIIY~'-iG9KyۓփU__aǎF)JooUTu{L2eҤI O(IZp=JQ};?a>^L-?Z_g&M񠠠#T"ԌH$<^wekF'::zٲe5g^fM'{+'a ]8i˅&9@V۵ziX_#m~AgogwҥZh4Çg>0Pjy4aS-?fGqcD<HV'lz?zSwekF懦Çgffr׿e=3x+j'ޖ+f eMPwФ#LP"tޮ[X6kB[˲C aYvٲef4ѕ+WzvԌ H+Bo輍 @A_A_PAAAA*ԞAAABAAA*ԞAAABAAA*ԞAAABAAA*LAAA6d@A9Ai}  y=   H[3  U=   H[3  U=   H[3  Udg}h͗A-]7)1AAݥK ݟAAABAAAڪF7CFײ x scEŊS)wѨhX@}\,# #,;0fkjV -eRqUߎ3I^^WkMB0@qD*",R %y~|q*BX ;Uo qq҂*?RH!f'vMdl_Z7:ya=-V4ͽ" 7C B=$fo8#4^a!և  meO B%F\~_R*6EEqrԪ1N)(&a<` )8։ǵ\PkML ÝZy]z'jS,hD=4Rݒ,JF&n "4D0'O(,\i:V`#pB)^j'ޏr⸆eh Wb82܅4 $G y2i+bp,dN3 }AZj B Ucˌj3QԗaTJ;I:])fkө`Y)$4q3MI%n1LQbM(^ty7^ϸ!10pp.]0@&sy߉ }bp n^' iwu@D"8o{N^^vxQl!Anncqp86ZHRǰJXmr-JNkUE * r3װ\Ed28V^R*+)ʍt}Lp:KU Ap8q8Ȇ /\AnLǰ&x͎a%eKnJ%e-$I B À JҠ/&5"쳈ewg? ^gJB\n T$j[eM0`(X"Y1G:r0f4d`H(4eH28~E!0,V4j&rXHRͲ UPH@ gG .(!GCƨU3C4rSpP5?\Xff/xJA0y~BQ)oÎ{YqRVM/y6U#Z8Zd:3J *\A蝞amG[vV;=sQT,a>Ln3@Ix{I˃LJi$2FxbcEKfzMHl)cI6_o#o C 63&0LȡV x{蕞b7իϷk[H\@{>JL록͗ V?2)HaɩEp|1Leˤ>l'7 J5eR*oHⰧOa'VT!U:x!>w\V@NڮFeL "yޞX-]8NZ(A`0LS L08N` Ys-VC8- EA Ё#"_r!1LN92v2Aryމa E|I}qj0La e,[ )D6zL7o%1T|'ImU2  A-{RD)\idDXϒRSk5J@OF LucoVf\"yO h{2"$;f=j25YPym8Ƭ9D9 @  3[#rq1@)" z̺@ QUA@ QUAys vxG - RYTu;m#UJov &mCgJ)@i)fA1lZمe3q|JL)hqs4*{#vZr V禨{֚VaSdV[5^}fJ9B9ыyש _g.b6U[}`eXjwXLv[.#v0n-A*[X`Jq2MG(g);d7~ISWdFl|`~'a)im  s`#cĔj %:$a`jzH湗2/T 7-_ZF+W?jntuE'kRgp;یWရuΔaz\ v6?=,̆uB\$rOޣk2bf^541zuTxѨcOܳ3UzPi4 xF^8fUJ|wN֨'kԳVL/n QPR$BD.U!&IjMVbyN4fWPl%?^|# ))`p d ('ˈ'^,7kFt{oh1}AoTW9֝$QDG.ljah#6Mn֯bO˘Z5ZJ(00EN->\κ؄쬫3i0hA+0Nn+cE,(h(xbk P-0f9'y .(T_;-;j7ꡝM6Mw> 2ogkD֛`= B Iqцo hޘގ!fkԏ " ,-@/YV.4 @`@ b-BO/10 I:B+AI l%v:ʼxէAocC֫.0KMyJŖe/p|PSPk|U70d>I&Ȥ= mX) BXg1즣610x# o"!چdQĀt)Qt eGqS]\F1zqwYR^g\]V"UJdaCq @,A8 P*0$M8v/ESf#-)9t 3GAӘ p $!@S]`\z1֫#IAD/Ƅ(l vAJE JapArhpXJt0ucpДMO.Ny$Q2B* *y 6s SM`\z1֫G6i[FSP j\- wOJ a_GQ;o-*ߪ*(Y"0I b4qB},q1j_O9L(IVRIEGhf-UKlڒ*wcTW;)^}`(z5%R#hh9"ˑ(&ʤ Ϲ8IYېvw,]3|<̎es.:ߝyYqܷQ1lOIo n:w}IW"7oMMsژ!vu@jo>ʢ)Uҋ^}K>F0^o]%$*(<̠ĻM7K1OO1wL+pF1jg[)ݧ'~%YW[ HjNU! 8AvVJ (7A27 @iñs&%0-Xx!} ˈ>z1^op| 83Lr0YTO:UC+(nBUBi7yBvx}['q3GC^2tSS]Gy2Cv n"+ ͞׏!} ˈ>z1^oǶ6)RIB%49x穄c$u21kLA&M&i̚ SNV $xW_VSe֝Xܭx!3p$q| _vFeWZ 8ײv(Y.Hz#JB;gSYnE90̬#/d7\1Gۃ0\5b|uY9;=ls;Zlbt}uUkG)-s.sY'VǍS]P\)F#[ Lwˆ@T3*?3epQ:vuY}E\zD֟ULOx80:N2!@69/ufFv[.9EקoJ+4N@TztwH0{, BoF% M8Iqm}آO݇8a%8I7ys+;v0T.S)Mzz@ *'FN̔slyA:x~~̋ѷal9!/͚,Ғ*\wt/.(TDUI '/S]CZ S]`\S @rֈð0*T"K%iJhFʬ?<1Y%*#aJYV>ggIQTESR.{zjys&: 3QvAoLS4ze"Hy>ںȏ6̢2@q5A)^v.>~*uTreTR5sy$89a:!58`6;'Afl:bsݟ7xfnfú9^-rbux[L=:t'x{@U4MTatΛdx ӫ w TDӌ !}T?;+;g77)eȰAҨ)V!k KsJC Ay2Dɡ%ް>ZDˈ̳r7Ѿ_*g~ٌ_fCOd+~FHryvC }wr&fW<|+˅ oߨ~v)V.#v0n8@ @ H_l'U DƼlQV @  @ T (?V]">@ 򂪌65}j @T *?sVVec'=˲[ Y)~l,_rMTMǷe?8`Ȉ>IC/_ae#O0/Eٳp^eϧAqc?~WhN1.p~Wsڷo=ԥS}v{]E@T?$u$^a.\,(,ɨgUmѱq8v}hxHV/YWo')gL>cW^CsruviڤrQ~經%5wj=eϪ @.|ɢo$~ijvfFw5?v4n4O_񇌬!G M*g~ˬU);D[7yy3g:SRS<|IJ<ϿvZ& =̿O71)Z%޻߭sG(գ_t>zrԴ4)zמξ{.VVV5kt.cQg߁ cGx{x{5_͓#㖣hfcgg۳Gw\gãIF$I6mש] lllڷm-jİ_LLJILJ~GÆ'G M|pwpp@+u'tg{ᄂy %&%K$=y))T*/Z"O5/*::66nW]X&B u748ݻyNZzQΐSBISgST}BgN"o޺獁ujY[[c&P(o|Μֿovl T*DBKiz NlؠGkZo* MQ!!E<}fʤ nn%0_ߦM A*ЭK/OM~v⡗,[|gjZZ=w;qTomZ1 `Ud)ʛĤ?;~W^v=-=RZ)҈~U Ä3 ӷw IH]WN!aiiiir]  po/KW:sV۟1t}6oagg<$J7˖oXJ܆p굊*DhhRn]{;L?ð,׃q;ٳkOrƺgMJRy89:ܹ4M֮EK?'Ϟyzx[a]:uXdYRr2tؾO>5iа|ɤ,?elэ_+ MMQYddn^؟Hq;U7fI\^%<9-[FDEh@zRRS4 w*'VVV4ptpptpݣ{||B|BZlV{=DINnFʫTM(w+F3i ϱOfYv@x5==ѓ' s0 m%-[¥+BT]{БfMEcb223j/w2<9xiܨAaa'O99g?֝d矞:sV8;4-J_LSW4Mo^FsIgd6jЀ;vP5JvܱXːAn v(pZ5]]\$Ʉ:bx73/]T*ܩ3{ x=<,#㓏FL:V@M<[Nw?9l E>I˖,ҮXcvSϖH$۶Ю]YpE.!V<=~\e9eaan]*Z޹cOQd^={n@tҕ*+{'Y7'N߷Ԕ]ۼ~MLlU4fMbkkr\._[Ȩ+׮oXJV_qeCbR+]0>!XIII3}I2+s/wne?gN=gx7)ZzC\^e- oج"\W{3tŋOU>Ճ'>~@ Ęѣ|*[ 5jhZ5 QïazO_ Znǰ-}$ 1Nf+7&Hr+%1Q@&ϳ |CC'(((};YZ჈NJl[5< ԩ8'N׷'[ETE #J]OL>zzV(DFܹ{\{ҵg_%7{/u=y-F\q⭄Eڥymmmm :'\<4(J#4&cd2cVZtI+lɱK-~ѷF ݼaXe\󆭢܈Jڭnnni\\jWL*SݽB/DHHSQ>e?߯yrS9rx>qy/ZG4 JbYYYZMʻ?4nTMPn-]\uOqtҹ}u^ޮefA]Mg亵k8ov)j׶[ K\+ - @?x OXSt*`iӸ[M4pظ䤔[rC|r\?--sæPjZ~_Ĥaa8?|$<<"3u㧫~6]tU*""uT=wi/qʍISf?{ܲ-.Us-l aܫmX.$v1K̰u $5k-~aHpP:~XiƢ|s֌/kΝ5};s֗V!EFS٧m AڴiѴi# ڴi٦uJ(OEqV666Xa"k qT(55Wn5=^% &9::Lbl)/9666b˻?4n0$$ƍ84jX)5|gk6(Υn'Mnް^:eKK\+ g*(hɧ c b7EoRYga^9[wCBdekRU ub~mkkCDl\ѣY~A5|\)rǎxrs)y9Sj}Թ*#l*湖ɤV*~bq痢 O(TMvSy8>iN_p=~:ng-@x{y,\/:ulWjՊ%wԴtv0du@!>>^aa*TՇ;z8;9)87KV.~=&ɳfhr/'S;ܼ^S 3&>]OJ?a;PA:lX>/;vh#%$$m߱{x]pP?}qsׯn#[s /] R-8n]_-XʰwK]{ -6.^\RJT-l߸yH$ zq-W)Ty<|$)9%Ns.C 3S~_/wb˻>DBk"r eReTh7Rs$K)=l*V)9Y)s\HdMSQol+k+!Gly?-)C8eVp7|Ν\Ng/'__Viݝ8Q.a aZlupF^e.s`ogkF+ O{ecG$U6MrN6fm7SaA<'A_.wyL]Q'-]OJD"0L|x+VR^W2y,\0+2WrmSQj#{fD/5i@@h Ax<]JҎzz+0LfV{Yh@@Z5mmmLFc>gШaFayAY]Je_=GPUߗ>}87W"Ma헑E SJjJ0qSPk]O?,DZB|#6 ֵ8Ɣ=rj*6uM_&HC:fd0,^&ep3,,̤i֬2ZRv6%%V()%%,WQ^ &&N7֐^x㽮?x0eܵT&M<9)eZ 0/_2ԩv5UnJ 莿_I͚Jejkk'Í,zb% $k"_Qqd^~c'7mQ ˩]"#-n|3WH2ghGM305Z21g] GRT/ܼu~ýqvi9YJhEK?x,*p r~>[ 6nԠqztCTKKMKOC=f?a"_չx:h4/&7dR̙_ܼu9cw=1:;9eeɣ0 sv;ZNxbې:z2Ry!ʻ]}C_y{;i}{G;jzWtdXZus608L*pMOFԴ|0qv )|>$M}x~Ů];$h(w'? jZҢy3w_wjNO4M g{ 9 k -fb>o/Ooo *C%q?9^رmEQZ$Ξ$.wFL`R_~|Yp{cb_PGmc׮i$TNy#o͚~-[/v%MCh+WowXV#ƎHM@8vɨ~4pڟO13j>tNC?ܻdUL[NDDdUYؾjFD<=k.:) iL# $ax ԨR1|T%-8vZJYLZ F&1jC+Ԯ5|` 7D0ܙӫHe%R- &MV/YJe$7Oѥs_NBXWy˳J{0v^8pP쟘*G 'Jk%$]P(ggtOi1M,bHnǏͳ[%Ը!?J|P ɍѾuV~=ԼY 4nԀaبѩii!{;-ܹ{WU)T*U1~پSTg *OL#&.ð8̲c}l2pS 'HްRH$=y),T*/Z"Ftu'tg{ᄂy %&%\sn{;~B7Ȩ1'_y;ѓ&ߺ}W}-Xyt켯9{ԯç͚7}+׮rC2$7bO|UlwCî߸xhؽ|1uF|a?\4~ldTGfMzݺq?ܱԯuoWU)nܺMZٲ}mբEzF=IϢcuLqIrW (Qaٱ/ Ug\X#a5 }3~(*ƁpA+Sy1 s̙~{ߏfM#?OKK֫[w#[}gfe@Ll܏k֏?Ao{}4 ;cOF}}'Mq\l܋=zT!GLP'ƍT;df\zzݻvxd_?-߼u{AVZ~ִivvUx,jϴCfzWycog۶u+e%4=qo_y]7Wܼ\eFg'' LgdfV@e0Fsp< V"[V %[J߷7sss==h?ŵ?*.ЭK'Fs@߾A@@@T *_Pee%{z/%FӔc9{!4w&MΞ;TB»t=CHϰ&3<>{'s[[wF|2z{“gxm|C2MvOu'4T{HRsQEDzzzrJJrJJNN'^oK,[ф^֭R\rsKa@M4A.* ǟXvs9![4e/;;EXcv IQT&5--ݻd!/_zȖ]k~~ǽheeg}k^x@-9OֵAz4T.~?32̜zdߞ͛kIb. \\9ssstpp>Fy^4wmoOt{{_ub蘖f˂@=XKY4G0yZ܂ x;웇h_`띓-5&-=۲zV0/28~jf4`HnA}j1yyaZy7Ƚ|`(zi-eexd27 O1[[שC{^ԴM[o޶cİ! 0dhy$q) *eC#aLqFh9xOhP^JjaT9nbV E"H+geM Nd`` -h-H-j_cn8o!oE~Uh4⼓J/,Plm쬬7WGOh4̥+W@&vab[%qD~iѿOp?5oL7|LZÆ ӛ*G 罌y`˲=3rVvWtdXZus6. ܕH$c?hBM~A8G#B?xV..dӛ*G M,3?+%J8vثI}hFYP cޯl[yfsP*wfOC`V4h(<ΟYtO0m["oۺCvA̜6uIQPe+tY9|+a>>ދ7Ow!eǣSٷW='G 'CBL$o9jQVZ42ŰN7-'N߷Ryգqcd2ֶUUkz,[WgٿaԴW ^Pެ[^Oq 2,%5u6_pFf:7d+׮ϟ;K*@n^kOrj^qO6Μ6]Yl[kM[ee xAHLLҕ~>wne?gN=gx7):?xСC'ׯo UCneeggd=vkM^zmJO@!g9ۗjD,6@Y_+Sr9dJ*9K.k-,VAN}=n"ݞbe/X i4+wY٥ZM;3PWy1}ʔFc~Ҧ#Tݼ왣^Dt"E BI3`0|!@3ޭ8)xS //pBU nVʶ.B+x3#<B!B/3!B 3@K󴽡UB&4O۳6g !T5TW5 %~k)zS+KiPf _|óeFVk\:=1-3{a/##Lӯ:;I kV!TyusӺEx:,u ,0kxj/[/|n}?;Sl^):ؾm[yddv#j86KmzY;k{:Bg7^OL|k .Z)R0=lSo]E[/aw)Wj]\ϻ y^RR9#: |Yl啎Be@INNWGt_ =;Z/}"5770o(A&b>ʗHd:iz͔wu}Px9\.+ ǛUYR1bJ ie 8ZG1#U)Re\蒋k%>-uVTdBGj {ϯs˫|BR0Cn^DZm+ej߶frcN֜jVR Q{ݩSkgΑ5} <,CLW)8UUO؟v)( G7''Z.Uz}dV (}PfqsOH#U|#PU呑Y# ?e.u }dZ)-Jk&ܯAJN5*tۖ!L$<Yu٥UFzǴ UvDYJUc{R˒H+C┓P |O"kשQ hdRa3:Dc{HWˇ`:??SsU`pڥ:8j*bqp 0Ia+C $99##3_"Q+k(+8@[bxyNڶV+ZH+Cfp>j]h)h".lB:tII(mY-9:d%.:PZ>!TEe*?M0MQjSg}☓;i`yq[UlS(/֏uw#v,R..B6jV^^R!8tg(jX\ળˤܵZ|յ gĔSOR"x`%sRo~uHXȏgcWW)VZg'd_6 QsJ啎BUթ=oޚtoǞ۵q("Qd- lOM\NC1:gÄ֫c|hy#T=)v=tPYW|4"6cU(?%(-zU")R4|WAUJ$ːa%J}1B-Z-ΫE# RmE+*`Ϯ}1/xt9hOl~+]{)Jhox=JGRhOl~+]{)J^V4]'2U^U7-B!B*EϾ$ B*ɸB,?B!?B!I2Tv}iذ!ܾ}%_ao,@*~Gk֬jχ~x'O]J!~^DI;zK.ݻwҺu* !T}Ur/NU؟X>|xvRG6oo\ڡCbһwo__:v8l0\Vo~ƍ~,۱cUV5jhܹQJSSS#""nݪ1ۛ]],ݺu87o͵ggUV ZmDDڵkju c0wʔ)gΜ!geeիWoذa-jӦͭ[,m_~EŒ?ۗ*p.U;eU78ެ::thڵ?ӏ?… qT*>}b3 IDAT:kaB>|x~ov}n„ 7n2epy_^233G5f̘VZcƌy95sԩgvww:ubxʔ)}т X5kV411f͚PN7|<<<]_]`AR?*q픭STYf'Np ....g0bbbRRRŒ7Ҭ|J R*!!!@5jڵkܹ`X!]@@L& e+]\\j֬CKSRR xbqwwoܸ1!$22t???ooh[5j׮کS)S/_rJ AAAqqqQQQj^W֭[fJV/yy;w ۷o0ԢEO޽{WHqttlԨ>xcBU /Xj_*qͭ VR3ݻw~m777GA!00u֔-[V}}}>>޼yLW?J֭[޽{Ɓ' 0`֬Yu/fRpT卋MT*v1 ?SάYz!$:88 1ăz}۾@%}gϞwM>xxƬ'رp#Fxyy]eɓ'߿ĉ6q)S=tжmaYvܸqK,|pvv^lH$rqqyիݻwgΜ)!>|xpp05*--mժU2-Tݺu?쳍7 ===SSSM7 |/9֭۹sΝ;sн{GY&$$IMѣG]v=u<~xڵ#Fptt4 c)U}޾@e>nI{!?Sqf͚>L/^_~E2Lĉ֭[T*Сd,RYn];;.]tãvRT$2/^(HfYϟsNXӓa$0ƛ` ,Z[)/ 5k(J''' m2^+:tp͛e"M7qN8!\挍0mРСCϜ9e˖2Wקt=***<<< @ReddKO>-|Ǐݭ,SB/2S6iOQ5g5k֜|aÆÇM.e˖Ǐ3nD.d;::o߾׮]NLL,4g/yٟMz=BP_}ڵ4fZRtB *q MST a:H$]\\!˲fǏ9rZ 29#$''3 sĉB]pעEBWP>}joo(bqBQR>>**J8 R%c)PՃKۗx~ve3ՎNۿ J%qq̘ hׯ_zU8<^z75c Lڵ`&L_233 ֭[NR(K,ffΝxߟO>Yn0&xʕ=nK۷K3g\~N۱cG c`0DEE-\P,g6}-\066ŋ7L&TT*=rHVX1s;wl޼yرk֬1 +V(+V8p'OJU^os&<<\`E.]F%nٲڵk^*,2X!T`Rlb2KN٪=vm˦T* MwhR 9rK}X,XDޞ,p\ e6ar ͟٫ .#@t~3! ˓*T,]B{yPÓ~0oڰz'9uy`&) }U@?BX$89LH121 L_ #:=tiS@r .m7VO|:;)ًDiC[4Q1af`OIe $R neNa;p9rad$WBߧ-B%8LvE$Rx MVmfob|npq'y4O7eB#9:sg۽~x_)] n<ˀX=dc"cXJKD tf]h@I)p5$7'M'6Gq5B)msڰ.MIWIbv :)Xu.YcoH=\ ) !?3 2[iox:<:=?Ae*ܼC"PkhєMQ;m@զ)MFT!I$W$:7nJКWfd+HL,xCU;b@6ЙIN#WCIFRO7$=gRowJPLJvjM u.:nsdk :Sߊ"IRx@f6dT2@$2_2jҢ KB<&*%7oAP#ÙÍo zC w䐖M Tެt%N.W ! 1O7z R >4mDbHJ!Z=] F  zHDDr9}g L Mޅ_aTNMFԠ% mуws€O ضܐ/atia;CLF{w-/1A^i<-(k;~2F&Yqr dfK[:/r3r|/A2eΰa{S-oZtd^ҘXw@]_qb'| R<\ >܎"~guzto2O |غx@4 baxt=5Pr,oTJd ,db"'X2ҥBd(%p<;j ߽+uQ9yf\a5:prg}Gp͛5M>J)Dc:}KgѺ5!,N_b;#^*3jxPM>d"YXy] :~X?SLN.QBhܖ&!wz;ѕ OJO 凿ߊ0F HxiD)|k||ZY7P҉DGo5ۥ VOڥ 3S̎#,5Y9Gy's"ӡ%;p87mƒn7]篱3_Z99SV*S ID&ނ/ NĂ^I:¼ك*;lD'{hބĒd Êwhio<>1Ypuz.4GC×ӗLÉE .뉘:>0gUIUҽ@J:=L*:{1KX:ڳ#ٴ]]1<j ӗO3g0Zsv/J 5kVG"cXga٘TBDbŠ*Hτ3awINmZ5RAeR\HNI A*:5)!8ܝ)H%T3s6OaYjz (!zKa_ M-or@. cT>^t:8q8'r9AXLN ;;| ˼)BUQrd1&[Ma@.1U*h\ e<\8؁ H5@"" !Z}dzHI<Y$ -4xdږ,ԮA@-:b&xHL!@[;:Vq $ՉgYM>rRy[6㏝cȷ+=?%OY؟A6r)9܊ 8h&{T baSB)R@@&+11s&oM$P9=[dbsʳt<x ,K_,bpuZ-gUgd (N_A`ɑZ*o=t\tx._+cC-P|b0S7'n!6_Gs;fՁ,pPJjFKJ!)IO֥BSHJƳ٠@,1 8S`p|=8SnFj&H@,z6]=h!=S((Hx ddZ,X6p8{Y`\`cEl 3ƞ&߀F#Yjg'*c8?∏']8]3p$X?Td$Y eaH?>W >|+5_^B`ntο%rrVyZPuÀ޼nͤCNCN.hӃ,Zٺ1X}HRB~ $= fn޶x ZQVnfM"kQ/ ~6c8ax{odR~X[F#ҎJD!#ؙA6g<0, ů@8\N_# 3x6sD|qgwsAMoK9M]r۲-/9(V[e ;eIYMK %#LIVW.BрJҾ_D 0k!-H%D- j z:ٗ{:@*)xL 9s KMRyչ yؾyah!.w@l yq%ɔ$gN]7+7!ܜ 'eYQP@,Ecŋd̆QJ(KK!Q(!Bʪgv,;BUE(SqBgl B!*+ B!*+ϼB߸a7sPԤq_-e=YhX}׻B_߮zvv$&$~)Ӕ~,4o~.B@խR7KU&t{ܧߊ49}y\ ŋԨY&!` !lxd= Xo&<'nrӥZ=C"d~v3~[kD=4]ϙ_i0JbIx ;AkW_x`Jg4y fk@ok5͞ 8~tLQ:H%.Tz0[.+Pz3_Fq8wP%\ͅ3Psu)|<轘21 l͜ .̜ItXD'ezpq!}r,c`|mo:s!C)Њڏ[=p9|)p3WB@*~e p&1؊# (f` @Xޛ\[^+D,n=-z(mݯBtҧ\NT}٠+] ݺW^LYjxPtnK!5dh-{+{Jl¼6_ܾ VCZ b!1 <-/lo[h_Lȿ 2Gs蠉)=:?U7m.q0oyWXLд *h] SUM?=2yWϙ^SUJcf+}gՏxN">%Mп0ɲ_{m:oSs~`չ wjsގ҇GnKx{!Q$"s9D MKv 0 1~6u}te_*;Mxک <ݘ)1 ;?{U9,SURcf+hBZGzW7 *-WWN45V8F-g9yŷ/o: ςKDz~ƿѵ죂(2ώujk7frV^2SUhSVӃ&T٠?3]ߤ_3':>81!C:jϪICʕ<U*O3ߝ6־JփTB̖J=@imf0ݯJ(B<Ȥ-aE i_< ֫EaN\(-N0?}m8%ǙqrJ9xMgsپL:CmM#WnmC#-{B̨MTtYgAR%A7ВTPzsW!S*w:tOyj,xOVO()SBH 7Rٳ/rf.h4/(++k >|؃.:}QcĿ_$!TqԤ?O^|S۩zD"Gܲ;~nAZ5MvE߭krb|988{vܲi@~us˦][7El35O9r:俧sƎz7Ul޺~7%Nݸy˷sZKvoݶ&$6lIIɟ~w V-[@h maBg6+C:BtjMsrA(Nشe[9lj`{7e~PX$J3{{m᫩gte+W{z/aqӄ7n@`nj9dSRo!6gu[ҫS9\zy>v$o2{Bbbhmp+4|? hZc7n&W9v'{w߼գkgX,_9r9qĤ$*fl}~uJ̢دѐ(zut1!}]ǏoeKGUȂU앐rhj۫ɘ3YSHl |R|C;Tj֪e w77*}zۻ׋Gh"ԙs:^sKoޣkghԿk==<YsV*Q{ѹ6>lMq qO#F7lh*鳃y1$4Ԙx_m>;v?}:{ܸR+"F y4/Χ<!!f̎?&]h”fM]aYVp.1 sW&%t,Ճ4Sg|QZv;( x Ю-[a<ϗ6ݶ%B\n]y(33y`1]V8n#G Qco}khӦ7n$Q勾0Z6o% }}ի|_h”;;]Ḃ}[ءZh߮{AR=O/UUiR4 \ x#(0aҦ۶DP%xu9tĒNlܘAMÇvuq}uhqV << iӍkVTJh~Uə0uNqtzm#v{OM[)wWLIvm^R*^VVւEG߻-@rJH$u+~7qRZz:qJwsuuB%ҽk癟eu#$Ęר{YvޛG{oߐ[aвEPԽ{IIv&9p'"rUMUJ-מ=m;~]QÆAM,]fJ=OA7?r՗T6cޛ!斕e06Ifl\ٙeRںpFG{`Rr\"''c OYYYp>zbX?z͐윴rU foڦb񇓦qFU[ !afdԙB1|ࡃG`0 >[^/gtsu+MuB%ҰAl:9%۶3.[ÇƓCGvur)!]iԮݪEs{{R3 bIz~Cc\$K4Bԃ+.e톪ԙM^]{w?xuH$b*_~KSRS5yLVt[ !gN>4!i^s ãy`|7B7u~eV7lPΎBf)xux{ߴ>uƬίupw|TR(z0[p#M?pcvf3TRe-7GDw7,[<~A(@tʠGn5~Y];>rTX$.`0ʟڻgU?YHo߮ͧS&E{K)%@^f)*Z\|?8t䟕?~ŤddZPN+`>`D[/_17BBn~}d7_}~#B !NNNIII@tUWRzo]9wcǍKIuZlT*@ɟp˖ !>={*DtIAůQ#{T?77R}~1sFÆOt_gLRQ%g'ǫnD"n[_"<""#<$b16!#tiO@ίѧ?cAqYo\.7ɟQ]VNBT,DtZ"\]X$?yz=XEKe&}UUIlӺ%ttZ/!1A@i*x c=?}k}vmZk FBJfVNe tO8#G ozRw7:̹sPzJ% |9WU-מ}_̬]{l$;tSRSZ Tt+YSG]VZu5T:~迏R%L&d H$\fs"~L49%ݭD"ڹ3Z]F3ow\U-אA۵m Æ qusuJǏݵg_*SgtL&ڥc'g-a;}9ڢyIM$b SW\skٺi^o8ϱO-`ݻ-frCҀnJR(vlyB!f"SJ)HnH$0y7MjbLjRPBp`XiiB.WT))f7X٫T0kY!ydzT Ø&JR^_elvsuVM_'e ÚNnTtObl_lyFhoy~Nọ̃̄Nqm |_UJei}`XWPԿR4\n~Ҧ#*p̬74 pwpvrۧq -hU5dՖeegJ1[~EO+5K+k4,m:BM%oVZbE"89::BU^gݳ`싯323mBU/?d~<@i9&M[D!nGD|9w@j<B!?B!?PuqӶm}CKK=2:r7 7}o֩Sˌjx_&Mʹ*O^j;+>J :~^75Oah]>Xt~\Mysbx'SqzSծSC=mT%@yc׾Woh4ڵyo``J+uR~萷;vhk\%wV ;h зu/P\ ѥKZE|ϯóݸRLNI{MN^_Ӭ79a`[\T!%o3oN}' }p6l$0"x+vD_,;tm۴H%=ٶcw||CF ԦMK\v;q۵m av9pRqҦ\PPGoWp^~vm[={Vڵmlj-Xn./Y^oQ*?߾UY3~ݪ>n֭=g/<\ؖ$e }ׯ]vZȑ۷ظg\|mӦ~d*3[=>"s~rvrjܸaK%(Bh4V-w+N +W,**Ns/z\z9RT&}߃ɜL o?/֟[ KL3I2 :iݼ}\ï _Ϭ:o=x+VuP$.ة?2h{QC,^wF!Tn OMOݻCG 0\.~3 ]9H$)OEWYw}*ryFQ}ݫ H%BJT ( ((H5 H1w.!a>$ٙyn>#J:v50e`#cC ú:Udіp%=؇ob+פѣ[*gqUUe7nMLLM4bCC9l+t9[BBraaQ0ťi-VaذSL&&FcǼYs'Nkmeamekر# >~5Y#DK$u{5FEEk~gq'Z1/<Q%/)+qn|B˼TT>|tjv̅{e{鼕I2H$M`_ǏW`eE<лn",KNF}oV 0  afj}} E&}tssM4xr_;_P_P6!ӵsÆ dI{g.Tݫd=5g``|}0;點h?x{yv ww ssý˼tqj:5uuu5jxv!:o%t.{]UU]SM`۟a02@Q- ks Ȉg2ii?[jOc}pi _ IDATY{9mws/))TUMۃO@bbrd3x᭐ eYUWW B)ŋĀ>pƝ(VoFz|-t-5-#7'Wno߱x(pUWW3w=*~q<&yTTtq.Al܋-H70beEUtt_gr&|}GyEtڥy|PFgHHT8xv#c0ߝ0nl''Ǎ|ۍ_y39;|/aŧzh6D|Bw+)7Udyk@/v j$I*J(VWWcnO_^f;8ތ<}_8dpgv6w>dtU|GMLL-፬,|P(dzU% (o>f/^]<}CGO?YЯO/F44x}4}ϝNdlZ5:ϴ3U_gM@~1ibX$GM\X\TJYG(ڳC ^]<:}V8`wmr&]SSlWAcFTj\ɹCBB<|[RRjjAjjj@IiH$$"5-̙~bg+(J755iFJƍIɩC`٠7הm۞M?ަzyl{qΙ Ԍ[ nyGGY3zꯊ7y܊K;2`ɒF ?]j ʾ^cK1TVI#=zoW)LDG[\8>ތ3g/^~b^̞9ekO lj#EQYY9a{!N%lٴqx]/(Tj\--5ݽt |fffjjA19s<VUU$aԨakmF8k5#%>xN^*Am=o^cǏ?ѓ 軞h\&?qg玝=:A<\-IY{2Cf98~+ cƎϜ,kvekXRSSnkj%axC r]QMT~9a`%:/(ӧ's=4H&ge0fFG‚" =k`ϿϿWrsvBIK,((׊KJڲ ׊7n߯{h( ٹyMMMx|T*Vo^b;$& (ݬ9/ްu,w=<~P*)"ԧwA]eTޗ)7B@S JdGst.{o ,"cXb|H>FX \싃͛w9sxmf4!+3Be,$RYrSaQLVovh?y$S6k֖MՈ~HԉC껞Y"5 Q]UPY]}{~zjZ_ :v\r|#P9l:m0)U^PLJ#US 9Mg#Hh~0ӝѭ;;3Lsmm|Bc26>c|\~TUWSnN_ٻGttl?%O O*>83#L&5O jGL&v&9l>' < zU%'_3SӒĤ\QD3WýAY >C̅zTv_N?~o&}:+663.&.\oNgñQ#y< Bx11ϧN ӎ;"#3;7'4aW}}0MlUՔ[ZjF~bbx]ȱ̡rKMMM8Τc.\<]'y^I}z?L2X"ݡ݂ Pwĭ  lFj=X*$`3ѣs }K-^?i\< N:U-3LI KQ[fA#4g_N .70໺8 6Pyj{prmanp-lӰ9Q#>sMM-FF|@ZU1")gM 塕8{bnnޜyKCfCBr"ٻW(@[]Wz^sfM۸i>pb>)4Mk X[Y.Z0kvv6jw=Q:99'07(Soyphz=ktB*i/=^[]jZ.߸~J&GHXMud8FO_Β+ank [?' 9vlܽZqrJڅ(OwxwN!}yi2s̘@`@RdEEv>PU1{PZ#߻9$plrG6[6S(7޾ +T=^t떯i|妋sG 4y w>y99yjw=Qe>2,"Yx5uz |:e ckvIu[FNLWD"@|68<ӯfhDEVoYY14*i7RDMmpkk˰$I(:_At ;~7 ckvI>zoPϿw'ú++*ggWZ"B$m۶G࠮2<#3뫵브.]WZ6Пrh$ CTm }£LIi|ky!@  @  ϼ$1)%2o@ǭK|?S^ImWyTǦ7#w?hX8M4_N6-]}׻h[n}žEG5UC=>_Byl}̜c#G\ @?Gztb^hWHYU`֕ ObeV .2#9jt`ĉ7uru8`W],mg" ujV&JmtꗣzMkRQYշO/dm<,&cm@|9WVG ceipnn _,& x <\ wdi9ps$WGtptҥy֊GQ4ʗ*]MU<|H*y+OE<*,*l6˭sqxDUUupP2=4x';kΞvh#I30ʅGOqwόH8GaH=O&ZAQLF1( LB+<2Jk50kffVaQy܋x.;=OJNS.0>?D"a?Ϗ|UXTĈIl;8(0#3+6.y֊X[xw1<&.6ʗ*]Mu r8 S]--۫\HLJ/(`NDz^FdhXYU)HLa&y_Ŀ?aسe8r͗9PVV(<'Ξ;_?{(: > govkZ󵗯^U[Ȩ>]tيw1|ՔۇseeTTT~iˮ=<"8GD>yqAaNLJY̬ʪK?y^WΪR(ż|F(Yttn!?<}MQz h ӕ~g':2i SFcJ]WHO?;shoiΟ3soLdgkiqHP&N\#4ǫ}1Oކu_uruA!c&7WWgg[6كUK~ڿΛA=w(*0kh`+˺GN.P$ڵrVHb{6֌㸯aC|}pVo#o&:lsً$q _&F8=O:Y}dąEIAyՇf<ŋ~>{NVV7{&L? \dJ_.%I[L;잞A8;uxr29>^^ХǁG&GUԛ,7zW93qc>ϙ4:v岏ߺc <=Iir|^G,K*=xVXĤ㿜ܵc̹ KJKIJ07o,  ^!@}K*$ّ={ַFM%I\.x;CF=~ IIYw_?!8yHIMnsf|hbA >[_p"DSg0wppd)IiC j[Cfѱ3-gLSWz}?=?i˶?yO3CYKw Q(\gެG íӔ'-Cv^T\Y@ @t֛i<[!+jjˌ L,UJ >νp֭+O͚^V㴌̜aC &әÑÇssuf32"DUVVkUKvu6=`YR?TVU%&TU{꿗槤)5^:dqwX8o'K-7{@P(HyeUol2 ss_"hLD C6,X 4%% Kus.jdd}.]Ihte݄^n!9yՖUv;|i.++Vo M\/\u t]y2a`,/(zlЀ|>/0ƭ;SY BH,,-kH򥃁RK}gOR$][n'5}:{x`r|iߨSf)**Yɒ' Tx \$iiiikcckccll|엓4]g4^:$+;nBGv6BHΞY a&&&-AM$pؘ @Lޚ@KF;lCFBPk,, tG,ݰq-̷-(Z0g3O+SrB_acmMw5U4PՊAp8\Ǐmm8l6h#Q^zR W@Z&Sv 1[ڝIDATP됳3ʊȨjrYY9F&&gameit<|>oՋ>^|[1WO9ph҄Xb{gXq?M.j1 Sv |$e2L&OLNI:{xrVG Ntcj>@Yytm_¤TyA1);TM+TnARÚ]`@vco=d2wH$m4Mv(%Eϟdo kL[\\R|؊|3'I㿜 ڕ7qbT ek#ޗBG$uNu͌ˁ# _됇ù\iv499O,?Ϙ659553+Kl93̝1 z~>̐SUeemm[RXTdiiչ3ӻ7Œ[w,?K273c|"?Y:wq|"vqv*++7,:NU[=6n*Jp竕ce\.gnz Ⓩ~cׄV,32L8aGcݗd>{efeO1f 2x$p7pA{ZI?n=zC(:҈ChAϞ![x}ذU>9r<`aŽ-H&_qǫNUV@EeW_oT^|۷Hһ޹w$w䣅|T$2/V>}sM~G ^xjtSƏ>`ŤqE  *WL PaXƞY,*iv SeUBxWEtek⪪*K **+i666j`L.25}Q󞗮V(%E vib_ޛK3c7P+To@B+Dpg9 Ł?) iP$bXo~h2+nD¢"Ќ 1+/hTX;O-JKKJ󞗮 ,8|>ljv@tWQ]~?hG*][QO+*+J/^rоCuJ  #CCNqh?ߴmu9.K͜[TݞWRYUIl%j~tNEeVdry 4y]G,n:ҞZ6uu&ƭ@2Š _hS@Zg^h m/5Y$'30'pǩ|.&YEs2b$3hFf\G Kˋ kq]gw$pGltS lnJl5};$U_ŨR }CXwwdp~%>Q:3!yK5֚:Tr}-WǮ:D52ݐl"p6ц'a.*jq5+:a yLMW:@iS="`ߣJT7h z{t{0 yG }|6 Y\AbgB`jz6mftcg$;nEƄܮ>t7k`"hA8Muc]Z O0p@P:sprbaq%WUx&r^(ޜjcX#ؽx KgYK,$N՗VG 6 Mc$NIOӘ!.Rt`WY+4δȈ_*<ϖyf`~ L|ǽAwkr@ ϼudt̡@d]iD>"<1[. }neI%71ېH':@W,M%2.sX#嗛9Z&ikko^4&FۛC!ެH'zhEP正g*HZ)f*2ɬkn^j/'p:Pp1vΰ$.Jo!06W nىyϳ;tOcD %7].)46.U>ִvn6Yt+uvgvܟ!)XAO:qIEЕ@/o`W+1eGKcnSD<b]mȗE%2~K5/Ƞ#Sg; 蚯[@ %bA| pǑ}\Xi\^#TָX`疛ʸ2JSa{kfaX.=PG N{=3O3 dVߣ1MuTY\',ͻXZZP[zxzVG ʭ}:?²J, Q6+GcJʷlq7ߦQڻ$aMS{_&)<6󜎺ԩSǏWOzO BP4`PgMj1;մ!h) !#퀞:& cuD  أ @N6\ <M\MYnr6K-U4,+hWQ4?U=&ë颴Kc{XJG  MzҸ'dx5]{i 3^X++xhS@ E& M $h~@ @UP@ @UЗdW3x`777q8NQA7.;o޼{JR}gΜ9/^j,aiR>ڢ*.iӦݿ?))ɳNNNB0&&FE m;}ۯoZ.#.h~=C|sYήݻkObb{ѣ?o߾> @7 z!cǎ=zt֭3gp8MOhh(kӧ=zСC .j"ڵnڴ)$Dݖү|-^O>a8;;^ T]8|&j^ě/Qn+޵]FuP=3~:|Ͽ{ĉ\ҥK i HKK{Iaa֭ĉٳg:th̰SN>}֭[O2:u%KV\iiid5}ďa50 ^zܹp;w???CCC33+=uԻ 9ٳY{UՖJKNN3VVV999sڿOOObllT%MC @ d_4i_P][{v@L{ŋFR67$YoPPMӾ J̙+Wqu5o 6lSSS3e\[l زeK׮]է_Ux)S]v̘1666WQ /E"Qpp… ߈ ޽{ƪOu뜝;tvZHv)Sۿk׮m0nccn:HDӴSRRRUUs,1110 ,9r+:vz޽{3a bggw-5 ,=z01Jݳeii)EUVuqŊgD###??q <}:Ⱦ0Un3NIKe-gN8!mѣ?#//я?ҹsݻw++7n 0 ..RRR?w'N}\v 2227y뭛+Ⱦ/fػVˈviϐ$w˗ovS<O,7ʕ HݻwWnP$¬:trY,V666ׯ_gݻpLdkɓQkkkǕ[^xEyyׯ_qF$g͚&P($P(411 BBBΟ?9wtuyڵǎS61k$,+W0Ü <{,;;ˌ*U園VVVr_~ 111>>>"ƍL322,--_yPWB zP6޵]FL'//o޽W^]nݣG.xન(...,,իT)EQ,--1 k0knn^SS\eee)))MƯ>|nnnSjchhl@"7Sت´7 `֬YH|>ǫnA%&&:4<|8m4f6Ԕ'OΘ14beeqFgϞM>q32a„t5.چWS8. ǍZ##SԨCCCÌp)S(O;wn;v'*]0#s}]= wYhH$Zd YuIk_mQS)))|YLLr /'''!!)桼PWB &hK[i_޵]FLE&石g $Io޼YiqjjG֯_/J#""?~̴E]zuʨ>Ν;3[Pu[n̞={Ǐg_v`ӦM8aÆL##{)][^p1r/\ ayyy;vXlYNNN\\O?4cƌ{*;v4ʯԶSSSğ9,PCXXԩS{1sz*_ EPhO{mweէ f8uTk'/ByE"QUSL4il 8BP0LxU166~}7|>ܼxp7R.[_r:]U~rV&~cq\UMh*_Vٗv / ڗ֕keD}AѥK!C>|XN@ ^d_Ⱦ }/hBѻwoBaÆN@ Ⱦ !B @ }/h @ h @ h @ h @ h @ h @ h @ h`?@ hC?@ @ @ c^DԃvIENDB`go-pretty-6.4.6/cmd/demo-table/demo.go000066400000000000000000001171361437722442100175270ustar00rootroot00000000000000package main import ( "fmt" "os" "strings" "github.com/jedib0t/go-pretty/v6/table" "github.com/jedib0t/go-pretty/v6/text" ) var ( colTitleIndex = "#" colTitleFirstName = "First Name" colTitleLastName = "Last Name" colTitleSalary = "Salary" rowHeader = table.Row{colTitleIndex, colTitleFirstName, colTitleLastName, colTitleSalary} row1 = table.Row{1, "Arya", "Stark", 3000} row2 = table.Row{20, "Jon", "Snow", 2000, "You know nothing, Jon Snow!"} row3 = table.Row{300, "Tyrion", "Lannister", 5000} rowFooter = table.Row{"", "", "Total", 10000} ) func demoTableColors() { tw := table.NewWriter() tw.AppendHeader(rowHeader) tw.AppendRows([]table.Row{row1, row2, row3}) tw.AppendFooter(rowFooter) tw.SetIndexColumn(1) tw.SetTitle("Game Of Thrones") stylePairs := [][]table.Style{ {table.StyleColoredBright, table.StyleColoredDark}, {table.StyleColoredBlackOnBlueWhite, table.StyleColoredBlueWhiteOnBlack}, {table.StyleColoredBlackOnCyanWhite, table.StyleColoredCyanWhiteOnBlack}, {table.StyleColoredBlackOnGreenWhite, table.StyleColoredGreenWhiteOnBlack}, {table.StyleColoredBlackOnMagentaWhite, table.StyleColoredMagentaWhiteOnBlack}, {table.StyleColoredBlackOnRedWhite, table.StyleColoredRedWhiteOnBlack}, {table.StyleColoredBlackOnYellowWhite, table.StyleColoredYellowWhiteOnBlack}, } twOuter := table.NewWriter() twOuter.AppendHeader(table.Row{"Bright", "Dark"}) for _, stylePair := range stylePairs { row := make(table.Row, 2) for idx, style := range stylePair { tw.SetCaption(style.Name) tw.SetStyle(style) tw.Style().Title.Align = text.AlignCenter row[idx] = tw.Render() } twOuter.AppendRow(row) } twOuter.SetColumnConfigs([]table.ColumnConfig{ {Name: "Bright", Align: text.AlignCenter, AlignHeader: text.AlignCenter}, {Name: "Dark", Align: text.AlignCenter, AlignHeader: text.AlignCenter}, }) twOuter.SetStyle(table.StyleLight) twOuter.Style().Title.Align = text.AlignCenter twOuter.SetTitle("C O L O R S") twOuter.Style().Options.SeparateRows = true fmt.Println(twOuter.Render()) } func demoTableFeatures() { //========================================================================== // Initialization //========================================================================== t := table.NewWriter() // you can also instantiate the object directly tTemp := table.Table{} tTemp.Render() // just to avoid the compile error of not using the object //========================================================================== //========================================================================== // Append a few rows and render to console //========================================================================== // a row need not be just strings t.AppendRow(table.Row{1, "Arya", "Stark", 3000}) // all rows need not have the same number of columns t.AppendRow(table.Row{20, "Jon", "Snow", 2000, "You know nothing, Jon Snow!"}) // table.Row is just a shorthand for []interface{} t.AppendRow([]interface{}{300, "Tyrion", "Lannister", 5000}) // time to take a peek t.SetCaption("Simple Table with 3 Rows.\n") fmt.Println(t.Render()) //+-----+--------+-----------+------+-----------------------------+ //| 1 | Arya | Stark | 3000 | | //| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | //| 300 | Tyrion | Lannister | 5000 | | //+-----+--------+-----------+------+-----------------------------+ //Simple Table with 3 Rows and a separator. //========================================================================== //========================================================================== // Can you index the columns? //========================================================================== t.SetAutoIndex(true) t.SetCaption("Table with Auto-Indexing.\n") fmt.Println(t.Render()) //+---+-----+--------+-----------+------+-----------------------------+ //| | A | B | C | D | E | //+---+-----+--------+-----------+------+-----------------------------+ //| 1 | 1 | Arya | Stark | 3000 | | //| 2 | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | //| 3 | 300 | Tyrion | Lannister | 5000 | | //+---+-----+--------+-----------+------+-----------------------------+ //Table with Auto-Indexing. // t.AppendHeader(rowHeader) t.SetCaption("Table with Auto-Indexing (columns-only).\n") fmt.Println(t.Render()) //+---+-----+------------+-----------+--------+-----------------------------+ //| | # | FIRST NAME | LAST NAME | SALARY | | //+---+-----+------------+-----------+--------+-----------------------------+ //| 1 | 1 | Arya | Stark | 3000 | | //| 2 | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | //| 3 | 300 | Tyrion | Lannister | 5000 | | //+---+-----+------------+-----------+--------+-----------------------------+ //========================================================================== //========================================================================== // A table needs to have a Header & Footer (for this demo at least!) //========================================================================== t.SetAutoIndex(false) t.SetCaption("Table with 3 Rows & and a Header.\n") fmt.Println(t.Render()) //+-----+------------+-----------+--------+-----------------------------+ //| # | FIRST NAME | LAST NAME | SALARY | | //+-----+------------+-----------+--------+-----------------------------+ //| 1 | Arya | Stark | 3000 | | //| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | //| 300 | Tyrion | Lannister | 5000 | | //+-----+------------+-----------+--------+-----------------------------+ //Table with 3 Rows & and a Header. // // and then add a footer t.AppendFooter(table.Row{"", "", "Total", 10000}) // time to take a peek t.SetCaption("Table with 3 Rows, a Header & a Footer.\n") fmt.Println(t.Render()) //+-----+------------+-----------+--------+-----------------------------+ //| # | FIRST NAME | LAST NAME | SALARY | | //+-----+------------+-----------+--------+-----------------------------+ //| 1 | Arya | Stark | 3000 | | //| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | //| 300 | Tyrion | Lannister | 5000 | | //+-----+------------+-----------+--------+-----------------------------+ //| | | TOTAL | 10000 | | //+-----+------------+-----------+--------+-----------------------------+ //Table with 3 Rows, a Header & a Footer. //========================================================================== //========================================================================== // Alignment? //========================================================================== // did you notice that the numeric columns were auto-aligned? when you don't // specify alignment, all the columns default to text.AlignDefault - numbers // go right and everything else left. but what if you want the first name to // go right too? and the last column to be "justified"? t.SetColumnConfigs([]table.ColumnConfig{ {Name: colTitleFirstName, Align: text.AlignRight}, // the 5th column does not have a title, so use the column number as the // identifier for the column {Number: 5, Align: text.AlignJustify}, }) // to show AlignJustify in action, lets add one more row t.AppendRow(table.Row{4, "Faceless", "Man", 0, "Needs a\tname."}) // time to take a peek: t.SetCaption("Table with Custom Alignment for 2 columns.\n") fmt.Println(t.Render()) //+-----+------------+-----------+--------+-----------------------------+ //| # | FIRST NAME | LAST NAME | SALARY | | //+-----+------------+-----------+--------+-----------------------------+ //| 1 | Arya | Stark | 3000 | | //| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | //| 300 | Tyrion | Lannister | 5000 | | //| 4 | Faceless | Man | 0 | Needs a name. | //+-----+------------+-----------+--------+-----------------------------+ //| | | TOTAL | 10000 | | //+-----+------------+-----------+--------+-----------------------------+ //Table with Custom Alignment for 2 columns. //========================================================================== //========================================================================== // Vertical Alignment? //========================================================================== // horizontal alignment is fine... what about vertical? lets add a row with // a column having multiple lines; and then play with VAlign t.AppendRow(table.Row{13, "Winter\nIs\nComing", "Valar\nMorghulis", 0, "You\n know\n nothing,\n Jon\n Snow!"}) // first without any custom VAlign t.SetCaption("Table with a Multi-line Row.\n") fmt.Println(t.Render()) //+-----+------------+-----------+--------+-----------------------------+ //| # | FIRST NAME | LAST NAME | SALARY | | //+-----+------------+-----------+--------+-----------------------------+ //| 1 | Arya | Stark | 3000 | | //| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | //| 300 | Tyrion | Lannister | 5000 | | //| 4 | Faceless | Man | 0 | Needs a name. | //| 13 | Winter | Valar | 0 | You | //| | Is | Morghulis | | know | //| | Coming | | | nothing, | //| | | | | Jon | //| | | | | Snow! | //+-----+------------+-----------+--------+-----------------------------+ //| | | TOTAL | 10000 | | //+-----+------------+-----------+--------+-----------------------------+ //Table with a Multi-line Row. // // time to Align/VAlign the columns... t.SetColumnConfigs([]table.ColumnConfig{ {Name: colTitleFirstName, Align: text.AlignRight, VAlign: text.VAlignMiddle}, {Name: colTitleLastName, VAlign: text.VAlignBottom}, {Name: colTitleSalary, Align: text.AlignRight, VAlign: text.VAlignMiddle}, // the 5th column does not have a title, so use the column number {Number: 5, Align: text.AlignJustify}, }) t.SetCaption("Table with a Multi-line Row with VAlign.\n") fmt.Println(t.Render()) //+-----+------------+-----------+--------+-----------------------------+ //| # | FIRST NAME | LAST NAME | SALARY | | //+-----+------------+-----------+--------+-----------------------------+ //| 1 | Arya | Stark | 3000 | | //| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | //| 300 | Tyrion | Lannister | 5000 | | //| 4 | Faceless | Man | 0 | Needs a name. | //| 13 | | | | You | //| | Winter | | | know | //| | Is | | 0 | nothing, | //| | Coming | Valar | | Jon | //| | | Morghulis | | Snow! | //+-----+------------+-----------+--------+-----------------------------+ //| | | TOTAL | 10000 | | //+-----+------------+-----------+--------+-----------------------------+ //Table with a Multi-line Row with VAlign. // // changed your mind about AlignJustify? t.SetColumnConfigs([]table.ColumnConfig{ {Name: colTitleFirstName, Align: text.AlignRight, VAlign: text.VAlignMiddle}, {Name: colTitleLastName, VAlign: text.VAlignBottom}, {Name: colTitleSalary, Align: text.AlignRight, VAlign: text.VAlignMiddle}, {Number: 5, Align: text.AlignCenter}, }) t.SetCaption("Table with a Multi-line Row with VAlign and changed Align.\n") fmt.Println(t.Render()) //+-----+------------+-----------+--------+-----------------------------+ //| # | FIRST NAME | LAST NAME | SALARY | | //+-----+------------+-----------+--------+-----------------------------+ //| 1 | Arya | Stark | 3000 | | //| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | //| 300 | Tyrion | Lannister | 5000 | | //| 4 | Faceless | Man | 0 | Needs a name. | //| 13 | | | | You | //| | Winter | | | know | //| | Is | | 0 | nothing, | //| | Coming | Valar | | Jon | //| | | Morghulis | | Snow! | //+-----+------------+-----------+--------+-----------------------------+ //| | | TOTAL | 10000 | | //+-----+------------+-----------+--------+-----------------------------+ //Table with a Multi-line Row with VAlign and changed Align. //========================================================================== //========================================================================== // Time to begin anew. Too much on the screen for a demo! How about some // custom separators? //========================================================================== t.ResetRows() t.AppendRow(row1) t.AppendRow(row2) t.AppendSeparator() t.AppendRow(row3) t.SetCaption("Simple Table with 3 Rows and a Separator in-between.\n") fmt.Println(t.Render()) //+-----+--------+-----------+------+-----------------------------+ //| 1 | Arya | Stark | 3000 | | //| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | //+-----+--------+-----------+------+-----------------------------+ //| 300 | Tyrion | Lannister | 5000 | | //+-----+--------+-----------+------+-----------------------------+ //Simple Table with 3 Rows and a Separator in-between. //========================================================================== //========================================================================== // Never-mind, lets start over yet again! //========================================================================== t.ResetRows() t.SetColumnConfigs(nil) t.AppendRow(row1) t.AppendRow(row2) t.AppendRow(row3) t.SetCaption("Starting afresh with a Simple Table again.\n") fmt.Println(t.Render()) //+-----+------------+-----------+--------+-----------------------------+ //| # | FIRST NAME | LAST NAME | SALARY | | //+-----+------------+-----------+--------+-----------------------------+ //| 1 | Arya | Stark | 3000 | | //| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | //| 300 | Tyrion | Lannister | 5000 | | //+-----+------------+-----------+--------+-----------------------------+ //| | | TOTAL | 10000 | | //+-----+------------+-----------+--------+-----------------------------+ //Starting afresh with a Simple Table again. //========================================================================== //========================================================================== // Does it support paging? //========================================================================== t.SetPageSize(1) t.Style().Box.PageSeparator = "\n... page break ..." t.SetCaption("Table with a PageSize of 1.\n") fmt.Println(t.Render()) //+-----+------------+-----------+--------+-----------------------------+ //| # | FIRST NAME | LAST NAME | SALARY | | //+-----+------------+-----------+--------+-----------------------------+ //| 1 | Arya | Stark | 3000 | | //+-----+------------+-----------+--------+-----------------------------+ //| | | TOTAL | 10000 | | //+-----+------------+-----------+--------+-----------------------------+ //... page break ... //+-----+------------+-----------+--------+-----------------------------+ //| # | FIRST NAME | LAST NAME | SALARY | | //+-----+------------+-----------+--------+-----------------------------+ //| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | //+-----+------------+-----------+--------+-----------------------------+ //| | | TOTAL | 10000 | | //+-----+------------+-----------+--------+-----------------------------+ //... page break ... //+-----+------------+-----------+--------+-----------------------------+ //| # | FIRST NAME | LAST NAME | SALARY | | //+-----+------------+-----------+--------+-----------------------------+ //| 300 | Tyrion | Lannister | 5000 | | //+-----+------------+-----------+--------+-----------------------------+ //| | | TOTAL | 10000 | | //+-----+------------+-----------+--------+-----------------------------+ //Table with a PageSize of 1. t.SetPageSize(0) // disables paging //========================================================================== //========================================================================== // How about limiting the length of every Row? //========================================================================== t.SetAllowedRowLength(50) t.SetCaption("Table with an Allowed Row Length of 50.\n") fmt.Println(t.Render()) //+-----+------------+-----------+--------+------- ~ //| # | FIRST NAME | LAST NAME | SALARY | ~ //+-----+------------+-----------+--------+------- ~ //| 1 | Arya | Stark | 3000 | ~ //| 20 | Jon | Snow | 2000 | You kn ~ //| 300 | Tyrion | Lannister | 5000 | ~ //+-----+------------+-----------+--------+------- ~ //| | | TOTAL | 10000 | ~ //+-----+------------+-----------+--------+------- ~ t.SetStyle(table.StyleDouble) t.SetCaption("Table with an Allowed Row Length of 50 in 'StyleDouble'.\n") fmt.Println(t.Render()) //╔═════╦════════════╦═══════════╦════════╦═══════ ≈ //║ # ║ FIRST NAME ║ LAST NAME ║ SALARY ║ ≈ //╠═════╬════════════╬═══════════╬════════╬═══════ ≈ //║ 1 ║ Arya ║ Stark ║ 3000 ║ ≈ //║ 20 ║ Jon ║ Snow ║ 2000 ║ You kn ≈ //║ 300 ║ Tyrion ║ Lannister ║ 5000 ║ ≈ //╠═════╬════════════╬═══════════╬════════╬═══════ ≈ //║ ║ ║ TOTAL ║ 10000 ║ ≈ //╚═════╩════════════╩═══════════╩════════╩═══════ ≈ //Table with an Allowed Row Length of 50 in 'StyleDouble'. //========================================================================== //========================================================================== // But I want to see all the data! //========================================================================== t.SetColumnConfigs([]table.ColumnConfig{ {Name: colTitleFirstName, WidthMax: 6}, {Name: colTitleLastName, WidthMax: 9}, {Name: colTitleSalary, WidthMax: 6}, {Number: 5, WidthMax: 10}, }) t.SetCaption("Table on a diet.\n") t.SetStyle(table.StyleRounded) fmt.Println(t.Render()) //╭─────┬────────┬───────────┬────────┬────────────╮ //│ # │ FIRST │ LAST NAME │ SALARY │ │ //│ │ NAME │ │ │ │ //├─────┼────────┼───────────┼────────┼────────────┤ //│ 1 │ Arya │ Stark │ 3000 │ │ //│ 20 │ Jon │ Snow │ 2000 │ You know n │ //│ │ │ │ │ othing, Jo │ //│ │ │ │ │ n Snow! │ //│ 300 │ Tyrion │ Lannister │ 5000 │ │ //├─────┼────────┼───────────┼────────┼────────────┤ //│ │ │ TOTAL │ 10000 │ │ //╰─────┴────────┴───────────┴────────┴────────────╯ //Table on a diet. t.SetAllowedRowLength(0) // remove the width restrictions t.SetColumnConfigs([]table.ColumnConfig{}) //========================================================================== //========================================================================== // ASCII is too simple for me. //========================================================================== t.SetStyle(table.StyleLight) t.SetCaption("Table using the style 'StyleLight'.\n") fmt.Println(t.Render()) //┌─────┬────────────┬───────────┬────────┬─────────────────────────────┐ //│ # │ FIRST NAME │ LAST NAME │ SALARY │ │ //├─────┼────────────┼───────────┼────────┼─────────────────────────────┤ //│ 1 │ Arya │ Stark │ 3000 │ │ //│ 20 │ Jon │ Snow │ 2000 │ You know nothing, Jon Snow! │ //│ 300 │ Tyrion │ Lannister │ 5000 │ │ //├─────┼────────────┼───────────┼────────┼─────────────────────────────┤ //│ │ │ TOTAL │ 10000 │ │ //└─────┴────────────┴───────────┴────────┴─────────────────────────────┘ //Table using the style 'StyleLight'. t.SetStyle(table.StyleDouble) t.SetCaption("Table using the style '%s'.\n", t.Style().Name) fmt.Println(t.Render()) //╔═════╦════════════╦═══════════╦════════╦═════════════════════════════╗ //║ # ║ FIRST NAME ║ LAST NAME ║ SALARY ║ ║ //╠═════╬════════════╬═══════════╬════════╬═════════════════════════════╣ //║ 1 ║ Arya ║ Stark ║ 3000 ║ ║ //║ 20 ║ Jon ║ Snow ║ 2000 ║ You know nothing, Jon Snow! ║ //║ 300 ║ Tyrion ║ Lannister ║ 5000 ║ ║ //╠═════╬════════════╬═══════════╬════════╬═════════════════════════════╣ //║ ║ ║ TOTAL ║ 10000 ║ ║ //╚═════╩════════════╩═══════════╩════════╩═════════════════════════════╝ //Table using the style 'StyleDouble'. //========================================================================== //========================================================================== // I don't like any of the ready-made styles. //========================================================================== t.SetStyle(table.Style{ Name: "funkyStyle", Box: table.BoxStyle{ BottomLeft: "\\", BottomRight: "/", BottomSeparator: "v", Left: "[", LeftSeparator: "{", MiddleHorizontal: "-", MiddleSeparator: "+", MiddleVertical: "|", PaddingLeft: "<", PaddingRight: ">", Right: "]", RightSeparator: "}", TopLeft: "(", TopRight: ")", TopSeparator: "^", UnfinishedRow: " ~~~", }, }) t.Style().Format = table.FormatOptions{ Footer: text.FormatLower, Header: text.FormatLower, Row: text.FormatUpper, } t.Style().Options.DrawBorder = true t.Style().Options.SeparateColumns = true t.Style().Options.SeparateFooter = true t.Style().Options.SeparateHeader = true t.SetCaption("Table using the style 'funkyStyle'.\n") fmt.Println(t.Render()) //(-----^------------^-----------^--------^-----------------------------) //[< #>||||< >] //{-----+------------+-----------+--------+-----------------------------} //[< 1>|||< 3000>|< >] //[< 20>|||< 2000>|] //[<300>|||< 5000>|< >] //{-----+------------+-----------+--------+-----------------------------} //[< >|< >||< 10000>|< >] //\-----v------------v-----------v--------v-----------------------------/ //Table using the style 'funkyStyle'. //========================================================================== //========================================================================== // I need some color in my life! //========================================================================== t.SetStyle(table.StyleBold) colorBOnW := text.Colors{text.BgWhite, text.FgBlack} // set colors using Colors/ColorsHeader/ColorsFooter t.SetColumnConfigs([]table.ColumnConfig{ {Name: colTitleIndex, Colors: text.Colors{text.FgYellow}, ColorsHeader: colorBOnW}, {Name: colTitleFirstName, Colors: text.Colors{text.FgHiRed}, ColorsHeader: colorBOnW}, {Name: colTitleLastName, Colors: text.Colors{text.FgHiRed}, ColorsHeader: colorBOnW, ColorsFooter: colorBOnW}, {Name: colTitleSalary, Colors: text.Colors{text.FgGreen}, ColorsHeader: colorBOnW, ColorsFooter: colorBOnW}, {Number: 5, Colors: text.Colors{text.FgCyan}, ColorsHeader: colorBOnW}, }) t.SetCaption("Table with Colors.\n") fmt.Println(t.Render()) //┏━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ //┃ # ┃ FIRST NAME ┃ LAST NAME ┃ SALARY ┃ ┃ //┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ //┃ 1 ┃ Arya ┃ Stark ┃ 3000 ┃ ┃ //┃ 20 ┃ Jon ┃ Snow ┃ 2000 ┃ You know nothing, Jon Snow! ┃ //┃ 300 ┃ Tyrion ┃ Lannister ┃ 5000 ┃ ┃ //┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ //┃ ┃ ┃ TOTAL ┃ 10000 ┃ ┃ //┗━━━━━┻━━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ //Table with Colors. // // "Table with Colors"??? where? i don't see any! well, you have to trust me // on this... the colors show on a terminal that supports it. to prove it, // lets print the same table line-by-line using "%#v" to see the control // sequences ... t.SetCaption("Table with Colors in Raw Mode.\n") for _, line := range strings.Split(t.Render(), "\n") { if line != "" { fmt.Printf("%#v\n", line) } } fmt.Println() //"┏━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓" //"┃\x1b[47;30m # \x1b[0m┃\x1b[47;30m FIRST NAME \x1b[0m┃\x1b[47;30m LAST NAME \x1b[0m┃\x1b[47;30m SALARY \x1b[0m┃\x1b[47;30m \x1b[0m┃" //"┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫" //"┃\x1b[33m 1 \x1b[0m┃\x1b[91m Arya \x1b[0m┃\x1b[91m Stark \x1b[0m┃\x1b[32m 3000 \x1b[0m┃\x1b[36m \x1b[0m┃" //"┃\x1b[33m 20 \x1b[0m┃\x1b[91m Jon \x1b[0m┃\x1b[91m Snow \x1b[0m┃\x1b[32m 2000 \x1b[0m┃\x1b[36m You know nothing, Jon Snow! \x1b[0m┃" //"┃\x1b[33m 300 \x1b[0m┃\x1b[91m Tyrion \x1b[0m┃\x1b[91m Lannister \x1b[0m┃\x1b[32m 5000 \x1b[0m┃\x1b[36m \x1b[0m┃" //"┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫" //"┃ ┃ ┃\x1b[47;30m TOTAL \x1b[0m┃\x1b[47;30m 10000 \x1b[0m┃ ┃" //"┗━━━━━┻━━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛" //"Table with Colors in Raw Mode." //"" // disable colors and revert to previous version of the column configs t.SetColumnConfigs([]table.ColumnConfig{}) //========================================================================== //========================================================================== // How about not asking me to set colors in such a verbose way? And I don't // like wasting my terminal space with borders and separators. //========================================================================== t.SetStyle(table.StyleColoredBright) t.SetCaption("Table with style 'StyleColoredBright'.\n") fmt.Println(t.Render()) // # FIRST NAME LAST NAME SALARY // 1 Arya Stark 3000 // 20 Jon Snow 2000 You know nothing, Jon Snow! // 300 Tyrion Lannister 5000 // TOTAL 10000 //Table with style 'StyleColoredBright'. t.SetStyle(table.StyleBold) //========================================================================== //========================================================================== // I don't like borders! //========================================================================== t.Style().Options.DrawBorder = false t.SetCaption("Table without Borders.\n") fmt.Println(t.Render()) // # ┃ FIRST NAME ┃ LAST NAME ┃ SALARY ┃ //━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // 1 ┃ Arya ┃ Stark ┃ 3000 ┃ // 20 ┃ Jon ┃ Snow ┃ 2000 ┃ You know nothing, Jon Snow! // 300 ┃ Tyrion ┃ Lannister ┃ 5000 ┃ //━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // ┃ ┃ TOTAL ┃ 10000 ┃ //Table without Borders. //========================================================================== //========================================================================== // I like walls and borders everywhere! //========================================================================== t.Style().Options.DrawBorder = true t.Style().Options.SeparateRows = true t.SetCaption("Table with Borders Everywhere!\n") t.SetTitle("Divide!") fmt.Println(t.Render()) //┏━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ //┃ # ┃ FIRST NAME ┃ LAST NAME ┃ SALARY ┃ ┃ //┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ //┃ 1 ┃ Arya ┃ Stark ┃ 3000 ┃ ┃ //┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ //┃ 20 ┃ Jon ┃ Snow ┃ 2000 ┃ You know nothing, Jon Snow! ┃ //┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ //┃ 300 ┃ Tyrion ┃ Lannister ┃ 5000 ┃ ┃ //┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ //┃ ┃ ┃ TOTAL ┃ 10000 ┃ ┃ //┗━━━━━┻━━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ //Table with Borders Everywhere! //========================================================================== //========================================================================== // There is strength in Unity. //========================================================================== t.Style().Options.DrawBorder = false t.Style().Options.SeparateColumns = false t.Style().Options.SeparateFooter = false t.Style().Options.SeparateHeader = false t.Style().Options.SeparateRows = false t.SetCaption("(c) No one!") t.SetTitle("Unite!") fmt.Println(t.Render()) fmt.Println() // # FIRST NAME LAST NAME SALARY // 1 Arya Stark 3000 // 20 Jon Snow 2000 You know nothing, Jon Snow! // 300 Tyrion Lannister 5000 // TOTAL 10000 //Table without Any Borders or Separators! //========================================================================== //========================================================================== // I want CSV. //========================================================================== for _, line := range strings.Split(t.RenderCSV(), "\n") { fmt.Printf("[CSV] %s\n", line) } fmt.Println() //[CSV] #,First Name,Last Name,Salary, //[CSV] 1,Arya,Stark,3000, //[CSV] 20,Jon,Snow,2000,"You know nothing\, Jon Snow!" //[CSV] 300,Tyrion,Lannister,5000, //[CSV] ,,Total,10000, //========================================================================== //========================================================================== // Nope. I want a HTML Table. //========================================================================== for _, line := range strings.Split(t.RenderHTML(), "\n") { fmt.Printf("[HTML] %s\n", line) } fmt.Println() //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML] //[HTML]
#First NameLast NameSalary 
1AryaStark3000 
20JonSnow2000You know nothing, Jon Snow!
300TyrionLannister5000 
  Total10000 
//========================================================================== //========================================================================== // Nope. I want a Markdown Table now. //========================================================================== for _, line := range strings.Split(t.RenderMarkdown(), "\n") { fmt.Printf("[Markdown] %s\n", line) } fmt.Println() //[Markdown] | # | First Name | Last Name | Salary | | //[Markdown] | ---:| --- | --- | ---:| --- | //[Markdown] | 1 | Arya | Stark | 3000 | | //[Markdown] | 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! | //[Markdown] | 300 | Tyrion | Lannister | 5000 | | //[Markdown] | | | Total | 10000 | | //========================================================================== //========================================================================== // That's it for today! New features will always find a place in this demo! //========================================================================== } func demoTableEmoji() { styles := []table.Style{ table.StyleDefault, table.StyleLight, table.StyleColoredBright, } for _, style := range styles { tw := table.NewWriter() tw.AppendHeader(table.Row{"Key", "Value"}) tw.AppendRows([]table.Row{ {"Emoji 1 🥰", 1000}, {"Emoji 2 ⚔️", 2000}, {"Emoji 3 🎁", 3000}, {"Emoji 4 ツ", 4000}, }) tw.AppendFooter(table.Row{"Total", 10000}) tw.SetAutoIndex(true) tw.SetStyle(style) fmt.Println(tw.Render()) fmt.Println() } } func main() { demoWhat := "features" if len(os.Args) > 1 { demoWhat = os.Args[1] } switch strings.ToLower(demoWhat) { case "colors": demoTableColors() case "emoji": demoTableEmoji() default: demoTableFeatures() } } go-pretty-6.4.6/cmd/profile-list/000077500000000000000000000000001437722442100166435ustar00rootroot00000000000000go-pretty-6.4.6/cmd/profile-list/profile.go000066400000000000000000000017161437722442100206370ustar00rootroot00000000000000package main import ( "fmt" "os" "strconv" "github.com/jedib0t/go-pretty/v6/list" "github.com/pkg/profile" ) var ( listItem1 = "Game Of Thrones" listItems2 = []interface{}{"Winter", "Is", "Coming"} listItems3 = []interface{}{"This", "Is", "Known"} profilers = []func(*profile.Profile){ profile.CPUProfile, profile.MemProfileRate(512), } ) func profileRender(profiler func(profile2 *profile.Profile), n int) { defer profile.Start(profiler, profile.ProfilePath("./")).Stop() for i := 0; i < n; i++ { lw := list.NewWriter() lw.AppendItem(listItem1) lw.Indent() lw.AppendItems(listItems2) lw.Indent() lw.AppendItems(listItems3) lw.Render() } } func main() { numRenders := 100000 if len(os.Args) > 1 { var err error numRenders, err = strconv.Atoi(os.Args[2]) if err != nil { fmt.Printf("Invalid Argument: '%s'\n", os.Args[2]) os.Exit(1) } } for _, profiler := range profilers { profileRender(profiler, numRenders) } } go-pretty-6.4.6/cmd/profile-progress/000077500000000000000000000000001437722442100175345ustar00rootroot00000000000000go-pretty-6.4.6/cmd/profile-progress/profile.go000066400000000000000000000030231437722442100215210ustar00rootroot00000000000000package main import ( "fmt" "io/ioutil" "os" "strconv" "time" "github.com/jedib0t/go-pretty/v6/progress" "github.com/pkg/profile" ) var ( tracker1 = progress.Tracker{Message: "Calculating Total # 1", Total: 1000, Units: progress.UnitsDefault} tracker2 = progress.Tracker{Message: "Downloading File # 2", Total: 1000, Units: progress.UnitsBytes} tracker3 = progress.Tracker{Message: "Transferring Amount # 3", Total: 1000, Units: progress.UnitsCurrencyDollar} profilers = []func(*profile.Profile){ profile.CPUProfile, profile.MemProfileRate(512), } ) func profileRender(profiler func(profile2 *profile.Profile), n int) { defer profile.Start(profiler, profile.ProfilePath("./")).Stop() trackSomething := func(pw progress.Writer, tracker *progress.Tracker) { tracker.Reset() pw.AppendTracker(tracker) time.Sleep(time.Millisecond * 100) tracker.Increment(tracker.Total / 2) time.Sleep(time.Millisecond * 100) tracker.Increment(tracker.Total / 2) } for i := 0; i < n; i++ { pw := progress.NewWriter() pw.SetAutoStop(true) pw.SetOutputWriter(ioutil.Discard) go trackSomething(pw, &tracker1) go trackSomething(pw, &tracker2) go trackSomething(pw, &tracker3) time.Sleep(time.Millisecond * 50) pw.Render() } } func main() { numRenders := 5 if len(os.Args) > 1 { var err error numRenders, err = strconv.Atoi(os.Args[2]) if err != nil { fmt.Printf("Invalid Argument: '%s'\n", os.Args[2]) os.Exit(1) } } for _, profiler := range profilers { profileRender(profiler, numRenders) } } go-pretty-6.4.6/cmd/profile-table/000077500000000000000000000000001437722442100167575ustar00rootroot00000000000000go-pretty-6.4.6/cmd/profile-table/profile.go000066400000000000000000000023241437722442100207470ustar00rootroot00000000000000package main import ( "fmt" "os" "strconv" "github.com/jedib0t/go-pretty/v6/table" "github.com/pkg/profile" ) var ( profilers = []func(*profile.Profile){ profile.CPUProfile, profile.MemProfileRate(512), } tableCaption = "Profiling a Simple Table." tableRowFooter = table.Row{"", "", "Total", 10000} tableRowHeader = table.Row{"#", "First Name", "Last Name", "Salary"} tableRows = []table.Row{ {1, "Arya", "Stark", 3000}, {20, "Jon", "Snow", 2000, "You know nothing, Jon Snow!"}, {300, "Tyrion", "Lannister", 5000}, } ) func profileRender(profiler func(profile2 *profile.Profile), n int) { defer profile.Start(profiler, profile.ProfilePath(".")).Stop() for i := 0; i < n; i++ { tw := table.NewWriter() tw.AppendHeader(tableRowHeader) tw.AppendRows(tableRows) tw.AppendFooter(tableRowFooter) tw.SetCaption(tableCaption) tw.Render() tw.RenderCSV() tw.RenderHTML() tw.RenderMarkdown() } } func main() { numRenders := 100000 if len(os.Args) > 1 { var err error numRenders, err = strconv.Atoi(os.Args[2]) if err != nil { fmt.Printf("Invalid Argument: '%s'\n", os.Args[2]) os.Exit(1) } } for _, profiler := range profilers { profileRender(profiler, numRenders) } } go-pretty-6.4.6/go.mod000066400000000000000000000003001437722442100145660ustar00rootroot00000000000000module github.com/jedib0t/go-pretty/v6 go 1.16 require ( github.com/mattn/go-runewidth v0.0.13 github.com/pkg/profile v1.6.0 github.com/stretchr/testify v1.7.4 golang.org/x/sys v0.1.0 ) go-pretty-6.4.6/go.sum000066400000000000000000000037151437722442100146300ustar00rootroot00000000000000github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/pkg/profile v1.6.0 h1:hUDfIISABYI59DyeB3OTay/HxSRwTQ8rB/H83k6r5dM= github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.4 h1:wZRexSlwd7ZXfKINDLsO4r7WBt3gTKONc6K/VesHvHM= github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= go-pretty-6.4.6/list/000077500000000000000000000000001437722442100144425ustar00rootroot00000000000000go-pretty-6.4.6/list/README.md000066400000000000000000000015041437722442100157210ustar00rootroot00000000000000## List [![Go Reference](https://pkg.go.dev/badge/github.com/jedib0t/go-pretty/v6/list.svg)](https://pkg.go.dev/github.com/jedib0t/go-pretty/v6/list) Pretty-print lists with multiple levels/indents into ASCII/Unicode strings. - Append Items one-by-one or as a group - Indent/UnIndent as you like - Support Items with Multiple-lines - Mirror output to an io.Writer object (like os.StdOut) - Completely customizable styles - Many ready-to-use styles: [style.go](style.go) - Render as: - (ASCII/Unicode) List - HTML List (with custom CSS Class) - Markdown List ``` ■ Game Of Thrones ■ Winter ■ Is ■ Coming ■ This ■ Is ■ Known ■ The Dark Tower ■ The Gunslinger ``` A demonstration of all the capabilities can be found here: [../cmd/demo-list](../cmd/demo-list) go-pretty-6.4.6/list/list.go000066400000000000000000000110651437722442100157470ustar00rootroot00000000000000package list import ( "fmt" "io" "strings" "unicode/utf8" ) const ( // DefaultHTMLCSSClass stores the css-class to use when none-provided via // SetHTMLCSSClass(cssClass string). DefaultHTMLCSSClass = "go-pretty-table" ) // listItem represents one line in the List type listItem struct { Level int Text string } // List helps print a 2-dimensional array in a human readable pretty-List. type List struct { // approxSize stores the approximate output length/size approxSize int // htmlCSSClass stores the HTML CSS Class to use on the