From 960da65723cd68383c40aeca046ad9dc943a276b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Sun, 3 Sep 2017 08:20:27 +0200 Subject: [PATCH] Write better readme (#837) Add a new readme that is more succinct and easier to understand for people encountering Pester for the first time. --- Examples/Planets/Get-Planet.Tests.ps1 | 151 +++++++++++++++++++ Examples/Planets/Get-Planet.ps1 | 23 +++ README.md | 206 +++++++++++++++----------- doc/readme/gitter-64.PNG | Bin 0 -> 746 bytes doc/readme/jacoco.PNG | Bin 0 -> 9320 bytes doc/readme/output.PNG | Bin 0 -> 21553 bytes doc/readme/slack-64.PNG | Bin 0 -> 6243 bytes doc/readme/stack-overflow-64.PNG | Bin 0 -> 2527 bytes doc/readme/twitter-64.PNG | Bin 0 -> 2168 bytes 9 files changed, 292 insertions(+), 88 deletions(-) create mode 100644 Examples/Planets/Get-Planet.Tests.ps1 create mode 100644 Examples/Planets/Get-Planet.ps1 create mode 100644 doc/readme/gitter-64.PNG create mode 100644 doc/readme/jacoco.PNG create mode 100644 doc/readme/output.PNG create mode 100644 doc/readme/slack-64.PNG create mode 100644 doc/readme/stack-overflow-64.PNG create mode 100644 doc/readme/twitter-64.PNG diff --git a/Examples/Planets/Get-Planet.Tests.ps1 b/Examples/Planets/Get-Planet.Tests.ps1 new file mode 100644 index 000000000..fdd87fc51 --- /dev/null +++ b/Examples/Planets/Get-Planet.Tests.ps1 @@ -0,0 +1,151 @@ +# In practice tests and your code are placed in two +# separate files. Tests belong in .Tests.ps1 file and code belongs +# in .ps1 file. Open the Get-Planet.ps1 file as well, please. + + +# You can run this test file by pressing F5, if your editor +# suports running powershell. + +# You should see this output: +# Describing Get-Planet +# [+] Given no parameters, it lists all 8 planets 55ms +# +# Context Filtering by Name +# [+] Given valid -Name 'Earth', it returns 'Earth' 61ms +# [+] Given valid -Name 'ne*', it returns 'Neptune' 11ms +# [+] Given valid -Name 'ur*', it returns 'Uranus' 19ms +# [+] Given valid -Name 'm*', it returns 'Mercury Mars' 9ms +# [+] Given invalid parameter -Name 'Alpha Centauri', it returns $null 22ms + + +# First we need to import the Get-Planet.ps1 file to make the function +# Get-Planet available to our test. Notice the . at the start +# of the line. +$here = (Split-Path -Parent $MyInvocation.MyCommand.Path) +. $here\Get-Planet.ps1 + +# Normally we would use this PowerShell 3 and newer compatible +# version of the same code, but we need to keep our examples +# compatible with PowerShell v2. +# . $PSScriptRoot\Get-Planet.ps1 + + +# Describe groups tests for easy navigation and overview. +# Usually we use the name of the function we are testing as description +# for our test group. +Describe 'Get-Planet' { + + # 'It' performs a single test. We write informative description + # to tell others what is the result we expect. In this case + # we expect that calling Get-Planet without any parameters will + # return 8 items, because that is how many planets there are in our + # solar system. + It 'Given no parameters, it lists all 8 planets' { + # In the body of the test we repeat what our description says, + # but this time in code. + + # We call our Get-Planet function without any parameters + # and store the result for later examination. + $allPlanets = Get-Planet + + # We count how many planets we got. And validate it by using + # the Should -Be assertion. + $allPlanets.Count | Should -Be 8 + + # The assertion will do nothing if the count is 8, + # and throw an exception if the count is something else. + # Yes, it is this simple: if ($count -ne 8) { throw "Count is wrong"} + } + + # Context is the same as Describe, it groups our tests. Here we use + # it to group tests for filtering planets by name. + Context "Filtering by Name" { + + # We want our function to filter planets by name when -Name parameter is + # provided, and we want it to support wildcards in the name, because that + # is what most other functions do, and people expect this to be possible. + + + # We could write many individual tests to test this functionality, + # but most of them would be the same except for the data. So a better + # option is to use TestCases to provide multiple sets of data for our test + # but keep the body of the test the same. Pester then generates one test + # for each test case, and injects our values in parameters. + # This allows us to easily add more test cased as bugs start popping up, without + # duplicating code. + + + #There are three steps to make this work: description, paramaters, and testcases. + + # We put names of our parameters in the description and sorround them by <>. + # Pester will expand test values into desciption, for example: + # Given valid -Name 'ne*', it returns 'Neptune' + It "Given valid -Name '', it returns ''" -TestCases @( + + # We define an array of hashtables. Each hashtable will be used + # for one test. + # @{ Filter = 'ne*' ; Expected = 'Neptune' } + # Every hashtable has keys named as our parameters, that is Filter and Expected. + # And values that will be injected in our test, in this case 'ne*' and 'Neptune'. + @{ Filter = 'Earth'; Expected = 'Earth' } + @{ Filter = 'ne*' ; Expected = 'Neptune' } + @{ Filter = 'ur*' ; Expected = 'Uranus' } + @{ Filter = 'm*' ; Expected = 'Mercury', 'Mars' } + ) { + + # We define parameters in param (), to pass our test data into the test body. + # Paremeter names must align with key names in the hashtables. + param ($Filter, $Expected) + + # We pass $Filter to -Name, for example 'ne*' in our second test. + $planets = Get-Planet -Name $Filter + # We validate that the returned name is equal to $Expected. + # That is Neptune, in our second test. + $planets | Select -ExpandProperty Name | Should -Be $Expected + + # again we are jumping thru hoops to keep PowerShell v2 compatibility + # in PowerShell v3 you would just do this, as seen in readme: + # $planets.Name | Should -Be $Expected + } + + # Testing just the positive cases is usually not enough. Our tests + # should also check that providing filter that matches no item returns + # $null. We could merge this with the previous test but it is better to + # split positive and negative cases, even if that means duplicated code. + # Normally we would use TestCases here as well, but let's keep it simple + # and show that Should -Be is pretty versatile in what it can assert. + It "Given invalid parameter -Name 'Alpha Centauri', it returns `$null" { + $planets = Get-Planet -Name 'Alpha Centauri' + $planets | Should -Be $null + } + } +} + +# Want to try it out yourself? + +## Excercise 1: +# Add filter Population that returns planets with population larger +# or equal to the given number (in billions). +# Use 7.5 as the population of Earth. Use 0 for all other planets. + +# Make sure to cover these test cases: +# - Population 7.5 returns Earth +# - Population 0 returns all planets +# - Population -1 returns no planets + + + +# Excercise 2: Test that planets are returned in the correct order, +# from the one closest to the Sun. +# Make sure to cover these test cases: +# - Order of planets is correct when no filters are used. +# - Order of planets is correct when -Name filter is used. + + + +# Excercise 3 (advanced): Add function that will list moons orbiting a given planet. +# - Make sure you can list all moons. +# - Make sure you can filter moons for given planet. +# - Make sure you Get-Planet and Get-Moon functions work together. +# $moons = Get-Planet Earth | Get-Moon +# $moons.Name | Should -Be Moon diff --git a/Examples/Planets/Get-Planet.ps1 b/Examples/Planets/Get-Planet.ps1 new file mode 100644 index 000000000..ef83bc9e9 --- /dev/null +++ b/Examples/Planets/Get-Planet.ps1 @@ -0,0 +1,23 @@ +# This is not the best file to start from, +# open Get-Planet.Tests.ps1 as well :) + + +function Get-Planet ([string]$Name = '*') +{ + $planets = @( + @{ Name = 'Mercury' } + @{ Name = 'Venus' } + @{ Name = 'Earth' } + @{ Name = 'Mars' } + @{ Name = 'Jupiter' } + @{ Name = 'Saturn' } + @{ Name = 'Uranus' } + @{ Name = 'Neptune' } + ) | foreach { New-Object -TypeName PSObject -Property $_ } + + $planets | where { $_.Name -like $Name } +} + +# The code above uses New-Object instead of the [PSCustomObject] +# you saw in the readme file. This is only to keep the example +# compatible with PowerShell version 2. diff --git a/README.md b/README.md index a09d10c91..8efa72f48 100644 --- a/README.md +++ b/README.md @@ -1,124 +1,154 @@ -__Build Status:__ [![Build status](https://build.powershell.org/guestAuth/app/rest/builds/buildType:(id:Pester_TestPester)/statusIcon)](https://build.powershell.org/project.html?projectId=Pester&tab=projectOverview&guest=1) +# Pester -Pester 3.0 has been released! To see a list of changes in this version, refer to the [What's New in Pester 3.0?](https://github.com/pester/Pester/wiki/What's-New-in-Pester-3.0) Wiki page. +Pester is the ubiquitous test and mock framework for PowerShell. ---- - -[![Join the chat at https://gitter.im/pester/Pester](https://badges.gitter.im/pester/Pester.svg)](https://gitter.im/pester/Pester?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +```powershell +# your function +function Get-Planet ([string]$Name='*') +{ + $planets = @( + @{ Name = 'Mercury' } + @{ Name = 'Venus' } + @{ Name = 'Earth' } + @{ Name = 'Mars' } + @{ Name = 'Jupiter' } + @{ Name = 'Saturn' } + @{ Name = 'Uranus' } + @{ Name = 'Neptune' } + ) | foreach { [PSCustomObject]$_ } + + $planets | where { $_.Name -like $Name } +} -Pester -======= -Pester provides a framework for **running unit tests to execute and validate PowerShell commands from within PowerShell**. Pester consists of a simple set of functions that expose a testing domain-specific language (DSL) for isolating, running, evaluating and reporting the results of PowerShell commands. +# Pester tests +Describe 'Get-Planet' { + It "Given no parameters, it lists all 8 planets" { + $allPlanets = Get-Planet + $allPlanets.Count | Should -Be 8 + } + + Context "Filtering by Name" { + It "Given valid -Name '', it returns ''" -TestCases @( + @{ Filter = 'Earth'; Expected = 'Earth' } + @{ Filter = 'ne*' ; Expected = 'Neptune' } + @{ Filter = 'ur*' ; Expected = 'Uranus' } + @{ Filter = 'm*' ; Expected = 'Mercury', 'Mars' } + ) { + param ($Filter, $Expected) + + $planets = Get-Planet -Name $Filter + $planets.Name | Should -Be $Expected + } -Pester tests can execute any command or script that is accessible to a Pester test file. This can include functions, cmdlets, modules and scripts. Pester can be run in *ad-hoc* style in a console or **it can be integrated into the build scripts of a continuous integration (CI) system**. + It "Given invalid parameter -Name 'Alpha Centauri', it returns `$null" { + $planets = Get-Planet -Name 'Alpha Centauri' + $planets | Should -Be $null + } + } +} +``` -**Pester also contains a powerful set of mocking functions** in which tests mimic any command functionality within the tested PowerShell code. +This code example lies a tiny bit, [find it annotated and production ready here](Examples/Planets). -Updating Pester on Windows 10 and Windows Server 2016 ------------ -There's a bit of a confusion with the version of Pester that ships in Windows 10 and Windows Server 2016. These operating systems by default have installed Pester version 3.4.0. Microsoft signed the Pester files (which they were required to do), but then PowerShellGet blows up when you try to update the module. Here's the command you need to run in order to get the latest version of Pester the first time on a Windows 10 system: +Learn more about the [usage and syntax](https://github.com/Pester/Pester/wiki) on our wiki. -`Install-Module Pester -Force -SkipPublisherCheck` +## Installation -Once that's done, you should be able to use a simple `Update-Module Pester` command in the future. +Pester is compatible with Windows 10, 8, 7, Vista and even 2003. We are also working hard on making it run on Linux and MacOS. -A Pester Test -------------- -BuildChanges.ps1 +Pester comes pre-installed with Windows 10, but we recommend updating, by running this PowerShell command _as administrator_: ```powershell +Install-Module -Name Pester -Force -SkipPublisherCheck +``` -function Build ($version) { - write-host "A build was run for version: $version" -} +Not running Windows 10 or facing problems? See the [full installation and update guide](https://github.com/pester/Pester/wiki/Installation-and-Update). -function BuildIfChanged { - $thisVersion=Get-Version - $nextVersion=Get-NextVersion - if($thisVersion -ne $nextVersion) {Build $nextVersion} - return $nextVersion -} +## Features -# Imagine that the following functions have heavy side-effect -function Get-Version { - throw New-Object NotImplementedException -} +### Test runner + +Pester runs your tests and prints a nicely formatted output to the screen. + +![test run output](doc/readme/output.PNG) + +Command line output is not the only output option, Pester also integrates with Visual Studio Code, Visual Studio, and any tool that can consume nUnit XML output. + +### Assertions -function Get-NextVersion { - throw New-Object NotImplementedException +Pester comes with a suite of assertions that cover a lot of common use cases. Pester assertions range from very versatile, like `Should -Be`, to specialized like `Should -Exists`. Here is how you ensure that a file exists: + +```powershell +Describe 'Notepad' { + It 'Exists in Windows folder' { + 'C:\Windows\notepad.exe' | Should -Exist + } } ``` -BuildChanges.Tests.ps1 +Learn more about assertion on [our wiki](https://github.com/pester/Pester/wiki/Should). + +### Mocking + +Pester has mocking built-in. Using mocks you can easily replace functions with empty implementation to avoid changing the real environment. ```powershell -$here = Split-Path -Parent $MyInvocation.MyCommand.Path -$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.' -. "$here\$sut" - -Describe "BuildIfChanged" { - Context "When there are changes" { - Mock Get-Version {return 1.1} - Mock Get-NextVersion {return 1.2} - Mock Build {} -Verifiable -ParameterFilter {$version -eq 1.2} - - $result = BuildIfChanged - - It "Builds the next version" { - Assert-VerifiableMocks - } - It "Returns the next version number" { - $result | Should Be 1.2 - } - } - Context "When there are no changes" { - Mock Get-Version -MockWith {return 1.1} - Mock Get-NextVersion -MockWith {return 1.1} - Mock Build {} +function Remove-Cache { + Remove-Item "$env:TEMP\cache.txt" +} + +Describe 'Remove-Cache' { + It 'Removes cached results from temp\cache.text' { + Mock -CommandName Remove-Item -MockWith {} - $result = BuildIfChanged + Remove-Cache - It "Should not build the next version" { - Assert-MockCalled Build -Times 0 -ParameterFilter {$version -eq 1.1} - } + Assert-MockCalled -CommandName Remove-Item -Times 1 -Exactly } } ``` -Running Tests -------------- - C:\PS> Invoke-Pester +Learn more [about Mocking here](https://github.com/pester/Pester/wiki/Mock). -This will run all tests inside of files named `*.Tests.ps1` recursively from the current directory and print a report of all failing and passing test results to the console. +### Code coverage - C:\PS> Invoke-Pester -TestName BuildIfChanged +Pester can measure how much of your code is covered by tests and export it to JaCoCo format that is easily understood by build servers. + +![JaCoCo code coverage report](doc/readme/jacoco.PNG) + +Learn more about [code coverage here](https://github.com/pester/Pester/wiki/Code-Coverage). + +### Build server integration + +Pester integrates nicely with TFS, AppVeyor, TeamCity, Jenkins and other CI servers. + +Testing your scripts, and all pull requests on AppVeyor is extremely simple. Just commit this `appveyor.yml` file to your repository, and select your repository on the AppVeyor website: + +```yml +version: 1.0.{build} +image: WMF 5 +install: +- ps: choco install pester +build: off +test_script: +- ps: Invoke-Pester -EnableExit +``` -You can also run specific tests by using the `-TestName` parameter of the `Invoke-Pester` command. The above example runs all tests with a `Describe` block named `BuildIfChanged`. If you want to run multiple tests, you can pass a string array into the `-TestName` parameter, similar to the following example: +See it [in action here!](https://ci.appveyor.com/project/nohwnd/planets) - C:\PS> Invoke-Pester -TestName BuildIfChanged, BaconShouldBeCrispy +Pester itself is build on the [community build server](build.powershell.org). -Continuous Integration with Pester ------------------------------------ +[![Build status](https://build.powershell.org/guestAuth/app/rest/builds/buildType:(id:Pester_TestPester)/statusIcon)](https://build.powershell.org/project.html?projectId=Pester&tab=projectOverview&guest=1) -Pester integrates well with almost any build automation solution. There are several options for this integration: +## Further reading -- The `-OutputFile` parameter allows you to export data about the test execution. Currently, this parameter allows you to produce NUnit-style XML output, which any modern CI solution should be able to read. -- The `-PassThru` parameter can be used if your CI solution supports running PowerShell code directly. After Pester finishes running, check the FailedCount property on the object to determine whether any tests failed, and take action from there. -- The `-EnableExit` switch causes Pester to exit the current PowerShell session with an error code. This error code will be the number of failed tests; 0 indicates success. +Do you like what you see? Learn how to use Pester with our [Getting started guide](https://github.com/pester/Pester/wiki/Getting-started-with-Pester), and continue with some of the other [resources](https://github.com/pester/Pester/wiki/Articles-and-other-resources). -As an example, there is also a file named `Pester.bat` in the `bin` folder which shows how you might integrate with a CI solution that does not support running PowerShell directly. By wrapping a call to `Invoke-Pester` in a batch file, and making sure that batch file returns a non-zero exit code if any tests fail, you can still use Pester even when limited to cmd.exe commands in your CI jobs. +## Got questions? -Whenever possible, it's better to run Invoke-Pester directly (either in an interactive PowerShell session, or using CI software that supports running PowerShell steps in jobs). This is the method that we test and support in our releases. +Got questions or you just want to get in touch? Use our issues page or one of these channels: -For Further Learning: ------------------------------------ -* [Getting started with Pester](http://www.powershellmagazine.com/2014/03/12/get-started-with-pester-powershell-unit-testing-framework/) -* [Testing your scripts with Pester, Assertions and more](http://www.powershellmagazine.com/2014/03/27/testing-your-powershell-scripts-with-pester-assertions-and-more/) -* [Writing Pester Tests](https://github.com/PowerShell/PowerShell/blob/master/docs/testing-guidelines/WritingPesterTests.md) -* [Pester Wiki](https://github.com/pester/Pester/wiki) -* [Google Discussion Group](https://groups.google.com/forum/?fromgroups#!forum/pester) -* `C:\PS> Import-Module ./pester.psm1; Get-Help about_pester` -* Microsoft's PowerShell test suite itself is being converted into Pester tests. [See the PowerShell-Tests repository.](https://github.com/PowerShell/PowerShell-Tests) -* Note: The following two links were for Pester v1.0. The syntax shown, particularly for performing assertions with Should, is no longer applicable to later versions of Pester. - * [powershell-bdd-testing-pester-screencast](http://scottmuc.com/blog/development/powershell-bdd-testing-pester-screencast/) - * [pester-bdd-for-the-system-administrator](http://scottmuc.com/blog/development/pester-bdd-for-the-system-administrator/) +[![Pester Twitter](doc/readme/twitter-64.PNG)](https://twitter.com/PSPester) +[![Pester on StackOverflow](doc/readme/stack-overflow-64.PNG)](https://stackoverflow.com/questions/tagged/pester) +[![Testing channel on Powershell Slack](doc/readme/slack-64.PNG)](https://powershell.slack.com/messages/C03QKTUCS) +[![Pester Gitter](doc/readme/gitter-64.PNG)](https://gitter.im/pester/Pester?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) diff --git a/doc/readme/gitter-64.PNG b/doc/readme/gitter-64.PNG new file mode 100644 index 0000000000000000000000000000000000000000..3ec4d112e9a6a301a31face414c65fc21acd91fc GIT binary patch literal 746 zcmeAS@N?(olHy`uVBq!ia0vp^c0laF!3HFqULN@hq!^2X+?^QKos)S9a~60+7BevL9RXp+soH$fKtah8*NBqf{Irtt#G+IN$CUh}R0Yr6#Prml z)Wnp^!jq{s3=B+Bo-U3d8P0EKpZC6SvK)t$>GBX7XN0ywsYFG%K67b=lnm|5+t+YbAn{+KaX2`-_Ks2nD-`0O2g(n z`=$0Tv(^5ZWX}7h+Q}=L(BV2&R_PqC;B&U++{@TEZ=T{~wvfN{_O`#Xyk@?#=vz6tZ_b?^ijVGa+&y<{D%U(c z-I@)n|RZ-gk)cA6{N`bBm#B-YTKxN1lIrrIk^- zc;(HUpjV%BDu0IktI6#Zny>HfzP;$k<0*IMp5QM%z3IUU+okt(l6HMv`E$pte=2kR zX8+nhZH9-6kLk`R|FFLiT-^{C3l!#cSeU!akp>4qTSu|;k)0rq=-zu-;&avc^sKPe zsjnSJ^sJ^p8x#m>GWWOc>m_FyIBAGVy6 WrknE00)GILB7>)^pUXO@geCwsJ7B;7 literal 0 HcmV?d00001 diff --git a/doc/readme/jacoco.PNG b/doc/readme/jacoco.PNG new file mode 100644 index 0000000000000000000000000000000000000000..071654205089b6ff394e14162fdfc881c54ebbf6 GIT binary patch literal 9320 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

G7x=%`R**nu%9v};OU)76ED=_) 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 ZKuZDqZL2{{e=f9Af|g literal 0 HcmV?d00001 diff --git a/doc/readme/output.PNG b/doc/readme/output.PNG new file mode 100644 index 0000000000000000000000000000000000000000..91bf28427f51c7c4c1ac50ccd0312319901fe508 GIT binary patch literal 21553 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 F`5)0(^34DM literal 0 HcmV?d00001 diff --git a/doc/readme/stack-overflow-64.PNG b/doc/readme/stack-overflow-64.PNG new file mode 100644 index 0000000000000000000000000000000000000000..9fc9368430f5faa0794b2a928c482f98746167b2 GIT binary patch literal 2527 zcmV<52_W`~P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn z4jTXf02y>eSaefwW^{L9a%BK_cXuvnZfkR6VQ^(GZ*pgw?mQX*00}=yL_t(&L+zRi za8%V9$NzWl?%ihqV*-iN3Z{ZQ9Ez<4npTCOC^{2go#~Xe!#EB_+cLF0MAFgHu@nLb zw$)BM>P(BZzs{Z5xB^3$iEjAmqcGI6s>40a$df&pQ02U-@XFD6{WC@q_o&eab<7I zM7ZvAu+E;!pvX7m=UO73X$PbfT3}74UrZ7Zlqc(=h9cfm-!tSjmXAkZ^w);;%dm^Xy4!89D_QZMGgqbjyv1{Oo3FxiG#5cGAs8Dy9iV zQOFA_5!qTT&WA%`MU%URH_w7nK0$~Nt-YFNGbS(g#rOTc!|H7Aj&Ic|YI*dTd&K!r zDX8f1W7k6Ql!)Y{xcyX~bcAci!E8Au@92%AVk+FXJ_(R7v~ykQ3PcV3p(-e|YfLK!!u+auV`OU5Dg{C(7)x2J4_q~LWr zvZb0_`xq4O7$Jb+N3c3Rg6rl7;kjdjuw@cjHJS$Ka`KYYJc+(s)e!j62jYA%6g-jn zmhXpi#@#Tf7I&2-67Lv&CGA{eQ}cZ)#qm?TEdwRGbfnf{SK6i=KwN zW&_OgjU>WM8QE>A6*W#BM0njaWV#=hFzrkCi|(uo&nP4hZlf4~T^e#@MB7l~#G8mb zwLq+<(rqUr;x`e2ul5KWW5!EsitxJWlp8uz`GDX-vpQQ5*xW&`PuV>OM!fg7f*&Ki z{yOqG%IMT?rm;+2i1B`V2b@!Gkyf(D!w9VzOEr5OIfsmIJxEzSobZ|-gU zw?V$jj#5&Nz)xFfw#UMXcJkDv>@;i2=t_$5I}m@PPS_YOb)Ln)69dw9FE2ySokaY# zAByvV$eZZslk*XzjGK6Uy|iS<|L{9duek{(_1s;_ie^$7b0reH)*Ls*_Nt#PA{^xFSG(^J?~4dB=tE-uDu;`Kv_v zN+&px*(v6YV{ah5@$OI|CN}_~0sdk@Boo690F&)`F8)ipSuVjNnm=aJ3 zu33xWrdq5}=Isyty`6|YdynX~#nMt@C8NTn{k8AW0;E)YN0?e!#T^jI(6{Q4cs&rd zi#ARkKzLI%9OYN_$)@6~C@Wi3U!61Vg!`^7RG%y5)!vvCqv5)lB!b#jirF+gvsU;l ze9Qg{b;4}&q$gl}c!0d*MR~`-|?c~kAl)HC9 zU(Mylq6LNe=^M!H>!41YEiZNx`Q>dePyLf}L@5Wku(7wORX4)BWV<*Y3ekl7IrUa~F-7c;E0Nsy6qT_nXf$I~>MG!0 zom*Ybq#&Zx7)?hJ-@cq;aKG5*h11hlJU1mYi##|i-gW)gKlwm#?pQE42&CoBrBuYoUE{iMV8(*e6z7YUMO>J`_eo zbQ*SN-uFtrwT)t)N|@#+@x5CIv0X&HHkAUn<}HVN!SFZ#Z4+&LNQs6rwWD&XwB!yy zLV^-rV(*jGe|rEfQ*zy$MwF_~7L+^@mzJSpo9OVSFTiX%LZ7HY9Y2#YYc*x!IbumD zl2?u-c5f8zr0CwLfk`(f7P&fiYufyW#QAWrO>}5A38R^&kECg*mXLp*;n|^j%-xsz zsq5jmng)UgW5S%i9q~mBHC8TI7U@SOK&Wb zX3eC5(0L%JG|^yi+o(L5{h7r!Ic zw4m-Qm5F;~;|#=Cviq_(&_HmFMlvqCG7bkZ2s9Xu($w!-j2Nhl&TgpKBAV;3-mo3U zsei$2JPa!lBKM_)L`?{s^q`LPK=cDWf_Mn3(W!x;u;7gW66v_&I;fN8!cAq%F0zUa zg+fRs=pp0-o8+dYrKQ;g5N7ZUOlm-MI!sy&7$3cx+8NFrO5$Dmb8|CP`Qfp695ppHv~107FRCZz znd8t;9DsRpKQ$OM812-LlLv?a;DKP* z&%H0eRlSr3X_9C|&5jOQfpzbg*ujX3&P4G9;GD7m?%RJXHVFcC=MdO(Mqag#tTFv= zLjzh{TcN6{t|%6ZVd27sl#{x*aF_%y`EuB%89el86!)$hz9G+3aDv^pcQ4%J+KjI2 zm^g7FCQY6!&IiI4(VY+Q&oa5UnmNOZ4H6yL(0jIrE7}(KR=i&EgPh$5_{g$>I8=%% zrVE8FqOC|&tc~qHz(>y?>}+D#G0kt*-+E5$aM+G`GzG4iz5m^!C=ywrDT+k)N#l~} zTo`HBW}L3!t*ZwW)4ZfBD=VXS(W0aOx8)UH@Nf*b)6&u*SATg;WDE-*X;^q#Fq8L0 z#se_YM^C{+VR-NUgp$?0>kl15b5m1MB(H36$bE))PNq+nmh5B|&9Nf3Z-=;BQYctL p+VyiGtLXn%F3Om`B>Lh2_#cbZW0_ebPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf02y>eSaefwW^{L9 za%BKPWN%_+AW3auXJt}lVPtu6$z?nM00-zvL_t(&L+zStY*S?z$N#;q?Yeb0218&X z0y8i~LHQs<)S#l`1w(XB)Tkf)#25XdiAE*FNaTYW6A31Q2GpVPHcW65qNu0@1i=ee zxoxmHx=Xv>+xh%YPs`eMUE8&!8~ef5oO8OK^M9Y`eJ<}?O`m|v2(9{h*)S$}v@<4n zv@<4nv~$@B&db8%@C82(wgqs!Gl*_)2pUZvDlA&eC^KMor5@Ebz534d$t%Gd_q)(^ z)Pqh>2nL-72CWA2Um++@>62glH(tcAm}SO&GtA+ONof4jjcdl~P+MtKj$;HneIc~< zhA^!(^AXI1Ut4@wy~_cA5U?6G&_z@xfKMBgUk+a%Z1UdqciT{I(WzI%_+?-k|MH;m zZx@2{nN9WO>XkUbA02dI?QSP_K30Je)1{f-o8_MG?scKks)bH7xX?rdLValO4PxCA z8?GqQV%KROcKqwZF_{Wx1K^P9@a7#h%&Q7pm&6FJ|J)9bANWr`Ajk1_gQz^x`3%?jV*;H)GX;LiJr?qKeLR2hrvX&z%YK0L!=9 zaiTMzUd=v7?S8!Vn{(J=Ntw8GWuXp*MtTX*;R@lVNyZql=Nw@zQNc&-0SORcm*Q)g zS&OHey2M4i%DHUwY;zALScfmRKXleW2zX|m1uriy#(!e@ZzKpl{zWIYANMKmi3)D% z2`bi&!1+{e)?v+$4y@blP|s$E-DiCgbmSgMf>S0??6gvy;yn$YcPc+GeeXa`g&t4L zwJ7h23J%EV#NVCmO$|EXLfP>?6^4RZb?CQ#S$9qL{|`dS_AMZDNKXAt}ejy z3yaiu^b^d)&JjvPae)?+vC!~E7uNnfd}|+U_e)?=53&pcmQjRr9@kAa;8k(${zPwE zQ*MyNK8Rw0AH+HLgM|LYn>r+&xYaA^!88(fQR6;BUEyhVi{NN84mTd08`n|ny`3E1UczV3*=jTXomsDvRmzCf#5uAvqVEX@p ziAK2n$psV6ZJXri5^?n}k9ctB7CWA6?nd(okCN<@A>$>e&v{guMKfQeLN-?JJ z=yZp$LV{DNNvDWP2iCbx5v!AdyGp#JR*L)^WB{*_JUcrdfkn+Ag?o~=Mx*xlbkpg1}gJd$If@{Yc zK?fFxlU`D*q#g4J5=&SQ%$LlNjHqC?Y1K9J(DwUB4 zmwm33{Lh{^88KIHood3=QawB)C{RW4NP?LsnPn&j499!-l)x>m5!Z`G5^kBl_olFl znb7{*9x0bHu`i{%Iv=2M*!WK>9=bYAD46}^w)!$mks#K=1+qN1HjQ)tOp|()oB_3T zJUdT%rM7nCbWcEPVXaarINy=YShCd<5F?aM_yF3WJSg7tAeK*R5Wxv#Lj_F{ohj!onh@r=<%}Xg-N$Q!}$%kA+hT)HA7( zR4}9U>$epvBbiTun$O~pTH&obZ0ecRNh+9JUuDFrHy7nqdg99G>cvGFb#g-rCX1>I zut6#?jW{>gy@p!Z%q17Z+v;bTaMR@UTsgv!c{m=fjBGjRMvt!##RcJ=ItDYo<{GBT zxfAqw?bh^NIYQckBmC3hR~F?@bp_#;0P?TA_TQVzHr%Xd<@fGgEHE-BW5E%)S+Qz+ z7tT4uE0no_E$g&0E#6r=Jh3EW!Q8CkuEW;9+!$xkL7xNb^2si^gQ%Nq#4B-oM46Jd zU_QXdhumm7>XpBSQeWo+W&~DyPtCQUp*FR$F%?o0%rtPI&5y5+dT^wJn_=Ov7v!oC zVSQ{h05dMIxRc!hbVLFEm)OOWMtW>%%s86=_Wi_V^;Q|E)_!tt$pWw`00!f z2V@Xf);Y!cArZ~F%-}`W=i_n^_(}XQievdnR}IMl2g@c?rOK*9opd+zs`OGsT-tB@ zMMx=1N1%1uM0A@YfHM;4+IvIjmefJFr1dD;Bwoo>Rc_HL`@&O-btpA!mG4pI18E5! u4dgBy<|$)>M>}JJM>}JJM?069VBmjIWJ)YR7^Hgu0000