pax_global_header00006660000000000000000000000064147616043240014521gustar00rootroot0000000000000052 comment=8a42da3e4bfdc7ea408fcd886064dffc4daffb22 client_golang-1.21.1/000077500000000000000000000000001476160432400144105ustar00rootroot00000000000000client_golang-1.21.1/.bingo/000077500000000000000000000000001476160432400155645ustar00rootroot00000000000000client_golang-1.21.1/.bingo/.gitignore000066400000000000000000000001731476160432400175550ustar00rootroot00000000000000 # Ignore everything * # But not these files: !.gitignore !*.mod !*.sum !README.md !Variables.mk !variables.env *tmp.mod client_golang-1.21.1/.bingo/README.md000066400000000000000000000014641476160432400170500ustar00rootroot00000000000000# Project Development Dependencies. This is directory which stores Go modules with pinned buildable package that is used within this repository, managed by https://github.com/bwplotka/bingo. * Run `bingo get` to install all tools having each own module file in this directory. * Run `bingo get ` to install that have own module file in this directory. * For Makefile: Make sure to put `include .bingo/Variables.mk` in your Makefile, then use $() variable where is the .bingo/.mod. * For shell: Run `source .bingo/variables.env` to source all environment variable for each tool. * For go: Import `.bingo/variables.go` to for variable names. * See https://github.com/bwplotka/bingo or -h on how to add, remove or change binaries dependencies. ## Requirements * Go 1.14+ client_golang-1.21.1/.bingo/Variables.mk000066400000000000000000000021471476160432400200310ustar00rootroot00000000000000# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.8. DO NOT EDIT. # All tools are designed to be build inside $GOBIN. BINGO_DIR := $(dir $(lastword $(MAKEFILE_LIST))) GOPATH ?= $(shell go env GOPATH) GOBIN ?= $(firstword $(subst :, ,${GOPATH}))/bin GO ?= $(shell which go) # Below generated variables ensure that every time a tool under each variable is invoked, the correct version # will be used; reinstalling only if needed. # For example for goimports variable: # # In your main Makefile (for non array binaries): # #include .bingo/Variables.mk # Assuming -dir was set to .bingo . # #command: $(GOIMPORTS) # @echo "Running goimports" # @$(GOIMPORTS) # GOIMPORTS := $(GOBIN)/goimports-v0.9.3 $(GOIMPORTS): $(BINGO_DIR)/goimports.mod @# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies. @echo "(re)installing $(GOBIN)/goimports-v0.9.3" @cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=goimports.mod -o=$(GOBIN)/goimports-v0.9.3 "golang.org/x/tools/cmd/goimports" client_golang-1.21.1/.bingo/go.mod000066400000000000000000000002241476160432400166700ustar00rootroot00000000000000module _ // Fake go.mod auto-created by 'bingo' for go -moddir compatibility with non-Go projects. Commit this file, together with other .mod files.client_golang-1.21.1/.bingo/goimports.mod000066400000000000000000000002121476160432400203030ustar00rootroot00000000000000module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT go 1.20 require golang.org/x/tools v0.9.3 // cmd/goimports client_golang-1.21.1/.bingo/goimports.sum000066400000000000000000000007131476160432400203360ustar00rootroot00000000000000golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= client_golang-1.21.1/.bingo/variables.env000066400000000000000000000006311476160432400202460ustar00rootroot00000000000000# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.8. DO NOT EDIT. # All tools are designed to be build inside $GOBIN. # Those variables will work only until 'bingo get' was invoked, or if tools were installed via Makefile's Variables.mk. GOBIN=${GOBIN:=$(go env GOBIN)} if [ -z "$GOBIN" ]; then GOBIN="$(go env GOPATH)/bin" fi GOIMPORTS="${GOBIN}/goimports-v0.9.3" client_golang-1.21.1/.github/000077500000000000000000000000001476160432400157505ustar00rootroot00000000000000client_golang-1.21.1/.github/CODEOWNERS000066400000000000000000000000521476160432400173400ustar00rootroot00000000000000* @ArthurSens @bwplotka @kakkoyun @vesari client_golang-1.21.1/.github/ISSUE_TEMPLATE.md000066400000000000000000000024171476160432400204610ustar00rootroot00000000000000 client_golang-1.21.1/.github/dependabot.yml000066400000000000000000000011141476160432400205750ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "gomod" directory: "/" schedule: interval: "monthly" - package-ecosystem: "gomod" directory: "/dagger" schedule: interval: "monthly" - package-ecosystem: "gomod" directory: "/examples/middleware" schedule: interval: "monthly" - package-ecosystem: "gomod" directory: "/tutorial/whatsup" schedule: interval: "monthly" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "monthly" groups: github-actions: patterns: - "*" client_golang-1.21.1/.github/settings.yml000066400000000000000000000034031476160432400203330ustar00rootroot00000000000000--- branches: - name: main protection: # Required. Require at least one approving review on a pull request, before merging. Set to null to disable. required_pull_request_reviews: # The number of approvals required. (1-6) required_approving_review_count: 1 # Dismiss approved reviews automatically when a new commit is pushed. dismiss_stale_reviews: false # Blocks merge until code owners have reviewed. require_code_owner_reviews: false # Specify which users and teams can dismiss pull request reviews. Pass an empty dismissal_restrictions object to disable. User and team dismissal_restrictions are only available for organization-owned repositories. Omit this parameter for personal repositories. dismissal_restrictions: users: [] teams: [] # Required. Require status checks to pass before merging. Set to null to disable required_status_checks: # Required. Require branches to be up to date before merging. strict: false # Required. The list of status checks to require in order to merge into this branch contexts: - DCO - "ci/circleci: go-1-17" - "ci/circleci: go-1-18" # Required. Enforce all configured restrictions for administrators. Set to true to enforce required status checks for repository administrators. Set to null to disable. enforce_admins: false # Prevent merge commits from being pushed to matching branches required_linear_history: false # Required. Restrict who can push to this branch. Team and user restrictions are only available for organization-owned repositories. Set to null to disable. restrictions: apps: [] users: [] teams: [] client_golang-1.21.1/.github/stale.yml000066400000000000000000000063621476160432400176120ustar00rootroot00000000000000# Configuration for probot-stale - https://github.com/probot/stale # Number of days of inactivity before an Issue or Pull Request becomes stale # daysUntilStale: 30 # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. # daysUntilClose: 7 # NOTICE: Check below for the individual settings for each type of event. # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) onlyLabels: [] # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable exemptLabels: - pinned - security - keep-open - wip - "[Status] Maybe Later" # Set to true to ignore issues in a project (defaults to false) exemptProjects: true # default: false # Set to true to ignore issues in a milestone (defaults to false) exemptMilestones: true # default: false # Set to true to ignore issues with an assignee (defaults to false) exemptAssignees: false # Label to use when marking as stale staleLabel: stale # Comment to post when marking as stale. Set to `false` to disable # markComment: > # This issue has been automatically marked as stale because it has not had # recent activity. It will be closed if no further activity occurs. Thank you # for your contributions. # Comment to post when removing the stale label. # unmarkComment: > # Your comment here. # Comment to post when closing a stale Issue or Pull Request. # closeComment: > # Your comment here. # Limit the number of actions per hour, from 1-30. Default is 30 limitPerRun: 30 # Limit to only `issues` or `pulls` # only: issues # Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': # pulls: # daysUntilStale: 30 # markComment: > # This pull request has been automatically marked as stale because it has not had # recent activity. It will be closed if no further activity occurs. Thank you # for your contributions. # issues: # exemptLabels: # - confirmed pull: daysUntilClose: 14 daysUntilStale: 60 markComment: > Hello πŸ‘‹ Looks like there was no activity on this amazing PR for the last 60 days. **Do you mind updating us on the status?** Is there anything we can help with? If you plan to still work on it, just comment on this PR or push a commit. Thanks! πŸ€— If there will be no activity in the next 2 weeks, this issue will be closed (we can always reopen a PR if you get back to this!). # unmarkComment: No need for unmark comment. closeComment: > Closing for now as promised, let us know if you need this to be reopened! πŸ€— issues: daysUntilClose: 90 daysUntilStale: 180 markComment: > Hello πŸ‘‹ Looks like there was no activity on this issue for the last 3 months. **Do you mind updating us on the status?** Is this still reproducible or needed? If yes, just comment on this PR or push a commit. Thanks! πŸ€— If there will be no activity in the next 4 weeks, this issue will be closed (we can always reopen an issue if we need!). # unmarkComment: No need for unmark comment. closeComment: > Closing for now as promised, let us know if you need this to be reopened! πŸ€— client_golang-1.21.1/.github/workflows/000077500000000000000000000000001476160432400200055ustar00rootroot00000000000000client_golang-1.21.1/.github/workflows/automerge-dependabot.yml000066400000000000000000000017161476160432400246300ustar00rootroot00000000000000name: Dependabot auto-merge on: pull_request concurrency: group: ${{ github.workflow }}-${{ (github.event.pull_request && github.event.pull_request.number) || github.ref || github.run_id }} cancel-in-progress: true permissions: contents: write pull-requests: write jobs: dependabot: runs-on: ubuntu-latest if: ${{ github.actor == 'dependabot[bot]' }} steps: - name: Dependabot metadata id: metadata uses: dependabot/fetch-metadata@dbb049abf0d677abbd7f7eee0375145b417fdd34 # v2.2.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" - name: Enable auto-merge for Dependabot PRs if: ${{steps.metadata.outputs.update-type == 'version-update:semver-minor' || steps.metadata.outputs.update-type == 'version-update:semver-patch'}} run: gh pr merge --auto --merge "$PR_URL" env: PR_URL: ${{github.event.pull_request.html_url}} GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} client_golang-1.21.1/.github/workflows/codeql-analysis.yml000066400000000000000000000054001476160432400236170ustar00rootroot00000000000000# For most projects, this workflow file will not need changing; you simply need # to commit it to your repository. # # You may wish to alter this file to override the set of languages analyzed, # or to provide custom queries or build logic. # # ******** NOTE ******** # We have attempted to detect the languages in your repository. Please check # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages. # name: "CodeQL" on: push: branches: [ main ] pull_request: # The branches below must be a subset of the branches above branches: [ main ] schedule: - cron: '31 21 * * 6' concurrency: group: ${{ github.workflow }}-${{ (github.event.pull_request && github.event.pull_request.number) || github.ref || github.run_id }} cancel-in-progress: true # Minimal permissions to be inherited by any job that don't declare it's own permissions permissions: contents: read jobs: analyze: name: Analyze runs-on: ubuntu-latest permissions: actions: read contents: read security-events: write strategy: fail-fast: false matrix: language: [ 'go' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://git.io/codeql-language-support steps: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. # queries: ./path/to/local/query, your-org/your-repo/queries@main # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild uses: github/codeql-action/autobuild@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 # ℹ️ Command-line programs to run using the OS shell. # πŸ“š https://git.io/JvXDl # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines # and modify them (or add more) to build your code if your project # uses a compiled language #- run: | # make bootstrap # make release - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 client_golang-1.21.1/.github/workflows/container_description.yml000066400000000000000000000044671476160432400251300ustar00rootroot00000000000000--- name: Push README to Docker Hub on: push: paths: - "README.md" - "README-containers.md" - ".github/workflows/container_description.yml" branches: [ main, master ] permissions: contents: read jobs: PushDockerHubReadme: runs-on: ubuntu-latest name: Push README to Docker Hub if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks. steps: - name: git checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set docker hub repo name run: echo "DOCKER_REPO_NAME=$(make docker-repo-name)" >> $GITHUB_ENV - name: Push README to Dockerhub uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8 # v1 env: DOCKER_USER: ${{ secrets.DOCKER_HUB_LOGIN }} DOCKER_PASS: ${{ secrets.DOCKER_HUB_PASSWORD }} with: destination_container_repo: ${{ env.DOCKER_REPO_NAME }} provider: dockerhub short_description: ${{ env.DOCKER_REPO_NAME }} # Empty string results in README-containers.md being pushed if it # exists. Otherwise, README.md is pushed. readme_file: '' PushQuayIoReadme: runs-on: ubuntu-latest name: Push README to quay.io if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks. steps: - name: git checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set quay.io org name run: echo "DOCKER_REPO=$(echo quay.io/${GITHUB_REPOSITORY_OWNER} | tr -d '-')" >> $GITHUB_ENV - name: Set quay.io repo name run: echo "DOCKER_REPO_NAME=$(make docker-repo-name)" >> $GITHUB_ENV - name: Push README to quay.io uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8 # v1 env: DOCKER_APIKEY: ${{ secrets.QUAY_IO_API_TOKEN }} with: destination_container_repo: ${{ env.DOCKER_REPO_NAME }} provider: quay # Empty string results in README-containers.md being pushed if it # exists. Otherwise, README.md is pushed. readme_file: '' client_golang-1.21.1/.github/workflows/go.yml000066400000000000000000000035431476160432400211420ustar00rootroot00000000000000--- name: Go on: pull_request: push: branches: - main - "release-*" concurrency: group: ${{ github.workflow }}-${{ (github.event.pull_request && github.event.pull_request.number) || github.ref || github.run_id }} cancel-in-progress: true # Minimal permissions to be inherited by any job that don't declare it's own permissions permissions: contents: read jobs: supportedVersions: name: Fetch supported Go versions runs-on: ubuntu-latest outputs: supported_versions: ${{ steps.matrix.outputs.supported_versions }} steps: - name: Checkout code uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Read supported_go_versions.txt id: matrix run: | versions=$(cat supported_go_versions.txt) matrix="[$(echo "$versions" | sed 's/\(.*\)/"\1"/' | paste -s -d,)]" echo "supported_versions=$matrix" >> $GITHUB_OUTPUT test: name: Tests runs-on: ubuntu-latest needs: supportedVersions strategy: matrix: go_version: ${{ fromJSON(needs.supportedVersions.outputs.supported_versions) }} steps: - name: Checkout code uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set up Go ${{ matrix.go_version }} uses: actions/setup-go@v5.0.2 with: go-version: ${{ matrix.go_version }} - name: Cache Go modules id: cache uses: actions/cache@v4 with: path: ~/go/pkg/mod key: v1-go${{ matrix.go_version }} - name: Run tests and check license run: make check_license test env: CI: true - name: Run style and unused if: ${{ matrix.go_version == '1.21' }} run: make style unused client_golang-1.21.1/.github/workflows/golangci-lint.yml000066400000000000000000000023451476160432400232630ustar00rootroot00000000000000--- # This action is synced from https://github.com/prometheus/prometheus name: golangci-lint on: push: paths: - "go.sum" - "go.mod" - "**.go" - "scripts/errcheck_excludes.txt" - ".github/workflows/golangci-lint.yml" - ".golangci.yml" pull_request: permissions: # added using https://github.com/step-security/secure-repo contents: read jobs: golangci: permissions: contents: read # for actions/checkout to fetch code pull-requests: read # for golangci/golangci-lint-action to fetch pull requests name: lint runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Install Go uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: 1.23.x - name: Install snmp_exporter/generator dependencies run: sudo apt-get update && sudo apt-get -y install libsnmp-dev if: github.repository == 'prometheus/snmp_exporter' - name: Lint uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 with: args: --verbose version: v1.63.4 client_golang-1.21.1/.github/workflows/scorecard.yml000066400000000000000000000036341476160432400225030ustar00rootroot00000000000000name: Scorecard supply-chain security on: # For Branch-Protection check. Only the default branch is supported. See # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection branch_protection_rule: # To guarantee Maintained check is occasionally updated. See # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained schedule: - cron: '22 1 * * 0' push: branches: [ "main" ] # Declare default permissions as read only. permissions: read-all jobs: analysis: name: Scorecard analysis runs-on: ubuntu-latest permissions: # Needed to upload the results to code-scanning dashboard. security-events: write # Needed to publish results and get a badge (see publish_results below). id-token: write # Uncomment the permissions below if installing in a private repository. # contents: read # actions: read steps: - name: "Checkout code" uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: "Run analysis" uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 with: results_file: results.sarif results_format: sarif publish_results: true # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: SARIF file path: results.sarif retention-days: 5 # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" uses: github/codeql-action/upload-sarif@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 with: sarif_file: results.sarif client_golang-1.21.1/.github/workflows/update-go-versions.yml000066400000000000000000000020701476160432400242620ustar00rootroot00000000000000--- name: Generate Metric files for new Go version on: workflow_dispatch: schedule: - cron: '0 0 1 * *' jobs: update-go-versions: name: Update Go Versions and Generate Tests runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Execute bash script run: bash update-go-version.bash # If there are no changes (i.e. no diff exists with the checked-out base branch), # no pull request will be created and the action exits silently. - name: Create a Pull Request if: github.event_name != 'pull_request' uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7.0.6 with: token: ${{ secrets.GITHUB_TOKEN }} commit-message: "Update Go Collector metrics for new Go version" title: "chore: Update metrics for new Go version" branch: update-metrics-for-new-go-version base: main draft: false delete-branch: true client_golang-1.21.1/.gitignore000066400000000000000000000010221476160432400163730ustar00rootroot00000000000000# Examples examples/simple/simple examples/random/random examples/gocollector/gocollector # Typical backup/temporary files of editors *~ *# # Never include any accidentally created vendor dirs. # This is a library! vendor/ # The remainder of this file is taken from # https://github.com/github/gitignore/blob/main/Go.gitignore # Binaries for programs and plugins *.exe *.exe~ *.dll *.so *.dylib # Test binary, built with `go test -c` *.test # Output of the go coverage tool, specifically when used with LiteIDE *.out .idea client_golang-1.21.1/.golangci.yml000066400000000000000000000041521476160432400167760ustar00rootroot00000000000000--- run: timeout: 5m skip-files: # Skip autogenerated files. - ^.*\.(pb|y)\.go$ output: sort-results: true linters: enable: - depguard - durationcheck - errorlint - exportloopref - gofmt - gofumpt - goimports - gosimple - ineffassign - misspell - nolintlint - perfsprint - predeclared - revive - staticcheck - unconvert - unused - usestdlibvars - wastedassign issues: max-same-issues: 0 exclude-rules: - path: _test.go linters: - errcheck - govet - structcheck linters-settings: depguard: rules: main: deny: #- pkg: "sync/atomic" # desc: "Use go.uber.org/atomic instead of sync/atomic" - pkg: "github.com/stretchr/testify/assert" desc: "Use github.com/stretchr/testify/require instead of github.com/stretchr/testify/assert" - pkg: "github.com/go-kit/kit/log" desc: "Use github.com/go-kit/log instead of github.com/go-kit/kit/log" - pkg: "io/ioutil" desc: "Use corresponding 'os' or 'io' functions instead." #- pkg: "regexp" # desc: "Use github.com/grafana/regexp instead of regexp" errcheck: exclude-functions: # The following 2 methods always return nil as the error - (*github.com/cespare/xxhash/v2.Digest).Write - (*github.com/cespare/xxhash/v2.Digest).WriteString - (*bufio.Writer).WriteRune goimports: local-prefixes: github.com/prometheus/client_golang gofumpt: extra-rules: true perfsprint: # Optimizes even if it requires an int or uint type cast. int-conversion: true # Optimizes into `err.Error()` even if it is only equivalent for non-nil errors. err-error: true # Optimizes `fmt.Errorf`. errorf: true # Optimizes `fmt.Sprintf` with only one argument. sprintf1: true # Optimizes into strings concatenation. strconcat: true revive: rules: # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-parameter - name: unused-parameter severity: warning disabled: true client_golang-1.21.1/CHANGELOG.md000066400000000000000000000661141476160432400162310ustar00rootroot00000000000000## Unreleased ## 1.21.1 / 2025-03-04 * [BUGFIX] prometheus: Revert of `Inc`, `Add` and `Observe` cumulative metric CAS optimizations (#1661), causing regressions on low contention cases. * [BUGFIX] prometheus: Fix GOOS=ios build, broken due to process_collector_* wrong build tags. ## 1.21.0 / 2025-02-17 :warning: This release contains potential breaking change if you upgrade `github.com/prometheus/common` to 0.62+ together with client_golang. :warning: New common version [changes `model.NameValidationScheme` global variable](https://github.com/prometheus/common/pull/724), which relaxes the validation of label names and metric name, allowing all UTF-8 characters. Typically, this should not break any user, unless your test or usage expects strict certain names to panic/fail on client_golang metric registration, gathering or scrape. In case of problems change `model.NameValidationScheme` to old `model.LegacyValidation` value in your project `init` function. * [BUGFIX] gocollector: Fix help message for runtime/metric metrics. #1583 * [BUGFIX] prometheus: Fix `Desc.String()` method for no labels case. #1687 * [ENHANCEMENT] prometheus: Optimize popular `prometheus.BuildFQName` function; now up to 30% faster. #1665 * [ENHANCEMENT] prometheus: Optimize `Inc`, `Add` and `Observe` cumulative metrics; now up to 50% faster under high concurrent contention. #1661 * [CHANGE] Upgrade prometheus/common to 0.62.0 which changes `model.NameValidationScheme` global variable. #1712 * [CHANGE] Add support for Go 1.23. #1602 * [FEATURE] process_collector: Add support for Darwin systems. #1600 #1616 #1625 #1675 #1715 * [FEATURE] api: Add ability to invoke `CloseIdleConnections` on api.Client using `api.Client.(CloseIdler).CloseIdleConnections()` casting. #1513 * [FEATURE] promhttp: Add `promhttp.HandlerOpts.EnableOpenMetricsTextCreatedSamples` option to create OpenMetrics _created lines. Not recommended unless you want to use opt-in Created Timestamp feature. Community works on OpenMetrics 2.0 format that should make those lines obsolete (they increase cardinality significantly). #1408 * [FEATURE] prometheus: Add `NewConstNativeHistogram` function. #1654 ## 1.20.5 / 2024-10-15 * [BUGFIX] testutil: Reverted #1424; functions using compareMetricFamilies are (again) only failing if filtered metricNames are in the expected input. ## 1.20.4 / 2024-09-07 * [BUGFIX] histograms: Fix possible data race when appending exemplars vs metrics gather. #1623 ## 1.20.3 / 2024-09-05 * [BUGFIX] histograms: Fix possible data race when appending exemplars. #1608 ## 1.20.2 / 2024-08-23 * [BUGFIX] promhttp: Unset Content-Encoding header when data is uncompressed. #1596 ## 1.20.1 / 2024-08-20 * [BUGFIX] process-collector: Fixed unregistered descriptor error when using process collector with `PedanticRegistry` on linux machines. #1587 ## 1.20.0 / 2024-08-14 * [CHANGE] :warning: go-collector: Remove `go_memstat_lookups_total` metric which was always 0; Go runtime stopped sharing pointer lookup statistics. #1577 * [FEATURE] :warning: go-collector: Add 3 default metrics: `go_gc_gogc_percent`, `go_gc_gomemlimit_bytes` and `go_sched_gomaxprocs_threads` as those are recommended by the Go team. #1559 * [FEATURE] go-collector: Add more information to all metrics' HELP e.g. the exact `runtime/metrics` sourcing each metric (if relevant). #1568 #1578 * [FEATURE] testutil: Add CollectAndFormat method. #1503 * [FEATURE] histograms: Add support for exemplars in native histograms. #1471 * [FEATURE] promhttp: Add experimental support for `zstd` on scrape, controlled by the request `Accept-Encoding` header. #1496 * [FEATURE] api/v1: Add `WithLimit` parameter to all API methods that supports it. #1544 * [FEATURE] prometheus: Add support for created timestamps in constant histograms and constant summaries. #1537 * [FEATURE] process-collector: Add network usage metrics: `process_network_receive_bytes_total` and `process_network_transmit_bytes_total`. #1555 * [FEATURE] promlint: Add duplicated metric lint rule. #1472 * [BUGFIX] promlint: Relax metric type in name linter rule. #1455 * [BUGFIX] promhttp: Make sure server instrumentation wrapping supports new and future extra responseWriter methods. #1480 * [BUGFIX] **breaking** testutil: Functions using compareMetricFamilies are now failing if filtered metricNames are not in the input. #1424 (reverted in 1.20.5) ## 1.19.0 / 2024-02-27 The module `prometheus/common v0.48.0` introduced an incompatibility when used together with client_golang (See https://github.com/prometheus/client_golang/pull/1448 for more details). If your project uses client_golang and you want to use `prometheus/common v0.48.0` or higher, please update client_golang to v1.19.0. * [CHANGE] Minimum required go version is now 1.20 (we also test client_golang against new 1.22 version). #1445 #1449 * [FEATURE] collectors: Add version collector. #1422 #1427 ## 1.18.0 / 2023-12-22 * [FEATURE] promlint: Allow creation of custom metric validations. #1311 * [FEATURE] Go programs using client_golang can be built in wasip1 OS. #1350 * [BUGFIX] histograms: Add timer to reset ASAP after bucket limiting has happened. #1367 * [BUGFIX] testutil: Fix comparison of metrics with empty Help strings. #1378 * [ENHANCEMENT] Improved performance of `MetricVec.WithLabelValues(...)`. #1360 ## 1.17.0 / 2023-09-27 * [CHANGE] Minimum required go version is now 1.19 (we also test client_golang against new 1.21 version). #1325 * [FEATURE] Add support for Created Timestamps in Counters, Summaries and Historams. #1313 * [ENHANCEMENT] Enable detection of a native histogram without observations. #1314 ## 1.16.0 / 2023-06-15 * [BUGFIX] api: Switch to POST for LabelNames, Series, and QueryExemplars. #1252 * [BUGFIX] api: Fix undefined execution order in return statements. #1260 * [BUGFIX] native histograms: Fix bug in bucket key calculation. #1279 * [ENHANCEMENT] Reduce constrainLabels allocations for all metrics. #1272 * [ENHANCEMENT] promhttp: Add process start time header for scrape efficiency. #1278 * [ENHANCEMENT] promlint: Improve metricUnits runtime. #1286 ## 1.15.1 / 2023-05-3 * [BUGFIX] Fixed promhttp.Instrument* handlers wrongly trying to attach exemplar to unsupported metrics (e.g. summary), \ causing panics. #1253 ## 1.15.0 / 2023-04-13 * [BUGFIX] Fix issue with atomic variables on ppc64le. #1171 * [BUGFIX] Support for multiple samples within same metric. #1181 * [BUGFIX] Bump golang.org/x/text to v0.3.8 to mitigate CVE-2022-32149. #1187 * [ENHANCEMENT] Add exemplars and middleware examples. #1173 * [ENHANCEMENT] Add more context to "duplicate label names" error to enable debugging. #1177 * [ENHANCEMENT] Add constrained labels and constrained variant for all MetricVecs. #1151 * [ENHANCEMENT] Moved away from deprecated github.com/golang/protobuf package. #1183 * [ENHANCEMENT] Add possibility to dynamically get label values for http instrumentation. #1066 * [ENHANCEMENT] Add ability to Pusher to add custom headers. #1218 * [ENHANCEMENT] api: Extend and improve efficiency of json-iterator usage. #1225 * [ENHANCEMENT] Added (official) support for go 1.20. #1234 * [ENHANCEMENT] timer: Added support for exemplars. #1233 * [ENHANCEMENT] Filter expected metrics as well in CollectAndCompare. #1143 * [ENHANCEMENT] :warning: Only set start/end if time is not Zero. This breaks compatibility in experimental api package. If you strictly depend on empty time.Time as actual value, the behavior is now changed. #1238 ## 1.14.0 / 2022-11-08 * [FEATURE] Add Support for Native Histograms. #1150 * [CHANGE] Extend `prometheus.Registry` to implement `prometheus.Collector` interface. #1103 ## 1.13.1 / 2022-11-01 * [BUGFIX] Fix race condition with Exemplar in Counter. #1146 * [BUGFIX] Fix `CumulativeCount` value of `+Inf` bucket created from exemplar. #1148 * [BUGFIX] Fix double-counting bug in `promhttp.InstrumentRoundTripperCounter`. #1118 ## 1.13.0 / 2022-08-05 * [CHANGE] Minimum required Go version is now 1.17 (we also test client_golang against new 1.19 version). * [ENHANCEMENT] Added `prometheus.TransactionalGatherer` interface for `promhttp.Handler` use which allows using low allocation update techniques for custom collectors. #989 * [ENHANCEMENT] Added exemplar support to `prometheus.NewConstHistogram`. See [`ExampleNewConstHistogram_WithExemplar`](prometheus/examples_test.go#L602) example on how to use it. #986 * [ENHANCEMENT] `prometheus/push.Pusher` has now context aware methods that pass context to HTTP request. #1028 * [ENHANCEMENT] `prometheus/push.Pusher` has now `Error` method that retrieve last error. #1075 * [ENHANCEMENT] `testutil.GatherAndCompare` provides now readable diff on failed comparisons. #998 * [ENHANCEMENT] Query API now supports timeouts. #1014 * [ENHANCEMENT] New `MetricVec` method `DeletePartialMatch(labels Labels)` for deleting all metrics that match provided labels. #1013 * [ENHANCEMENT] `api.Config` now accepts passing custom `*http.Client`. #1025 * [BUGFIX] Raise exemplar labels limit from 64 to 128 bytes as specified in OpenMetrics spec. #1091 * [BUGFIX] Allow adding exemplar to +Inf bucket to const histograms. #1094 * [ENHANCEMENT] Most `promhttp.Instrument*` middlewares now supports adding exemplars to metrics. This allows hooking those to your tracing middleware that retrieves trace ID and put it in exemplar if present. #1055 * [ENHANCEMENT] Added `testutil.ScrapeAndCompare` method. #1043 * [BUGFIX] Fixed `GopherJS` build support. #897 * [ENHANCEMENT] :warning: Added way to specify what `runtime/metrics` `collectors.NewGoCollector` should use. See [`ExampleGoCollector_WithAdvancedGoMetrics`](prometheus/collectors/go_collector_latest_test.go#L263). #1102 ## 1.12.2 / 2022-05-13 * [CHANGE] Added `collectors.WithGoCollections` that allows to choose what collection of Go runtime metrics user wants: Equivalent of [`MemStats` structure](https://pkg.go.dev/runtime#MemStats) configured using `GoRuntimeMemStatsCollection`, new based on dedicated [runtime/metrics](https://pkg.go.dev/runtime/metrics) metrics represented by `GoRuntimeMetricsCollection` option, or both by specifying `GoRuntimeMemStatsCollection | GoRuntimeMetricsCollection` flag. #1031 * [CHANGE] :warning: Change in `collectors.NewGoCollector` metrics: Reverting addition of new ~80 runtime metrics by default. You can enable this back with `GoRuntimeMetricsCollection` option or `GoRuntimeMemStatsCollection | GoRuntimeMetricsCollection` for smooth transition. * [BUGFIX] Fixed the bug that causes generated histogram metric names to end with `_total`. ⚠️ This changes 3 metric names in the new Go collector that was reverted from default in this release. * `go_gc_heap_allocs_by_size_bytes_total` -> `go_gc_heap_allocs_by_size_bytes`, * `go_gc_heap_frees_by_size_bytes_total` -> `go_gc_heap_allocs_by_size_bytes` * `go_gc_pauses_seconds_total` -> `go_gc_pauses_seconds`. * [CHANCE] Removed `-Inf` buckets from new Go Collector histograms. ## 1.12.1 / 2022-01-29 * [BUGFIX] Make the Go 1.17 collector concurrency-safe #969 * Use simpler locking in the Go 1.17 collector #975 * [BUGFIX] Reduce granularity of histogram buckets for Go 1.17 collector #974 * [ENHANCEMENT] API client: make HTTP reads more efficient #976 ## 1.12.0 / 2022-01-19 * [CHANGE] example/random: Move flags and metrics into main() #935 * [FEATURE] API client: Support wal replay status api #944 * [FEATURE] Use the runtime/metrics package for the Go collector for 1.17+ #955 * [ENHANCEMENT] API client: Update /api/v1/status/tsdb to include headStats #925 * [ENHANCEMENT] promhttp: Check validity of method and code label values #962 ## 1.11.0 / 2021-06-07 * [CHANGE] Add new collectors package. #862 * [CHANGE] `prometheus.NewExpvarCollector` is deprecated, use `collectors.NewExpvarCollector` instead. #862 * [CHANGE] `prometheus.NewGoCollector` is deprecated, use `collectors.NewGoCollector` instead. #862 * [CHANGE] `prometheus.NewBuildInfoCollector` is deprecated, use `collectors.NewBuildInfoCollector` instead. #862 * [FEATURE] Add new collector for database/sql#DBStats. #866 * [FEATURE] API client: Add exemplars API support. #861 * [ENHANCEMENT] API client: Add newer fields to Rules API. #855 * [ENHANCEMENT] API client: Add missing fields to Targets API. #856 ## 1.10.0 / 2021-03-18 * [CHANGE] Minimum required Go version is now 1.13. * [CHANGE] API client: Add matchers to `LabelNames` and `LabesValues`. #828 * [FEATURE] API client: Add buildinfo call. #841 * [BUGFIX] Fix build on riscv64. #833 ## 1.9.0 / 2020-12-17 * [FEATURE] `NewPidFileFn` helper to create process collectors for processes whose PID is read from a file. #804 * [BUGFIX] promhttp: Prevent endless loop in `InstrumentHandler...` middlewares with invalid metric or label names. #823 ## 1.8.0 / 2020-10-15 * [CHANGE] API client: Use `time.Time` rather than `string` for timestamps in `RuntimeinfoResult`. #777 * [FEATURE] Export `MetricVec` to facilitate implementation of vectors of custom `Metric` types. #803 * [FEATURE] API client: Support `/status/tsdb` endpoint. #773 * [ENHANCEMENT] API client: Enable GET fallback on status code 501. #802 * [ENHANCEMENT] Remove `Metric` references after reslicing to free up more memory. #784 ## 1.7.1 / 2020-06-23 * [BUGFIX] API client: Actually propagate start/end parameters of `LabelNames` and `LabelValues`. #771 ## 1.7.0 / 2020-06-17 * [CHANGE] API client: Add start/end parameters to `LabelNames` and `LabelValues`. #767 * [FEATURE] testutil: Add `GatherAndCount` and enable filtering in `CollectAndCount` #753 * [FEATURE] API client: Add support for `status` and `runtimeinfo` endpoints. #755 * [ENHANCEMENT] Wrapping `nil` with a `WrapRegistererWith...` function creates a no-op `Registerer`. #764 * [ENHANCEMENT] promlint: Allow Kelvin as a base unit for cases like color temperature. #761 * [BUGFIX] push: Properly handle empty job and label values. #752 ## 1.6.0 / 2020-04-28 * [FEATURE] testutil: Add lint checks for metrics, including a sub-package `promlint` to expose the linter engine for external usage. #739 #743 * [ENHANCEMENT] API client: Improve error messages. #731 * [BUGFIX] process collector: Fix `process_resident_memory_bytes` on 32bit MS Windows. #734 ## 1.5.1 / 2020-03-14 * [BUGFIX] promhttp: Remove another superfluous `WriteHeader` call. #726 ## 1.5.0 / 2020-03-03 * [FEATURE] promauto: Add a factory to allow automatic registration with a local registry. #713 * [FEATURE] promauto: Add `NewUntypedFunc`. #713 * [FEATURE] API client: Support new metadata endpoint. #718 ## 1.4.1 / 2020-02-07 * [BUGFIX] Fix timestamp of exemplars in `CounterVec`. #710 ## 1.4.0 / 2020-01-27 * [CHANGE] Go collector: Improve doc string for `go_gc_duration_seconds`. #702 * [FEATURE] Support a subset of OpenMetrics, including exemplars. Needs opt-in via `promhttp.HandlerOpts`. **EXPERIMENTAL** #706 * [FEATURE] Add `testutil.CollectAndCount`. #703 ## 1.3.0 / 2019-12-21 * [FEATURE] Support tags in Graphite bridge. #668 * [BUGFIX] API client: Actually return Prometheus warnings. #699 ## 1.2.1 / 2019-10-17 * [BUGFIX] Fix regression in the implementation of `Registerer.Unregister`. #663 ## 1.2.0 / 2019-10-15 * [FEATURE] Support pushing to Pushgateway v0.10+. #652 * [ENHANCEMENT] Improve hashing to make a spurious `AlreadyRegisteredError` less likely to occur. #657 * [ENHANCEMENT] API client: Add godoc examples. #630 * [BUGFIX] promhttp: Correctly call WriteHeader in HTTP middleware. #634 ## 1.1.0 / 2019-08-01 * [CHANGE] API client: Format time as UTC rather than RFC3339Nano. #617 * [CHANGE] API client: Add warnings to `LabelValues` and `LabelNames` calls. #609 * [FEATURE] Push: Support base64 encoding in grouping key. #624 * [FEATURE] Push: Add Delete method to Pusher. #613 ## 1.0.0 / 2019-06-15 _This release removes all previously deprecated features, resulting in the breaking changes listed below. As this is v1.0.0, semantic versioning applies from now on, with the exception of the API client and parts marked explicitly as experimental._ * [CHANGE] Remove objectives from the default `Summary`. (Objectives have to be set explicitly in the `SummaryOpts`.) #600 * [CHANGE] Remove all HTTP related feature in the `prometheus` package. (Use the `promhttp` package instead.) #600 * [CHANGE] Remove `push.FromGatherer`, `push.AddFromGatherer`, `push.Collectors`. (Use `push.New` instead.) #600 * [CHANGE] API client: Pass warnings through on non-error responses. #599 * [CHANGE] API client: Add warnings to `Series` call. #603 * [FEATURE] Make process collector work on Microsoft Windows. **EXPERIMENTAL** #596 * [FEATURE] API client: Add `/labels` call. #604 * [BUGFIX] Make `AlreadyRegisteredError` usable for wrapped registries. #607 ## 0.9.4 / 2019-06-07 * [CHANGE] API client: Switch to alert values as strings. #585 * [FEATURE] Add a collector for Go module build information. #595 * [FEATURE] promhttp: Add an counter for internal errors during HTTP exposition. #594 * [FEATURE] API client: Support target metadata API. #590 * [FEATURE] API client: Support storage warnings. #562 * [ENHANCEMENT] API client: Improve performance handling JSON. #570 * [BUGFIX] Reduce test flakiness. #573 ## 0.9.3 / 2019-05-16 * [CHANGE] Required Go version is now 1.9+. #561 * [FEATURE] API client: Add POST with get fallback for Query/QueryRange. #557 * [FEATURE] API client: Add alerts endpoint. #552 * [FEATURE] API client: Add rules endpoint. #508 * [FEATURE] push: Add option to pick metrics format. #540 * [ENHANCEMENT] Limit time the Go collector may take to collect memstats, returning results from the previous collection in case of a timeout. #568 * [ENHANCEMENT] Pusher now requires only a thin interface instead of a full `http.Client`, facilitating mocking and custom HTTP client implementation. #559 * [ENHANCEMENT] Memory usage improvement for histograms and summaries without objectives. #536 * [ENHANCEMENT] Summaries without objectives are now lock-free. #521 * [BUGFIX] promhttp: `InstrumentRoundTripperTrace` now takes into account a pre-set context. #582 * [BUGFIX] `TestCounterAddLarge` now works on all platforms. #567 * [BUGFIX] Fix `promhttp` examples. #535 #544 * [BUGFIX] API client: Wait for done before writing to shared response body. #532 * [BUGFIX] API client: Deal with discovered labels properly. #529 ## 0.9.2 / 2018-12-06 * [FEATURE] Support for Go modules. #501 * [FEATURE] `Timer.ObserveDuration` returns observed duration. #509 * [ENHANCEMENT] Improved doc comments and error messages. #504 * [BUGFIX] Fix race condition during metrics gathering. #512 * [BUGFIX] Fix testutil metric comparison for Histograms and empty labels. #494 #498 ## 0.9.1 / 2018-11-03 * [FEATURE] Add `WriteToTextfile` function to facilitate the creation of *.prom files for the textfile collector of the node exporter. #489 * [ENHANCEMENT] More descriptive error messages for inconsistent label cardinality. #487 * [ENHANCEMENT] Exposition: Use a GZIP encoder pool to avoid allocations in high-frequency scrape scenarios. #366 * [ENHANCEMENT] Exposition: Streaming serving of metrics data while encoding. #482 * [ENHANCEMENT] API client: Add a way to return the body of a 5xx response. #479 ## 0.9.0 / 2018-10-15 * [CHANGE] Go1.6 is no longer supported. * [CHANGE] More refinements of the `Registry` consistency checks: Duplicated labels are now detected, but inconsistent label dimensions are now allowed. Collisions with the β€œmagic” metric and label names in Summaries and Histograms are detected now. #108 #417 #471 * [CHANGE] Changed `ProcessCollector` constructor. #219 * [CHANGE] Changed Go counter `go_memstats_heap_released_bytes_total` to gauge `go_memstats_heap_released_bytes`. #229 * [CHANGE] Unexported `LabelPairSorter`. #453 * [CHANGE] Removed the `Untyped` metric from direct instrumentation. #340 * [CHANGE] Unexported `MetricVec`. #319 * [CHANGE] Removed deprecated `Set` method from `Counter` #247 * [CHANGE] Removed deprecated `RegisterOrGet` and `MustRegisterOrGet`. #247 * [CHANGE] API client: Introduced versioned packages. * [FEATURE] A `Registerer` can be wrapped with prefixes and labels. #357 * [FEATURE] β€œDescribe by collect” helper function. #239 * [FEATURE] Added package `testutil`. #58 * [FEATURE] Timestamp can be explicitly set for const metrics. #187 * [FEATURE] β€œUnchecked” collectors are possible now without cheating. #47 * [FEATURE] Pushing to the Pushgateway reworked in package `push` to support many new features. (The old functions are still usable but deprecated.) #372 #341 * [FEATURE] Configurable connection limit for scrapes. #179 * [FEATURE] New HTTP middlewares to instrument `http.Handler` and `http.RoundTripper`. The old middlewares and the pre-instrumented `/metrics` handler are (strongly) deprecated. #316 #57 #101 #224 * [FEATURE] β€œCurrying” for metric vectors. #320 * [FEATURE] A `Summary` can be created without quantiles. #118 * [FEATURE] Added a `Timer` helper type. #231 * [FEATURE] Added a Graphite bridge. #197 * [FEATURE] Help strings are now optional. #460 * [FEATURE] Added `process_virtual_memory_max_bytes` metric. #438 #440 * [FEATURE] Added `go_gc_cpu_fraction` and `go_threads` metrics. #281 #277 * [FEATURE] Added `promauto` package with auto-registering metrics. #385 #393 * [FEATURE] Add `SetToCurrentTime` method to `Gauge`. #259 * [FEATURE] API client: Add AlertManager, Status, and Target methods. #402 * [FEATURE] API client: Add admin methods. #398 * [FEATURE] API client: Support series API. #361 * [FEATURE] API client: Support querying label values. * [ENHANCEMENT] Smarter creation of goroutines during scraping. Solves memory usage spikes in certain situations. #369 * [ENHANCEMENT] Counters are now faster if dealing with integers only. #367 * [ENHANCEMENT] Improved label validation. #274 #335 * [BUGFIX] Creating a const metric with an invalid `Desc` returns an error. #460 * [BUGFIX] Histogram observations don't race any longer with exposition. #275 * [BUGFIX] Fixed goroutine leaks. #236 #472 * [BUGFIX] Fixed an error message for exponential histogram buckets. #467 * [BUGFIX] Fixed data race writing to the metric map. #401 * [BUGFIX] API client: Decode JSON on a 4xx response but do not on 204 responses. #476 #414 ## 0.8.0 / 2016-08-17 * [CHANGE] Registry is doing more consistency checks. This might break existing setups that used to export inconsistent metrics. * [CHANGE] Pushing to Pushgateway moved to package `push` and changed to allow arbitrary grouping. * [CHANGE] Removed `SelfCollector`. * [CHANGE] Removed `PanicOnCollectError` and `EnableCollectChecks` methods. * [CHANGE] Moved packages to the prometheus/common repo: `text`, `model`, `extraction`. * [CHANGE] Deprecated a number of functions. * [FEATURE] Allow custom registries. Added `Registerer` and `Gatherer` interfaces. * [FEATURE] Separated HTTP exposition, allowing custom HTTP handlers (package `promhttp`) and enabling the creation of other exposition mechanisms. * [FEATURE] `MustRegister` is variadic now, allowing registration of many collectors in one call. * [FEATURE] Added HTTP API v1 package. * [ENHANCEMENT] Numerous documentation improvements. * [ENHANCEMENT] Improved metric sorting. * [ENHANCEMENT] Inlined fnv64a hashing for improved performance. * [ENHANCEMENT] Several test improvements. * [BUGFIX] Handle collisions in MetricVec. ## 0.7.0 / 2015-07-27 * [CHANGE] Rename ExporterLabelPrefix to ExportedLabelPrefix. * [BUGFIX] Closed gaps in metric consistency check. * [BUGFIX] Validate LabelName/LabelSet on JSON unmarshaling. * [ENHANCEMENT] Document the possibility to create "empty" metrics in a metric vector. * [ENHANCEMENT] Fix and clarify various doc comments and the README.md. * [ENHANCEMENT] (Kind of) solve "The Proxy Problem" of http.InstrumentHandler. * [ENHANCEMENT] Change responseWriterDelegator.written to int64. ## 0.6.0 / 2015-06-01 * [CHANGE] Rename process_goroutines to go_goroutines. * [ENHANCEMENT] Validate label names during YAML decoding. * [ENHANCEMENT] Add LabelName regular expression. * [BUGFIX] Ensure alignment of struct members for 32-bit systems. ## 0.5.0 / 2015-05-06 * [BUGFIX] Removed a weakness in the fingerprinting aka signature code. This makes fingerprinting slower and more allocation-heavy, but the weakness was too severe to be tolerated. * [CHANGE] As a result of the above, Metric.Fingerprint is now returning a different fingerprint. To keep the same fingerprint, the new method Metric.FastFingerprint was introduced, which will be used by the Prometheus server for storage purposes (implying that a collision detection has to be added, too). * [ENHANCEMENT] The Metric.Equal and Metric.Before do not depend on fingerprinting anymore, removing the possibility of an undetected fingerprint collision. * [FEATURE] The Go collector in the exposition library includes garbage collection stats. * [FEATURE] The exposition library allows to create constant "throw-away" summaries and histograms. * [CHANGE] A number of new reserved labels and prefixes. ## 0.4.0 / 2015-04-08 * [CHANGE] Return NaN when Summaries have no observations yet. * [BUGFIX] Properly handle Summary decay upon Write(). * [BUGFIX] Fix the documentation link to the consumption library. * [FEATURE] Allow the metric family injection hook to merge with existing metric families. * [ENHANCEMENT] Removed cgo dependency and conditional compilation of procfs. * [MAINTENANCE] Adjusted to changes in matttproud/golang_protobuf_extensions. ## 0.3.2 / 2015-03-11 * [BUGFIX] Fixed the receiver type of COWMetric.Set(). This method is only used by the Prometheus server internally. * [CLEANUP] Added licenses of vendored code left out by godep. ## 0.3.1 / 2015-03-04 * [ENHANCEMENT] Switched fingerprinting functions from own free list to sync.Pool. * [CHANGE] Makefile uses Go 1.4.2 now (only relevant for examples and tests). ## 0.3.0 / 2015-03-03 * [CHANGE] Changed the fingerprinting for metrics. THIS WILL INVALIDATE ALL PERSISTED FINGERPRINTS. IF YOU COMPILE THE PROMETHEUS SERVER WITH THIS VERSION, YOU HAVE TO WIPE THE PREVIOUSLY CREATED STORAGE. * [CHANGE] LabelValuesToSignature removed. (Nobody had used it, and it was arguably broken.) * [CHANGE] Vendored dependencies. Those are only used by the Makefile. If client_golang is used as a library, the vendoring will stay out of your way. * [BUGFIX] Remove a weakness in the fingerprinting for metrics. (This made the fingerprinting change above necessary.) * [FEATURE] Added new fingerprinting functions SignatureForLabels and SignatureWithoutLabels to be used by the Prometheus server. These functions require fewer allocations than the ones currently used by the server. ## 0.2.0 / 2015-02-23 * [FEATURE] Introduce new Histagram metric type. * [CHANGE] Ignore process collector errors for now (better error handling pending). * [CHANGE] Use clear error interface for process pidFn. * [BUGFIX] Fix Go download links for several archs and OSes. * [ENHANCEMENT] Massively improve Gauge and Counter performance. * [ENHANCEMENT] Catch illegal label names for summaries in histograms. * [ENHANCEMENT] Reduce allocations during fingerprinting. * [ENHANCEMENT] Remove cgo dependency. procfs package will only be included if both cgo is available and the build is for an OS with procfs. * [CLEANUP] Clean up code style issues. * [CLEANUP] Mark slow test as such and exclude them from travis. * [CLEANUP] Update protobuf library package name. * [CLEANUP] Updated vendoring of beorn7/perks. ## 0.1.0 / 2015-02-02 * [CLEANUP] Introduced semantic versioning and changelog. From now on, changes will be reported in this file. client_golang-1.21.1/CODE_OF_CONDUCT.md000066400000000000000000000002301476160432400172020ustar00rootroot00000000000000# Prometheus Community Code of Conduct Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). client_golang-1.21.1/CONTRIBUTING.md000066400000000000000000000020611476160432400166400ustar00rootroot00000000000000# Contributing Thank you for contributing to our project! Here are the steps and guidelines to follow when creating a pull request (PR). Prometheus uses GitHub to manage reviews of pull requests. * If you have a trivial fix or improvement, go ahead and create a pull request, addressing (with `@...`) the maintainer of this repository (see [MAINTAINERS.md](MAINTAINERS.md)) in the description of the pull request. * If you plan to do something more involved, first discuss your ideas on our [mailing list](https://groups.google.com/forum/?fromgroups#!forum/prometheus-developers). This will avoid unnecessary work and surely give you and us a good deal of inspiration. * Relevant coding style guidelines are the [Go Code Review Comments](https://code.google.com/p/go-wiki/wiki/CodeReviewComments) and the _Formatting and style_ section of Peter Bourgon's [Go: Best Practices for Production Environments](http://peter.bourgon.org/go-in-production/#formatting-and-style). * Be sure to sign off on the [DCO](https://github.com/probot/dco#how-it-works) client_golang-1.21.1/Dockerfile000066400000000000000000000026071476160432400164070ustar00rootroot00000000000000# This Dockerfile builds an image for a client_golang example. # # Use as (from the root for the client_golang repository): # docker build -f Dockerfile -t prometheus/golang-example . # Run as # docker run -P prometheus/golang-example /random # or # docker run -P prometheus/golang-example /simple # Test as # curl $ip:$port/metrics # Builder image, where we build the example. FROM golang:1 AS builder WORKDIR /go/src/github.com/prometheus/client_golang COPY . . WORKDIR /go/src/github.com/prometheus/client_golang/prometheus RUN go get -d WORKDIR /go/src/github.com/prometheus/client_golang/examples/random RUN CGO_ENABLED=0 GOOS=linux go build -a -tags netgo -ldflags '-w' WORKDIR /go/src/github.com/prometheus/client_golang/examples/simple RUN CGO_ENABLED=0 GOOS=linux go build -a -tags netgo -ldflags '-w' WORKDIR /go/src/github.com/prometheus/client_golang/examples/gocollector RUN CGO_ENABLED=0 GOOS=linux go build -a -tags netgo -ldflags '-w' # Final image. FROM quay.io/prometheus/busybox:latest LABEL maintainer="The Prometheus Authors " COPY --from=builder /go/src/github.com/prometheus/client_golang/examples/random \ /go/src/github.com/prometheus/client_golang/examples/simple \ /go/src/github.com/prometheus/client_golang/examples/gocollector ./ EXPOSE 8080 CMD ["echo", "Please run an example. Either /random, /simple or /gocollector"] client_golang-1.21.1/LICENSE000066400000000000000000000261351476160432400154240ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. client_golang-1.21.1/MAINTAINERS.md000066400000000000000000000003231476160432400165020ustar00rootroot00000000000000* Arianna Vespri @vesari * Arthur Silva Sens @ArthurSens * BartΕ‚omiej PΕ‚otka @bwplotka * Kemal Akkoyun @kakkoyun client_golang-1.21.1/Makefile000066400000000000000000000022331476160432400160500ustar00rootroot00000000000000# Copyright 2018 The Prometheus Authors # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. include .bingo/Variables.mk include Makefile.common .PHONY: test test: deps common-test .PHONY: test-short test-short: deps common-test-short .PHONY: generate-go-collector-test-files file := supported_go_versions.txt VERSIONS := $(shell cat ${file}) generate-go-collector-test-files: for GO_VERSION in $(VERSIONS); do \ docker run \ --platform linux/amd64 \ --rm -v $(PWD):/workspace \ -w /workspace \ golang:$$GO_VERSION \ bash ./generate-go-collector.bash; \ done; \ go mod tidy .PHONY: fmt fmt: common-format $(GOIMPORTS) -local github.com/prometheus/client_golang -w . client_golang-1.21.1/Makefile.common000066400000000000000000000221631476160432400173430ustar00rootroot00000000000000# Copyright 2018 The Prometheus Authors # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # A common Makefile that includes rules to be reused in different prometheus projects. # !!! Open PRs only against the prometheus/prometheus/Makefile.common repository! # Example usage : # Create the main Makefile in the root project directory. # include Makefile.common # customTarget: # @echo ">> Running customTarget" # # Ensure GOBIN is not set during build so that promu is installed to the correct path unexport GOBIN GO ?= go GOFMT ?= $(GO)fmt FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH))) GOOPTS ?= GOHOSTOS ?= $(shell $(GO) env GOHOSTOS) GOHOSTARCH ?= $(shell $(GO) env GOHOSTARCH) GO_VERSION ?= $(shell $(GO) version) GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION)) PRE_GO_111 ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.') PROMU := $(FIRST_GOPATH)/bin/promu pkgs = ./... ifeq (arm, $(GOHOSTARCH)) GOHOSTARM ?= $(shell GOARM= $(GO) env GOARM) GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)v$(GOHOSTARM) else GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH) endif GOTEST := $(GO) test GOTEST_DIR := ifneq ($(CIRCLE_JOB),) ifneq ($(shell command -v gotestsum 2> /dev/null),) GOTEST_DIR := test-results GOTEST := gotestsum --junitfile $(GOTEST_DIR)/unit-tests.xml -- endif endif PROMU_VERSION ?= 0.17.0 PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz SKIP_GOLANGCI_LINT := GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= GOLANGCI_LINT_VERSION ?= v1.63.4 # golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64. # windows isn't included here because of the path separator being different. ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386 arm64)) # If we're in CI and there is an Actions file, that means the linter # is being run in Actions, so we don't need to run it here. ifneq (,$(SKIP_GOLANGCI_LINT)) GOLANGCI_LINT := else ifeq (,$(CIRCLE_JOB)) GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint else ifeq (,$(wildcard .github/workflows/golangci-lint.yml)) GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint endif endif endif PREFIX ?= $(shell pwd) BIN_DIR ?= $(shell pwd) DOCKER_IMAGE_TAG ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD)) DOCKERFILE_PATH ?= ./Dockerfile DOCKERBUILD_CONTEXT ?= ./ DOCKER_REPO ?= prom DOCKER_ARCHS ?= amd64 BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS)) PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS)) TAG_DOCKER_ARCHS = $(addprefix common-docker-tag-latest-,$(DOCKER_ARCHS)) SANITIZED_DOCKER_IMAGE_TAG := $(subst +,-,$(DOCKER_IMAGE_TAG)) ifeq ($(GOHOSTARCH),amd64) ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux freebsd darwin windows)) # Only supported on amd64 test-flags := -race endif endif # This rule is used to forward a target like "build" to "common-build". This # allows a new "build" target to be defined in a Makefile which includes this # one and override "common-build" without override warnings. %: common-% ; .PHONY: common-all common-all: precheck style check_license lint yamllint unused build test .PHONY: common-style common-style: @echo ">> checking code style" @fmtRes=$$($(GOFMT) -d $$(find . -path ./vendor -prune -o -name '*.go' -print)); \ if [ -n "$${fmtRes}" ]; then \ echo "gofmt checking failed!"; echo "$${fmtRes}"; echo; \ echo "Please ensure you are using $$($(GO) version) for formatting code."; \ exit 1; \ fi .PHONY: common-check_license common-check_license: @echo ">> checking license header" @licRes=$$(for file in $$(find . -type f -iname '*.go' ! -path './vendor/*') ; do \ awk 'NR<=3' $$file | grep -Eq "(Copyright|generated|GENERATED)" || echo $$file; \ done); \ if [ -n "$${licRes}" ]; then \ echo "license header checking failed:"; echo "$${licRes}"; \ exit 1; \ fi .PHONY: common-deps common-deps: @echo ">> getting dependencies" $(GO) mod download .PHONY: update-go-deps update-go-deps: @echo ">> updating Go dependencies" @for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \ $(GO) get -d $$m; \ done $(GO) mod tidy .PHONY: common-test-short common-test-short: $(GOTEST_DIR) @echo ">> running short tests" $(GOTEST) -short $(GOOPTS) $(pkgs) .PHONY: common-test common-test: $(GOTEST_DIR) @echo ">> running all tests" $(GOTEST) $(test-flags) $(GOOPTS) $(pkgs) $(GOTEST_DIR): @mkdir -p $@ .PHONY: common-format common-format: @echo ">> formatting code" $(GO) fmt $(pkgs) .PHONY: common-vet common-vet: @echo ">> vetting code" $(GO) vet $(GOOPTS) $(pkgs) .PHONY: common-lint common-lint: $(GOLANGCI_LINT) ifdef GOLANGCI_LINT @echo ">> running golangci-lint" $(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs) endif .PHONY: common-lint-fix common-lint-fix: $(GOLANGCI_LINT) ifdef GOLANGCI_LINT @echo ">> running golangci-lint fix" $(GOLANGCI_LINT) run --fix $(GOLANGCI_LINT_OPTS) $(pkgs) endif .PHONY: common-yamllint common-yamllint: @echo ">> running yamllint on all YAML files in the repository" ifeq (, $(shell command -v yamllint 2> /dev/null)) @echo "yamllint not installed so skipping" else yamllint . endif # For backward-compatibility. .PHONY: common-staticcheck common-staticcheck: lint .PHONY: common-unused common-unused: @echo ">> running check for unused/missing packages in go.mod" $(GO) mod tidy @git diff --exit-code -- go.sum go.mod .PHONY: common-build common-build: promu @echo ">> building binaries" $(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES) .PHONY: common-tarball common-tarball: promu @echo ">> building release tarball" $(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR) .PHONY: common-docker-repo-name common-docker-repo-name: @echo "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)" .PHONY: common-docker $(BUILD_DOCKER_ARCHS) common-docker: $(BUILD_DOCKER_ARCHS) $(BUILD_DOCKER_ARCHS): common-docker-%: docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \ -f $(DOCKERFILE_PATH) \ --build-arg ARCH="$*" \ --build-arg OS="linux" \ $(DOCKERBUILD_CONTEXT) .PHONY: common-docker-publish $(PUBLISH_DOCKER_ARCHS) common-docker-publish: $(PUBLISH_DOCKER_ARCHS) $(PUBLISH_DOCKER_ARCHS): common-docker-publish-%: docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" DOCKER_MAJOR_VERSION_TAG = $(firstword $(subst ., ,$(shell cat VERSION))) .PHONY: common-docker-tag-latest $(TAG_DOCKER_ARCHS) common-docker-tag-latest: $(TAG_DOCKER_ARCHS) $(TAG_DOCKER_ARCHS): common-docker-tag-latest-%: docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest" docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)" .PHONY: common-docker-manifest common-docker-manifest: DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(SANITIZED_DOCKER_IMAGE_TAG)) DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" .PHONY: promu promu: $(PROMU) $(PROMU): $(eval PROMU_TMP := $(shell mktemp -d)) curl -s -L $(PROMU_URL) | tar -xvzf - -C $(PROMU_TMP) mkdir -p $(FIRST_GOPATH)/bin cp $(PROMU_TMP)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM)/promu $(FIRST_GOPATH)/bin/promu rm -r $(PROMU_TMP) .PHONY: proto proto: @echo ">> generating code from proto files" @./scripts/genproto.sh ifdef GOLANGCI_LINT $(GOLANGCI_LINT): mkdir -p $(FIRST_GOPATH)/bin curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_LINT_VERSION)/install.sh \ | sed -e '/install -d/d' \ | sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION) endif .PHONY: precheck precheck:: define PRECHECK_COMMAND_template = precheck:: $(1)_precheck PRECHECK_COMMAND_$(1) ?= $(1) $$(strip $$(PRECHECK_OPTIONS_$(1))) .PHONY: $(1)_precheck $(1)_precheck: @if ! $$(PRECHECK_COMMAND_$(1)) 1>/dev/null 2>&1; then \ echo "Execution of '$$(PRECHECK_COMMAND_$(1))' command failed. Is $(1) installed?"; \ exit 1; \ fi endef govulncheck: install-govulncheck govulncheck ./... install-govulncheck: command -v govulncheck > /dev/null || go install golang.org/x/vuln/cmd/govulncheck@latest client_golang-1.21.1/NOTICE000066400000000000000000000011671476160432400153210ustar00rootroot00000000000000Prometheus instrumentation library for Go applications Copyright 2012-2015 The Prometheus Authors This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/). The following components are included in this product: perks - a fork of https://github.com/bmizerany/perks https://github.com/beorn7/perks Copyright 2013-2015 Blake Mizerany, BjΓΆrn Rabenstein See https://github.com/beorn7/perks/blob/master/README.md for license details. Go support for Protocol Buffers - Google's data interchange format http://github.com/golang/protobuf/ Copyright 2010 The Go Authors See source code for license details. client_golang-1.21.1/README.md000066400000000000000000000076201476160432400156740ustar00rootroot00000000000000# Prometheus Go client library [![CI](https://github.com/prometheus/client_golang/actions/workflows/go.yml/badge.svg)](https://github.com/prometheus/client_golang/actions/workflows/ci.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/prometheus/client_golang)](https://goreportcard.com/report/github.com/prometheus/client_golang) [![Go Reference](https://pkg.go.dev/badge/github.com/prometheus/client_golang.svg)](https://pkg.go.dev/github.com/prometheus/client_golang) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/prometheus/client_golang/badge)](https://securityscorecards.dev/viewer/?uri=github.com/prometheus/client_golang) [![Slack](https://img.shields.io/badge/join%20slack-%23prometheus--client_golang-brightgreen.svg)](https://slack.cncf.io/) This is the [Go](http://golang.org) client library for [Prometheus](http://prometheus.io). It has two separate parts, one for instrumenting application code, and one for creating clients that talk to the Prometheus HTTP API. ## Version Compatibility This library supports the three most recent major releases of Go. While it may function with older versions, we only provide fixes and support for the currently supported Go releases. > [!NOTE] > See our [Release Process](RELEASE.md#supported-go-versions) for details on compatibility and support policies. ## Important note about releases and stability This repository generally follows [Semantic Versioning](https://semver.org/). However, the API client in `prometheus/client_golang/api/…` is still considered experimental. Breaking changes of the API client will _not_ trigger a new major release. The same is true for selected other new features explicitly marked as **EXPERIMENTAL** in CHANGELOG.md. Features that require breaking changes in the stable parts of the repository are being batched up and tracked in the [v2 milestone](https://github.com/prometheus/client_golang/milestone/2), but plans for further development of v2 at the moment. > NOTE: The initial v2 attempt is in a [separate branch](https://github.com/prometheus/client_golang/tree/dev-v2). We also started experimenting on a new `prometheus.V2.*` APIs in [the 1.x's V2 struct](https://github.com/prometheus/client_golang/blob/main/prometheus/vnext.go#L23). Help wanted! ## Instrumenting applications [![Go Reference](https://pkg.go.dev/badge/github.com/prometheus/client_golang/prometheus.svg)](https://pkg.go.dev/github.com/prometheus/client_golang/prometheus) The [`prometheus` directory](https://github.com/prometheus/client_golang/tree/main/prometheus) contains the instrumentation library. See the [guide](https://prometheus.io/docs/guides/go-application/) on the Prometheus website to learn more about instrumenting applications. The [`examples` directory](https://github.com/prometheus/client_golang/tree/main/examples) contains simple examples of instrumented code. ## Client for the Prometheus HTTP API [![Go Reference](https://pkg.go.dev/badge/github.com/prometheus/client_golang/api.svg)](https://pkg.go.dev/github.com/prometheus/client_golang/api) The [`api/prometheus` directory](https://github.com/prometheus/client_golang/tree/main/api/prometheus) contains the client for the [Prometheus HTTP API](http://prometheus.io/docs/querying/api/). It allows you to write Go applications that query time series data from a Prometheus server. It is still in alpha stage. ## Where is `model`, `extraction`, and `text`? The `model` packages has been moved to [`prometheus/common/model`](https://github.com/prometheus/common/tree/main/model). The `extraction` and `text` packages are now contained in [`prometheus/common/expfmt`](https://github.com/prometheus/common/tree/main/expfmt). ## Contributing and community See the [contributing guidelines](CONTRIBUTING.md) and the [Community section](http://prometheus.io/community/) of the homepage. `client_golang` community is also present on the CNCF Slack `#prometheus-client_golang`. client_golang-1.21.1/RELEASE.md000066400000000000000000000122051476160432400160120ustar00rootroot00000000000000# Release The Prometheus Go client library does not follow a strict release schedule. Releases are made based on necessity and the current state of the project. ## Branch Management We use [Semantic Versioning](https://semver.org/). - Maintain separate `release-.` branches - Branch protection enabled automatically for `release-*` branches - Bug fixes go to the latest release branch, then merge to main - Features and changes go to main branch - Non-latest minor release branches are maintained (e.g. bug and security fixes) on the best-effort basis ## Pre-Release Preparations 1. Review main branch state: - Expedite critical bug fixes - Don't rush on risky changes, consider them for the next release if not ready - Update dependencies via Dependabot PRs or manually if needed - Check for security alerts ## Cutting a Minor Release 1. Create release branch: ```bash git checkout -b release-. main git push origin release-. ``` 2. Create a new branch on top of `release-.`: ```bash git checkout -b /cut-..0 release-. ``` 3. Update version and documentation: - Update `VERSION` file - Update `CHANGELOG.md` (user-impacting changes) - Each release documents the minimum required Go version - Order: [SECURITY], [CHANGE], [FEATURE], [ENHANCEMENT], [BUGFIX] - For RCs, append `-rc.0` 4. Create PR and get review 5. After merge, create tags: ```bash tag="v$(< VERSION)" git tag -s "${tag}" -m "${tag}" git push origin "${tag}" ``` 6. For Release Candidates: - Create PR against [prometheus/prometheus](https://github.com/prometheus/prometheus) using RC version - Create PR against [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) using RC version - Make sure the CI is green for the PRs - Allow 1-2 days for downstream testing - Fix any issues found before final release - Use `-rc.1`, `-rc.2` etc. for additional fixes - For RCs, ensure "pre-release" box is checked 7. For Final Release: - Wait for CI completion - Click "Publish release"! 8. Announce release: - - Slack - x.com/BlueSky 9. Merge release branch to main: ```bash git checkout main git merge --no-ff release-. ``` ## Cutting a Patch Release 1. Create branch from release branch: ```bash git checkout -b /cut-.. release-. ``` 2. Apply fixes: - Commit the required fixes; avoid refactoring or otherwise risky changes (preferred) - Cherry-pick from main if fix was already merged there: `git cherry-pick ` 3. Follow steps 3-9 from minor release process ## Handling Merge Conflicts If conflicts occur merging to main: 1. Create branch: `/resolve-conflicts` 2. Fix conflicts there 3. PR into main 4. Leave release branch unchanged ## Note on Versioning ## Compatibility Guarantees ### Supported Go Versions - Support provided only for the three most recent major Go releases - While the library may work with older Go versions, support and fixes are best-effort for those. - Each release documents the minimum required Go version ### API Stability The Prometheus Go client library aims to maintain backward compatibility within minor versions, similar to [Go 1 compatibility promises](https://golang.org/doc/go1compat): ## Minor Version Changes - API signatures are `stable` within a **minor** version - No breaking changes are introduced - Methods may be added, but not removed - Arguments may NOT be removed or added (unless varargs) - Return types may NOT be changed - Types may be modified or relocated - Default behaviors might be altered (unfortunately, this has happened in the past) ## Major Version Changes - API signatures may change between **major** versions - Types may be modified or relocated - Default behaviors might be altered - Feature removal/deprecation can occur with minor version bump ### Compatibility Testing Before each release: 1. **Internal Testing**: - Full test suite must pass - Integration tests with latest Prometheus server - (optional) Benchmark comparisons with previous version > There is no facility for running benchmarks in CI, so this is best-effort. 2. **External Validation**: Test against bigger users, especially looking for broken tests or builds. This will give us awareness of a potential accidental breaking changes, or if there were intentional ones, the potential damage radius of them. - Testing with [prometheus/prometheus](https://github.com/prometheus/prometheus) `main` branch - Testing with [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) `main` branch - Breaking changes must be documented in CHANGELOG.md ### Version Policy - Bug fixes increment patch version (e.g., v0.9.1) - New features increment minor version (e.g., v0.10.0) - Breaking changes increment minor version with clear documentation ### Deprecation Policy 1. Features may be deprecated in any minor release 2. Deprecated features: - Will be documented in CHANGELOG.md - Will emit warnings when used (when possible) client_golang-1.21.1/SECURITY.md000066400000000000000000000002541476160432400162020ustar00rootroot00000000000000# Reporting a security issue The Prometheus security policy, including how to report vulnerabilities, can be found here: client_golang-1.21.1/VERSION000066400000000000000000000000071476160432400154550ustar00rootroot000000000000001.21.1 client_golang-1.21.1/api/000077500000000000000000000000001476160432400151615ustar00rootroot00000000000000client_golang-1.21.1/api/client.go000066400000000000000000000071451476160432400167750ustar00rootroot00000000000000// Copyright 2015 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package api provides clients for the HTTP APIs. package api import ( "bytes" "context" "errors" "net" "net/http" "net/url" "path" "strings" "time" ) // DefaultRoundTripper is used if no RoundTripper is set in Config. var DefaultRoundTripper http.RoundTripper = &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, }).DialContext, TLSHandshakeTimeout: 10 * time.Second, } // Config defines configuration parameters for a new client. type Config struct { // The address of the Prometheus to connect to. Address string // Client is used by the Client to drive HTTP requests. If not provided, // a new one based on the provided RoundTripper (or DefaultRoundTripper) will be used. Client *http.Client // RoundTripper is used by the Client to drive HTTP requests. If not // provided, DefaultRoundTripper will be used. RoundTripper http.RoundTripper } func (cfg *Config) roundTripper() http.RoundTripper { if cfg.RoundTripper == nil { return DefaultRoundTripper } return cfg.RoundTripper } func (cfg *Config) client() http.Client { if cfg.Client == nil { return http.Client{ Transport: cfg.roundTripper(), } } return *cfg.Client } func (cfg *Config) validate() error { if cfg.Client != nil && cfg.RoundTripper != nil { return errors.New("api.Config.RoundTripper and api.Config.Client are mutually exclusive") } return nil } // Client is the interface for an API client. type Client interface { URL(ep string, args map[string]string) *url.URL Do(context.Context, *http.Request) (*http.Response, []byte, error) } type CloseIdler interface { CloseIdleConnections() } // NewClient returns a new Client. // // It is safe to use the returned Client from multiple goroutines. func NewClient(cfg Config) (Client, error) { u, err := url.Parse(cfg.Address) if err != nil { return nil, err } u.Path = strings.TrimRight(u.Path, "/") if err := cfg.validate(); err != nil { return nil, err } return &httpClient{ endpoint: u, client: cfg.client(), }, nil } type httpClient struct { endpoint *url.URL client http.Client } func (c *httpClient) URL(ep string, args map[string]string) *url.URL { p := path.Join(c.endpoint.Path, ep) for arg, val := range args { arg = ":" + arg p = strings.ReplaceAll(p, arg, val) } u := *c.endpoint u.Path = p return &u } func (c *httpClient) CloseIdleConnections() { c.client.CloseIdleConnections() } func (c *httpClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, error) { if ctx != nil { req = req.WithContext(ctx) } resp, err := c.client.Do(req) defer func() { if resp != nil { resp.Body.Close() } }() if err != nil { return nil, nil, err } var body []byte done := make(chan struct{}) go func() { var buf bytes.Buffer _, err = buf.ReadFrom(resp.Body) body = buf.Bytes() close(done) }() select { case <-ctx.Done(): <-done err = resp.Body.Close() if err == nil { err = ctx.Err() } case <-done: } return resp, body, err } client_golang-1.21.1/api/client_test.go000066400000000000000000000074061476160432400200340ustar00rootroot00000000000000// Copyright 2015 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package api import ( "bytes" "context" "fmt" "net/http" "net/http/httptest" "net/url" "testing" ) func TestConfig(t *testing.T) { c := Config{} if c.roundTripper() != DefaultRoundTripper { t.Fatalf("expected default roundtripper for nil RoundTripper field") } } func TestClientURL(t *testing.T) { tests := []struct { address string endpoint string args map[string]string expected string }{ { address: "http://localhost:9090", endpoint: "/test", expected: "http://localhost:9090/test", }, { address: "http://localhost", endpoint: "/test", expected: "http://localhost/test", }, { address: "http://localhost:9090", endpoint: "test", expected: "http://localhost:9090/test", }, { address: "http://localhost:9090/prefix", endpoint: "/test", expected: "http://localhost:9090/prefix/test", }, { address: "https://localhost:9090/", endpoint: "/test/", expected: "https://localhost:9090/test", }, { address: "http://localhost:9090", endpoint: "/test/:param", args: map[string]string{ "param": "content", }, expected: "http://localhost:9090/test/content", }, { address: "http://localhost:9090", endpoint: "/test/:param/more/:param", args: map[string]string{ "param": "content", }, expected: "http://localhost:9090/test/content/more/content", }, { address: "http://localhost:9090", endpoint: "/test/:param/more/:foo", args: map[string]string{ "param": "content", "foo": "bar", }, expected: "http://localhost:9090/test/content/more/bar", }, { address: "http://localhost:9090", endpoint: "/test/:param", args: map[string]string{ "nonexistent": "content", }, expected: "http://localhost:9090/test/:param", }, } for _, test := range tests { ep, err := url.Parse(test.address) if err != nil { t.Fatal(err) } hclient := &httpClient{ endpoint: ep, client: http.Client{Transport: DefaultRoundTripper}, } u := hclient.URL(test.endpoint, test.args) if u.String() != test.expected { t.Errorf("unexpected result: got %s, want %s", u, test.expected) continue } } } // Serve any http request with a response of N KB of spaces. type serveSpaces struct { sizeKB int } func (t serveSpaces) ServeHTTP(w http.ResponseWriter, req *http.Request) { kb := bytes.Repeat([]byte{' '}, 1024) for i := 0; i < t.sizeKB; i++ { w.Write(kb) } } func BenchmarkClient(b *testing.B) { b.ReportAllocs() ctx := context.Background() for _, sizeKB := range []int{4, 50, 1000, 2000} { b.Run(fmt.Sprintf("%dKB", sizeKB), func(b *testing.B) { testServer := httptest.NewServer(serveSpaces{sizeKB}) defer testServer.Close() client, err := NewClient(Config{ Address: testServer.URL, }) if err != nil { b.Fatalf("Failed to initialize client: %v", err) } url, err := url.Parse(testServer.URL + "/prometheus/api/v1/query?query=up") if err != nil { b.Fatalf("Failed to parse url: %v", err) } req := &http.Request{ URL: url, } b.ResetTimer() for i := 0; i < b.N; i++ { _, _, err := client.Do(ctx, req) if err != nil { b.Fatalf("Query failed: %v", err) } } b.StopTimer() }) } } client_golang-1.21.1/api/prometheus/000077500000000000000000000000001476160432400173545ustar00rootroot00000000000000client_golang-1.21.1/api/prometheus/v1/000077500000000000000000000000001476160432400177025ustar00rootroot00000000000000client_golang-1.21.1/api/prometheus/v1/api.go000066400000000000000000001242321476160432400210060ustar00rootroot00000000000000// Copyright 2017 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package v1 provides bindings to the Prometheus HTTP API v1: // http://prometheus.io/docs/querying/api/ package v1 import ( "context" "errors" "fmt" "math" "net/http" "net/url" "strconv" "strings" "time" "unsafe" json "github.com/json-iterator/go" "github.com/prometheus/common/model" "github.com/prometheus/client_golang/api" ) func init() { json.RegisterTypeEncoderFunc("model.SamplePair", marshalSamplePairJSON, marshalJSONIsEmpty) json.RegisterTypeDecoderFunc("model.SamplePair", unmarshalSamplePairJSON) json.RegisterTypeEncoderFunc("model.SampleHistogramPair", marshalSampleHistogramPairJSON, marshalJSONIsEmpty) json.RegisterTypeDecoderFunc("model.SampleHistogramPair", unmarshalSampleHistogramPairJSON) json.RegisterTypeEncoderFunc("model.SampleStream", marshalSampleStreamJSON, marshalJSONIsEmpty) // Only needed for benchmark. json.RegisterTypeDecoderFunc("model.SampleStream", unmarshalSampleStreamJSON) // Only needed for benchmark. } func unmarshalSamplePairJSON(ptr unsafe.Pointer, iter *json.Iterator) { p := (*model.SamplePair)(ptr) if !iter.ReadArray() { iter.ReportError("unmarshal model.SamplePair", "SamplePair must be [timestamp, value]") return } t := iter.ReadNumber() if err := p.Timestamp.UnmarshalJSON([]byte(t)); err != nil { iter.ReportError("unmarshal model.SamplePair", err.Error()) return } if !iter.ReadArray() { iter.ReportError("unmarshal model.SamplePair", "SamplePair missing value") return } f, err := strconv.ParseFloat(iter.ReadString(), 64) if err != nil { iter.ReportError("unmarshal model.SamplePair", err.Error()) return } p.Value = model.SampleValue(f) if iter.ReadArray() { iter.ReportError("unmarshal model.SamplePair", "SamplePair has too many values, must be [timestamp, value]") return } } func marshalSamplePairJSON(ptr unsafe.Pointer, stream *json.Stream) { p := *((*model.SamplePair)(ptr)) stream.WriteArrayStart() marshalTimestamp(p.Timestamp, stream) stream.WriteMore() marshalFloat(float64(p.Value), stream) stream.WriteArrayEnd() } func unmarshalSampleHistogramPairJSON(ptr unsafe.Pointer, iter *json.Iterator) { p := (*model.SampleHistogramPair)(ptr) if !iter.ReadArray() { iter.ReportError("unmarshal model.SampleHistogramPair", "SampleHistogramPair must be [timestamp, {histogram}]") return } t := iter.ReadNumber() if err := p.Timestamp.UnmarshalJSON([]byte(t)); err != nil { iter.ReportError("unmarshal model.SampleHistogramPair", err.Error()) return } if !iter.ReadArray() { iter.ReportError("unmarshal model.SampleHistogramPair", "SamplePair missing histogram") return } h := &model.SampleHistogram{} p.Histogram = h for key := iter.ReadObject(); key != ""; key = iter.ReadObject() { switch key { case "count": f, err := strconv.ParseFloat(iter.ReadString(), 64) if err != nil { iter.ReportError("unmarshal model.SampleHistogramPair", "count of histogram is not a float") return } h.Count = model.FloatString(f) case "sum": f, err := strconv.ParseFloat(iter.ReadString(), 64) if err != nil { iter.ReportError("unmarshal model.SampleHistogramPair", "sum of histogram is not a float") return } h.Sum = model.FloatString(f) case "buckets": for iter.ReadArray() { b, err := unmarshalHistogramBucket(iter) if err != nil { iter.ReportError("unmarshal model.HistogramBucket", err.Error()) return } h.Buckets = append(h.Buckets, b) } default: iter.ReportError("unmarshal model.SampleHistogramPair", fmt.Sprint("unexpected key in histogram:", key)) return } } if iter.ReadArray() { iter.ReportError("unmarshal model.SampleHistogramPair", "SampleHistogramPair has too many values, must be [timestamp, {histogram}]") return } } func marshalSampleHistogramPairJSON(ptr unsafe.Pointer, stream *json.Stream) { p := *((*model.SampleHistogramPair)(ptr)) stream.WriteArrayStart() marshalTimestamp(p.Timestamp, stream) stream.WriteMore() marshalHistogram(*p.Histogram, stream) stream.WriteArrayEnd() } func unmarshalSampleStreamJSON(ptr unsafe.Pointer, iter *json.Iterator) { ss := (*model.SampleStream)(ptr) for key := iter.ReadObject(); key != ""; key = iter.ReadObject() { switch key { case "metric": metricString := iter.ReadAny().ToString() if err := json.UnmarshalFromString(metricString, &ss.Metric); err != nil { iter.ReportError("unmarshal model.SampleStream", err.Error()) return } case "values": for iter.ReadArray() { v := model.SamplePair{} unmarshalSamplePairJSON(unsafe.Pointer(&v), iter) ss.Values = append(ss.Values, v) } case "histograms": for iter.ReadArray() { h := model.SampleHistogramPair{} unmarshalSampleHistogramPairJSON(unsafe.Pointer(&h), iter) ss.Histograms = append(ss.Histograms, h) } default: iter.ReportError("unmarshal model.SampleStream", fmt.Sprint("unexpected key:", key)) return } } } func marshalSampleStreamJSON(ptr unsafe.Pointer, stream *json.Stream) { ss := *((*model.SampleStream)(ptr)) stream.WriteObjectStart() stream.WriteObjectField(`metric`) m, err := json.ConfigCompatibleWithStandardLibrary.Marshal(ss.Metric) if err != nil { stream.Error = err return } stream.SetBuffer(append(stream.Buffer(), m...)) if len(ss.Values) > 0 { stream.WriteMore() stream.WriteObjectField(`values`) stream.WriteArrayStart() for i, v := range ss.Values { if i > 0 { stream.WriteMore() } marshalSamplePairJSON(unsafe.Pointer(&v), stream) } stream.WriteArrayEnd() } if len(ss.Histograms) > 0 { stream.WriteMore() stream.WriteObjectField(`histograms`) stream.WriteArrayStart() for i, h := range ss.Histograms { if i > 0 { stream.WriteMore() } marshalSampleHistogramPairJSON(unsafe.Pointer(&h), stream) } stream.WriteArrayEnd() } stream.WriteObjectEnd() } func marshalFloat(v float64, stream *json.Stream) { stream.WriteRaw(`"`) // Taken from https://github.com/json-iterator/go/blob/master/stream_float.go#L71 as a workaround // to https://github.com/json-iterator/go/issues/365 (json-iterator, to follow json standard, doesn't allow inf/nan). buf := stream.Buffer() abs := math.Abs(v) fmt := byte('f') // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. if abs != 0 { if abs < 1e-6 || abs >= 1e21 { fmt = 'e' } } buf = strconv.AppendFloat(buf, v, fmt, -1, 64) stream.SetBuffer(buf) stream.WriteRaw(`"`) } func marshalTimestamp(timestamp model.Time, stream *json.Stream) { t := int64(timestamp) // Write out the timestamp as a float divided by 1000. // This is ~3x faster than converting to a float. if t < 0 { stream.WriteRaw(`-`) t = -t } stream.WriteInt64(t / 1000) fraction := t % 1000 if fraction != 0 { stream.WriteRaw(`.`) if fraction < 100 { stream.WriteRaw(`0`) } if fraction < 10 { stream.WriteRaw(`0`) } stream.WriteInt64(fraction) } } func unmarshalHistogramBucket(iter *json.Iterator) (*model.HistogramBucket, error) { b := model.HistogramBucket{} if !iter.ReadArray() { return nil, errors.New("HistogramBucket must be [boundaries, lower, upper, count]") } boundaries, err := iter.ReadNumber().Int64() if err != nil { return nil, err } b.Boundaries = int32(boundaries) if !iter.ReadArray() { return nil, errors.New("HistogramBucket must be [boundaries, lower, upper, count]") } f, err := strconv.ParseFloat(iter.ReadString(), 64) if err != nil { return nil, err } b.Lower = model.FloatString(f) if !iter.ReadArray() { return nil, errors.New("HistogramBucket must be [boundaries, lower, upper, count]") } f, err = strconv.ParseFloat(iter.ReadString(), 64) if err != nil { return nil, err } b.Upper = model.FloatString(f) if !iter.ReadArray() { return nil, errors.New("HistogramBucket must be [boundaries, lower, upper, count]") } f, err = strconv.ParseFloat(iter.ReadString(), 64) if err != nil { return nil, err } b.Count = model.FloatString(f) if iter.ReadArray() { return nil, errors.New("HistogramBucket has too many values, must be [boundaries, lower, upper, count]") } return &b, nil } // marshalHistogramBucket writes something like: [ 3, "-0.25", "0.25", "3"] // See marshalHistogram to understand what the numbers mean func marshalHistogramBucket(b model.HistogramBucket, stream *json.Stream) { stream.WriteArrayStart() stream.WriteInt32(b.Boundaries) stream.WriteMore() marshalFloat(float64(b.Lower), stream) stream.WriteMore() marshalFloat(float64(b.Upper), stream) stream.WriteMore() marshalFloat(float64(b.Count), stream) stream.WriteArrayEnd() } // marshalHistogram writes something like: // // { // "count": "42", // "sum": "34593.34", // "buckets": [ // [ 3, "-0.25", "0.25", "3"], // [ 0, "0.25", "0.5", "12"], // [ 0, "0.5", "1", "21"], // [ 0, "2", "4", "6"] // ] // } // // The 1st element in each bucket array determines if the boundaries are // inclusive (AKA closed) or exclusive (AKA open): // // 0: lower exclusive, upper inclusive // 1: lower inclusive, upper exclusive // 2: both exclusive // 3: both inclusive // // The 2nd and 3rd elements are the lower and upper boundary. The 4th element is // the bucket count. func marshalHistogram(h model.SampleHistogram, stream *json.Stream) { stream.WriteObjectStart() stream.WriteObjectField(`count`) marshalFloat(float64(h.Count), stream) stream.WriteMore() stream.WriteObjectField(`sum`) marshalFloat(float64(h.Sum), stream) bucketFound := false for _, bucket := range h.Buckets { if bucket.Count == 0 { continue // No need to expose empty buckets in JSON. } stream.WriteMore() if !bucketFound { stream.WriteObjectField(`buckets`) stream.WriteArrayStart() } bucketFound = true marshalHistogramBucket(*bucket, stream) } if bucketFound { stream.WriteArrayEnd() } stream.WriteObjectEnd() } func marshalJSONIsEmpty(ptr unsafe.Pointer) bool { return false } const ( apiPrefix = "/api/v1" epAlerts = apiPrefix + "/alerts" epAlertManagers = apiPrefix + "/alertmanagers" epQuery = apiPrefix + "/query" epQueryRange = apiPrefix + "/query_range" epQueryExemplars = apiPrefix + "/query_exemplars" epLabels = apiPrefix + "/labels" epLabelValues = apiPrefix + "/label/:name/values" epSeries = apiPrefix + "/series" epTargets = apiPrefix + "/targets" epTargetsMetadata = apiPrefix + "/targets/metadata" epMetadata = apiPrefix + "/metadata" epRules = apiPrefix + "/rules" epSnapshot = apiPrefix + "/admin/tsdb/snapshot" epDeleteSeries = apiPrefix + "/admin/tsdb/delete_series" epCleanTombstones = apiPrefix + "/admin/tsdb/clean_tombstones" epConfig = apiPrefix + "/status/config" epFlags = apiPrefix + "/status/flags" epBuildinfo = apiPrefix + "/status/buildinfo" epRuntimeinfo = apiPrefix + "/status/runtimeinfo" epTSDB = apiPrefix + "/status/tsdb" epWalReplay = apiPrefix + "/status/walreplay" ) // AlertState models the state of an alert. type AlertState string // ErrorType models the different API error types. type ErrorType string // HealthStatus models the health status of a scrape target. type HealthStatus string // RuleType models the type of a rule. type RuleType string // RuleHealth models the health status of a rule. type RuleHealth string // MetricType models the type of a metric. type MetricType string const ( // Possible values for AlertState. AlertStateFiring AlertState = "firing" AlertStateInactive AlertState = "inactive" AlertStatePending AlertState = "pending" // Possible values for ErrorType. ErrBadData ErrorType = "bad_data" ErrTimeout ErrorType = "timeout" ErrCanceled ErrorType = "canceled" ErrExec ErrorType = "execution" ErrBadResponse ErrorType = "bad_response" ErrServer ErrorType = "server_error" ErrClient ErrorType = "client_error" // Possible values for HealthStatus. HealthGood HealthStatus = "up" HealthUnknown HealthStatus = "unknown" HealthBad HealthStatus = "down" // Possible values for RuleType. RuleTypeRecording RuleType = "recording" RuleTypeAlerting RuleType = "alerting" // Possible values for RuleHealth. RuleHealthGood = "ok" RuleHealthUnknown = "unknown" RuleHealthBad = "err" // Possible values for MetricType MetricTypeCounter MetricType = "counter" MetricTypeGauge MetricType = "gauge" MetricTypeHistogram MetricType = "histogram" MetricTypeGaugeHistogram MetricType = "gaugehistogram" MetricTypeSummary MetricType = "summary" MetricTypeInfo MetricType = "info" MetricTypeStateset MetricType = "stateset" MetricTypeUnknown MetricType = "unknown" ) // Error is an error returned by the API. type Error struct { Type ErrorType Msg string Detail string } func (e *Error) Error() string { return fmt.Sprintf("%s: %s", e.Type, e.Msg) } // Range represents a sliced time range. type Range struct { // The boundaries of the time range. Start, End time.Time // The maximum time between two slices within the boundaries. Step time.Duration } // API provides bindings for Prometheus's v1 API. type API interface { // Alerts returns a list of all active alerts. Alerts(ctx context.Context) (AlertsResult, error) // AlertManagers returns an overview of the current state of the Prometheus alert manager discovery. AlertManagers(ctx context.Context) (AlertManagersResult, error) // CleanTombstones removes the deleted data from disk and cleans up the existing tombstones. CleanTombstones(ctx context.Context) error // Config returns the current Prometheus configuration. Config(ctx context.Context) (ConfigResult, error) // DeleteSeries deletes data for a selection of series in a time range. DeleteSeries(ctx context.Context, matches []string, startTime, endTime time.Time) error // Flags returns the flag values that Prometheus was launched with. Flags(ctx context.Context) (FlagsResult, error) // LabelNames returns the unique label names present in the block in sorted order by given time range and matchers. LabelNames(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) ([]string, Warnings, error) // LabelValues performs a query for the values of the given label, time range and matchers. LabelValues(ctx context.Context, label string, matches []string, startTime, endTime time.Time, opts ...Option) (model.LabelValues, Warnings, error) // Query performs a query for the given time. Query(ctx context.Context, query string, ts time.Time, opts ...Option) (model.Value, Warnings, error) // QueryRange performs a query for the given range. QueryRange(ctx context.Context, query string, r Range, opts ...Option) (model.Value, Warnings, error) // QueryExemplars performs a query for exemplars by the given query and time range. QueryExemplars(ctx context.Context, query string, startTime, endTime time.Time) ([]ExemplarQueryResult, error) // Buildinfo returns various build information properties about the Prometheus server Buildinfo(ctx context.Context) (BuildinfoResult, error) // Runtimeinfo returns the various runtime information properties about the Prometheus server. Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error) // Series finds series by label matchers. Series(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) ([]model.LabelSet, Warnings, error) // Snapshot creates a snapshot of all current data into snapshots/- // under the TSDB's data directory and returns the directory as response. Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, error) // Rules returns a list of alerting and recording rules that are currently loaded. Rules(ctx context.Context) (RulesResult, error) // Targets returns an overview of the current state of the Prometheus target discovery. Targets(ctx context.Context) (TargetsResult, error) // TargetsMetadata returns metadata about metrics currently scraped by the target. TargetsMetadata(ctx context.Context, matchTarget, metric, limit string) ([]MetricMetadata, error) // Metadata returns metadata about metrics currently scraped by the metric name. Metadata(ctx context.Context, metric, limit string) (map[string][]Metadata, error) // TSDB returns the cardinality statistics. TSDB(ctx context.Context, opts ...Option) (TSDBResult, error) // WalReplay returns the current replay status of the wal. WalReplay(ctx context.Context) (WalReplayStatus, error) } // AlertsResult contains the result from querying the alerts endpoint. type AlertsResult struct { Alerts []Alert `json:"alerts"` } // AlertManagersResult contains the result from querying the alertmanagers endpoint. type AlertManagersResult struct { Active []AlertManager `json:"activeAlertManagers"` Dropped []AlertManager `json:"droppedAlertManagers"` } // AlertManager models a configured Alert Manager. type AlertManager struct { URL string `json:"url"` } // ConfigResult contains the result from querying the config endpoint. type ConfigResult struct { YAML string `json:"yaml"` } // FlagsResult contains the result from querying the flag endpoint. type FlagsResult map[string]string // BuildinfoResult contains the results from querying the buildinfo endpoint. type BuildinfoResult struct { Version string `json:"version"` Revision string `json:"revision"` Branch string `json:"branch"` BuildUser string `json:"buildUser"` BuildDate string `json:"buildDate"` GoVersion string `json:"goVersion"` } // RuntimeinfoResult contains the result from querying the runtimeinfo endpoint. type RuntimeinfoResult struct { StartTime time.Time `json:"startTime"` CWD string `json:"CWD"` ReloadConfigSuccess bool `json:"reloadConfigSuccess"` LastConfigTime time.Time `json:"lastConfigTime"` CorruptionCount int `json:"corruptionCount"` GoroutineCount int `json:"goroutineCount"` GOMAXPROCS int `json:"GOMAXPROCS"` GOGC string `json:"GOGC"` GODEBUG string `json:"GODEBUG"` StorageRetention string `json:"storageRetention"` } // SnapshotResult contains the result from querying the snapshot endpoint. type SnapshotResult struct { Name string `json:"name"` } // RulesResult contains the result from querying the rules endpoint. type RulesResult struct { Groups []RuleGroup `json:"groups"` } // RuleGroup models a rule group that contains a set of recording and alerting rules. type RuleGroup struct { Name string `json:"name"` File string `json:"file"` Interval float64 `json:"interval"` Rules Rules `json:"rules"` } // Recording and alerting rules are stored in the same slice to preserve the order // that rules are returned in by the API. // // Rule types can be determined using a type switch: // // switch v := rule.(type) { // case RecordingRule: // fmt.Print("got a recording rule") // case AlertingRule: // fmt.Print("got a alerting rule") // default: // fmt.Printf("unknown rule type %s", v) // } type Rules []interface{} // AlertingRule models a alerting rule. type AlertingRule struct { Name string `json:"name"` Query string `json:"query"` Duration float64 `json:"duration"` Labels model.LabelSet `json:"labels"` Annotations model.LabelSet `json:"annotations"` Alerts []*Alert `json:"alerts"` Health RuleHealth `json:"health"` LastError string `json:"lastError,omitempty"` EvaluationTime float64 `json:"evaluationTime"` LastEvaluation time.Time `json:"lastEvaluation"` State string `json:"state"` } // RecordingRule models a recording rule. type RecordingRule struct { Name string `json:"name"` Query string `json:"query"` Labels model.LabelSet `json:"labels,omitempty"` Health RuleHealth `json:"health"` LastError string `json:"lastError,omitempty"` EvaluationTime float64 `json:"evaluationTime"` LastEvaluation time.Time `json:"lastEvaluation"` } // Alert models an active alert. type Alert struct { ActiveAt time.Time `json:"activeAt"` Annotations model.LabelSet Labels model.LabelSet State AlertState Value string } // TargetsResult contains the result from querying the targets endpoint. type TargetsResult struct { Active []ActiveTarget `json:"activeTargets"` Dropped []DroppedTarget `json:"droppedTargets"` } // ActiveTarget models an active Prometheus scrape target. type ActiveTarget struct { DiscoveredLabels map[string]string `json:"discoveredLabels"` Labels model.LabelSet `json:"labels"` ScrapePool string `json:"scrapePool"` ScrapeURL string `json:"scrapeUrl"` GlobalURL string `json:"globalUrl"` LastError string `json:"lastError"` LastScrape time.Time `json:"lastScrape"` LastScrapeDuration float64 `json:"lastScrapeDuration"` Health HealthStatus `json:"health"` } // DroppedTarget models a dropped Prometheus scrape target. type DroppedTarget struct { DiscoveredLabels map[string]string `json:"discoveredLabels"` } // MetricMetadata models the metadata of a metric with its scrape target and name. type MetricMetadata struct { Target map[string]string `json:"target"` Metric string `json:"metric,omitempty"` Type MetricType `json:"type"` Help string `json:"help"` Unit string `json:"unit"` } // Metadata models the metadata of a metric. type Metadata struct { Type MetricType `json:"type"` Help string `json:"help"` Unit string `json:"unit"` } // queryResult contains result data for a query. type queryResult struct { Type model.ValueType `json:"resultType"` Result interface{} `json:"result"` // The decoded value. v model.Value } // TSDBResult contains the result from querying the tsdb endpoint. type TSDBResult struct { HeadStats TSDBHeadStats `json:"headStats"` SeriesCountByMetricName []Stat `json:"seriesCountByMetricName"` LabelValueCountByLabelName []Stat `json:"labelValueCountByLabelName"` MemoryInBytesByLabelName []Stat `json:"memoryInBytesByLabelName"` SeriesCountByLabelValuePair []Stat `json:"seriesCountByLabelValuePair"` } // TSDBHeadStats contains TSDB stats type TSDBHeadStats struct { NumSeries int `json:"numSeries"` NumLabelPairs int `json:"numLabelPairs"` ChunkCount int `json:"chunkCount"` MinTime int `json:"minTime"` MaxTime int `json:"maxTime"` } // WalReplayStatus represents the wal replay status. type WalReplayStatus struct { Min int `json:"min"` Max int `json:"max"` Current int `json:"current"` } // Stat models information about statistic value. type Stat struct { Name string `json:"name"` Value uint64 `json:"value"` } func (rg *RuleGroup) UnmarshalJSON(b []byte) error { v := struct { Name string `json:"name"` File string `json:"file"` Interval float64 `json:"interval"` Rules []json.RawMessage `json:"rules"` }{} if err := json.Unmarshal(b, &v); err != nil { return err } rg.Name = v.Name rg.File = v.File rg.Interval = v.Interval for _, rule := range v.Rules { alertingRule := AlertingRule{} if err := json.Unmarshal(rule, &alertingRule); err == nil { rg.Rules = append(rg.Rules, alertingRule) continue } recordingRule := RecordingRule{} if err := json.Unmarshal(rule, &recordingRule); err == nil { rg.Rules = append(rg.Rules, recordingRule) continue } return errors.New("failed to decode JSON into an alerting or recording rule") } return nil } func (r *AlertingRule) UnmarshalJSON(b []byte) error { v := struct { Type string `json:"type"` }{} if err := json.Unmarshal(b, &v); err != nil { return err } if v.Type == "" { return errors.New("type field not present in rule") } if v.Type != string(RuleTypeAlerting) { return fmt.Errorf("expected rule of type %s but got %s", string(RuleTypeAlerting), v.Type) } rule := struct { Name string `json:"name"` Query string `json:"query"` Duration float64 `json:"duration"` Labels model.LabelSet `json:"labels"` Annotations model.LabelSet `json:"annotations"` Alerts []*Alert `json:"alerts"` Health RuleHealth `json:"health"` LastError string `json:"lastError,omitempty"` EvaluationTime float64 `json:"evaluationTime"` LastEvaluation time.Time `json:"lastEvaluation"` State string `json:"state"` }{} if err := json.Unmarshal(b, &rule); err != nil { return err } r.Health = rule.Health r.Annotations = rule.Annotations r.Name = rule.Name r.Query = rule.Query r.Alerts = rule.Alerts r.Duration = rule.Duration r.Labels = rule.Labels r.LastError = rule.LastError r.EvaluationTime = rule.EvaluationTime r.LastEvaluation = rule.LastEvaluation r.State = rule.State return nil } func (r *RecordingRule) UnmarshalJSON(b []byte) error { v := struct { Type string `json:"type"` }{} if err := json.Unmarshal(b, &v); err != nil { return err } if v.Type == "" { return errors.New("type field not present in rule") } if v.Type != string(RuleTypeRecording) { return fmt.Errorf("expected rule of type %s but got %s", string(RuleTypeRecording), v.Type) } rule := struct { Name string `json:"name"` Query string `json:"query"` Labels model.LabelSet `json:"labels,omitempty"` Health RuleHealth `json:"health"` LastError string `json:"lastError,omitempty"` EvaluationTime float64 `json:"evaluationTime"` LastEvaluation time.Time `json:"lastEvaluation"` }{} if err := json.Unmarshal(b, &rule); err != nil { return err } r.Health = rule.Health r.Labels = rule.Labels r.Name = rule.Name r.LastError = rule.LastError r.Query = rule.Query r.EvaluationTime = rule.EvaluationTime r.LastEvaluation = rule.LastEvaluation return nil } func (qr *queryResult) UnmarshalJSON(b []byte) error { v := struct { Type model.ValueType `json:"resultType"` Result json.RawMessage `json:"result"` }{} err := json.Unmarshal(b, &v) if err != nil { return err } switch v.Type { case model.ValScalar: var sv model.Scalar err = json.Unmarshal(v.Result, &sv) qr.v = &sv case model.ValVector: var vv model.Vector err = json.Unmarshal(v.Result, &vv) qr.v = vv case model.ValMatrix: var mv model.Matrix err = json.Unmarshal(v.Result, &mv) qr.v = mv default: err = fmt.Errorf("unexpected value type %q", v.Type) } return err } // Exemplar is additional information associated with a time series. type Exemplar struct { Labels model.LabelSet `json:"labels"` Value model.SampleValue `json:"value"` Timestamp model.Time `json:"timestamp"` } type ExemplarQueryResult struct { SeriesLabels model.LabelSet `json:"seriesLabels"` Exemplars []Exemplar `json:"exemplars"` } // NewAPI returns a new API for the client. // // It is safe to use the returned API from multiple goroutines. func NewAPI(c api.Client) API { return &httpAPI{ client: &apiClientImpl{ client: c, }, } } type httpAPI struct { client apiClient } func (h *httpAPI) Alerts(ctx context.Context) (AlertsResult, error) { u := h.client.URL(epAlerts, nil) req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return AlertsResult{}, err } _, body, _, err := h.client.Do(ctx, req) if err != nil { return AlertsResult{}, err } var res AlertsResult err = json.Unmarshal(body, &res) return res, err } func (h *httpAPI) AlertManagers(ctx context.Context) (AlertManagersResult, error) { u := h.client.URL(epAlertManagers, nil) req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return AlertManagersResult{}, err } _, body, _, err := h.client.Do(ctx, req) if err != nil { return AlertManagersResult{}, err } var res AlertManagersResult err = json.Unmarshal(body, &res) return res, err } func (h *httpAPI) CleanTombstones(ctx context.Context) error { u := h.client.URL(epCleanTombstones, nil) req, err := http.NewRequest(http.MethodPost, u.String(), nil) if err != nil { return err } _, _, _, err = h.client.Do(ctx, req) return err } func (h *httpAPI) Config(ctx context.Context) (ConfigResult, error) { u := h.client.URL(epConfig, nil) req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return ConfigResult{}, err } _, body, _, err := h.client.Do(ctx, req) if err != nil { return ConfigResult{}, err } var res ConfigResult err = json.Unmarshal(body, &res) return res, err } func (h *httpAPI) DeleteSeries(ctx context.Context, matches []string, startTime, endTime time.Time) error { u := h.client.URL(epDeleteSeries, nil) q := u.Query() for _, m := range matches { q.Add("match[]", m) } if !startTime.IsZero() { q.Set("start", formatTime(startTime)) } if !endTime.IsZero() { q.Set("end", formatTime(endTime)) } u.RawQuery = q.Encode() req, err := http.NewRequest(http.MethodPost, u.String(), nil) if err != nil { return err } _, _, _, err = h.client.Do(ctx, req) return err } func (h *httpAPI) Flags(ctx context.Context) (FlagsResult, error) { u := h.client.URL(epFlags, nil) req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return FlagsResult{}, err } _, body, _, err := h.client.Do(ctx, req) if err != nil { return FlagsResult{}, err } var res FlagsResult err = json.Unmarshal(body, &res) return res, err } func (h *httpAPI) Buildinfo(ctx context.Context) (BuildinfoResult, error) { u := h.client.URL(epBuildinfo, nil) req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return BuildinfoResult{}, err } _, body, _, err := h.client.Do(ctx, req) if err != nil { return BuildinfoResult{}, err } var res BuildinfoResult err = json.Unmarshal(body, &res) return res, err } func (h *httpAPI) Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error) { u := h.client.URL(epRuntimeinfo, nil) req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return RuntimeinfoResult{}, err } _, body, _, err := h.client.Do(ctx, req) if err != nil { return RuntimeinfoResult{}, err } var res RuntimeinfoResult err = json.Unmarshal(body, &res) return res, err } func (h *httpAPI) LabelNames(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) ([]string, Warnings, error) { u := h.client.URL(epLabels, nil) q := addOptionalURLParams(u.Query(), opts) if !startTime.IsZero() { q.Set("start", formatTime(startTime)) } if !endTime.IsZero() { q.Set("end", formatTime(endTime)) } for _, m := range matches { q.Add("match[]", m) } _, body, w, err := h.client.DoGetFallback(ctx, u, q) if err != nil { return nil, w, err } var labelNames []string err = json.Unmarshal(body, &labelNames) return labelNames, w, err } func (h *httpAPI) LabelValues(ctx context.Context, label string, matches []string, startTime, endTime time.Time, opts ...Option) (model.LabelValues, Warnings, error) { u := h.client.URL(epLabelValues, map[string]string{"name": label}) q := addOptionalURLParams(u.Query(), opts) if !startTime.IsZero() { q.Set("start", formatTime(startTime)) } if !endTime.IsZero() { q.Set("end", formatTime(endTime)) } for _, m := range matches { q.Add("match[]", m) } u.RawQuery = q.Encode() req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return nil, nil, err } _, body, w, err := h.client.Do(ctx, req) if err != nil { return nil, w, err } var labelValues model.LabelValues err = json.Unmarshal(body, &labelValues) return labelValues, w, err } type apiOptions struct { timeout time.Duration limit uint64 } type Option func(c *apiOptions) // WithTimeout can be used to provide an optional query evaluation timeout for Query and QueryRange. // https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries func WithTimeout(timeout time.Duration) Option { return func(o *apiOptions) { o.timeout = timeout } } // WithLimit provides an optional maximum number of returned entries for APIs that support limit parameter // e.g. https://prometheus.io/docs/prometheus/latest/querying/api/#instant-querie:~:text=%3A%20End%20timestamp.-,limit%3D%3Cnumber%3E,-%3A%20Maximum%20number%20of func WithLimit(limit uint64) Option { return func(o *apiOptions) { o.limit = limit } } func addOptionalURLParams(q url.Values, opts []Option) url.Values { opt := &apiOptions{} for _, o := range opts { o(opt) } if opt.timeout > 0 { q.Set("timeout", opt.timeout.String()) } if opt.limit > 0 { q.Set("limit", strconv.FormatUint(opt.limit, 10)) } return q } func (h *httpAPI) Query(ctx context.Context, query string, ts time.Time, opts ...Option) (model.Value, Warnings, error) { u := h.client.URL(epQuery, nil) q := addOptionalURLParams(u.Query(), opts) q.Set("query", query) if !ts.IsZero() { q.Set("time", formatTime(ts)) } _, body, warnings, err := h.client.DoGetFallback(ctx, u, q) if err != nil { return nil, warnings, err } var qres queryResult return qres.v, warnings, json.Unmarshal(body, &qres) } func (h *httpAPI) QueryRange(ctx context.Context, query string, r Range, opts ...Option) (model.Value, Warnings, error) { u := h.client.URL(epQueryRange, nil) q := addOptionalURLParams(u.Query(), opts) q.Set("query", query) q.Set("start", formatTime(r.Start)) q.Set("end", formatTime(r.End)) q.Set("step", strconv.FormatFloat(r.Step.Seconds(), 'f', -1, 64)) _, body, warnings, err := h.client.DoGetFallback(ctx, u, q) if err != nil { return nil, warnings, err } var qres queryResult return qres.v, warnings, json.Unmarshal(body, &qres) } func (h *httpAPI) Series(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) ([]model.LabelSet, Warnings, error) { u := h.client.URL(epSeries, nil) q := addOptionalURLParams(u.Query(), opts) for _, m := range matches { q.Add("match[]", m) } if !startTime.IsZero() { q.Set("start", formatTime(startTime)) } if !endTime.IsZero() { q.Set("end", formatTime(endTime)) } _, body, warnings, err := h.client.DoGetFallback(ctx, u, q) if err != nil { return nil, warnings, err } var mset []model.LabelSet return mset, warnings, json.Unmarshal(body, &mset) } func (h *httpAPI) Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, error) { u := h.client.URL(epSnapshot, nil) q := u.Query() q.Set("skip_head", strconv.FormatBool(skipHead)) u.RawQuery = q.Encode() req, err := http.NewRequest(http.MethodPost, u.String(), nil) if err != nil { return SnapshotResult{}, err } _, body, _, err := h.client.Do(ctx, req) if err != nil { return SnapshotResult{}, err } var res SnapshotResult err = json.Unmarshal(body, &res) return res, err } func (h *httpAPI) Rules(ctx context.Context) (RulesResult, error) { u := h.client.URL(epRules, nil) req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return RulesResult{}, err } _, body, _, err := h.client.Do(ctx, req) if err != nil { return RulesResult{}, err } var res RulesResult err = json.Unmarshal(body, &res) return res, err } func (h *httpAPI) Targets(ctx context.Context) (TargetsResult, error) { u := h.client.URL(epTargets, nil) req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return TargetsResult{}, err } _, body, _, err := h.client.Do(ctx, req) if err != nil { return TargetsResult{}, err } var res TargetsResult err = json.Unmarshal(body, &res) return res, err } func (h *httpAPI) TargetsMetadata(ctx context.Context, matchTarget, metric, limit string) ([]MetricMetadata, error) { u := h.client.URL(epTargetsMetadata, nil) q := u.Query() q.Set("match_target", matchTarget) q.Set("metric", metric) q.Set("limit", limit) u.RawQuery = q.Encode() req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return nil, err } _, body, _, err := h.client.Do(ctx, req) if err != nil { return nil, err } var res []MetricMetadata err = json.Unmarshal(body, &res) return res, err } func (h *httpAPI) Metadata(ctx context.Context, metric, limit string) (map[string][]Metadata, error) { u := h.client.URL(epMetadata, nil) q := u.Query() q.Set("metric", metric) q.Set("limit", limit) u.RawQuery = q.Encode() req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return nil, err } _, body, _, err := h.client.Do(ctx, req) if err != nil { return nil, err } var res map[string][]Metadata err = json.Unmarshal(body, &res) return res, err } func (h *httpAPI) TSDB(ctx context.Context, opts ...Option) (TSDBResult, error) { u := h.client.URL(epTSDB, nil) q := addOptionalURLParams(u.Query(), opts) u.RawQuery = q.Encode() req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return TSDBResult{}, err } _, body, _, err := h.client.Do(ctx, req) if err != nil { return TSDBResult{}, err } var res TSDBResult err = json.Unmarshal(body, &res) return res, err } func (h *httpAPI) WalReplay(ctx context.Context) (WalReplayStatus, error) { u := h.client.URL(epWalReplay, nil) req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return WalReplayStatus{}, err } _, body, _, err := h.client.Do(ctx, req) if err != nil { return WalReplayStatus{}, err } var res WalReplayStatus err = json.Unmarshal(body, &res) return res, err } func (h *httpAPI) QueryExemplars(ctx context.Context, query string, startTime, endTime time.Time) ([]ExemplarQueryResult, error) { u := h.client.URL(epQueryExemplars, nil) q := u.Query() q.Set("query", query) if !startTime.IsZero() { q.Set("start", formatTime(startTime)) } if !endTime.IsZero() { q.Set("end", formatTime(endTime)) } _, body, _, err := h.client.DoGetFallback(ctx, u, q) if err != nil { return nil, err } var res []ExemplarQueryResult err = json.Unmarshal(body, &res) return res, err } // Warnings is an array of non critical errors type Warnings []string // apiClient wraps a regular client and processes successful API responses. // Successful also includes responses that errored at the API level. type apiClient interface { URL(ep string, args map[string]string) *url.URL Do(context.Context, *http.Request) (*http.Response, []byte, Warnings, error) DoGetFallback(ctx context.Context, u *url.URL, args url.Values) (*http.Response, []byte, Warnings, error) } type apiClientImpl struct { client api.Client } type apiResponse struct { Status string `json:"status"` Data json.RawMessage `json:"data"` ErrorType ErrorType `json:"errorType"` Error string `json:"error"` Warnings []string `json:"warnings,omitempty"` } func apiError(code int) bool { // These are the codes that Prometheus sends when it returns an error. return code == http.StatusUnprocessableEntity || code == http.StatusBadRequest } func errorTypeAndMsgFor(resp *http.Response) (ErrorType, string) { switch resp.StatusCode / 100 { case 4: return ErrClient, fmt.Sprintf("client error: %d", resp.StatusCode) case 5: return ErrServer, fmt.Sprintf("server error: %d", resp.StatusCode) } return ErrBadResponse, fmt.Sprintf("bad response code %d", resp.StatusCode) } func (h *apiClientImpl) URL(ep string, args map[string]string) *url.URL { return h.client.URL(ep, args) } func (h *apiClientImpl) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, Warnings, error) { resp, body, err := h.client.Do(ctx, req) if err != nil { return resp, body, nil, err } code := resp.StatusCode if code/100 != 2 && !apiError(code) { errorType, errorMsg := errorTypeAndMsgFor(resp) return resp, body, nil, &Error{ Type: errorType, Msg: errorMsg, Detail: string(body), } } var result apiResponse if http.StatusNoContent != code { if jsonErr := json.Unmarshal(body, &result); jsonErr != nil { return resp, body, nil, &Error{ Type: ErrBadResponse, Msg: jsonErr.Error(), } } } if apiError(code) && result.Status == "success" { err = &Error{ Type: ErrBadResponse, Msg: "inconsistent body for response code", } } if result.Status == "error" { err = &Error{ Type: result.ErrorType, Msg: result.Error, } } return resp, []byte(result.Data), result.Warnings, err } // DoGetFallback will attempt to do the request as-is, and on a 405 or 501 it // will fallback to a GET request. func (h *apiClientImpl) DoGetFallback(ctx context.Context, u *url.URL, args url.Values) (*http.Response, []byte, Warnings, error) { encodedArgs := args.Encode() req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(encodedArgs)) if err != nil { return nil, nil, nil, err } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") // Following comment originates from https://pkg.go.dev/net/http#Transport // Transport only retries a request upon encountering a network error if the request is // idempotent and either has no body or has its Request.GetBody defined. HTTP requests // are considered idempotent if they have HTTP methods GET, HEAD, OPTIONS, or TRACE; or // if their Header map contains an "Idempotency-Key" or "X-Idempotency-Key" entry. If the // idempotency key value is a zero-length slice, the request is treated as idempotent but // the header is not sent on the wire. req.Header["Idempotency-Key"] = nil resp, body, warnings, err := h.Do(ctx, req) if resp != nil && (resp.StatusCode == http.StatusMethodNotAllowed || resp.StatusCode == http.StatusNotImplemented) { u.RawQuery = encodedArgs req, err = http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return nil, nil, warnings, err } return h.Do(ctx, req) } return resp, body, warnings, err } func formatTime(t time.Time) string { return strconv.FormatFloat(float64(t.Unix())+float64(t.Nanosecond())/1e9, 'f', -1, 64) } client_golang-1.21.1/api/prometheus/v1/api_bench_test.go000066400000000000000000000131071476160432400232020ustar00rootroot00000000000000// Copyright 2019 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package v1 import ( "encoding/json" "strconv" "testing" "time" jsoniter "github.com/json-iterator/go" "github.com/prometheus/common/model" ) func generateData(timeseries, datapoints int) (floatMatrix, histogramMatrix model.Matrix) { for i := 0; i < timeseries; i++ { lset := map[model.LabelName]model.LabelValue{ model.MetricNameLabel: model.LabelValue("timeseries_" + strconv.Itoa(i)), "foo": "bar", } now := model.Time(1677587274055) floats := make([]model.SamplePair, datapoints) histograms := make([]model.SampleHistogramPair, datapoints) for x := datapoints; x > 0; x-- { f := float64(x) floats[x-1] = model.SamplePair{ // Set the time back assuming a 15s interval. Since this is used for // Marshal/Unmarshal testing the actual interval doesn't matter. Timestamp: now.Add(time.Second * -15 * time.Duration(x)), Value: model.SampleValue(f), } histograms[x-1] = model.SampleHistogramPair{ Timestamp: now.Add(time.Second * -15 * time.Duration(x)), Histogram: &model.SampleHistogram{ Count: model.FloatString(13.5 * f), Sum: model.FloatString(.1 * f), Buckets: model.HistogramBuckets{ { Boundaries: 1, Lower: -4870.992343051145, Upper: -4466.7196729968955, Count: model.FloatString(1 * f), }, { Boundaries: 1, Lower: -861.0779292198035, Upper: -789.6119426088657, Count: model.FloatString(2 * f), }, { Boundaries: 1, Lower: -558.3399591246119, Upper: -512, Count: model.FloatString(3 * f), }, { Boundaries: 0, Lower: 2048, Upper: 2233.3598364984477, Count: model.FloatString(1.5 * f), }, { Boundaries: 0, Lower: 2896.3093757400984, Upper: 3158.4477704354626, Count: model.FloatString(2.5 * f), }, { Boundaries: 0, Lower: 4466.7196729968955, Upper: 4870.992343051145, Count: model.FloatString(3.5 * f), }, }, }, } } fss := &model.SampleStream{ Metric: model.Metric(lset), Values: floats, } hss := &model.SampleStream{ Metric: model.Metric(lset), Histograms: histograms, } floatMatrix = append(floatMatrix, fss) histogramMatrix = append(histogramMatrix, hss) } return } func BenchmarkSamplesJsonSerialization(b *testing.B) { for _, timeseriesCount := range []int{10, 100, 1000} { b.Run(strconv.Itoa(timeseriesCount), func(b *testing.B) { for _, datapointCount := range []int{10, 100, 1000} { b.Run(strconv.Itoa(datapointCount), func(b *testing.B) { floats, histograms := generateData(timeseriesCount, datapointCount) floatBytes, err := json.Marshal(floats) if err != nil { b.Fatalf("Error marshaling: %v", err) } histogramBytes, err := json.Marshal(histograms) if err != nil { b.Fatalf("Error marshaling: %v", err) } b.Run("marshal", func(b *testing.B) { b.Run("encoding/json/floats", func(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { if _, err := json.Marshal(floats); err != nil { b.Fatal(err) } } }) b.Run("jsoniter/floats", func(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { if _, err := jsoniter.Marshal(floats); err != nil { b.Fatal(err) } } }) b.Run("encoding/json/histograms", func(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { if _, err := json.Marshal(histograms); err != nil { b.Fatal(err) } } }) b.Run("jsoniter/histograms", func(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { if _, err := jsoniter.Marshal(histograms); err != nil { b.Fatal(err) } } }) }) b.Run("unmarshal", func(b *testing.B) { b.Run("encoding/json/floats", func(b *testing.B) { b.ReportAllocs() var m model.Matrix for i := 0; i < b.N; i++ { if err := json.Unmarshal(floatBytes, &m); err != nil { b.Fatal(err) } } }) b.Run("jsoniter/floats", func(b *testing.B) { b.ReportAllocs() var m model.Matrix for i := 0; i < b.N; i++ { if err := jsoniter.Unmarshal(floatBytes, &m); err != nil { b.Fatal(err) } } }) b.Run("encoding/json/histograms", func(b *testing.B) { b.ReportAllocs() var m model.Matrix for i := 0; i < b.N; i++ { if err := json.Unmarshal(histogramBytes, &m); err != nil { b.Fatal(err) } } }) b.Run("jsoniter/histograms", func(b *testing.B) { b.ReportAllocs() var m model.Matrix for i := 0; i < b.N; i++ { if err := jsoniter.Unmarshal(histogramBytes, &m); err != nil { b.Fatal(err) } } }) }) }) } }) } } client_golang-1.21.1/api/prometheus/v1/api_test.go000066400000000000000000001433151476160432400220500ustar00rootroot00000000000000// Copyright 2017 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package v1 import ( "context" "errors" "io" "math" "net/http" "net/http/httptest" "net/url" "reflect" "strconv" "strings" "testing" "time" json "github.com/json-iterator/go" "github.com/prometheus/common/model" ) type apiTest struct { do func() (interface{}, Warnings, error) inWarnings []string inErr error inStatusCode int inRes interface{} reqPath string reqMethod string res interface{} err error } type apiTestClient struct { *testing.T curTest apiTest } func (c *apiTestClient) URL(ep string, args map[string]string) *url.URL { path := ep for k, v := range args { path = strings.ReplaceAll(path, ":"+k, v) } u := &url.URL{ Host: "test:9090", Path: path, } return u } func (c *apiTestClient) Do(_ context.Context, req *http.Request) (*http.Response, []byte, Warnings, error) { test := c.curTest if req.URL.Path != test.reqPath { c.Errorf("unexpected request path: want %s, got %s", test.reqPath, req.URL.Path) } if req.Method != test.reqMethod { c.Errorf("unexpected request method: want %s, got %s", test.reqMethod, req.Method) } b, err := json.Marshal(test.inRes) if err != nil { c.Fatal(err) } resp := &http.Response{} if test.inStatusCode != 0 { resp.StatusCode = test.inStatusCode } else if test.inErr != nil { resp.StatusCode = http.StatusUnprocessableEntity } else { resp.StatusCode = http.StatusOK } return resp, b, test.inWarnings, test.inErr } func (c *apiTestClient) DoGetFallback(ctx context.Context, u *url.URL, args url.Values) (*http.Response, []byte, Warnings, error) { req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(args.Encode())) if err != nil { return nil, nil, nil, err } return c.Do(ctx, req) } func TestAPIs(t *testing.T) { testTime := time.Now() tc := &apiTestClient{ T: t, } promAPI := &httpAPI{ client: tc, } doAlertManagers := func() func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { v, err := promAPI.AlertManagers(context.Background()) return v, nil, err } } doCleanTombstones := func() func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { return nil, nil, promAPI.CleanTombstones(context.Background()) } } doConfig := func() func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { v, err := promAPI.Config(context.Background()) return v, nil, err } } doDeleteSeries := func(matcher string, startTime, endTime time.Time) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { return nil, nil, promAPI.DeleteSeries(context.Background(), []string{matcher}, startTime, endTime) } } doFlags := func() func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { v, err := promAPI.Flags(context.Background()) return v, nil, err } } doBuildinfo := func() func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { v, err := promAPI.Buildinfo(context.Background()) return v, nil, err } } doRuntimeinfo := func() func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { v, err := promAPI.Runtimeinfo(context.Background()) return v, nil, err } } doLabelNames := func(matches []string, startTime, endTime time.Time, opts ...Option) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { return promAPI.LabelNames(context.Background(), matches, startTime, endTime, opts...) } } doLabelValues := func(matches []string, label string, startTime, endTime time.Time, opts ...Option) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { return promAPI.LabelValues(context.Background(), label, matches, startTime, endTime, opts...) } } doQuery := func(q string, ts time.Time, opts ...Option) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { return promAPI.Query(context.Background(), q, ts, opts...) } } doQueryRange := func(q string, rng Range, opts ...Option) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { return promAPI.QueryRange(context.Background(), q, rng, opts...) } } doSeries := func(matcher string, startTime, endTime time.Time, opts ...Option) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { return promAPI.Series(context.Background(), []string{matcher}, startTime, endTime, opts...) } } doSnapshot := func(skipHead bool) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { v, err := promAPI.Snapshot(context.Background(), skipHead) return v, nil, err } } doRules := func() func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { v, err := promAPI.Rules(context.Background()) return v, nil, err } } doTargets := func() func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { v, err := promAPI.Targets(context.Background()) return v, nil, err } } doTargetsMetadata := func(matchTarget, metric, limit string) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { v, err := promAPI.TargetsMetadata(context.Background(), matchTarget, metric, limit) return v, nil, err } } doMetadata := func(metric, limit string) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { v, err := promAPI.Metadata(context.Background(), metric, limit) return v, nil, err } } doTSDB := func(opts ...Option) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { v, err := promAPI.TSDB(context.Background(), opts...) return v, nil, err } } doWalReply := func() func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { v, err := promAPI.WalReplay(context.Background()) return v, nil, err } } doQueryExemplars := func(query string, startTime, endTime time.Time) func() (interface{}, Warnings, error) { return func() (interface{}, Warnings, error) { v, err := promAPI.QueryExemplars(context.Background(), query, startTime, endTime) return v, nil, err } } queryTests := []apiTest{ { do: doQuery("2", testTime, WithTimeout(5*time.Second)), inRes: &queryResult{ Type: model.ValScalar, Result: &model.Scalar{ Value: 2, Timestamp: model.TimeFromUnix(testTime.Unix()), }, }, reqMethod: "POST", reqPath: "/api/v1/query", res: &model.Scalar{ Value: 2, Timestamp: model.TimeFromUnix(testTime.Unix()), }, }, { do: doQuery("2", testTime), inErr: errors.New("some error"), reqMethod: "POST", reqPath: "/api/v1/query", err: errors.New("some error"), }, { do: doQuery("2", testTime), inRes: "some body", inStatusCode: 500, inErr: &Error{ Type: ErrServer, Msg: "server error: 500", Detail: "some body", }, reqMethod: "POST", reqPath: "/api/v1/query", err: errors.New("server_error: server error: 500"), }, { do: doQuery("2", testTime), inRes: "some body", inStatusCode: 404, inErr: &Error{ Type: ErrClient, Msg: "client error: 404", Detail: "some body", }, reqMethod: "POST", reqPath: "/api/v1/query", err: errors.New("client_error: client error: 404"), }, // Warning only. { do: doQuery("2", testTime), inWarnings: []string{"warning"}, inRes: &queryResult{ Type: model.ValScalar, Result: &model.Scalar{ Value: 2, Timestamp: model.TimeFromUnix(testTime.Unix()), }, }, reqMethod: "POST", reqPath: "/api/v1/query", res: &model.Scalar{ Value: 2, Timestamp: model.TimeFromUnix(testTime.Unix()), }, }, // Warning + error. { do: doQuery("2", testTime), inWarnings: []string{"warning"}, inRes: "some body", inStatusCode: 404, inErr: &Error{ Type: ErrClient, Msg: "client error: 404", Detail: "some body", }, reqMethod: "POST", reqPath: "/api/v1/query", err: errors.New("client_error: client error: 404"), }, { do: doQueryRange("2", Range{ Start: testTime.Add(-time.Minute), End: testTime, Step: 1 * time.Minute, }, WithTimeout(5*time.Second)), inErr: errors.New("some error"), reqMethod: "POST", reqPath: "/api/v1/query_range", err: errors.New("some error"), }, { do: doLabelNames(nil, testTime.Add(-100*time.Hour), testTime), inRes: []string{"val1", "val2"}, reqMethod: "POST", reqPath: "/api/v1/labels", res: []string{"val1", "val2"}, }, { do: doLabelNames(nil, testTime.Add(-100*time.Hour), testTime), inRes: []string{"val1", "val2"}, inWarnings: []string{"a"}, reqMethod: "POST", reqPath: "/api/v1/labels", res: []string{"val1", "val2"}, }, { do: doLabelNames(nil, testTime.Add(-100*time.Hour), testTime), inErr: errors.New("some error"), reqMethod: "POST", reqPath: "/api/v1/labels", err: errors.New("some error"), }, { do: doLabelNames(nil, testTime.Add(-100*time.Hour), testTime), inErr: errors.New("some error"), inWarnings: []string{"a"}, reqMethod: "POST", reqPath: "/api/v1/labels", err: errors.New("some error"), }, { do: doLabelNames([]string{"up"}, testTime.Add(-100*time.Hour), testTime), inRes: []string{"val1", "val2"}, reqMethod: "POST", reqPath: "/api/v1/labels", res: []string{"val1", "val2"}, }, { do: doLabelValues(nil, "mylabel", testTime.Add(-100*time.Hour), testTime), inRes: []string{"val1", "val2"}, reqMethod: "GET", reqPath: "/api/v1/label/mylabel/values", res: model.LabelValues{"val1", "val2"}, }, { do: doLabelValues(nil, "mylabel", testTime.Add(-100*time.Hour), testTime), inRes: []string{"val1", "val2"}, inWarnings: []string{"a"}, reqMethod: "GET", reqPath: "/api/v1/label/mylabel/values", res: model.LabelValues{"val1", "val2"}, }, { do: doLabelValues(nil, "mylabel", testTime.Add(-100*time.Hour), testTime), inErr: errors.New("some error"), reqMethod: "GET", reqPath: "/api/v1/label/mylabel/values", err: errors.New("some error"), }, { do: doLabelValues(nil, "mylabel", testTime.Add(-100*time.Hour), testTime), inErr: errors.New("some error"), inWarnings: []string{"a"}, reqMethod: "GET", reqPath: "/api/v1/label/mylabel/values", err: errors.New("some error"), }, { do: doLabelValues([]string{"up"}, "mylabel", testTime.Add(-100*time.Hour), testTime), inRes: []string{"val1", "val2"}, reqMethod: "GET", reqPath: "/api/v1/label/mylabel/values", res: model.LabelValues{"val1", "val2"}, }, { do: doSeries("up", testTime.Add(-time.Minute), testTime), inRes: []map[string]string{ { "__name__": "up", "job": "prometheus", "instance": "localhost:9090", }, }, reqMethod: "POST", reqPath: "/api/v1/series", res: []model.LabelSet{ { "__name__": "up", "job": "prometheus", "instance": "localhost:9090", }, }, }, // Series with data + warning. { do: doSeries("up", testTime.Add(-time.Minute), testTime), inRes: []map[string]string{ { "__name__": "up", "job": "prometheus", "instance": "localhost:9090", }, }, inWarnings: []string{"a"}, reqMethod: "POST", reqPath: "/api/v1/series", res: []model.LabelSet{ { "__name__": "up", "job": "prometheus", "instance": "localhost:9090", }, }, }, { do: doSeries("up", testTime.Add(-time.Minute), testTime), inErr: errors.New("some error"), reqMethod: "POST", reqPath: "/api/v1/series", err: errors.New("some error"), }, // Series with error and warning. { do: doSeries("up", testTime.Add(-time.Minute), testTime), inErr: errors.New("some error"), inWarnings: []string{"a"}, reqMethod: "POST", reqPath: "/api/v1/series", err: errors.New("some error"), }, { do: doSnapshot(true), inRes: map[string]string{ "name": "20171210T211224Z-2be650b6d019eb54", }, reqMethod: "POST", reqPath: "/api/v1/admin/tsdb/snapshot", res: SnapshotResult{ Name: "20171210T211224Z-2be650b6d019eb54", }, }, { do: doSnapshot(true), inErr: errors.New("some error"), reqMethod: "POST", reqPath: "/api/v1/admin/tsdb/snapshot", err: errors.New("some error"), }, { do: doCleanTombstones(), reqMethod: "POST", reqPath: "/api/v1/admin/tsdb/clean_tombstones", }, { do: doCleanTombstones(), inErr: errors.New("some error"), reqMethod: "POST", reqPath: "/api/v1/admin/tsdb/clean_tombstones", err: errors.New("some error"), }, { do: doDeleteSeries("up", testTime.Add(-time.Minute), testTime), inRes: []map[string]string{ { "__name__": "up", "job": "prometheus", "instance": "localhost:9090", }, }, reqMethod: "POST", reqPath: "/api/v1/admin/tsdb/delete_series", }, { do: doDeleteSeries("up", testTime.Add(-time.Minute), testTime), inErr: errors.New("some error"), reqMethod: "POST", reqPath: "/api/v1/admin/tsdb/delete_series", err: errors.New("some error"), }, { do: doConfig(), reqMethod: "GET", reqPath: "/api/v1/status/config", inRes: map[string]string{ "yaml": "", }, res: ConfigResult{ YAML: "", }, }, { do: doConfig(), reqMethod: "GET", reqPath: "/api/v1/status/config", inErr: errors.New("some error"), err: errors.New("some error"), }, { do: doFlags(), reqMethod: "GET", reqPath: "/api/v1/status/flags", inRes: map[string]string{ "alertmanager.notification-queue-capacity": "10000", "alertmanager.timeout": "10s", "log.level": "info", "query.lookback-delta": "5m", "query.max-concurrency": "20", }, res: FlagsResult{ "alertmanager.notification-queue-capacity": "10000", "alertmanager.timeout": "10s", "log.level": "info", "query.lookback-delta": "5m", "query.max-concurrency": "20", }, }, { do: doFlags(), reqMethod: "GET", reqPath: "/api/v1/status/flags", inErr: errors.New("some error"), err: errors.New("some error"), }, { do: doBuildinfo(), reqMethod: "GET", reqPath: "/api/v1/status/buildinfo", inErr: errors.New("some error"), err: errors.New("some error"), }, { do: doBuildinfo(), reqMethod: "GET", reqPath: "/api/v1/status/buildinfo", inRes: map[string]interface{}{ "version": "2.23.0", "revision": "26d89b4b0776fe4cd5a3656dfa520f119a375273", "branch": "HEAD", "buildUser": "root@37609b3a0a21", "buildDate": "20201126-10:56:17", "goVersion": "go1.15.5", }, res: BuildinfoResult{ Version: "2.23.0", Revision: "26d89b4b0776fe4cd5a3656dfa520f119a375273", Branch: "HEAD", BuildUser: "root@37609b3a0a21", BuildDate: "20201126-10:56:17", GoVersion: "go1.15.5", }, }, { do: doRuntimeinfo(), reqMethod: "GET", reqPath: "/api/v1/status/runtimeinfo", inErr: errors.New("some error"), err: errors.New("some error"), }, { do: doRuntimeinfo(), reqMethod: "GET", reqPath: "/api/v1/status/runtimeinfo", inRes: map[string]interface{}{ "startTime": "2020-05-18T15:52:53.4503113Z", "CWD": "/prometheus", "reloadConfigSuccess": true, "lastConfigTime": "2020-05-18T15:52:56Z", "corruptionCount": 0, "goroutineCount": 217, "GOMAXPROCS": 2, "GOGC": "100", "GODEBUG": "allocfreetrace", "storageRetention": "1d", }, res: RuntimeinfoResult{ StartTime: time.Date(2020, 5, 18, 15, 52, 53, 450311300, time.UTC), CWD: "/prometheus", ReloadConfigSuccess: true, LastConfigTime: time.Date(2020, 5, 18, 15, 52, 56, 0, time.UTC), CorruptionCount: 0, GoroutineCount: 217, GOMAXPROCS: 2, GOGC: "100", GODEBUG: "allocfreetrace", StorageRetention: "1d", }, }, { do: doAlertManagers(), reqMethod: "GET", reqPath: "/api/v1/alertmanagers", inRes: map[string]interface{}{ "activeAlertManagers": []map[string]string{ { "url": "http://127.0.0.1:9091/api/v1/alerts", }, }, "droppedAlertManagers": []map[string]string{ { "url": "http://127.0.0.1:9092/api/v1/alerts", }, }, }, res: AlertManagersResult{ Active: []AlertManager{ { URL: "http://127.0.0.1:9091/api/v1/alerts", }, }, Dropped: []AlertManager{ { URL: "http://127.0.0.1:9092/api/v1/alerts", }, }, }, }, { do: doAlertManagers(), reqMethod: "GET", reqPath: "/api/v1/alertmanagers", inErr: errors.New("some error"), err: errors.New("some error"), }, { do: doRules(), reqMethod: "GET", reqPath: "/api/v1/rules", inRes: map[string]interface{}{ "groups": []map[string]interface{}{ { "file": "/rules.yaml", "interval": 60, "name": "example", "rules": []map[string]interface{}{ { "alerts": []map[string]interface{}{ { "activeAt": testTime.UTC().Format(time.RFC3339Nano), "annotations": map[string]interface{}{ "summary": "High request latency", }, "labels": map[string]interface{}{ "alertname": "HighRequestLatency", "severity": "page", }, "state": "firing", "value": "1e+00", }, }, "annotations": map[string]interface{}{ "summary": "High request latency", }, "duration": 600, "health": "ok", "labels": map[string]interface{}{ "severity": "page", }, "name": "HighRequestLatency", "query": "job:request_latency_seconds:mean5m{job=\"myjob\"} > 0.5", "type": "alerting", }, { "health": "ok", "name": "job:http_inprogress_requests:sum", "query": "sum(http_inprogress_requests) by (job)", "type": "recording", }, }, }, }, }, res: RulesResult{ Groups: []RuleGroup{ { Name: "example", File: "/rules.yaml", Interval: 60, Rules: []interface{}{ AlertingRule{ Alerts: []*Alert{ { ActiveAt: testTime.UTC(), Annotations: model.LabelSet{ "summary": "High request latency", }, Labels: model.LabelSet{ "alertname": "HighRequestLatency", "severity": "page", }, State: AlertStateFiring, Value: "1e+00", }, }, Annotations: model.LabelSet{ "summary": "High request latency", }, Labels: model.LabelSet{ "severity": "page", }, Duration: 600, Health: RuleHealthGood, Name: "HighRequestLatency", Query: "job:request_latency_seconds:mean5m{job=\"myjob\"} > 0.5", LastError: "", }, RecordingRule{ Health: RuleHealthGood, Name: "job:http_inprogress_requests:sum", Query: "sum(http_inprogress_requests) by (job)", LastError: "", }, }, }, }, }, }, // This has the newer API elements like lastEvaluation, evaluationTime, etc. { do: doRules(), reqMethod: "GET", reqPath: "/api/v1/rules", inRes: map[string]interface{}{ "groups": []map[string]interface{}{ { "file": "/rules.yaml", "interval": 60, "name": "example", "rules": []map[string]interface{}{ { "alerts": []map[string]interface{}{ { "activeAt": testTime.UTC().Format(time.RFC3339Nano), "annotations": map[string]interface{}{ "summary": "High request latency", }, "labels": map[string]interface{}{ "alertname": "HighRequestLatency", "severity": "page", }, "state": "firing", "value": "1e+00", }, }, "annotations": map[string]interface{}{ "summary": "High request latency", }, "duration": 600, "health": "ok", "labels": map[string]interface{}{ "severity": "page", }, "name": "HighRequestLatency", "query": "job:request_latency_seconds:mean5m{job=\"myjob\"} > 0.5", "type": "alerting", "evaluationTime": 0.5, "lastEvaluation": "2020-05-18T15:52:53.4503113Z", "state": "firing", }, { "health": "ok", "name": "job:http_inprogress_requests:sum", "query": "sum(http_inprogress_requests) by (job)", "type": "recording", "evaluationTime": 0.3, "lastEvaluation": "2020-05-18T15:52:53.4503113Z", }, }, }, }, }, res: RulesResult{ Groups: []RuleGroup{ { Name: "example", File: "/rules.yaml", Interval: 60, Rules: []interface{}{ AlertingRule{ Alerts: []*Alert{ { ActiveAt: testTime.UTC(), Annotations: model.LabelSet{ "summary": "High request latency", }, Labels: model.LabelSet{ "alertname": "HighRequestLatency", "severity": "page", }, State: AlertStateFiring, Value: "1e+00", }, }, Annotations: model.LabelSet{ "summary": "High request latency", }, Labels: model.LabelSet{ "severity": "page", }, Duration: 600, Health: RuleHealthGood, Name: "HighRequestLatency", Query: "job:request_latency_seconds:mean5m{job=\"myjob\"} > 0.5", LastError: "", EvaluationTime: 0.5, LastEvaluation: time.Date(2020, 5, 18, 15, 52, 53, 450311300, time.UTC), State: "firing", }, RecordingRule{ Health: RuleHealthGood, Name: "job:http_inprogress_requests:sum", Query: "sum(http_inprogress_requests) by (job)", LastError: "", EvaluationTime: 0.3, LastEvaluation: time.Date(2020, 5, 18, 15, 52, 53, 450311300, time.UTC), }, }, }, }, }, }, { do: doRules(), reqMethod: "GET", reqPath: "/api/v1/rules", inErr: errors.New("some error"), err: errors.New("some error"), }, { do: doTargets(), reqMethod: "GET", reqPath: "/api/v1/targets", inRes: map[string]interface{}{ "activeTargets": []map[string]interface{}{ { "discoveredLabels": map[string]string{ "__address__": "127.0.0.1:9090", "__metrics_path__": "/metrics", "__scheme__": "http", "job": "prometheus", }, "labels": map[string]string{ "instance": "127.0.0.1:9090", "job": "prometheus", }, "scrapePool": "prometheus", "scrapeUrl": "http://127.0.0.1:9090", "globalUrl": "http://127.0.0.1:9090", "lastError": "error while scraping target", "lastScrape": testTime.UTC().Format(time.RFC3339Nano), "lastScrapeDuration": 0.001146115, "health": "up", }, }, "droppedTargets": []map[string]interface{}{ { "discoveredLabels": map[string]string{ "__address__": "127.0.0.1:9100", "__metrics_path__": "/metrics", "__scheme__": "http", "job": "node", }, }, }, }, res: TargetsResult{ Active: []ActiveTarget{ { DiscoveredLabels: map[string]string{ "__address__": "127.0.0.1:9090", "__metrics_path__": "/metrics", "__scheme__": "http", "job": "prometheus", }, Labels: model.LabelSet{ "instance": "127.0.0.1:9090", "job": "prometheus", }, ScrapePool: "prometheus", ScrapeURL: "http://127.0.0.1:9090", GlobalURL: "http://127.0.0.1:9090", LastError: "error while scraping target", LastScrape: testTime.UTC(), LastScrapeDuration: 0.001146115, Health: HealthGood, }, }, Dropped: []DroppedTarget{ { DiscoveredLabels: map[string]string{ "__address__": "127.0.0.1:9100", "__metrics_path__": "/metrics", "__scheme__": "http", "job": "node", }, }, }, }, }, { do: doTargets(), reqMethod: "GET", reqPath: "/api/v1/targets", inErr: errors.New("some error"), err: errors.New("some error"), }, { do: doTargetsMetadata("{job=\"prometheus\"}", "go_goroutines", "1"), inRes: []map[string]interface{}{ { "target": map[string]interface{}{ "instance": "127.0.0.1:9090", "job": "prometheus", }, "type": "gauge", "help": "Number of goroutines that currently exist.", "unit": "", }, }, reqMethod: "GET", reqPath: "/api/v1/targets/metadata", res: []MetricMetadata{ { Target: map[string]string{ "instance": "127.0.0.1:9090", "job": "prometheus", }, Type: "gauge", Help: "Number of goroutines that currently exist.", Unit: "", }, }, }, { do: doTargetsMetadata("{job=\"prometheus\"}", "go_goroutines", "1"), inErr: errors.New("some error"), reqMethod: "GET", reqPath: "/api/v1/targets/metadata", err: errors.New("some error"), }, { do: doMetadata("go_goroutines", "1"), inRes: map[string]interface{}{ "go_goroutines": []map[string]interface{}{ { "type": "gauge", "help": "Number of goroutines that currently exist.", "unit": "", }, }, }, reqMethod: "GET", reqPath: "/api/v1/metadata", res: map[string][]Metadata{ "go_goroutines": { { Type: "gauge", Help: "Number of goroutines that currently exist.", Unit: "", }, }, }, }, { do: doMetadata("", "1"), inErr: errors.New("some error"), reqMethod: "GET", reqPath: "/api/v1/metadata", err: errors.New("some error"), }, { do: doTSDB(), reqMethod: "GET", reqPath: "/api/v1/status/tsdb", inErr: errors.New("some error"), err: errors.New("some error"), }, { do: doTSDB(), reqMethod: "GET", reqPath: "/api/v1/status/tsdb", inRes: map[string]interface{}{ "headStats": map[string]interface{}{ "numSeries": 18476, "numLabelPairs": 4301, "chunkCount": 72692, "minTime": 1634644800304, "maxTime": 1634650590304, }, "seriesCountByMetricName": []interface{}{ map[string]interface{}{ "name": "kubelet_http_requests_duration_seconds_bucket", "value": 1000, }, }, "labelValueCountByLabelName": []interface{}{ map[string]interface{}{ "name": "__name__", "value": 200, }, }, "memoryInBytesByLabelName": []interface{}{ map[string]interface{}{ "name": "id", "value": 4096, }, }, "seriesCountByLabelValuePair": []interface{}{ map[string]interface{}{ "name": "job=kubelet", "value": 30000, }, }, }, res: TSDBResult{ HeadStats: TSDBHeadStats{ NumSeries: 18476, NumLabelPairs: 4301, ChunkCount: 72692, MinTime: 1634644800304, MaxTime: 1634650590304, }, SeriesCountByMetricName: []Stat{ { Name: "kubelet_http_requests_duration_seconds_bucket", Value: 1000, }, }, LabelValueCountByLabelName: []Stat{ { Name: "__name__", Value: 200, }, }, MemoryInBytesByLabelName: []Stat{ { Name: "id", Value: 4096, }, }, SeriesCountByLabelValuePair: []Stat{ { Name: "job=kubelet", Value: 30000, }, }, }, }, { do: doWalReply(), reqMethod: "GET", reqPath: "/api/v1/status/walreplay", inErr: errors.New("some error"), err: errors.New("some error"), }, { do: doWalReply(), reqMethod: "GET", reqPath: "/api/v1/status/walreplay", inRes: map[string]interface{}{ "min": 2, "max": 5, "current": 40, }, res: WalReplayStatus{ Min: 2, Max: 5, Current: 40, }, }, { do: doQueryExemplars("tns_request_duration_seconds_bucket", testTime.Add(-1*time.Minute), testTime), reqMethod: "POST", reqPath: "/api/v1/query_exemplars", inErr: errors.New("some error"), err: errors.New("some error"), }, { do: doQueryExemplars("tns_request_duration_seconds_bucket", testTime.Add(-1*time.Minute), testTime), reqMethod: "POST", reqPath: "/api/v1/query_exemplars", inRes: []interface{}{ map[string]interface{}{ "seriesLabels": map[string]interface{}{ "__name__": "tns_request_duration_seconds_bucket", "instance": "app:80", "job": "tns/app", }, "exemplars": []interface{}{ map[string]interface{}{ "labels": map[string]interface{}{ "traceID": "19fd8c8a33975a23", }, "value": "0.003863295", "timestamp": model.TimeFromUnixNano(testTime.UnixNano()), }, map[string]interface{}{ "labels": map[string]interface{}{ "traceID": "67f743f07cc786b0", }, "value": "0.001535405", "timestamp": model.TimeFromUnixNano(testTime.UnixNano()), }, }, }, }, res: []ExemplarQueryResult{ { SeriesLabels: model.LabelSet{ "__name__": "tns_request_duration_seconds_bucket", "instance": "app:80", "job": "tns/app", }, Exemplars: []Exemplar{ { Labels: model.LabelSet{"traceID": "19fd8c8a33975a23"}, Value: 0.003863295, Timestamp: model.TimeFromUnixNano(testTime.UnixNano()), }, { Labels: model.LabelSet{"traceID": "67f743f07cc786b0"}, Value: 0.001535405, Timestamp: model.TimeFromUnixNano(testTime.UnixNano()), }, }, }, }, }, } var tests []apiTest tests = append(tests, queryTests...) for i, test := range tests { t.Run(strconv.Itoa(i), func(t *testing.T) { tc.curTest = test res, warnings, err := test.do() if (test.inWarnings == nil) != (warnings == nil) && !reflect.DeepEqual(test.inWarnings, warnings) { t.Fatalf("mismatch in warnings expected=%v actual=%v", test.inWarnings, warnings) } if test.err != nil { if err == nil { t.Fatalf("expected error %q but got none", test.err) } if err.Error() != test.err.Error() { t.Errorf("unexpected error: want %s, got %s", test.err, err) } apiErr := &Error{} if ok := errors.As(err, &apiErr); ok { if apiErr.Detail != test.inRes { t.Errorf("%q should be %q", apiErr.Detail, test.inRes) } } return } if err != nil { t.Fatalf("unexpected error: %s", err) } if !reflect.DeepEqual(res, test.res) { t.Errorf("unexpected result: want %v, got %v", test.res, res) } }) } } type testClient struct { *testing.T ch chan apiClientTest req *http.Request } type apiClientTest struct { code int response interface{} expectedBody string expectedErr *Error expectedWarnings Warnings } func (c *testClient) URL(ep string, args map[string]string) *url.URL { return nil } func (c *testClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, error) { if ctx == nil { c.Fatalf("context was not passed down") } if req != c.req { c.Fatalf("request was not passed down") } test := <-c.ch var b []byte var err error switch v := test.response.(type) { case string: b = []byte(v) default: b, err = json.Marshal(v) if err != nil { c.Fatal(err) } } resp := &http.Response{ StatusCode: test.code, } return resp, b, nil } func TestAPIClientDo(t *testing.T) { tests := []apiClientTest{ { code: http.StatusUnprocessableEntity, response: &apiResponse{ Status: "error", Data: json.RawMessage(`null`), ErrorType: ErrBadData, Error: "failed", }, expectedErr: &Error{ Type: ErrBadData, Msg: "failed", }, expectedBody: `null`, }, { code: http.StatusUnprocessableEntity, response: &apiResponse{ Status: "error", Data: json.RawMessage(`"test"`), ErrorType: ErrTimeout, Error: "timed out", }, expectedErr: &Error{ Type: ErrTimeout, Msg: "timed out", }, expectedBody: `test`, }, { code: http.StatusInternalServerError, response: "500 error details", expectedErr: &Error{ Type: ErrServer, Msg: "server error: 500", Detail: "500 error details", }, }, { code: http.StatusNotFound, response: "404 error details", expectedErr: &Error{ Type: ErrClient, Msg: "client error: 404", Detail: "404 error details", }, }, { code: http.StatusBadRequest, response: &apiResponse{ Status: "error", Data: json.RawMessage(`null`), ErrorType: ErrBadData, Error: "end timestamp must not be before start time", }, expectedErr: &Error{ Type: ErrBadData, Msg: "end timestamp must not be before start time", }, }, { code: http.StatusUnprocessableEntity, response: "bad json", expectedErr: &Error{ Type: ErrBadResponse, Msg: "readObjectStart: expect { or n, but found b, error found in #1 byte of ...|bad json|..., bigger context ...|bad json|...", }, }, { code: http.StatusUnprocessableEntity, response: &apiResponse{ Status: "success", Data: json.RawMessage(`"test"`), }, expectedErr: &Error{ Type: ErrBadResponse, Msg: "inconsistent body for response code", }, }, { code: http.StatusUnprocessableEntity, response: &apiResponse{ Status: "success", Data: json.RawMessage(`"test"`), ErrorType: ErrTimeout, Error: "timed out", }, expectedErr: &Error{ Type: ErrBadResponse, Msg: "inconsistent body for response code", }, }, { code: http.StatusOK, response: &apiResponse{ Status: "error", Data: json.RawMessage(`"test"`), ErrorType: ErrTimeout, Error: "timed out", }, expectedErr: &Error{ Type: ErrTimeout, Msg: "timed out", }, }, { code: http.StatusOK, response: &apiResponse{ Status: "error", Data: json.RawMessage(`"test"`), ErrorType: ErrTimeout, Error: "timed out", Warnings: []string{"a"}, }, expectedErr: &Error{ Type: ErrTimeout, Msg: "timed out", }, expectedWarnings: []string{"a"}, }, } tc := &testClient{ T: t, ch: make(chan apiClientTest, 1), req: &http.Request{}, } client := &apiClientImpl{ client: tc, } for i, test := range tests { t.Run(strconv.Itoa(i), func(t *testing.T) { tc.ch <- test _, body, warnings, err := client.Do(context.Background(), tc.req) if test.expectedWarnings != nil { if !reflect.DeepEqual(test.expectedWarnings, warnings) { t.Fatalf("mismatch in warnings expected=%v actual=%v", test.expectedWarnings, warnings) } } else { if warnings != nil { t.Fatalf("unexpected warnings: %v", warnings) } } if test.expectedErr != nil { if err == nil { t.Fatal("expected error, but got none") } if test.expectedErr.Error() != err.Error() { t.Fatalf("expected error:%v, but got:%v", test.expectedErr.Error(), err.Error()) } if test.expectedErr.Detail != "" { apiErr := &Error{} if errors.As(err, &apiErr) { if apiErr.Detail != test.expectedErr.Detail { t.Fatalf("expected error detail :%v, but got:%v", apiErr.Detail, test.expectedErr.Detail) } } else { t.Fatalf("expected v1.Error instance, but got:%T", err) } } return } if err != nil { t.Fatalf("unexpected error:%v", err) } if test.expectedBody != string(body) { t.Fatalf("expected body :%v, but got:%v", test.expectedBody, string(body)) } }) } } func TestSamplesJSONSerialization(t *testing.T) { tests := []struct { point model.SamplePair expected string }{ { point: model.SamplePair{0, 0}, expected: `[0,"0"]`, }, { point: model.SamplePair{1, 20}, expected: `[0.001,"20"]`, }, { point: model.SamplePair{10, 20}, expected: `[0.010,"20"]`, }, { point: model.SamplePair{100, 20}, expected: `[0.100,"20"]`, }, { point: model.SamplePair{1001, 20}, expected: `[1.001,"20"]`, }, { point: model.SamplePair{1010, 20}, expected: `[1.010,"20"]`, }, { point: model.SamplePair{1100, 20}, expected: `[1.100,"20"]`, }, { point: model.SamplePair{12345678123456555, 20}, expected: `[12345678123456.555,"20"]`, }, { point: model.SamplePair{-1, 20}, expected: `[-0.001,"20"]`, }, { point: model.SamplePair{0, model.SampleValue(math.NaN())}, expected: `[0,"NaN"]`, }, { point: model.SamplePair{0, model.SampleValue(math.Inf(1))}, expected: `[0,"+Inf"]`, }, { point: model.SamplePair{0, model.SampleValue(math.Inf(-1))}, expected: `[0,"-Inf"]`, }, { point: model.SamplePair{0, model.SampleValue(1.2345678e6)}, expected: `[0,"1234567.8"]`, }, { point: model.SamplePair{0, 1.2345678e-6}, expected: `[0,"0.0000012345678"]`, }, { point: model.SamplePair{0, 1.2345678e-67}, expected: `[0,"1.2345678e-67"]`, }, } for _, test := range tests { t.Run(test.expected, func(t *testing.T) { b, err := json.Marshal(test.point) if err != nil { t.Fatal(err) } if string(b) != test.expected { t.Fatalf("Mismatch marshal expected=%s actual=%s", test.expected, string(b)) } // To test Unmarshal we will Unmarshal then re-Marshal this way we // can do a string compare, otherwise Nan values don't show equivalence // properly. var sp model.SamplePair if err = json.Unmarshal(b, &sp); err != nil { t.Fatal(err) } b, err = json.Marshal(sp) if err != nil { t.Fatal(err) } if string(b) != test.expected { t.Fatalf("Mismatch marshal expected=%s actual=%s", test.expected, string(b)) } }) } } func TestHistogramJSONSerialization(t *testing.T) { tests := []struct { name string point model.SampleHistogramPair expected string }{ { name: "empty histogram", point: model.SampleHistogramPair{ Timestamp: 0, Histogram: &model.SampleHistogram{}, }, expected: `[0,{"count":"0","sum":"0"}]`, }, { name: "histogram with NaN/Inf and no buckets", point: model.SampleHistogramPair{ Timestamp: 0, Histogram: &model.SampleHistogram{ Count: model.FloatString(math.NaN()), Sum: model.FloatString(math.Inf(1)), }, }, expected: `[0,{"count":"NaN","sum":"+Inf"}]`, }, { name: "six-bucket histogram", point: model.SampleHistogramPair{ Timestamp: 1, Histogram: &model.SampleHistogram{ Count: 13.5, Sum: 3897.1, Buckets: model.HistogramBuckets{ { Boundaries: 1, Lower: -4870.992343051145, Upper: -4466.7196729968955, Count: 1, }, { Boundaries: 1, Lower: -861.0779292198035, Upper: -789.6119426088657, Count: 2, }, { Boundaries: 1, Lower: -558.3399591246119, Upper: -512, Count: 3, }, { Boundaries: 0, Lower: 2048, Upper: 2233.3598364984477, Count: 1.5, }, { Boundaries: 0, Lower: 2896.3093757400984, Upper: 3158.4477704354626, Count: 2.5, }, { Boundaries: 0, Lower: 4466.7196729968955, Upper: 4870.992343051145, Count: 3.5, }, }, }, }, expected: `[0.001,{"count":"13.5","sum":"3897.1","buckets":[[1,"-4870.992343051145","-4466.7196729968955","1"],[1,"-861.0779292198035","-789.6119426088657","2"],[1,"-558.3399591246119","-512","3"],[0,"2048","2233.3598364984477","1.5"],[0,"2896.3093757400984","3158.4477704354626","2.5"],[0,"4466.7196729968955","4870.992343051145","3.5"]]}]`, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { b, err := json.Marshal(test.point) if err != nil { t.Fatal(err) } if string(b) != test.expected { t.Fatalf("Mismatch marshal expected=%s actual=%s", test.expected, string(b)) } // To test Unmarshal we will Unmarshal then re-Marshal. This way we // can do a string compare, otherwise NaN values don't show equivalence // properly. var sp model.SampleHistogramPair if err = json.Unmarshal(b, &sp); err != nil { t.Fatal(err) } b, err = json.Marshal(sp) if err != nil { t.Fatal(err) } if string(b) != test.expected { t.Fatalf("Mismatch marshal expected=%s actual=%s", test.expected, string(b)) } }) } } func TestSampleStreamJSONSerialization(t *testing.T) { floats, histograms := generateData(1, 5) tests := []struct { name string stream model.SampleStream expectedJSON string }{ { "floats", *floats[0], `{"metric":{"__name__":"timeseries_0","foo":"bar"},"values":[[1677587259.055,"1"],[1677587244.055,"2"],[1677587229.055,"3"],[1677587214.055,"4"],[1677587199.055,"5"]]}`, }, { "histograms", *histograms[0], `{"metric":{"__name__":"timeseries_0","foo":"bar"},"histograms":[[1677587259.055,{"count":"13.5","sum":"0.1","buckets":[[1,"-4870.992343051145","-4466.7196729968955","1"],[1,"-861.0779292198035","-789.6119426088657","2"],[1,"-558.3399591246119","-512","3"],[0,"2048","2233.3598364984477","1.5"],[0,"2896.3093757400984","3158.4477704354626","2.5"],[0,"4466.7196729968955","4870.992343051145","3.5"]]}],[1677587244.055,{"count":"27","sum":"0.2","buckets":[[1,"-4870.992343051145","-4466.7196729968955","2"],[1,"-861.0779292198035","-789.6119426088657","4"],[1,"-558.3399591246119","-512","6"],[0,"2048","2233.3598364984477","3"],[0,"2896.3093757400984","3158.4477704354626","5"],[0,"4466.7196729968955","4870.992343051145","7"]]}],[1677587229.055,{"count":"40.5","sum":"0.30000000000000004","buckets":[[1,"-4870.992343051145","-4466.7196729968955","3"],[1,"-861.0779292198035","-789.6119426088657","6"],[1,"-558.3399591246119","-512","9"],[0,"2048","2233.3598364984477","4.5"],[0,"2896.3093757400984","3158.4477704354626","7.5"],[0,"4466.7196729968955","4870.992343051145","10.5"]]}],[1677587214.055,{"count":"54","sum":"0.4","buckets":[[1,"-4870.992343051145","-4466.7196729968955","4"],[1,"-861.0779292198035","-789.6119426088657","8"],[1,"-558.3399591246119","-512","12"],[0,"2048","2233.3598364984477","6"],[0,"2896.3093757400984","3158.4477704354626","10"],[0,"4466.7196729968955","4870.992343051145","14"]]}],[1677587199.055,{"count":"67.5","sum":"0.5","buckets":[[1,"-4870.992343051145","-4466.7196729968955","5"],[1,"-861.0779292198035","-789.6119426088657","10"],[1,"-558.3399591246119","-512","15"],[0,"2048","2233.3598364984477","7.5"],[0,"2896.3093757400984","3158.4477704354626","12.5"],[0,"4466.7196729968955","4870.992343051145","17.5"]]}]]}`, }, { "both", model.SampleStream{ Metric: floats[0].Metric, Values: floats[0].Values, Histograms: histograms[0].Histograms, }, `{"metric":{"__name__":"timeseries_0","foo":"bar"},"values":[[1677587259.055,"1"],[1677587244.055,"2"],[1677587229.055,"3"],[1677587214.055,"4"],[1677587199.055,"5"]],"histograms":[[1677587259.055,{"count":"13.5","sum":"0.1","buckets":[[1,"-4870.992343051145","-4466.7196729968955","1"],[1,"-861.0779292198035","-789.6119426088657","2"],[1,"-558.3399591246119","-512","3"],[0,"2048","2233.3598364984477","1.5"],[0,"2896.3093757400984","3158.4477704354626","2.5"],[0,"4466.7196729968955","4870.992343051145","3.5"]]}],[1677587244.055,{"count":"27","sum":"0.2","buckets":[[1,"-4870.992343051145","-4466.7196729968955","2"],[1,"-861.0779292198035","-789.6119426088657","4"],[1,"-558.3399591246119","-512","6"],[0,"2048","2233.3598364984477","3"],[0,"2896.3093757400984","3158.4477704354626","5"],[0,"4466.7196729968955","4870.992343051145","7"]]}],[1677587229.055,{"count":"40.5","sum":"0.30000000000000004","buckets":[[1,"-4870.992343051145","-4466.7196729968955","3"],[1,"-861.0779292198035","-789.6119426088657","6"],[1,"-558.3399591246119","-512","9"],[0,"2048","2233.3598364984477","4.5"],[0,"2896.3093757400984","3158.4477704354626","7.5"],[0,"4466.7196729968955","4870.992343051145","10.5"]]}],[1677587214.055,{"count":"54","sum":"0.4","buckets":[[1,"-4870.992343051145","-4466.7196729968955","4"],[1,"-861.0779292198035","-789.6119426088657","8"],[1,"-558.3399591246119","-512","12"],[0,"2048","2233.3598364984477","6"],[0,"2896.3093757400984","3158.4477704354626","10"],[0,"4466.7196729968955","4870.992343051145","14"]]}],[1677587199.055,{"count":"67.5","sum":"0.5","buckets":[[1,"-4870.992343051145","-4466.7196729968955","5"],[1,"-861.0779292198035","-789.6119426088657","10"],[1,"-558.3399591246119","-512","15"],[0,"2048","2233.3598364984477","7.5"],[0,"2896.3093757400984","3158.4477704354626","12.5"],[0,"4466.7196729968955","4870.992343051145","17.5"]]}]]}`, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { b, err := json.Marshal(test.stream) if err != nil { t.Fatal(err) } if string(b) != test.expectedJSON { t.Fatalf("Mismatch marshal expected=%s actual=%s", test.expectedJSON, string(b)) } var stream model.SampleStream if err = json.Unmarshal(b, &stream); err != nil { t.Fatal(err) } if !reflect.DeepEqual(test.stream, stream) { t.Fatalf("Mismatch after unmarshal expected=%#v actual=%#v", test.stream, stream) } }) } } type httpTestClient struct { client http.Client } func (c *httpTestClient) URL(ep string, args map[string]string) *url.URL { return nil } func (c *httpTestClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, error) { resp, err := c.client.Do(req) if err != nil { return nil, nil, err } var body []byte done := make(chan struct{}) go func() { body, err = io.ReadAll(resp.Body) close(done) }() select { case <-ctx.Done(): <-done err = resp.Body.Close() if err == nil { err = ctx.Err() } case <-done: } return resp, body, err } func TestDoGetFallback(t *testing.T) { v := url.Values{"a": []string{"1", "2"}} type testResponse struct { Values string Method string } // Start a local HTTP server. server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { req.ParseForm() testResp, _ := json.Marshal(&testResponse{ Values: req.Form.Encode(), Method: req.Method, }) apiResp := &apiResponse{ Data: testResp, } body, _ := json.Marshal(apiResp) if req.Method == http.MethodPost { if req.URL.Path == "/blockPost405" { http.Error(w, string(body), http.StatusMethodNotAllowed) return } } if req.Method == http.MethodPost { if req.URL.Path == "/blockPost501" { http.Error(w, string(body), http.StatusNotImplemented) return } } w.Write(body) })) // Close the server when test finishes. defer server.Close() u, err := url.Parse(server.URL) if err != nil { t.Fatal(err) } client := &httpTestClient{client: *(server.Client())} api := &apiClientImpl{ client: client, } // Do a post, and ensure that the post succeeds. _, b, _, err := api.DoGetFallback(context.TODO(), u, v) if err != nil { t.Fatalf("Error doing local request: %v", err) } resp := &testResponse{} if err := json.Unmarshal(b, resp); err != nil { t.Fatal(err) } if resp.Method != http.MethodPost { t.Fatalf("Mismatch method") } if resp.Values != v.Encode() { t.Fatalf("Mismatch in values") } // Do a fallback to a get on 405. u.Path = "/blockPost405" _, b, _, err = api.DoGetFallback(context.TODO(), u, v) if err != nil { t.Fatalf("Error doing local request: %v", err) } if err := json.Unmarshal(b, resp); err != nil { t.Fatal(err) } if resp.Method != http.MethodGet { t.Fatalf("Mismatch method") } if resp.Values != v.Encode() { t.Fatalf("Mismatch in values") } // Do a fallback to a get on 501. u.Path = "/blockPost501" _, b, _, err = api.DoGetFallback(context.TODO(), u, v) if err != nil { t.Fatalf("Error doing local request: %v", err) } if err := json.Unmarshal(b, resp); err != nil { t.Fatal(err) } if resp.Method != http.MethodGet { t.Fatalf("Mismatch method") } if resp.Values != v.Encode() { t.Fatalf("Mismatch in values") } } client_golang-1.21.1/api/prometheus/v1/example_test.go000066400000000000000000000164541476160432400227350ustar00rootroot00000000000000// Copyright 2019 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package v1_test provides examples making requests to Prometheus using the // Golang client. package v1_test import ( "context" "fmt" "net/http" "os" "time" "github.com/prometheus/common/config" "github.com/prometheus/client_golang/api" v1 "github.com/prometheus/client_golang/api/prometheus/v1" ) func ExampleAPI_query() { client, err := api.NewClient(api.Config{ Address: "http://demo.robustperception.io:9090", }) if err != nil { fmt.Printf("Error creating client: %v\n", err) os.Exit(1) } v1api := v1.NewAPI(client) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() result, warnings, err := v1api.Query(ctx, "up", time.Now(), v1.WithTimeout(5*time.Second)) if err != nil { fmt.Printf("Error querying Prometheus: %v\n", err) os.Exit(1) } if len(warnings) > 0 { fmt.Printf("Warnings: %v\n", warnings) } fmt.Printf("Result:\n%v\n", result) } func ExampleAPI_queryRange() { client, err := api.NewClient(api.Config{ Address: "http://demo.robustperception.io:9090", }) if err != nil { fmt.Printf("Error creating client: %v\n", err) os.Exit(1) } v1api := v1.NewAPI(client) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() r := v1.Range{ Start: time.Now().Add(-time.Hour), End: time.Now(), Step: time.Minute, } result, warnings, err := v1api.QueryRange(ctx, "rate(prometheus_tsdb_head_samples_appended_total[5m])", r, v1.WithTimeout(5*time.Second)) if err != nil { fmt.Printf("Error querying Prometheus: %v\n", err) os.Exit(1) } if len(warnings) > 0 { fmt.Printf("Warnings: %v\n", warnings) } fmt.Printf("Result:\n%v\n", result) } type userAgentRoundTripper struct { name string rt http.RoundTripper } // RoundTrip implements the http.RoundTripper interface. func (u userAgentRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { if r.UserAgent() == "" { // The specification of http.RoundTripper says that it shouldn't mutate // the request so make a copy of req.Header since this is all that is // modified. r2 := new(http.Request) *r2 = *r r2.Header = make(http.Header) for k, s := range r.Header { r2.Header[k] = s } r2.Header.Set("User-Agent", u.name) r = r2 } return u.rt.RoundTrip(r) } func ExampleAPI_queryRangeWithUserAgent() { client, err := api.NewClient(api.Config{ Address: "http://demo.robustperception.io:9090", RoundTripper: userAgentRoundTripper{name: "Client-Golang", rt: api.DefaultRoundTripper}, }) if err != nil { fmt.Printf("Error creating client: %v\n", err) os.Exit(1) } v1api := v1.NewAPI(client) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() r := v1.Range{ Start: time.Now().Add(-time.Hour), End: time.Now(), Step: time.Minute, } result, warnings, err := v1api.QueryRange(ctx, "rate(prometheus_tsdb_head_samples_appended_total[5m])", r) if err != nil { fmt.Printf("Error querying Prometheus: %v\n", err) os.Exit(1) } if len(warnings) > 0 { fmt.Printf("Warnings: %v\n", warnings) } fmt.Printf("Result:\n%v\n", result) } func ExampleAPI_queryRangeWithBasicAuth() { client, err := api.NewClient(api.Config{ Address: "http://demo.robustperception.io:9090", // We can use amazing github.com/prometheus/common/config helper! RoundTripper: config.NewBasicAuthRoundTripper( config.NewInlineSecret("me"), config.NewInlineSecret("definitely_me"), api.DefaultRoundTripper, ), }) if err != nil { fmt.Printf("Error creating client: %v\n", err) os.Exit(1) } v1api := v1.NewAPI(client) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() r := v1.Range{ Start: time.Now().Add(-time.Hour), End: time.Now(), Step: time.Minute, } result, warnings, err := v1api.QueryRange(ctx, "rate(prometheus_tsdb_head_samples_appended_total[5m])", r) if err != nil { fmt.Printf("Error querying Prometheus: %v\n", err) os.Exit(1) } if len(warnings) > 0 { fmt.Printf("Warnings: %v\n", warnings) } fmt.Printf("Result:\n%v\n", result) } func ExampleAPI_queryRangeWithAuthBearerToken() { client, err := api.NewClient(api.Config{ Address: "http://demo.robustperception.io:9090", // We can use amazing github.com/prometheus/common/config helper! RoundTripper: config.NewAuthorizationCredentialsRoundTripper( "Bearer", config.NewInlineSecret("secret_token"), api.DefaultRoundTripper, ), }) if err != nil { fmt.Printf("Error creating client: %v\n", err) os.Exit(1) } v1api := v1.NewAPI(client) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() r := v1.Range{ Start: time.Now().Add(-time.Hour), End: time.Now(), Step: time.Minute, } result, warnings, err := v1api.QueryRange(ctx, "rate(prometheus_tsdb_head_samples_appended_total[5m])", r) if err != nil { fmt.Printf("Error querying Prometheus: %v\n", err) os.Exit(1) } if len(warnings) > 0 { fmt.Printf("Warnings: %v\n", warnings) } fmt.Printf("Result:\n%v\n", result) } func ExampleAPI_queryRangeWithAuthBearerTokenHeadersRoundTripper() { client, err := api.NewClient(api.Config{ Address: "http://demo.robustperception.io:9090", // We can use amazing github.com/prometheus/common/config helper! RoundTripper: config.NewHeadersRoundTripper( &config.Headers{ Headers: map[string]config.Header{ "Authorization": { Values: []string{"Bearer secret"}, }, }, }, api.DefaultRoundTripper, ), }) if err != nil { fmt.Printf("Error creating client: %v\n", err) os.Exit(1) } v1api := v1.NewAPI(client) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() r := v1.Range{ Start: time.Now().Add(-time.Hour), End: time.Now(), Step: time.Minute, } result, warnings, err := v1api.QueryRange(ctx, "rate(prometheus_tsdb_head_samples_appended_total[5m])", r) if err != nil { fmt.Printf("Error querying Prometheus: %v\n", err) os.Exit(1) } if len(warnings) > 0 { fmt.Printf("Warnings: %v\n", warnings) } fmt.Printf("Result:\n%v\n", result) } func ExampleAPI_series() { client, err := api.NewClient(api.Config{ Address: "http://demo.robustperception.io:9090", }) if err != nil { fmt.Printf("Error creating client: %v\n", err) os.Exit(1) } v1api := v1.NewAPI(client) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() lbls, warnings, err := v1api.Series(ctx, []string{ "{__name__=~\"scrape_.+\",job=\"node\"}", "{__name__=~\"scrape_.+\",job=\"prometheus\"}", }, time.Now().Add(-time.Hour), time.Now()) if err != nil { fmt.Printf("Error querying Prometheus: %v\n", err) os.Exit(1) } if len(warnings) > 0 { fmt.Printf("Warnings: %v\n", warnings) } fmt.Println("Result:") for _, lbl := range lbls { fmt.Println(lbl) } } client_golang-1.21.1/examples/000077500000000000000000000000001476160432400162265ustar00rootroot00000000000000client_golang-1.21.1/examples/createdtimestamps/000077500000000000000000000000001476160432400217445ustar00rootroot00000000000000client_golang-1.21.1/examples/createdtimestamps/main.go000066400000000000000000000033661476160432400232270ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // A simple example of how to exposed created timestamps in OpenMetrics format. package main import ( "log" "net/http" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) func main() { requestDurations := prometheus.NewHistogram(prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "A histogram of the HTTP request durations in seconds.", Buckets: prometheus.ExponentialBuckets(0.1, 1.5, 5), }) // Create non-global registry. registry := prometheus.NewRegistry() registry.MustRegister( requestDurations, ) go func() { for { // Record fictional latency. now := time.Now() requestDurations.Observe(time.Since(now).Seconds()) time.Sleep(600 * time.Millisecond) } }() // Expose /metrics HTTP endpoint using the created custom registry. http.Handle( "/metrics", promhttp.HandlerFor( registry, promhttp.HandlerOpts{ EnableOpenMetrics: true, EnableOpenMetricsTextCreatedSamples: true, }), ) // To test: curl -H 'Accept: application/openmetrics-text' localhost:8080/metrics log.Fatalln(http.ListenAndServe(":8080", nil)) } client_golang-1.21.1/examples/customlabels/000077500000000000000000000000001476160432400207235ustar00rootroot00000000000000client_golang-1.21.1/examples/customlabels/main.go000066400000000000000000000056501476160432400222040ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // A simple example of how to add fixed custom labels to all metrics exported by the origin collector. // For more details, see the documentation: https://pkg.go.dev/github.com/prometheus/client_golang/prometheus#WrapRegistererWith package main import ( "flag" "log" "net/http" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" ) var addr = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.") func main() { flag.Parse() // Create a new registry. reg := prometheus.NewRegistry() reg.MustRegister( collectors.NewGoCollector(), collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), ) // We should see the following metrics with an extra source label. But // other collectors registered above are expected not to have the extra // label. // See also https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels startFireKeeper(prometheus.WrapRegistererWith(prometheus.Labels{"component": "FireKeeper"}, reg)) startSparkForge(prometheus.WrapRegistererWith(prometheus.Labels{"component": "SparkForge"}, reg)) http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{})) log.Fatal(http.ListenAndServe(*addr, nil)) } func startFireKeeper(reg prometheus.Registerer) { firesMaintained := promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "fires_maintained_total", Help: "Total number of fires maintained", }) sparksDistributed := promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "sparks_distributed_total", Help: "Total number of sparks distributed", }) go func() { for { time.Sleep(5 * time.Second) firesMaintained.Inc() log.Println("FireKeeper maintained a fire") } }() go func() { for { time.Sleep(7 * time.Second) sparksDistributed.Inc() log.Println("FireKeeper distributed a spark") } }() } func startSparkForge(reg prometheus.Registerer) { itemsForged := promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "items_forged_total", Help: "Total number of items forged", }) go func() { for { time.Sleep(6 * time.Second) itemsForged.Inc() log.Println("SparkForge forged an item") } }() } client_golang-1.21.1/examples/exemplars/000077500000000000000000000000001476160432400202265ustar00rootroot00000000000000client_golang-1.21.1/examples/exemplars/main.go000066400000000000000000000040721476160432400215040ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // A simple example of how to record a latency metric with exemplars, using a fictional id // as a prometheus label. package main import ( "log" "math/rand" "net/http" "strconv" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" ) func main() { requestDurations := prometheus.NewHistogram(prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "A histogram of the HTTP request durations in seconds.", Buckets: prometheus.ExponentialBuckets(0.1, 1.5, 5), }) // Create non-global registry. registry := prometheus.NewRegistry() // Add go runtime metrics and process collectors. registry.MustRegister( collectors.NewGoCollector(), collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), requestDurations, ) go func() { for { // Record fictional latency. now := time.Now() requestDurations.(prometheus.ExemplarObserver).ObserveWithExemplar( time.Since(now).Seconds(), prometheus.Labels{"dummyID": strconv.Itoa(rand.Intn(100000))}, ) time.Sleep(600 * time.Millisecond) } }() // Expose /metrics HTTP endpoint using the created custom registry. http.Handle( "/metrics", promhttp.HandlerFor( registry, promhttp.HandlerOpts{ EnableOpenMetrics: true, }), ) // To test: curl -H 'Accept: application/openmetrics-text' localhost:8080/metrics log.Fatalln(http.ListenAndServe(":8080", nil)) } client_golang-1.21.1/examples/gocollector/000077500000000000000000000000001476160432400205425ustar00rootroot00000000000000client_golang-1.21.1/examples/gocollector/main.go000066400000000000000000000037231476160432400220220ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build go1.17 // +build go1.17 // A minimal example of how to include Prometheus instrumentation. package main import ( "flag" "fmt" "log" "net/http" "regexp" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" ) var addr = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.") func main() { flag.Parse() // Create a new registry. reg := prometheus.NewRegistry() // Register metrics from GoCollector collecting statistics from the Go Runtime. // This enabled default, recommended metrics with the additional, recommended metric for // goroutine scheduling latencies histogram that is currently bit too expensive for default option. // // See the related GopherConUK talk to learn more: https://www.youtube.com/watch?v=18dyI_8VFa0 reg.MustRegister( collectors.NewGoCollector( collectors.WithGoCollectorRuntimeMetrics( collectors.GoRuntimeMetricsRule{Matcher: regexp.MustCompile("/sched/latencies:seconds")}, ), ), ) // Expose the registered metrics via HTTP. http.Handle("/metrics", promhttp.HandlerFor( reg, promhttp.HandlerOpts{ // Opt into OpenMetrics to support exemplars. EnableOpenMetrics: true, }, )) fmt.Println("Hello world from new Go Collector!") log.Fatal(http.ListenAndServe(*addr, nil)) } client_golang-1.21.1/examples/middleware/000077500000000000000000000000001476160432400203435ustar00rootroot00000000000000client_golang-1.21.1/examples/middleware/httpmiddleware/000077500000000000000000000000001476160432400233605ustar00rootroot00000000000000client_golang-1.21.1/examples/middleware/httpmiddleware/httpmiddleware.go000066400000000000000000000061501476160432400267260ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package httpmiddleware is adapted from // https://github.com/bwplotka/correlator/tree/main/examples/observability/ping/pkg/httpinstrumentation package httpmiddleware import ( "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" ) type Middleware interface { // WrapHandler wraps the given HTTP handler for instrumentation. WrapHandler(handlerName string, handler http.Handler) http.HandlerFunc } type middleware struct { buckets []float64 registry prometheus.Registerer } // WrapHandler wraps the given HTTP handler for instrumentation: // It registers four metric collectors (if not already done) and reports HTTP // metrics to the (newly or already) registered collectors. // Each has a constant label named "handler" with the provided handlerName as // value. func (m *middleware) WrapHandler(handlerName string, handler http.Handler) http.HandlerFunc { reg := prometheus.WrapRegistererWith(prometheus.Labels{"handler": handlerName}, m.registry) requestsTotal := promauto.With(reg).NewCounterVec( prometheus.CounterOpts{ Name: "http_requests_total", Help: "Tracks the number of HTTP requests.", }, []string{"method", "code"}, ) requestDuration := promauto.With(reg).NewHistogramVec( prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "Tracks the latencies for HTTP requests.", Buckets: m.buckets, }, []string{"method", "code"}, ) requestSize := promauto.With(reg).NewSummaryVec( prometheus.SummaryOpts{ Name: "http_request_size_bytes", Help: "Tracks the size of HTTP requests.", }, []string{"method", "code"}, ) responseSize := promauto.With(reg).NewSummaryVec( prometheus.SummaryOpts{ Name: "http_response_size_bytes", Help: "Tracks the size of HTTP responses.", }, []string{"method", "code"}, ) // Wraps the provided http.Handler to observe the request result with the provided metrics. base := promhttp.InstrumentHandlerCounter( requestsTotal, promhttp.InstrumentHandlerDuration( requestDuration, promhttp.InstrumentHandlerRequestSize( requestSize, promhttp.InstrumentHandlerResponseSize( responseSize, handler, ), ), ), ) return base.ServeHTTP } // New returns a Middleware interface. func New(registry prometheus.Registerer, buckets []float64) Middleware { if buckets == nil { buckets = prometheus.ExponentialBuckets(0.1, 1.5, 5) } return &middleware{ buckets: buckets, registry: registry, } } client_golang-1.21.1/examples/middleware/main.go000066400000000000000000000027671476160432400216320ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Simple example of auto-instrumentation by using an HTTP Middleware with relevant metrics. package main import ( "log" "net/http" "github.com/prometheus/client_golang/examples/middleware/httpmiddleware" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" ) func main() { // Create non-global registry. registry := prometheus.NewRegistry() // Add go runtime metrics and process collectors. registry.MustRegister( collectors.NewGoCollector(), collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), ) // Expose /metrics HTTP endpoint using the created custom registry. http.Handle( "/metrics", httpmiddleware.New( registry, nil). WrapHandler("/metrics", promhttp.HandlerFor( registry, promhttp.HandlerOpts{}), )) log.Fatalln(http.ListenAndServe(":8080", nil)) } client_golang-1.21.1/examples/random/000077500000000000000000000000001476160432400175065ustar00rootroot00000000000000client_golang-1.21.1/examples/random/main.go000066400000000000000000000122171476160432400207640ustar00rootroot00000000000000// Copyright 2015 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // A simple example exposing fictional RPC latencies with different types of // random distributions (uniform, normal, and exponential) as Prometheus // metrics. package main import ( "flag" "log" "math" "math/rand" "net/http" "strconv" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" ) type metrics struct { rpcDurations *prometheus.SummaryVec rpcDurationsHistogram prometheus.Histogram } func NewMetrics(reg prometheus.Registerer, normMean, normDomain float64) *metrics { m := &metrics{ // Create a summary to track fictional inter service RPC latencies for three // distinct services with different latency distributions. These services are // differentiated via a "service" label. rpcDurations: prometheus.NewSummaryVec( prometheus.SummaryOpts{ Name: "rpc_durations_seconds", Help: "RPC latency distributions.", Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, }, []string{"service"}, ), // The same as above, but now as a histogram, and only for the // normal distribution. The histogram features both conventional // buckets as well as sparse buckets, the latter needed for the // experimental native histograms (ingested by a Prometheus // server v2.40 with the corresponding feature flag // enabled). The conventional buckets are targeted to the // parameters of the normal distribution, with 20 buckets // centered on the mean, each half-sigma wide. The sparse // buckets are always centered on zero, with a growth factor of // one bucket to the next of (at most) 1.1. (The precise factor // is 2^2^-3 = 1.0905077...) rpcDurationsHistogram: prometheus.NewHistogram(prometheus.HistogramOpts{ Name: "rpc_durations_histogram_seconds", Help: "RPC latency distributions.", Buckets: prometheus.LinearBuckets(normMean-5*normDomain, .5*normDomain, 20), NativeHistogramBucketFactor: 1.1, }), } reg.MustRegister(m.rpcDurations) reg.MustRegister(m.rpcDurationsHistogram) return m } func main() { var ( addr = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.") uniformDomain = flag.Float64("uniform.domain", 0.0002, "The domain for the uniform distribution.") normDomain = flag.Float64("normal.domain", 0.0002, "The domain for the normal distribution.") normMean = flag.Float64("normal.mean", 0.00001, "The mean for the normal distribution.") oscillationPeriod = flag.Duration("oscillation-period", 10*time.Minute, "The duration of the rate oscillation period.") ) flag.Parse() // Create a non-global registry. reg := prometheus.NewRegistry() // Create new metrics and register them using the custom registry. m := NewMetrics(reg, *normMean, *normDomain) // Add Go module build info. reg.MustRegister(collectors.NewBuildInfoCollector()) start := time.Now() oscillationFactor := func() float64 { return 2 + math.Sin(math.Sin(2*math.Pi*float64(time.Since(start))/float64(*oscillationPeriod))) } // Periodically record some sample latencies for the three services. go func() { for { v := rand.Float64() * *uniformDomain m.rpcDurations.WithLabelValues("uniform").Observe(v) time.Sleep(time.Duration(100*oscillationFactor()) * time.Millisecond) } }() go func() { for { v := (rand.NormFloat64() * *normDomain) + *normMean m.rpcDurations.WithLabelValues("normal").Observe(v) // Demonstrate exemplar support with a dummy ID. This // would be something like a trace ID in a real // application. Note the necessary type assertion. We // already know that rpcDurationsHistogram implements // the ExemplarObserver interface and thus don't need to // check the outcome of the type assertion. m.rpcDurationsHistogram.(prometheus.ExemplarObserver).ObserveWithExemplar( v, prometheus.Labels{"dummyID": strconv.Itoa(rand.Intn(100000))}, ) time.Sleep(time.Duration(75*oscillationFactor()) * time.Millisecond) } }() go func() { for { v := rand.ExpFloat64() / 1e6 m.rpcDurations.WithLabelValues("exponential").Observe(v) time.Sleep(time.Duration(50*oscillationFactor()) * time.Millisecond) } }() // Expose the registered metrics via HTTP. http.Handle("/metrics", promhttp.HandlerFor( reg, promhttp.HandlerOpts{ // Opt into OpenMetrics to support exemplars. EnableOpenMetrics: true, // Pass custom registry Registry: reg, }, )) log.Fatal(http.ListenAndServe(*addr, nil)) } client_golang-1.21.1/examples/simple/000077500000000000000000000000001476160432400175175ustar00rootroot00000000000000client_golang-1.21.1/examples/simple/main.go000066400000000000000000000026571476160432400210040ustar00rootroot00000000000000// Copyright 2015 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // A minimal example of how to include Prometheus instrumentation. package main import ( "flag" "log" "net/http" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) var addr = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.") func main() { flag.Parse() // Create non-global registry. reg := prometheus.NewRegistry() // Add go runtime metrics and process collectors. reg.MustRegister( collectors.NewGoCollector(), collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), ) // Expose /metrics HTTP endpoint using the created custom registry. http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg})) log.Fatal(http.ListenAndServe(*addr, nil)) } client_golang-1.21.1/examples/versioncollector/000077500000000000000000000000001476160432400216225ustar00rootroot00000000000000client_golang-1.21.1/examples/versioncollector/main.go000066400000000000000000000031061476160432400230750ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build go1.17 // +build go1.17 // A minimal example of how to include Prometheus instrumentation. package main import ( "flag" "fmt" "log" "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors/version" "github.com/prometheus/client_golang/prometheus/promhttp" ) var addr = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.") // Build using ldflags, for example: // go build -ldflags "-X github.com/prometheus/common/version.Version=1.0.0 -X github.com/prometheus/common/version.Branch=abc123" . func main() { flag.Parse() // Create a new registry. reg := prometheus.NewRegistry() // Register version collector. reg.MustRegister(version.NewCollector("example")) // Expose the registered metrics via HTTP. http.Handle("/metrics", promhttp.HandlerFor( reg, promhttp.HandlerOpts{}, )) fmt.Println("Hello world from new Version Collector!") log.Fatal(http.ListenAndServe(*addr, nil)) } client_golang-1.21.1/generate-go-collector.bash000066400000000000000000000004011476160432400214230ustar00rootroot00000000000000#!/bin/env bash set -e go get github.com/hashicorp/go-version@v1.6.0 go run prometheus/gen_go_collector_metrics_set.go mv -f go_collector_metrics_* prometheus go run prometheus/collectors/gen_go_collector_set.go mv -f go_collector_* prometheus/collectors client_golang-1.21.1/go.mod000066400000000000000000000020441476160432400155160ustar00rootroot00000000000000module github.com/prometheus/client_golang go 1.21 require ( github.com/beorn7/perks v1.0.1 github.com/cespare/xxhash/v2 v2.3.0 github.com/google/go-cmp v0.6.0 github.com/json-iterator/go v1.1.12 github.com/klauspost/compress v1.17.11 github.com/kylelemons/godebug v1.1.0 github.com/prometheus/client_model v0.6.1 github.com/prometheus/common v0.62.0 github.com/prometheus/procfs v0.15.1 golang.org/x/sys v0.28.0 google.golang.org/protobuf v1.36.1 ) require ( github.com/jpillora/backoff v1.0.0 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect golang.org/x/net v0.33.0 // indirect golang.org/x/oauth2 v0.24.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) exclude github.com/prometheus/client_golang v1.12.1 client_golang-1.21.1/go.sum000066400000000000000000000133071476160432400155470ustar00rootroot00000000000000github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.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/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 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/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= client_golang-1.21.1/internal/000077500000000000000000000000001476160432400162245ustar00rootroot00000000000000client_golang-1.21.1/internal/github.com/000077500000000000000000000000001476160432400202635ustar00rootroot00000000000000client_golang-1.21.1/internal/github.com/golang/000077500000000000000000000000001476160432400215325ustar00rootroot00000000000000client_golang-1.21.1/internal/github.com/golang/gddo/000077500000000000000000000000001476160432400224475ustar00rootroot00000000000000client_golang-1.21.1/internal/github.com/golang/gddo/LICENSE000066400000000000000000000027071476160432400234620ustar00rootroot00000000000000Copyright (c) 2013 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. client_golang-1.21.1/internal/github.com/golang/gddo/README.md000066400000000000000000000002001476160432400237160ustar00rootroot00000000000000This source code is a stripped down version from the archived repository https://github.com/golang/gddo and licensed under BSD. client_golang-1.21.1/internal/github.com/golang/gddo/httputil/000077500000000000000000000000001476160432400243245ustar00rootroot00000000000000client_golang-1.21.1/internal/github.com/golang/gddo/httputil/header/000077500000000000000000000000001476160432400255545ustar00rootroot00000000000000client_golang-1.21.1/internal/github.com/golang/gddo/httputil/header/header.go000066400000000000000000000061141476160432400273350ustar00rootroot00000000000000// Copyright 2013 The Go Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd. // Package header provides functions for parsing HTTP headers. package header import ( "net/http" "strings" ) // Octet types from RFC 2616. var octetTypes [256]octetType type octetType byte const ( isToken octetType = 1 << iota isSpace ) func init() { // OCTET = // CHAR = // CTL = // CR = // LF = // SP = // HT = // <"> = // CRLF = CR LF // LWS = [CRLF] 1*( SP | HT ) // TEXT = // separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> // | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT // token = 1* // qdtext = > for c := 0; c < 256; c++ { var t octetType isCtl := c <= 31 || c == 127 isChar := 0 <= c && c <= 127 isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) if strings.ContainsRune(" \t\r\n", rune(c)) { t |= isSpace } if isChar && !isCtl && !isSeparator { t |= isToken } octetTypes[c] = t } } // AcceptSpec describes an Accept* header. type AcceptSpec struct { Value string Q float64 } // ParseAccept parses Accept* headers. func ParseAccept(header http.Header, key string) (specs []AcceptSpec) { loop: for _, s := range header[key] { for { var spec AcceptSpec spec.Value, s = expectTokenSlash(s) if spec.Value == "" { continue loop } spec.Q = 1.0 s = skipSpace(s) if strings.HasPrefix(s, ";") { s = skipSpace(s[1:]) if !strings.HasPrefix(s, "q=") { continue loop } spec.Q, s = expectQuality(s[2:]) if spec.Q < 0.0 { continue loop } } specs = append(specs, spec) s = skipSpace(s) if !strings.HasPrefix(s, ",") { continue loop } s = skipSpace(s[1:]) } } return } func skipSpace(s string) (rest string) { i := 0 for ; i < len(s); i++ { if octetTypes[s[i]]&isSpace == 0 { break } } return s[i:] } func expectTokenSlash(s string) (token, rest string) { i := 0 for ; i < len(s); i++ { b := s[i] if (octetTypes[b]&isToken == 0) && b != '/' { break } } return s[:i], s[i:] } func expectQuality(s string) (q float64, rest string) { switch { case len(s) == 0: return -1, "" case s[0] == '0': q = 0 case s[0] == '1': q = 1 default: return -1, "" } s = s[1:] if !strings.HasPrefix(s, ".") { return q, s } s = s[1:] i := 0 n := 0 d := 1 for ; i < len(s); i++ { b := s[i] if b < '0' || b > '9' { break } n = n*10 + int(b) - '0' d *= 10 } return q + float64(n)/float64(d), s[i:] } client_golang-1.21.1/internal/github.com/golang/gddo/httputil/header/header_test.go000066400000000000000000000033611476160432400303750ustar00rootroot00000000000000// Copyright 2013 The Go Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd. package header import ( "net/http" "testing" "github.com/google/go-cmp/cmp" ) var parseAcceptTests = []struct { s string expected []AcceptSpec }{ {"text/html", []AcceptSpec{{"text/html", 1}}}, {"text/html; q=0", []AcceptSpec{{"text/html", 0}}}, {"text/html; q=0.0", []AcceptSpec{{"text/html", 0}}}, {"text/html; q=1", []AcceptSpec{{"text/html", 1}}}, {"text/html; q=1.0", []AcceptSpec{{"text/html", 1}}}, {"text/html; q=0.1", []AcceptSpec{{"text/html", 0.1}}}, {"text/html;q=0.1", []AcceptSpec{{"text/html", 0.1}}}, {"text/html, text/plain", []AcceptSpec{{"text/html", 1}, {"text/plain", 1}}}, {"text/html; q=0.1, text/plain", []AcceptSpec{{"text/html", 0.1}, {"text/plain", 1}}}, {"iso-8859-5, unicode-1-1;q=0.8,iso-8859-1", []AcceptSpec{{"iso-8859-5", 1}, {"unicode-1-1", 0.8}, {"iso-8859-1", 1}}}, {"iso-8859-1", []AcceptSpec{{"iso-8859-1", 1}}}, {"*", []AcceptSpec{{"*", 1}}}, {"da, en-gb;q=0.8, en;q=0.7", []AcceptSpec{{"da", 1}, {"en-gb", 0.8}, {"en", 0.7}}}, {"da, q, en-gb;q=0.8", []AcceptSpec{{"da", 1}, {"q", 1}, {"en-gb", 0.8}}}, {"image/png, image/*;q=0.5", []AcceptSpec{{"image/png", 1}, {"image/*", 0.5}}}, // bad cases {"value1; q=0.1.2", []AcceptSpec{{"value1", 0.1}}}, {"da, en-gb;q=foo", []AcceptSpec{{"da", 1}}}, } func TestParseAccept(t *testing.T) { for _, tt := range parseAcceptTests { header := http.Header{"Accept": {tt.s}} actual := ParseAccept(header, "Accept") if !cmp.Equal(actual, tt.expected) { t.Errorf("ParseAccept(h, %q)=%v, want %v", tt.s, actual, tt.expected) } } } client_golang-1.21.1/internal/github.com/golang/gddo/httputil/negotiate.go000066400000000000000000000020141476160432400266270ustar00rootroot00000000000000// Copyright 2013 The Go Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd. package httputil import ( "net/http" "github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header" ) // NegotiateContentEncoding returns the best offered content encoding for the // request's Accept-Encoding header. If two offers match with equal weight and // then the offer earlier in the list is preferred. If no offers are // acceptable, then "" is returned. func NegotiateContentEncoding(r *http.Request, offers []string) string { bestOffer := "identity" bestQ := -1.0 specs := header.ParseAccept(r.Header, "Accept-Encoding") for _, offer := range offers { for _, spec := range specs { if spec.Q > bestQ && (spec.Value == "*" || spec.Value == offer) { bestQ = spec.Q bestOffer = offer } } } if bestQ == 0 { bestOffer = "" } return bestOffer } client_golang-1.21.1/internal/github.com/golang/gddo/httputil/negotiate_test.go000066400000000000000000000025201476160432400276700ustar00rootroot00000000000000// Copyright 2013 The Go Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd. package httputil import ( "net/http" "testing" ) var negotiateContentEncodingTests = []struct { s string offers []string expect string }{ {"", []string{"identity", "gzip"}, "identity"}, {"*;q=0", []string{"identity", "gzip"}, ""}, {"gzip", []string{"identity", "gzip"}, "gzip"}, {"gzip,zstd", []string{"identity", "zstd"}, "zstd"}, {"zstd,gzip", []string{"gzip", "zstd"}, "gzip"}, {"gzip,zstd", []string{"gzip", "zstd"}, "gzip"}, {"gzip,zstd", []string{"zstd", "gzip"}, "zstd"}, {"gzip;q=0.1,zstd;q=0.5", []string{"gzip", "zstd"}, "zstd"}, {"gzip;q=1.0, identity; q=0.5, *;q=0", []string{"identity", "gzip"}, "gzip"}, {"gzip;q=1.0, identity; q=0.5, *;q=0", []string{"identity", "zstd"}, "identity"}, {"zstd", []string{"identity", "gzip"}, "identity"}, } func TestNegotiateContentEncoding(t *testing.T) { for _, tt := range negotiateContentEncodingTests { r := &http.Request{Header: http.Header{"Accept-Encoding": {tt.s}}} actual := NegotiateContentEncoding(r, tt.offers) if actual != tt.expect { t.Errorf("NegotiateContentEncoding(%q, %#v)=%q, want %q", tt.s, tt.offers, actual, tt.expect) } } } client_golang-1.21.1/prometheus/000077500000000000000000000000001476160432400166035ustar00rootroot00000000000000client_golang-1.21.1/prometheus/.gitignore000066400000000000000000000000341476160432400205700ustar00rootroot00000000000000command-line-arguments.test client_golang-1.21.1/prometheus/README.md000066400000000000000000000002471476160432400200650ustar00rootroot00000000000000See [![Go Reference](https://pkg.go.dev/badge/github.com/prometheus/client_golang/prometheus.svg)](https://pkg.go.dev/github.com/prometheus/client_golang/prometheus). client_golang-1.21.1/prometheus/benchmark_test.go000066400000000000000000000145441476160432400221330ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "sync" "testing" ) func BenchmarkCounter(b *testing.B) { type fns []func(*CounterVec) Counter twoConstraint := func(_ string) string { return "two" } deLV := func(m *CounterVec) Counter { return m.WithLabelValues("eins", "zwei", "drei") } frLV := func(m *CounterVec) Counter { return m.WithLabelValues("une", "deux", "trois") } nlLV := func(m *CounterVec) Counter { return m.WithLabelValues("een", "twee", "drie") } deML := func(m *CounterVec) Counter { return m.With(Labels{"two": "zwei", "one": "eins", "three": "drei"}) } frML := func(m *CounterVec) Counter { return m.With(Labels{"two": "deux", "one": "une", "three": "trois"}) } nlML := func(m *CounterVec) Counter { return m.With(Labels{"two": "twee", "one": "een", "three": "drie"}) } deLabels := Labels{"two": "zwei", "one": "eins", "three": "drei"} dePML := func(m *CounterVec) Counter { return m.With(deLabels) } frLabels := Labels{"two": "deux", "one": "une", "three": "trois"} frPML := func(m *CounterVec) Counter { return m.With(frLabels) } nlLabels := Labels{"two": "twee", "one": "een", "three": "drie"} nlPML := func(m *CounterVec) Counter { return m.With(nlLabels) } table := []struct { name string constraint LabelConstraint counters fns }{ {"With Label Values", nil, fns{deLV}}, {"With Label Values and Constraint", twoConstraint, fns{deLV}}, {"With triple Label Values", nil, fns{deLV, frLV, nlLV}}, {"With triple Label Values and Constraint", twoConstraint, fns{deLV, frLV, nlLV}}, {"With repeated Label Values", nil, fns{deLV, deLV}}, {"With repeated Label Values and Constraint", twoConstraint, fns{deLV, deLV}}, {"With Mapped Labels", nil, fns{deML}}, {"With Mapped Labels and Constraint", twoConstraint, fns{deML}}, {"With triple Mapped Labels", nil, fns{deML, frML, nlML}}, {"With triple Mapped Labels and Constraint", twoConstraint, fns{deML, frML, nlML}}, {"With repeated Mapped Labels", nil, fns{deML, deML}}, {"With repeated Mapped Labels and Constraint", twoConstraint, fns{deML, deML}}, {"With Prepared Mapped Labels", nil, fns{dePML}}, {"With Prepared Mapped Labels and Constraint", twoConstraint, fns{dePML}}, {"With triple Prepared Mapped Labels", nil, fns{dePML, frPML, nlPML}}, {"With triple Prepared Mapped Labels and Constraint", twoConstraint, fns{dePML, frPML, nlPML}}, {"With repeated Prepared Mapped Labels", nil, fns{dePML, dePML}}, {"With repeated Prepared Mapped Labels and Constraint", twoConstraint, fns{dePML, dePML}}, } for _, t := range table { b.Run(t.name, func(b *testing.B) { m := V2.NewCounterVec( CounterVecOpts{ CounterOpts: CounterOpts{ Name: "benchmark_counter", Help: "A counter to benchmark it.", }, VariableLabels: ConstrainedLabels{ ConstrainedLabel{Name: "one"}, ConstrainedLabel{Name: "two", Constraint: t.constraint}, ConstrainedLabel{Name: "three"}, }, }, ) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { for _, fn := range t.counters { fn(m).Inc() } } }) } } func BenchmarkCounterWithLabelValuesConcurrent(b *testing.B) { m := NewCounterVec( CounterOpts{ Name: "benchmark_counter", Help: "A counter to benchmark it.", }, []string{"one", "two", "three"}, ) b.ReportAllocs() b.ResetTimer() wg := sync.WaitGroup{} for i := 0; i < 10; i++ { wg.Add(1) go func() { for j := 0; j < b.N/10; j++ { m.WithLabelValues("eins", "zwei", "drei").Inc() } wg.Done() }() } wg.Wait() } func BenchmarkCounterNoLabels(b *testing.B) { m := NewCounter(CounterOpts{ Name: "benchmark_counter", Help: "A counter to benchmark it.", }) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { m.Inc() } } func BenchmarkGaugeWithLabelValues(b *testing.B) { m := NewGaugeVec( GaugeOpts{ Name: "benchmark_gauge", Help: "A gauge to benchmark it.", }, []string{"one", "two", "three"}, ) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { m.WithLabelValues("eins", "zwei", "drei").Set(3.1415) } } func BenchmarkGaugeNoLabels(b *testing.B) { m := NewGauge(GaugeOpts{ Name: "benchmark_gauge", Help: "A gauge to benchmark it.", }) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { m.Set(3.1415) } } func BenchmarkSummaryWithLabelValues(b *testing.B) { m := NewSummaryVec( SummaryOpts{ Name: "benchmark_summary", Help: "A summary to benchmark it.", Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, }, []string{"one", "two", "three"}, ) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { m.WithLabelValues("eins", "zwei", "drei").Observe(3.1415) } } func BenchmarkSummaryNoLabels(b *testing.B) { m := NewSummary(SummaryOpts{ Name: "benchmark_summary", Help: "A summary to benchmark it.", Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, }, ) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { m.Observe(3.1415) } } func BenchmarkHistogramWithLabelValues(b *testing.B) { m := NewHistogramVec( HistogramOpts{ Name: "benchmark_histogram", Help: "A histogram to benchmark it.", }, []string{"one", "two", "three"}, ) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { m.WithLabelValues("eins", "zwei", "drei").Observe(3.1415) } } func BenchmarkHistogramNoLabels(b *testing.B) { m := NewHistogram(HistogramOpts{ Name: "benchmark_histogram", Help: "A histogram to benchmark it.", }, ) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { m.Observe(3.1415) } } func BenchmarkParallelCounter(b *testing.B) { c := NewCounter(CounterOpts{ Name: "benchmark_counter", Help: "A Counter to benchmark it.", }) b.ReportAllocs() b.ResetTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { c.Inc() } }) } client_golang-1.21.1/prometheus/build_info_collector.go000066400000000000000000000023661476160432400233210ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import "runtime/debug" // NewBuildInfoCollector is the obsolete version of collectors.NewBuildInfoCollector. // See there for documentation. // // Deprecated: Use collectors.NewBuildInfoCollector instead. func NewBuildInfoCollector() Collector { path, version, sum := "unknown", "unknown", "unknown" if bi, ok := debug.ReadBuildInfo(); ok { path = bi.Main.Path version = bi.Main.Version sum = bi.Main.Sum } c := &selfCollector{MustNewConstMetric( NewDesc( "go_build_info", "Build information about the main Go module.", nil, Labels{"path": path, "version": version, "checksum": sum}, ), GaugeValue, 1)} c.init(c.self) return c } client_golang-1.21.1/prometheus/collector.go000066400000000000000000000126131476160432400211230ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus // Collector is the interface implemented by anything that can be used by // Prometheus to collect metrics. A Collector has to be registered for // collection. See Registerer.Register. // // The stock metrics provided by this package (Gauge, Counter, Summary, // Histogram, Untyped) are also Collectors (which only ever collect one metric, // namely itself). An implementer of Collector may, however, collect multiple // metrics in a coordinated fashion and/or create metrics on the fly. Examples // for collectors already implemented in this library are the metric vectors // (i.e. collection of multiple instances of the same Metric but with different // label values) like GaugeVec or SummaryVec, and the ExpvarCollector. type Collector interface { // Describe sends the super-set of all possible descriptors of metrics // collected by this Collector to the provided channel and returns once // the last descriptor has been sent. The sent descriptors fulfill the // consistency and uniqueness requirements described in the Desc // documentation. // // It is valid if one and the same Collector sends duplicate // descriptors. Those duplicates are simply ignored. However, two // different Collectors must not send duplicate descriptors. // // Sending no descriptor at all marks the Collector as β€œunchecked”, // i.e. no checks will be performed at registration time, and the // Collector may yield any Metric it sees fit in its Collect method. // // This method idempotently sends the same descriptors throughout the // lifetime of the Collector. It may be called concurrently and // therefore must be implemented in a concurrency safe way. // // If a Collector encounters an error while executing this method, it // must send an invalid descriptor (created with NewInvalidDesc) to // signal the error to the registry. Describe(chan<- *Desc) // Collect is called by the Prometheus registry when collecting // metrics. The implementation sends each collected metric via the // provided channel and returns once the last metric has been sent. The // descriptor of each sent metric is one of those returned by Describe // (unless the Collector is unchecked, see above). Returned metrics that // share the same descriptor must differ in their variable label // values. // // This method may be called concurrently and must therefore be // implemented in a concurrency safe way. Blocking occurs at the expense // of total performance of rendering all registered metrics. Ideally, // Collector implementations support concurrent readers. Collect(chan<- Metric) } // DescribeByCollect is a helper to implement the Describe method of a custom // Collector. It collects the metrics from the provided Collector and sends // their descriptors to the provided channel. // // If a Collector collects the same metrics throughout its lifetime, its // Describe method can simply be implemented as: // // func (c customCollector) Describe(ch chan<- *Desc) { // DescribeByCollect(c, ch) // } // // However, this will not work if the metrics collected change dynamically over // the lifetime of the Collector in a way that their combined set of descriptors // changes as well. The shortcut implementation will then violate the contract // of the Describe method. If a Collector sometimes collects no metrics at all // (for example vectors like CounterVec, GaugeVec, etc., which only collect // metrics after a metric with a fully specified label set has been accessed), // it might even get registered as an unchecked Collector (cf. the Register // method of the Registerer interface). Hence, only use this shortcut // implementation of Describe if you are certain to fulfill the contract. // // The Collector example demonstrates a use of DescribeByCollect. func DescribeByCollect(c Collector, descs chan<- *Desc) { metrics := make(chan Metric) go func() { c.Collect(metrics) close(metrics) }() for m := range metrics { descs <- m.Desc() } } // selfCollector implements Collector for a single Metric so that the Metric // collects itself. Add it as an anonymous field to a struct that implements // Metric, and call init with the Metric itself as an argument. type selfCollector struct { self Metric } // init provides the selfCollector with a reference to the metric it is supposed // to collect. It is usually called within the factory function to create a // metric. See example. func (c *selfCollector) init(self Metric) { c.self = self } // Describe implements Collector. func (c *selfCollector) Describe(ch chan<- *Desc) { ch <- c.self.Desc() } // Collect implements Collector. func (c *selfCollector) Collect(ch chan<- Metric) { ch <- c.self } // collectorMetric is a metric that is also a collector. // Because of selfCollector, most (if not all) Metrics in // this package are also collectors. type collectorMetric interface { Metric Collector } client_golang-1.21.1/prometheus/collector_test.go000066400000000000000000000035431476160432400221640ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import "testing" type collectorDescribedByCollect struct { cnt Counter gge Gauge } func (c collectorDescribedByCollect) Collect(ch chan<- Metric) { ch <- c.cnt ch <- c.gge } func (c collectorDescribedByCollect) Describe(ch chan<- *Desc) { DescribeByCollect(c, ch) } func TestDescribeByCollect(t *testing.T) { goodCollector := collectorDescribedByCollect{ cnt: NewCounter(CounterOpts{Name: "c1", Help: "help c1"}), gge: NewGauge(GaugeOpts{Name: "g1", Help: "help g1"}), } collidingCollector := collectorDescribedByCollect{ cnt: NewCounter(CounterOpts{Name: "c2", Help: "help c2"}), gge: NewGauge(GaugeOpts{Name: "g1", Help: "help g1"}), } inconsistentCollector := collectorDescribedByCollect{ cnt: NewCounter(CounterOpts{Name: "c3", Help: "help c3"}), gge: NewGauge(GaugeOpts{Name: "c3", Help: "help inconsistent"}), } reg := NewPedanticRegistry() if err := reg.Register(goodCollector); err != nil { t.Error("registration failed:", err) } if err := reg.Register(collidingCollector); err == nil { t.Error("registration unexpectedly succeeded") } if err := reg.Register(inconsistentCollector); err == nil { t.Error("registration unexpectedly succeeded") } if _, err := reg.Gather(); err != nil { t.Error("gathering failed:", err) } } client_golang-1.21.1/prometheus/collectors/000077500000000000000000000000001476160432400207545ustar00rootroot00000000000000client_golang-1.21.1/prometheus/collectors/collectors.go000066400000000000000000000040041476160432400234520ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package collectors provides implementations of prometheus.Collector to // conveniently collect process and Go-related metrics. package collectors import "github.com/prometheus/client_golang/prometheus" // NewBuildInfoCollector returns a collector collecting a single metric // "go_build_info" with the constant value 1 and three labels "path", "version", // and "checksum". Their label values contain the main module path, version, and // checksum, respectively. The labels will only have meaningful values if the // binary is built with Go module support and from source code retrieved from // the source repository (rather than the local file system). This is usually // accomplished by building from outside of GOPATH, specifying the full address // of the main package, e.g. "GO111MODULE=on go run // github.com/prometheus/client_golang/examples/random". If built without Go // module support, all label values will be "unknown". If built with Go module // support but using the source code from the local file system, the "path" will // be set appropriately, but "checksum" will be empty and "version" will be // "(devel)". // // This collector uses only the build information for the main module. See // https://github.com/povilasv/prommod for an example of a collector for the // module dependencies. func NewBuildInfoCollector() prometheus.Collector { //nolint:staticcheck // Ignore SA1019 until v2. return prometheus.NewBuildInfoCollector() } client_golang-1.21.1/prometheus/collectors/dbstats_collector.go000066400000000000000000000106401476160432400250160ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package collectors import ( "database/sql" "github.com/prometheus/client_golang/prometheus" ) type dbStatsCollector struct { db *sql.DB maxOpenConnections *prometheus.Desc openConnections *prometheus.Desc inUseConnections *prometheus.Desc idleConnections *prometheus.Desc waitCount *prometheus.Desc waitDuration *prometheus.Desc maxIdleClosed *prometheus.Desc maxIdleTimeClosed *prometheus.Desc maxLifetimeClosed *prometheus.Desc } // NewDBStatsCollector returns a collector that exports metrics about the given *sql.DB. // See https://golang.org/pkg/database/sql/#DBStats for more information on stats. func NewDBStatsCollector(db *sql.DB, dbName string) prometheus.Collector { fqName := func(name string) string { return "go_sql_" + name } return &dbStatsCollector{ db: db, maxOpenConnections: prometheus.NewDesc( fqName("max_open_connections"), "Maximum number of open connections to the database.", nil, prometheus.Labels{"db_name": dbName}, ), openConnections: prometheus.NewDesc( fqName("open_connections"), "The number of established connections both in use and idle.", nil, prometheus.Labels{"db_name": dbName}, ), inUseConnections: prometheus.NewDesc( fqName("in_use_connections"), "The number of connections currently in use.", nil, prometheus.Labels{"db_name": dbName}, ), idleConnections: prometheus.NewDesc( fqName("idle_connections"), "The number of idle connections.", nil, prometheus.Labels{"db_name": dbName}, ), waitCount: prometheus.NewDesc( fqName("wait_count_total"), "The total number of connections waited for.", nil, prometheus.Labels{"db_name": dbName}, ), waitDuration: prometheus.NewDesc( fqName("wait_duration_seconds_total"), "The total time blocked waiting for a new connection.", nil, prometheus.Labels{"db_name": dbName}, ), maxIdleClosed: prometheus.NewDesc( fqName("max_idle_closed_total"), "The total number of connections closed due to SetMaxIdleConns.", nil, prometheus.Labels{"db_name": dbName}, ), maxIdleTimeClosed: prometheus.NewDesc( fqName("max_idle_time_closed_total"), "The total number of connections closed due to SetConnMaxIdleTime.", nil, prometheus.Labels{"db_name": dbName}, ), maxLifetimeClosed: prometheus.NewDesc( fqName("max_lifetime_closed_total"), "The total number of connections closed due to SetConnMaxLifetime.", nil, prometheus.Labels{"db_name": dbName}, ), } } // Describe implements Collector. func (c *dbStatsCollector) Describe(ch chan<- *prometheus.Desc) { ch <- c.maxOpenConnections ch <- c.openConnections ch <- c.inUseConnections ch <- c.idleConnections ch <- c.waitCount ch <- c.waitDuration ch <- c.maxIdleClosed ch <- c.maxLifetimeClosed ch <- c.maxIdleTimeClosed } // Collect implements Collector. func (c *dbStatsCollector) Collect(ch chan<- prometheus.Metric) { stats := c.db.Stats() ch <- prometheus.MustNewConstMetric(c.maxOpenConnections, prometheus.GaugeValue, float64(stats.MaxOpenConnections)) ch <- prometheus.MustNewConstMetric(c.openConnections, prometheus.GaugeValue, float64(stats.OpenConnections)) ch <- prometheus.MustNewConstMetric(c.inUseConnections, prometheus.GaugeValue, float64(stats.InUse)) ch <- prometheus.MustNewConstMetric(c.idleConnections, prometheus.GaugeValue, float64(stats.Idle)) ch <- prometheus.MustNewConstMetric(c.waitCount, prometheus.CounterValue, float64(stats.WaitCount)) ch <- prometheus.MustNewConstMetric(c.waitDuration, prometheus.CounterValue, stats.WaitDuration.Seconds()) ch <- prometheus.MustNewConstMetric(c.maxIdleClosed, prometheus.CounterValue, float64(stats.MaxIdleClosed)) ch <- prometheus.MustNewConstMetric(c.maxLifetimeClosed, prometheus.CounterValue, float64(stats.MaxLifetimeClosed)) ch <- prometheus.MustNewConstMetric(c.maxIdleTimeClosed, prometheus.CounterValue, float64(stats.MaxIdleTimeClosed)) } client_golang-1.21.1/prometheus/collectors/dbstats_collector_test.go000066400000000000000000000046171476160432400260640ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package collectors import ( "database/sql" "testing" "github.com/prometheus/client_golang/prometheus" ) func TestDBStatsCollector(t *testing.T) { reg := prometheus.NewPedanticRegistry() { db := new(sql.DB) if err := reg.Register(NewDBStatsCollector(db, "db_A")); err != nil { t.Fatal(err) } } { db := new(sql.DB) if err := reg.Register(NewDBStatsCollector(db, "db_B")); err != nil { t.Fatal(err) } } mfs, err := reg.Gather() if err != nil { t.Fatal(err) } names := []string{ "go_sql_max_open_connections", "go_sql_open_connections", "go_sql_in_use_connections", "go_sql_idle_connections", "go_sql_wait_count_total", "go_sql_wait_duration_seconds_total", "go_sql_max_idle_closed_total", "go_sql_max_lifetime_closed_total", "go_sql_max_idle_time_closed_total", } type result struct { found bool } results := make(map[string]result) for _, name := range names { results[name] = result{found: false} } for _, mf := range mfs { m := mf.GetMetric() if len(m) != 2 { t.Errorf("expected 2 metrics bug got %d", len(m)) } labelA := m[0].GetLabel()[0] if name := labelA.GetName(); name != "db_name" { t.Errorf("expected to get label \"db_name\" but got %s", name) } if value := labelA.GetValue(); value != "db_A" { t.Errorf("expected to get value \"db_A\" but got %s", value) } labelB := m[1].GetLabel()[0] if name := labelB.GetName(); name != "db_name" { t.Errorf("expected to get label \"db_name\" but got %s", name) } if value := labelB.GetValue(); value != "db_B" { t.Errorf("expected to get value \"db_B\" but got %s", value) } for _, name := range names { if name == mf.GetName() { results[name] = result{found: true} break } } } for name, result := range results { if !result.found { t.Errorf("%s not found", name) } } } client_golang-1.21.1/prometheus/collectors/expvar_collector.go000066400000000000000000000054361476160432400246660ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package collectors import "github.com/prometheus/client_golang/prometheus" // NewExpvarCollector returns a newly allocated expvar Collector. // // An expvar Collector collects metrics from the expvar interface. It provides a // quick way to expose numeric values that are already exported via expvar as // Prometheus metrics. Note that the data models of expvar and Prometheus are // fundamentally different, and that the expvar Collector is inherently slower // than native Prometheus metrics. Thus, the expvar Collector is probably great // for experiments and prototyping, but you should seriously consider a more // direct implementation of Prometheus metrics for monitoring production // systems. // // The exports map has the following meaning: // // The keys in the map correspond to expvar keys, i.e. for every expvar key you // want to export as Prometheus metric, you need an entry in the exports // map. The descriptor mapped to each key describes how to export the expvar // value. It defines the name and the help string of the Prometheus metric // proxying the expvar value. The type will always be Untyped. // // For descriptors without variable labels, the expvar value must be a number or // a bool. The number is then directly exported as the Prometheus sample // value. (For a bool, 'false' translates to 0 and 'true' to 1). Expvar values // that are not numbers or bools are silently ignored. // // If the descriptor has one variable label, the expvar value must be an expvar // map. The keys in the expvar map become the various values of the one // Prometheus label. The values in the expvar map must be numbers or bools again // as above. // // For descriptors with more than one variable label, the expvar must be a // nested expvar map, i.e. where the values of the topmost map are maps again // etc. until a depth is reached that corresponds to the number of labels. The // leaves of that structure must be numbers or bools as above to serve as the // sample values. // // Anything that does not fit into the scheme above is silently ignored. func NewExpvarCollector(exports map[string]*prometheus.Desc) prometheus.Collector { //nolint:staticcheck // Ignore SA1019 until v2. return prometheus.NewExpvarCollector(exports) } client_golang-1.21.1/prometheus/collectors/gen_go_collector_set.go000066400000000000000000000147051476160432400254710ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build ignore // +build ignore package main import ( "bytes" "fmt" "go/format" "log" "os" "regexp" "runtime" "runtime/metrics" "sort" "strings" "text/template" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/internal" version "github.com/hashicorp/go-version" ) type metricGroup struct { Name string Regex *regexp.Regexp Metrics []string } var metricGroups = []metricGroup{ {"withAllMetrics", nil, nil}, {"withGCMetrics", regexp.MustCompile("^go_gc_.*"), nil}, {"withMemoryMetrics", regexp.MustCompile("^go_memory_classes_.*"), nil}, {"withSchedulerMetrics", regexp.MustCompile("^go_sched_.*"), nil}, {"withDebugMetrics", regexp.MustCompile("^go_godebug_non_default_behavior_.*"), nil}, } func main() { var givenVersion string toolVersion := runtime.Version() if len(os.Args) != 2 { log.Printf("requires Go version (e.g. go1.17) as an argument. Since it is not specified, assuming %s.", toolVersion) givenVersion = toolVersion } else { givenVersion = os.Args[1] } log.Printf("given version for Go: %s", givenVersion) log.Printf("tool version for Go: %s", toolVersion) tv, err := version.NewVersion(strings.TrimPrefix(givenVersion, "go")) if err != nil { log.Fatal(err) } toolVersion = strings.Split(strings.TrimPrefix(toolVersion, "go"), " ")[0] gv, err := version.NewVersion(toolVersion) if err != nil { log.Fatal(err) } if !gv.Equal(tv) { log.Fatalf("using Go version %q but expected Go version %q", tv, gv) } v := goVersion(gv.Segments()[1]) log.Printf("generating metrics for Go version %q", v) descriptions := computeMetricsList(metrics.All()) groupedMetrics := groupMetrics(descriptions) // Find default metrics. var defaultRuntimeDesc []metrics.Description for _, d := range metrics.All() { if !internal.GoCollectorDefaultRuntimeMetrics.MatchString(d.Name) { continue } defaultRuntimeDesc = append(defaultRuntimeDesc, d) } defaultRuntimeMetricsList := computeMetricsList(defaultRuntimeDesc) onlyGCDefRuntimeMetricsList := []string{} onlySchedDefRuntimeMetricsList := []string{} for _, m := range defaultRuntimeMetricsList { if strings.HasPrefix(m, "go_gc") { onlyGCDefRuntimeMetricsList = append(onlyGCDefRuntimeMetricsList, m) } if strings.HasPrefix(m, "go_sched") { onlySchedDefRuntimeMetricsList = append(onlySchedDefRuntimeMetricsList, m) } else { continue } } // Generate code. var buf bytes.Buffer err = testFile.Execute(&buf, struct { GoVersion goVersion Groups []metricGroup DefaultRuntimeMetricsList []string OnlyGCDefRuntimeMetricsList []string OnlySchedDefRuntimeMetricsList []string }{ GoVersion: v, Groups: groupedMetrics, DefaultRuntimeMetricsList: defaultRuntimeMetricsList, OnlyGCDefRuntimeMetricsList: onlyGCDefRuntimeMetricsList, OnlySchedDefRuntimeMetricsList: onlySchedDefRuntimeMetricsList, }) if err != nil { log.Fatalf("executing template: %v", err) } // Format it. result, err := format.Source(buf.Bytes()) if err != nil { log.Fatalf("formatting code: %v", err) } // Write it to a file. fname := fmt.Sprintf("go_collector_%s_test.go", v.Abbr()) if err := os.WriteFile(fname, result, 0o644); err != nil { log.Fatalf("writing file: %v", err) } } func computeMetricsList(descs []metrics.Description) []string { var metricsList []string for _, d := range descs { if trans := rm2prom(d); trans != "" { metricsList = append(metricsList, trans) } } return metricsList } func rm2prom(d metrics.Description) string { ns, ss, n, ok := internal.RuntimeMetricsToProm(&d) if !ok { return "" } return prometheus.BuildFQName(ns, ss, n) } func groupMetrics(metricsList []string) []metricGroup { var groupedMetrics []metricGroup for _, group := range metricGroups { matchedMetrics := make([]string, 0) for _, metric := range metricsList { if group.Regex == nil || group.Regex.MatchString(metric) { matchedMetrics = append(matchedMetrics, metric) } } sort.Strings(matchedMetrics) groupedMetrics = append(groupedMetrics, metricGroup{ Name: group.Name, Regex: group.Regex, Metrics: matchedMetrics, }) } return groupedMetrics } type goVersion int func (g goVersion) String() string { return fmt.Sprintf("go1.%d", g) } func (g goVersion) Abbr() string { return fmt.Sprintf("go1%d", g) } var testFile = template.Must(template.New("testFile").Funcs(map[string]interface{}{ "nextVersion": func(version goVersion) string { return (version + goVersion(1)).String() }, }).Parse(`// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build {{.GoVersion}} && !{{nextVersion .GoVersion}} // +build {{.GoVersion}},!{{nextVersion .GoVersion}} package collectors {{- range .Groups }} func {{ .Name }}() []string { return withBaseMetrics([]string{ {{- range $metric := .Metrics }} {{ $metric | printf "%q" }}, {{- end }} }) } {{ end }} var ( defaultRuntimeMetrics = []string{ {{- range $metric := .DefaultRuntimeMetricsList }} {{ $metric | printf "%q"}}, {{- end }} } onlyGCDefRuntimeMetrics = []string{ {{- range $metric := .OnlyGCDefRuntimeMetricsList }} {{ $metric | printf "%q"}}, {{- end }} } onlySchedDefRuntimeMetrics = []string{ {{- range $metric := .OnlySchedDefRuntimeMetricsList }} {{ $metric | printf "%q"}}, {{- end }} } ) `)) client_golang-1.21.1/prometheus/collectors/go_collector_go116.go000066400000000000000000000045731476160432400247040ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build !go1.17 // +build !go1.17 package collectors import "github.com/prometheus/client_golang/prometheus" // NewGoCollector returns a collector that exports metrics about the current Go // process. This includes memory stats. To collect those, runtime.ReadMemStats // is called. This requires to β€œstop the world”, which usually only happens for // garbage collection (GC). Take the following implications into account when // deciding whether to use the Go collector: // // 1. The performance impact of stopping the world is the more relevant the more // frequently metrics are collected. However, with Go1.9 or later the // stop-the-world time per metrics collection is very short (~25Β΅s) so that the // performance impact will only matter in rare cases. However, with older Go // versions, the stop-the-world duration depends on the heap size and can be // quite significant (~1.7 ms/GiB as per // https://go-review.googlesource.com/c/go/+/34937). // // 2. During an ongoing GC, nothing else can stop the world. Therefore, if the // metrics collection happens to coincide with GC, it will only complete after // GC has finished. Usually, GC is fast enough to not cause problems. However, // with a very large heap, GC might take multiple seconds, which is enough to // cause scrape timeouts in common setups. To avoid this problem, the Go // collector will use the memstats from a previous collection if // runtime.ReadMemStats takes more than 1s. However, if there are no previously // collected memstats, or their collection is more than 5m ago, the collection // will block until runtime.ReadMemStats succeeds. // // NOTE: The problem is solved in Go 1.15, see // https://github.com/golang/go/issues/19812 for the related Go issue. func NewGoCollector() prometheus.Collector { return prometheus.NewGoCollector() } client_golang-1.21.1/prometheus/collectors/go_collector_go120_test.go000066400000000000000000000104311476160432400257240ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build go1.20 && !go1.21 // +build go1.20,!go1.21 package collectors func withAllMetrics() []string { return withBaseMetrics([]string{ "go_cgo_go_to_c_calls_calls_total", "go_cpu_classes_gc_mark_assist_cpu_seconds_total", "go_cpu_classes_gc_mark_dedicated_cpu_seconds_total", "go_cpu_classes_gc_mark_idle_cpu_seconds_total", "go_cpu_classes_gc_pause_cpu_seconds_total", "go_cpu_classes_gc_total_cpu_seconds_total", "go_cpu_classes_idle_cpu_seconds_total", "go_cpu_classes_scavenge_assist_cpu_seconds_total", "go_cpu_classes_scavenge_background_cpu_seconds_total", "go_cpu_classes_scavenge_total_cpu_seconds_total", "go_cpu_classes_total_cpu_seconds_total", "go_cpu_classes_user_cpu_seconds_total", "go_gc_cycles_automatic_gc_cycles_total", "go_gc_cycles_forced_gc_cycles_total", "go_gc_cycles_total_gc_cycles_total", "go_gc_heap_allocs_by_size_bytes", "go_gc_heap_allocs_bytes_total", "go_gc_heap_allocs_objects_total", "go_gc_heap_frees_by_size_bytes", "go_gc_heap_frees_bytes_total", "go_gc_heap_frees_objects_total", "go_gc_heap_goal_bytes", "go_gc_heap_objects_objects", "go_gc_heap_tiny_allocs_objects_total", "go_gc_limiter_last_enabled_gc_cycle", "go_gc_pauses_seconds", "go_gc_stack_starting_size_bytes", "go_memory_classes_heap_free_bytes", "go_memory_classes_heap_objects_bytes", "go_memory_classes_heap_released_bytes", "go_memory_classes_heap_stacks_bytes", "go_memory_classes_heap_unused_bytes", "go_memory_classes_metadata_mcache_free_bytes", "go_memory_classes_metadata_mcache_inuse_bytes", "go_memory_classes_metadata_mspan_free_bytes", "go_memory_classes_metadata_mspan_inuse_bytes", "go_memory_classes_metadata_other_bytes", "go_memory_classes_os_stacks_bytes", "go_memory_classes_other_bytes", "go_memory_classes_profiling_buckets_bytes", "go_memory_classes_total_bytes", "go_sched_gomaxprocs_threads", "go_sched_goroutines_goroutines", "go_sched_latencies_seconds", "go_sync_mutex_wait_total_seconds_total", }) } func withGCMetrics() []string { return withBaseMetrics([]string{ "go_gc_cycles_automatic_gc_cycles_total", "go_gc_cycles_forced_gc_cycles_total", "go_gc_cycles_total_gc_cycles_total", "go_gc_heap_allocs_by_size_bytes", "go_gc_heap_allocs_bytes_total", "go_gc_heap_allocs_objects_total", "go_gc_heap_frees_by_size_bytes", "go_gc_heap_frees_bytes_total", "go_gc_heap_frees_objects_total", "go_gc_heap_goal_bytes", "go_gc_heap_objects_objects", "go_gc_heap_tiny_allocs_objects_total", "go_gc_limiter_last_enabled_gc_cycle", "go_gc_pauses_seconds", "go_gc_stack_starting_size_bytes", }) } func withMemoryMetrics() []string { return withBaseMetrics([]string{ "go_memory_classes_heap_free_bytes", "go_memory_classes_heap_objects_bytes", "go_memory_classes_heap_released_bytes", "go_memory_classes_heap_stacks_bytes", "go_memory_classes_heap_unused_bytes", "go_memory_classes_metadata_mcache_free_bytes", "go_memory_classes_metadata_mcache_inuse_bytes", "go_memory_classes_metadata_mspan_free_bytes", "go_memory_classes_metadata_mspan_inuse_bytes", "go_memory_classes_metadata_other_bytes", "go_memory_classes_os_stacks_bytes", "go_memory_classes_other_bytes", "go_memory_classes_profiling_buckets_bytes", "go_memory_classes_total_bytes", }) } func withSchedulerMetrics() []string { return withBaseMetrics([]string{ "go_sched_gomaxprocs_threads", "go_sched_goroutines_goroutines", "go_sched_latencies_seconds", }) } func withDebugMetrics() []string { return withBaseMetrics([]string{}) } var ( defaultRuntimeMetrics = []string{ "go_sched_gomaxprocs_threads", } onlyGCDefRuntimeMetrics = []string{} onlySchedDefRuntimeMetrics = []string{ "go_sched_gomaxprocs_threads", } ) client_golang-1.21.1/prometheus/collectors/go_collector_go121_test.go000066400000000000000000000161701476160432400257330ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build go1.21 && !go1.22 // +build go1.21,!go1.22 package collectors func withAllMetrics() []string { return withBaseMetrics([]string{ "go_cgo_go_to_c_calls_calls_total", "go_cpu_classes_gc_mark_assist_cpu_seconds_total", "go_cpu_classes_gc_mark_dedicated_cpu_seconds_total", "go_cpu_classes_gc_mark_idle_cpu_seconds_total", "go_cpu_classes_gc_pause_cpu_seconds_total", "go_cpu_classes_gc_total_cpu_seconds_total", "go_cpu_classes_idle_cpu_seconds_total", "go_cpu_classes_scavenge_assist_cpu_seconds_total", "go_cpu_classes_scavenge_background_cpu_seconds_total", "go_cpu_classes_scavenge_total_cpu_seconds_total", "go_cpu_classes_total_cpu_seconds_total", "go_cpu_classes_user_cpu_seconds_total", "go_gc_cycles_automatic_gc_cycles_total", "go_gc_cycles_forced_gc_cycles_total", "go_gc_cycles_total_gc_cycles_total", "go_gc_gogc_percent", "go_gc_gomemlimit_bytes", "go_gc_heap_allocs_by_size_bytes", "go_gc_heap_allocs_bytes_total", "go_gc_heap_allocs_objects_total", "go_gc_heap_frees_by_size_bytes", "go_gc_heap_frees_bytes_total", "go_gc_heap_frees_objects_total", "go_gc_heap_goal_bytes", "go_gc_heap_live_bytes", "go_gc_heap_objects_objects", "go_gc_heap_tiny_allocs_objects_total", "go_gc_limiter_last_enabled_gc_cycle", "go_gc_pauses_seconds", "go_gc_scan_globals_bytes", "go_gc_scan_heap_bytes", "go_gc_scan_stack_bytes", "go_gc_scan_total_bytes", "go_gc_stack_starting_size_bytes", "go_godebug_non_default_behavior_execerrdot_events_total", "go_godebug_non_default_behavior_gocachehash_events_total", "go_godebug_non_default_behavior_gocachetest_events_total", "go_godebug_non_default_behavior_gocacheverify_events_total", "go_godebug_non_default_behavior_http2client_events_total", "go_godebug_non_default_behavior_http2server_events_total", "go_godebug_non_default_behavior_installgoroot_events_total", "go_godebug_non_default_behavior_jstmpllitinterp_events_total", "go_godebug_non_default_behavior_multipartmaxheaders_events_total", "go_godebug_non_default_behavior_multipartmaxparts_events_total", "go_godebug_non_default_behavior_multipathtcp_events_total", "go_godebug_non_default_behavior_netedns0_events_total", "go_godebug_non_default_behavior_panicnil_events_total", "go_godebug_non_default_behavior_randautoseed_events_total", "go_godebug_non_default_behavior_tarinsecurepath_events_total", "go_godebug_non_default_behavior_tlsmaxrsasize_events_total", "go_godebug_non_default_behavior_x509sha1_events_total", "go_godebug_non_default_behavior_x509usefallbackroots_events_total", "go_godebug_non_default_behavior_zipinsecurepath_events_total", "go_memory_classes_heap_free_bytes", "go_memory_classes_heap_objects_bytes", "go_memory_classes_heap_released_bytes", "go_memory_classes_heap_stacks_bytes", "go_memory_classes_heap_unused_bytes", "go_memory_classes_metadata_mcache_free_bytes", "go_memory_classes_metadata_mcache_inuse_bytes", "go_memory_classes_metadata_mspan_free_bytes", "go_memory_classes_metadata_mspan_inuse_bytes", "go_memory_classes_metadata_other_bytes", "go_memory_classes_os_stacks_bytes", "go_memory_classes_other_bytes", "go_memory_classes_profiling_buckets_bytes", "go_memory_classes_total_bytes", "go_sched_gomaxprocs_threads", "go_sched_goroutines_goroutines", "go_sched_latencies_seconds", "go_sync_mutex_wait_total_seconds_total", }) } func withGCMetrics() []string { return withBaseMetrics([]string{ "go_gc_cycles_automatic_gc_cycles_total", "go_gc_cycles_forced_gc_cycles_total", "go_gc_cycles_total_gc_cycles_total", "go_gc_gogc_percent", "go_gc_gomemlimit_bytes", "go_gc_heap_allocs_by_size_bytes", "go_gc_heap_allocs_bytes_total", "go_gc_heap_allocs_objects_total", "go_gc_heap_frees_by_size_bytes", "go_gc_heap_frees_bytes_total", "go_gc_heap_frees_objects_total", "go_gc_heap_goal_bytes", "go_gc_heap_live_bytes", "go_gc_heap_objects_objects", "go_gc_heap_tiny_allocs_objects_total", "go_gc_limiter_last_enabled_gc_cycle", "go_gc_pauses_seconds", "go_gc_scan_globals_bytes", "go_gc_scan_heap_bytes", "go_gc_scan_stack_bytes", "go_gc_scan_total_bytes", "go_gc_stack_starting_size_bytes", }) } func withMemoryMetrics() []string { return withBaseMetrics([]string{ "go_memory_classes_heap_free_bytes", "go_memory_classes_heap_objects_bytes", "go_memory_classes_heap_released_bytes", "go_memory_classes_heap_stacks_bytes", "go_memory_classes_heap_unused_bytes", "go_memory_classes_metadata_mcache_free_bytes", "go_memory_classes_metadata_mcache_inuse_bytes", "go_memory_classes_metadata_mspan_free_bytes", "go_memory_classes_metadata_mspan_inuse_bytes", "go_memory_classes_metadata_other_bytes", "go_memory_classes_os_stacks_bytes", "go_memory_classes_other_bytes", "go_memory_classes_profiling_buckets_bytes", "go_memory_classes_total_bytes", }) } func withSchedulerMetrics() []string { return withBaseMetrics([]string{ "go_sched_gomaxprocs_threads", "go_sched_goroutines_goroutines", "go_sched_latencies_seconds", }) } func withDebugMetrics() []string { return withBaseMetrics([]string{ "go_godebug_non_default_behavior_execerrdot_events_total", "go_godebug_non_default_behavior_gocachehash_events_total", "go_godebug_non_default_behavior_gocachetest_events_total", "go_godebug_non_default_behavior_gocacheverify_events_total", "go_godebug_non_default_behavior_http2client_events_total", "go_godebug_non_default_behavior_http2server_events_total", "go_godebug_non_default_behavior_installgoroot_events_total", "go_godebug_non_default_behavior_jstmpllitinterp_events_total", "go_godebug_non_default_behavior_multipartmaxheaders_events_total", "go_godebug_non_default_behavior_multipartmaxparts_events_total", "go_godebug_non_default_behavior_multipathtcp_events_total", "go_godebug_non_default_behavior_netedns0_events_total", "go_godebug_non_default_behavior_panicnil_events_total", "go_godebug_non_default_behavior_randautoseed_events_total", "go_godebug_non_default_behavior_tarinsecurepath_events_total", "go_godebug_non_default_behavior_tlsmaxrsasize_events_total", "go_godebug_non_default_behavior_x509sha1_events_total", "go_godebug_non_default_behavior_x509usefallbackroots_events_total", "go_godebug_non_default_behavior_zipinsecurepath_events_total", }) } var ( defaultRuntimeMetrics = []string{ "go_gc_gogc_percent", "go_gc_gomemlimit_bytes", "go_sched_gomaxprocs_threads", } onlyGCDefRuntimeMetrics = []string{ "go_gc_gogc_percent", "go_gc_gomemlimit_bytes", } onlySchedDefRuntimeMetrics = []string{ "go_sched_gomaxprocs_threads", } ) client_golang-1.21.1/prometheus/collectors/go_collector_go122_test.go000066400000000000000000000205001476160432400257240ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build go1.22 && !go1.23 // +build go1.22,!go1.23 package collectors func withAllMetrics() []string { return withBaseMetrics([]string{ "go_cgo_go_to_c_calls_calls_total", "go_cpu_classes_gc_mark_assist_cpu_seconds_total", "go_cpu_classes_gc_mark_dedicated_cpu_seconds_total", "go_cpu_classes_gc_mark_idle_cpu_seconds_total", "go_cpu_classes_gc_pause_cpu_seconds_total", "go_cpu_classes_gc_total_cpu_seconds_total", "go_cpu_classes_idle_cpu_seconds_total", "go_cpu_classes_scavenge_assist_cpu_seconds_total", "go_cpu_classes_scavenge_background_cpu_seconds_total", "go_cpu_classes_scavenge_total_cpu_seconds_total", "go_cpu_classes_total_cpu_seconds_total", "go_cpu_classes_user_cpu_seconds_total", "go_gc_cycles_automatic_gc_cycles_total", "go_gc_cycles_forced_gc_cycles_total", "go_gc_cycles_total_gc_cycles_total", "go_gc_gogc_percent", "go_gc_gomemlimit_bytes", "go_gc_heap_allocs_by_size_bytes", "go_gc_heap_allocs_bytes_total", "go_gc_heap_allocs_objects_total", "go_gc_heap_frees_by_size_bytes", "go_gc_heap_frees_bytes_total", "go_gc_heap_frees_objects_total", "go_gc_heap_goal_bytes", "go_gc_heap_live_bytes", "go_gc_heap_objects_objects", "go_gc_heap_tiny_allocs_objects_total", "go_gc_limiter_last_enabled_gc_cycle", "go_gc_pauses_seconds", "go_gc_scan_globals_bytes", "go_gc_scan_heap_bytes", "go_gc_scan_stack_bytes", "go_gc_scan_total_bytes", "go_gc_stack_starting_size_bytes", "go_godebug_non_default_behavior_execerrdot_events_total", "go_godebug_non_default_behavior_gocachehash_events_total", "go_godebug_non_default_behavior_gocachetest_events_total", "go_godebug_non_default_behavior_gocacheverify_events_total", "go_godebug_non_default_behavior_gotypesalias_events_total", "go_godebug_non_default_behavior_http2client_events_total", "go_godebug_non_default_behavior_http2server_events_total", "go_godebug_non_default_behavior_httplaxcontentlength_events_total", "go_godebug_non_default_behavior_httpmuxgo121_events_total", "go_godebug_non_default_behavior_installgoroot_events_total", "go_godebug_non_default_behavior_jstmpllitinterp_events_total", "go_godebug_non_default_behavior_multipartmaxheaders_events_total", "go_godebug_non_default_behavior_multipartmaxparts_events_total", "go_godebug_non_default_behavior_multipathtcp_events_total", "go_godebug_non_default_behavior_netedns0_events_total", "go_godebug_non_default_behavior_panicnil_events_total", "go_godebug_non_default_behavior_randautoseed_events_total", "go_godebug_non_default_behavior_tarinsecurepath_events_total", "go_godebug_non_default_behavior_tls10server_events_total", "go_godebug_non_default_behavior_tlsmaxrsasize_events_total", "go_godebug_non_default_behavior_tlsrsakex_events_total", "go_godebug_non_default_behavior_tlsunsafeekm_events_total", "go_godebug_non_default_behavior_x509sha1_events_total", "go_godebug_non_default_behavior_x509usefallbackroots_events_total", "go_godebug_non_default_behavior_x509usepolicies_events_total", "go_godebug_non_default_behavior_zipinsecurepath_events_total", "go_memory_classes_heap_free_bytes", "go_memory_classes_heap_objects_bytes", "go_memory_classes_heap_released_bytes", "go_memory_classes_heap_stacks_bytes", "go_memory_classes_heap_unused_bytes", "go_memory_classes_metadata_mcache_free_bytes", "go_memory_classes_metadata_mcache_inuse_bytes", "go_memory_classes_metadata_mspan_free_bytes", "go_memory_classes_metadata_mspan_inuse_bytes", "go_memory_classes_metadata_other_bytes", "go_memory_classes_os_stacks_bytes", "go_memory_classes_other_bytes", "go_memory_classes_profiling_buckets_bytes", "go_memory_classes_total_bytes", "go_sched_gomaxprocs_threads", "go_sched_goroutines_goroutines", "go_sched_latencies_seconds", "go_sched_pauses_stopping_gc_seconds", "go_sched_pauses_stopping_other_seconds", "go_sched_pauses_total_gc_seconds", "go_sched_pauses_total_other_seconds", "go_sync_mutex_wait_total_seconds_total", }) } func withGCMetrics() []string { return withBaseMetrics([]string{ "go_gc_cycles_automatic_gc_cycles_total", "go_gc_cycles_forced_gc_cycles_total", "go_gc_cycles_total_gc_cycles_total", "go_gc_gogc_percent", "go_gc_gomemlimit_bytes", "go_gc_heap_allocs_by_size_bytes", "go_gc_heap_allocs_bytes_total", "go_gc_heap_allocs_objects_total", "go_gc_heap_frees_by_size_bytes", "go_gc_heap_frees_bytes_total", "go_gc_heap_frees_objects_total", "go_gc_heap_goal_bytes", "go_gc_heap_live_bytes", "go_gc_heap_objects_objects", "go_gc_heap_tiny_allocs_objects_total", "go_gc_limiter_last_enabled_gc_cycle", "go_gc_pauses_seconds", "go_gc_scan_globals_bytes", "go_gc_scan_heap_bytes", "go_gc_scan_stack_bytes", "go_gc_scan_total_bytes", "go_gc_stack_starting_size_bytes", }) } func withMemoryMetrics() []string { return withBaseMetrics([]string{ "go_memory_classes_heap_free_bytes", "go_memory_classes_heap_objects_bytes", "go_memory_classes_heap_released_bytes", "go_memory_classes_heap_stacks_bytes", "go_memory_classes_heap_unused_bytes", "go_memory_classes_metadata_mcache_free_bytes", "go_memory_classes_metadata_mcache_inuse_bytes", "go_memory_classes_metadata_mspan_free_bytes", "go_memory_classes_metadata_mspan_inuse_bytes", "go_memory_classes_metadata_other_bytes", "go_memory_classes_os_stacks_bytes", "go_memory_classes_other_bytes", "go_memory_classes_profiling_buckets_bytes", "go_memory_classes_total_bytes", }) } func withSchedulerMetrics() []string { return withBaseMetrics([]string{ "go_sched_gomaxprocs_threads", "go_sched_goroutines_goroutines", "go_sched_latencies_seconds", "go_sched_pauses_stopping_gc_seconds", "go_sched_pauses_stopping_other_seconds", "go_sched_pauses_total_gc_seconds", "go_sched_pauses_total_other_seconds", }) } func withDebugMetrics() []string { return withBaseMetrics([]string{ "go_godebug_non_default_behavior_execerrdot_events_total", "go_godebug_non_default_behavior_gocachehash_events_total", "go_godebug_non_default_behavior_gocachetest_events_total", "go_godebug_non_default_behavior_gocacheverify_events_total", "go_godebug_non_default_behavior_gotypesalias_events_total", "go_godebug_non_default_behavior_http2client_events_total", "go_godebug_non_default_behavior_http2server_events_total", "go_godebug_non_default_behavior_httplaxcontentlength_events_total", "go_godebug_non_default_behavior_httpmuxgo121_events_total", "go_godebug_non_default_behavior_installgoroot_events_total", "go_godebug_non_default_behavior_jstmpllitinterp_events_total", "go_godebug_non_default_behavior_multipartmaxheaders_events_total", "go_godebug_non_default_behavior_multipartmaxparts_events_total", "go_godebug_non_default_behavior_multipathtcp_events_total", "go_godebug_non_default_behavior_netedns0_events_total", "go_godebug_non_default_behavior_panicnil_events_total", "go_godebug_non_default_behavior_randautoseed_events_total", "go_godebug_non_default_behavior_tarinsecurepath_events_total", "go_godebug_non_default_behavior_tls10server_events_total", "go_godebug_non_default_behavior_tlsmaxrsasize_events_total", "go_godebug_non_default_behavior_tlsrsakex_events_total", "go_godebug_non_default_behavior_tlsunsafeekm_events_total", "go_godebug_non_default_behavior_x509sha1_events_total", "go_godebug_non_default_behavior_x509usefallbackroots_events_total", "go_godebug_non_default_behavior_x509usepolicies_events_total", "go_godebug_non_default_behavior_zipinsecurepath_events_total", }) } var ( defaultRuntimeMetrics = []string{ "go_gc_gogc_percent", "go_gc_gomemlimit_bytes", "go_sched_gomaxprocs_threads", } onlyGCDefRuntimeMetrics = []string{ "go_gc_gogc_percent", "go_gc_gomemlimit_bytes", } onlySchedDefRuntimeMetrics = []string{ "go_sched_gomaxprocs_threads", } ) client_golang-1.21.1/prometheus/collectors/go_collector_go123_test.go000066400000000000000000000221361476160432400257340ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build go1.23 && !go1.24 // +build go1.23,!go1.24 package collectors func withAllMetrics() []string { return withBaseMetrics([]string{ "go_cgo_go_to_c_calls_calls_total", "go_cpu_classes_gc_mark_assist_cpu_seconds_total", "go_cpu_classes_gc_mark_dedicated_cpu_seconds_total", "go_cpu_classes_gc_mark_idle_cpu_seconds_total", "go_cpu_classes_gc_pause_cpu_seconds_total", "go_cpu_classes_gc_total_cpu_seconds_total", "go_cpu_classes_idle_cpu_seconds_total", "go_cpu_classes_scavenge_assist_cpu_seconds_total", "go_cpu_classes_scavenge_background_cpu_seconds_total", "go_cpu_classes_scavenge_total_cpu_seconds_total", "go_cpu_classes_total_cpu_seconds_total", "go_cpu_classes_user_cpu_seconds_total", "go_gc_cycles_automatic_gc_cycles_total", "go_gc_cycles_forced_gc_cycles_total", "go_gc_cycles_total_gc_cycles_total", "go_gc_gogc_percent", "go_gc_gomemlimit_bytes", "go_gc_heap_allocs_by_size_bytes", "go_gc_heap_allocs_bytes_total", "go_gc_heap_allocs_objects_total", "go_gc_heap_frees_by_size_bytes", "go_gc_heap_frees_bytes_total", "go_gc_heap_frees_objects_total", "go_gc_heap_goal_bytes", "go_gc_heap_live_bytes", "go_gc_heap_objects_objects", "go_gc_heap_tiny_allocs_objects_total", "go_gc_limiter_last_enabled_gc_cycle", "go_gc_pauses_seconds", "go_gc_scan_globals_bytes", "go_gc_scan_heap_bytes", "go_gc_scan_stack_bytes", "go_gc_scan_total_bytes", "go_gc_stack_starting_size_bytes", "go_godebug_non_default_behavior_asynctimerchan_events_total", "go_godebug_non_default_behavior_execerrdot_events_total", "go_godebug_non_default_behavior_gocachehash_events_total", "go_godebug_non_default_behavior_gocachetest_events_total", "go_godebug_non_default_behavior_gocacheverify_events_total", "go_godebug_non_default_behavior_gotypesalias_events_total", "go_godebug_non_default_behavior_http2client_events_total", "go_godebug_non_default_behavior_http2server_events_total", "go_godebug_non_default_behavior_httplaxcontentlength_events_total", "go_godebug_non_default_behavior_httpmuxgo121_events_total", "go_godebug_non_default_behavior_httpservecontentkeepheaders_events_total", "go_godebug_non_default_behavior_installgoroot_events_total", "go_godebug_non_default_behavior_multipartmaxheaders_events_total", "go_godebug_non_default_behavior_multipartmaxparts_events_total", "go_godebug_non_default_behavior_multipathtcp_events_total", "go_godebug_non_default_behavior_netedns0_events_total", "go_godebug_non_default_behavior_panicnil_events_total", "go_godebug_non_default_behavior_randautoseed_events_total", "go_godebug_non_default_behavior_tarinsecurepath_events_total", "go_godebug_non_default_behavior_tls10server_events_total", "go_godebug_non_default_behavior_tls3des_events_total", "go_godebug_non_default_behavior_tlsmaxrsasize_events_total", "go_godebug_non_default_behavior_tlsrsakex_events_total", "go_godebug_non_default_behavior_tlsunsafeekm_events_total", "go_godebug_non_default_behavior_winreadlinkvolume_events_total", "go_godebug_non_default_behavior_winsymlink_events_total", "go_godebug_non_default_behavior_x509keypairleaf_events_total", "go_godebug_non_default_behavior_x509negativeserial_events_total", "go_godebug_non_default_behavior_x509sha1_events_total", "go_godebug_non_default_behavior_x509usefallbackroots_events_total", "go_godebug_non_default_behavior_x509usepolicies_events_total", "go_godebug_non_default_behavior_zipinsecurepath_events_total", "go_memory_classes_heap_free_bytes", "go_memory_classes_heap_objects_bytes", "go_memory_classes_heap_released_bytes", "go_memory_classes_heap_stacks_bytes", "go_memory_classes_heap_unused_bytes", "go_memory_classes_metadata_mcache_free_bytes", "go_memory_classes_metadata_mcache_inuse_bytes", "go_memory_classes_metadata_mspan_free_bytes", "go_memory_classes_metadata_mspan_inuse_bytes", "go_memory_classes_metadata_other_bytes", "go_memory_classes_os_stacks_bytes", "go_memory_classes_other_bytes", "go_memory_classes_profiling_buckets_bytes", "go_memory_classes_total_bytes", "go_sched_gomaxprocs_threads", "go_sched_goroutines_goroutines", "go_sched_latencies_seconds", "go_sched_pauses_stopping_gc_seconds", "go_sched_pauses_stopping_other_seconds", "go_sched_pauses_total_gc_seconds", "go_sched_pauses_total_other_seconds", "go_sync_mutex_wait_total_seconds_total", }) } func withGCMetrics() []string { return withBaseMetrics([]string{ "go_gc_cycles_automatic_gc_cycles_total", "go_gc_cycles_forced_gc_cycles_total", "go_gc_cycles_total_gc_cycles_total", "go_gc_gogc_percent", "go_gc_gomemlimit_bytes", "go_gc_heap_allocs_by_size_bytes", "go_gc_heap_allocs_bytes_total", "go_gc_heap_allocs_objects_total", "go_gc_heap_frees_by_size_bytes", "go_gc_heap_frees_bytes_total", "go_gc_heap_frees_objects_total", "go_gc_heap_goal_bytes", "go_gc_heap_live_bytes", "go_gc_heap_objects_objects", "go_gc_heap_tiny_allocs_objects_total", "go_gc_limiter_last_enabled_gc_cycle", "go_gc_pauses_seconds", "go_gc_scan_globals_bytes", "go_gc_scan_heap_bytes", "go_gc_scan_stack_bytes", "go_gc_scan_total_bytes", "go_gc_stack_starting_size_bytes", }) } func withMemoryMetrics() []string { return withBaseMetrics([]string{ "go_memory_classes_heap_free_bytes", "go_memory_classes_heap_objects_bytes", "go_memory_classes_heap_released_bytes", "go_memory_classes_heap_stacks_bytes", "go_memory_classes_heap_unused_bytes", "go_memory_classes_metadata_mcache_free_bytes", "go_memory_classes_metadata_mcache_inuse_bytes", "go_memory_classes_metadata_mspan_free_bytes", "go_memory_classes_metadata_mspan_inuse_bytes", "go_memory_classes_metadata_other_bytes", "go_memory_classes_os_stacks_bytes", "go_memory_classes_other_bytes", "go_memory_classes_profiling_buckets_bytes", "go_memory_classes_total_bytes", }) } func withSchedulerMetrics() []string { return withBaseMetrics([]string{ "go_sched_gomaxprocs_threads", "go_sched_goroutines_goroutines", "go_sched_latencies_seconds", "go_sched_pauses_stopping_gc_seconds", "go_sched_pauses_stopping_other_seconds", "go_sched_pauses_total_gc_seconds", "go_sched_pauses_total_other_seconds", }) } func withDebugMetrics() []string { return withBaseMetrics([]string{ "go_godebug_non_default_behavior_asynctimerchan_events_total", "go_godebug_non_default_behavior_execerrdot_events_total", "go_godebug_non_default_behavior_gocachehash_events_total", "go_godebug_non_default_behavior_gocachetest_events_total", "go_godebug_non_default_behavior_gocacheverify_events_total", "go_godebug_non_default_behavior_gotypesalias_events_total", "go_godebug_non_default_behavior_http2client_events_total", "go_godebug_non_default_behavior_http2server_events_total", "go_godebug_non_default_behavior_httplaxcontentlength_events_total", "go_godebug_non_default_behavior_httpmuxgo121_events_total", "go_godebug_non_default_behavior_httpservecontentkeepheaders_events_total", "go_godebug_non_default_behavior_installgoroot_events_total", "go_godebug_non_default_behavior_multipartmaxheaders_events_total", "go_godebug_non_default_behavior_multipartmaxparts_events_total", "go_godebug_non_default_behavior_multipathtcp_events_total", "go_godebug_non_default_behavior_netedns0_events_total", "go_godebug_non_default_behavior_panicnil_events_total", "go_godebug_non_default_behavior_randautoseed_events_total", "go_godebug_non_default_behavior_tarinsecurepath_events_total", "go_godebug_non_default_behavior_tls10server_events_total", "go_godebug_non_default_behavior_tls3des_events_total", "go_godebug_non_default_behavior_tlsmaxrsasize_events_total", "go_godebug_non_default_behavior_tlsrsakex_events_total", "go_godebug_non_default_behavior_tlsunsafeekm_events_total", "go_godebug_non_default_behavior_winreadlinkvolume_events_total", "go_godebug_non_default_behavior_winsymlink_events_total", "go_godebug_non_default_behavior_x509keypairleaf_events_total", "go_godebug_non_default_behavior_x509negativeserial_events_total", "go_godebug_non_default_behavior_x509sha1_events_total", "go_godebug_non_default_behavior_x509usefallbackroots_events_total", "go_godebug_non_default_behavior_x509usepolicies_events_total", "go_godebug_non_default_behavior_zipinsecurepath_events_total", }) } var ( defaultRuntimeMetrics = []string{ "go_gc_gogc_percent", "go_gc_gomemlimit_bytes", "go_sched_gomaxprocs_threads", } onlyGCDefRuntimeMetrics = []string{ "go_gc_gogc_percent", "go_gc_gomemlimit_bytes", } onlySchedDefRuntimeMetrics = []string{ "go_sched_gomaxprocs_threads", } ) client_golang-1.21.1/prometheus/collectors/go_collector_latest.go000066400000000000000000000163451476160432400253430ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build go1.17 // +build go1.17 package collectors import ( "regexp" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/internal" ) var ( // MetricsAll allows all the metrics to be collected from Go runtime. MetricsAll = GoRuntimeMetricsRule{regexp.MustCompile("/.*")} // MetricsGC allows only GC metrics to be collected from Go runtime. // e.g. go_gc_cycles_automatic_gc_cycles_total // NOTE: This does not include new class of "/cpu/classes/gc/..." metrics. // Use custom metric rule to access those. MetricsGC = GoRuntimeMetricsRule{regexp.MustCompile(`^/gc/.*`)} // MetricsMemory allows only memory metrics to be collected from Go runtime. // e.g. go_memory_classes_heap_free_bytes MetricsMemory = GoRuntimeMetricsRule{regexp.MustCompile(`^/memory/.*`)} // MetricsScheduler allows only scheduler metrics to be collected from Go runtime. // e.g. go_sched_goroutines_goroutines MetricsScheduler = GoRuntimeMetricsRule{regexp.MustCompile(`^/sched/.*`)} // MetricsDebug allows only debug metrics to be collected from Go runtime. // e.g. go_godebug_non_default_behavior_gocachetest_events_total MetricsDebug = GoRuntimeMetricsRule{regexp.MustCompile(`^/godebug/.*`)} ) // WithGoCollectorMemStatsMetricsDisabled disables metrics that is gathered in runtime.MemStats structure such as: // // go_memstats_alloc_bytes // go_memstats_alloc_bytes_total // go_memstats_sys_bytes // go_memstats_mallocs_total // go_memstats_frees_total // go_memstats_heap_alloc_bytes // go_memstats_heap_sys_bytes // go_memstats_heap_idle_bytes // go_memstats_heap_inuse_bytes // go_memstats_heap_released_bytes // go_memstats_heap_objects // go_memstats_stack_inuse_bytes // go_memstats_stack_sys_bytes // go_memstats_mspan_inuse_bytes // go_memstats_mspan_sys_bytes // go_memstats_mcache_inuse_bytes // go_memstats_mcache_sys_bytes // go_memstats_buck_hash_sys_bytes // go_memstats_gc_sys_bytes // go_memstats_other_sys_bytes // go_memstats_next_gc_bytes // // so the metrics known from pre client_golang v1.12.0, // // NOTE(bwplotka): The above represents runtime.MemStats statistics, but they are // actually implemented using new runtime/metrics package. (except skipped go_memstats_gc_cpu_fraction // -- see https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034 for explanation). // // Some users might want to disable this on collector level (although you can use scrape relabelling on Prometheus), // because similar metrics can be now obtained using WithGoCollectorRuntimeMetrics. Note that the semantics of new // metrics might be different, plus the names can be change over time with different Go version. // // NOTE(bwplotka): Changing metric names can be tedious at times as the alerts, recording rules and dashboards have to be adjusted. // The old metrics are also very useful, with many guides and books written about how to interpret them. // // As a result our recommendation would be to stick with MemStats like metrics and enable other runtime/metrics if you are interested // in advanced insights Go provides. See ExampleGoCollector_WithAdvancedGoMetrics. func WithGoCollectorMemStatsMetricsDisabled() func(options *internal.GoCollectorOptions) { return func(o *internal.GoCollectorOptions) { o.DisableMemStatsLikeMetrics = true } } // GoRuntimeMetricsRule allow enabling and configuring particular group of runtime/metrics. // TODO(bwplotka): Consider adding ability to adjust buckets. type GoRuntimeMetricsRule struct { // Matcher represents RE2 expression will match the runtime/metrics from https://golang.bg/src/runtime/metrics/description.go // Use `regexp.MustCompile` or `regexp.Compile` to create this field. Matcher *regexp.Regexp } // WithGoCollectorRuntimeMetrics allows enabling and configuring particular group of runtime/metrics. // See the list of metrics https://golang.bg/src/runtime/metrics/description.go (pick the Go version you use there!). // You can use this option in repeated manner, which will add new rules. The order of rules is important, the last rule // that matches particular metrics is applied. func WithGoCollectorRuntimeMetrics(rules ...GoRuntimeMetricsRule) func(options *internal.GoCollectorOptions) { rs := make([]internal.GoCollectorRule, len(rules)) for i, r := range rules { rs[i] = internal.GoCollectorRule{ Matcher: r.Matcher, } } return func(o *internal.GoCollectorOptions) { o.RuntimeMetricRules = append(o.RuntimeMetricRules, rs...) } } // WithoutGoCollectorRuntimeMetrics allows disabling group of runtime/metrics that you might have added in WithGoCollectorRuntimeMetrics. // It behaves similarly to WithGoCollectorRuntimeMetrics just with deny-list semantics. func WithoutGoCollectorRuntimeMetrics(matchers ...*regexp.Regexp) func(options *internal.GoCollectorOptions) { rs := make([]internal.GoCollectorRule, len(matchers)) for i, m := range matchers { rs[i] = internal.GoCollectorRule{ Matcher: m, Deny: true, } } return func(o *internal.GoCollectorOptions) { o.RuntimeMetricRules = append(o.RuntimeMetricRules, rs...) } } // GoCollectionOption represents Go collection option flag. // Deprecated. type GoCollectionOption uint32 const ( // GoRuntimeMemStatsCollection represents the metrics represented by runtime.MemStats structure. // // Deprecated: Use WithGoCollectorMemStatsMetricsDisabled() function to disable those metrics in the collector. GoRuntimeMemStatsCollection GoCollectionOption = 1 << iota // GoRuntimeMetricsCollection is the new set of metrics represented by runtime/metrics package. // // Deprecated: Use WithGoCollectorRuntimeMetrics(GoRuntimeMetricsRule{Matcher: regexp.MustCompile("/.*")}) // function to enable those metrics in the collector. GoRuntimeMetricsCollection ) // WithGoCollections allows enabling different collections for Go collector on top of base metrics. // // Deprecated: Use WithGoCollectorRuntimeMetrics() and WithGoCollectorMemStatsMetricsDisabled() instead to control metrics. func WithGoCollections(flags GoCollectionOption) func(options *internal.GoCollectorOptions) { return func(options *internal.GoCollectorOptions) { if flags&GoRuntimeMemStatsCollection == 0 { WithGoCollectorMemStatsMetricsDisabled()(options) } if flags&GoRuntimeMetricsCollection != 0 { WithGoCollectorRuntimeMetrics(GoRuntimeMetricsRule{Matcher: regexp.MustCompile("/.*")})(options) } } } // NewGoCollector returns a collector that exports metrics about the current Go // process using debug.GCStats (base metrics) and runtime/metrics (both in MemStats style and new ones). func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) prometheus.Collector { //nolint:staticcheck // Ignore SA1019 until v2. return prometheus.NewGoCollector(opts...) } client_golang-1.21.1/prometheus/collectors/go_collector_latest_test.go000066400000000000000000000200231476160432400263660ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build go1.17 // +build go1.17 package collectors import ( "encoding/json" "log" "net/http" "regexp" "sort" "testing" "github.com/google/go-cmp/cmp" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) var baseMetrics = []string{ "go_gc_duration_seconds", "go_goroutines", "go_info", "go_memstats_last_gc_time_seconds", "go_threads", } var memstatMetrics = []string{ "go_memstats_alloc_bytes", "go_memstats_alloc_bytes_total", "go_memstats_buck_hash_sys_bytes", "go_memstats_frees_total", "go_memstats_gc_sys_bytes", "go_memstats_heap_alloc_bytes", "go_memstats_heap_idle_bytes", "go_memstats_heap_inuse_bytes", "go_memstats_heap_objects", "go_memstats_heap_released_bytes", "go_memstats_heap_sys_bytes", "go_memstats_mallocs_total", "go_memstats_mcache_inuse_bytes", "go_memstats_mcache_sys_bytes", "go_memstats_mspan_inuse_bytes", "go_memstats_mspan_sys_bytes", "go_memstats_next_gc_bytes", "go_memstats_other_sys_bytes", "go_memstats_stack_inuse_bytes", "go_memstats_stack_sys_bytes", "go_memstats_sys_bytes", } func withDefaultRuntimeMetrics(metricNames []string, withoutGC, withoutSched bool) []string { switch { case withoutGC && !withoutSched: // If only withoutGC is true, exclude "go_gc_*" metrics. metricNames = append(metricNames, onlySchedDefRuntimeMetrics...) case withoutSched && !withoutGC: // If only withoutSched is true, exclude "go_sched_*" metrics. metricNames = append(metricNames, onlyGCDefRuntimeMetrics...) default: // In any other case, use the default metrics. metricNames = append(metricNames, defaultRuntimeMetrics...) } // sorting is required sort.Strings(metricNames) return metricNames } func TestGoCollectorMarshalling(t *testing.T) { reg := prometheus.NewPedanticRegistry() reg.MustRegister(NewGoCollector( WithGoCollectorRuntimeMetrics(GoRuntimeMetricsRule{ Matcher: regexp.MustCompile("/.*"), }), )) result, err := reg.Gather() if err != nil { t.Fatal(err) } if _, err := json.Marshal(result); err != nil { t.Errorf("json marshalling should not fail, %v", err) } } func TestWithGoCollectorDefault(t *testing.T) { reg := prometheus.NewPedanticRegistry() reg.MustRegister(NewGoCollector()) result, err := reg.Gather() if err != nil { t.Fatal(err) } got := []string{} for _, r := range result { got = append(got, r.GetName()) } expected := append(withBaseMetrics(memstatMetrics), defaultRuntimeMetrics...) sort.Strings(expected) if diff := cmp.Diff(got, expected); diff != "" { t.Errorf("[IMPORTANT, those are default metrics, can't change in 1.x] missmatch (-want +got):\n%s", diff) } } func TestWithGoCollectorMemStatsMetricsDisabled(t *testing.T) { reg := prometheus.NewPedanticRegistry() reg.MustRegister(NewGoCollector( WithGoCollectorMemStatsMetricsDisabled(), )) result, err := reg.Gather() if err != nil { t.Fatal(err) } got := []string{} for _, r := range result { got = append(got, r.GetName()) } if diff := cmp.Diff(got, withBaseMetrics(defaultRuntimeMetrics)); diff != "" { t.Errorf("missmatch (-want +got):\n%s", diff) } } func TestGoCollectorAllowList(t *testing.T) { for _, test := range []struct { name string rules []GoRuntimeMetricsRule expected []string }{ { name: "Without any rules", rules: nil, expected: withBaseMetrics(defaultRuntimeMetrics), }, { name: "allow all", rules: []GoRuntimeMetricsRule{MetricsAll}, expected: withAllMetrics(), }, { name: "allow GC", rules: []GoRuntimeMetricsRule{MetricsGC}, expected: withDefaultRuntimeMetrics(withGCMetrics(), true, false), }, { name: "allow Memory", rules: []GoRuntimeMetricsRule{MetricsMemory}, expected: withDefaultRuntimeMetrics(withMemoryMetrics(), false, false), }, { name: "allow Scheduler", rules: []GoRuntimeMetricsRule{MetricsScheduler}, expected: withDefaultRuntimeMetrics(withSchedulerMetrics(), false, true), }, { name: "allow debug", rules: []GoRuntimeMetricsRule{MetricsDebug}, expected: withDefaultRuntimeMetrics(withDebugMetrics(), false, false), }, } { t.Run(test.name, func(t *testing.T) { reg := prometheus.NewPedanticRegistry() reg.MustRegister(NewGoCollector( WithGoCollectorMemStatsMetricsDisabled(), WithGoCollectorRuntimeMetrics(test.rules...), )) result, err := reg.Gather() if err != nil { t.Fatal(err) } got := []string{} for _, r := range result { got = append(got, r.GetName()) } if diff := cmp.Diff(got, test.expected); diff != "" { t.Errorf("missmatch (-want +got):\n%s", diff) } }) } } func withBaseMetrics(metricNames []string) []string { metricNames = append(metricNames, baseMetrics...) sort.Strings(metricNames) return metricNames } func TestGoCollectorDenyList(t *testing.T) { for _, test := range []struct { name string matchers []*regexp.Regexp expected []string }{ { name: "Without any matchers", matchers: nil, expected: withBaseMetrics(defaultRuntimeMetrics), }, { name: "deny all", matchers: []*regexp.Regexp{regexp.MustCompile("/.*")}, expected: baseMetrics, }, { name: "deny gc and scheduler latency", matchers: []*regexp.Regexp{ regexp.MustCompile("^/gc/.*"), regexp.MustCompile("^/sched/latencies:.*"), }, expected: withDefaultRuntimeMetrics(baseMetrics, true, false), }, { name: "deny gc and scheduler", matchers: []*regexp.Regexp{ regexp.MustCompile("^/gc/.*"), regexp.MustCompile("^/sched/.*"), }, expected: baseMetrics, }, } { t.Run(test.name, func(t *testing.T) { reg := prometheus.NewPedanticRegistry() reg.MustRegister(NewGoCollector( WithGoCollectorMemStatsMetricsDisabled(), WithoutGoCollectorRuntimeMetrics(test.matchers...), )) result, err := reg.Gather() if err != nil { t.Fatal(err) } got := []string{} for _, r := range result { got = append(got, r.GetName()) } if diff := cmp.Diff(got, test.expected); diff != "" { t.Errorf("missmatch (-want +got):\n%s", diff) } }) } } func ExampleGoCollector() { reg := prometheus.NewPedanticRegistry() // Register the GoCollector with the default options. Only the base metrics, default runtime metrics and memstats are enabled. reg.MustRegister(NewGoCollector()) http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{})) log.Fatal(http.ListenAndServe(":8080", nil)) } func ExampleGoCollector_WithAdvancedGoMetrics() { reg := prometheus.NewPedanticRegistry() // Enable Go metrics with pre-defined rules. Or your custom rules. reg.MustRegister( NewGoCollector( WithGoCollectorMemStatsMetricsDisabled(), WithGoCollectorRuntimeMetrics( MetricsScheduler, MetricsMemory, GoRuntimeMetricsRule{ Matcher: regexp.MustCompile("^/mycustomrule.*"), }, ), WithoutGoCollectorRuntimeMetrics(regexp.MustCompile("^/gc/.*")), )) http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{})) log.Fatal(http.ListenAndServe(":8080", nil)) } func ExampleGoCollector_DefaultRegister() { // Unregister the default GoCollector. prometheus.Unregister(NewGoCollector()) // Register the default GoCollector with a custom config. prometheus.MustRegister(NewGoCollector(WithGoCollectorRuntimeMetrics( MetricsScheduler, MetricsGC, GoRuntimeMetricsRule{ Matcher: regexp.MustCompile("^/mycustomrule.*"), }, ), )) http.Handle("/metrics", promhttp.Handler()) log.Fatal(http.ListenAndServe(":8080", nil)) } client_golang-1.21.1/prometheus/collectors/process_collector.go000066400000000000000000000050411476160432400250270ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package collectors import "github.com/prometheus/client_golang/prometheus" // ProcessCollectorOpts defines the behavior of a process metrics collector // created with NewProcessCollector. type ProcessCollectorOpts struct { // PidFn returns the PID of the process the collector collects metrics // for. It is called upon each collection. By default, the PID of the // current process is used, as determined on construction time by // calling os.Getpid(). PidFn func() (int, error) // If non-empty, each of the collected metrics is prefixed by the // provided string and an underscore ("_"). Namespace string // If true, any error encountered during collection is reported as an // invalid metric (see NewInvalidMetric). Otherwise, errors are ignored // and the collected metrics will be incomplete. (Possibly, no metrics // will be collected at all.) While that's usually not desired, it is // appropriate for the common "mix-in" of process metrics, where process // metrics are nice to have, but failing to collect them should not // disrupt the collection of the remaining metrics. ReportErrors bool } // NewProcessCollector returns a collector which exports the current state of // process metrics including CPU, memory and file descriptor usage as well as // the process start time. The detailed behavior is defined by the provided // ProcessCollectorOpts. The zero value of ProcessCollectorOpts creates a // collector for the current process with an empty namespace string and no error // reporting. // // The collector only works on operating systems with a Linux-style proc // filesystem and on Microsoft Windows. On other operating systems, it will not // collect any metrics. func NewProcessCollector(opts ProcessCollectorOpts) prometheus.Collector { //nolint:staticcheck // Ignore SA1019 until v2. return prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{ PidFn: opts.PidFn, Namespace: opts.Namespace, ReportErrors: opts.ReportErrors, }) } client_golang-1.21.1/prometheus/collectors/version/000077500000000000000000000000001476160432400224415ustar00rootroot00000000000000client_golang-1.21.1/prometheus/collectors/version/version.go000066400000000000000000000027351476160432400244640ustar00rootroot00000000000000// Copyright 2016 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package version import ( "fmt" "github.com/prometheus/common/version" "github.com/prometheus/client_golang/prometheus" ) // NewCollector returns a collector that exports metrics about current version // information. func NewCollector(program string) prometheus.Collector { return prometheus.NewGaugeFunc( prometheus.GaugeOpts{ Namespace: program, Name: "build_info", Help: fmt.Sprintf( "A metric with a constant '1' value labeled by version, revision, branch, goversion from which %s was built, and the goos and goarch for the build.", program, ), ConstLabels: prometheus.Labels{ "version": version.Version, "revision": version.GetRevision(), "branch": version.Branch, "goversion": version.GoVersion, "goos": version.GoOS, "goarch": version.GoArch, "tags": version.GetTags(), }, }, func() float64 { return 1 }, ) } client_golang-1.21.1/prometheus/counter.go000066400000000000000000000310071476160432400206120ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "errors" "math" "sync/atomic" "time" dto "github.com/prometheus/client_model/go" "google.golang.org/protobuf/types/known/timestamppb" ) // Counter is a Metric that represents a single numerical value that only ever // goes up. That implies that it cannot be used to count items whose number can // also go down, e.g. the number of currently running goroutines. Those // "counters" are represented by Gauges. // // A Counter is typically used to count requests served, tasks completed, errors // occurred, etc. // // To create Counter instances, use NewCounter. type Counter interface { Metric Collector // Inc increments the counter by 1. Use Add to increment it by arbitrary // non-negative values. Inc() // Add adds the given value to the counter. It panics if the value is < // 0. Add(float64) } // ExemplarAdder is implemented by Counters that offer the option of adding a // value to the Counter together with an exemplar. Its AddWithExemplar method // works like the Add method of the Counter interface but also replaces the // currently saved exemplar (if any) with a new one, created from the provided // value, the current time as timestamp, and the provided labels. Empty Labels // will lead to a valid (label-less) exemplar. But if Labels is nil, the current // exemplar is left in place. AddWithExemplar panics if the value is < 0, if any // of the provided labels are invalid, or if the provided labels contain more // than 128 runes in total. type ExemplarAdder interface { AddWithExemplar(value float64, exemplar Labels) } // CounterOpts is an alias for Opts. See there for doc comments. type CounterOpts Opts // CounterVecOpts bundles the options to create a CounterVec metric. // It is mandatory to set CounterOpts, see there for mandatory fields. VariableLabels // is optional and can safely be left to its default value. type CounterVecOpts struct { CounterOpts // VariableLabels are used to partition the metric vector by the given set // of labels. Each label value will be constrained with the optional Constraint // function, if provided. VariableLabels ConstrainableLabels } // NewCounter creates a new Counter based on the provided CounterOpts. // // The returned implementation also implements ExemplarAdder. It is safe to // perform the corresponding type assertion. // // The returned implementation tracks the counter value in two separate // variables, a float64 and a uint64. The latter is used to track calls of the // Inc method and calls of the Add method with a value that can be represented // as a uint64. This allows atomic increments of the counter with optimal // performance. (It is common to have an Inc call in very hot execution paths.) // Both internal tracking values are added up in the Write method. This has to // be taken into account when it comes to precision and overflow behavior. func NewCounter(opts CounterOpts) Counter { desc := NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, nil, opts.ConstLabels, ) if opts.now == nil { opts.now = time.Now } result := &counter{desc: desc, labelPairs: desc.constLabelPairs, now: opts.now} result.init(result) // Init self-collection. result.createdTs = timestamppb.New(opts.now()) return result } type counter struct { // valBits contains the bits of the represented float64 value, while // valInt stores values that are exact integers. Both have to go first // in the struct to guarantee alignment for atomic operations. // http://golang.org/pkg/sync/atomic/#pkg-note-BUG valBits uint64 valInt uint64 selfCollector desc *Desc createdTs *timestamppb.Timestamp labelPairs []*dto.LabelPair exemplar atomic.Value // Containing nil or a *dto.Exemplar. // now is for testing purposes, by default it's time.Now. now func() time.Time } func (c *counter) Desc() *Desc { return c.desc } func (c *counter) Add(v float64) { if v < 0 { panic(errors.New("counter cannot decrease in value")) } ival := uint64(v) if float64(ival) == v { atomic.AddUint64(&c.valInt, ival) return } for { oldBits := atomic.LoadUint64(&c.valBits) newBits := math.Float64bits(math.Float64frombits(oldBits) + v) if atomic.CompareAndSwapUint64(&c.valBits, oldBits, newBits) { return } } } func (c *counter) AddWithExemplar(v float64, e Labels) { c.Add(v) c.updateExemplar(v, e) } func (c *counter) Inc() { atomic.AddUint64(&c.valInt, 1) } func (c *counter) get() float64 { fval := math.Float64frombits(atomic.LoadUint64(&c.valBits)) ival := atomic.LoadUint64(&c.valInt) return fval + float64(ival) } func (c *counter) Write(out *dto.Metric) error { // Read the Exemplar first and the value second. This is to avoid a race condition // where users see an exemplar for a not-yet-existing observation. var exemplar *dto.Exemplar if e := c.exemplar.Load(); e != nil { exemplar = e.(*dto.Exemplar) } val := c.get() return populateMetric(CounterValue, val, c.labelPairs, exemplar, out, c.createdTs) } func (c *counter) updateExemplar(v float64, l Labels) { if l == nil { return } e, err := newExemplar(v, c.now(), l) if err != nil { panic(err) } c.exemplar.Store(e) } // CounterVec is a Collector that bundles a set of Counters that all share the // same Desc, but have different values for their variable labels. This is used // if you want to count the same thing partitioned by various dimensions // (e.g. number of HTTP requests, partitioned by response code and // method). Create instances with NewCounterVec. type CounterVec struct { *MetricVec } // NewCounterVec creates a new CounterVec based on the provided CounterOpts and // partitioned by the given label names. func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec { return V2.NewCounterVec(CounterVecOpts{ CounterOpts: opts, VariableLabels: UnconstrainedLabels(labelNames), }) } // NewCounterVec creates a new CounterVec based on the provided CounterVecOpts. func (v2) NewCounterVec(opts CounterVecOpts) *CounterVec { desc := V2.NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, opts.VariableLabels, opts.ConstLabels, ) if opts.now == nil { opts.now = time.Now } return &CounterVec{ MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { if len(lvs) != len(desc.variableLabels.names) { panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, lvs)) } result := &counter{desc: desc, labelPairs: MakeLabelPairs(desc, lvs), now: opts.now} result.init(result) // Init self-collection. result.createdTs = timestamppb.New(opts.now()) return result }), } } // GetMetricWithLabelValues returns the Counter for the given slice of label // values (same order as the variable labels in Desc). If that combination of // label values is accessed for the first time, a new Counter is created. // // It is possible to call this method without using the returned Counter to only // create the new Counter but leave it at its starting value 0. See also the // SummaryVec example. // // Keeping the Counter for later use is possible (and should be considered if // performance is critical), but keep in mind that Reset, DeleteLabelValues and // Delete can be used to delete the Counter from the CounterVec. In that case, // the Counter will still exist, but it will not be exported anymore, even if a // Counter with the same label values is created later. // // An error is returned if the number of label values is not the same as the // number of variable labels in Desc (minus any curried labels). // // Note that for more than one label value, this method is prone to mistakes // caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as // an alternative to avoid that type of mistake. For higher label numbers, the // latter has a much more readable (albeit more verbose) syntax, but it comes // with a performance overhead (for creating and processing the Labels map). // See also the GaugeVec example. func (v *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) { metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...) if metric != nil { return metric.(Counter), err } return nil, err } // GetMetricWith returns the Counter for the given Labels map (the label names // must match those of the variable labels in Desc). If that label map is // accessed for the first time, a new Counter is created. Implications of // creating a Counter without using it and keeping the Counter for later use are // the same as for GetMetricWithLabelValues. // // An error is returned if the number and names of the Labels are inconsistent // with those of the variable labels in Desc (minus any curried labels). // // This method is used for the same purpose as // GetMetricWithLabelValues(...string). See there for pros and cons of the two // methods. func (v *CounterVec) GetMetricWith(labels Labels) (Counter, error) { metric, err := v.MetricVec.GetMetricWith(labels) if metric != nil { return metric.(Counter), err } return nil, err } // WithLabelValues works as GetMetricWithLabelValues, but panics where // GetMetricWithLabelValues would have returned an error. Not returning an // error allows shortcuts like // // myVec.WithLabelValues("404", "GET").Add(42) func (v *CounterVec) WithLabelValues(lvs ...string) Counter { c, err := v.GetMetricWithLabelValues(lvs...) if err != nil { panic(err) } return c } // With works as GetMetricWith, but panics where GetMetricWithLabels would have // returned an error. Not returning an error allows shortcuts like // // myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42) func (v *CounterVec) With(labels Labels) Counter { c, err := v.GetMetricWith(labels) if err != nil { panic(err) } return c } // CurryWith returns a vector curried with the provided labels, i.e. the // returned vector has those labels pre-set for all labeled operations performed // on it. The cardinality of the curried vector is reduced accordingly. The // order of the remaining labels stays the same (just with the curried labels // taken out of the sequence – which is relevant for the // (GetMetric)WithLabelValues methods). It is possible to curry a curried // vector, but only with labels not yet used for currying before. // // The metrics contained in the CounterVec are shared between the curried and // uncurried vectors. They are just accessed differently. Curried and uncurried // vectors behave identically in terms of collection. Only one must be // registered with a given registry (usually the uncurried version). The Reset // method deletes all metrics, even if called on a curried vector. func (v *CounterVec) CurryWith(labels Labels) (*CounterVec, error) { vec, err := v.MetricVec.CurryWith(labels) if vec != nil { return &CounterVec{vec}, err } return nil, err } // MustCurryWith works as CurryWith but panics where CurryWith would have // returned an error. func (v *CounterVec) MustCurryWith(labels Labels) *CounterVec { vec, err := v.CurryWith(labels) if err != nil { panic(err) } return vec } // CounterFunc is a Counter whose value is determined at collect time by calling a // provided function. // // To create CounterFunc instances, use NewCounterFunc. type CounterFunc interface { Metric Collector } // NewCounterFunc creates a new CounterFunc based on the provided // CounterOpts. The value reported is determined by calling the given function // from within the Write method. Take into account that metric collection may // happen concurrently. If that results in concurrent calls to Write, like in // the case where a CounterFunc is directly registered with Prometheus, the // provided function must be concurrency-safe. The function should also honor // the contract for a Counter (values only go up, not down), but compliance will // not be checked. // // Check out the ExampleGaugeFunc examples for the similar GaugeFunc. func NewCounterFunc(opts CounterOpts, function func() float64) CounterFunc { return newValueFunc(NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, nil, opts.ConstLabels, ), CounterValue, function) } client_golang-1.21.1/prometheus/counter_test.go000066400000000000000000000242021476160432400216500ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "math" "strings" "testing" "time" dto "github.com/prometheus/client_model/go" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" ) func TestCounterAdd(t *testing.T) { now := time.Now() counter := NewCounter(CounterOpts{ Name: "test", Help: "test help", ConstLabels: Labels{"a": "1", "b": "2"}, now: func() time.Time { return now }, }).(*counter) counter.Inc() if expected, got := 0.0, math.Float64frombits(counter.valBits); expected != got { t.Errorf("Expected %f, got %f.", expected, got) } if expected, got := uint64(1), counter.valInt; expected != got { t.Errorf("Expected %d, got %d.", expected, got) } counter.Add(42) if expected, got := 0.0, math.Float64frombits(counter.valBits); expected != got { t.Errorf("Expected %f, got %f.", expected, got) } if expected, got := uint64(43), counter.valInt; expected != got { t.Errorf("Expected %d, got %d.", expected, got) } counter.Add(24.42) if expected, got := 24.42, math.Float64frombits(counter.valBits); expected != got { t.Errorf("Expected %f, got %f.", expected, got) } if expected, got := uint64(43), counter.valInt; expected != got { t.Errorf("Expected %d, got %d.", expected, got) } if expected, got := "counter cannot decrease in value", decreaseCounter(counter).Error(); expected != got { t.Errorf("Expected error %q, got %q.", expected, got) } m := &dto.Metric{} counter.Write(m) expected := &dto.Metric{ Label: []*dto.LabelPair{ {Name: proto.String("a"), Value: proto.String("1")}, {Name: proto.String("b"), Value: proto.String("2")}, }, Counter: &dto.Counter{ Value: proto.Float64(67.42), CreatedTimestamp: timestamppb.New(now), }, } if !proto.Equal(expected, m) { t.Errorf("expected %q, got %q", expected, m) } } func decreaseCounter(c *counter) (err error) { defer func() { if e := recover(); e != nil { err = e.(error) } }() c.Add(-1) return nil } func TestCounterVecGetMetricWithInvalidLabelValues(t *testing.T) { testCases := []struct { desc string labels Labels }{ { desc: "non utf8 label value", labels: Labels{"a": "\xFF"}, }, { desc: "not enough label values", labels: Labels{}, }, { desc: "too many label values", labels: Labels{"a": "1", "b": "2"}, }, } for _, test := range testCases { counterVec := NewCounterVec(CounterOpts{ Name: "test", }, []string{"a"}) labelValues := make([]string, 0, len(test.labels)) for _, val := range test.labels { labelValues = append(labelValues, val) } expectPanic(t, func() { counterVec.WithLabelValues(labelValues...) }, "WithLabelValues: expected panic because: "+test.desc) expectPanic(t, func() { counterVec.With(test.labels) }, "WithLabelValues: expected panic because: "+test.desc) if _, err := counterVec.GetMetricWithLabelValues(labelValues...); err == nil { t.Errorf("GetMetricWithLabelValues: expected error because: %s", test.desc) } if _, err := counterVec.GetMetricWith(test.labels); err == nil { t.Errorf("GetMetricWith: expected error because: %s", test.desc) } } } func expectPanic(t *testing.T, op func(), errorMsg string) { defer func() { if err := recover(); err == nil { t.Error(errorMsg) } }() op() } func TestCounterAddInf(t *testing.T) { now := time.Now() counter := NewCounter(CounterOpts{ Name: "test", Help: "test help", now: func() time.Time { return now }, }).(*counter) counter.Inc() if expected, got := 0.0, math.Float64frombits(counter.valBits); expected != got { t.Errorf("Expected %f, got %f.", expected, got) } if expected, got := uint64(1), counter.valInt; expected != got { t.Errorf("Expected %d, got %d.", expected, got) } counter.Add(math.Inf(1)) if expected, got := math.Inf(1), math.Float64frombits(counter.valBits); expected != got { t.Errorf("valBits expected %f, got %f.", expected, got) } if expected, got := uint64(1), counter.valInt; expected != got { t.Errorf("valInts expected %d, got %d.", expected, got) } counter.Inc() if expected, got := math.Inf(1), math.Float64frombits(counter.valBits); expected != got { t.Errorf("Expected %f, got %f.", expected, got) } if expected, got := uint64(2), counter.valInt; expected != got { t.Errorf("Expected %d, got %d.", expected, got) } m := &dto.Metric{} counter.Write(m) expected := &dto.Metric{ Counter: &dto.Counter{ Value: proto.Float64(math.Inf(1)), CreatedTimestamp: timestamppb.New(now), }, } if !proto.Equal(expected, m) { t.Errorf("expected %q, got %q", expected, m) } } func TestCounterAddLarge(t *testing.T) { now := time.Now() counter := NewCounter(CounterOpts{ Name: "test", Help: "test help", now: func() time.Time { return now }, }).(*counter) // large overflows the underlying type and should therefore be stored in valBits. large := math.Nextafter(float64(math.MaxUint64), 1e20) counter.Add(large) if expected, got := large, math.Float64frombits(counter.valBits); expected != got { t.Errorf("valBits expected %f, got %f.", expected, got) } if expected, got := uint64(0), counter.valInt; expected != got { t.Errorf("valInts expected %d, got %d.", expected, got) } m := &dto.Metric{} counter.Write(m) expected := &dto.Metric{ Counter: &dto.Counter{ Value: proto.Float64(large), CreatedTimestamp: timestamppb.New(now), }, } if !proto.Equal(expected, m) { t.Errorf("expected %q, got %q", expected, m) } } func TestCounterAddSmall(t *testing.T) { now := time.Now() counter := NewCounter(CounterOpts{ Name: "test", Help: "test help", now: func() time.Time { return now }, }).(*counter) small := 0.000000000001 counter.Add(small) if expected, got := small, math.Float64frombits(counter.valBits); expected != got { t.Errorf("valBits expected %f, got %f.", expected, got) } if expected, got := uint64(0), counter.valInt; expected != got { t.Errorf("valInts expected %d, got %d.", expected, got) } m := &dto.Metric{} counter.Write(m) expected := &dto.Metric{ Counter: &dto.Counter{ Value: proto.Float64(small), CreatedTimestamp: timestamppb.New(now), }, } if !proto.Equal(expected, m) { t.Errorf("expected %q, got %q", expected, m) } } func TestCounterExemplar(t *testing.T) { now := time.Now() counter := NewCounter(CounterOpts{ Name: "test", Help: "test help", now: func() time.Time { return now }, }).(*counter) ts := timestamppb.New(now) if err := ts.CheckValid(); err != nil { t.Fatal(err) } expectedExemplar := &dto.Exemplar{ Label: []*dto.LabelPair{ {Name: proto.String("foo"), Value: proto.String("bar")}, }, Value: proto.Float64(42), Timestamp: ts, } counter.AddWithExemplar(42, Labels{"foo": "bar"}) if expected, got := expectedExemplar.String(), counter.exemplar.Load().(*dto.Exemplar).String(); expected != got { t.Errorf("expected exemplar %s, got %s.", expected, got) } addExemplarWithInvalidLabel := func() (err error) { defer func() { if e := recover(); e != nil { err = e.(error) } }() // Should panic because of invalid label name. counter.AddWithExemplar(42, Labels{"in\x80valid": "smile"}) return nil } if addExemplarWithInvalidLabel() == nil { t.Error("adding exemplar with invalid label succeeded") } addExemplarWithOversizedLabels := func() (err error) { defer func() { if e := recover(); e != nil { err = e.(error) } }() // Should panic because of 129 runes. counter.AddWithExemplar(42, Labels{ "abcdefghijklmnopqrstuvwxyz": "26+16 characters", "x1234567": "8+15 characters", "z": strings.Repeat("x", 63), }) return nil } if addExemplarWithOversizedLabels() == nil { t.Error("adding exemplar with oversized labels succeeded") } } func TestCounterVecCreatedTimestampWithDeletes(t *testing.T) { now := time.Now() counterVec := NewCounterVec(CounterOpts{ Name: "test", Help: "test help", now: func() time.Time { return now }, }, []string{"label"}) // First use of "With" should populate CT. counterVec.WithLabelValues("1") expected := map[string]time.Time{"1": now} now = now.Add(1 * time.Hour) expectCTsForMetricVecValues(t, counterVec.MetricVec, dto.MetricType_COUNTER, expected) // Two more labels at different times. counterVec.WithLabelValues("2") expected["2"] = now now = now.Add(1 * time.Hour) counterVec.WithLabelValues("3") expected["3"] = now now = now.Add(1 * time.Hour) expectCTsForMetricVecValues(t, counterVec.MetricVec, dto.MetricType_COUNTER, expected) // Recreate metric instance should reset created timestamp to now. counterVec.DeleteLabelValues("1") counterVec.WithLabelValues("1") expected["1"] = now now = now.Add(1 * time.Hour) expectCTsForMetricVecValues(t, counterVec.MetricVec, dto.MetricType_COUNTER, expected) } func expectCTsForMetricVecValues(t testing.TB, vec *MetricVec, typ dto.MetricType, ctsPerLabelValue map[string]time.Time) { t.Helper() for val, ct := range ctsPerLabelValue { var metric dto.Metric m, err := vec.GetMetricWithLabelValues(val) if err != nil { t.Fatal(err) } if err := m.Write(&metric); err != nil { t.Fatal(err) } var gotTs time.Time switch typ { case dto.MetricType_COUNTER: gotTs = metric.Counter.CreatedTimestamp.AsTime() case dto.MetricType_HISTOGRAM: gotTs = metric.Histogram.CreatedTimestamp.AsTime() case dto.MetricType_SUMMARY: gotTs = metric.Summary.CreatedTimestamp.AsTime() default: t.Fatalf("unknown metric type %v", typ) } if !gotTs.Equal(ct) { t.Errorf("expected created timestamp for %s with label value %q: %s, got %s", typ, val, ct, gotTs) } } } client_golang-1.21.1/prometheus/desc.go000066400000000000000000000174311476160432400200560ustar00rootroot00000000000000// Copyright 2016 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "fmt" "sort" "strings" "github.com/cespare/xxhash/v2" dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/model" "google.golang.org/protobuf/proto" "github.com/prometheus/client_golang/prometheus/internal" ) // Desc is the descriptor used by every Prometheus Metric. It is essentially // the immutable meta-data of a Metric. The normal Metric implementations // included in this package manage their Desc under the hood. Users only have to // deal with Desc if they use advanced features like the ExpvarCollector or // custom Collectors and Metrics. // // Descriptors registered with the same registry have to fulfill certain // consistency and uniqueness criteria if they share the same fully-qualified // name: They must have the same help string and the same label names (aka label // dimensions) in each, constLabels and variableLabels, but they must differ in // the values of the constLabels. // // Descriptors that share the same fully-qualified names and the same label // values of their constLabels are considered equal. // // Use NewDesc to create new Desc instances. type Desc struct { // fqName has been built from Namespace, Subsystem, and Name. fqName string // help provides some helpful information about this metric. help string // constLabelPairs contains precalculated DTO label pairs based on // the constant labels. constLabelPairs []*dto.LabelPair // variableLabels contains names of labels and normalization function for // which the metric maintains variable values. variableLabels *compiledLabels // id is a hash of the values of the ConstLabels and fqName. This // must be unique among all registered descriptors and can therefore be // used as an identifier of the descriptor. id uint64 // dimHash is a hash of the label names (preset and variable) and the // Help string. Each Desc with the same fqName must have the same // dimHash. dimHash uint64 // err is an error that occurred during construction. It is reported on // registration time. err error } // NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc // and will be reported on registration time. variableLabels and constLabels can // be nil if no such labels should be set. fqName must not be empty. // // variableLabels only contain the label names. Their label values are variable // and therefore not part of the Desc. (They are managed within the Metric.) // // For constLabels, the label values are constant. Therefore, they are fully // specified in the Desc. See the Collector example for a usage pattern. func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *Desc { return V2.NewDesc(fqName, help, UnconstrainedLabels(variableLabels), constLabels) } // NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc // and will be reported on registration time. variableLabels and constLabels can // be nil if no such labels should be set. fqName must not be empty. // // variableLabels only contain the label names and normalization functions. Their // label values are variable and therefore not part of the Desc. (They are managed // within the Metric.) // // For constLabels, the label values are constant. Therefore, they are fully // specified in the Desc. See the Collector example for a usage pattern. func (v2) NewDesc(fqName, help string, variableLabels ConstrainableLabels, constLabels Labels) *Desc { d := &Desc{ fqName: fqName, help: help, variableLabels: variableLabels.compile(), } if !model.IsValidMetricName(model.LabelValue(fqName)) { d.err = fmt.Errorf("%q is not a valid metric name", fqName) return d } // labelValues contains the label values of const labels (in order of // their sorted label names) plus the fqName (at position 0). labelValues := make([]string, 1, len(constLabels)+1) labelValues[0] = fqName labelNames := make([]string, 0, len(constLabels)+len(d.variableLabels.names)) labelNameSet := map[string]struct{}{} // First add only the const label names and sort them... for labelName := range constLabels { if !checkLabelName(labelName) { d.err = fmt.Errorf("%q is not a valid label name for metric %q", labelName, fqName) return d } labelNames = append(labelNames, labelName) labelNameSet[labelName] = struct{}{} } sort.Strings(labelNames) // ... so that we can now add const label values in the order of their names. for _, labelName := range labelNames { labelValues = append(labelValues, constLabels[labelName]) } // Validate the const label values. They can't have a wrong cardinality, so // use in len(labelValues) as expectedNumberOfValues. if err := validateLabelValues(labelValues, len(labelValues)); err != nil { d.err = err return d } // Now add the variable label names, but prefix them with something that // cannot be in a regular label name. That prevents matching the label // dimension with a different mix between preset and variable labels. for _, label := range d.variableLabels.names { if !checkLabelName(label) { d.err = fmt.Errorf("%q is not a valid label name for metric %q", label, fqName) return d } labelNames = append(labelNames, "$"+label) labelNameSet[label] = struct{}{} } if len(labelNames) != len(labelNameSet) { d.err = fmt.Errorf("duplicate label names in constant and variable labels for metric %q", fqName) return d } xxh := xxhash.New() for _, val := range labelValues { xxh.WriteString(val) xxh.Write(separatorByteSlice) } d.id = xxh.Sum64() // Sort labelNames so that order doesn't matter for the hash. sort.Strings(labelNames) // Now hash together (in this order) the help string and the sorted // label names. xxh.Reset() xxh.WriteString(help) xxh.Write(separatorByteSlice) for _, labelName := range labelNames { xxh.WriteString(labelName) xxh.Write(separatorByteSlice) } d.dimHash = xxh.Sum64() d.constLabelPairs = make([]*dto.LabelPair, 0, len(constLabels)) for n, v := range constLabels { d.constLabelPairs = append(d.constLabelPairs, &dto.LabelPair{ Name: proto.String(n), Value: proto.String(v), }) } sort.Sort(internal.LabelPairSorter(d.constLabelPairs)) return d } // NewInvalidDesc returns an invalid descriptor, i.e. a descriptor with the // provided error set. If a collector returning such a descriptor is registered, // registration will fail with the provided error. NewInvalidDesc can be used by // a Collector to signal inability to describe itself. func NewInvalidDesc(err error) *Desc { return &Desc{ err: err, } } func (d *Desc) String() string { lpStrings := make([]string, 0, len(d.constLabelPairs)) for _, lp := range d.constLabelPairs { lpStrings = append( lpStrings, fmt.Sprintf("%s=%q", lp.GetName(), lp.GetValue()), ) } vlStrings := []string{} if d.variableLabels != nil { vlStrings = make([]string, 0, len(d.variableLabels.names)) for _, vl := range d.variableLabels.names { if fn, ok := d.variableLabels.labelConstraints[vl]; ok && fn != nil { vlStrings = append(vlStrings, fmt.Sprintf("c(%s)", vl)) } else { vlStrings = append(vlStrings, vl) } } } return fmt.Sprintf( "Desc{fqName: %q, help: %q, constLabels: {%s}, variableLabels: {%s}}", d.fqName, d.help, strings.Join(lpStrings, ","), strings.Join(vlStrings, ","), ) } client_golang-1.21.1/prometheus/desc_test.go000066400000000000000000000031041476160432400211050ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "testing" ) func TestNewDescInvalidLabelValues(t *testing.T) { desc := NewDesc( "sample_label", "sample label", nil, Labels{"a": "\xFF"}, ) if desc.err == nil { t.Errorf("NewDesc: expected error because: %s", desc.err) } } func TestNewDescNilLabelValues(t *testing.T) { desc := NewDesc( "sample_label", "sample label", nil, nil, ) if desc.err != nil { t.Errorf("NewDesc: unexpected error: %s", desc.err) } } func TestNewDescWithNilLabelValues_String(t *testing.T) { desc := NewDesc( "sample_label", "sample label", nil, nil, ) if desc.String() != `Desc{fqName: "sample_label", help: "sample label", constLabels: {}, variableLabels: {}}` { t.Errorf("String: unexpected output: %s", desc.String()) } } func TestNewInvalidDesc_String(t *testing.T) { desc := NewInvalidDesc( nil, ) if desc.String() != `Desc{fqName: "", help: "", constLabels: {}, variableLabels: {}}` { t.Errorf("String: unexpected output: %s", desc.String()) } } client_golang-1.21.1/prometheus/doc.go000066400000000000000000000235651476160432400177120ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package prometheus is the core instrumentation package. It provides metrics // primitives to instrument code for monitoring. It also offers a registry for // metrics. Sub-packages allow to expose the registered metrics via HTTP // (package promhttp) or push them to a Pushgateway (package push). There is // also a sub-package promauto, which provides metrics constructors with // automatic registration. // // All exported functions and methods are safe to be used concurrently unless // specified otherwise. // // # A Basic Example // // As a starting point, a very basic usage example: // // package main // // import ( // "log" // "net/http" // // "github.com/prometheus/client_golang/prometheus" // "github.com/prometheus/client_golang/prometheus/promhttp" // ) // // type metrics struct { // cpuTemp prometheus.Gauge // hdFailures *prometheus.CounterVec // } // // func NewMetrics(reg prometheus.Registerer) *metrics { // m := &metrics{ // cpuTemp: prometheus.NewGauge(prometheus.GaugeOpts{ // Name: "cpu_temperature_celsius", // Help: "Current temperature of the CPU.", // }), // hdFailures: prometheus.NewCounterVec( // prometheus.CounterOpts{ // Name: "hd_errors_total", // Help: "Number of hard-disk errors.", // }, // []string{"device"}, // ), // } // reg.MustRegister(m.cpuTemp) // reg.MustRegister(m.hdFailures) // return m // } // // func main() { // // Create a non-global registry. // reg := prometheus.NewRegistry() // // // Create new metrics and register them using the custom registry. // m := NewMetrics(reg) // // Set values for the new created metrics. // m.cpuTemp.Set(65.3) // m.hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc() // // // Expose metrics and custom registry via an HTTP server // // using the HandleFor function. "/metrics" is the usual endpoint for that. // http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg})) // log.Fatal(http.ListenAndServe(":8080", nil)) // } // // This is a complete program that exports two metrics, a Gauge and a Counter, // the latter with a label attached to turn it into a (one-dimensional) vector. // It register the metrics using a custom registry and exposes them via an HTTP server // on the /metrics endpoint. // // # Metrics // // The number of exported identifiers in this package might appear a bit // overwhelming. However, in addition to the basic plumbing shown in the example // above, you only need to understand the different metric types and their // vector versions for basic usage. Furthermore, if you are not concerned with // fine-grained control of when and how to register metrics with the registry, // have a look at the promauto package, which will effectively allow you to // ignore registration altogether in simple cases. // // Above, you have already touched the Counter and the Gauge. There are two more // advanced metric types: the Summary and Histogram. A more thorough description // of those four metric types can be found in the Prometheus docs: // https://prometheus.io/docs/concepts/metric_types/ // // In addition to the fundamental metric types Gauge, Counter, Summary, and // Histogram, a very important part of the Prometheus data model is the // partitioning of samples along dimensions called labels, which results in // metric vectors. The fundamental types are GaugeVec, CounterVec, SummaryVec, // and HistogramVec. // // While only the fundamental metric types implement the Metric interface, both // the metrics and their vector versions implement the Collector interface. A // Collector manages the collection of a number of Metrics, but for convenience, // a Metric can also β€œcollect itself”. Note that Gauge, Counter, Summary, and // Histogram are interfaces themselves while GaugeVec, CounterVec, SummaryVec, // and HistogramVec are not. // // To create instances of Metrics and their vector versions, you need a suitable // …Opts struct, i.e. GaugeOpts, CounterOpts, SummaryOpts, or HistogramOpts. // // # Custom Collectors and constant Metrics // // While you could create your own implementations of Metric, most likely you // will only ever implement the Collector interface on your own. At a first // glance, a custom Collector seems handy to bundle Metrics for common // registration (with the prime example of the different metric vectors above, // which bundle all the metrics of the same name but with different labels). // // There is a more involved use case, too: If you already have metrics // available, created outside of the Prometheus context, you don't need the // interface of the various Metric types. You essentially want to mirror the // existing numbers into Prometheus Metrics during collection. An own // implementation of the Collector interface is perfect for that. You can create // Metric instances β€œon the fly” using NewConstMetric, NewConstHistogram, and // NewConstSummary (and their respective Must… versions). NewConstMetric is used // for all metric types with just a float64 as their value: Counter, Gauge, and // a special β€œtype” called Untyped. Use the latter if you are not sure if the // mirrored metric is a Counter or a Gauge. Creation of the Metric instance // happens in the Collect method. The Describe method has to return separate // Desc instances, representative of the β€œthrow-away” metrics to be created // later. NewDesc comes in handy to create those Desc instances. Alternatively, // you could return no Desc at all, which will mark the Collector β€œunchecked”. // No checks are performed at registration time, but metric consistency will // still be ensured at scrape time, i.e. any inconsistencies will lead to scrape // errors. Thus, with unchecked Collectors, the responsibility to not collect // metrics that lead to inconsistencies in the total scrape result lies with the // implementer of the Collector. While this is not a desirable state, it is // sometimes necessary. The typical use case is a situation where the exact // metrics to be returned by a Collector cannot be predicted at registration // time, but the implementer has sufficient knowledge of the whole system to // guarantee metric consistency. // // The Collector example illustrates the use case. You can also look at the // source code of the processCollector (mirroring process metrics), the // goCollector (mirroring Go metrics), or the expvarCollector (mirroring expvar // metrics) as examples that are used in this package itself. // // If you just need to call a function to get a single float value to collect as // a metric, GaugeFunc, CounterFunc, or UntypedFunc might be interesting // shortcuts. // // # Advanced Uses of the Registry // // While MustRegister is the by far most common way of registering a Collector, // sometimes you might want to handle the errors the registration might cause. // As suggested by the name, MustRegister panics if an error occurs. With the // Register function, the error is returned and can be handled. // // An error is returned if the registered Collector is incompatible or // inconsistent with already registered metrics. The registry aims for // consistency of the collected metrics according to the Prometheus data model. // Inconsistencies are ideally detected at registration time, not at collect // time. The former will usually be detected at start-up time of a program, // while the latter will only happen at scrape time, possibly not even on the // first scrape if the inconsistency only becomes relevant later. That is the // main reason why a Collector and a Metric have to describe themselves to the // registry. // // So far, everything we did operated on the so-called default registry, as it // can be found in the global DefaultRegisterer variable. With NewRegistry, you // can create a custom registry, or you can even implement the Registerer or // Gatherer interfaces yourself. The methods Register and Unregister work in the // same way on a custom registry as the global functions Register and Unregister // on the default registry. // // There are a number of uses for custom registries: You can use registries with // special properties, see NewPedanticRegistry. You can avoid global state, as // it is imposed by the DefaultRegisterer. You can use multiple registries at // the same time to expose different metrics in different ways. You can use // separate registries for testing purposes. // // Also note that the DefaultRegisterer comes registered with a Collector for Go // runtime metrics (via NewGoCollector) and a Collector for process metrics (via // NewProcessCollector). With a custom registry, you are in control and decide // yourself about the Collectors to register. // // # HTTP Exposition // // The Registry implements the Gatherer interface. The caller of the Gather // method can then expose the gathered metrics in some way. Usually, the metrics // are served via HTTP on the /metrics endpoint. That's happening in the example // above. The tools to expose metrics via HTTP are in the promhttp sub-package. // // # Pushing to the Pushgateway // // Function for pushing to the Pushgateway can be found in the push sub-package. // // # Graphite Bridge // // Functions and examples to push metrics from a Gatherer to Graphite can be // found in the graphite sub-package. // // # Other Means of Exposition // // More ways of exposing metrics can easily be added by following the approaches // of the existing implementations. package prometheus client_golang-1.21.1/prometheus/example_clustermanager_test.go000066400000000000000000000117061476160432400247250ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus_test import ( "log" "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) // ClusterManager is an example for a system that might have been built without // Prometheus in mind. It models a central manager of jobs running in a // cluster. Thus, we implement a custom Collector called // ClusterManagerCollector, which collects information from a ClusterManager // using its provided methods and turns them into Prometheus Metrics for // collection. // // An additional challenge is that multiple instances of the ClusterManager are // run within the same binary, each in charge of a different zone. We need to // make use of wrapping Registerers to be able to register each // ClusterManagerCollector instance with Prometheus. type ClusterManager struct { Zone string // Contains many more fields not listed in this example. } // ReallyExpensiveAssessmentOfTheSystemState is a mock for the data gathering a // real cluster manager would have to do. Since it may actually be really // expensive, it must only be called once per collection. This implementation, // obviously, only returns some made-up data. func (c *ClusterManager) ReallyExpensiveAssessmentOfTheSystemState() ( oomCountByHost map[string]int, ramUsageByHost map[string]float64, ) { // Just example fake data. oomCountByHost = map[string]int{ "foo.example.org": 42, "bar.example.org": 2001, } ramUsageByHost = map[string]float64{ "foo.example.org": 6.023e23, "bar.example.org": 3.14, } return } // ClusterManagerCollector implements the Collector interface. type ClusterManagerCollector struct { ClusterManager *ClusterManager } // Descriptors used by the ClusterManagerCollector below. var ( oomCountDesc = prometheus.NewDesc( "clustermanager_oom_crashes_total", "Number of OOM crashes.", []string{"host"}, nil, ) ramUsageDesc = prometheus.NewDesc( "clustermanager_ram_usage_bytes", "RAM usage as reported to the cluster manager.", []string{"host"}, nil, ) ) // Describe is implemented with DescribeByCollect. That's possible because the // Collect method will always return the same two metrics with the same two // descriptors. func (cc ClusterManagerCollector) Describe(ch chan<- *prometheus.Desc) { prometheus.DescribeByCollect(cc, ch) } // Collect first triggers the ReallyExpensiveAssessmentOfTheSystemState. Then it // creates constant metrics for each host on the fly based on the returned data. // // Note that Collect could be called concurrently, so we depend on // ReallyExpensiveAssessmentOfTheSystemState to be concurrency-safe. func (cc ClusterManagerCollector) Collect(ch chan<- prometheus.Metric) { oomCountByHost, ramUsageByHost := cc.ClusterManager.ReallyExpensiveAssessmentOfTheSystemState() for host, oomCount := range oomCountByHost { ch <- prometheus.MustNewConstMetric( oomCountDesc, prometheus.CounterValue, float64(oomCount), host, ) } for host, ramUsage := range ramUsageByHost { ch <- prometheus.MustNewConstMetric( ramUsageDesc, prometheus.GaugeValue, ramUsage, host, ) } } // NewClusterManager first creates a Prometheus-ignorant ClusterManager // instance. Then, it creates a ClusterManagerCollector for the just created // ClusterManager. Finally, it registers the ClusterManagerCollector with a // wrapping Registerer that adds the zone as a label. In this way, the metrics // collected by different ClusterManagerCollectors do not collide. func NewClusterManager(zone string, reg prometheus.Registerer) *ClusterManager { c := &ClusterManager{ Zone: zone, } cc := ClusterManagerCollector{ClusterManager: c} prometheus.WrapRegistererWith(prometheus.Labels{"zone": zone}, reg).MustRegister(cc) return c } func ExampleCollector() { // Since we are dealing with custom Collector implementations, it might // be a good idea to try it out with a pedantic registry. reg := prometheus.NewPedanticRegistry() // Construct cluster managers. In real code, we would assign them to // variables to then do something with them. NewClusterManager("db", reg) NewClusterManager("ca", reg) // Add the standard process and Go metrics to the custom registry. reg.MustRegister( prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}), prometheus.NewGoCollector(), ) http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{})) log.Fatal(http.ListenAndServe(":8080", nil)) } client_golang-1.21.1/prometheus/example_metricvec_test.go000066400000000000000000000100731476160432400236660ustar00rootroot00000000000000// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus_test import ( "fmt" "google.golang.org/protobuf/proto" dto "github.com/prometheus/client_model/go" "github.com/prometheus/client_golang/prometheus" ) // Info implements an info pseudo-metric, which is modeled as a Gauge that // always has a value of 1. In practice, you would just use a Gauge directly, // but for this example, we pretend it would be useful to have a β€œnative” // implementation. type Info struct { desc *prometheus.Desc labelPairs []*dto.LabelPair } func (i Info) Desc() *prometheus.Desc { return i.desc } func (i Info) Write(out *dto.Metric) error { out.Label = i.labelPairs out.Gauge = &dto.Gauge{Value: proto.Float64(1)} return nil } // InfoVec is the vector version for Info. As an info metric never changes, we // wouldn't really need to wrap GetMetricWithLabelValues and GetMetricWith // because Info has no additional methods compared to the vanilla Metric that // the unwrapped MetricVec methods return. However, to demonstrate all there is // to do to fully implement a vector for a custom Metric implementation, we do // it in this example anyway. type InfoVec struct { *prometheus.MetricVec } func NewInfoVec(name, help string, labelNames []string) *InfoVec { desc := prometheus.NewDesc(name, help, labelNames, nil) return &InfoVec{ MetricVec: prometheus.NewMetricVec(desc, func(lvs ...string) prometheus.Metric { if len(lvs) != len(labelNames) { panic("inconsistent label cardinality") } return Info{desc: desc, labelPairs: prometheus.MakeLabelPairs(desc, lvs)} }), } } func (v *InfoVec) GetMetricWithLabelValues(lvs ...string) (Info, error) { metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...) return metric.(Info), err } func (v *InfoVec) GetMetricWith(labels prometheus.Labels) (Info, error) { metric, err := v.MetricVec.GetMetricWith(labels) return metric.(Info), err } func (v *InfoVec) WithLabelValues(lvs ...string) Info { i, err := v.GetMetricWithLabelValues(lvs...) if err != nil { panic(err) } return i } func (v *InfoVec) With(labels prometheus.Labels) Info { i, err := v.GetMetricWith(labels) if err != nil { panic(err) } return i } func (v *InfoVec) CurryWith(labels prometheus.Labels) (*InfoVec, error) { vec, err := v.MetricVec.CurryWith(labels) if vec != nil { return &InfoVec{vec}, err } return nil, err } func (v *InfoVec) MustCurryWith(labels prometheus.Labels) *InfoVec { vec, err := v.CurryWith(labels) if err != nil { panic(err) } return vec } func ExampleMetricVec() { infoVec := NewInfoVec( "library_version_info", "Versions of the libraries used in this binary.", []string{"library", "version"}, ) infoVec.WithLabelValues("prometheus/client_golang", "1.7.1") infoVec.WithLabelValues("k8s.io/client-go", "0.18.8") // Just for demonstration, let's check the state of the InfoVec by // registering it with a custom registry and then let it collect the // metrics. reg := prometheus.NewRegistry() reg.MustRegister(infoVec) metricFamilies, err := reg.Gather() if err != nil || len(metricFamilies) != 1 { panic("unexpected behavior of custom test registry") } fmt.Println(toNormalizedJSON(metricFamilies[0])) // Output: // {"name":"library_version_info","help":"Versions of the libraries used in this binary.","type":"GAUGE","metric":[{"label":[{"name":"library","value":"k8s.io/client-go"},{"name":"version","value":"0.18.8"}],"gauge":{"value":1}},{"label":[{"name":"library","value":"prometheus/client_golang"},{"name":"version","value":"1.7.1"}],"gauge":{"value":1}}]} } client_golang-1.21.1/prometheus/example_timer_complex_test.go000066400000000000000000000052311476160432400245540ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus_test import ( "net/http" "github.com/prometheus/client_golang/prometheus" ) // apiRequestDuration tracks the duration separate for each HTTP status // class (1xx, 2xx, ...). This creates a fair amount of time series on // the Prometheus server. Usually, you would track the duration of // serving HTTP request without partitioning by outcome. Do something // like this only if needed. Also note how only status classes are // tracked, not every single status code. The latter would create an // even larger amount of time series. Request counters partitioned by // status code are usually OK as each counter only creates one time // series. Histograms are way more expensive, so partition with care and // only where you really need separate latency tracking. Partitioning by // status class is only an example. In concrete cases, other partitions // might make more sense. var apiRequestDuration = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "api_request_duration_seconds", Help: "Histogram for the request duration of the public API, partitioned by status class.", Buckets: prometheus.ExponentialBuckets(0.1, 1.5, 5), }, []string{"status_class"}, ) func handler(w http.ResponseWriter, r *http.Request) { status := http.StatusOK // The ObserverFunc gets called by the deferred ObserveDuration and // decides which Histogram's Observe method is called. timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) { switch { case status >= 500: // Server error. apiRequestDuration.WithLabelValues("5xx").Observe(v) case status >= 400: // Client error. apiRequestDuration.WithLabelValues("4xx").Observe(v) case status >= 300: // Redirection. apiRequestDuration.WithLabelValues("3xx").Observe(v) case status >= 200: // Success. apiRequestDuration.WithLabelValues("2xx").Observe(v) default: // Informational. apiRequestDuration.WithLabelValues("1xx").Observe(v) } })) defer timer.ObserveDuration() // Handle the request. Set status accordingly. // ... } func ExampleTimer_complex() { http.HandleFunc("/api", handler) } client_golang-1.21.1/prometheus/example_timer_gauge_test.go000066400000000000000000000030521476160432400241740ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus_test import ( "os" "github.com/prometheus/client_golang/prometheus" ) // If a function is called rarely (i.e. not more often than scrapes // happen) or ideally only once (like in a batch job), it can make sense // to use a Gauge for timing the function call. For timing a batch job // and pushing the result to a Pushgateway, see also the comprehensive // example in the push package. var funcDuration = prometheus.NewGauge(prometheus.GaugeOpts{ Name: "example_function_duration_seconds", Help: "Duration of the last call of an example function.", }) func run() error { // The Set method of the Gauge is used to observe the duration. timer := prometheus.NewTimer(prometheus.ObserverFunc(funcDuration.Set)) defer timer.ObserveDuration() // Do something. Return errors as encountered. The use of 'defer' above // makes sure the function is still timed properly. return nil } func ExampleTimer_gauge() { if err := run(); err != nil { os.Exit(1) } } client_golang-1.21.1/prometheus/example_timer_test.go000066400000000000000000000025301476160432400230240ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus_test import ( "math/rand" "time" "github.com/prometheus/client_golang/prometheus" ) var requestDuration = prometheus.NewHistogram(prometheus.HistogramOpts{ Name: "example_request_duration_seconds", Help: "Histogram for the runtime of a simple example function.", Buckets: prometheus.LinearBuckets(0.01, 0.01, 10), }) func ExampleTimer() { // timer times this example function. It uses a Histogram, but a Summary // would also work, as both implement Observer. Check out // https://prometheus.io/docs/practices/histograms/ for differences. timer := prometheus.NewTimer(requestDuration) defer timer.ObserveDuration() // Do something here that takes time. time.Sleep(time.Duration(rand.NormFloat64()*10000+50000) * time.Microsecond) } client_golang-1.21.1/prometheus/examples_test.go000066400000000000000000000672171476160432400220240ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus_test import ( "bytes" "errors" "fmt" "math" "net/http" "runtime" "strings" "time" dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) func ExampleGauge() { opsQueued := prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: "our_company", Subsystem: "blob_storage", Name: "ops_queued", Help: "Number of blob storage operations waiting to be processed.", }) prometheus.MustRegister(opsQueued) // 10 operations queued by the goroutine managing incoming requests. opsQueued.Add(10) // A worker goroutine has picked up a waiting operation. opsQueued.Dec() // And once more... opsQueued.Dec() } func ExampleGaugeVec() { opsQueued := prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: "our_company", Subsystem: "blob_storage", Name: "ops_queued", Help: "Number of blob storage operations waiting to be processed, partitioned by user and type.", }, []string{ // Which user has requested the operation? "user", // Of what type is the operation? "type", }, ) prometheus.MustRegister(opsQueued) // Increase a value using compact (but order-sensitive!) WithLabelValues(). opsQueued.WithLabelValues("bob", "put").Add(4) // Increase a value with a map using WithLabels. More verbose, but order // doesn't matter anymore. opsQueued.With(prometheus.Labels{"type": "delete", "user": "alice"}).Inc() } func ExampleGaugeFunc_simple() { if err := prometheus.Register(prometheus.NewGaugeFunc( prometheus.GaugeOpts{ Subsystem: "runtime", Name: "goroutines_count", Help: "Number of goroutines that currently exist.", }, func() float64 { return float64(runtime.NumGoroutine()) }, )); err == nil { fmt.Println("GaugeFunc 'goroutines_count' registered.") } // Note that the count of goroutines is a gauge (and not a counter) as // it can go up and down. // Output: // GaugeFunc 'goroutines_count' registered. } func ExampleGaugeFunc_constLabels() { // primaryDB and secondaryDB represent two example *sql.DB connections we want to instrument. var primaryDB, secondaryDB interface { Stats() struct{ OpenConnections int } } if err := prometheus.Register(prometheus.NewGaugeFunc( prometheus.GaugeOpts{ Namespace: "mysql", Name: "connections_open", Help: "Number of mysql connections open.", ConstLabels: prometheus.Labels{"destination": "primary"}, }, func() float64 { return float64(primaryDB.Stats().OpenConnections) }, )); err == nil { fmt.Println(`GaugeFunc 'connections_open' for primary DB connection registered with labels {destination="primary"}`) } if err := prometheus.Register(prometheus.NewGaugeFunc( prometheus.GaugeOpts{ Namespace: "mysql", Name: "connections_open", Help: "Number of mysql connections open.", ConstLabels: prometheus.Labels{"destination": "secondary"}, }, func() float64 { return float64(secondaryDB.Stats().OpenConnections) }, )); err == nil { fmt.Println(`GaugeFunc 'connections_open' for secondary DB connection registered with labels {destination="secondary"}`) } // Note that we can register more than once GaugeFunc with same metric name // as long as their const labels are consistent. // Output: // GaugeFunc 'connections_open' for primary DB connection registered with labels {destination="primary"} // GaugeFunc 'connections_open' for secondary DB connection registered with labels {destination="secondary"} } func ExampleCounterVec() { httpReqs := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "http_requests_total", Help: "How many HTTP requests processed, partitioned by status code and HTTP method.", }, []string{"code", "method"}, ) prometheus.MustRegister(httpReqs) httpReqs.WithLabelValues("404", "POST").Add(42) // If you have to access the same set of labels very frequently, it // might be good to retrieve the metric only once and keep a handle to // it. But beware of deletion of that metric, see below! m := httpReqs.WithLabelValues("200", "GET") for i := 0; i < 1000000; i++ { m.Inc() } // Delete a metric from the vector. If you have previously kept a handle // to that metric (as above), future updates via that handle will go // unseen (even if you re-create a metric with the same label set // later). httpReqs.DeleteLabelValues("200", "GET") // Same thing with the more verbose Labels syntax. httpReqs.Delete(prometheus.Labels{"method": "GET", "code": "200"}) // Just for demonstration, let's check the state of the counter vector // by registering it with a custom registry and then let it collect the // metrics. reg := prometheus.NewRegistry() reg.MustRegister(httpReqs) metricFamilies, err := reg.Gather() if err != nil || len(metricFamilies) != 1 { panic("unexpected behavior of custom test registry") } fmt.Println(toNormalizedJSON(sanitizeMetricFamily(metricFamilies[0]))) // Output: // {"name":"http_requests_total","help":"How many HTTP requests processed, partitioned by status code and HTTP method.","type":"COUNTER","metric":[{"label":[{"name":"code","value":"404"},{"name":"method","value":"POST"}],"counter":{"value":42,"createdTimestamp":"1970-01-01T00:00:10Z"}}]} } func ExampleRegister() { // Imagine you have a worker pool and want to count the tasks completed. taskCounter := prometheus.NewCounter(prometheus.CounterOpts{ Subsystem: "worker_pool", Name: "completed_tasks_total", Help: "Total number of tasks completed.", }) // This will register fine. if err := prometheus.Register(taskCounter); err != nil { fmt.Println(err) } else { fmt.Println("taskCounter registered.") } // Don't forget to tell the HTTP server about the Prometheus handler. // (In a real program, you still need to start the HTTP server...) http.Handle("/metrics", promhttp.Handler()) // Now you can start workers and give every one of them a pointer to // taskCounter and let it increment it whenever it completes a task. taskCounter.Inc() // This has to happen somewhere in the worker code. // But wait, you want to see how individual workers perform. So you need // a vector of counters, with one element for each worker. taskCounterVec := prometheus.NewCounterVec( prometheus.CounterOpts{ Subsystem: "worker_pool", Name: "completed_tasks_total", Help: "Total number of tasks completed.", }, []string{"worker_id"}, ) // Registering will fail because we already have a metric of that name. if err := prometheus.Register(taskCounterVec); err != nil { fmt.Println("taskCounterVec not registered:", err) } else { fmt.Println("taskCounterVec registered.") } // To fix, first unregister the old taskCounter. if prometheus.Unregister(taskCounter) { fmt.Println("taskCounter unregistered.") } // Try registering taskCounterVec again. if err := prometheus.Register(taskCounterVec); err != nil { fmt.Println("taskCounterVec not registered:", err) } else { fmt.Println("taskCounterVec registered.") } // Bummer! Still doesn't work. // Prometheus will not allow you to ever export metrics with // inconsistent help strings or label names. After unregistering, the // unregistered metrics will cease to show up in the /metrics HTTP // response, but the registry still remembers that those metrics had // been exported before. For this example, we will now choose a // different name. (In a real program, you would obviously not export // the obsolete metric in the first place.) taskCounterVec = prometheus.NewCounterVec( prometheus.CounterOpts{ Subsystem: "worker_pool", Name: "completed_tasks_by_id", Help: "Total number of tasks completed.", }, []string{"worker_id"}, ) if err := prometheus.Register(taskCounterVec); err != nil { fmt.Println("taskCounterVec not registered:", err) } else { fmt.Println("taskCounterVec registered.") } // Finally it worked! // The workers have to tell taskCounterVec their id to increment the // right element in the metric vector. taskCounterVec.WithLabelValues("42").Inc() // Code from worker 42. // Each worker could also keep a reference to their own counter element // around. Pick the counter at initialization time of the worker. myCounter := taskCounterVec.WithLabelValues("42") // From worker 42 initialization code. myCounter.Inc() // Somewhere in the code of that worker. // Note that something like WithLabelValues("42", "spurious arg") would // panic (because you have provided too many label values). If you want // to get an error instead, use GetMetricWithLabelValues(...) instead. notMyCounter, err := taskCounterVec.GetMetricWithLabelValues("42", "spurious arg") if err != nil { fmt.Println("Worker initialization failed:", err) } if notMyCounter == nil { fmt.Println("notMyCounter is nil.") } // A different (and somewhat tricky) approach is to use // ConstLabels. ConstLabels are pairs of label names and label values // that never change. Each worker creates and registers an own Counter // instance where the only difference is in the value of the // ConstLabels. Those Counters can all be registered because the // different ConstLabel values guarantee that each worker will increment // a different Counter metric. counterOpts := prometheus.CounterOpts{ Subsystem: "worker_pool", Name: "completed_tasks", Help: "Total number of tasks completed.", ConstLabels: prometheus.Labels{"worker_id": "42"}, } taskCounterForWorker42 := prometheus.NewCounter(counterOpts) if err := prometheus.Register(taskCounterForWorker42); err != nil { fmt.Println("taskCounterVForWorker42 not registered:", err) } else { fmt.Println("taskCounterForWorker42 registered.") } // Obviously, in real code, taskCounterForWorker42 would be a member // variable of a worker struct, and the "42" would be retrieved with a // GetId() method or something. The Counter would be created and // registered in the initialization code of the worker. // For the creation of the next Counter, we can recycle // counterOpts. Just change the ConstLabels. counterOpts.ConstLabels = prometheus.Labels{"worker_id": "2001"} taskCounterForWorker2001 := prometheus.NewCounter(counterOpts) if err := prometheus.Register(taskCounterForWorker2001); err != nil { fmt.Println("taskCounterVForWorker2001 not registered:", err) } else { fmt.Println("taskCounterForWorker2001 registered.") } taskCounterForWorker2001.Inc() taskCounterForWorker42.Inc() taskCounterForWorker2001.Inc() // Yet another approach would be to turn the workers themselves into // Collectors and register them. See the Collector example for details. // Output: // taskCounter registered. // taskCounterVec not registered: a previously registered descriptor with the same fully-qualified name as Desc{fqName: "worker_pool_completed_tasks_total", help: "Total number of tasks completed.", constLabels: {}, variableLabels: {worker_id}} has different label names or a different help string // taskCounter unregistered. // taskCounterVec not registered: a previously registered descriptor with the same fully-qualified name as Desc{fqName: "worker_pool_completed_tasks_total", help: "Total number of tasks completed.", constLabels: {}, variableLabels: {worker_id}} has different label names or a different help string // taskCounterVec registered. // Worker initialization failed: inconsistent label cardinality: expected 1 label values but got 2 in []string{"42", "spurious arg"} // notMyCounter is nil. // taskCounterForWorker42 registered. // taskCounterForWorker2001 registered. } func ExampleSummary() { temps := prometheus.NewSummary(prometheus.SummaryOpts{ Name: "pond_temperature_celsius", Help: "The temperature of the frog pond.", Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, }) // Simulate some observations. for i := 0; i < 1000; i++ { temps.Observe(30 + math.Floor(120*math.Sin(float64(i)*0.1))/10) } // Just for demonstration, let's check the state of the summary by // (ab)using its Write method (which is usually only used by Prometheus // internally). metric := &dto.Metric{} temps.Write(metric) fmt.Println(toNormalizedJSON(sanitizeMetric(metric))) // Output: // {"summary":{"sampleCount":"1000","sampleSum":29969.50000000001,"quantile":[{"quantile":0.5,"value":31.1},{"quantile":0.9,"value":41.3},{"quantile":0.99,"value":41.9}],"createdTimestamp":"1970-01-01T00:00:10Z"}} } func ExampleSummaryVec() { temps := prometheus.NewSummaryVec( prometheus.SummaryOpts{ Name: "pond_temperature_celsius", Help: "The temperature of the frog pond.", Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, }, []string{"species"}, ) // Simulate some observations. for i := 0; i < 1000; i++ { temps.WithLabelValues("litoria-caerulea").Observe(30 + math.Floor(120*math.Sin(float64(i)*0.1))/10) temps.WithLabelValues("lithobates-catesbeianus").Observe(32 + math.Floor(100*math.Cos(float64(i)*0.11))/10) } // Create a Summary without any observations. temps.WithLabelValues("leiopelma-hochstetteri") // Just for demonstration, let's check the state of the summary vector // by registering it with a custom registry and then let it collect the // metrics. reg := prometheus.NewRegistry() reg.MustRegister(temps) metricFamilies, err := reg.Gather() if err != nil || len(metricFamilies) != 1 { panic("unexpected behavior of custom test registry") } fmt.Println(toNormalizedJSON(sanitizeMetricFamily(metricFamilies[0]))) // Output: // {"name":"pond_temperature_celsius","help":"The temperature of the frog pond.","type":"SUMMARY","metric":[{"label":[{"name":"species","value":"leiopelma-hochstetteri"}],"summary":{"sampleCount":"0","sampleSum":0,"quantile":[{"quantile":0.5,"value":"NaN"},{"quantile":0.9,"value":"NaN"},{"quantile":0.99,"value":"NaN"}],"createdTimestamp":"1970-01-01T00:00:10Z"}},{"label":[{"name":"species","value":"lithobates-catesbeianus"}],"summary":{"sampleCount":"1000","sampleSum":31956.100000000017,"quantile":[{"quantile":0.5,"value":32.4},{"quantile":0.9,"value":41.4},{"quantile":0.99,"value":41.9}],"createdTimestamp":"1970-01-01T00:00:10Z"}},{"label":[{"name":"species","value":"litoria-caerulea"}],"summary":{"sampleCount":"1000","sampleSum":29969.50000000001,"quantile":[{"quantile":0.5,"value":31.1},{"quantile":0.9,"value":41.3},{"quantile":0.99,"value":41.9}],"createdTimestamp":"1970-01-01T00:00:10Z"}}]} } func ExampleNewConstSummary() { desc := prometheus.NewDesc( "http_request_duration_seconds", "A summary of the HTTP request durations.", []string{"code", "method"}, prometheus.Labels{"owner": "example"}, ) // Create a constant summary from values we got from a 3rd party telemetry system. s := prometheus.MustNewConstSummary( desc, 4711, 403.34, map[float64]float64{0.5: 42.3, 0.9: 323.3}, "200", "get", ) // Just for demonstration, let's check the state of the summary by // (ab)using its Write method (which is usually only used by Prometheus // internally). metric := &dto.Metric{} s.Write(metric) fmt.Println(toNormalizedJSON(metric)) // Output: // {"label":[{"name":"code","value":"200"},{"name":"method","value":"get"},{"name":"owner","value":"example"}],"summary":{"sampleCount":"4711","sampleSum":403.34,"quantile":[{"quantile":0.5,"value":42.3},{"quantile":0.9,"value":323.3}]}} } func ExampleNewConstSummaryWithCreatedTimestamp() { desc := prometheus.NewDesc( "http_request_duration_seconds", "A summary of the HTTP request durations.", []string{"code", "method"}, prometheus.Labels{"owner": "example"}, ) // Create a constant summary with created timestamp set createdTs := time.Unix(1719670764, 123) s := prometheus.MustNewConstSummaryWithCreatedTimestamp( desc, 4711, 403.34, map[float64]float64{0.5: 42.3, 0.9: 323.3}, createdTs, "200", "get", ) // Just for demonstration, let's check the state of the summary by // (ab)using its Write method (which is usually only used by Prometheus // internally). metric := &dto.Metric{} s.Write(metric) fmt.Println(toNormalizedJSON(metric)) // Output: // {"label":[{"name":"code","value":"200"},{"name":"method","value":"get"},{"name":"owner","value":"example"}],"summary":{"sampleCount":"4711","sampleSum":403.34,"quantile":[{"quantile":0.5,"value":42.3},{"quantile":0.9,"value":323.3}],"createdTimestamp":"2024-06-29T14:19:24.000000123Z"}} } func ExampleHistogram() { temps := prometheus.NewHistogram(prometheus.HistogramOpts{ Name: "pond_temperature_celsius", Help: "The temperature of the frog pond.", // Sorry, we can't measure how badly it smells. Buckets: prometheus.LinearBuckets(20, 5, 5), // 5 buckets, each 5 centigrade wide. }) // Simulate some observations. for i := 0; i < 1000; i++ { temps.Observe(30 + math.Floor(120*math.Sin(float64(i)*0.1))/10) } // Just for demonstration, let's check the state of the histogram by // (ab)using its Write method (which is usually only used by Prometheus // internally). metric := &dto.Metric{} temps.Write(metric) fmt.Println(toNormalizedJSON(sanitizeMetric(metric))) // Output: // {"histogram":{"sampleCount":"1000","sampleSum":29969.50000000001,"bucket":[{"cumulativeCount":"192","upperBound":20},{"cumulativeCount":"366","upperBound":25},{"cumulativeCount":"501","upperBound":30},{"cumulativeCount":"638","upperBound":35},{"cumulativeCount":"816","upperBound":40}],"createdTimestamp":"1970-01-01T00:00:10Z"}} } func ExampleNewConstHistogram() { desc := prometheus.NewDesc( "http_request_duration_seconds", "A histogram of the HTTP request durations.", []string{"code", "method"}, prometheus.Labels{"owner": "example"}, ) // Create a constant histogram from values we got from a 3rd party telemetry system. h := prometheus.MustNewConstHistogram( desc, 4711, 403.34, map[float64]uint64{25: 121, 50: 2403, 100: 3221, 200: 4233}, "200", "get", ) // Just for demonstration, let's check the state of the histogram by // (ab)using its Write method (which is usually only used by Prometheus // internally). metric := &dto.Metric{} h.Write(metric) fmt.Println(toNormalizedJSON(metric)) // Output: // {"label":[{"name":"code","value":"200"},{"name":"method","value":"get"},{"name":"owner","value":"example"}],"histogram":{"sampleCount":"4711","sampleSum":403.34,"bucket":[{"cumulativeCount":"121","upperBound":25},{"cumulativeCount":"2403","upperBound":50},{"cumulativeCount":"3221","upperBound":100},{"cumulativeCount":"4233","upperBound":200}]}} } func ExampleNewConstHistogramWithCreatedTimestamp() { desc := prometheus.NewDesc( "http_request_duration_seconds", "A histogram of the HTTP request durations.", []string{"code", "method"}, prometheus.Labels{"owner": "example"}, ) createdTs := time.Unix(1719670764, 123) h := prometheus.MustNewConstHistogramWithCreatedTimestamp( desc, 4711, 403.34, map[float64]uint64{25: 121, 50: 2403, 100: 3221, 200: 4233}, createdTs, "200", "get", ) // Just for demonstration, let's check the state of the histogram by // (ab)using its Write method (which is usually only used by Prometheus // internally). metric := &dto.Metric{} h.Write(metric) fmt.Println(toNormalizedJSON(metric)) // Output: // {"label":[{"name":"code","value":"200"},{"name":"method","value":"get"},{"name":"owner","value":"example"}],"histogram":{"sampleCount":"4711","sampleSum":403.34,"bucket":[{"cumulativeCount":"121","upperBound":25},{"cumulativeCount":"2403","upperBound":50},{"cumulativeCount":"3221","upperBound":100},{"cumulativeCount":"4233","upperBound":200}],"createdTimestamp":"2024-06-29T14:19:24.000000123Z"}} } func ExampleNewConstHistogram_WithExemplar() { desc := prometheus.NewDesc( "http_request_duration_seconds", "A histogram of the HTTP request durations.", []string{"code", "method"}, prometheus.Labels{"owner": "example"}, ) // Create a constant histogram from values we got from a 3rd party telemetry system. h := prometheus.MustNewConstHistogram( desc, 4711, 403.34, map[float64]uint64{25: 121, 50: 2403, 100: 3221, 200: 4233}, "200", "get", ) // Wrap const histogram with exemplars for each bucket. exemplarTs, _ := time.Parse(time.RFC850, "Monday, 02-Jan-06 15:04:05 GMT") exemplarLabels := prometheus.Labels{"testName": "testVal"} h = prometheus.MustNewMetricWithExemplars( h, prometheus.Exemplar{Labels: exemplarLabels, Timestamp: exemplarTs, Value: 24.0}, prometheus.Exemplar{Labels: exemplarLabels, Timestamp: exemplarTs, Value: 42.0}, prometheus.Exemplar{Labels: exemplarLabels, Timestamp: exemplarTs, Value: 89.0}, prometheus.Exemplar{Labels: exemplarLabels, Timestamp: exemplarTs, Value: 157.0}, ) // Just for demonstration, let's check the state of the histogram by // (ab)using its Write method (which is usually only used by Prometheus // internally). metric := &dto.Metric{} h.Write(metric) fmt.Println(toNormalizedJSON(metric)) // Output: // {"label":[{"name":"code","value":"200"},{"name":"method","value":"get"},{"name":"owner","value":"example"}],"histogram":{"sampleCount":"4711","sampleSum":403.34,"bucket":[{"cumulativeCount":"121","upperBound":25,"exemplar":{"label":[{"name":"testName","value":"testVal"}],"value":24,"timestamp":"2006-01-02T15:04:05Z"}},{"cumulativeCount":"2403","upperBound":50,"exemplar":{"label":[{"name":"testName","value":"testVal"}],"value":42,"timestamp":"2006-01-02T15:04:05Z"}},{"cumulativeCount":"3221","upperBound":100,"exemplar":{"label":[{"name":"testName","value":"testVal"}],"value":89,"timestamp":"2006-01-02T15:04:05Z"}},{"cumulativeCount":"4233","upperBound":200,"exemplar":{"label":[{"name":"testName","value":"testVal"}],"value":157,"timestamp":"2006-01-02T15:04:05Z"}}]}} } func ExampleAlreadyRegisteredError() { reqCounter := prometheus.NewCounter(prometheus.CounterOpts{ Name: "requests_total", Help: "The total number of requests served.", }) if err := prometheus.Register(reqCounter); err != nil { are := &prometheus.AlreadyRegisteredError{} if errors.As(err, are) { // A counter for that metric has been registered before. // Use the old counter from now on. reqCounter = are.ExistingCollector.(prometheus.Counter) } else { // Something else went wrong! panic(err) } } reqCounter.Inc() } func ExampleGatherers() { reg := prometheus.NewRegistry() temp := prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "temperature_kelvin", Help: "Temperature in Kelvin.", }, []string{"location"}, ) reg.MustRegister(temp) temp.WithLabelValues("outside").Set(273.14) temp.WithLabelValues("inside").Set(298.44) var parser expfmt.TextParser text := ` # TYPE humidity_percent gauge # HELP humidity_percent Humidity in %. humidity_percent{location="outside"} 45.4 humidity_percent{location="inside"} 33.2 # TYPE temperature_kelvin gauge # HELP temperature_kelvin Temperature in Kelvin. temperature_kelvin{location="somewhere else"} 4.5 ` parseText := func() ([]*dto.MetricFamily, error) { parsed, err := parser.TextToMetricFamilies(strings.NewReader(text)) if err != nil { return nil, err } var result []*dto.MetricFamily for _, mf := range parsed { result = append(result, mf) } return result, nil } gatherers := prometheus.Gatherers{ reg, prometheus.GathererFunc(parseText), } gathering, err := gatherers.Gather() if err != nil { fmt.Println(err) } out := &bytes.Buffer{} for _, mf := range gathering { if _, err := expfmt.MetricFamilyToText(out, mf); err != nil { panic(err) } } fmt.Print(out.String()) fmt.Println("----------") // Note how the temperature_kelvin metric family has been merged from // different sources. Now try text = ` # TYPE humidity_percent gauge # HELP humidity_percent Humidity in %. humidity_percent{location="outside"} 45.4 humidity_percent{location="inside"} 33.2 # TYPE temperature_kelvin gauge # HELP temperature_kelvin Temperature in Kelvin. # Duplicate metric: temperature_kelvin{location="outside"} 265.3 # Missing location label (note that this is undesirable but valid): temperature_kelvin 4.5 ` gathering, err = gatherers.Gather() if err != nil { // We expect error collected metric "temperature_kelvin" { label: gauge: } was collected before with the same name and label values // We cannot assert it because of https://github.com/golang/protobuf/issues/1121 if strings.HasPrefix(err.Error(), `collected metric "temperature_kelvin" `) { fmt.Println("Found duplicated metric `temperature_kelvin`") } else { fmt.Print(err) } } // Note that still as many metrics as possible are returned: out.Reset() for _, mf := range gathering { if _, err := expfmt.MetricFamilyToText(out, mf); err != nil { panic(err) } } fmt.Print(out.String()) // Output: // # HELP humidity_percent Humidity in %. // # TYPE humidity_percent gauge // humidity_percent{location="inside"} 33.2 // humidity_percent{location="outside"} 45.4 // # HELP temperature_kelvin Temperature in Kelvin. // # TYPE temperature_kelvin gauge // temperature_kelvin{location="inside"} 298.44 // temperature_kelvin{location="outside"} 273.14 // temperature_kelvin{location="somewhere else"} 4.5 // ---------- // Found duplicated metric `temperature_kelvin` // # HELP humidity_percent Humidity in %. // # TYPE humidity_percent gauge // humidity_percent{location="inside"} 33.2 // humidity_percent{location="outside"} 45.4 // # HELP temperature_kelvin Temperature in Kelvin. // # TYPE temperature_kelvin gauge // temperature_kelvin 4.5 // temperature_kelvin{location="inside"} 298.44 // temperature_kelvin{location="outside"} 273.14 } func ExampleNewMetricWithTimestamp() { desc := prometheus.NewDesc( "temperature_kelvin", "Current temperature in Kelvin.", nil, nil, ) // Create a constant gauge from values we got from an external // temperature reporting system. Those values are reported with a slight // delay, so we want to add the timestamp of the actual measurement. temperatureReportedByExternalSystem := 298.15 timeReportedByExternalSystem := time.Date(2009, time.November, 10, 23, 0, 0, 12345678, time.UTC) s := prometheus.NewMetricWithTimestamp( timeReportedByExternalSystem, prometheus.MustNewConstMetric( desc, prometheus.GaugeValue, temperatureReportedByExternalSystem, ), ) // Just for demonstration, let's check the state of the gauge by // (ab)using its Write method (which is usually only used by Prometheus // internally). metric := &dto.Metric{} s.Write(metric) fmt.Println(toNormalizedJSON(metric)) // Output: // {"gauge":{"value":298.15},"timestampMs":"1257894000012"} } func ExampleNewConstMetricWithCreatedTimestamp() { // Here we have a metric that is reported by an external system. // Besides providing the value, the external system also provides the // timestamp when the metric was created. desc := prometheus.NewDesc( "time_since_epoch_seconds", "Current epoch time in seconds.", nil, nil, ) timeSinceEpochReportedByExternalSystem := time.Date(2009, time.November, 10, 23, 0, 0, 12345678, time.UTC) epoch := time.Unix(0, 0).UTC() s := prometheus.MustNewConstMetricWithCreatedTimestamp( desc, prometheus.CounterValue, float64(timeSinceEpochReportedByExternalSystem.Unix()), epoch, ) metric := &dto.Metric{} s.Write(metric) fmt.Println(toNormalizedJSON(metric)) // Output: // {"counter":{"value":1257894000,"createdTimestamp":"1970-01-01T00:00:00Z"}} } client_golang-1.21.1/prometheus/expvar_collector.go000066400000000000000000000043351476160432400225120ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "encoding/json" "expvar" ) type expvarCollector struct { exports map[string]*Desc } // NewExpvarCollector is the obsolete version of collectors.NewExpvarCollector. // See there for documentation. // // Deprecated: Use collectors.NewExpvarCollector instead. func NewExpvarCollector(exports map[string]*Desc) Collector { return &expvarCollector{ exports: exports, } } // Describe implements Collector. func (e *expvarCollector) Describe(ch chan<- *Desc) { for _, desc := range e.exports { ch <- desc } } // Collect implements Collector. func (e *expvarCollector) Collect(ch chan<- Metric) { for name, desc := range e.exports { var m Metric expVar := expvar.Get(name) if expVar == nil { continue } var v interface{} labels := make([]string, len(desc.variableLabels.names)) if err := json.Unmarshal([]byte(expVar.String()), &v); err != nil { ch <- NewInvalidMetric(desc, err) continue } var processValue func(v interface{}, i int) processValue = func(v interface{}, i int) { if i >= len(labels) { copiedLabels := append(make([]string, 0, len(labels)), labels...) switch v := v.(type) { case float64: m = MustNewConstMetric(desc, UntypedValue, v, copiedLabels...) case bool: if v { m = MustNewConstMetric(desc, UntypedValue, 1, copiedLabels...) } else { m = MustNewConstMetric(desc, UntypedValue, 0, copiedLabels...) } default: return } ch <- m return } vm, ok := v.(map[string]interface{}) if !ok { return } for lv, val := range vm { labels[i] = lv processValue(val, i+1) } } processValue(v, 0) } } client_golang-1.21.1/prometheus/expvar_collector_test.go000066400000000000000000000064521476160432400235530ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus_test import ( "expvar" "fmt" "sort" "strings" dto "github.com/prometheus/client_model/go" "github.com/prometheus/client_golang/prometheus" ) func ExampleNewExpvarCollector() { expvarCollector := prometheus.NewExpvarCollector(map[string]*prometheus.Desc{ "memstats": prometheus.NewDesc( "expvar_memstats", "All numeric memstats as one metric family. Not a good role-model, actually... ;-)", []string{"type"}, nil, ), "lone-int": prometheus.NewDesc( "expvar_lone_int", "Just an expvar int as an example.", nil, nil, ), "http-request-map": prometheus.NewDesc( "expvar_http_request_total", "How many http requests processed, partitioned by status code and http method.", []string{"code", "method"}, nil, ), }) prometheus.MustRegister(expvarCollector) // The Prometheus part is done here. But to show that this example is // doing anything, we have to manually export something via expvar. In // real-life use-cases, some library would already have exported via // expvar what we want to re-export as Prometheus metrics. expvar.NewInt("lone-int").Set(42) expvarMap := expvar.NewMap("http-request-map") var ( expvarMap1, expvarMap2 expvar.Map expvarInt11, expvarInt12, expvarInt21, expvarInt22 expvar.Int ) expvarMap1.Init() expvarMap2.Init() expvarInt11.Set(3) expvarInt12.Set(13) expvarInt21.Set(11) expvarInt22.Set(212) expvarMap1.Set("POST", &expvarInt11) expvarMap1.Set("GET", &expvarInt12) expvarMap2.Set("POST", &expvarInt21) expvarMap2.Set("GET", &expvarInt22) expvarMap.Set("404", &expvarMap1) expvarMap.Set("200", &expvarMap2) // Results in the following expvar map: // "http-request-count": {"200": {"POST": 11, "GET": 212}, "404": {"POST": 3, "GET": 13}} // Let's see what the scrape would yield, but exclude the memstats metrics. metricStrings := []string{} metric := dto.Metric{} metricChan := make(chan prometheus.Metric) go func() { expvarCollector.Collect(metricChan) close(metricChan) }() for m := range metricChan { if !strings.Contains(m.Desc().String(), "expvar_memstats") { metric.Reset() m.Write(&metric) metricStrings = append(metricStrings, toNormalizedJSON(&metric)) } } sort.Strings(metricStrings) for _, s := range metricStrings { fmt.Println(s) } // Output: // {"label":[{"name":"code","value":"200"},{"name":"method","value":"GET"}],"untyped":{"value":212}} // {"label":[{"name":"code","value":"200"},{"name":"method","value":"POST"}],"untyped":{"value":11}} // {"label":[{"name":"code","value":"404"},{"name":"method","value":"GET"}],"untyped":{"value":13}} // {"label":[{"name":"code","value":"404"},{"name":"method","value":"POST"}],"untyped":{"value":3}} // {"untyped":{"value":42}} } client_golang-1.21.1/prometheus/fnv.go000066400000000000000000000022551476160432400177270ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus // Inline and byte-free variant of hash/fnv's fnv64a. const ( offset64 = 14695981039346656037 prime64 = 1099511628211 ) // hashNew initializies a new fnv64a hash value. func hashNew() uint64 { return offset64 } // hashAdd adds a string to a fnv64a hash value, returning the updated hash. func hashAdd(h uint64, s string) uint64 { for i := 0; i < len(s); i++ { h ^= uint64(s[i]) h *= prime64 } return h } // hashAddByte adds a byte to a fnv64a hash value, returning the updated hash. func hashAddByte(h uint64, b byte) uint64 { h ^= uint64(b) h *= prime64 return h } client_golang-1.21.1/prometheus/gauge.go000066400000000000000000000250411476160432400202240ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "math" "sync/atomic" "time" dto "github.com/prometheus/client_model/go" ) // Gauge is a Metric that represents a single numerical value that can // arbitrarily go up and down. // // A Gauge is typically used for measured values like temperatures or current // memory usage, but also "counts" that can go up and down, like the number of // running goroutines. // // To create Gauge instances, use NewGauge. type Gauge interface { Metric Collector // Set sets the Gauge to an arbitrary value. Set(float64) // Inc increments the Gauge by 1. Use Add to increment it by arbitrary // values. Inc() // Dec decrements the Gauge by 1. Use Sub to decrement it by arbitrary // values. Dec() // Add adds the given value to the Gauge. (The value can be negative, // resulting in a decrease of the Gauge.) Add(float64) // Sub subtracts the given value from the Gauge. (The value can be // negative, resulting in an increase of the Gauge.) Sub(float64) // SetToCurrentTime sets the Gauge to the current Unix time in seconds. SetToCurrentTime() } // GaugeOpts is an alias for Opts. See there for doc comments. type GaugeOpts Opts // GaugeVecOpts bundles the options to create a GaugeVec metric. // It is mandatory to set GaugeOpts, see there for mandatory fields. VariableLabels // is optional and can safely be left to its default value. type GaugeVecOpts struct { GaugeOpts // VariableLabels are used to partition the metric vector by the given set // of labels. Each label value will be constrained with the optional Constraint // function, if provided. VariableLabels ConstrainableLabels } // NewGauge creates a new Gauge based on the provided GaugeOpts. // // The returned implementation is optimized for a fast Set method. If you have a // choice for managing the value of a Gauge via Set vs. Inc/Dec/Add/Sub, pick // the former. For example, the Inc method of the returned Gauge is slower than // the Inc method of a Counter returned by NewCounter. This matches the typical // scenarios for Gauges and Counters, where the former tends to be Set-heavy and // the latter Inc-heavy. func NewGauge(opts GaugeOpts) Gauge { desc := NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, nil, opts.ConstLabels, ) result := &gauge{desc: desc, labelPairs: desc.constLabelPairs} result.init(result) // Init self-collection. return result } type gauge struct { // valBits contains the bits of the represented float64 value. It has // to go first in the struct to guarantee alignment for atomic // operations. http://golang.org/pkg/sync/atomic/#pkg-note-BUG valBits uint64 selfCollector desc *Desc labelPairs []*dto.LabelPair } func (g *gauge) Desc() *Desc { return g.desc } func (g *gauge) Set(val float64) { atomic.StoreUint64(&g.valBits, math.Float64bits(val)) } func (g *gauge) SetToCurrentTime() { g.Set(float64(time.Now().UnixNano()) / 1e9) } func (g *gauge) Inc() { g.Add(1) } func (g *gauge) Dec() { g.Add(-1) } func (g *gauge) Add(val float64) { for { oldBits := atomic.LoadUint64(&g.valBits) newBits := math.Float64bits(math.Float64frombits(oldBits) + val) if atomic.CompareAndSwapUint64(&g.valBits, oldBits, newBits) { return } } } func (g *gauge) Sub(val float64) { g.Add(val * -1) } func (g *gauge) Write(out *dto.Metric) error { val := math.Float64frombits(atomic.LoadUint64(&g.valBits)) return populateMetric(GaugeValue, val, g.labelPairs, nil, out, nil) } // GaugeVec is a Collector that bundles a set of Gauges that all share the same // Desc, but have different values for their variable labels. This is used if // you want to count the same thing partitioned by various dimensions // (e.g. number of operations queued, partitioned by user and operation // type). Create instances with NewGaugeVec. type GaugeVec struct { *MetricVec } // NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and // partitioned by the given label names. func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec { return V2.NewGaugeVec(GaugeVecOpts{ GaugeOpts: opts, VariableLabels: UnconstrainedLabels(labelNames), }) } // NewGaugeVec creates a new GaugeVec based on the provided GaugeVecOpts. func (v2) NewGaugeVec(opts GaugeVecOpts) *GaugeVec { desc := V2.NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, opts.VariableLabels, opts.ConstLabels, ) return &GaugeVec{ MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { if len(lvs) != len(desc.variableLabels.names) { panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, lvs)) } result := &gauge{desc: desc, labelPairs: MakeLabelPairs(desc, lvs)} result.init(result) // Init self-collection. return result }), } } // GetMetricWithLabelValues returns the Gauge for the given slice of label // values (same order as the variable labels in Desc). If that combination of // label values is accessed for the first time, a new Gauge is created. // // It is possible to call this method without using the returned Gauge to only // create the new Gauge but leave it at its starting value 0. See also the // SummaryVec example. // // Keeping the Gauge for later use is possible (and should be considered if // performance is critical), but keep in mind that Reset, DeleteLabelValues and // Delete can be used to delete the Gauge from the GaugeVec. In that case, the // Gauge will still exist, but it will not be exported anymore, even if a // Gauge with the same label values is created later. See also the CounterVec // example. // // An error is returned if the number of label values is not the same as the // number of variable labels in Desc (minus any curried labels). // // Note that for more than one label value, this method is prone to mistakes // caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as // an alternative to avoid that type of mistake. For higher label numbers, the // latter has a much more readable (albeit more verbose) syntax, but it comes // with a performance overhead (for creating and processing the Labels map). func (v *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) { metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...) if metric != nil { return metric.(Gauge), err } return nil, err } // GetMetricWith returns the Gauge for the given Labels map (the label names // must match those of the variable labels in Desc). If that label map is // accessed for the first time, a new Gauge is created. Implications of // creating a Gauge without using it and keeping the Gauge for later use are // the same as for GetMetricWithLabelValues. // // An error is returned if the number and names of the Labels are inconsistent // with those of the variable labels in Desc (minus any curried labels). // // This method is used for the same purpose as // GetMetricWithLabelValues(...string). See there for pros and cons of the two // methods. func (v *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) { metric, err := v.MetricVec.GetMetricWith(labels) if metric != nil { return metric.(Gauge), err } return nil, err } // WithLabelValues works as GetMetricWithLabelValues, but panics where // GetMetricWithLabelValues would have returned an error. Not returning an // error allows shortcuts like // // myVec.WithLabelValues("404", "GET").Add(42) func (v *GaugeVec) WithLabelValues(lvs ...string) Gauge { g, err := v.GetMetricWithLabelValues(lvs...) if err != nil { panic(err) } return g } // With works as GetMetricWith, but panics where GetMetricWithLabels would have // returned an error. Not returning an error allows shortcuts like // // myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42) func (v *GaugeVec) With(labels Labels) Gauge { g, err := v.GetMetricWith(labels) if err != nil { panic(err) } return g } // CurryWith returns a vector curried with the provided labels, i.e. the // returned vector has those labels pre-set for all labeled operations performed // on it. The cardinality of the curried vector is reduced accordingly. The // order of the remaining labels stays the same (just with the curried labels // taken out of the sequence – which is relevant for the // (GetMetric)WithLabelValues methods). It is possible to curry a curried // vector, but only with labels not yet used for currying before. // // The metrics contained in the GaugeVec are shared between the curried and // uncurried vectors. They are just accessed differently. Curried and uncurried // vectors behave identically in terms of collection. Only one must be // registered with a given registry (usually the uncurried version). The Reset // method deletes all metrics, even if called on a curried vector. func (v *GaugeVec) CurryWith(labels Labels) (*GaugeVec, error) { vec, err := v.MetricVec.CurryWith(labels) if vec != nil { return &GaugeVec{vec}, err } return nil, err } // MustCurryWith works as CurryWith but panics where CurryWith would have // returned an error. func (v *GaugeVec) MustCurryWith(labels Labels) *GaugeVec { vec, err := v.CurryWith(labels) if err != nil { panic(err) } return vec } // GaugeFunc is a Gauge whose value is determined at collect time by calling a // provided function. // // To create GaugeFunc instances, use NewGaugeFunc. type GaugeFunc interface { Metric Collector } // NewGaugeFunc creates a new GaugeFunc based on the provided GaugeOpts. The // value reported is determined by calling the given function from within the // Write method. Take into account that metric collection may happen // concurrently. Therefore, it must be safe to call the provided function // concurrently. // // NewGaugeFunc is a good way to create an β€œinfo” style metric with a constant // value of 1. Example: // https://github.com/prometheus/common/blob/8558a5b7db3c84fa38b4766966059a7bd5bfa2ee/version/info.go#L36-L56 func NewGaugeFunc(opts GaugeOpts, function func() float64) GaugeFunc { return newValueFunc(NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, nil, opts.ConstLabels, ), GaugeValue, function) } client_golang-1.21.1/prometheus/gauge_test.go000066400000000000000000000115271476160432400212670ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "math" "math/rand" "sync" "testing" "testing/quick" "time" dto "github.com/prometheus/client_model/go" "google.golang.org/protobuf/proto" ) func listenGaugeStream(vals, result chan float64, done chan struct{}) { var sum float64 outer: for { select { case <-done: close(vals) for v := range vals { sum += v } break outer case v := <-vals: sum += v } } result <- sum close(result) } func TestGaugeConcurrency(t *testing.T) { it := func(n uint32) bool { mutations := int(n % 10000) concLevel := int(n%15 + 1) var start, end sync.WaitGroup start.Add(1) end.Add(concLevel) sStream := make(chan float64, mutations*concLevel) result := make(chan float64) done := make(chan struct{}) go listenGaugeStream(sStream, result, done) go func() { end.Wait() close(done) }() gge := NewGauge(GaugeOpts{ Name: "test_gauge", Help: "no help can be found here", }) for i := 0; i < concLevel; i++ { vals := make([]float64, mutations) for j := 0; j < mutations; j++ { vals[j] = rand.Float64() - 0.5 } go func(vals []float64) { start.Wait() for _, v := range vals { sStream <- v gge.Add(v) } end.Done() }(vals) } start.Done() if expected, got := <-result, math.Float64frombits(gge.(*gauge).valBits); math.Abs(expected-got) > 0.000001 { t.Fatalf("expected approx. %f, got %f", expected, got) return false } return true } if err := quick.Check(it, nil); err != nil { t.Fatal(err) } } func TestGaugeVecConcurrency(t *testing.T) { it := func(n uint32) bool { mutations := int(n % 10000) concLevel := int(n%15 + 1) vecLength := int(n%5 + 1) var start, end sync.WaitGroup start.Add(1) end.Add(concLevel) sStreams := make([]chan float64, vecLength) results := make([]chan float64, vecLength) done := make(chan struct{}) for i := 0; i < vecLength; i++ { sStreams[i] = make(chan float64, mutations*concLevel) results[i] = make(chan float64) go listenGaugeStream(sStreams[i], results[i], done) } go func() { end.Wait() close(done) }() gge := NewGaugeVec( GaugeOpts{ Name: "test_gauge", Help: "no help can be found here", }, []string{"label"}, ) for i := 0; i < concLevel; i++ { vals := make([]float64, mutations) pick := make([]int, mutations) for j := 0; j < mutations; j++ { vals[j] = rand.Float64() - 0.5 pick[j] = rand.Intn(vecLength) } go func(vals []float64) { start.Wait() for i, v := range vals { sStreams[pick[i]] <- v gge.WithLabelValues(string('A' + rune(pick[i]))).Add(v) } end.Done() }(vals) } start.Done() for i := range sStreams { if expected, got := <-results[i], math.Float64frombits(gge.WithLabelValues(string('A'+rune(i))).(*gauge).valBits); math.Abs(expected-got) > 0.000001 { t.Fatalf("expected approx. %f, got %f", expected, got) return false } } return true } if err := quick.Check(it, nil); err != nil { t.Fatal(err) } } func TestGaugeFunc(t *testing.T) { gf := NewGaugeFunc( GaugeOpts{ Name: "test_name", Help: "test help", ConstLabels: Labels{"a": "1", "b": "2"}, }, func() float64 { return 3.1415 }, ) if expected, got := `Desc{fqName: "test_name", help: "test help", constLabels: {a="1",b="2"}, variableLabels: {}}`, gf.Desc().String(); expected != got { t.Errorf("expected %q, got %q", expected, got) } m := &dto.Metric{} gf.Write(m) expected := &dto.Metric{ Label: []*dto.LabelPair{ {Name: proto.String("a"), Value: proto.String("1")}, {Name: proto.String("b"), Value: proto.String("2")}, }, Gauge: &dto.Gauge{ Value: proto.Float64(3.1415), }, } if !proto.Equal(expected, m) { t.Errorf("expected %q, got %q", expected, m) } } func TestGaugeSetCurrentTime(t *testing.T) { g := NewGauge(GaugeOpts{ Name: "test_name", Help: "test help", }) g.SetToCurrentTime() unixTime := float64(time.Now().Unix()) m := &dto.Metric{} g.Write(m) delta := unixTime - m.GetGauge().GetValue() // This is just a smoke test to make sure SetToCurrentTime is not // totally off. Tests with current time involved are hard... if math.Abs(delta) > 5 { t.Errorf("Gauge set to current time deviates from current time by more than 5s, delta is %f seconds", delta) } } client_golang-1.21.1/prometheus/gen_go_collector_metrics_set.go000066400000000000000000000127201476160432400250410ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build ignore // +build ignore package main import ( "bytes" "fmt" "go/format" "log" "math" "os" "runtime" "runtime/metrics" "strings" "text/template" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/internal" version "github.com/hashicorp/go-version" ) func main() { var givenVersion string toolVersion := runtime.Version() if len(os.Args) != 2 { log.Printf("requires Go version (e.g. go1.17) as an argument. Since it is not specified, assuming %s.", toolVersion) givenVersion = toolVersion } else { givenVersion = os.Args[1] } log.Printf("given version for Go: %s", givenVersion) log.Printf("tool version for Go: %s", toolVersion) tv, err := version.NewVersion(strings.TrimPrefix(givenVersion, "go")) if err != nil { log.Fatal(err) } toolVersion = strings.Split(strings.TrimPrefix(toolVersion, "go"), " ")[0] gv, err := version.NewVersion(toolVersion) if err != nil { log.Fatal(err) } if !gv.Equal(tv) { log.Fatalf("using Go version %q but expected Go version %q", tv, gv) } v := goVersion(gv.Segments()[1]) log.Printf("generating metrics for Go version %q", v) allDesc := metrics.All() // Find default metrics. var defaultDesc []metrics.Description for _, d := range allDesc { if !internal.GoCollectorDefaultRuntimeMetrics.MatchString(d.Name) { continue } defaultDesc = append(defaultDesc, d) } // Generate code. var buf bytes.Buffer err = testFile.Execute(&buf, struct { AllDescriptions []metrics.Description DefaultDescriptions []metrics.Description GoVersion goVersion Cardinality int }{ AllDescriptions: allDesc, DefaultDescriptions: defaultDesc, GoVersion: v, Cardinality: rmCardinality(), }) if err != nil { log.Fatalf("executing template: %v", err) } // Format it. result, err := format.Source(buf.Bytes()) if err != nil { log.Fatalf("formatting code: %v", err) } // Write it to a file. fname := fmt.Sprintf("go_collector_metrics_%s_test.go", v.Abbr()) if err := os.WriteFile(fname, result, 0o644); err != nil { log.Fatalf("writing file: %v", err) } } type goVersion int func (g goVersion) String() string { return fmt.Sprintf("go1.%d", g) } func (g goVersion) Abbr() string { return fmt.Sprintf("go1%d", g) } func rmCardinality() int { cardinality := 0 // Collect all histogram samples so that we can get their buckets. // The API guarantees that the buckets are always fixed for the lifetime // of the process. var histograms []metrics.Sample for _, d := range metrics.All() { if d.Kind == metrics.KindFloat64Histogram { histograms = append(histograms, metrics.Sample{Name: d.Name}) } else { cardinality++ } } // Handle histograms. metrics.Read(histograms) for i := range histograms { name := histograms[i].Name buckets := internal.RuntimeMetricsBucketsForUnit( histograms[i].Value.Float64Histogram().Buckets, name[strings.IndexRune(name, ':')+1:], ) cardinality += len(buckets) + 3 // Plus total count, sum, and the implicit infinity bucket. // runtime/metrics bucket boundaries are lower-bound-inclusive, but // always represents each actual *boundary* so Buckets is always // 1 longer than Counts, while in Prometheus the mapping is one-to-one, // as the bottom bucket extends to -Inf, and the top infinity bucket is // implicit. Therefore, we should have one fewer bucket than is listed // above. cardinality-- if buckets[len(buckets)-1] == math.Inf(1) { // We already counted the infinity bucket separately. cardinality-- } // Prometheus also doesn't have buckets for -Inf, so they need to be omitted. // See the following PR for more information: // https://github.com/prometheus/client_golang/pull/1049 if buckets[0] == math.Inf(-1) { cardinality-- } } return cardinality } var testFile = template.Must(template.New("testFile").Funcs(map[string]interface{}{ "rm2prom": func(d metrics.Description) string { ns, ss, n, ok := internal.RuntimeMetricsToProm(&d) if !ok { return "" } return prometheus.BuildFQName(ns, ss, n) }, "nextVersion": func(version goVersion) string { return (version + goVersion(1)).String() }, }).Parse(`// Code generated by gen_go_collector_metrics_set.go; DO NOT EDIT. //go:generate go run gen_go_collector_metrics_set.go {{.GoVersion}} //go:build {{.GoVersion}} && !{{nextVersion .GoVersion}} // +build {{.GoVersion}},!{{nextVersion .GoVersion}} package prometheus var ( expectedRuntimeMetrics = map[string]string{ {{- range .AllDescriptions -}} {{- $trans := rm2prom . -}} {{- if ne $trans "" }} {{.Name | printf "%q"}}: {{$trans | printf "%q"}}, {{- end -}} {{end}} } expMetrics = map[string]string{ {{- range .DefaultDescriptions -}} {{- $trans := rm2prom . -}} {{- if ne $trans "" }} {{.Name | printf "%q"}}: {{$trans | printf "%q"}}, {{- end -}} {{end}} } ) const expectedRuntimeMetricsCardinality = {{.Cardinality}} `)) client_golang-1.21.1/prometheus/get_pid.go000066400000000000000000000014141476160432400205450ustar00rootroot00000000000000// Copyright 2015 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build !js || wasm // +build !js wasm package prometheus import "os" func getPIDFn() func() (int, error) { pid := os.Getpid() return func() (int, error) { return pid, nil } } client_golang-1.21.1/prometheus/get_pid_gopherjs.go000066400000000000000000000013511476160432400224460ustar00rootroot00000000000000// Copyright 2015 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build js && !wasm // +build js,!wasm package prometheus func getPIDFn() func() (int, error) { return func() (int, error) { return 1, nil } } client_golang-1.21.1/prometheus/go_collector.go000066400000000000000000000237211476160432400216120ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "runtime" "runtime/debug" "time" ) // goRuntimeMemStats provides the metrics initially provided by runtime.ReadMemStats. // From Go 1.17 those similar (and better) statistics are provided by runtime/metrics, so // while eval closure works on runtime.MemStats, the struct from Go 1.17+ is // populated using runtime/metrics. Those are the defaults we can't alter. func goRuntimeMemStats() memStatsMetrics { return memStatsMetrics{ { desc: NewDesc( memstatNamespace("alloc_bytes"), "Number of bytes allocated in heap and currently in use. Equals to /memory/classes/heap/objects:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.Alloc) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("alloc_bytes_total"), "Total number of bytes allocated in heap until now, even if released already. Equals to /gc/heap/allocs:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.TotalAlloc) }, valType: CounterValue, }, { desc: NewDesc( memstatNamespace("sys_bytes"), "Number of bytes obtained from system. Equals to /memory/classes/total:byte.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.Sys) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("mallocs_total"), // TODO(bwplotka): We could add go_memstats_heap_objects, probably useful for discovery. Let's gather more feedback, kind of a waste of bytes for everybody for compatibility reasons to keep both, and we can't really rename/remove useful metric. "Total number of heap objects allocated, both live and gc-ed. Semantically a counter version for go_memstats_heap_objects gauge. Equals to /gc/heap/allocs:objects + /gc/heap/tiny/allocs:objects.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.Mallocs) }, valType: CounterValue, }, { desc: NewDesc( memstatNamespace("frees_total"), "Total number of heap objects frees. Equals to /gc/heap/frees:objects + /gc/heap/tiny/allocs:objects.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.Frees) }, valType: CounterValue, }, { desc: NewDesc( memstatNamespace("heap_alloc_bytes"), "Number of heap bytes allocated and currently in use, same as go_memstats_alloc_bytes. Equals to /memory/classes/heap/objects:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapAlloc) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("heap_sys_bytes"), "Number of heap bytes obtained from system. Equals to /memory/classes/heap/objects:bytes + /memory/classes/heap/unused:bytes + /memory/classes/heap/released:bytes + /memory/classes/heap/free:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapSys) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("heap_idle_bytes"), "Number of heap bytes waiting to be used. Equals to /memory/classes/heap/released:bytes + /memory/classes/heap/free:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapIdle) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("heap_inuse_bytes"), "Number of heap bytes that are in use. Equals to /memory/classes/heap/objects:bytes + /memory/classes/heap/unused:bytes", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapInuse) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("heap_released_bytes"), "Number of heap bytes released to OS. Equals to /memory/classes/heap/released:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapReleased) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("heap_objects"), "Number of currently allocated objects. Equals to /gc/heap/objects:objects.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapObjects) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("stack_inuse_bytes"), "Number of bytes obtained from system for stack allocator in non-CGO environments. Equals to /memory/classes/heap/stacks:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackInuse) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("stack_sys_bytes"), "Number of bytes obtained from system for stack allocator. Equals to /memory/classes/heap/stacks:bytes + /memory/classes/os-stacks:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackSys) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("mspan_inuse_bytes"), "Number of bytes in use by mspan structures. Equals to /memory/classes/metadata/mspan/inuse:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanInuse) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("mspan_sys_bytes"), "Number of bytes used for mspan structures obtained from system. Equals to /memory/classes/metadata/mspan/inuse:bytes + /memory/classes/metadata/mspan/free:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanSys) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("mcache_inuse_bytes"), "Number of bytes in use by mcache structures. Equals to /memory/classes/metadata/mcache/inuse:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheInuse) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("mcache_sys_bytes"), "Number of bytes used for mcache structures obtained from system. Equals to /memory/classes/metadata/mcache/inuse:bytes + /memory/classes/metadata/mcache/free:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheSys) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("buck_hash_sys_bytes"), "Number of bytes used by the profiling bucket hash table. Equals to /memory/classes/profiling/buckets:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.BuckHashSys) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("gc_sys_bytes"), "Number of bytes used for garbage collection system metadata. Equals to /memory/classes/metadata/other:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.GCSys) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("other_sys_bytes"), "Number of bytes used for other system allocations. Equals to /memory/classes/other:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.OtherSys) }, valType: GaugeValue, }, { desc: NewDesc( memstatNamespace("next_gc_bytes"), "Number of heap bytes when next garbage collection will take place. Equals to /gc/heap/goal:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.NextGC) }, valType: GaugeValue, }, } } type baseGoCollector struct { goroutinesDesc *Desc threadsDesc *Desc gcDesc *Desc gcLastTimeDesc *Desc goInfoDesc *Desc } func newBaseGoCollector() baseGoCollector { return baseGoCollector{ goroutinesDesc: NewDesc( "go_goroutines", "Number of goroutines that currently exist.", nil, nil), threadsDesc: NewDesc( "go_threads", "Number of OS threads created.", nil, nil), gcDesc: NewDesc( "go_gc_duration_seconds", "A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.", nil, nil), gcLastTimeDesc: NewDesc( "go_memstats_last_gc_time_seconds", "Number of seconds since 1970 of last garbage collection.", nil, nil), goInfoDesc: NewDesc( "go_info", "Information about the Go environment.", nil, Labels{"version": runtime.Version()}), } } // Describe returns all descriptions of the collector. func (c *baseGoCollector) Describe(ch chan<- *Desc) { ch <- c.goroutinesDesc ch <- c.threadsDesc ch <- c.gcDesc ch <- c.gcLastTimeDesc ch <- c.goInfoDesc } // Collect returns the current state of all metrics of the collector. func (c *baseGoCollector) Collect(ch chan<- Metric) { ch <- MustNewConstMetric(c.goroutinesDesc, GaugeValue, float64(runtime.NumGoroutine())) n := getRuntimeNumThreads() ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, n) var stats debug.GCStats stats.PauseQuantiles = make([]time.Duration, 5) debug.ReadGCStats(&stats) quantiles := make(map[float64]float64) for idx, pq := range stats.PauseQuantiles[1:] { quantiles[float64(idx+1)/float64(len(stats.PauseQuantiles)-1)] = pq.Seconds() } quantiles[0.0] = stats.PauseQuantiles[0].Seconds() ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), stats.PauseTotal.Seconds(), quantiles) ch <- MustNewConstMetric(c.gcLastTimeDesc, GaugeValue, float64(stats.LastGC.UnixNano())/1e9) ch <- MustNewConstMetric(c.goInfoDesc, GaugeValue, 1) } func memstatNamespace(s string) string { return "go_memstats_" + s } // memStatsMetrics provide description, evaluator, runtime/metrics name, and // value type for memstat metrics. type memStatsMetrics []struct { desc *Desc eval func(*runtime.MemStats) float64 valType ValueType } client_golang-1.21.1/prometheus/go_collector_go116.go000066400000000000000000000071351476160432400225300ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build !go1.17 // +build !go1.17 package prometheus import ( "runtime" "sync" "time" ) type goCollector struct { base baseGoCollector // ms... are memstats related. msLast *runtime.MemStats // Previously collected memstats. msLastTimestamp time.Time msMtx sync.Mutex // Protects msLast and msLastTimestamp. msMetrics memStatsMetrics msRead func(*runtime.MemStats) // For mocking in tests. msMaxWait time.Duration // Wait time for fresh memstats. msMaxAge time.Duration // Maximum allowed age of old memstats. } // NewGoCollector is the obsolete version of collectors.NewGoCollector. // See there for documentation. // // Deprecated: Use collectors.NewGoCollector instead. func NewGoCollector() Collector { msMetrics := goRuntimeMemStats() msMetrics = append(msMetrics, struct { desc *Desc eval func(*runtime.MemStats) float64 valType ValueType }{ // This metric is omitted in Go1.17+, see https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034 desc: NewDesc( memstatNamespace("gc_cpu_fraction"), "The fraction of this program's available CPU time used by the GC since the program started.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return ms.GCCPUFraction }, valType: GaugeValue, }) return &goCollector{ base: newBaseGoCollector(), msLast: &runtime.MemStats{}, msRead: runtime.ReadMemStats, msMaxWait: time.Second, msMaxAge: 5 * time.Minute, msMetrics: msMetrics, } } // Describe returns all descriptions of the collector. func (c *goCollector) Describe(ch chan<- *Desc) { c.base.Describe(ch) for _, i := range c.msMetrics { ch <- i.desc } } // Collect returns the current state of all metrics of the collector. func (c *goCollector) Collect(ch chan<- Metric) { var ( ms = &runtime.MemStats{} done = make(chan struct{}) ) // Start reading memstats first as it might take a while. go func() { c.msRead(ms) c.msMtx.Lock() c.msLast = ms c.msLastTimestamp = time.Now() c.msMtx.Unlock() close(done) }() // Collect base non-memory metrics. c.base.Collect(ch) timer := time.NewTimer(c.msMaxWait) select { case <-done: // Our own ReadMemStats succeeded in time. Use it. timer.Stop() // Important for high collection frequencies to not pile up timers. c.msCollect(ch, ms) return case <-timer.C: // Time out, use last memstats if possible. Continue below. } c.msMtx.Lock() if time.Since(c.msLastTimestamp) < c.msMaxAge { // Last memstats are recent enough. Collect from them under the lock. c.msCollect(ch, c.msLast) c.msMtx.Unlock() return } // If we are here, the last memstats are too old or don't exist. We have // to wait until our own ReadMemStats finally completes. For that to // happen, we have to release the lock. c.msMtx.Unlock() <-done c.msCollect(ch, ms) } func (c *goCollector) msCollect(ch chan<- Metric, ms *runtime.MemStats) { for _, i := range c.msMetrics { ch <- MustNewConstMetric(i.desc, i.valType, i.eval(ms)) } } client_golang-1.21.1/prometheus/go_collector_go116_test.go000066400000000000000000000060531476160432400235650ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build !go1.17 // +build !go1.17 package prometheus import ( "runtime" "testing" "time" dto "github.com/prometheus/client_model/go" ) func TestGoCollectorMemStats(t *testing.T) { var ( c = NewGoCollector().(*goCollector) got uint64 ) checkCollect := func(want uint64) { metricCh := make(chan Metric) endCh := make(chan struct{}) go func() { c.Collect(metricCh) close(endCh) }() Collect: for { select { case metric := <-metricCh: if metric.Desc().fqName != "go_memstats_alloc_bytes" { continue Collect } pb := &dto.Metric{} metric.Write(pb) got = uint64(pb.GetGauge().GetValue()) case <-endCh: break Collect } } if want != got { t.Errorf("unexpected value of go_memstats_alloc_bytes, want %d, got %d", want, got) } } // Speed up the timing to make the test faster. c.msMaxWait = 5 * time.Millisecond c.msMaxAge = 50 * time.Millisecond // Scenario 1: msRead responds slowly, no previous memstats available, // msRead is executed anyway. c.msRead = func(ms *runtime.MemStats) { time.Sleep(20 * time.Millisecond) ms.Alloc = 1 } checkCollect(1) // Now msLast is set. c.msMtx.Lock() if want, got := uint64(1), c.msLast.Alloc; want != got { t.Errorf("unexpected of msLast.Alloc, want %d, got %d", want, got) } c.msMtx.Unlock() // Scenario 2: msRead responds fast, previous memstats available, new // value collected. c.msRead = func(ms *runtime.MemStats) { ms.Alloc = 2 } checkCollect(2) // msLast is set, too. c.msMtx.Lock() if want, got := uint64(2), c.msLast.Alloc; want != got { t.Errorf("unexpected of msLast.Alloc, want %d, got %d", want, got) } c.msMtx.Unlock() // Scenario 3: msRead responds slowly, previous memstats available, old // value collected. c.msRead = func(ms *runtime.MemStats) { time.Sleep(20 * time.Millisecond) ms.Alloc = 3 } checkCollect(2) // After waiting, new value is still set in msLast. time.Sleep(80 * time.Millisecond) c.msMtx.Lock() if want, got := uint64(3), c.msLast.Alloc; want != got { t.Errorf("unexpected of msLast.Alloc, want %d, got %d", want, got) } c.msMtx.Unlock() // Scenario 4: msRead responds slowly, previous memstats is too old, new // value collected. c.msRead = func(ms *runtime.MemStats) { time.Sleep(20 * time.Millisecond) ms.Alloc = 4 } checkCollect(4) c.msMtx.Lock() if want, got := uint64(4), c.msLast.Alloc; want != got { t.Errorf("unexpected of msLast.Alloc, want %d, got %d", want, got) } c.msMtx.Unlock() } client_golang-1.21.1/prometheus/go_collector_latest.go000066400000000000000000000452511476160432400231700ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build go1.17 // +build go1.17 package prometheus import ( "fmt" "math" "runtime" "runtime/metrics" "strings" "sync" "github.com/prometheus/client_golang/prometheus/internal" dto "github.com/prometheus/client_model/go" "google.golang.org/protobuf/proto" ) const ( // constants for strings referenced more than once. goGCHeapTinyAllocsObjects = "/gc/heap/tiny/allocs:objects" goGCHeapAllocsObjects = "/gc/heap/allocs:objects" goGCHeapFreesObjects = "/gc/heap/frees:objects" goGCHeapFreesBytes = "/gc/heap/frees:bytes" goGCHeapAllocsBytes = "/gc/heap/allocs:bytes" goGCHeapObjects = "/gc/heap/objects:objects" goGCHeapGoalBytes = "/gc/heap/goal:bytes" goMemoryClassesTotalBytes = "/memory/classes/total:bytes" goMemoryClassesHeapObjectsBytes = "/memory/classes/heap/objects:bytes" goMemoryClassesHeapUnusedBytes = "/memory/classes/heap/unused:bytes" goMemoryClassesHeapReleasedBytes = "/memory/classes/heap/released:bytes" goMemoryClassesHeapFreeBytes = "/memory/classes/heap/free:bytes" goMemoryClassesHeapStacksBytes = "/memory/classes/heap/stacks:bytes" goMemoryClassesOSStacksBytes = "/memory/classes/os-stacks:bytes" goMemoryClassesMetadataMSpanInuseBytes = "/memory/classes/metadata/mspan/inuse:bytes" goMemoryClassesMetadataMSPanFreeBytes = "/memory/classes/metadata/mspan/free:bytes" goMemoryClassesMetadataMCacheInuseBytes = "/memory/classes/metadata/mcache/inuse:bytes" goMemoryClassesMetadataMCacheFreeBytes = "/memory/classes/metadata/mcache/free:bytes" goMemoryClassesProfilingBucketsBytes = "/memory/classes/profiling/buckets:bytes" goMemoryClassesMetadataOtherBytes = "/memory/classes/metadata/other:bytes" goMemoryClassesOtherBytes = "/memory/classes/other:bytes" ) // rmNamesForMemStatsMetrics represents runtime/metrics names required to populate goRuntimeMemStats from like logic. var rmNamesForMemStatsMetrics = []string{ goGCHeapTinyAllocsObjects, goGCHeapAllocsObjects, goGCHeapFreesObjects, goGCHeapAllocsBytes, goGCHeapObjects, goGCHeapGoalBytes, goMemoryClassesTotalBytes, goMemoryClassesHeapObjectsBytes, goMemoryClassesHeapUnusedBytes, goMemoryClassesHeapReleasedBytes, goMemoryClassesHeapFreeBytes, goMemoryClassesHeapStacksBytes, goMemoryClassesOSStacksBytes, goMemoryClassesMetadataMSpanInuseBytes, goMemoryClassesMetadataMSPanFreeBytes, goMemoryClassesMetadataMCacheInuseBytes, goMemoryClassesMetadataMCacheFreeBytes, goMemoryClassesProfilingBucketsBytes, goMemoryClassesMetadataOtherBytes, goMemoryClassesOtherBytes, } func bestEffortLookupRM(lookup []string) []metrics.Description { ret := make([]metrics.Description, 0, len(lookup)) for _, rm := range metrics.All() { for _, m := range lookup { if m == rm.Name { ret = append(ret, rm) } } } return ret } type goCollector struct { base baseGoCollector // mu protects updates to all fields ensuring a consistent // snapshot is always produced by Collect. mu sync.Mutex // Contains all samples that has to retrieved from runtime/metrics (not all of them will be exposed). sampleBuf []metrics.Sample // sampleMap allows lookup for MemStats metrics and runtime/metrics histograms for exact sums. sampleMap map[string]*metrics.Sample // rmExposedMetrics represents all runtime/metrics package metrics // that were configured to be exposed. rmExposedMetrics []collectorMetric rmExactSumMapForHist map[string]string // With Go 1.17, the runtime/metrics package was introduced. // From that point on, metric names produced by the runtime/metrics // package could be generated from runtime/metrics names. However, // these differ from the old names for the same values. // // This field exists to export the same values under the old names // as well. msMetrics memStatsMetrics msMetricsEnabled bool } type rmMetricDesc struct { metrics.Description } func matchRuntimeMetricsRules(rules []internal.GoCollectorRule) []rmMetricDesc { var descs []rmMetricDesc for _, d := range metrics.All() { var ( deny = true desc rmMetricDesc ) for _, r := range rules { if !r.Matcher.MatchString(d.Name) { continue } deny = r.Deny } if deny { continue } desc.Description = d descs = append(descs, desc) } return descs } func defaultGoCollectorOptions() internal.GoCollectorOptions { return internal.GoCollectorOptions{ RuntimeMetricSumForHist: map[string]string{ "/gc/heap/allocs-by-size:bytes": goGCHeapAllocsBytes, "/gc/heap/frees-by-size:bytes": goGCHeapFreesBytes, }, RuntimeMetricRules: []internal.GoCollectorRule{ // Recommended metrics we want by default from runtime/metrics. {Matcher: internal.GoCollectorDefaultRuntimeMetrics}, }, } } // NewGoCollector is the obsolete version of collectors.NewGoCollector. // See there for documentation. // // Deprecated: Use collectors.NewGoCollector instead. func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector { opt := defaultGoCollectorOptions() for _, o := range opts { o(&opt) } exposedDescriptions := matchRuntimeMetricsRules(opt.RuntimeMetricRules) // Collect all histogram samples so that we can get their buckets. // The API guarantees that the buckets are always fixed for the lifetime // of the process. var histograms []metrics.Sample for _, d := range exposedDescriptions { if d.Kind == metrics.KindFloat64Histogram { histograms = append(histograms, metrics.Sample{Name: d.Name}) } } if len(histograms) > 0 { metrics.Read(histograms) } bucketsMap := make(map[string][]float64) for i := range histograms { bucketsMap[histograms[i].Name] = histograms[i].Value.Float64Histogram().Buckets } // Generate a collector for each exposed runtime/metrics metric. metricSet := make([]collectorMetric, 0, len(exposedDescriptions)) // SampleBuf is used for reading from runtime/metrics. // We are assuming the largest case to have stable pointers for sampleMap purposes. sampleBuf := make([]metrics.Sample, 0, len(exposedDescriptions)+len(opt.RuntimeMetricSumForHist)+len(rmNamesForMemStatsMetrics)) sampleMap := make(map[string]*metrics.Sample, len(exposedDescriptions)) for _, d := range exposedDescriptions { namespace, subsystem, name, ok := internal.RuntimeMetricsToProm(&d.Description) if !ok { // Just ignore this metric; we can't do anything with it here. // If a user decides to use the latest version of Go, we don't want // to fail here. This condition is tested in TestExpectedRuntimeMetrics. continue } help := attachOriginalName(d.Description.Description, d.Name) sampleBuf = append(sampleBuf, metrics.Sample{Name: d.Name}) sampleMap[d.Name] = &sampleBuf[len(sampleBuf)-1] var m collectorMetric if d.Kind == metrics.KindFloat64Histogram { _, hasSum := opt.RuntimeMetricSumForHist[d.Name] unit := d.Name[strings.IndexRune(d.Name, ':')+1:] m = newBatchHistogram( NewDesc( BuildFQName(namespace, subsystem, name), help, nil, nil, ), internal.RuntimeMetricsBucketsForUnit(bucketsMap[d.Name], unit), hasSum, ) } else if d.Cumulative { m = NewCounter(CounterOpts{ Namespace: namespace, Subsystem: subsystem, Name: name, Help: help, }, ) } else { m = NewGauge(GaugeOpts{ Namespace: namespace, Subsystem: subsystem, Name: name, Help: help, }) } metricSet = append(metricSet, m) } // Add exact sum metrics to sampleBuf if not added before. for _, h := range histograms { sumMetric, ok := opt.RuntimeMetricSumForHist[h.Name] if !ok { continue } if _, ok := sampleMap[sumMetric]; ok { continue } sampleBuf = append(sampleBuf, metrics.Sample{Name: sumMetric}) sampleMap[sumMetric] = &sampleBuf[len(sampleBuf)-1] } var ( msMetrics memStatsMetrics msDescriptions []metrics.Description ) if !opt.DisableMemStatsLikeMetrics { msMetrics = goRuntimeMemStats() msDescriptions = bestEffortLookupRM(rmNamesForMemStatsMetrics) // Check if metric was not exposed before and if not, add to sampleBuf. for _, mdDesc := range msDescriptions { if _, ok := sampleMap[mdDesc.Name]; ok { continue } sampleBuf = append(sampleBuf, metrics.Sample{Name: mdDesc.Name}) sampleMap[mdDesc.Name] = &sampleBuf[len(sampleBuf)-1] } } return &goCollector{ base: newBaseGoCollector(), sampleBuf: sampleBuf, sampleMap: sampleMap, rmExposedMetrics: metricSet, rmExactSumMapForHist: opt.RuntimeMetricSumForHist, msMetrics: msMetrics, msMetricsEnabled: !opt.DisableMemStatsLikeMetrics, } } func attachOriginalName(desc, origName string) string { return fmt.Sprintf("%s Sourced from %s.", desc, origName) } // Describe returns all descriptions of the collector. func (c *goCollector) Describe(ch chan<- *Desc) { c.base.Describe(ch) for _, i := range c.msMetrics { ch <- i.desc } for _, m := range c.rmExposedMetrics { ch <- m.Desc() } } // Collect returns the current state of all metrics of the collector. func (c *goCollector) Collect(ch chan<- Metric) { // Collect base non-memory metrics. c.base.Collect(ch) if len(c.sampleBuf) == 0 { return } // Collect must be thread-safe, so prevent concurrent use of // sampleBuf elements. Just read into sampleBuf but write all the data // we get into our Metrics or MemStats. // // This lock also ensures that the Metrics we send out are all from // the same updates, ensuring their mutual consistency insofar as // is guaranteed by the runtime/metrics package. // // N.B. This locking is heavy-handed, but Collect is expected to be called // relatively infrequently. Also the core operation here, metrics.Read, // is fast (O(tens of microseconds)) so contention should certainly be // low, though channel operations and any allocations may add to that. c.mu.Lock() defer c.mu.Unlock() // Populate runtime/metrics sample buffer. metrics.Read(c.sampleBuf) // Collect all our runtime/metrics user chose to expose from sampleBuf (if any). for i, metric := range c.rmExposedMetrics { // We created samples for exposed metrics first in order, so indexes match. sample := c.sampleBuf[i] // N.B. switch on concrete type because it's significantly more efficient // than checking for the Counter and Gauge interface implementations. In // this case, we control all the types here. switch m := metric.(type) { case *counter: // Guard against decreases. This should never happen, but a failure // to do so will result in a panic, which is a harsh consequence for // a metrics collection bug. v0, v1 := m.get(), unwrapScalarRMValue(sample.Value) if v1 > v0 { m.Add(unwrapScalarRMValue(sample.Value) - m.get()) } m.Collect(ch) case *gauge: m.Set(unwrapScalarRMValue(sample.Value)) m.Collect(ch) case *batchHistogram: m.update(sample.Value.Float64Histogram(), c.exactSumFor(sample.Name)) m.Collect(ch) default: panic("unexpected metric type") } } if c.msMetricsEnabled { // ms is a dummy MemStats that we populate ourselves so that we can // populate the old metrics from it if goMemStatsCollection is enabled. var ms runtime.MemStats memStatsFromRM(&ms, c.sampleMap) for _, i := range c.msMetrics { ch <- MustNewConstMetric(i.desc, i.valType, i.eval(&ms)) } } } // unwrapScalarRMValue unwraps a runtime/metrics value that is assumed // to be scalar and returns the equivalent float64 value. Panics if the // value is not scalar. func unwrapScalarRMValue(v metrics.Value) float64 { switch v.Kind() { case metrics.KindUint64: return float64(v.Uint64()) case metrics.KindFloat64: return v.Float64() case metrics.KindBad: // Unsupported metric. // // This should never happen because we always populate our metric // set from the runtime/metrics package. panic("unexpected bad kind metric") default: // Unsupported metric kind. // // This should never happen because we check for this during initialization // and flag and filter metrics whose kinds we don't understand. panic(fmt.Sprintf("unexpected unsupported metric: %v", v.Kind())) } } // exactSumFor takes a runtime/metrics metric name (that is assumed to // be of kind KindFloat64Histogram) and returns its exact sum and whether // its exact sum exists. // // The runtime/metrics API for histograms doesn't currently expose exact // sums, but some of the other metrics are in fact exact sums of histograms. func (c *goCollector) exactSumFor(rmName string) float64 { sumName, ok := c.rmExactSumMapForHist[rmName] if !ok { return 0 } s, ok := c.sampleMap[sumName] if !ok { return 0 } return unwrapScalarRMValue(s.Value) } func memStatsFromRM(ms *runtime.MemStats, rm map[string]*metrics.Sample) { lookupOrZero := func(name string) uint64 { if s, ok := rm[name]; ok { return s.Value.Uint64() } return 0 } // Currently, MemStats adds tiny alloc count to both Mallocs AND Frees. // The reason for this is because MemStats couldn't be extended at the time // but there was a desire to have Mallocs at least be a little more representative, // while having Mallocs - Frees still represent a live object count. // Unfortunately, MemStats doesn't actually export a large allocation count, // so it's impossible to pull this number out directly. tinyAllocs := lookupOrZero(goGCHeapTinyAllocsObjects) ms.Mallocs = lookupOrZero(goGCHeapAllocsObjects) + tinyAllocs ms.Frees = lookupOrZero(goGCHeapFreesObjects) + tinyAllocs ms.TotalAlloc = lookupOrZero(goGCHeapAllocsBytes) ms.Sys = lookupOrZero(goMemoryClassesTotalBytes) ms.Lookups = 0 // Already always zero. ms.HeapAlloc = lookupOrZero(goMemoryClassesHeapObjectsBytes) ms.Alloc = ms.HeapAlloc ms.HeapInuse = ms.HeapAlloc + lookupOrZero(goMemoryClassesHeapUnusedBytes) ms.HeapReleased = lookupOrZero(goMemoryClassesHeapReleasedBytes) ms.HeapIdle = ms.HeapReleased + lookupOrZero(goMemoryClassesHeapFreeBytes) ms.HeapSys = ms.HeapInuse + ms.HeapIdle ms.HeapObjects = lookupOrZero(goGCHeapObjects) ms.StackInuse = lookupOrZero(goMemoryClassesHeapStacksBytes) ms.StackSys = ms.StackInuse + lookupOrZero(goMemoryClassesOSStacksBytes) ms.MSpanInuse = lookupOrZero(goMemoryClassesMetadataMSpanInuseBytes) ms.MSpanSys = ms.MSpanInuse + lookupOrZero(goMemoryClassesMetadataMSPanFreeBytes) ms.MCacheInuse = lookupOrZero(goMemoryClassesMetadataMCacheInuseBytes) ms.MCacheSys = ms.MCacheInuse + lookupOrZero(goMemoryClassesMetadataMCacheFreeBytes) ms.BuckHashSys = lookupOrZero(goMemoryClassesProfilingBucketsBytes) ms.GCSys = lookupOrZero(goMemoryClassesMetadataOtherBytes) ms.OtherSys = lookupOrZero(goMemoryClassesOtherBytes) ms.NextGC = lookupOrZero(goGCHeapGoalBytes) // N.B. GCCPUFraction is intentionally omitted. This metric is not useful, // and often misleading due to the fact that it's an average over the lifetime // of the process. // See https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034 // for more details. ms.GCCPUFraction = 0 } // batchHistogram is a mutable histogram that is updated // in batches. type batchHistogram struct { selfCollector // Static fields updated only once. desc *Desc hasSum bool // Because this histogram operates in batches, it just uses a // single mutex for everything. updates are always serialized // but Write calls may operate concurrently with updates. // Contention between these two sources should be rare. mu sync.Mutex buckets []float64 // Inclusive lower bounds, like runtime/metrics. counts []uint64 sum float64 // Used if hasSum is true. } // newBatchHistogram creates a new batch histogram value with the given // Desc, buckets, and whether or not it has an exact sum available. // // buckets must always be from the runtime/metrics package, following // the same conventions. func newBatchHistogram(desc *Desc, buckets []float64, hasSum bool) *batchHistogram { // We need to remove -Inf values. runtime/metrics keeps them around. // But -Inf bucket should not be allowed for prometheus histograms. if buckets[0] == math.Inf(-1) { buckets = buckets[1:] } h := &batchHistogram{ desc: desc, buckets: buckets, // Because buckets follows runtime/metrics conventions, there's // 1 more value in the buckets list than there are buckets represented, // because in runtime/metrics, the bucket values represent *boundaries*, // and non-Inf boundaries are inclusive lower bounds for that bucket. counts: make([]uint64, len(buckets)-1), hasSum: hasSum, } h.init(h) return h } // update updates the batchHistogram from a runtime/metrics histogram. // // sum must be provided if the batchHistogram was created to have an exact sum. // h.buckets must be a strict subset of his.Buckets. func (h *batchHistogram) update(his *metrics.Float64Histogram, sum float64) { counts, buckets := his.Counts, his.Buckets h.mu.Lock() defer h.mu.Unlock() // Clear buckets. for i := range h.counts { h.counts[i] = 0 } // Copy and reduce buckets. var j int for i, count := range counts { h.counts[j] += count if buckets[i+1] == h.buckets[j+1] { j++ } } if h.hasSum { h.sum = sum } } func (h *batchHistogram) Desc() *Desc { return h.desc } func (h *batchHistogram) Write(out *dto.Metric) error { h.mu.Lock() defer h.mu.Unlock() sum := float64(0) if h.hasSum { sum = h.sum } dtoBuckets := make([]*dto.Bucket, 0, len(h.counts)) totalCount := uint64(0) for i, count := range h.counts { totalCount += count if !h.hasSum { if count != 0 { // N.B. This computed sum is an underestimate. sum += h.buckets[i] * float64(count) } } // Skip the +Inf bucket, but only for the bucket list. // It must still count for sum and totalCount. if math.IsInf(h.buckets[i+1], 1) { break } // Float64Histogram's upper bound is exclusive, so make it inclusive // by obtaining the next float64 value down, in order. upperBound := math.Nextafter(h.buckets[i+1], h.buckets[i]) dtoBuckets = append(dtoBuckets, &dto.Bucket{ CumulativeCount: proto.Uint64(totalCount), UpperBound: proto.Float64(upperBound), }) } out.Histogram = &dto.Histogram{ Bucket: dtoBuckets, SampleCount: proto.Uint64(totalCount), SampleSum: proto.Float64(sum), } return nil } client_golang-1.21.1/prometheus/go_collector_latest_test.go000066400000000000000000000274231476160432400242300ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build go1.17 // +build go1.17 package prometheus import ( "math" "reflect" "regexp" "runtime" "runtime/metrics" "sync" "testing" dto "github.com/prometheus/client_model/go" "github.com/prometheus/client_golang/prometheus/internal" ) func TestRmForMemStats(t *testing.T) { descs := bestEffortLookupRM(rmNamesForMemStatsMetrics) if got, want := len(descs), len(rmNamesForMemStatsMetrics); got != want { t.Errorf("got %d, want %d metrics", got, want) } for _, d := range descs { // We don't expect histograms there. if d.Kind == metrics.KindFloat64Histogram { t.Errorf("we don't expect to use histograms for MemStats metrics, got %v", d.Name) } } } func expectedBaseMetrics() map[string]struct{} { metrics := map[string]struct{}{} b := newBaseGoCollector() for _, m := range []string{ b.gcDesc.fqName, b.goInfoDesc.fqName, b.goroutinesDesc.fqName, b.gcLastTimeDesc.fqName, b.threadsDesc.fqName, } { metrics[m] = struct{}{} } return metrics } func addExpectedRuntimeMemStats(metrics map[string]struct{}) map[string]struct{} { for _, m := range goRuntimeMemStats() { metrics[m.desc.fqName] = struct{}{} } return metrics } func addExpectedRuntimeMetrics(metrics map[string]struct{}) map[string]struct{} { for _, m := range expectedRuntimeMetrics { metrics[m] = struct{}{} } return metrics } func addExpectedDefaultRuntimeMetrics(metrics map[string]struct{}) map[string]struct{} { for _, e := range expMetrics { metrics[e] = struct{}{} } return metrics } func TestGoCollector_ExposedMetrics(t *testing.T) { for _, tcase := range []struct { opts internal.GoCollectorOptions expectedFQNameSet map[string]struct{} }{ { opts: internal.GoCollectorOptions{ DisableMemStatsLikeMetrics: true, }, expectedFQNameSet: expectedBaseMetrics(), }, { // Default, only MemStats and default Runtime metrics. opts: defaultGoCollectorOptions(), expectedFQNameSet: addExpectedDefaultRuntimeMetrics(addExpectedRuntimeMemStats(expectedBaseMetrics())), }, { // Get all runtime/metrics without MemStats. opts: internal.GoCollectorOptions{ DisableMemStatsLikeMetrics: true, RuntimeMetricRules: []internal.GoCollectorRule{ {Matcher: regexp.MustCompile("/.*")}, }, }, expectedFQNameSet: addExpectedRuntimeMetrics(expectedBaseMetrics()), }, { // Get all runtime/metrics and MemStats. opts: internal.GoCollectorOptions{ RuntimeMetricRules: []internal.GoCollectorRule{ {Matcher: regexp.MustCompile("/.*")}, }, }, expectedFQNameSet: addExpectedRuntimeMemStats(addExpectedRuntimeMetrics(expectedBaseMetrics())), }, } { if ok := t.Run("", func(t *testing.T) { goMetrics := collectGoMetrics(t, tcase.opts) goMetricSet := make(map[string]Metric) for _, m := range goMetrics { goMetricSet[m.Desc().fqName] = m } for i := range goMetrics { name := goMetrics[i].Desc().fqName if _, ok := tcase.expectedFQNameSet[name]; !ok { t.Errorf("found unexpected metric %s", name) continue } } // Now iterate over the expected metrics and look for removals. for expectedName := range tcase.expectedFQNameSet { if _, ok := goMetricSet[expectedName]; !ok { t.Errorf("missing expected metric %s in collection", expectedName) continue } } }); !ok { return } } } var sink interface{} func TestBatchHistogram(t *testing.T) { goMetrics := collectGoMetrics(t, internal.GoCollectorOptions{ RuntimeMetricRules: []internal.GoCollectorRule{ {Matcher: regexp.MustCompile("/.*")}, }, }) var mhist Metric for _, m := range goMetrics { if m.Desc().fqName == "go_gc_heap_allocs_by_size_bytes" { mhist = m break } } if mhist == nil { t.Fatal("failed to find metric to test") } hist, ok := mhist.(*batchHistogram) if !ok { t.Fatal("found metric is not a runtime/metrics histogram") } // Make a bunch of allocations then do another collection. // // The runtime/metrics API tries to reuse memory where possible, // so make sure that we didn't hang on to any of that memory in // hist. countsCopy := make([]uint64, len(hist.counts)) copy(countsCopy, hist.counts) for i := 0; i < 100; i++ { sink = make([]byte, 128) } collectGoMetrics(t, defaultGoCollectorOptions()) for i, v := range hist.counts { if v != countsCopy[i] { t.Error("counts changed during new collection") break } } // Get the runtime/metrics copy. s := []metrics.Sample{ {Name: "/gc/heap/allocs-by-size:bytes"}, } metrics.Read(s) rmHist := s[0].Value.Float64Histogram() wantBuckets := internal.RuntimeMetricsBucketsForUnit(rmHist.Buckets, "bytes") // runtime/metrics histograms always have a +Inf bucket and are lower // bound inclusive. In contrast, we have an implicit +Inf bucket and // are upper bound inclusive, so we can chop off the first bucket // (since the conversion to upper bound inclusive will shift all buckets // down one index) and the +Inf for the last bucket. wantBuckets = wantBuckets[1 : len(wantBuckets)-1] // Check to make sure the output proto makes sense. pb := &dto.Metric{} hist.Write(pb) if math.IsInf(pb.Histogram.Bucket[len(pb.Histogram.Bucket)-1].GetUpperBound(), +1) { t.Errorf("found +Inf bucket") } if got := len(pb.Histogram.Bucket); got != len(wantBuckets) { t.Errorf("got %d buckets in protobuf, want %d", got, len(wantBuckets)) } for i, bucket := range pb.Histogram.Bucket { // runtime/metrics histograms are lower-bound inclusive, but we're // upper-bound inclusive. So just make sure the new inclusive upper // bound is somewhere close by (in some cases it's equal). wantBound := wantBuckets[i] if gotBound := *bucket.UpperBound; (wantBound-gotBound)/wantBound > 0.001 { t.Errorf("got bound %f, want within 0.1%% of %f", gotBound, wantBound) } // Make sure counts are cumulative. Because of the consistency guarantees // made by the runtime/metrics package, we're really not guaranteed to get // anything even remotely the same here. if i > 0 && *bucket.CumulativeCount < *pb.Histogram.Bucket[i-1].CumulativeCount { t.Error("cumulative counts are non-monotonic") } } } func collectGoMetrics(t *testing.T, opts internal.GoCollectorOptions) []Metric { t.Helper() c := NewGoCollector(func(o *internal.GoCollectorOptions) { o.DisableMemStatsLikeMetrics = opts.DisableMemStatsLikeMetrics o.RuntimeMetricSumForHist = opts.RuntimeMetricSumForHist o.RuntimeMetricRules = opts.RuntimeMetricRules }).(*goCollector) // Collect all metrics. ch := make(chan Metric) var wg sync.WaitGroup var metrics []Metric wg.Add(1) go func() { defer wg.Done() for metric := range ch { metrics = append(metrics, metric) } }() c.Collect(ch) close(ch) wg.Wait() return metrics } func TestMemStatsEquivalence(t *testing.T) { var msReal, msFake runtime.MemStats descs := bestEffortLookupRM(rmNamesForMemStatsMetrics) samples := make([]metrics.Sample, len(descs)) samplesMap := make(map[string]*metrics.Sample) for i := range descs { samples[i].Name = descs[i].Name samplesMap[descs[i].Name] = &samples[i] } // Force a GC cycle to try to reach a clean slate. runtime.GC() // Populate msReal. runtime.ReadMemStats(&msReal) // Populate msFake and hope that no GC happened in between (: metrics.Read(samples) memStatsFromRM(&msFake, samplesMap) // Iterate over them and make sure they're somewhat close. msRealValue := reflect.ValueOf(msReal) msFakeValue := reflect.ValueOf(msFake) typ := msRealValue.Type() for i := 0; i < msRealValue.NumField(); i++ { fr := msRealValue.Field(i) ff := msFakeValue.Field(i) if typ.Field(i).Name == "PauseTotalNs" || typ.Field(i).Name == "LastGC" { // We don't use those fields for metrics, // thus we are not interested in having this filled. continue } switch fr.Kind() { // Fields which we are interested in are all uint64s. // The only float64 field GCCPUFraction is by design omitted. case reflect.Uint64: vr := fr.Interface().(uint64) vf := ff.Interface().(uint64) if float64(vr-vf)/float64(vf) > 0.05 { t.Errorf("wrong value for %s: got %d, want %d", typ.Field(i).Name, vf, vr) } } } } func TestExpectedRuntimeMetrics(t *testing.T) { goMetrics := collectGoMetrics(t, internal.GoCollectorOptions{ DisableMemStatsLikeMetrics: true, RuntimeMetricRules: []internal.GoCollectorRule{ {Matcher: regexp.MustCompile("/.*")}, }, }) goMetricSet := make(map[string]Metric) for _, m := range goMetrics { goMetricSet[m.Desc().fqName] = m } descs := metrics.All() rmSet := make(map[string]struct{}) // Iterate over runtime-reported descriptions to find new metrics. for i := range descs { rmName := descs[i].Name rmSet[rmName] = struct{}{} // expectedRuntimeMetrics depends on Go version. expFQName, ok := expectedRuntimeMetrics[rmName] if !ok { t.Errorf("found new runtime/metrics metric %s", rmName) _, _, _, ok := internal.RuntimeMetricsToProm(&descs[i]) if !ok { t.Errorf("new metric has name that can't be converted, or has an unsupported Kind") } continue } _, ok = goMetricSet[expFQName] if !ok { t.Errorf("existing runtime/metrics metric %s (expected fq name %s) not collected", rmName, expFQName) continue } } // Now iterate over the expected metrics and look for removals. cardinality := 0 for rmName, fqName := range expectedRuntimeMetrics { if _, ok := rmSet[rmName]; !ok { t.Errorf("runtime/metrics metric %s removed", rmName) continue } if _, ok := goMetricSet[fqName]; !ok { t.Errorf("runtime/metrics metric %s not appearing under expected name %s", rmName, fqName) continue } // While we're at it, check to make sure expected cardinality lines // up, but at the point of the protobuf write to get as close to the // real deal as possible. // // Note that we filter out non-runtime/metrics metrics here, because // those are manually managed. var m dto.Metric if err := goMetricSet[fqName].Write(&m); err != nil { t.Errorf("writing metric %s: %v", fqName, err) continue } // N.B. These are the only fields populated by runtime/metrics metrics specifically. // Other fields are populated by e.g. GCStats metrics. switch { case m.Counter != nil: fallthrough case m.Gauge != nil: cardinality++ case m.Histogram != nil: cardinality += len(m.Histogram.Bucket) + 3 // + sum, count, and +inf default: t.Errorf("unexpected protobuf structure for metric %s", fqName) } } if t.Failed() { t.Log("a new Go version may have been detected, please run") t.Log("\tgo run gen_go_collector_metrics_set.go go1.X") t.Log("where X is the Go version you are currently using") } expectCardinality := expectedRuntimeMetricsCardinality if cardinality != expectCardinality { t.Errorf("unexpected cardinality for runtime/metrics metrics: got %d, want %d", cardinality, expectCardinality) } } func TestGoCollectorConcurrency(t *testing.T) { c := NewGoCollector().(*goCollector) // Set up multiple goroutines to Collect from the // same GoCollector. In race mode with GOMAXPROCS > 1, // this test should fail often if Collect is not // concurrent-safe. for i := 0; i < 4; i++ { go func() { ch := make(chan Metric) go func() { // Drain all metrics received until the // channel is closed. for range ch { } }() c.Collect(ch) close(ch) }() } } client_golang-1.21.1/prometheus/go_collector_metrics_go120_test.go000066400000000000000000000105371476160432400253100ustar00rootroot00000000000000// Code generated by gen_go_collector_metrics_set.go; DO NOT EDIT. //go:generate go run gen_go_collector_metrics_set.go go1.20 //go:build go1.20 && !go1.21 // +build go1.20,!go1.21 package prometheus var ( expectedRuntimeMetrics = map[string]string{ "/cgo/go-to-c-calls:calls": "go_cgo_go_to_c_calls_calls_total", "/cpu/classes/gc/mark/assist:cpu-seconds": "go_cpu_classes_gc_mark_assist_cpu_seconds_total", "/cpu/classes/gc/mark/dedicated:cpu-seconds": "go_cpu_classes_gc_mark_dedicated_cpu_seconds_total", "/cpu/classes/gc/mark/idle:cpu-seconds": "go_cpu_classes_gc_mark_idle_cpu_seconds_total", "/cpu/classes/gc/pause:cpu-seconds": "go_cpu_classes_gc_pause_cpu_seconds_total", "/cpu/classes/gc/total:cpu-seconds": "go_cpu_classes_gc_total_cpu_seconds_total", "/cpu/classes/idle:cpu-seconds": "go_cpu_classes_idle_cpu_seconds_total", "/cpu/classes/scavenge/assist:cpu-seconds": "go_cpu_classes_scavenge_assist_cpu_seconds_total", "/cpu/classes/scavenge/background:cpu-seconds": "go_cpu_classes_scavenge_background_cpu_seconds_total", "/cpu/classes/scavenge/total:cpu-seconds": "go_cpu_classes_scavenge_total_cpu_seconds_total", "/cpu/classes/total:cpu-seconds": "go_cpu_classes_total_cpu_seconds_total", "/cpu/classes/user:cpu-seconds": "go_cpu_classes_user_cpu_seconds_total", "/gc/cycles/automatic:gc-cycles": "go_gc_cycles_automatic_gc_cycles_total", "/gc/cycles/forced:gc-cycles": "go_gc_cycles_forced_gc_cycles_total", "/gc/cycles/total:gc-cycles": "go_gc_cycles_total_gc_cycles_total", "/gc/heap/allocs-by-size:bytes": "go_gc_heap_allocs_by_size_bytes", "/gc/heap/allocs:bytes": "go_gc_heap_allocs_bytes_total", "/gc/heap/allocs:objects": "go_gc_heap_allocs_objects_total", "/gc/heap/frees-by-size:bytes": "go_gc_heap_frees_by_size_bytes", "/gc/heap/frees:bytes": "go_gc_heap_frees_bytes_total", "/gc/heap/frees:objects": "go_gc_heap_frees_objects_total", "/gc/heap/goal:bytes": "go_gc_heap_goal_bytes", "/gc/heap/objects:objects": "go_gc_heap_objects_objects", "/gc/heap/tiny/allocs:objects": "go_gc_heap_tiny_allocs_objects_total", "/gc/limiter/last-enabled:gc-cycle": "go_gc_limiter_last_enabled_gc_cycle", "/gc/pauses:seconds": "go_gc_pauses_seconds", "/gc/stack/starting-size:bytes": "go_gc_stack_starting_size_bytes", "/memory/classes/heap/free:bytes": "go_memory_classes_heap_free_bytes", "/memory/classes/heap/objects:bytes": "go_memory_classes_heap_objects_bytes", "/memory/classes/heap/released:bytes": "go_memory_classes_heap_released_bytes", "/memory/classes/heap/stacks:bytes": "go_memory_classes_heap_stacks_bytes", "/memory/classes/heap/unused:bytes": "go_memory_classes_heap_unused_bytes", "/memory/classes/metadata/mcache/free:bytes": "go_memory_classes_metadata_mcache_free_bytes", "/memory/classes/metadata/mcache/inuse:bytes": "go_memory_classes_metadata_mcache_inuse_bytes", "/memory/classes/metadata/mspan/free:bytes": "go_memory_classes_metadata_mspan_free_bytes", "/memory/classes/metadata/mspan/inuse:bytes": "go_memory_classes_metadata_mspan_inuse_bytes", "/memory/classes/metadata/other:bytes": "go_memory_classes_metadata_other_bytes", "/memory/classes/os-stacks:bytes": "go_memory_classes_os_stacks_bytes", "/memory/classes/other:bytes": "go_memory_classes_other_bytes", "/memory/classes/profiling/buckets:bytes": "go_memory_classes_profiling_buckets_bytes", "/memory/classes/total:bytes": "go_memory_classes_total_bytes", "/sched/gomaxprocs:threads": "go_sched_gomaxprocs_threads", "/sched/goroutines:goroutines": "go_sched_goroutines_goroutines", "/sched/latencies:seconds": "go_sched_latencies_seconds", "/sync/mutex/wait/total:seconds": "go_sync_mutex_wait_total_seconds_total", } expMetrics = map[string]string{ "/sched/gomaxprocs:threads": "go_sched_gomaxprocs_threads", } ) const expectedRuntimeMetricsCardinality = 89 client_golang-1.21.1/prometheus/go_collector_metrics_go121_test.go000066400000000000000000000177041476160432400253140ustar00rootroot00000000000000// Code generated by gen_go_collector_metrics_set.go; DO NOT EDIT. //go:generate go run gen_go_collector_metrics_set.go go1.21 //go:build go1.21 && !go1.22 // +build go1.21,!go1.22 package prometheus var ( expectedRuntimeMetrics = map[string]string{ "/cgo/go-to-c-calls:calls": "go_cgo_go_to_c_calls_calls_total", "/cpu/classes/gc/mark/assist:cpu-seconds": "go_cpu_classes_gc_mark_assist_cpu_seconds_total", "/cpu/classes/gc/mark/dedicated:cpu-seconds": "go_cpu_classes_gc_mark_dedicated_cpu_seconds_total", "/cpu/classes/gc/mark/idle:cpu-seconds": "go_cpu_classes_gc_mark_idle_cpu_seconds_total", "/cpu/classes/gc/pause:cpu-seconds": "go_cpu_classes_gc_pause_cpu_seconds_total", "/cpu/classes/gc/total:cpu-seconds": "go_cpu_classes_gc_total_cpu_seconds_total", "/cpu/classes/idle:cpu-seconds": "go_cpu_classes_idle_cpu_seconds_total", "/cpu/classes/scavenge/assist:cpu-seconds": "go_cpu_classes_scavenge_assist_cpu_seconds_total", "/cpu/classes/scavenge/background:cpu-seconds": "go_cpu_classes_scavenge_background_cpu_seconds_total", "/cpu/classes/scavenge/total:cpu-seconds": "go_cpu_classes_scavenge_total_cpu_seconds_total", "/cpu/classes/total:cpu-seconds": "go_cpu_classes_total_cpu_seconds_total", "/cpu/classes/user:cpu-seconds": "go_cpu_classes_user_cpu_seconds_total", "/gc/cycles/automatic:gc-cycles": "go_gc_cycles_automatic_gc_cycles_total", "/gc/cycles/forced:gc-cycles": "go_gc_cycles_forced_gc_cycles_total", "/gc/cycles/total:gc-cycles": "go_gc_cycles_total_gc_cycles_total", "/gc/gogc:percent": "go_gc_gogc_percent", "/gc/gomemlimit:bytes": "go_gc_gomemlimit_bytes", "/gc/heap/allocs-by-size:bytes": "go_gc_heap_allocs_by_size_bytes", "/gc/heap/allocs:bytes": "go_gc_heap_allocs_bytes_total", "/gc/heap/allocs:objects": "go_gc_heap_allocs_objects_total", "/gc/heap/frees-by-size:bytes": "go_gc_heap_frees_by_size_bytes", "/gc/heap/frees:bytes": "go_gc_heap_frees_bytes_total", "/gc/heap/frees:objects": "go_gc_heap_frees_objects_total", "/gc/heap/goal:bytes": "go_gc_heap_goal_bytes", "/gc/heap/live:bytes": "go_gc_heap_live_bytes", "/gc/heap/objects:objects": "go_gc_heap_objects_objects", "/gc/heap/tiny/allocs:objects": "go_gc_heap_tiny_allocs_objects_total", "/gc/limiter/last-enabled:gc-cycle": "go_gc_limiter_last_enabled_gc_cycle", "/gc/pauses:seconds": "go_gc_pauses_seconds", "/gc/scan/globals:bytes": "go_gc_scan_globals_bytes", "/gc/scan/heap:bytes": "go_gc_scan_heap_bytes", "/gc/scan/stack:bytes": "go_gc_scan_stack_bytes", "/gc/scan/total:bytes": "go_gc_scan_total_bytes", "/gc/stack/starting-size:bytes": "go_gc_stack_starting_size_bytes", "/godebug/non-default-behavior/execerrdot:events": "go_godebug_non_default_behavior_execerrdot_events_total", "/godebug/non-default-behavior/gocachehash:events": "go_godebug_non_default_behavior_gocachehash_events_total", "/godebug/non-default-behavior/gocachetest:events": "go_godebug_non_default_behavior_gocachetest_events_total", "/godebug/non-default-behavior/gocacheverify:events": "go_godebug_non_default_behavior_gocacheverify_events_total", "/godebug/non-default-behavior/http2client:events": "go_godebug_non_default_behavior_http2client_events_total", "/godebug/non-default-behavior/http2server:events": "go_godebug_non_default_behavior_http2server_events_total", "/godebug/non-default-behavior/installgoroot:events": "go_godebug_non_default_behavior_installgoroot_events_total", "/godebug/non-default-behavior/jstmpllitinterp:events": "go_godebug_non_default_behavior_jstmpllitinterp_events_total", "/godebug/non-default-behavior/multipartmaxheaders:events": "go_godebug_non_default_behavior_multipartmaxheaders_events_total", "/godebug/non-default-behavior/multipartmaxparts:events": "go_godebug_non_default_behavior_multipartmaxparts_events_total", "/godebug/non-default-behavior/multipathtcp:events": "go_godebug_non_default_behavior_multipathtcp_events_total", "/godebug/non-default-behavior/netedns0:events": "go_godebug_non_default_behavior_netedns0_events_total", "/godebug/non-default-behavior/panicnil:events": "go_godebug_non_default_behavior_panicnil_events_total", "/godebug/non-default-behavior/randautoseed:events": "go_godebug_non_default_behavior_randautoseed_events_total", "/godebug/non-default-behavior/tarinsecurepath:events": "go_godebug_non_default_behavior_tarinsecurepath_events_total", "/godebug/non-default-behavior/tlsmaxrsasize:events": "go_godebug_non_default_behavior_tlsmaxrsasize_events_total", "/godebug/non-default-behavior/x509sha1:events": "go_godebug_non_default_behavior_x509sha1_events_total", "/godebug/non-default-behavior/x509usefallbackroots:events": "go_godebug_non_default_behavior_x509usefallbackroots_events_total", "/godebug/non-default-behavior/zipinsecurepath:events": "go_godebug_non_default_behavior_zipinsecurepath_events_total", "/memory/classes/heap/free:bytes": "go_memory_classes_heap_free_bytes", "/memory/classes/heap/objects:bytes": "go_memory_classes_heap_objects_bytes", "/memory/classes/heap/released:bytes": "go_memory_classes_heap_released_bytes", "/memory/classes/heap/stacks:bytes": "go_memory_classes_heap_stacks_bytes", "/memory/classes/heap/unused:bytes": "go_memory_classes_heap_unused_bytes", "/memory/classes/metadata/mcache/free:bytes": "go_memory_classes_metadata_mcache_free_bytes", "/memory/classes/metadata/mcache/inuse:bytes": "go_memory_classes_metadata_mcache_inuse_bytes", "/memory/classes/metadata/mspan/free:bytes": "go_memory_classes_metadata_mspan_free_bytes", "/memory/classes/metadata/mspan/inuse:bytes": "go_memory_classes_metadata_mspan_inuse_bytes", "/memory/classes/metadata/other:bytes": "go_memory_classes_metadata_other_bytes", "/memory/classes/os-stacks:bytes": "go_memory_classes_os_stacks_bytes", "/memory/classes/other:bytes": "go_memory_classes_other_bytes", "/memory/classes/profiling/buckets:bytes": "go_memory_classes_profiling_buckets_bytes", "/memory/classes/total:bytes": "go_memory_classes_total_bytes", "/sched/gomaxprocs:threads": "go_sched_gomaxprocs_threads", "/sched/goroutines:goroutines": "go_sched_goroutines_goroutines", "/sched/latencies:seconds": "go_sched_latencies_seconds", "/sync/mutex/wait/total:seconds": "go_sync_mutex_wait_total_seconds_total", } expMetrics = map[string]string{ "/gc/gogc:percent": "go_gc_gogc_percent", "/gc/gomemlimit:bytes": "go_gc_gomemlimit_bytes", "/sched/gomaxprocs:threads": "go_sched_gomaxprocs_threads", } ) const expectedRuntimeMetricsCardinality = 115 client_golang-1.21.1/prometheus/go_collector_metrics_go122_test.go000066400000000000000000000223071476160432400253100ustar00rootroot00000000000000// Code generated by gen_go_collector_metrics_set.go; DO NOT EDIT. //go:generate go run gen_go_collector_metrics_set.go go1.22 //go:build go1.22 && !go1.23 // +build go1.22,!go1.23 package prometheus var ( expectedRuntimeMetrics = map[string]string{ "/cgo/go-to-c-calls:calls": "go_cgo_go_to_c_calls_calls_total", "/cpu/classes/gc/mark/assist:cpu-seconds": "go_cpu_classes_gc_mark_assist_cpu_seconds_total", "/cpu/classes/gc/mark/dedicated:cpu-seconds": "go_cpu_classes_gc_mark_dedicated_cpu_seconds_total", "/cpu/classes/gc/mark/idle:cpu-seconds": "go_cpu_classes_gc_mark_idle_cpu_seconds_total", "/cpu/classes/gc/pause:cpu-seconds": "go_cpu_classes_gc_pause_cpu_seconds_total", "/cpu/classes/gc/total:cpu-seconds": "go_cpu_classes_gc_total_cpu_seconds_total", "/cpu/classes/idle:cpu-seconds": "go_cpu_classes_idle_cpu_seconds_total", "/cpu/classes/scavenge/assist:cpu-seconds": "go_cpu_classes_scavenge_assist_cpu_seconds_total", "/cpu/classes/scavenge/background:cpu-seconds": "go_cpu_classes_scavenge_background_cpu_seconds_total", "/cpu/classes/scavenge/total:cpu-seconds": "go_cpu_classes_scavenge_total_cpu_seconds_total", "/cpu/classes/total:cpu-seconds": "go_cpu_classes_total_cpu_seconds_total", "/cpu/classes/user:cpu-seconds": "go_cpu_classes_user_cpu_seconds_total", "/gc/cycles/automatic:gc-cycles": "go_gc_cycles_automatic_gc_cycles_total", "/gc/cycles/forced:gc-cycles": "go_gc_cycles_forced_gc_cycles_total", "/gc/cycles/total:gc-cycles": "go_gc_cycles_total_gc_cycles_total", "/gc/gogc:percent": "go_gc_gogc_percent", "/gc/gomemlimit:bytes": "go_gc_gomemlimit_bytes", "/gc/heap/allocs-by-size:bytes": "go_gc_heap_allocs_by_size_bytes", "/gc/heap/allocs:bytes": "go_gc_heap_allocs_bytes_total", "/gc/heap/allocs:objects": "go_gc_heap_allocs_objects_total", "/gc/heap/frees-by-size:bytes": "go_gc_heap_frees_by_size_bytes", "/gc/heap/frees:bytes": "go_gc_heap_frees_bytes_total", "/gc/heap/frees:objects": "go_gc_heap_frees_objects_total", "/gc/heap/goal:bytes": "go_gc_heap_goal_bytes", "/gc/heap/live:bytes": "go_gc_heap_live_bytes", "/gc/heap/objects:objects": "go_gc_heap_objects_objects", "/gc/heap/tiny/allocs:objects": "go_gc_heap_tiny_allocs_objects_total", "/gc/limiter/last-enabled:gc-cycle": "go_gc_limiter_last_enabled_gc_cycle", "/gc/pauses:seconds": "go_gc_pauses_seconds", "/gc/scan/globals:bytes": "go_gc_scan_globals_bytes", "/gc/scan/heap:bytes": "go_gc_scan_heap_bytes", "/gc/scan/stack:bytes": "go_gc_scan_stack_bytes", "/gc/scan/total:bytes": "go_gc_scan_total_bytes", "/gc/stack/starting-size:bytes": "go_gc_stack_starting_size_bytes", "/godebug/non-default-behavior/execerrdot:events": "go_godebug_non_default_behavior_execerrdot_events_total", "/godebug/non-default-behavior/gocachehash:events": "go_godebug_non_default_behavior_gocachehash_events_total", "/godebug/non-default-behavior/gocachetest:events": "go_godebug_non_default_behavior_gocachetest_events_total", "/godebug/non-default-behavior/gocacheverify:events": "go_godebug_non_default_behavior_gocacheverify_events_total", "/godebug/non-default-behavior/gotypesalias:events": "go_godebug_non_default_behavior_gotypesalias_events_total", "/godebug/non-default-behavior/http2client:events": "go_godebug_non_default_behavior_http2client_events_total", "/godebug/non-default-behavior/http2server:events": "go_godebug_non_default_behavior_http2server_events_total", "/godebug/non-default-behavior/httplaxcontentlength:events": "go_godebug_non_default_behavior_httplaxcontentlength_events_total", "/godebug/non-default-behavior/httpmuxgo121:events": "go_godebug_non_default_behavior_httpmuxgo121_events_total", "/godebug/non-default-behavior/installgoroot:events": "go_godebug_non_default_behavior_installgoroot_events_total", "/godebug/non-default-behavior/jstmpllitinterp:events": "go_godebug_non_default_behavior_jstmpllitinterp_events_total", "/godebug/non-default-behavior/multipartmaxheaders:events": "go_godebug_non_default_behavior_multipartmaxheaders_events_total", "/godebug/non-default-behavior/multipartmaxparts:events": "go_godebug_non_default_behavior_multipartmaxparts_events_total", "/godebug/non-default-behavior/multipathtcp:events": "go_godebug_non_default_behavior_multipathtcp_events_total", "/godebug/non-default-behavior/netedns0:events": "go_godebug_non_default_behavior_netedns0_events_total", "/godebug/non-default-behavior/panicnil:events": "go_godebug_non_default_behavior_panicnil_events_total", "/godebug/non-default-behavior/randautoseed:events": "go_godebug_non_default_behavior_randautoseed_events_total", "/godebug/non-default-behavior/tarinsecurepath:events": "go_godebug_non_default_behavior_tarinsecurepath_events_total", "/godebug/non-default-behavior/tls10server:events": "go_godebug_non_default_behavior_tls10server_events_total", "/godebug/non-default-behavior/tlsmaxrsasize:events": "go_godebug_non_default_behavior_tlsmaxrsasize_events_total", "/godebug/non-default-behavior/tlsrsakex:events": "go_godebug_non_default_behavior_tlsrsakex_events_total", "/godebug/non-default-behavior/tlsunsafeekm:events": "go_godebug_non_default_behavior_tlsunsafeekm_events_total", "/godebug/non-default-behavior/x509sha1:events": "go_godebug_non_default_behavior_x509sha1_events_total", "/godebug/non-default-behavior/x509usefallbackroots:events": "go_godebug_non_default_behavior_x509usefallbackroots_events_total", "/godebug/non-default-behavior/x509usepolicies:events": "go_godebug_non_default_behavior_x509usepolicies_events_total", "/godebug/non-default-behavior/zipinsecurepath:events": "go_godebug_non_default_behavior_zipinsecurepath_events_total", "/memory/classes/heap/free:bytes": "go_memory_classes_heap_free_bytes", "/memory/classes/heap/objects:bytes": "go_memory_classes_heap_objects_bytes", "/memory/classes/heap/released:bytes": "go_memory_classes_heap_released_bytes", "/memory/classes/heap/stacks:bytes": "go_memory_classes_heap_stacks_bytes", "/memory/classes/heap/unused:bytes": "go_memory_classes_heap_unused_bytes", "/memory/classes/metadata/mcache/free:bytes": "go_memory_classes_metadata_mcache_free_bytes", "/memory/classes/metadata/mcache/inuse:bytes": "go_memory_classes_metadata_mcache_inuse_bytes", "/memory/classes/metadata/mspan/free:bytes": "go_memory_classes_metadata_mspan_free_bytes", "/memory/classes/metadata/mspan/inuse:bytes": "go_memory_classes_metadata_mspan_inuse_bytes", "/memory/classes/metadata/other:bytes": "go_memory_classes_metadata_other_bytes", "/memory/classes/os-stacks:bytes": "go_memory_classes_os_stacks_bytes", "/memory/classes/other:bytes": "go_memory_classes_other_bytes", "/memory/classes/profiling/buckets:bytes": "go_memory_classes_profiling_buckets_bytes", "/memory/classes/total:bytes": "go_memory_classes_total_bytes", "/sched/gomaxprocs:threads": "go_sched_gomaxprocs_threads", "/sched/goroutines:goroutines": "go_sched_goroutines_goroutines", "/sched/latencies:seconds": "go_sched_latencies_seconds", "/sched/pauses/stopping/gc:seconds": "go_sched_pauses_stopping_gc_seconds", "/sched/pauses/stopping/other:seconds": "go_sched_pauses_stopping_other_seconds", "/sched/pauses/total/gc:seconds": "go_sched_pauses_total_gc_seconds", "/sched/pauses/total/other:seconds": "go_sched_pauses_total_other_seconds", "/sync/mutex/wait/total:seconds": "go_sync_mutex_wait_total_seconds_total", } expMetrics = map[string]string{ "/gc/gogc:percent": "go_gc_gogc_percent", "/gc/gomemlimit:bytes": "go_gc_gomemlimit_bytes", "/sched/gomaxprocs:threads": "go_sched_gomaxprocs_threads", } ) const expectedRuntimeMetricsCardinality = 162 client_golang-1.21.1/prometheus/go_collector_metrics_go123_test.go000066400000000000000000000250541476160432400253130ustar00rootroot00000000000000// Code generated by gen_go_collector_metrics_set.go; DO NOT EDIT. //go:generate go run gen_go_collector_metrics_set.go go1.23 //go:build go1.23 && !go1.24 // +build go1.23,!go1.24 package prometheus var ( expectedRuntimeMetrics = map[string]string{ "/cgo/go-to-c-calls:calls": "go_cgo_go_to_c_calls_calls_total", "/cpu/classes/gc/mark/assist:cpu-seconds": "go_cpu_classes_gc_mark_assist_cpu_seconds_total", "/cpu/classes/gc/mark/dedicated:cpu-seconds": "go_cpu_classes_gc_mark_dedicated_cpu_seconds_total", "/cpu/classes/gc/mark/idle:cpu-seconds": "go_cpu_classes_gc_mark_idle_cpu_seconds_total", "/cpu/classes/gc/pause:cpu-seconds": "go_cpu_classes_gc_pause_cpu_seconds_total", "/cpu/classes/gc/total:cpu-seconds": "go_cpu_classes_gc_total_cpu_seconds_total", "/cpu/classes/idle:cpu-seconds": "go_cpu_classes_idle_cpu_seconds_total", "/cpu/classes/scavenge/assist:cpu-seconds": "go_cpu_classes_scavenge_assist_cpu_seconds_total", "/cpu/classes/scavenge/background:cpu-seconds": "go_cpu_classes_scavenge_background_cpu_seconds_total", "/cpu/classes/scavenge/total:cpu-seconds": "go_cpu_classes_scavenge_total_cpu_seconds_total", "/cpu/classes/total:cpu-seconds": "go_cpu_classes_total_cpu_seconds_total", "/cpu/classes/user:cpu-seconds": "go_cpu_classes_user_cpu_seconds_total", "/gc/cycles/automatic:gc-cycles": "go_gc_cycles_automatic_gc_cycles_total", "/gc/cycles/forced:gc-cycles": "go_gc_cycles_forced_gc_cycles_total", "/gc/cycles/total:gc-cycles": "go_gc_cycles_total_gc_cycles_total", "/gc/gogc:percent": "go_gc_gogc_percent", "/gc/gomemlimit:bytes": "go_gc_gomemlimit_bytes", "/gc/heap/allocs-by-size:bytes": "go_gc_heap_allocs_by_size_bytes", "/gc/heap/allocs:bytes": "go_gc_heap_allocs_bytes_total", "/gc/heap/allocs:objects": "go_gc_heap_allocs_objects_total", "/gc/heap/frees-by-size:bytes": "go_gc_heap_frees_by_size_bytes", "/gc/heap/frees:bytes": "go_gc_heap_frees_bytes_total", "/gc/heap/frees:objects": "go_gc_heap_frees_objects_total", "/gc/heap/goal:bytes": "go_gc_heap_goal_bytes", "/gc/heap/live:bytes": "go_gc_heap_live_bytes", "/gc/heap/objects:objects": "go_gc_heap_objects_objects", "/gc/heap/tiny/allocs:objects": "go_gc_heap_tiny_allocs_objects_total", "/gc/limiter/last-enabled:gc-cycle": "go_gc_limiter_last_enabled_gc_cycle", "/gc/pauses:seconds": "go_gc_pauses_seconds", "/gc/scan/globals:bytes": "go_gc_scan_globals_bytes", "/gc/scan/heap:bytes": "go_gc_scan_heap_bytes", "/gc/scan/stack:bytes": "go_gc_scan_stack_bytes", "/gc/scan/total:bytes": "go_gc_scan_total_bytes", "/gc/stack/starting-size:bytes": "go_gc_stack_starting_size_bytes", "/godebug/non-default-behavior/asynctimerchan:events": "go_godebug_non_default_behavior_asynctimerchan_events_total", "/godebug/non-default-behavior/execerrdot:events": "go_godebug_non_default_behavior_execerrdot_events_total", "/godebug/non-default-behavior/gocachehash:events": "go_godebug_non_default_behavior_gocachehash_events_total", "/godebug/non-default-behavior/gocachetest:events": "go_godebug_non_default_behavior_gocachetest_events_total", "/godebug/non-default-behavior/gocacheverify:events": "go_godebug_non_default_behavior_gocacheverify_events_total", "/godebug/non-default-behavior/gotypesalias:events": "go_godebug_non_default_behavior_gotypesalias_events_total", "/godebug/non-default-behavior/http2client:events": "go_godebug_non_default_behavior_http2client_events_total", "/godebug/non-default-behavior/http2server:events": "go_godebug_non_default_behavior_http2server_events_total", "/godebug/non-default-behavior/httplaxcontentlength:events": "go_godebug_non_default_behavior_httplaxcontentlength_events_total", "/godebug/non-default-behavior/httpmuxgo121:events": "go_godebug_non_default_behavior_httpmuxgo121_events_total", "/godebug/non-default-behavior/httpservecontentkeepheaders:events": "go_godebug_non_default_behavior_httpservecontentkeepheaders_events_total", "/godebug/non-default-behavior/installgoroot:events": "go_godebug_non_default_behavior_installgoroot_events_total", "/godebug/non-default-behavior/multipartmaxheaders:events": "go_godebug_non_default_behavior_multipartmaxheaders_events_total", "/godebug/non-default-behavior/multipartmaxparts:events": "go_godebug_non_default_behavior_multipartmaxparts_events_total", "/godebug/non-default-behavior/multipathtcp:events": "go_godebug_non_default_behavior_multipathtcp_events_total", "/godebug/non-default-behavior/netedns0:events": "go_godebug_non_default_behavior_netedns0_events_total", "/godebug/non-default-behavior/panicnil:events": "go_godebug_non_default_behavior_panicnil_events_total", "/godebug/non-default-behavior/randautoseed:events": "go_godebug_non_default_behavior_randautoseed_events_total", "/godebug/non-default-behavior/tarinsecurepath:events": "go_godebug_non_default_behavior_tarinsecurepath_events_total", "/godebug/non-default-behavior/tls10server:events": "go_godebug_non_default_behavior_tls10server_events_total", "/godebug/non-default-behavior/tls3des:events": "go_godebug_non_default_behavior_tls3des_events_total", "/godebug/non-default-behavior/tlsmaxrsasize:events": "go_godebug_non_default_behavior_tlsmaxrsasize_events_total", "/godebug/non-default-behavior/tlsrsakex:events": "go_godebug_non_default_behavior_tlsrsakex_events_total", "/godebug/non-default-behavior/tlsunsafeekm:events": "go_godebug_non_default_behavior_tlsunsafeekm_events_total", "/godebug/non-default-behavior/winreadlinkvolume:events": "go_godebug_non_default_behavior_winreadlinkvolume_events_total", "/godebug/non-default-behavior/winsymlink:events": "go_godebug_non_default_behavior_winsymlink_events_total", "/godebug/non-default-behavior/x509keypairleaf:events": "go_godebug_non_default_behavior_x509keypairleaf_events_total", "/godebug/non-default-behavior/x509negativeserial:events": "go_godebug_non_default_behavior_x509negativeserial_events_total", "/godebug/non-default-behavior/x509sha1:events": "go_godebug_non_default_behavior_x509sha1_events_total", "/godebug/non-default-behavior/x509usefallbackroots:events": "go_godebug_non_default_behavior_x509usefallbackroots_events_total", "/godebug/non-default-behavior/x509usepolicies:events": "go_godebug_non_default_behavior_x509usepolicies_events_total", "/godebug/non-default-behavior/zipinsecurepath:events": "go_godebug_non_default_behavior_zipinsecurepath_events_total", "/memory/classes/heap/free:bytes": "go_memory_classes_heap_free_bytes", "/memory/classes/heap/objects:bytes": "go_memory_classes_heap_objects_bytes", "/memory/classes/heap/released:bytes": "go_memory_classes_heap_released_bytes", "/memory/classes/heap/stacks:bytes": "go_memory_classes_heap_stacks_bytes", "/memory/classes/heap/unused:bytes": "go_memory_classes_heap_unused_bytes", "/memory/classes/metadata/mcache/free:bytes": "go_memory_classes_metadata_mcache_free_bytes", "/memory/classes/metadata/mcache/inuse:bytes": "go_memory_classes_metadata_mcache_inuse_bytes", "/memory/classes/metadata/mspan/free:bytes": "go_memory_classes_metadata_mspan_free_bytes", "/memory/classes/metadata/mspan/inuse:bytes": "go_memory_classes_metadata_mspan_inuse_bytes", "/memory/classes/metadata/other:bytes": "go_memory_classes_metadata_other_bytes", "/memory/classes/os-stacks:bytes": "go_memory_classes_os_stacks_bytes", "/memory/classes/other:bytes": "go_memory_classes_other_bytes", "/memory/classes/profiling/buckets:bytes": "go_memory_classes_profiling_buckets_bytes", "/memory/classes/total:bytes": "go_memory_classes_total_bytes", "/sched/gomaxprocs:threads": "go_sched_gomaxprocs_threads", "/sched/goroutines:goroutines": "go_sched_goroutines_goroutines", "/sched/latencies:seconds": "go_sched_latencies_seconds", "/sched/pauses/stopping/gc:seconds": "go_sched_pauses_stopping_gc_seconds", "/sched/pauses/stopping/other:seconds": "go_sched_pauses_stopping_other_seconds", "/sched/pauses/total/gc:seconds": "go_sched_pauses_total_gc_seconds", "/sched/pauses/total/other:seconds": "go_sched_pauses_total_other_seconds", "/sync/mutex/wait/total:seconds": "go_sync_mutex_wait_total_seconds_total", } expMetrics = map[string]string{ "/gc/gogc:percent": "go_gc_gogc_percent", "/gc/gomemlimit:bytes": "go_gc_gomemlimit_bytes", "/sched/gomaxprocs:threads": "go_sched_gomaxprocs_threads", } ) const expectedRuntimeMetricsCardinality = 168 client_golang-1.21.1/prometheus/go_collector_test.go000066400000000000000000000076661476160432400226630ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "runtime" "testing" "time" dto "github.com/prometheus/client_model/go" ) func TestGoCollectorGoroutines(t *testing.T) { var ( c = NewGoCollector() metricCh = make(chan Metric) waitCh = make(chan struct{}) endGoroutineCh = make(chan struct{}) endCollectionCh = make(chan struct{}) old = -1 ) defer func() { close(endGoroutineCh) // Drain the collect channel to prevent goroutine leak. for { select { case <-metricCh: case <-endCollectionCh: return } } }() go func() { c.Collect(metricCh) for i := 1; i <= 10; i++ { // Start 10 goroutines to be sure we'll detect an // increase even if unrelated goroutines happen to // terminate during this test. go func(c <-chan struct{}) { <-c }(endGoroutineCh) } <-waitCh c.Collect(metricCh) close(endCollectionCh) }() for { select { case m := <-metricCh: // m can be Gauge or Counter, // currently just test the go_goroutines Gauge // and ignore others. if m.Desc().fqName != "go_goroutines" { continue } pb := &dto.Metric{} m.Write(pb) if pb.GetGauge() == nil { continue } if old == -1 { old = int(pb.GetGauge().GetValue()) close(waitCh) continue } if diff := old - int(pb.GetGauge().GetValue()); diff > -1 { t.Errorf("want at least one new goroutine, got %d fewer", diff) } case <-time.After(1 * time.Second): t.Fatalf("expected collect timed out") } break } } func TestGoCollectorGC(t *testing.T) { var ( c = NewGoCollector() metricCh = make(chan Metric) waitCh = make(chan struct{}) endCollectionCh = make(chan struct{}) oldGC uint64 oldPause float64 ) go func() { c.Collect(metricCh) // force GC runtime.GC() <-waitCh c.Collect(metricCh) close(endCollectionCh) }() defer func() { // Drain the collect channel to prevent goroutine leak. for { select { case <-metricCh: case <-endCollectionCh: return } } }() first := true for { select { case metric := <-metricCh: pb := &dto.Metric{} metric.Write(pb) if pb.GetSummary() == nil { continue } if len(pb.GetSummary().Quantile) != 5 { t.Errorf("expected 4 buckets, got %d", len(pb.GetSummary().Quantile)) } for idx, want := range []float64{0.0, 0.25, 0.5, 0.75, 1.0} { if *pb.GetSummary().Quantile[idx].Quantile != want { t.Errorf("bucket #%d is off, got %f, want %f", idx, *pb.GetSummary().Quantile[idx].Quantile, want) } } if first { first = false oldGC = *pb.GetSummary().SampleCount oldPause = *pb.GetSummary().SampleSum close(waitCh) continue } if diff := *pb.GetSummary().SampleCount - oldGC; diff < 1 { t.Errorf("want at least 1 new garbage collection run, got %d", diff) } if diff := *pb.GetSummary().SampleSum - oldPause; diff <= 0 { t.Errorf("want an increase in pause time, got a change of %f", diff) } case <-time.After(1 * time.Second): t.Fatalf("expected collect timed out") } break } } func BenchmarkGoCollector(b *testing.B) { c := NewGoCollector().(*goCollector) b.ResetTimer() for i := 0; i < b.N; i++ { ch := make(chan Metric, 8) go func() { // Drain all metrics received until the // channel is closed. for range ch { } }() c.Collect(ch) close(ch) } } client_golang-1.21.1/prometheus/graphite/000077500000000000000000000000001476160432400204065ustar00rootroot00000000000000client_golang-1.21.1/prometheus/graphite/bridge.go000066400000000000000000000160341476160432400221750ustar00rootroot00000000000000// Copyright 2016 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package graphite provides a bridge to push Prometheus metrics to a Graphite // server. package graphite import ( "bufio" "context" "errors" "fmt" "io" "net" "sort" "time" "github.com/prometheus/common/expfmt" "github.com/prometheus/common/model" dto "github.com/prometheus/client_model/go" "github.com/prometheus/client_golang/prometheus" ) const ( defaultInterval = 15 * time.Second millisecondsPerSecond = 1000 ) // HandlerErrorHandling defines how a Handler serving metrics will handle // errors. type HandlerErrorHandling int // These constants cause handlers serving metrics to behave as described if // errors are encountered. const ( // Ignore errors and try to push as many metrics to Graphite as possible. ContinueOnError HandlerErrorHandling = iota // Abort the push to Graphite upon the first error encountered. AbortOnError ) // Config defines the Graphite bridge config. type Config struct { // Whether to use Graphite tags or not. Defaults to false. UseTags bool // The url to push data to. Required. URL string // The prefix for the pushed Graphite metrics. Defaults to empty string. Prefix string // The interval to use for pushing data to Graphite. Defaults to 15 seconds. Interval time.Duration // The timeout for pushing metrics to Graphite. Defaults to 15 seconds. Timeout time.Duration // The Gatherer to use for metrics. Defaults to prometheus.DefaultGatherer. Gatherer prometheus.Gatherer // The logger that messages are written to. Defaults to no logging. Logger Logger // ErrorHandling defines how errors are handled. Note that errors are // logged regardless of the configured ErrorHandling provided Logger // is not nil. ErrorHandling HandlerErrorHandling } // Bridge pushes metrics to the configured Graphite server. type Bridge struct { useTags bool url string prefix string interval time.Duration timeout time.Duration errorHandling HandlerErrorHandling logger Logger g prometheus.Gatherer } // Logger is the minimal interface Bridge needs for logging. Note that // log.Logger from the standard library implements this interface, and it is // easy to implement by custom loggers, if they don't do so already anyway. type Logger interface { Println(v ...interface{}) } // NewBridge returns a pointer to a new Bridge struct. func NewBridge(c *Config) (*Bridge, error) { b := &Bridge{} b.useTags = c.UseTags if c.URL == "" { return nil, errors.New("missing URL") } b.url = c.URL if c.Gatherer == nil { b.g = prometheus.DefaultGatherer } else { b.g = c.Gatherer } if c.Logger != nil { b.logger = c.Logger } if c.Prefix != "" { b.prefix = c.Prefix } var z time.Duration if c.Interval == z { b.interval = defaultInterval } else { b.interval = c.Interval } if c.Timeout == z { b.timeout = defaultInterval } else { b.timeout = c.Timeout } b.errorHandling = c.ErrorHandling return b, nil } // Run starts the event loop that pushes Prometheus metrics to Graphite at the // configured interval. func (b *Bridge) Run(ctx context.Context) { ticker := time.NewTicker(b.interval) defer ticker.Stop() for { select { case <-ticker.C: if err := b.Push(); err != nil && b.logger != nil { b.logger.Println("error pushing to Graphite:", err) } case <-ctx.Done(): return } } } // Push pushes Prometheus metrics to the configured Graphite server. func (b *Bridge) Push() error { mfs, err := b.g.Gather() if err != nil || len(mfs) == 0 { switch b.errorHandling { case AbortOnError: return err case ContinueOnError: if b.logger != nil { b.logger.Println("continue on error:", err) } default: panic("unrecognized error handling value") } } conn, err := net.DialTimeout("tcp", b.url, b.timeout) if err != nil { return err } defer conn.Close() return writeMetrics(conn, mfs, b.useTags, b.prefix, model.Now()) } func writeMetrics(w io.Writer, mfs []*dto.MetricFamily, useTags bool, prefix string, now model.Time) error { vec, err := expfmt.ExtractSamples(&expfmt.DecodeOptions{ Timestamp: now, }, mfs...) if err != nil { return err } buf := bufio.NewWriter(w) for _, s := range vec { if prefix != "" { for _, c := range prefix { if _, err := buf.WriteRune(c); err != nil { return err } } if err := buf.WriteByte('.'); err != nil { return err } } if err := writeMetric(buf, s.Metric, useTags); err != nil { return err } if _, err := fmt.Fprintf(buf, " %g %d\n", s.Value, int64(s.Timestamp)/millisecondsPerSecond); err != nil { return err } if err := buf.Flush(); err != nil { return err } } return nil } func writeMetric(buf *bufio.Writer, m model.Metric, useTags bool) error { metricName, hasName := m[model.MetricNameLabel] numLabels := len(m) - 1 if !hasName { numLabels = len(m) } var err error switch numLabels { case 0: if hasName { return writeSanitized(buf, string(metricName)) } default: if err = writeSanitized(buf, string(metricName)); err != nil { return err } if useTags { return writeTags(buf, m) } return writeLabels(buf, m, numLabels) } return nil } func writeTags(buf *bufio.Writer, m model.Metric) error { for label, value := range m { if label != model.MetricNameLabel { buf.WriteRune(';') if _, err := buf.WriteString(string(label)); err != nil { return err } buf.WriteRune('=') if _, err := buf.WriteString(string(value)); err != nil { return err } } } return nil } func writeLabels(buf *bufio.Writer, m model.Metric, numLabels int) error { labelStrings := make([]string, 0, numLabels) for label, value := range m { if label != model.MetricNameLabel { labelString := string(label) + " " + string(value) labelStrings = append(labelStrings, labelString) } } sort.Strings(labelStrings) for _, s := range labelStrings { if err := buf.WriteByte('.'); err != nil { return err } if err := writeSanitized(buf, s); err != nil { return err } } return nil } func writeSanitized(buf *bufio.Writer, s string) error { prevUnderscore := false for _, c := range s { c = replaceInvalidRune(c) if c == '_' { if prevUnderscore { continue } prevUnderscore = true } else { prevUnderscore = false } if _, err := buf.WriteRune(c); err != nil { return err } } return nil } func replaceInvalidRune(c rune) rune { if c == ' ' { return '.' } if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == ':' || c == '-' || (c >= '0' && c <= '9')) { return '_' } return c } client_golang-1.21.1/prometheus/graphite/bridge_test.go000066400000000000000000000307211476160432400232330ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package graphite import ( "bufio" "bytes" "context" "errors" "fmt" "io" "log" "net" "os" "reflect" "regexp" "sort" "strings" "testing" "time" "github.com/prometheus/common/model" "github.com/prometheus/client_golang/prometheus" ) func TestSanitize(t *testing.T) { testCases := []struct { in, out string }{ {in: "hello", out: "hello"}, {in: "hE/l1o", out: "hE_l1o"}, {in: "he,*ll(.o", out: "he_ll_o"}, {in: "hello_there%^&", out: "hello_there_"}, {in: "hell-.o", out: "hell-_o"}, } var buf bytes.Buffer w := bufio.NewWriter(&buf) for i, tc := range testCases { if err := writeSanitized(w, tc.in); err != nil { t.Fatalf("write failed: %v", err) } if err := w.Flush(); err != nil { t.Fatalf("flush failed: %v", err) } if want, got := tc.out, buf.String(); want != got { t.Fatalf("test case index %d: got sanitized string %s, want %s", i, got, want) } buf.Reset() } } func TestWriteSummary(t *testing.T) { testWriteSummary(t, false) testWriteSummary(t, true) } func testWriteSummary(t *testing.T, useTags bool) { sumVec := prometheus.NewSummaryVec( prometheus.SummaryOpts{ Name: "name", Help: "docstring", ConstLabels: prometheus.Labels{"constname": "constvalue"}, Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, }, []string{"labelname"}, ) sumVec.WithLabelValues("val1").Observe(float64(10)) sumVec.WithLabelValues("val1").Observe(float64(20)) sumVec.WithLabelValues("val1").Observe(float64(30)) sumVec.WithLabelValues("val2").Observe(float64(20)) sumVec.WithLabelValues("val2").Observe(float64(30)) sumVec.WithLabelValues("val2").Observe(float64(40)) reg := prometheus.NewRegistry() reg.MustRegister(sumVec) mfs, err := reg.Gather() if err != nil { t.Fatalf("error: %v", err) } testCases := []struct { prefix string }{ {prefix: "prefix"}, {prefix: "pre/fix"}, {prefix: "pre.fix"}, {prefix: ""}, } var ( want = `%s.name.constname.constvalue.labelname.val1.quantile.0_5 20 1477043 %s.name.constname.constvalue.labelname.val1.quantile.0_9 30 1477043 %s.name.constname.constvalue.labelname.val1.quantile.0_99 30 1477043 %s.name_sum.constname.constvalue.labelname.val1 60 1477043 %s.name_count.constname.constvalue.labelname.val1 3 1477043 %s.name.constname.constvalue.labelname.val2.quantile.0_5 30 1477043 %s.name.constname.constvalue.labelname.val2.quantile.0_9 40 1477043 %s.name.constname.constvalue.labelname.val2.quantile.0_99 40 1477043 %s.name_sum.constname.constvalue.labelname.val2 90 1477043 %s.name_count.constname.constvalue.labelname.val2 3 1477043 ` wantTagged = `%s.name;constname=constvalue;labelname=val1;quantile=0.5 20 1477043 %s.name;constname=constvalue;labelname=val1;quantile=0.9 30 1477043 %s.name;constname=constvalue;labelname=val1;quantile=0.99 30 1477043 %s.name_sum;constname=constvalue;labelname=val1 60 1477043 %s.name_count;constname=constvalue;labelname=val1 3 1477043 %s.name;constname=constvalue;labelname=val2;quantile=0.5 30 1477043 %s.name;constname=constvalue;labelname=val2;quantile=0.9 40 1477043 %s.name;constname=constvalue;labelname=val2;quantile=0.99 40 1477043 %s.name_sum;constname=constvalue;labelname=val2 90 1477043 %s.name_count;constname=constvalue;labelname=val2 3 1477043 ` ) if useTags { want = wantTagged } for i, tc := range testCases { now := model.Time(1477043083) var buf bytes.Buffer err = writeMetrics(&buf, mfs, useTags, tc.prefix, now) if err != nil { t.Fatalf("error: %v", err) } var wantWithPrefix string if tc.prefix == "" { wantWithPrefix = strings.ReplaceAll(want, "%s.", "") } else { wantWithPrefix = fmt.Sprintf(want, tc.prefix, tc.prefix, tc.prefix, tc.prefix, tc.prefix, tc.prefix, tc.prefix, tc.prefix, tc.prefix, tc.prefix, ) } got := buf.String() if err := checkLinesAreEqual(wantWithPrefix, got, useTags); err != nil { t.Fatalf("test case index %d:\n%s", i, err.Error()) } } } func TestWriteHistogram(t *testing.T) { testWriteHistogram(t, false) testWriteHistogram(t, true) } func testWriteHistogram(t *testing.T, useTags bool) { histVec := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "name", Help: "docstring", ConstLabels: prometheus.Labels{"constname": "constvalue"}, Buckets: []float64{0.01, 0.02, 0.05, 0.1}, }, []string{"labelname"}, ) histVec.WithLabelValues("val1").Observe(float64(10)) histVec.WithLabelValues("val1").Observe(float64(20)) histVec.WithLabelValues("val1").Observe(float64(30)) histVec.WithLabelValues("val2").Observe(float64(20)) histVec.WithLabelValues("val2").Observe(float64(30)) histVec.WithLabelValues("val2").Observe(float64(40)) reg := prometheus.NewRegistry() reg.MustRegister(histVec) mfs, err := reg.Gather() if err != nil { t.Fatalf("error: %v", err) } now := model.Time(1477043083) var buf bytes.Buffer err = writeMetrics(&buf, mfs, useTags, "prefix", now) if err != nil { t.Fatalf("error: %v", err) } var ( want = `prefix.name_bucket.constname.constvalue.labelname.val1.le.0_01 0 1477043 prefix.name_bucket.constname.constvalue.labelname.val1.le.0_02 0 1477043 prefix.name_bucket.constname.constvalue.labelname.val1.le.0_05 0 1477043 prefix.name_bucket.constname.constvalue.labelname.val1.le.0_1 0 1477043 prefix.name_sum.constname.constvalue.labelname.val1 60 1477043 prefix.name_count.constname.constvalue.labelname.val1 3 1477043 prefix.name_bucket.constname.constvalue.labelname.val1.le._Inf 3 1477043 prefix.name_bucket.constname.constvalue.labelname.val2.le.0_01 0 1477043 prefix.name_bucket.constname.constvalue.labelname.val2.le.0_02 0 1477043 prefix.name_bucket.constname.constvalue.labelname.val2.le.0_05 0 1477043 prefix.name_bucket.constname.constvalue.labelname.val2.le.0_1 0 1477043 prefix.name_sum.constname.constvalue.labelname.val2 90 1477043 prefix.name_count.constname.constvalue.labelname.val2 3 1477043 prefix.name_bucket.constname.constvalue.labelname.val2.le._Inf 3 1477043 ` wantTagged = `prefix.name_bucket;constname=constvalue;labelname=val1;le=0.01 0 1477043 prefix.name_bucket;constname=constvalue;labelname=val1;le=0.02 0 1477043 prefix.name_bucket;constname=constvalue;labelname=val1;le=0.05 0 1477043 prefix.name_bucket;constname=constvalue;labelname=val1;le=0.1 0 1477043 prefix.name_sum;constname=constvalue;labelname=val1 60 1477043 prefix.name_count;constname=constvalue;labelname=val1 3 1477043 prefix.name_bucket;constname=constvalue;labelname=val1;le=+Inf 3 1477043 prefix.name_bucket;constname=constvalue;labelname=val2;le=0.01 0 1477043 prefix.name_bucket;constname=constvalue;labelname=val2;le=0.02 0 1477043 prefix.name_bucket;constname=constvalue;labelname=val2;le=0.05 0 1477043 prefix.name_bucket;constname=constvalue;labelname=val2;le=0.1 0 1477043 prefix.name_sum;constname=constvalue;labelname=val2 90 1477043 prefix.name_count;constname=constvalue;labelname=val2 3 1477043 prefix.name_bucket;constname=constvalue;labelname=val2;le=+Inf 3 1477043 ` ) if useTags { want = wantTagged } got := buf.String() if err := checkLinesAreEqual(want, got, useTags); err != nil { t.Fatal(err.Error()) } } func TestToReader(t *testing.T) { testToReader(t, false) testToReader(t, true) } func testToReader(t *testing.T, useTags bool) { cntVec := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "name", Help: "docstring", ConstLabels: prometheus.Labels{"constname": "constvalue"}, }, []string{"labelname"}, ) cntVec.WithLabelValues("val1").Inc() cntVec.WithLabelValues("val2").Inc() reg := prometheus.NewRegistry() reg.MustRegister(cntVec) var ( want = `prefix.name.constname.constvalue.labelname.val1 1 1477043 prefix.name.constname.constvalue.labelname.val2 1 1477043 ` wantTagged = `prefix.name;constname=constvalue;labelname=val1 1 1477043 prefix.name;constname=constvalue;labelname=val2 1 1477043 ` ) if useTags { want = wantTagged } mfs, err := reg.Gather() if err != nil { t.Fatalf("error: %v", err) } now := model.Time(1477043083) var buf bytes.Buffer err = writeMetrics(&buf, mfs, useTags, "prefix", now) if err != nil { t.Fatalf("error: %v", err) } got := buf.String() if err := checkLinesAreEqual(want, got, useTags); err != nil { t.Fatal(err.Error()) } } func checkLinesAreEqual(w, g string, useTags bool) error { if useTags { taggedLineRegexp := regexp.MustCompile(`;| `) wantLines, err := stringToLines(w) if err != nil { return err } gotLines, err := stringToLines(g) if err != nil { return err } for lineInd := range gotLines { var log string // Tagged metric, order of tags doesn't matter // m1 := "prefix.name;tag1=val1;tag2=val2 3 1477043" // m2 := "prefix.name;tag2=val2;tag1=val1 3 1477043" // m1 should be equal to m2 wantSplit := taggedLineRegexp.Split(wantLines[lineInd], -1) gotSplit := taggedLineRegexp.Split(gotLines[lineInd], -1) sort.Strings(wantSplit) sort.Strings(gotSplit) log += fmt.Sprintf("want: %v\ngot: %v\n\n", wantSplit, gotSplit) if !reflect.DeepEqual(wantSplit, gotSplit) { return errors.New(log) } } return nil } if w != g { return fmt.Errorf("wanted:\n\n%s\ngot:\n\n%s", w, g) } return nil } func stringToLines(s string) (lines []string, err error) { scanner := bufio.NewScanner(strings.NewReader(s)) for scanner.Scan() { lines = append(lines, scanner.Text()) } err = scanner.Err() return } func TestPush(t *testing.T) { reg := prometheus.NewRegistry() cntVec := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "name", Help: "docstring", ConstLabels: prometheus.Labels{"constname": "constvalue"}, }, []string{"labelname"}, ) cntVec.WithLabelValues("val1").Inc() cntVec.WithLabelValues("val2").Inc() reg.MustRegister(cntVec) host := "localhost" port := ":56789" b, err := NewBridge(&Config{ URL: host + port, Gatherer: reg, Prefix: "prefix", }) if err != nil { t.Fatalf("error creating bridge: %v", err) } nmg, err := newMockGraphite(port) if err != nil { t.Fatalf("error creating mock graphite: %v", err) } defer nmg.Close() err = b.Push() if err != nil { t.Fatalf("error pushing: %v", err) } wants := []string{ "prefix.name.constname.constvalue.labelname.val1 1", "prefix.name.constname.constvalue.labelname.val2 1", } select { case got := <-nmg.readc: for _, want := range wants { matched, err := regexp.MatchString(want, got) if err != nil { t.Fatalf("error pushing: %v", err) } if !matched { t.Fatalf("missing metric:\nno match for %s received by server:\n%s", want, got) } } return case err := <-nmg.errc: t.Fatalf("error reading push: %v", err) case <-time.After(50 * time.Millisecond): t.Fatalf("no result from graphite server") } } func newMockGraphite(port string) (*mockGraphite, error) { readc := make(chan string) errc := make(chan error) ln, err := net.Listen("tcp", port) if err != nil { return nil, err } go func() { conn, err := ln.Accept() if err != nil { errc <- err } var b bytes.Buffer io.Copy(&b, conn) readc <- b.String() }() return &mockGraphite{ readc: readc, errc: errc, Listener: ln, }, nil } type mockGraphite struct { readc chan string errc chan error net.Listener } func ExampleBridge() { b, err := NewBridge(&Config{ URL: "graphite.example.org:3099", Gatherer: prometheus.DefaultGatherer, Prefix: "prefix", Interval: 15 * time.Second, Timeout: 10 * time.Second, ErrorHandling: AbortOnError, Logger: log.New(os.Stdout, "graphite bridge: ", log.Lshortfile), }) if err != nil { panic(err) } go func() { // Start something in a goroutine that uses metrics. }() // Push initial metrics to Graphite. Fail fast if the push fails. if err := b.Push(); err != nil { panic(err) } // Create a Context to control stopping the Run() loop that pushes // metrics to Graphite. ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Start pushing metrics to Graphite in the Run() loop. b.Run(ctx) } client_golang-1.21.1/prometheus/histogram.go000066400000000000000000002404151476160432400211350ustar00rootroot00000000000000// Copyright 2015 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "errors" "fmt" "math" "runtime" "sort" "sync" "sync/atomic" "time" dto "github.com/prometheus/client_model/go" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" ) const ( nativeHistogramSchemaMaximum = 8 nativeHistogramSchemaMinimum = -4 ) // nativeHistogramBounds for the frac of observed values. Only relevant for // schema > 0. The position in the slice is the schema. (0 is never used, just // here for convenience of using the schema directly as the index.) // // TODO(beorn7): Currently, we do a binary search into these slices. There are // ways to turn it into a small number of simple array lookups. It probably only // matters for schema 5 and beyond, but should be investigated. See this comment // as a starting point: // https://github.com/open-telemetry/opentelemetry-specification/issues/1776#issuecomment-870164310 var nativeHistogramBounds = [][]float64{ // Schema "0": {0.5}, // Schema 1: {0.5, 0.7071067811865475}, // Schema 2: {0.5, 0.5946035575013605, 0.7071067811865475, 0.8408964152537144}, // Schema 3: { 0.5, 0.5452538663326288, 0.5946035575013605, 0.6484197773255048, 0.7071067811865475, 0.7711054127039704, 0.8408964152537144, 0.9170040432046711, }, // Schema 4: { 0.5, 0.5221368912137069, 0.5452538663326288, 0.5693943173783458, 0.5946035575013605, 0.620928906036742, 0.6484197773255048, 0.6771277734684463, 0.7071067811865475, 0.7384130729697496, 0.7711054127039704, 0.805245165974627, 0.8408964152537144, 0.8781260801866495, 0.9170040432046711, 0.9576032806985735, }, // Schema 5: { 0.5, 0.5109485743270583, 0.5221368912137069, 0.5335702003384117, 0.5452538663326288, 0.5571933712979462, 0.5693943173783458, 0.5818624293887887, 0.5946035575013605, 0.6076236799902344, 0.620928906036742, 0.6345254785958666, 0.6484197773255048, 0.6626183215798706, 0.6771277734684463, 0.6919549409819159, 0.7071067811865475, 0.7225904034885232, 0.7384130729697496, 0.7545822137967112, 0.7711054127039704, 0.7879904225539431, 0.805245165974627, 0.8228777390769823, 0.8408964152537144, 0.8593096490612387, 0.8781260801866495, 0.8973545375015533, 0.9170040432046711, 0.9370838170551498, 0.9576032806985735, 0.9785720620876999, }, // Schema 6: { 0.5, 0.5054446430258502, 0.5109485743270583, 0.5165124395106142, 0.5221368912137069, 0.5278225891802786, 0.5335702003384117, 0.5393803988785598, 0.5452538663326288, 0.5511912916539204, 0.5571933712979462, 0.5632608093041209, 0.5693943173783458, 0.5755946149764913, 0.5818624293887887, 0.5881984958251406, 0.5946035575013605, 0.6010783657263515, 0.6076236799902344, 0.6142402680534349, 0.620928906036742, 0.6276903785123455, 0.6345254785958666, 0.6414350080393891, 0.6484197773255048, 0.6554806057623822, 0.6626183215798706, 0.6698337620266515, 0.6771277734684463, 0.6845012114872953, 0.6919549409819159, 0.6994898362691555, 0.7071067811865475, 0.7148066691959849, 0.7225904034885232, 0.7304588970903234, 0.7384130729697496, 0.7464538641456323, 0.7545822137967112, 0.762799075372269, 0.7711054127039704, 0.7795022001189185, 0.7879904225539431, 0.7965710756711334, 0.805245165974627, 0.8140137109286738, 0.8228777390769823, 0.8318382901633681, 0.8408964152537144, 0.8500531768592616, 0.8593096490612387, 0.8686669176368529, 0.8781260801866495, 0.8876882462632604, 0.8973545375015533, 0.9071260877501991, 0.9170040432046711, 0.9269895625416926, 0.9370838170551498, 0.9472879907934827, 0.9576032806985735, 0.9680308967461471, 0.9785720620876999, 0.9892280131939752, }, // Schema 7: { 0.5, 0.5027149505564014, 0.5054446430258502, 0.5081891574554764, 0.5109485743270583, 0.5137229745593818, 0.5165124395106142, 0.5193170509806894, 0.5221368912137069, 0.5249720429003435, 0.5278225891802786, 0.5306886136446309, 0.5335702003384117, 0.5364674337629877, 0.5393803988785598, 0.5423091811066545, 0.5452538663326288, 0.5482145409081883, 0.5511912916539204, 0.5541842058618393, 0.5571933712979462, 0.5602188762048033, 0.5632608093041209, 0.5663192597993595, 0.5693943173783458, 0.572486072215902, 0.5755946149764913, 0.5787200368168754, 0.5818624293887887, 0.585021884841625, 0.5881984958251406, 0.5913923554921704, 0.5946035575013605, 0.5978321960199137, 0.6010783657263515, 0.6043421618132907, 0.6076236799902344, 0.6109230164863786, 0.6142402680534349, 0.6175755319684665, 0.620928906036742, 0.6243004885946023, 0.6276903785123455, 0.6310986751971253, 0.6345254785958666, 0.637970889198196, 0.6414350080393891, 0.6449179367033329, 0.6484197773255048, 0.6519406325959679, 0.6554806057623822, 0.659039800633032, 0.6626183215798706, 0.6662162735415805, 0.6698337620266515, 0.6734708931164728, 0.6771277734684463, 0.6808045103191123, 0.6845012114872953, 0.688217985377265, 0.6919549409819159, 0.6957121878859629, 0.6994898362691555, 0.7032879969095076, 0.7071067811865475, 0.7109463010845827, 0.7148066691959849, 0.718687998724491, 0.7225904034885232, 0.7265139979245261, 0.7304588970903234, 0.7344252166684908, 0.7384130729697496, 0.7424225829363761, 0.7464538641456323, 0.7505070348132126, 0.7545822137967112, 0.7586795205991071, 0.762799075372269, 0.7669409989204777, 0.7711054127039704, 0.7752924388424999, 0.7795022001189185, 0.7837348199827764, 0.7879904225539431, 0.7922691326262467, 0.7965710756711334, 0.8008963778413465, 0.805245165974627, 0.8096175675974316, 0.8140137109286738, 0.8184337248834821, 0.8228777390769823, 0.8273458838280969, 0.8318382901633681, 0.8363550898207981, 0.8408964152537144, 0.8454623996346523, 0.8500531768592616, 0.8546688815502312, 0.8593096490612387, 0.8639756154809185, 0.8686669176368529, 0.8733836930995842, 0.8781260801866495, 0.8828942179666361, 0.8876882462632604, 0.8925083056594671, 0.8973545375015533, 0.9022270839033115, 0.9071260877501991, 0.9120516927035263, 0.9170040432046711, 0.9219832844793128, 0.9269895625416926, 0.9320230241988943, 0.9370838170551498, 0.9421720895161669, 0.9472879907934827, 0.9524316709088368, 0.9576032806985735, 0.9628029718180622, 0.9680308967461471, 0.9732872087896164, 0.9785720620876999, 0.9838856116165875, 0.9892280131939752, 0.9945994234836328, }, // Schema 8: { 0.5, 0.5013556375251013, 0.5027149505564014, 0.5040779490592088, 0.5054446430258502, 0.5068150424757447, 0.5081891574554764, 0.509566998038869, 0.5109485743270583, 0.5123338964485679, 0.5137229745593818, 0.5151158188430205, 0.5165124395106142, 0.5179128468009786, 0.5193170509806894, 0.520725062344158, 0.5221368912137069, 0.5235525479396449, 0.5249720429003435, 0.526395386502313, 0.5278225891802786, 0.5292536613972564, 0.5306886136446309, 0.5321274564422321, 0.5335702003384117, 0.5350168559101208, 0.5364674337629877, 0.5379219445313954, 0.5393803988785598, 0.5408428074966075, 0.5423091811066545, 0.5437795304588847, 0.5452538663326288, 0.5467321995364429, 0.5482145409081883, 0.549700901315111, 0.5511912916539204, 0.5526857228508706, 0.5541842058618393, 0.5556867516724088, 0.5571933712979462, 0.5587040757836845, 0.5602188762048033, 0.5617377836665098, 0.5632608093041209, 0.564787964283144, 0.5663192597993595, 0.5678547070789026, 0.5693943173783458, 0.5709381019847808, 0.572486072215902, 0.5740382394200894, 0.5755946149764913, 0.5771552102951081, 0.5787200368168754, 0.5802891060137493, 0.5818624293887887, 0.5834400184762408, 0.585021884841625, 0.5866080400818185, 0.5881984958251406, 0.5897932637314379, 0.5913923554921704, 0.5929957828304968, 0.5946035575013605, 0.5962156912915756, 0.5978321960199137, 0.5994530835371903, 0.6010783657263515, 0.6027080545025619, 0.6043421618132907, 0.6059806996384005, 0.6076236799902344, 0.6092711149137041, 0.6109230164863786, 0.6125793968185725, 0.6142402680534349, 0.6159056423670379, 0.6175755319684665, 0.6192499490999082, 0.620928906036742, 0.622612415087629, 0.6243004885946023, 0.6259931389331581, 0.6276903785123455, 0.6293922197748583, 0.6310986751971253, 0.6328097572894031, 0.6345254785958666, 0.6362458516947014, 0.637970889198196, 0.6397006037528346, 0.6414350080393891, 0.6431741147730128, 0.6449179367033329, 0.6466664866145447, 0.6484197773255048, 0.6501778216898253, 0.6519406325959679, 0.6537082229673385, 0.6554806057623822, 0.6572577939746774, 0.659039800633032, 0.6608266388015788, 0.6626183215798706, 0.6644148621029772, 0.6662162735415805, 0.6680225691020727, 0.6698337620266515, 0.6716498655934177, 0.6734708931164728, 0.6752968579460171, 0.6771277734684463, 0.6789636531064505, 0.6808045103191123, 0.6826503586020058, 0.6845012114872953, 0.6863570825438342, 0.688217985377265, 0.690083933630119, 0.6919549409819159, 0.6938310211492645, 0.6957121878859629, 0.6975984549830999, 0.6994898362691555, 0.7013863456101023, 0.7032879969095076, 0.7051948041086352, 0.7071067811865475, 0.7090239421602076, 0.7109463010845827, 0.7128738720527471, 0.7148066691959849, 0.7167447066838943, 0.718687998724491, 0.7206365595643126, 0.7225904034885232, 0.7245495448210174, 0.7265139979245261, 0.7284837772007218, 0.7304588970903234, 0.7324393720732029, 0.7344252166684908, 0.7364164454346837, 0.7384130729697496, 0.7404151139112358, 0.7424225829363761, 0.7444354947621984, 0.7464538641456323, 0.7484777058836176, 0.7505070348132126, 0.7525418658117031, 0.7545822137967112, 0.7566280937263048, 0.7586795205991071, 0.7607365094544071, 0.762799075372269, 0.7648672334736434, 0.7669409989204777, 0.7690203869158282, 0.7711054127039704, 0.7731960915705107, 0.7752924388424999, 0.7773944698885442, 0.7795022001189185, 0.7816156449856788, 0.7837348199827764, 0.7858597406461707, 0.7879904225539431, 0.7901268813264122, 0.7922691326262467, 0.7944171921585818, 0.7965710756711334, 0.7987307989543135, 0.8008963778413465, 0.8030678282083853, 0.805245165974627, 0.8074284071024302, 0.8096175675974316, 0.8118126635086642, 0.8140137109286738, 0.8162207259936375, 0.8184337248834821, 0.820652723822003, 0.8228777390769823, 0.8251087869603088, 0.8273458838280969, 0.8295890460808079, 0.8318382901633681, 0.8340936325652911, 0.8363550898207981, 0.8386226785089391, 0.8408964152537144, 0.8431763167241966, 0.8454623996346523, 0.8477546807446661, 0.8500531768592616, 0.8523579048290255, 0.8546688815502312, 0.8569861239649629, 0.8593096490612387, 0.8616394738731368, 0.8639756154809185, 0.8663180910111553, 0.8686669176368529, 0.871022112577578, 0.8733836930995842, 0.8757516765159389, 0.8781260801866495, 0.8805069215187917, 0.8828942179666361, 0.8852879870317771, 0.8876882462632604, 0.890095013257712, 0.8925083056594671, 0.8949281411607002, 0.8973545375015533, 0.8997875124702672, 0.9022270839033115, 0.9046732696855155, 0.9071260877501991, 0.909585556079304, 0.9120516927035263, 0.9145245157024483, 0.9170040432046711, 0.9194902933879467, 0.9219832844793128, 0.9244830347552253, 0.9269895625416926, 0.92950288621441, 0.9320230241988943, 0.9345499949706191, 0.9370838170551498, 0.93962450902828, 0.9421720895161669, 0.9447265771954693, 0.9472879907934827, 0.9498563490882775, 0.9524316709088368, 0.9550139751351947, 0.9576032806985735, 0.9601996065815236, 0.9628029718180622, 0.9654133954938133, 0.9680308967461471, 0.9706554947643201, 0.9732872087896164, 0.9759260581154889, 0.9785720620876999, 0.9812252401044634, 0.9838856116165875, 0.9865531961276168, 0.9892280131939752, 0.9919100824251095, 0.9945994234836328, 0.9972960560854698, }, } // The nativeHistogramBounds above can be generated with the code below. // // TODO(beorn7): It's tempting to actually use `go generate` to generate the // code above. However, this could lead to slightly different numbers on // different architectures. We still need to come to terms if we are fine with // that, or if we might prefer to specify precise numbers in the standard. // // var nativeHistogramBounds [][]float64 = make([][]float64, 9) // // func init() { // // Populate nativeHistogramBounds. // numBuckets := 1 // for i := range nativeHistogramBounds { // bounds := []float64{0.5} // factor := math.Exp2(math.Exp2(float64(-i))) // for j := 0; j < numBuckets-1; j++ { // var bound float64 // if (j+1)%2 == 0 { // // Use previously calculated value for increased precision. // bound = nativeHistogramBounds[i-1][j/2+1] // } else { // bound = bounds[j] * factor // } // bounds = append(bounds, bound) // } // numBuckets *= 2 // nativeHistogramBounds[i] = bounds // } // } // A Histogram counts individual observations from an event or sample stream in // configurable static buckets (or in dynamic sparse buckets as part of the // experimental Native Histograms, see below for more details). Similar to a // Summary, it also provides a sum of observations and an observation count. // // On the Prometheus server, quantiles can be calculated from a Histogram using // the histogram_quantile PromQL function. // // Note that Histograms, in contrast to Summaries, can be aggregated in PromQL // (see the documentation for detailed procedures). However, Histograms require // the user to pre-define suitable buckets, and they are in general less // accurate. (Both problems are addressed by the experimental Native // Histograms. To use them, configure a NativeHistogramBucketFactor in the // HistogramOpts. They also require a Prometheus server v2.40+ with the // corresponding feature flag enabled.) // // The Observe method of a Histogram has a very low performance overhead in // comparison with the Observe method of a Summary. // // To create Histogram instances, use NewHistogram. type Histogram interface { Metric Collector // Observe adds a single observation to the histogram. Observations are // usually positive or zero. Negative observations are accepted but // prevent current versions of Prometheus from properly detecting // counter resets in the sum of observations. (The experimental Native // Histograms handle negative observations properly.) See // https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations // for details. Observe(float64) } // bucketLabel is used for the label that defines the upper bound of a // bucket of a histogram ("le" -> "less or equal"). const bucketLabel = "le" // DefBuckets are the default Histogram buckets. The default buckets are // tailored to broadly measure the response time (in seconds) of a network // service. Most likely, however, you will be required to define buckets // customized to your use case. var DefBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10} // DefNativeHistogramZeroThreshold is the default value for // NativeHistogramZeroThreshold in the HistogramOpts. // // The value is 2^-128 (or 0.5*2^-127 in the actual IEEE 754 representation), // which is a bucket boundary at all possible resolutions. const DefNativeHistogramZeroThreshold = 2.938735877055719e-39 // NativeHistogramZeroThresholdZero can be used as NativeHistogramZeroThreshold // in the HistogramOpts to create a zero bucket of width zero, i.e. a zero // bucket that only receives observations of precisely zero. const NativeHistogramZeroThresholdZero = -1 var errBucketLabelNotAllowed = fmt.Errorf( "%q is not allowed as label name in histograms", bucketLabel, ) // LinearBuckets creates 'count' regular buckets, each 'width' wide, where the // lowest bucket has an upper bound of 'start'. The final +Inf bucket is not // counted and not included in the returned slice. The returned slice is meant // to be used for the Buckets field of HistogramOpts. // // The function panics if 'count' is zero or negative. func LinearBuckets(start, width float64, count int) []float64 { if count < 1 { panic("LinearBuckets needs a positive count") } buckets := make([]float64, count) for i := range buckets { buckets[i] = start start += width } return buckets } // ExponentialBuckets creates 'count' regular buckets, where the lowest bucket // has an upper bound of 'start' and each following bucket's upper bound is // 'factor' times the previous bucket's upper bound. The final +Inf bucket is // not counted and not included in the returned slice. The returned slice is // meant to be used for the Buckets field of HistogramOpts. // // The function panics if 'count' is 0 or negative, if 'start' is 0 or negative, // or if 'factor' is less than or equal 1. func ExponentialBuckets(start, factor float64, count int) []float64 { if count < 1 { panic("ExponentialBuckets needs a positive count") } if start <= 0 { panic("ExponentialBuckets needs a positive start value") } if factor <= 1 { panic("ExponentialBuckets needs a factor greater than 1") } buckets := make([]float64, count) for i := range buckets { buckets[i] = start start *= factor } return buckets } // ExponentialBucketsRange creates 'count' buckets, where the lowest bucket is // 'min' and the highest bucket is 'max'. The final +Inf bucket is not counted // and not included in the returned slice. The returned slice is meant to be // used for the Buckets field of HistogramOpts. // // The function panics if 'count' is 0 or negative, if 'min' is 0 or negative. func ExponentialBucketsRange(minBucket, maxBucket float64, count int) []float64 { if count < 1 { panic("ExponentialBucketsRange count needs a positive count") } if minBucket <= 0 { panic("ExponentialBucketsRange min needs to be greater than 0") } // Formula for exponential buckets. // max = min*growthFactor^(bucketCount-1) // We know max/min and highest bucket. Solve for growthFactor. growthFactor := math.Pow(maxBucket/minBucket, 1.0/float64(count-1)) // Now that we know growthFactor, solve for each bucket. buckets := make([]float64, count) for i := 1; i <= count; i++ { buckets[i-1] = minBucket * math.Pow(growthFactor, float64(i-1)) } return buckets } // HistogramOpts bundles the options for creating a Histogram metric. It is // mandatory to set Name to a non-empty string. All other fields are optional // and can safely be left at their zero value, although it is strongly // encouraged to set a Help string. type HistogramOpts struct { // Namespace, Subsystem, and Name are components of the fully-qualified // name of the Histogram (created by joining these components with // "_"). Only Name is mandatory, the others merely help structuring the // name. Note that the fully-qualified name of the Histogram must be a // valid Prometheus metric name. Namespace string Subsystem string Name string // Help provides information about this Histogram. // // Metrics with the same fully-qualified name must have the same Help // string. Help string // ConstLabels are used to attach fixed labels to this metric. Metrics // with the same fully-qualified name must have the same label names in // their ConstLabels. // // ConstLabels are only used rarely. In particular, do not use them to // attach the same labels to all your metrics. Those use cases are // better covered by target labels set by the scraping Prometheus // server, or by one specific metric (e.g. a build_info or a // machine_role metric). See also // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels ConstLabels Labels // Buckets defines the buckets into which observations are counted. Each // element in the slice is the upper inclusive bound of a bucket. The // values must be sorted in strictly increasing order. There is no need // to add a highest bucket with +Inf bound, it will be added // implicitly. If Buckets is left as nil or set to a slice of length // zero, it is replaced by default buckets. The default buckets are // DefBuckets if no buckets for a native histogram (see below) are used, // otherwise the default is no buckets. (In other words, if you want to // use both regular buckets and buckets for a native histogram, you have // to define the regular buckets here explicitly.) Buckets []float64 // If NativeHistogramBucketFactor is greater than one, so-called sparse // buckets are used (in addition to the regular buckets, if defined // above). A Histogram with sparse buckets will be ingested as a Native // Histogram by a Prometheus server with that feature enabled (requires // Prometheus v2.40+). Sparse buckets are exponential buckets covering // the whole float64 range (with the exception of the β€œzero” bucket, see // NativeHistogramZeroThreshold below). From any one bucket to the next, // the width of the bucket grows by a constant // factor. NativeHistogramBucketFactor provides an upper bound for this // factor (exception see below). The smaller // NativeHistogramBucketFactor, the more buckets will be used and thus // the more costly the histogram will become. A generally good trade-off // between cost and accuracy is a value of 1.1 (each bucket is at most // 10% wider than the previous one), which will result in each power of // two divided into 8 buckets (e.g. there will be 8 buckets between 1 // and 2, same as between 2 and 4, and 4 and 8, etc.). // // Details about the actually used factor: The factor is calculated as // 2^(2^-n), where n is an integer number between (and including) -4 and // 8. n is chosen so that the resulting factor is the largest that is // still smaller or equal to NativeHistogramBucketFactor. Note that the // smallest possible factor is therefore approx. 1.00271 (i.e. 2^(2^-8) // ). If NativeHistogramBucketFactor is greater than 1 but smaller than // 2^(2^-8), then the actually used factor is still 2^(2^-8) even though // it is larger than the provided NativeHistogramBucketFactor. // // NOTE: Native Histograms are still an experimental feature. Their // behavior might still change without a major version // bump. Subsequently, all NativeHistogram... options here might still // change their behavior or name (or might completely disappear) without // a major version bump. NativeHistogramBucketFactor float64 // All observations with an absolute value of less or equal // NativeHistogramZeroThreshold are accumulated into a β€œzero” bucket. // For best results, this should be close to a bucket boundary. This is // usually the case if picking a power of two. If // NativeHistogramZeroThreshold is left at zero, // DefNativeHistogramZeroThreshold is used as the threshold. To // configure a zero bucket with an actual threshold of zero (i.e. only // observations of precisely zero will go into the zero bucket), set // NativeHistogramZeroThreshold to the NativeHistogramZeroThresholdZero // constant (or any negative float value). NativeHistogramZeroThreshold float64 // The next three fields define a strategy to limit the number of // populated sparse buckets. If NativeHistogramMaxBucketNumber is left // at zero, the number of buckets is not limited. (Note that this might // lead to unbounded memory consumption if the values observed by the // Histogram are sufficiently wide-spread. In particular, this could be // used as a DoS attack vector. Where the observed values depend on // external inputs, it is highly recommended to set a // NativeHistogramMaxBucketNumber.) Once the set // NativeHistogramMaxBucketNumber is exceeded, the following strategy is // enacted: // - First, if the last reset (or the creation) of the histogram is at // least NativeHistogramMinResetDuration ago, then the whole // histogram is reset to its initial state (including regular // buckets). // - If less time has passed, or if NativeHistogramMinResetDuration is // zero, no reset is performed. Instead, the zero threshold is // increased sufficiently to reduce the number of buckets to or below // NativeHistogramMaxBucketNumber, but not to more than // NativeHistogramMaxZeroThreshold. Thus, if // NativeHistogramMaxZeroThreshold is already at or below the current // zero threshold, nothing happens at this step. // - After that, if the number of buckets still exceeds // NativeHistogramMaxBucketNumber, the resolution of the histogram is // reduced by doubling the width of the sparse buckets (up to a // growth factor between one bucket to the next of 2^(2^4) = 65536, // see above). // - Any increased zero threshold or reduced resolution is reset back // to their original values once NativeHistogramMinResetDuration has // passed (since the last reset or the creation of the histogram). NativeHistogramMaxBucketNumber uint32 NativeHistogramMinResetDuration time.Duration NativeHistogramMaxZeroThreshold float64 // NativeHistogramMaxExemplars limits the number of exemplars // that are kept in memory for each native histogram. If you leave it at // zero, a default value of 10 is used. If no exemplars should be kept specifically // for native histograms, set it to a negative value. (Scrapers can // still use the exemplars exposed for classic buckets, which are managed // independently.) NativeHistogramMaxExemplars int // NativeHistogramExemplarTTL is only checked once // NativeHistogramMaxExemplars is exceeded. In that case, the // oldest exemplar is removed if it is older than NativeHistogramExemplarTTL. // Otherwise, the older exemplar in the pair of exemplars that are closest // together (on an exponential scale) is removed. // If NativeHistogramExemplarTTL is left at its zero value, a default value of // 5m is used. To always delete the oldest exemplar, set it to a negative value. NativeHistogramExemplarTTL time.Duration // now is for testing purposes, by default it's time.Now. now func() time.Time // afterFunc is for testing purposes, by default it's time.AfterFunc. afterFunc func(time.Duration, func()) *time.Timer } // HistogramVecOpts bundles the options to create a HistogramVec metric. // It is mandatory to set HistogramOpts, see there for mandatory fields. VariableLabels // is optional and can safely be left to its default value. type HistogramVecOpts struct { HistogramOpts // VariableLabels are used to partition the metric vector by the given set // of labels. Each label value will be constrained with the optional Constraint // function, if provided. VariableLabels ConstrainableLabels } // NewHistogram creates a new Histogram based on the provided HistogramOpts. It // panics if the buckets in HistogramOpts are not in strictly increasing order. // // The returned implementation also implements ExemplarObserver. It is safe to // perform the corresponding type assertion. Exemplars are tracked separately // for each bucket. func NewHistogram(opts HistogramOpts) Histogram { return newHistogram( NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, nil, opts.ConstLabels, ), opts, ) } func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogram { if len(desc.variableLabels.names) != len(labelValues) { panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, labelValues)) } for _, n := range desc.variableLabels.names { if n == bucketLabel { panic(errBucketLabelNotAllowed) } } for _, lp := range desc.constLabelPairs { if lp.GetName() == bucketLabel { panic(errBucketLabelNotAllowed) } } if opts.now == nil { opts.now = time.Now } if opts.afterFunc == nil { opts.afterFunc = time.AfterFunc } h := &histogram{ desc: desc, upperBounds: opts.Buckets, labelPairs: MakeLabelPairs(desc, labelValues), nativeHistogramMaxBuckets: opts.NativeHistogramMaxBucketNumber, nativeHistogramMaxZeroThreshold: opts.NativeHistogramMaxZeroThreshold, nativeHistogramMinResetDuration: opts.NativeHistogramMinResetDuration, lastResetTime: opts.now(), now: opts.now, afterFunc: opts.afterFunc, } if len(h.upperBounds) == 0 && opts.NativeHistogramBucketFactor <= 1 { h.upperBounds = DefBuckets } if opts.NativeHistogramBucketFactor <= 1 { h.nativeHistogramSchema = math.MinInt32 // To mark that there are no sparse buckets. } else { switch { case opts.NativeHistogramZeroThreshold > 0: h.nativeHistogramZeroThreshold = opts.NativeHistogramZeroThreshold case opts.NativeHistogramZeroThreshold == 0: h.nativeHistogramZeroThreshold = DefNativeHistogramZeroThreshold } // Leave h.nativeHistogramZeroThreshold at 0 otherwise. h.nativeHistogramSchema = pickSchema(opts.NativeHistogramBucketFactor) h.nativeExemplars = makeNativeExemplars(opts.NativeHistogramExemplarTTL, opts.NativeHistogramMaxExemplars) } for i, upperBound := range h.upperBounds { if i < len(h.upperBounds)-1 { if upperBound >= h.upperBounds[i+1] { panic(fmt.Errorf( "histogram buckets must be in increasing order: %f >= %f", upperBound, h.upperBounds[i+1], )) } } else { if math.IsInf(upperBound, +1) { // The +Inf bucket is implicit. Remove it here. h.upperBounds = h.upperBounds[:i] } } } // Finally we know the final length of h.upperBounds and can make buckets // for both counts as well as exemplars: h.counts[0] = &histogramCounts{buckets: make([]uint64, len(h.upperBounds))} atomic.StoreUint64(&h.counts[0].nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold)) atomic.StoreInt32(&h.counts[0].nativeHistogramSchema, h.nativeHistogramSchema) h.counts[1] = &histogramCounts{buckets: make([]uint64, len(h.upperBounds))} atomic.StoreUint64(&h.counts[1].nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold)) atomic.StoreInt32(&h.counts[1].nativeHistogramSchema, h.nativeHistogramSchema) h.exemplars = make([]atomic.Value, len(h.upperBounds)+1) h.init(h) // Init self-collection. return h } type histogramCounts struct { // Order in this struct matters for the alignment required by atomic // operations, see http://golang.org/pkg/sync/atomic/#pkg-note-BUG // sumBits contains the bits of the float64 representing the sum of all // observations. sumBits uint64 count uint64 // nativeHistogramZeroBucket counts all (positive and negative) // observations in the zero bucket (with an absolute value less or equal // the current threshold, see next field. nativeHistogramZeroBucket uint64 // nativeHistogramZeroThresholdBits is the bit pattern of the current // threshold for the zero bucket. It's initially equal to // nativeHistogramZeroThreshold but may change according to the bucket // count limitation strategy. nativeHistogramZeroThresholdBits uint64 // nativeHistogramSchema may change over time according to the bucket // count limitation strategy and therefore has to be saved here. nativeHistogramSchema int32 // Number of (positive and negative) sparse buckets. nativeHistogramBucketsNumber uint32 // Regular buckets. buckets []uint64 // The sparse buckets for native histograms are implemented with a // sync.Map for now. A dedicated data structure will likely be more // efficient. There are separate maps for negative and positive // observations. The map's value is an *int64, counting observations in // that bucket. (Note that we don't use uint64 as an int64 won't // overflow in practice, and working with signed numbers from the // beginning simplifies the handling of deltas.) The map's key is the // index of the bucket according to the used // nativeHistogramSchema. Index 0 is for an upper bound of 1. nativeHistogramBucketsPositive, nativeHistogramBucketsNegative sync.Map } // observe manages the parts of observe that only affects // histogramCounts. doSparse is true if sparse buckets should be done, // too. func (hc *histogramCounts) observe(v float64, bucket int, doSparse bool) { if bucket < len(hc.buckets) { atomic.AddUint64(&hc.buckets[bucket], 1) } atomicAddFloat(&hc.sumBits, v) if doSparse && !math.IsNaN(v) { var ( key int schema = atomic.LoadInt32(&hc.nativeHistogramSchema) zeroThreshold = math.Float64frombits(atomic.LoadUint64(&hc.nativeHistogramZeroThresholdBits)) bucketCreated, isInf bool ) if math.IsInf(v, 0) { // Pretend v is MaxFloat64 but later increment key by one. if math.IsInf(v, +1) { v = math.MaxFloat64 } else { v = -math.MaxFloat64 } isInf = true } frac, exp := math.Frexp(math.Abs(v)) if schema > 0 { bounds := nativeHistogramBounds[schema] key = sort.SearchFloat64s(bounds, frac) + (exp-1)*len(bounds) } else { key = exp if frac == 0.5 { key-- } offset := (1 << -schema) - 1 key = (key + offset) >> -schema } if isInf { key++ } switch { case v > zeroThreshold: bucketCreated = addToBucket(&hc.nativeHistogramBucketsPositive, key, 1) case v < -zeroThreshold: bucketCreated = addToBucket(&hc.nativeHistogramBucketsNegative, key, 1) default: atomic.AddUint64(&hc.nativeHistogramZeroBucket, 1) } if bucketCreated { atomic.AddUint32(&hc.nativeHistogramBucketsNumber, 1) } } // Increment count last as we take it as a signal that the observation // is complete. atomic.AddUint64(&hc.count, 1) } type histogram struct { // countAndHotIdx enables lock-free writes with use of atomic updates. // The most significant bit is the hot index [0 or 1] of the count field // below. Observe calls update the hot one. All remaining bits count the // number of Observe calls. Observe starts by incrementing this counter, // and finish by incrementing the count field in the respective // histogramCounts, as a marker for completion. // // Calls of the Write method (which are non-mutating reads from the // perspective of the histogram) swap the hot–cold under the writeMtx // lock. A cooldown is awaited (while locked) by comparing the number of // observations with the initiation count. Once they match, then the // last observation on the now cool one has completed. All cold fields must // be merged into the new hot before releasing writeMtx. // // Fields with atomic access first! See alignment constraint: // http://golang.org/pkg/sync/atomic/#pkg-note-BUG countAndHotIdx uint64 selfCollector desc *Desc // Only used in the Write method and for sparse bucket management. mtx sync.Mutex // Two counts, one is "hot" for lock-free observations, the other is // "cold" for writing out a dto.Metric. It has to be an array of // pointers to guarantee 64bit alignment of the histogramCounts, see // http://golang.org/pkg/sync/atomic/#pkg-note-BUG. counts [2]*histogramCounts upperBounds []float64 labelPairs []*dto.LabelPair exemplars []atomic.Value // One more than buckets (to include +Inf), each a *dto.Exemplar. nativeHistogramSchema int32 // The initial schema. Set to math.MinInt32 if no sparse buckets are used. nativeHistogramZeroThreshold float64 // The initial zero threshold. nativeHistogramMaxZeroThreshold float64 nativeHistogramMaxBuckets uint32 nativeHistogramMinResetDuration time.Duration // lastResetTime is protected by mtx. It is also used as created timestamp. lastResetTime time.Time // resetScheduled is protected by mtx. It is true if a reset is // scheduled for a later time (when nativeHistogramMinResetDuration has // passed). resetScheduled bool nativeExemplars nativeExemplars // now is for testing purposes, by default it's time.Now. now func() time.Time // afterFunc is for testing purposes, by default it's time.AfterFunc. afterFunc func(time.Duration, func()) *time.Timer } func (h *histogram) Desc() *Desc { return h.desc } func (h *histogram) Observe(v float64) { h.observe(v, h.findBucket(v)) } // ObserveWithExemplar should not be called in a high-frequency setting // for a native histogram with configured exemplars. For this case, // the implementation isn't lock-free and might suffer from lock contention. func (h *histogram) ObserveWithExemplar(v float64, e Labels) { i := h.findBucket(v) h.observe(v, i) h.updateExemplar(v, i, e) } func (h *histogram) Write(out *dto.Metric) error { // For simplicity, we protect this whole method by a mutex. It is not in // the hot path, i.e. Observe is called much more often than Write. The // complication of making Write lock-free isn't worth it, if possible at // all. h.mtx.Lock() defer h.mtx.Unlock() // Adding 1<<63 switches the hot index (from 0 to 1 or from 1 to 0) // without touching the count bits. See the struct comments for a full // description of the algorithm. n := atomic.AddUint64(&h.countAndHotIdx, 1<<63) // count is contained unchanged in the lower 63 bits. count := n & ((1 << 63) - 1) // The most significant bit tells us which counts is hot. The complement // is thus the cold one. hotCounts := h.counts[n>>63] coldCounts := h.counts[(^n)>>63] waitForCooldown(count, coldCounts) his := &dto.Histogram{ Bucket: make([]*dto.Bucket, len(h.upperBounds)), SampleCount: proto.Uint64(count), SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))), CreatedTimestamp: timestamppb.New(h.lastResetTime), } out.Histogram = his out.Label = h.labelPairs var cumCount uint64 for i, upperBound := range h.upperBounds { cumCount += atomic.LoadUint64(&coldCounts.buckets[i]) his.Bucket[i] = &dto.Bucket{ CumulativeCount: proto.Uint64(cumCount), UpperBound: proto.Float64(upperBound), } if e := h.exemplars[i].Load(); e != nil { his.Bucket[i].Exemplar = e.(*dto.Exemplar) } } // If there is an exemplar for the +Inf bucket, we have to add that bucket explicitly. if e := h.exemplars[len(h.upperBounds)].Load(); e != nil { b := &dto.Bucket{ CumulativeCount: proto.Uint64(count), UpperBound: proto.Float64(math.Inf(1)), Exemplar: e.(*dto.Exemplar), } his.Bucket = append(his.Bucket, b) } if h.nativeHistogramSchema > math.MinInt32 { his.ZeroThreshold = proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.nativeHistogramZeroThresholdBits))) his.Schema = proto.Int32(atomic.LoadInt32(&coldCounts.nativeHistogramSchema)) zeroBucket := atomic.LoadUint64(&coldCounts.nativeHistogramZeroBucket) defer func() { coldCounts.nativeHistogramBucketsPositive.Range(addAndReset(&hotCounts.nativeHistogramBucketsPositive, &hotCounts.nativeHistogramBucketsNumber)) coldCounts.nativeHistogramBucketsNegative.Range(addAndReset(&hotCounts.nativeHistogramBucketsNegative, &hotCounts.nativeHistogramBucketsNumber)) }() his.ZeroCount = proto.Uint64(zeroBucket) his.NegativeSpan, his.NegativeDelta = makeBuckets(&coldCounts.nativeHistogramBucketsNegative) his.PositiveSpan, his.PositiveDelta = makeBuckets(&coldCounts.nativeHistogramBucketsPositive) // Add a no-op span to a histogram without observations and with // a zero threshold of zero. Otherwise, a native histogram would // look like a classic histogram to scrapers. if *his.ZeroThreshold == 0 && *his.ZeroCount == 0 && len(his.PositiveSpan) == 0 && len(his.NegativeSpan) == 0 { his.PositiveSpan = []*dto.BucketSpan{{ Offset: proto.Int32(0), Length: proto.Uint32(0), }} } if h.nativeExemplars.isEnabled() { h.nativeExemplars.Lock() his.Exemplars = append(his.Exemplars, h.nativeExemplars.exemplars...) h.nativeExemplars.Unlock() } } addAndResetCounts(hotCounts, coldCounts) return nil } // findBucket returns the index of the bucket for the provided value, or // len(h.upperBounds) for the +Inf bucket. func (h *histogram) findBucket(v float64) int { n := len(h.upperBounds) if n == 0 { return 0 } // Early exit: if v is less than or equal to the first upper bound, return 0 if v <= h.upperBounds[0] { return 0 } // Early exit: if v is greater than the last upper bound, return len(h.upperBounds) if v > h.upperBounds[n-1] { return n } // For small arrays, use simple linear search // "magic number" 35 is result of tests on couple different (AWS and baremetal) servers // see more details here: https://github.com/prometheus/client_golang/pull/1662 if n < 35 { for i, bound := range h.upperBounds { if v <= bound { return i } } // If v is greater than all upper bounds, return len(h.upperBounds) return n } // For larger arrays, use stdlib's binary search return sort.SearchFloat64s(h.upperBounds, v) } // observe is the implementation for Observe without the findBucket part. func (h *histogram) observe(v float64, bucket int) { // Do not add to sparse buckets for NaN observations. doSparse := h.nativeHistogramSchema > math.MinInt32 && !math.IsNaN(v) // We increment h.countAndHotIdx so that the counter in the lower // 63 bits gets incremented. At the same time, we get the new value // back, which we can use to find the currently-hot counts. n := atomic.AddUint64(&h.countAndHotIdx, 1) hotCounts := h.counts[n>>63] hotCounts.observe(v, bucket, doSparse) if doSparse { h.limitBuckets(hotCounts, v, bucket) } } // limitBuckets applies a strategy to limit the number of populated sparse // buckets. It's generally best effort, and there are situations where the // number can go higher (if even the lowest resolution isn't enough to reduce // the number sufficiently, or if the provided counts aren't fully updated yet // by a concurrently happening Write call). func (h *histogram) limitBuckets(counts *histogramCounts, value float64, bucket int) { if h.nativeHistogramMaxBuckets == 0 { return // No limit configured. } if h.nativeHistogramMaxBuckets >= atomic.LoadUint32(&counts.nativeHistogramBucketsNumber) { return // Bucket limit not exceeded yet. } h.mtx.Lock() defer h.mtx.Unlock() // The hot counts might have been swapped just before we acquired the // lock. Re-fetch the hot counts first... n := atomic.LoadUint64(&h.countAndHotIdx) hotIdx := n >> 63 coldIdx := (^n) >> 63 hotCounts := h.counts[hotIdx] coldCounts := h.counts[coldIdx] // ...and then check again if we really have to reduce the bucket count. if h.nativeHistogramMaxBuckets >= atomic.LoadUint32(&hotCounts.nativeHistogramBucketsNumber) { return // Bucket limit not exceeded after all. } // Try the various strategies in order. if h.maybeReset(hotCounts, coldCounts, coldIdx, value, bucket) { return } // One of the other strategies will happen. To undo what they will do as // soon as enough time has passed to satisfy // h.nativeHistogramMinResetDuration, schedule a reset at the right time // if we haven't done so already. if h.nativeHistogramMinResetDuration > 0 && !h.resetScheduled { h.resetScheduled = true h.afterFunc(h.nativeHistogramMinResetDuration-h.now().Sub(h.lastResetTime), h.reset) } if h.maybeWidenZeroBucket(hotCounts, coldCounts) { return } h.doubleBucketWidth(hotCounts, coldCounts) } // maybeReset resets the whole histogram if at least // h.nativeHistogramMinResetDuration has been passed. It returns true if the // histogram has been reset. The caller must have locked h.mtx. func (h *histogram) maybeReset( hot, cold *histogramCounts, coldIdx uint64, value float64, bucket int, ) bool { // We are using the possibly mocked h.now() rather than // time.Since(h.lastResetTime) to enable testing. if h.nativeHistogramMinResetDuration == 0 || // No reset configured. h.resetScheduled || // Do not interefere if a reset is already scheduled. h.now().Sub(h.lastResetTime) < h.nativeHistogramMinResetDuration { return false } // Completely reset coldCounts. h.resetCounts(cold) // Repeat the latest observation to not lose it completely. cold.observe(value, bucket, true) // Make coldCounts the new hot counts while resetting countAndHotIdx. n := atomic.SwapUint64(&h.countAndHotIdx, (coldIdx<<63)+1) count := n & ((1 << 63) - 1) waitForCooldown(count, hot) // Finally, reset the formerly hot counts, too. h.resetCounts(hot) h.lastResetTime = h.now() return true } // reset resets the whole histogram. It locks h.mtx itself, i.e. it has to be // called without having locked h.mtx. func (h *histogram) reset() { h.mtx.Lock() defer h.mtx.Unlock() n := atomic.LoadUint64(&h.countAndHotIdx) hotIdx := n >> 63 coldIdx := (^n) >> 63 hot := h.counts[hotIdx] cold := h.counts[coldIdx] // Completely reset coldCounts. h.resetCounts(cold) // Make coldCounts the new hot counts while resetting countAndHotIdx. n = atomic.SwapUint64(&h.countAndHotIdx, coldIdx<<63) count := n & ((1 << 63) - 1) waitForCooldown(count, hot) // Finally, reset the formerly hot counts, too. h.resetCounts(hot) h.lastResetTime = h.now() h.resetScheduled = false } // maybeWidenZeroBucket widens the zero bucket until it includes the existing // buckets closest to the zero bucket (which could be two, if an equidistant // negative and a positive bucket exists, but usually it's only one bucket to be // merged into the new wider zero bucket). h.nativeHistogramMaxZeroThreshold // limits how far the zero bucket can be extended, and if that's not enough to // include an existing bucket, the method returns false. The caller must have // locked h.mtx. func (h *histogram) maybeWidenZeroBucket(hot, cold *histogramCounts) bool { currentZeroThreshold := math.Float64frombits(atomic.LoadUint64(&hot.nativeHistogramZeroThresholdBits)) if currentZeroThreshold >= h.nativeHistogramMaxZeroThreshold { return false } // Find the key of the bucket closest to zero. smallestKey := findSmallestKey(&hot.nativeHistogramBucketsPositive) smallestNegativeKey := findSmallestKey(&hot.nativeHistogramBucketsNegative) if smallestNegativeKey < smallestKey { smallestKey = smallestNegativeKey } if smallestKey == math.MaxInt32 { return false } newZeroThreshold := getLe(smallestKey, atomic.LoadInt32(&hot.nativeHistogramSchema)) if newZeroThreshold > h.nativeHistogramMaxZeroThreshold { return false // New threshold would exceed the max threshold. } atomic.StoreUint64(&cold.nativeHistogramZeroThresholdBits, math.Float64bits(newZeroThreshold)) // Remove applicable buckets. if _, loaded := cold.nativeHistogramBucketsNegative.LoadAndDelete(smallestKey); loaded { atomicDecUint32(&cold.nativeHistogramBucketsNumber) } if _, loaded := cold.nativeHistogramBucketsPositive.LoadAndDelete(smallestKey); loaded { atomicDecUint32(&cold.nativeHistogramBucketsNumber) } // Make cold counts the new hot counts. n := atomic.AddUint64(&h.countAndHotIdx, 1<<63) count := n & ((1 << 63) - 1) // Swap the pointer names to represent the new roles and make // the rest less confusing. hot, cold = cold, hot waitForCooldown(count, cold) // Add all the now cold counts to the new hot counts... addAndResetCounts(hot, cold) // ...adjust the new zero threshold in the cold counts, too... atomic.StoreUint64(&cold.nativeHistogramZeroThresholdBits, math.Float64bits(newZeroThreshold)) // ...and then merge the newly deleted buckets into the wider zero // bucket. mergeAndDeleteOrAddAndReset := func(hotBuckets, coldBuckets *sync.Map) func(k, v interface{}) bool { return func(k, v interface{}) bool { key := k.(int) bucket := v.(*int64) if key == smallestKey { // Merge into hot zero bucket... atomic.AddUint64(&hot.nativeHistogramZeroBucket, uint64(atomic.LoadInt64(bucket))) // ...and delete from cold counts. coldBuckets.Delete(key) atomicDecUint32(&cold.nativeHistogramBucketsNumber) } else { // Add to corresponding hot bucket... if addToBucket(hotBuckets, key, atomic.LoadInt64(bucket)) { atomic.AddUint32(&hot.nativeHistogramBucketsNumber, 1) } // ...and reset cold bucket. atomic.StoreInt64(bucket, 0) } return true } } cold.nativeHistogramBucketsPositive.Range(mergeAndDeleteOrAddAndReset(&hot.nativeHistogramBucketsPositive, &cold.nativeHistogramBucketsPositive)) cold.nativeHistogramBucketsNegative.Range(mergeAndDeleteOrAddAndReset(&hot.nativeHistogramBucketsNegative, &cold.nativeHistogramBucketsNegative)) return true } // doubleBucketWidth doubles the bucket width (by decrementing the schema // number). Note that very sparse buckets could lead to a low reduction of the // bucket count (or even no reduction at all). The method does nothing if the // schema is already -4. func (h *histogram) doubleBucketWidth(hot, cold *histogramCounts) { coldSchema := atomic.LoadInt32(&cold.nativeHistogramSchema) if coldSchema == -4 { return // Already at lowest resolution. } coldSchema-- atomic.StoreInt32(&cold.nativeHistogramSchema, coldSchema) // Play it simple and just delete all cold buckets. atomic.StoreUint32(&cold.nativeHistogramBucketsNumber, 0) deleteSyncMap(&cold.nativeHistogramBucketsNegative) deleteSyncMap(&cold.nativeHistogramBucketsPositive) // Make coldCounts the new hot counts. n := atomic.AddUint64(&h.countAndHotIdx, 1<<63) count := n & ((1 << 63) - 1) // Swap the pointer names to represent the new roles and make // the rest less confusing. hot, cold = cold, hot waitForCooldown(count, cold) // Add all the now cold counts to the new hot counts... addAndResetCounts(hot, cold) // ...adjust the schema in the cold counts, too... atomic.StoreInt32(&cold.nativeHistogramSchema, coldSchema) // ...and then merge the cold buckets into the wider hot buckets. merge := func(hotBuckets *sync.Map) func(k, v interface{}) bool { return func(k, v interface{}) bool { key := k.(int) bucket := v.(*int64) // Adjust key to match the bucket to merge into. if key > 0 { key++ } key /= 2 // Add to corresponding hot bucket. if addToBucket(hotBuckets, key, atomic.LoadInt64(bucket)) { atomic.AddUint32(&hot.nativeHistogramBucketsNumber, 1) } return true } } cold.nativeHistogramBucketsPositive.Range(merge(&hot.nativeHistogramBucketsPositive)) cold.nativeHistogramBucketsNegative.Range(merge(&hot.nativeHistogramBucketsNegative)) // Play it simple again and just delete all cold buckets. atomic.StoreUint32(&cold.nativeHistogramBucketsNumber, 0) deleteSyncMap(&cold.nativeHistogramBucketsNegative) deleteSyncMap(&cold.nativeHistogramBucketsPositive) } func (h *histogram) resetCounts(counts *histogramCounts) { atomic.StoreUint64(&counts.sumBits, 0) atomic.StoreUint64(&counts.count, 0) atomic.StoreUint64(&counts.nativeHistogramZeroBucket, 0) atomic.StoreUint64(&counts.nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold)) atomic.StoreInt32(&counts.nativeHistogramSchema, h.nativeHistogramSchema) atomic.StoreUint32(&counts.nativeHistogramBucketsNumber, 0) for i := range h.upperBounds { atomic.StoreUint64(&counts.buckets[i], 0) } deleteSyncMap(&counts.nativeHistogramBucketsNegative) deleteSyncMap(&counts.nativeHistogramBucketsPositive) } // updateExemplar replaces the exemplar for the provided classic bucket. // With empty labels, it's a no-op. It panics if any of the labels is invalid. // If histogram is native, the exemplar will be cached into nativeExemplars, // which has a limit, and will remove one exemplar when limit is reached. func (h *histogram) updateExemplar(v float64, bucket int, l Labels) { if l == nil { return } e, err := newExemplar(v, h.now(), l) if err != nil { panic(err) } h.exemplars[bucket].Store(e) doSparse := h.nativeHistogramSchema > math.MinInt32 && !math.IsNaN(v) if doSparse { h.nativeExemplars.addExemplar(e) } } // HistogramVec is a Collector that bundles a set of Histograms that all share the // same Desc, but have different values for their variable labels. This is used // if you want to count the same thing partitioned by various dimensions // (e.g. HTTP request latencies, partitioned by status code and method). Create // instances with NewHistogramVec. type HistogramVec struct { *MetricVec } // NewHistogramVec creates a new HistogramVec based on the provided HistogramOpts and // partitioned by the given label names. func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec { return V2.NewHistogramVec(HistogramVecOpts{ HistogramOpts: opts, VariableLabels: UnconstrainedLabels(labelNames), }) } // NewHistogramVec creates a new HistogramVec based on the provided HistogramVecOpts. func (v2) NewHistogramVec(opts HistogramVecOpts) *HistogramVec { desc := V2.NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, opts.VariableLabels, opts.ConstLabels, ) return &HistogramVec{ MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { return newHistogram(desc, opts.HistogramOpts, lvs...) }), } } // GetMetricWithLabelValues returns the Histogram for the given slice of label // values (same order as the variable labels in Desc). If that combination of // label values is accessed for the first time, a new Histogram is created. // // It is possible to call this method without using the returned Histogram to only // create the new Histogram but leave it at its starting value, a Histogram without // any observations. // // Keeping the Histogram for later use is possible (and should be considered if // performance is critical), but keep in mind that Reset, DeleteLabelValues and // Delete can be used to delete the Histogram from the HistogramVec. In that case, the // Histogram will still exist, but it will not be exported anymore, even if a // Histogram with the same label values is created later. See also the CounterVec // example. // // An error is returned if the number of label values is not the same as the // number of variable labels in Desc (minus any curried labels). // // Note that for more than one label value, this method is prone to mistakes // caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as // an alternative to avoid that type of mistake. For higher label numbers, the // latter has a much more readable (albeit more verbose) syntax, but it comes // with a performance overhead (for creating and processing the Labels map). // See also the GaugeVec example. func (v *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) { metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...) if metric != nil { return metric.(Observer), err } return nil, err } // GetMetricWith returns the Histogram for the given Labels map (the label names // must match those of the variable labels in Desc). If that label map is // accessed for the first time, a new Histogram is created. Implications of // creating a Histogram without using it and keeping the Histogram for later use // are the same as for GetMetricWithLabelValues. // // An error is returned if the number and names of the Labels are inconsistent // with those of the variable labels in Desc (minus any curried labels). // // This method is used for the same purpose as // GetMetricWithLabelValues(...string). See there for pros and cons of the two // methods. func (v *HistogramVec) GetMetricWith(labels Labels) (Observer, error) { metric, err := v.MetricVec.GetMetricWith(labels) if metric != nil { return metric.(Observer), err } return nil, err } // WithLabelValues works as GetMetricWithLabelValues, but panics where // GetMetricWithLabelValues would have returned an error. Not returning an // error allows shortcuts like // // myVec.WithLabelValues("404", "GET").Observe(42.21) func (v *HistogramVec) WithLabelValues(lvs ...string) Observer { h, err := v.GetMetricWithLabelValues(lvs...) if err != nil { panic(err) } return h } // With works as GetMetricWith but panics where GetMetricWithLabels would have // returned an error. Not returning an error allows shortcuts like // // myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21) func (v *HistogramVec) With(labels Labels) Observer { h, err := v.GetMetricWith(labels) if err != nil { panic(err) } return h } // CurryWith returns a vector curried with the provided labels, i.e. the // returned vector has those labels pre-set for all labeled operations performed // on it. The cardinality of the curried vector is reduced accordingly. The // order of the remaining labels stays the same (just with the curried labels // taken out of the sequence – which is relevant for the // (GetMetric)WithLabelValues methods). It is possible to curry a curried // vector, but only with labels not yet used for currying before. // // The metrics contained in the HistogramVec are shared between the curried and // uncurried vectors. They are just accessed differently. Curried and uncurried // vectors behave identically in terms of collection. Only one must be // registered with a given registry (usually the uncurried version). The Reset // method deletes all metrics, even if called on a curried vector. func (v *HistogramVec) CurryWith(labels Labels) (ObserverVec, error) { vec, err := v.MetricVec.CurryWith(labels) if vec != nil { return &HistogramVec{vec}, err } return nil, err } // MustCurryWith works as CurryWith but panics where CurryWith would have // returned an error. func (v *HistogramVec) MustCurryWith(labels Labels) ObserverVec { vec, err := v.CurryWith(labels) if err != nil { panic(err) } return vec } type constHistogram struct { desc *Desc count uint64 sum float64 buckets map[float64]uint64 labelPairs []*dto.LabelPair createdTs *timestamppb.Timestamp } func (h *constHistogram) Desc() *Desc { return h.desc } func (h *constHistogram) Write(out *dto.Metric) error { his := &dto.Histogram{ CreatedTimestamp: h.createdTs, } buckets := make([]*dto.Bucket, 0, len(h.buckets)) his.SampleCount = proto.Uint64(h.count) his.SampleSum = proto.Float64(h.sum) for upperBound, count := range h.buckets { buckets = append(buckets, &dto.Bucket{ CumulativeCount: proto.Uint64(count), UpperBound: proto.Float64(upperBound), }) } if len(buckets) > 0 { sort.Sort(buckSort(buckets)) } his.Bucket = buckets out.Histogram = his out.Label = h.labelPairs return nil } // NewConstHistogram returns a metric representing a Prometheus histogram with // fixed values for the count, sum, and bucket counts. As those parameters // cannot be changed, the returned value does not implement the Histogram // interface (but only the Metric interface). Users of this package will not // have much use for it in regular operations. However, when implementing custom // Collectors, it is useful as a throw-away metric that is generated on the fly // to send it to Prometheus in the Collect method. // // buckets is a map of upper bounds to cumulative counts, excluding the +Inf // bucket. The +Inf bucket is implicit, and its value is equal to the provided count. // // NewConstHistogram returns an error if the length of labelValues is not // consistent with the variable labels in Desc or if Desc is invalid. func NewConstHistogram( desc *Desc, count uint64, sum float64, buckets map[float64]uint64, labelValues ...string, ) (Metric, error) { if desc.err != nil { return nil, desc.err } if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { return nil, err } return &constHistogram{ desc: desc, count: count, sum: sum, buckets: buckets, labelPairs: MakeLabelPairs(desc, labelValues), }, nil } // MustNewConstHistogram is a version of NewConstHistogram that panics where // NewConstHistogram would have returned an error. func MustNewConstHistogram( desc *Desc, count uint64, sum float64, buckets map[float64]uint64, labelValues ...string, ) Metric { m, err := NewConstHistogram(desc, count, sum, buckets, labelValues...) if err != nil { panic(err) } return m } // NewConstHistogramWithCreatedTimestamp does the same thing as NewConstHistogram but sets the created timestamp. func NewConstHistogramWithCreatedTimestamp( desc *Desc, count uint64, sum float64, buckets map[float64]uint64, ct time.Time, labelValues ...string, ) (Metric, error) { if desc.err != nil { return nil, desc.err } if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { return nil, err } return &constHistogram{ desc: desc, count: count, sum: sum, buckets: buckets, labelPairs: MakeLabelPairs(desc, labelValues), createdTs: timestamppb.New(ct), }, nil } // MustNewConstHistogramWithCreatedTimestamp is a version of NewConstHistogramWithCreatedTimestamp that panics where // NewConstHistogramWithCreatedTimestamp would have returned an error. func MustNewConstHistogramWithCreatedTimestamp( desc *Desc, count uint64, sum float64, buckets map[float64]uint64, ct time.Time, labelValues ...string, ) Metric { m, err := NewConstHistogramWithCreatedTimestamp(desc, count, sum, buckets, ct, labelValues...) if err != nil { panic(err) } return m } type buckSort []*dto.Bucket func (s buckSort) Len() int { return len(s) } func (s buckSort) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s buckSort) Less(i, j int) bool { return s[i].GetUpperBound() < s[j].GetUpperBound() } // pickSchema returns the largest number n between -4 and 8 such that // 2^(2^-n) is less or equal the provided bucketFactor. // // Special cases: // - bucketFactor <= 1: panics. // - bucketFactor < 2^(2^-8) (but > 1): still returns 8. func pickSchema(bucketFactor float64) int32 { if bucketFactor <= 1 { panic(fmt.Errorf("bucketFactor %f is <=1", bucketFactor)) } floor := math.Floor(math.Log2(math.Log2(bucketFactor))) switch { case floor <= -8: return nativeHistogramSchemaMaximum case floor >= 4: return nativeHistogramSchemaMinimum default: return -int32(floor) } } func makeBuckets(buckets *sync.Map) ([]*dto.BucketSpan, []int64) { var ii []int buckets.Range(func(k, v interface{}) bool { ii = append(ii, k.(int)) return true }) sort.Ints(ii) if len(ii) == 0 { return nil, nil } var ( spans []*dto.BucketSpan deltas []int64 prevCount int64 nextI int ) appendDelta := func(count int64) { *spans[len(spans)-1].Length++ deltas = append(deltas, count-prevCount) prevCount = count } for n, i := range ii { v, _ := buckets.Load(i) count := atomic.LoadInt64(v.(*int64)) // Multiple spans with only small gaps in between are probably // encoded more efficiently as one larger span with a few empty // buckets. Needs some research to find the sweet spot. For now, // we assume that gaps of one or two buckets should not create // a new span. iDelta := int32(i - nextI) if n == 0 || iDelta > 2 { // We have to create a new span, either because we are // at the very beginning, or because we have found a gap // of more than two buckets. spans = append(spans, &dto.BucketSpan{ Offset: proto.Int32(iDelta), Length: proto.Uint32(0), }) } else { // We have found a small gap (or no gap at all). // Insert empty buckets as needed. for j := int32(0); j < iDelta; j++ { appendDelta(0) } } appendDelta(count) nextI = i + 1 } return spans, deltas } // addToBucket increments the sparse bucket at key by the provided amount. It // returns true if a new sparse bucket had to be created for that. func addToBucket(buckets *sync.Map, key int, increment int64) bool { if existingBucket, ok := buckets.Load(key); ok { // Fast path without allocation. atomic.AddInt64(existingBucket.(*int64), increment) return false } // Bucket doesn't exist yet. Slow path allocating new counter. newBucket := increment // TODO(beorn7): Check if this is sufficient to not let increment escape. if actualBucket, loaded := buckets.LoadOrStore(key, &newBucket); loaded { // The bucket was created concurrently in another goroutine. // Have to increment after all. atomic.AddInt64(actualBucket.(*int64), increment) return false } return true } // addAndReset returns a function to be used with sync.Map.Range of spare // buckets in coldCounts. It increments the buckets in the provided hotBuckets // according to the buckets ranged through. It then resets all buckets ranged // through to 0 (but leaves them in place so that they don't need to get // recreated on the next scrape). func addAndReset(hotBuckets *sync.Map, bucketNumber *uint32) func(k, v interface{}) bool { return func(k, v interface{}) bool { bucket := v.(*int64) if addToBucket(hotBuckets, k.(int), atomic.LoadInt64(bucket)) { atomic.AddUint32(bucketNumber, 1) } atomic.StoreInt64(bucket, 0) return true } } func deleteSyncMap(m *sync.Map) { m.Range(func(k, v interface{}) bool { m.Delete(k) return true }) } func findSmallestKey(m *sync.Map) int { result := math.MaxInt32 m.Range(func(k, v interface{}) bool { key := k.(int) if key < result { result = key } return true }) return result } func getLe(key int, schema int32) float64 { // Here a bit of context about the behavior for the last bucket counting // regular numbers (called simply "last bucket" below) and the bucket // counting observations of Β±Inf (called "inf bucket" below, with a key // one higher than that of the "last bucket"): // // If we apply the usual formula to the last bucket, its upper bound // would be calculated as +Inf. The reason is that the max possible // regular float64 number (math.MaxFloat64) doesn't coincide with one of // the calculated bucket boundaries. So the calculated boundary has to // be larger than math.MaxFloat64, and the only float64 larger than // math.MaxFloat64 is +Inf. However, we want to count actual // observations of Β±Inf in the inf bucket. Therefore, we have to treat // the upper bound of the last bucket specially and set it to // math.MaxFloat64. (The upper bound of the inf bucket, with its key // being one higher than that of the last bucket, naturally comes out as // +Inf by the usual formula. So that's fine.) // // math.MaxFloat64 has a frac of 0.9999999999999999 and an exp of // 1024. If there were a float64 number following math.MaxFloat64, it // would have a frac of 1.0 and an exp of 1024, or equivalently a frac // of 0.5 and an exp of 1025. However, since frac must be smaller than // 1, and exp must be smaller than 1025, either representation overflows // a float64. (Which, in turn, is the reason that math.MaxFloat64 is the // largest possible float64. Q.E.D.) However, the formula for // calculating the upper bound from the idx and schema of the last // bucket results in precisely that. It is either frac=1.0 & exp=1024 // (for schema < 0) or frac=0.5 & exp=1025 (for schema >=0). (This is, // by the way, a power of two where the exponent itself is a power of // two, 2¹⁰ in fact, which coinicides with a bucket boundary in all // schemas.) So these are the special cases we have to catch below. if schema < 0 { exp := key << -schema if exp == 1024 { // This is the last bucket before the overflow bucket // (for Β±Inf observations). Return math.MaxFloat64 as // explained above. return math.MaxFloat64 } return math.Ldexp(1, exp) } fracIdx := key & ((1 << schema) - 1) frac := nativeHistogramBounds[schema][fracIdx] exp := (key >> schema) + 1 if frac == 0.5 && exp == 1025 { // This is the last bucket before the overflow bucket (for Β±Inf // observations). Return math.MaxFloat64 as explained above. return math.MaxFloat64 } return math.Ldexp(frac, exp) } // waitForCooldown returns after the count field in the provided histogramCounts // has reached the provided count value. func waitForCooldown(count uint64, counts *histogramCounts) { for count != atomic.LoadUint64(&counts.count) { runtime.Gosched() // Let observations get work done. } } // atomicAddFloat adds the provided float atomically to another float // represented by the bit pattern the bits pointer is pointing to. func atomicAddFloat(bits *uint64, v float64) { for { loadedBits := atomic.LoadUint64(bits) newBits := math.Float64bits(math.Float64frombits(loadedBits) + v) if atomic.CompareAndSwapUint64(bits, loadedBits, newBits) { break } } } // atomicDecUint32 atomically decrements the uint32 p points to. See // https://pkg.go.dev/sync/atomic#AddUint32 to understand how this is done. func atomicDecUint32(p *uint32) { atomic.AddUint32(p, ^uint32(0)) } // addAndResetCounts adds certain fields (count, sum, conventional buckets, zero // bucket) from the cold counts to the corresponding fields in the hot // counts. Those fields are then reset to 0 in the cold counts. func addAndResetCounts(hot, cold *histogramCounts) { atomic.AddUint64(&hot.count, atomic.LoadUint64(&cold.count)) atomic.StoreUint64(&cold.count, 0) coldSum := math.Float64frombits(atomic.LoadUint64(&cold.sumBits)) atomicAddFloat(&hot.sumBits, coldSum) atomic.StoreUint64(&cold.sumBits, 0) for i := range hot.buckets { atomic.AddUint64(&hot.buckets[i], atomic.LoadUint64(&cold.buckets[i])) atomic.StoreUint64(&cold.buckets[i], 0) } atomic.AddUint64(&hot.nativeHistogramZeroBucket, atomic.LoadUint64(&cold.nativeHistogramZeroBucket)) atomic.StoreUint64(&cold.nativeHistogramZeroBucket, 0) } type nativeExemplars struct { sync.Mutex // Time-to-live for exemplars, it is set to -1 if exemplars are disabled, that is NativeHistogramMaxExemplars is below 0. // The ttl is used on insertion to remove an exemplar that is older than ttl, if present. ttl time.Duration exemplars []*dto.Exemplar } func (n *nativeExemplars) isEnabled() bool { return n.ttl != -1 } func makeNativeExemplars(ttl time.Duration, maxCount int) nativeExemplars { if ttl == 0 { ttl = 5 * time.Minute } if maxCount == 0 { maxCount = 10 } if maxCount < 0 { maxCount = 0 ttl = -1 } return nativeExemplars{ ttl: ttl, exemplars: make([]*dto.Exemplar, 0, maxCount), } } func (n *nativeExemplars) addExemplar(e *dto.Exemplar) { if !n.isEnabled() { return } n.Lock() defer n.Unlock() // When the number of exemplars has not yet exceeded or // is equal to cap(n.exemplars), then // insert the new exemplar directly. if len(n.exemplars) < cap(n.exemplars) { var nIdx int for nIdx = 0; nIdx < len(n.exemplars); nIdx++ { if *e.Value < *n.exemplars[nIdx].Value { break } } n.exemplars = append(n.exemplars[:nIdx], append([]*dto.Exemplar{e}, n.exemplars[nIdx:]...)...) return } if len(n.exemplars) == 1 { // When the number of exemplars is 1, then // replace the existing exemplar with the new exemplar. n.exemplars[0] = e return } // From this point on, the number of exemplars is greater than 1. // When the number of exemplars exceeds the limit, remove one exemplar. var ( ot = time.Time{} // Oldest timestamp seen. Initial value doesn't matter as we replace it due to otIdx == -1 in the loop. otIdx = -1 // Index of the exemplar with the oldest timestamp. md = -1.0 // Logarithm of the delta of the closest pair of exemplars. // The insertion point of the new exemplar in the exemplars slice after insertion. // This is calculated purely based on the order of the exemplars by value. // nIdx == len(n.exemplars) means the new exemplar is to be inserted after the end. nIdx = -1 // rIdx is ultimately the index for the exemplar that we are replacing with the new exemplar. // The aim is to keep a good spread of exemplars by value and not let them bunch up too much. // It is calculated in 3 steps: // 1. First we set rIdx to the index of the older exemplar within the closest pair by value. // That is the following will be true (on log scale): // either the exemplar pair on index (rIdx-1, rIdx) or (rIdx, rIdx+1) will have // the closest values to each other from all pairs. // For example, suppose the values are distributed like this: // |-----------x-------------x----------------x----x-----| // ^--rIdx as this is older. // Or like this: // |-----------x-------------x----------------x----x-----| // ^--rIdx as this is older. // 2. If there is an exemplar that expired, then we simple reset rIdx to that index. // 3. We check if by inserting the new exemplar we would create a closer pair at // (nIdx-1, nIdx) or (nIdx, nIdx+1) and set rIdx to nIdx-1 or nIdx accordingly to // keep the spread of exemplars by value; otherwise we keep rIdx as it is. rIdx = -1 cLog float64 // Logarithm of the current exemplar. pLog float64 // Logarithm of the previous exemplar. ) for i, exemplar := range n.exemplars { // Find the exemplar with the oldest timestamp. if otIdx == -1 || exemplar.Timestamp.AsTime().Before(ot) { ot = exemplar.Timestamp.AsTime() otIdx = i } // Find the index at which to insert new the exemplar. if nIdx == -1 && *e.Value <= *exemplar.Value { nIdx = i } // Find the two closest exemplars and pick the one the with older timestamp. pLog = cLog cLog = math.Log(exemplar.GetValue()) if i == 0 { continue } diff := math.Abs(cLog - pLog) if md == -1 || diff < md { // The closest exemplar pair is at index: i-1, i. // Choose the exemplar with the older timestamp for replacement. md = diff if n.exemplars[i].Timestamp.AsTime().Before(n.exemplars[i-1].Timestamp.AsTime()) { rIdx = i } else { rIdx = i - 1 } } } // If all existing exemplar are smaller than new exemplar, // then the exemplar should be inserted at the end. if nIdx == -1 { nIdx = len(n.exemplars) } // Here, we have the following relationships: // n.exemplars[nIdx-1].Value < e.Value (if nIdx > 0) // e.Value <= n.exemplars[nIdx].Value (if nIdx < len(n.exemplars)) if otIdx != -1 && e.Timestamp.AsTime().Sub(ot) > n.ttl { // If the oldest exemplar has expired, then replace it with the new exemplar. rIdx = otIdx } else { // In the previous for loop, when calculating the closest pair of exemplars, // we did not take into account the newly inserted exemplar. // So we need to calculate with the newly inserted exemplar again. elog := math.Log(e.GetValue()) if nIdx > 0 { diff := math.Abs(elog - math.Log(n.exemplars[nIdx-1].GetValue())) if diff < md { // The value we are about to insert is closer to the previous exemplar at the insertion point than what we calculated before in rIdx. // v--rIdx // |-----------x-n-----------x----------------x----x-----| // nIdx-1--^ ^--new exemplar value // Do not make the spread worse, replace nIdx-1 and not rIdx. md = diff rIdx = nIdx - 1 } } if nIdx < len(n.exemplars) { diff := math.Abs(math.Log(n.exemplars[nIdx].GetValue()) - elog) if diff < md { // The value we are about to insert is closer to the next exemplar at the insertion point than what we calculated before in rIdx. // v--rIdx // |-----------x-----------n-x----------------x----x-----| // new exemplar value--^ ^--nIdx // Do not make the spread worse, replace nIdx-1 and not rIdx. rIdx = nIdx } } } // Adjust the slice according to rIdx and nIdx. switch { case rIdx == nIdx: n.exemplars[nIdx] = e case rIdx < nIdx: n.exemplars = append(n.exemplars[:rIdx], append(n.exemplars[rIdx+1:nIdx], append([]*dto.Exemplar{e}, n.exemplars[nIdx:]...)...)...) case rIdx > nIdx: n.exemplars = append(n.exemplars[:nIdx], append([]*dto.Exemplar{e}, append(n.exemplars[nIdx:rIdx], n.exemplars[rIdx+1:]...)...)...) } } type constNativeHistogram struct { desc *Desc dto.Histogram labelPairs []*dto.LabelPair } func validateCount(sum float64, count uint64, negativeBuckets, positiveBuckets map[int]int64, zeroBucket uint64) error { var bucketPopulationSum int64 for _, v := range positiveBuckets { bucketPopulationSum += v } for _, v := range negativeBuckets { bucketPopulationSum += v } bucketPopulationSum += int64(zeroBucket) // If the sum of observations is NaN, the number of observations must be greater or equal to the sum of all bucket counts. // Otherwise, the number of observations must be equal to the sum of all bucket counts . if math.IsNaN(sum) && bucketPopulationSum > int64(count) || !math.IsNaN(sum) && bucketPopulationSum != int64(count) { return errors.New("the sum of all bucket populations exceeds the count of observations") } return nil } // NewConstNativeHistogram returns a metric representing a Prometheus native histogram with // fixed values for the count, sum, and positive/negative/zero bucket counts. As those parameters // cannot be changed, the returned value does not implement the Histogram // interface (but only the Metric interface). Users of this package will not // have much use for it in regular operations. However, when implementing custom // OpenTelemetry Collectors, it is useful as a throw-away metric that is generated on the fly // to send it to Prometheus in the Collect method. // // zeroBucket counts all (positive and negative) // observations in the zero bucket (with an absolute value less or equal // the current threshold). // positiveBuckets and negativeBuckets are separate maps for negative and positive // observations. The map's value is an int64, counting observations in // that bucket. The map's key is the // index of the bucket according to the used // Schema. Index 0 is for an upper bound of 1 in positive buckets and for a lower bound of -1 in negative buckets. // NewConstNativeHistogram returns an error if // - the length of labelValues is not consistent with the variable labels in Desc or if Desc is invalid. // - the schema passed is not between 8 and -4 // - the sum of counts in all buckets including the zero bucket does not equal the count if sum is not NaN (or exceeds the count if sum is NaN) // // See https://opentelemetry.io/docs/specs/otel/compatibility/prometheus_and_openmetrics/#exponential-histograms for more details about the conversion from OTel to Prometheus. func NewConstNativeHistogram( desc *Desc, count uint64, sum float64, positiveBuckets, negativeBuckets map[int]int64, zeroBucket uint64, schema int32, zeroThreshold float64, createdTimestamp time.Time, labelValues ...string, ) (Metric, error) { if desc.err != nil { return nil, desc.err } if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { return nil, err } if schema > nativeHistogramSchemaMaximum || schema < nativeHistogramSchemaMinimum { return nil, errors.New("invalid native histogram schema") } if err := validateCount(sum, count, negativeBuckets, positiveBuckets, zeroBucket); err != nil { return nil, err } NegativeSpan, NegativeDelta := makeBucketsFromMap(negativeBuckets) PositiveSpan, PositiveDelta := makeBucketsFromMap(positiveBuckets) ret := &constNativeHistogram{ desc: desc, Histogram: dto.Histogram{ CreatedTimestamp: timestamppb.New(createdTimestamp), Schema: &schema, ZeroThreshold: &zeroThreshold, SampleCount: &count, SampleSum: &sum, NegativeSpan: NegativeSpan, NegativeDelta: NegativeDelta, PositiveSpan: PositiveSpan, PositiveDelta: PositiveDelta, ZeroCount: proto.Uint64(zeroBucket), }, labelPairs: MakeLabelPairs(desc, labelValues), } if *ret.ZeroThreshold == 0 && *ret.ZeroCount == 0 && len(ret.PositiveSpan) == 0 && len(ret.NegativeSpan) == 0 { ret.PositiveSpan = []*dto.BucketSpan{{ Offset: proto.Int32(0), Length: proto.Uint32(0), }} } return ret, nil } // MustNewConstNativeHistogram is a version of NewConstNativeHistogram that panics where // NewConstNativeHistogram would have returned an error. func MustNewConstNativeHistogram( desc *Desc, count uint64, sum float64, positiveBuckets, negativeBuckets map[int]int64, zeroBucket uint64, nativeHistogramSchema int32, nativeHistogramZeroThreshold float64, createdTimestamp time.Time, labelValues ...string, ) Metric { nativehistogram, err := NewConstNativeHistogram(desc, count, sum, positiveBuckets, negativeBuckets, zeroBucket, nativeHistogramSchema, nativeHistogramZeroThreshold, createdTimestamp, labelValues...) if err != nil { panic(err) } return nativehistogram } func (h *constNativeHistogram) Desc() *Desc { return h.desc } func (h *constNativeHistogram) Write(out *dto.Metric) error { out.Histogram = &h.Histogram out.Label = h.labelPairs return nil } func makeBucketsFromMap(buckets map[int]int64) ([]*dto.BucketSpan, []int64) { if len(buckets) == 0 { return nil, nil } var ii []int for k := range buckets { ii = append(ii, k) } sort.Ints(ii) var ( spans []*dto.BucketSpan deltas []int64 prevCount int64 nextI int ) appendDelta := func(count int64) { *spans[len(spans)-1].Length++ deltas = append(deltas, count-prevCount) prevCount = count } for n, i := range ii { count := buckets[i] // Multiple spans with only small gaps in between are probably // encoded more efficiently as one larger span with a few empty // buckets. Needs some research to find the sweet spot. For now, // we assume that gaps of one or two buckets should not create // a new span. iDelta := int32(i - nextI) if n == 0 || iDelta > 2 { // We have to create a new span, either because we are // at the very beginning, or because we have found a gap // of more than two buckets. spans = append(spans, &dto.BucketSpan{ Offset: proto.Int32(iDelta), Length: proto.Uint32(0), }) } else { // We have found a small gap (or no gap at all). // Insert empty buckets as needed. for j := int32(0); j < iDelta; j++ { appendDelta(0) } } appendDelta(count) nextI = i + 1 } return spans, deltas } client_golang-1.21.1/prometheus/histogram_test.go000066400000000000000000001662141476160432400222000ustar00rootroot00000000000000// Copyright 2015 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "math" "math/rand" "reflect" "runtime" "sort" "sync" "sync/atomic" "testing" "testing/quick" "time" dto "github.com/prometheus/client_model/go" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" "github.com/prometheus/client_golang/prometheus/internal" ) func benchmarkHistogramObserve(w int, b *testing.B) { b.StopTimer() wg := new(sync.WaitGroup) wg.Add(w) g := new(sync.WaitGroup) g.Add(1) s := NewHistogram(HistogramOpts{}) for i := 0; i < w; i++ { go func() { g.Wait() for i := 0; i < b.N; i++ { s.Observe(float64(i)) } wg.Done() }() } b.StartTimer() g.Done() wg.Wait() } func BenchmarkHistogramObserve1(b *testing.B) { benchmarkHistogramObserve(1, b) } func BenchmarkHistogramObserve2(b *testing.B) { benchmarkHistogramObserve(2, b) } func BenchmarkHistogramObserve4(b *testing.B) { benchmarkHistogramObserve(4, b) } func BenchmarkHistogramObserve8(b *testing.B) { benchmarkHistogramObserve(8, b) } func benchmarkHistogramWrite(w int, b *testing.B) { b.StopTimer() wg := new(sync.WaitGroup) wg.Add(w) g := new(sync.WaitGroup) g.Add(1) s := NewHistogram(HistogramOpts{}) for i := 0; i < 1000000; i++ { s.Observe(float64(i)) } for j := 0; j < w; j++ { outs := make([]dto.Metric, b.N) go func(o []dto.Metric) { g.Wait() for i := 0; i < b.N; i++ { s.Write(&o[i]) } wg.Done() }(outs) } b.StartTimer() g.Done() wg.Wait() } func BenchmarkHistogramWrite1(b *testing.B) { benchmarkHistogramWrite(1, b) } func BenchmarkHistogramWrite2(b *testing.B) { benchmarkHistogramWrite(2, b) } func BenchmarkHistogramWrite4(b *testing.B) { benchmarkHistogramWrite(4, b) } func BenchmarkHistogramWrite8(b *testing.B) { benchmarkHistogramWrite(8, b) } func TestHistogramNonMonotonicBuckets(t *testing.T) { testCases := map[string][]float64{ "not strictly monotonic": {1, 2, 2, 3}, "not monotonic at all": {1, 2, 4, 3, 5}, "have +Inf in the middle": {1, 2, math.Inf(+1), 3}, } for name, buckets := range testCases { func() { defer func() { if r := recover(); r == nil { t.Errorf("Buckets %v are %s but NewHistogram did not panic.", buckets, name) } }() _ = NewHistogram(HistogramOpts{ Name: "test_histogram", Help: "helpless", Buckets: buckets, }) }() } } // Intentionally adding +Inf here to test if that case is handled correctly. // Also, getCumulativeCounts depends on it. var testBuckets = []float64{-2, -1, -0.5, 0, 0.5, 1, 2, math.Inf(+1)} func TestHistogramConcurrency(t *testing.T) { if testing.Short() { t.Skip("Skipping test in short mode.") } rand.New(rand.NewSource(42)) it := func(n uint32) bool { mutations := int(n%1e4 + 1e4) concLevel := int(n%5 + 1) total := mutations * concLevel var start, end sync.WaitGroup start.Add(1) end.Add(concLevel) his := NewHistogram(HistogramOpts{ Name: "test_histogram", Help: "helpless", Buckets: testBuckets, }) allVars := make([]float64, total) var sampleSum float64 for i := 0; i < concLevel; i++ { vals := make([]float64, mutations) for j := 0; j < mutations; j++ { v := rand.NormFloat64() vals[j] = v allVars[i*mutations+j] = v sampleSum += v } go func(vals []float64) { start.Wait() for _, v := range vals { if n%2 == 0 { his.Observe(v) } else { his.(ExemplarObserver).ObserveWithExemplar(v, Labels{"foo": "bar"}) } } end.Done() }(vals) } sort.Float64s(allVars) start.Done() end.Wait() m := &dto.Metric{} his.Write(m) if got, want := int(*m.Histogram.SampleCount), total; got != want { t.Errorf("got sample count %d, want %d", got, want) } if got, want := *m.Histogram.SampleSum, sampleSum; math.Abs((got-want)/want) > 0.001 { t.Errorf("got sample sum %f, want %f", got, want) } wantCounts := getCumulativeCounts(allVars) wantBuckets := len(testBuckets) if !math.IsInf(m.Histogram.Bucket[len(m.Histogram.Bucket)-1].GetUpperBound(), +1) { wantBuckets-- } if got := len(m.Histogram.Bucket); got != wantBuckets { t.Errorf("got %d buckets in protobuf, want %d", got, wantBuckets) } for i, wantBound := range testBuckets { if i == len(testBuckets)-1 { break // No +Inf bucket in protobuf. } if gotBound := *m.Histogram.Bucket[i].UpperBound; gotBound != wantBound { t.Errorf("got bound %f, want %f", gotBound, wantBound) } if gotCount, wantCount := *m.Histogram.Bucket[i].CumulativeCount, wantCounts[i]; gotCount != wantCount { t.Errorf("got count %d, want %d", gotCount, wantCount) } } return true } if err := quick.Check(it, nil); err != nil { t.Error(err) } } func TestHistogramVecConcurrency(t *testing.T) { if testing.Short() { t.Skip("Skipping test in short mode.") } rand.New(rand.NewSource(42)) it := func(n uint32) bool { mutations := int(n%1e4 + 1e4) concLevel := int(n%7 + 1) vecLength := int(n%3 + 1) var start, end sync.WaitGroup start.Add(1) end.Add(concLevel) his := NewHistogramVec( HistogramOpts{ Name: "test_histogram", Help: "helpless", Buckets: []float64{-2, -1, -0.5, 0, 0.5, 1, 2, math.Inf(+1)}, }, []string{"label"}, ) allVars := make([][]float64, vecLength) sampleSums := make([]float64, vecLength) for i := 0; i < concLevel; i++ { vals := make([]float64, mutations) picks := make([]int, mutations) for j := 0; j < mutations; j++ { v := rand.NormFloat64() vals[j] = v pick := rand.Intn(vecLength) picks[j] = pick allVars[pick] = append(allVars[pick], v) sampleSums[pick] += v } go func(vals []float64) { start.Wait() for i, v := range vals { his.WithLabelValues(string('A' + rune(picks[i]))).Observe(v) } end.Done() }(vals) } for _, vars := range allVars { sort.Float64s(vars) } start.Done() end.Wait() for i := 0; i < vecLength; i++ { m := &dto.Metric{} s := his.WithLabelValues(string('A' + rune(i))) s.(Histogram).Write(m) if got, want := len(m.Histogram.Bucket), len(testBuckets)-1; got != want { t.Errorf("got %d buckets in protobuf, want %d", got, want) } if got, want := int(*m.Histogram.SampleCount), len(allVars[i]); got != want { t.Errorf("got sample count %d, want %d", got, want) } if got, want := *m.Histogram.SampleSum, sampleSums[i]; math.Abs((got-want)/want) > 0.001 { t.Errorf("got sample sum %f, want %f", got, want) } wantCounts := getCumulativeCounts(allVars[i]) for j, wantBound := range testBuckets { if j == len(testBuckets)-1 { break // No +Inf bucket in protobuf. } if gotBound := *m.Histogram.Bucket[j].UpperBound; gotBound != wantBound { t.Errorf("got bound %f, want %f", gotBound, wantBound) } if gotCount, wantCount := *m.Histogram.Bucket[j].CumulativeCount, wantCounts[j]; gotCount != wantCount { t.Errorf("got count %d, want %d", gotCount, wantCount) } } } return true } if err := quick.Check(it, nil); err != nil { t.Error(err) } } func getCumulativeCounts(vars []float64) []uint64 { counts := make([]uint64, len(testBuckets)) for _, v := range vars { for i := len(testBuckets) - 1; i >= 0; i-- { if v > testBuckets[i] { break } counts[i]++ } } return counts } func TestBuckets(t *testing.T) { got := LinearBuckets(-15, 5, 6) want := []float64{-15, -10, -5, 0, 5, 10} if !reflect.DeepEqual(got, want) { t.Errorf("linear buckets: got %v, want %v", got, want) } got = ExponentialBuckets(100, 1.2, 3) want = []float64{100, 120, 144} if !reflect.DeepEqual(got, want) { t.Errorf("exponential buckets: got %v, want %v", got, want) } got = ExponentialBucketsRange(1, 100, 10) want = []float64{ 1.0, 1.6681, 2.7825, 4.6415, 7.7426, 12.9154, 21.5443, 35.9381, 59.9484, 100.0000, } const epsilon = 0.0001 if !internal.AlmostEqualFloat64s(got, want, epsilon) { t.Errorf("exponential buckets range: got %v, want %v (epsilon %f)", got, want, epsilon) } } func TestHistogramAtomicObserve(t *testing.T) { var ( quit = make(chan struct{}) his = NewHistogram(HistogramOpts{ Buckets: []float64{0.5, 10, 20}, }) ) defer func() { close(quit) }() observe := func() { for { select { case <-quit: return default: his.Observe(1) time.Sleep(time.Nanosecond) } } } go observe() go observe() go observe() for i := 0; i < 100; i++ { m := &dto.Metric{} if err := his.Write(m); err != nil { t.Fatal("unexpected error writing histogram:", err) } h := m.GetHistogram() if h.GetSampleCount() != uint64(h.GetSampleSum()) || h.GetSampleCount() != h.GetBucket()[1].GetCumulativeCount() || h.GetSampleCount() != h.GetBucket()[2].GetCumulativeCount() { t.Fatalf( "inconsistent counts in histogram: count=%d sum=%f buckets=[%d, %d]", h.GetSampleCount(), h.GetSampleSum(), h.GetBucket()[1].GetCumulativeCount(), h.GetBucket()[2].GetCumulativeCount(), ) } runtime.Gosched() } } func TestHistogramExemplar(t *testing.T) { now := time.Now() histogram := NewHistogram(HistogramOpts{ Name: "test", Help: "test help", Buckets: []float64{1, 2, 3, 4}, now: func() time.Time { return now }, }).(*histogram) ts := timestamppb.New(now) if err := ts.CheckValid(); err != nil { t.Fatal(err) } expectedExemplars := []*dto.Exemplar{ nil, { Label: []*dto.LabelPair{ {Name: proto.String("id"), Value: proto.String("2")}, }, Value: proto.Float64(1.6), Timestamp: ts, }, nil, { Label: []*dto.LabelPair{ {Name: proto.String("id"), Value: proto.String("3")}, }, Value: proto.Float64(4), Timestamp: ts, }, { Label: []*dto.LabelPair{ {Name: proto.String("id"), Value: proto.String("4")}, }, Value: proto.Float64(4.5), Timestamp: ts, }, } histogram.ObserveWithExemplar(1.5, Labels{"id": "1"}) histogram.ObserveWithExemplar(1.6, Labels{"id": "2"}) // To replace exemplar in bucket 0. histogram.ObserveWithExemplar(4, Labels{"id": "3"}) histogram.ObserveWithExemplar(4.5, Labels{"id": "4"}) // Should go to +Inf bucket. for i, ex := range histogram.exemplars { var got, expected string if val := ex.Load(); val != nil { got = val.(*dto.Exemplar).String() } if expectedExemplars[i] != nil { expected = expectedExemplars[i].String() } if got != expected { t.Errorf("expected exemplar %s, got %s.", expected, got) } } } func TestNativeHistogram(t *testing.T) { now := time.Now() scenarios := []struct { name string observations []float64 // With simulated interval of 1m. factor float64 zeroThreshold float64 maxBuckets uint32 minResetDuration time.Duration maxZeroThreshold float64 want *dto.Histogram }{ { name: "no sparse buckets", observations: []float64{1, 2, 3}, factor: 1, want: &dto.Histogram{ SampleCount: proto.Uint64(3), SampleSum: proto.Float64(6), Bucket: []*dto.Bucket{ {CumulativeCount: proto.Uint64(0), UpperBound: proto.Float64(0.005)}, {CumulativeCount: proto.Uint64(0), UpperBound: proto.Float64(0.01)}, {CumulativeCount: proto.Uint64(0), UpperBound: proto.Float64(0.025)}, {CumulativeCount: proto.Uint64(0), UpperBound: proto.Float64(0.05)}, {CumulativeCount: proto.Uint64(0), UpperBound: proto.Float64(0.1)}, {CumulativeCount: proto.Uint64(0), UpperBound: proto.Float64(0.25)}, {CumulativeCount: proto.Uint64(0), UpperBound: proto.Float64(0.5)}, {CumulativeCount: proto.Uint64(1), UpperBound: proto.Float64(1)}, {CumulativeCount: proto.Uint64(2), UpperBound: proto.Float64(2.5)}, {CumulativeCount: proto.Uint64(3), UpperBound: proto.Float64(5)}, {CumulativeCount: proto.Uint64(3), UpperBound: proto.Float64(10)}, }, CreatedTimestamp: timestamppb.New(now), }, }, { name: "no observations", factor: 1.1, want: &dto.Histogram{ SampleCount: proto.Uint64(0), SampleSum: proto.Float64(0), Schema: proto.Int32(3), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(0), CreatedTimestamp: timestamppb.New(now), }, }, { name: "no observations and zero threshold of zero resulting in no-op span", factor: 1.1, zeroThreshold: NativeHistogramZeroThresholdZero, want: &dto.Histogram{ SampleCount: proto.Uint64(0), SampleSum: proto.Float64(0), Schema: proto.Int32(3), ZeroThreshold: proto.Float64(0), ZeroCount: proto.Uint64(0), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(0)}, }, CreatedTimestamp: timestamppb.New(now), }, }, { name: "factor 1.1 results in schema 3", observations: []float64{0, 1, 2, 3}, factor: 1.1, want: &dto.Histogram{ SampleCount: proto.Uint64(4), SampleSum: proto.Float64(6), Schema: proto.Int32(3), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(1)}, {Offset: proto.Int32(7), Length: proto.Uint32(1)}, {Offset: proto.Int32(4), Length: proto.Uint32(1)}, }, PositiveDelta: []int64{1, 0, 0}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "factor 1.2 results in schema 2", observations: []float64{0, 1, 1.2, 1.4, 1.8, 2}, factor: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(6), SampleSum: proto.Float64(7.4), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, PositiveDelta: []int64{1, -1, 2, -2, 2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "factor 4 results in schema -1", observations: []float64{ 0.0156251, 0.0625, // Bucket -2: (0.015625, 0.0625) 0.1, 0.25, // Bucket -1: (0.0625, 0.25] 0.5, 1, // Bucket 0: (0.25, 1] 1.5, 2, 3, 3.5, // Bucket 1: (1, 4] 5, 6, 7, // Bucket 2: (4, 16] 33.33, // Bucket 3: (16, 64] }, factor: 4, want: &dto.Histogram{ SampleCount: proto.Uint64(14), SampleSum: proto.Float64(63.2581251), Schema: proto.Int32(-1), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(0), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(-2), Length: proto.Uint32(6)}, }, PositiveDelta: []int64{2, 0, 0, 2, -1, -2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "factor 17 results in schema -2", observations: []float64{ 0.0156251, 0.0625, // Bucket -1: (0.015625, 0.0625] 0.1, 0.25, 0.5, 1, // Bucket 0: (0.0625, 1] 1.5, 2, 3, 3.5, 5, 6, 7, // Bucket 1: (1, 16] 33.33, // Bucket 2: (16, 256] }, factor: 17, want: &dto.Histogram{ SampleCount: proto.Uint64(14), SampleSum: proto.Float64(63.2581251), Schema: proto.Int32(-2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(0), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(-1), Length: proto.Uint32(4)}, }, PositiveDelta: []int64{2, 2, 3, -6}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "negative buckets", observations: []float64{0, -1, -1.2, -1.4, -1.8, -2}, factor: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(6), SampleSum: proto.Float64(-7.4), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, NegativeDelta: []int64{1, -1, 2, -2, 2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "negative and positive buckets", observations: []float64{0, -1, -1.2, -1.4, -1.8, -2, 1, 1.2, 1.4, 1.8, 2}, factor: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(11), SampleSum: proto.Float64(0), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, NegativeDelta: []int64{1, -1, 2, -2, 2}, PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, PositiveDelta: []int64{1, -1, 2, -2, 2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "wide zero bucket", observations: []float64{0, -1, -1.2, -1.4, -1.8, -2, 1, 1.2, 1.4, 1.8, 2}, factor: 1.2, zeroThreshold: 1.4, want: &dto.Histogram{ SampleCount: proto.Uint64(11), SampleSum: proto.Float64(0), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(1.4), ZeroCount: proto.Uint64(7), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(4), Length: proto.Uint32(1)}, }, NegativeDelta: []int64{2}, PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(4), Length: proto.Uint32(1)}, }, PositiveDelta: []int64{2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "NaN observation", observations: []float64{0, 1, 1.2, 1.4, 1.8, 2, math.NaN()}, factor: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(7), SampleSum: proto.Float64(math.NaN()), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, PositiveDelta: []int64{1, -1, 2, -2, 2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "+Inf observation", observations: []float64{0, 1, 1.2, 1.4, 1.8, 2, math.Inf(+1)}, factor: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(7), SampleSum: proto.Float64(math.Inf(+1)), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, {Offset: proto.Int32(4092), Length: proto.Uint32(1)}, }, PositiveDelta: []int64{1, -1, 2, -2, 2, -1}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "-Inf observation", observations: []float64{0, 1, 1.2, 1.4, 1.8, 2, math.Inf(-1)}, factor: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(7), SampleSum: proto.Float64(math.Inf(-1)), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(4097), Length: proto.Uint32(1)}, }, NegativeDelta: []int64{1}, PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, PositiveDelta: []int64{1, -1, 2, -2, 2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "limited buckets but nothing triggered", observations: []float64{0, 1, 1.2, 1.4, 1.8, 2}, factor: 1.2, maxBuckets: 4, want: &dto.Histogram{ SampleCount: proto.Uint64(6), SampleSum: proto.Float64(7.4), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, PositiveDelta: []int64{1, -1, 2, -2, 2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by halving resolution", observations: []float64{0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3}, factor: 1.2, maxBuckets: 4, want: &dto.Histogram{ SampleCount: proto.Uint64(8), SampleSum: proto.Float64(11.5), Schema: proto.Int32(1), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, PositiveDelta: []int64{1, 2, -1, -2, 1}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by widening the zero bucket", observations: []float64{0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3}, factor: 1.2, maxBuckets: 4, maxZeroThreshold: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(8), SampleSum: proto.Float64(11.5), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(1), ZeroCount: proto.Uint64(2), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(1), Length: proto.Uint32(7)}, }, PositiveDelta: []int64{1, 1, -2, 2, -2, 0, 1}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by widening the zero bucket twice", observations: []float64{0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3, 4}, factor: 1.2, maxBuckets: 4, maxZeroThreshold: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(9), SampleSum: proto.Float64(15.5), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(1.189207115002721), ZeroCount: proto.Uint64(3), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(2), Length: proto.Uint32(7)}, }, PositiveDelta: []int64{2, -2, 2, -2, 0, 1, 0}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by reset", observations: []float64{0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3, 4}, factor: 1.2, maxBuckets: 4, maxZeroThreshold: 1.2, minResetDuration: 5 * time.Minute, want: &dto.Histogram{ SampleCount: proto.Uint64(2), SampleSum: proto.Float64(7), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(0), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(7), Length: proto.Uint32(2)}, }, PositiveDelta: []int64{1, 0}, CreatedTimestamp: timestamppb.New(now.Add(8 * time.Minute)), // We expect reset to happen after 8 observations. }, }, { name: "limited buckets but nothing triggered, negative observations", observations: []float64{0, -1, -1.2, -1.4, -1.8, -2}, factor: 1.2, maxBuckets: 4, want: &dto.Histogram{ SampleCount: proto.Uint64(6), SampleSum: proto.Float64(-7.4), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, NegativeDelta: []int64{1, -1, 2, -2, 2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by halving resolution, negative observations", observations: []float64{0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3}, factor: 1.2, maxBuckets: 4, want: &dto.Histogram{ SampleCount: proto.Uint64(8), SampleSum: proto.Float64(-11.5), Schema: proto.Int32(1), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, NegativeDelta: []int64{1, 2, -1, -2, 1}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by widening the zero bucket, negative observations", observations: []float64{0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3}, factor: 1.2, maxBuckets: 4, maxZeroThreshold: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(8), SampleSum: proto.Float64(-11.5), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(1), ZeroCount: proto.Uint64(2), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(1), Length: proto.Uint32(7)}, }, NegativeDelta: []int64{1, 1, -2, 2, -2, 0, 1}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by widening the zero bucket twice, negative observations", observations: []float64{0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3, -4}, factor: 1.2, maxBuckets: 4, maxZeroThreshold: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(9), SampleSum: proto.Float64(-15.5), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(1.189207115002721), ZeroCount: proto.Uint64(3), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(2), Length: proto.Uint32(7)}, }, NegativeDelta: []int64{2, -2, 2, -2, 0, 1, 0}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by reset, negative observations", observations: []float64{0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3, -4}, factor: 1.2, maxBuckets: 4, maxZeroThreshold: 1.2, minResetDuration: 5 * time.Minute, want: &dto.Histogram{ SampleCount: proto.Uint64(2), SampleSum: proto.Float64(-7), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(0), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(7), Length: proto.Uint32(2)}, }, NegativeDelta: []int64{1, 0}, CreatedTimestamp: timestamppb.New(now.Add(8 * time.Minute)), // We expect reset to happen after 8 observations. }, }, { name: "buckets limited by halving resolution, then reset", observations: []float64{0, 1, 1.1, 1.2, 1.4, 1.8, 2, 5, 5.1, 3, 4}, factor: 1.2, maxBuckets: 4, minResetDuration: 9 * time.Minute, want: &dto.Histogram{ SampleCount: proto.Uint64(3), SampleSum: proto.Float64(12.1), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(0), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(7), Length: proto.Uint32(4)}, }, PositiveDelta: []int64{1, 0, -1, 1}, CreatedTimestamp: timestamppb.New(now.Add(9 * time.Minute)), // We expect reset to happen after 8 minutes. }, }, { name: "buckets limited by widening the zero bucket, then reset", observations: []float64{0, 1, 1.1, 1.2, 1.4, 1.8, 2, 5, 5.1, 3, 4}, factor: 1.2, maxBuckets: 4, maxZeroThreshold: 1.2, minResetDuration: 9 * time.Minute, want: &dto.Histogram{ SampleCount: proto.Uint64(3), SampleSum: proto.Float64(12.1), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(0), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(7), Length: proto.Uint32(4)}, }, PositiveDelta: []int64{1, 0, -1, 1}, CreatedTimestamp: timestamppb.New(now.Add(9 * time.Minute)), // We expect reset to happen after 8 minutes. }, }, } for _, s := range scenarios { t.Run(s.name, func(t *testing.T) { var ( ts = now funcToCall func() whenToCall time.Duration ) his := NewHistogram(HistogramOpts{ Name: "name", Help: "help", NativeHistogramBucketFactor: s.factor, NativeHistogramZeroThreshold: s.zeroThreshold, NativeHistogramMaxBucketNumber: s.maxBuckets, NativeHistogramMinResetDuration: s.minResetDuration, NativeHistogramMaxZeroThreshold: s.maxZeroThreshold, now: func() time.Time { return ts }, afterFunc: func(d time.Duration, f func()) *time.Timer { funcToCall = f whenToCall = d return nil }, }) ts = ts.Add(time.Minute) for _, o := range s.observations { his.Observe(o) ts = ts.Add(time.Minute) whenToCall -= time.Minute if funcToCall != nil && whenToCall <= 0 { funcToCall() funcToCall = nil } } m := &dto.Metric{} if err := his.Write(m); err != nil { t.Fatal("unexpected error writing metric", err) } got := m.Histogram if !proto.Equal(s.want, got) { t.Errorf("want histogram %q, got %q", s.want, got) } }) } } func TestNativeHistogramConcurrency(t *testing.T) { if testing.Short() { t.Skip("Skipping test in short mode.") } rand.New(rand.NewSource(42)) it := func(n uint32) bool { ts := time.Now().Add(30 * time.Second).Unix() mutations := int(n%1e4 + 1e4) concLevel := int(n%5 + 1) total := mutations * concLevel var start, end sync.WaitGroup start.Add(1) end.Add(concLevel) his := NewHistogram(HistogramOpts{ Name: "test_native_histogram", Help: "This help is sparse.", NativeHistogramBucketFactor: 1.05, NativeHistogramZeroThreshold: 0.0000001, NativeHistogramMaxBucketNumber: 50, NativeHistogramMinResetDuration: time.Hour, // Comment out to test for totals below. NativeHistogramMaxZeroThreshold: 0.001, now: func() time.Time { return time.Unix(atomic.LoadInt64(&ts), 0) }, }) allVars := make([]float64, total) var sampleSum float64 for i := 0; i < concLevel; i++ { vals := make([]float64, mutations) for j := 0; j < mutations; j++ { v := rand.NormFloat64() vals[j] = v allVars[i*mutations+j] = v sampleSum += v } go func(vals []float64) { start.Wait() for i, v := range vals { // An observation every 1 to 10 seconds. atomic.AddInt64(&ts, rand.Int63n(10)+1) if i%2 == 0 { his.Observe(v) } else { his.(ExemplarObserver).ObserveWithExemplar(v, Labels{"foo": "bar"}) } } end.Done() }(vals) } sort.Float64s(allVars) start.Done() end.Wait() m := &dto.Metric{} his.Write(m) // Uncomment these tests for totals only if you have disabled histogram resets above. // // if got, want := int(*m.Histogram.SampleCount), total; got != want { // t.Errorf("got sample count %d, want %d", got, want) // } // if got, want := *m.Histogram.SampleSum, sampleSum; math.Abs((got-want)/want) > 0.001 { // t.Errorf("got sample sum %f, want %f", got, want) // } sumBuckets := int(m.Histogram.GetZeroCount()) current := 0 for _, delta := range m.Histogram.GetNegativeDelta() { current += int(delta) if current < 0 { t.Fatalf("negative bucket population negative: %d", current) } sumBuckets += current } current = 0 for _, delta := range m.Histogram.GetPositiveDelta() { current += int(delta) if current < 0 { t.Fatalf("positive bucket population negative: %d", current) } sumBuckets += current } if got, want := sumBuckets, int(*m.Histogram.SampleCount); got != want { t.Errorf("got bucket population sum %d, want %d", got, want) } return true } if err := quick.Check(it, nil); err != nil { t.Error(err) } } func TestGetLe(t *testing.T) { scenarios := []struct { key int schema int32 want float64 }{ { key: -1, schema: -1, want: 0.25, }, { key: 0, schema: -1, want: 1, }, { key: 1, schema: -1, want: 4, }, { key: 512, schema: -1, want: math.MaxFloat64, }, { key: 513, schema: -1, want: math.Inf(+1), }, { key: -1, schema: 0, want: 0.5, }, { key: 0, schema: 0, want: 1, }, { key: 1, schema: 0, want: 2, }, { key: 1024, schema: 0, want: math.MaxFloat64, }, { key: 1025, schema: 0, want: math.Inf(+1), }, { key: -1, schema: 2, want: 0.8408964152537144, }, { key: 0, schema: 2, want: 1, }, { key: 1, schema: 2, want: 1.189207115002721, }, { key: 4096, schema: 2, want: math.MaxFloat64, }, { key: 4097, schema: 2, want: math.Inf(+1), }, } for i, s := range scenarios { got := getLe(s.key, s.schema) if s.want != got { t.Errorf("%d. key %d, schema %d, want upper bound of %g, got %g", i, s.key, s.schema, s.want, got) } } } func TestHistogramCreatedTimestamp(t *testing.T) { now := time.Now() histogram := NewHistogram(HistogramOpts{ Name: "test", Help: "test help", Buckets: []float64{1, 2, 3, 4}, now: func() time.Time { return now }, }) var metric dto.Metric if err := histogram.Write(&metric); err != nil { t.Fatal(err) } if metric.Histogram.CreatedTimestamp.AsTime().Unix() != now.Unix() { t.Errorf("expected created timestamp %d, got %d", now.Unix(), metric.Histogram.CreatedTimestamp.AsTime().Unix()) } } func TestHistogramVecCreatedTimestamp(t *testing.T) { now := time.Now() histogramVec := NewHistogramVec(HistogramOpts{ Name: "test", Help: "test help", Buckets: []float64{1, 2, 3, 4}, now: func() time.Time { return now }, }, []string{"label"}) histogram := histogramVec.WithLabelValues("value").(Histogram) var metric dto.Metric if err := histogram.Write(&metric); err != nil { t.Fatal(err) } if metric.Histogram.CreatedTimestamp.AsTime().Unix() != now.Unix() { t.Errorf("expected created timestamp %d, got %d", now.Unix(), metric.Histogram.CreatedTimestamp.AsTime().Unix()) } } func TestHistogramVecCreatedTimestampWithDeletes(t *testing.T) { now := time.Now() histogramVec := NewHistogramVec(HistogramOpts{ Name: "test", Help: "test help", Buckets: []float64{1, 2, 3, 4}, now: func() time.Time { return now }, }, []string{"label"}) // First use of "With" should populate CT. histogramVec.WithLabelValues("1") expected := map[string]time.Time{"1": now} now = now.Add(1 * time.Hour) expectCTsForMetricVecValues(t, histogramVec.MetricVec, dto.MetricType_HISTOGRAM, expected) // Two more labels at different times. histogramVec.WithLabelValues("2") expected["2"] = now now = now.Add(1 * time.Hour) histogramVec.WithLabelValues("3") expected["3"] = now now = now.Add(1 * time.Hour) expectCTsForMetricVecValues(t, histogramVec.MetricVec, dto.MetricType_HISTOGRAM, expected) // Recreate metric instance should reset created timestamp to now. histogramVec.DeleteLabelValues("1") histogramVec.WithLabelValues("1") expected["1"] = now now = now.Add(1 * time.Hour) expectCTsForMetricVecValues(t, histogramVec.MetricVec, dto.MetricType_HISTOGRAM, expected) } func TestNewConstHistogramWithCreatedTimestamp(t *testing.T) { metricDesc := NewDesc( "sample_value", "sample value", nil, nil, ) buckets := map[float64]uint64{25: 100, 50: 200} createdTs := time.Unix(1719670764, 123) h, err := NewConstHistogramWithCreatedTimestamp(metricDesc, 100, 200, buckets, createdTs) if err != nil { t.Fatal(err) } var metric dto.Metric if err := h.Write(&metric); err != nil { t.Fatal(err) } if metric.Histogram.CreatedTimestamp.AsTime().UnixMicro() != createdTs.UnixMicro() { t.Errorf("Expected created timestamp %v, got %v", createdTs, &metric.Histogram.CreatedTimestamp) } } func TestNativeHistogramExemplar(t *testing.T) { // Test the histogram with positive NativeHistogramExemplarTTL and NativeHistogramMaxExemplars h := NewHistogram(HistogramOpts{ Name: "test", Help: "test help", Buckets: []float64{1, 2, 3, 4}, NativeHistogramBucketFactor: 1.1, NativeHistogramMaxExemplars: 3, NativeHistogramExemplarTTL: 10 * time.Second, }).(*histogram) tcs := []struct { name string addFunc func(*histogram) expectedValues []float64 }{ { name: "add exemplars to the limit", addFunc: func(h *histogram) { h.ObserveWithExemplar(1, Labels{"id": "1"}) h.ObserveWithExemplar(3, Labels{"id": "1"}) h.ObserveWithExemplar(5, Labels{"id": "1"}) }, expectedValues: []float64{1, 3, 5}, }, { name: "remove exemplar in closest pair, the removed index equals to inserted index", addFunc: func(h *histogram) { h.ObserveWithExemplar(4, Labels{"id": "1"}) }, expectedValues: []float64{1, 3, 4}, }, { name: "remove exemplar in closest pair, the removed index is bigger than inserted index", addFunc: func(h *histogram) { h.ObserveWithExemplar(0, Labels{"id": "1"}) }, expectedValues: []float64{0, 1, 4}, }, { name: "remove exemplar with oldest timestamp, the removed index is smaller than inserted index", addFunc: func(h *histogram) { h.now = func() time.Time { return time.Now().Add(time.Second * 11) } h.ObserveWithExemplar(6, Labels{"id": "1"}) }, expectedValues: []float64{0, 4, 6}, }, } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { tc.addFunc(h) compareNativeExemplarValues(t, h.nativeExemplars.exemplars, tc.expectedValues) }) } // Test the histogram with negative NativeHistogramExemplarTTL h = NewHistogram(HistogramOpts{ Name: "test", Help: "test help", Buckets: []float64{1, 2, 3, 4}, NativeHistogramBucketFactor: 1.1, NativeHistogramMaxExemplars: 3, NativeHistogramExemplarTTL: -1 * time.Second, }).(*histogram) tcs = []struct { name string addFunc func(*histogram) expectedValues []float64 }{ { name: "add exemplars to the limit", addFunc: func(h *histogram) { h.ObserveWithExemplar(1, Labels{"id": "1"}) h.ObserveWithExemplar(3, Labels{"id": "1"}) h.ObserveWithExemplar(5, Labels{"id": "1"}) }, expectedValues: []float64{1, 3, 5}, }, { name: "remove exemplar with oldest timestamp, the removed index is smaller than inserted index", addFunc: func(h *histogram) { h.ObserveWithExemplar(4, Labels{"id": "1"}) }, expectedValues: []float64{3, 4, 5}, }, { name: "remove exemplar with oldest timestamp, the removed index equals to inserted index", addFunc: func(h *histogram) { h.ObserveWithExemplar(0, Labels{"id": "1"}) }, expectedValues: []float64{0, 4, 5}, }, { name: "remove exemplar with oldest timestamp, the removed index is bigger than inserted index", addFunc: func(h *histogram) { h.ObserveWithExemplar(3, Labels{"id": "1"}) }, expectedValues: []float64{0, 3, 4}, }, } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { tc.addFunc(h) compareNativeExemplarValues(t, h.nativeExemplars.exemplars, tc.expectedValues) }) } // Test the histogram with negative NativeHistogramMaxExemplars h = NewHistogram(HistogramOpts{ Name: "test", Help: "test help", Buckets: []float64{1, 2, 3, 4}, NativeHistogramBucketFactor: 1.1, NativeHistogramMaxExemplars: -1, NativeHistogramExemplarTTL: -1 * time.Second, }).(*histogram) tcs = []struct { name string addFunc func(*histogram) expectedValues []float64 }{ { name: "add exemplars to the limit, but no effect", addFunc: func(h *histogram) { h.ObserveWithExemplar(1, Labels{"id": "1"}) h.ObserveWithExemplar(3, Labels{"id": "1"}) h.ObserveWithExemplar(5, Labels{"id": "1"}) }, expectedValues: []float64{}, }, } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { tc.addFunc(h) compareNativeExemplarValues(t, h.nativeExemplars.exemplars, tc.expectedValues) }) } } func compareNativeExemplarValues(t *testing.T, exps []*dto.Exemplar, values []float64) { if len(exps) != len(values) { t.Errorf("the count of exemplars is not %d", len(values)) } for i, e := range exps { if e.GetValue() != values[i] { t.Errorf("the %dth exemplar value %v is not as expected: %v", i, e.GetValue(), values[i]) } } } var resultFindBucket int func benchmarkFindBucket(b *testing.B, l int) { h := &histogram{upperBounds: make([]float64, l)} for i := range h.upperBounds { h.upperBounds[i] = float64(i) } v := float64(l / 2) b.ResetTimer() for i := 0; i < b.N; i++ { resultFindBucket = h.findBucket(v) } } func BenchmarkFindBucketShort(b *testing.B) { benchmarkFindBucket(b, 20) } func BenchmarkFindBucketMid(b *testing.B) { benchmarkFindBucket(b, 40) } func BenchmarkFindBucketLarge(b *testing.B) { benchmarkFindBucket(b, 100) } func BenchmarkFindBucketHuge(b *testing.B) { benchmarkFindBucket(b, 500) } func BenchmarkFindBucketInf(b *testing.B) { h := &histogram{upperBounds: make([]float64, 500)} for i := range h.upperBounds { h.upperBounds[i] = float64(i) } v := 1000.5 b.ResetTimer() for i := 0; i < b.N; i++ { resultFindBucket = h.findBucket(v) } } func BenchmarkFindBucketLow(b *testing.B) { h := &histogram{upperBounds: make([]float64, 500)} for i := range h.upperBounds { h.upperBounds[i] = float64(i) } v := -1.1 b.ResetTimer() for i := 0; i < b.N; i++ { resultFindBucket = h.findBucket(v) } } func TestFindBucket(t *testing.T) { smallHistogram := &histogram{upperBounds: []float64{1, 2, 3, 4, 5}} largeHistogram := &histogram{upperBounds: make([]float64, 50)} for i := range largeHistogram.upperBounds { largeHistogram.upperBounds[i] = float64(i) } tests := []struct { h *histogram v float64 expected int }{ {smallHistogram, -1, 0}, {smallHistogram, 0.5, 0}, {smallHistogram, 2.5, 2}, {smallHistogram, 5.5, 5}, {largeHistogram, -1, 0}, {largeHistogram, 25.5, 26}, {largeHistogram, 49.5, 50}, {largeHistogram, 50.5, 50}, {largeHistogram, 5000.5, 50}, } for _, tt := range tests { result := tt.h.findBucket(tt.v) if result != tt.expected { t.Errorf("findBucket(%v) = %d; expected %d", tt.v, result, tt.expected) } } } func syncMapToMap(syncmap *sync.Map) (m map[int]int64) { m = map[int]int64{} syncmap.Range(func(key, value any) bool { m[key.(int)] = *value.(*int64) return true }) return m } func TestConstNativeHistogram(t *testing.T) { now := time.Now() scenarios := []struct { name string observations []float64 // With simulated interval of 1m. factor float64 zeroThreshold float64 maxBuckets uint32 minResetDuration time.Duration maxZeroThreshold float64 want *dto.Histogram }{ { name: "no observations", factor: 1.1, want: &dto.Histogram{ SampleCount: proto.Uint64(0), SampleSum: proto.Float64(0), Schema: proto.Int32(3), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(0), CreatedTimestamp: timestamppb.New(now), }, }, { name: "no observations and zero threshold of zero resulting in no-op span", factor: 1.1, zeroThreshold: NativeHistogramZeroThresholdZero, want: &dto.Histogram{ SampleCount: proto.Uint64(0), SampleSum: proto.Float64(0), Schema: proto.Int32(3), ZeroThreshold: proto.Float64(0), ZeroCount: proto.Uint64(0), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(0)}, }, CreatedTimestamp: timestamppb.New(now), }, }, { name: "factor 1.1 results in schema 3", observations: []float64{0, 1, 2, 3}, factor: 1.1, want: &dto.Histogram{ SampleCount: proto.Uint64(4), SampleSum: proto.Float64(6), Schema: proto.Int32(3), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(1)}, {Offset: proto.Int32(7), Length: proto.Uint32(1)}, {Offset: proto.Int32(4), Length: proto.Uint32(1)}, }, PositiveDelta: []int64{1, 0, 0}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "factor 1.2 results in schema 2", observations: []float64{0, 1, 1.2, 1.4, 1.8, 2}, factor: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(6), SampleSum: proto.Float64(7.4), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, PositiveDelta: []int64{1, -1, 2, -2, 2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "factor 4 results in schema -1", observations: []float64{ 0.0156251, 0.0625, // Bucket -2: (0.015625, 0.0625) 0.1, 0.25, // Bucket -1: (0.0625, 0.25] 0.5, 1, // Bucket 0: (0.25, 1] 1.5, 2, 3, 3.5, // Bucket 1: (1, 4] 5, 6, 7, // Bucket 2: (4, 16] 33.33, // Bucket 3: (16, 64] }, factor: 4, want: &dto.Histogram{ SampleCount: proto.Uint64(14), SampleSum: proto.Float64(63.2581251), Schema: proto.Int32(-1), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(0), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(-2), Length: proto.Uint32(6)}, }, PositiveDelta: []int64{2, 0, 0, 2, -1, -2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "factor 17 results in schema -2", observations: []float64{ 0.0156251, 0.0625, // Bucket -1: (0.015625, 0.0625] 0.1, 0.25, 0.5, 1, // Bucket 0: (0.0625, 1] 1.5, 2, 3, 3.5, 5, 6, 7, // Bucket 1: (1, 16] 33.33, // Bucket 2: (16, 256] }, factor: 17, want: &dto.Histogram{ SampleCount: proto.Uint64(14), SampleSum: proto.Float64(63.2581251), Schema: proto.Int32(-2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(0), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(-1), Length: proto.Uint32(4)}, }, PositiveDelta: []int64{2, 2, 3, -6}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "negative buckets", observations: []float64{0, -1, -1.2, -1.4, -1.8, -2}, factor: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(6), SampleSum: proto.Float64(-7.4), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, NegativeDelta: []int64{1, -1, 2, -2, 2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "negative and positive buckets", observations: []float64{0, -1, -1.2, -1.4, -1.8, -2, 1, 1.2, 1.4, 1.8, 2}, factor: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(11), SampleSum: proto.Float64(0), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, NegativeDelta: []int64{1, -1, 2, -2, 2}, PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, PositiveDelta: []int64{1, -1, 2, -2, 2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "wide zero bucket", observations: []float64{0, -1, -1.2, -1.4, -1.8, -2, 1, 1.2, 1.4, 1.8, 2}, factor: 1.2, zeroThreshold: 1.4, want: &dto.Histogram{ SampleCount: proto.Uint64(11), SampleSum: proto.Float64(0), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(1.4), ZeroCount: proto.Uint64(7), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(4), Length: proto.Uint32(1)}, }, NegativeDelta: []int64{2}, PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(4), Length: proto.Uint32(1)}, }, PositiveDelta: []int64{2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "NaN observation", observations: []float64{0, 1, 1.2, 1.4, 1.8, 2, math.NaN()}, factor: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(7), SampleSum: proto.Float64(math.NaN()), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, PositiveDelta: []int64{1, -1, 2, -2, 2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "+Inf observation", observations: []float64{0, 1, 1.2, 1.4, 1.8, 2, math.Inf(+1)}, factor: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(7), SampleSum: proto.Float64(math.Inf(+1)), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, {Offset: proto.Int32(4092), Length: proto.Uint32(1)}, }, PositiveDelta: []int64{1, -1, 2, -2, 2, -1}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "-Inf observation", observations: []float64{0, 1, 1.2, 1.4, 1.8, 2, math.Inf(-1)}, factor: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(7), SampleSum: proto.Float64(math.Inf(-1)), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(4097), Length: proto.Uint32(1)}, }, NegativeDelta: []int64{1}, PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, PositiveDelta: []int64{1, -1, 2, -2, 2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "limited buckets but nothing triggered", observations: []float64{0, 1, 1.2, 1.4, 1.8, 2}, factor: 1.2, maxBuckets: 4, want: &dto.Histogram{ SampleCount: proto.Uint64(6), SampleSum: proto.Float64(7.4), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, PositiveDelta: []int64{1, -1, 2, -2, 2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by halving resolution", observations: []float64{0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3}, factor: 1.2, maxBuckets: 4, want: &dto.Histogram{ SampleCount: proto.Uint64(8), SampleSum: proto.Float64(11.5), Schema: proto.Int32(1), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, PositiveDelta: []int64{1, 2, -1, -2, 1}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by widening the zero bucket", observations: []float64{0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3}, factor: 1.2, maxBuckets: 4, maxZeroThreshold: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(8), SampleSum: proto.Float64(11.5), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(1), ZeroCount: proto.Uint64(2), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(1), Length: proto.Uint32(7)}, }, PositiveDelta: []int64{1, 1, -2, 2, -2, 0, 1}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by widening the zero bucket twice", observations: []float64{0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3, 4}, factor: 1.2, maxBuckets: 4, maxZeroThreshold: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(9), SampleSum: proto.Float64(15.5), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(1.189207115002721), ZeroCount: proto.Uint64(3), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(2), Length: proto.Uint32(7)}, }, PositiveDelta: []int64{2, -2, 2, -2, 0, 1, 0}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by reset", observations: []float64{0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3, 4}, factor: 1.2, maxBuckets: 4, maxZeroThreshold: 1.2, minResetDuration: 5 * time.Minute, want: &dto.Histogram{ SampleCount: proto.Uint64(2), SampleSum: proto.Float64(7), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(0), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(7), Length: proto.Uint32(2)}, }, PositiveDelta: []int64{1, 0}, CreatedTimestamp: timestamppb.New(now.Add(8 * time.Minute)), // We expect reset to happen after 8 observations. }, }, { name: "limited buckets but nothing triggered, negative observations", observations: []float64{0, -1, -1.2, -1.4, -1.8, -2}, factor: 1.2, maxBuckets: 4, want: &dto.Histogram{ SampleCount: proto.Uint64(6), SampleSum: proto.Float64(-7.4), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, NegativeDelta: []int64{1, -1, 2, -2, 2}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by halving resolution, negative observations", observations: []float64{0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3}, factor: 1.2, maxBuckets: 4, want: &dto.Histogram{ SampleCount: proto.Uint64(8), SampleSum: proto.Float64(-11.5), Schema: proto.Int32(1), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(1), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(0), Length: proto.Uint32(5)}, }, NegativeDelta: []int64{1, 2, -1, -2, 1}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by widening the zero bucket, negative observations", observations: []float64{0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3}, factor: 1.2, maxBuckets: 4, maxZeroThreshold: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(8), SampleSum: proto.Float64(-11.5), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(1), ZeroCount: proto.Uint64(2), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(1), Length: proto.Uint32(7)}, }, NegativeDelta: []int64{1, 1, -2, 2, -2, 0, 1}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by widening the zero bucket twice, negative observations", observations: []float64{0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3, -4}, factor: 1.2, maxBuckets: 4, maxZeroThreshold: 1.2, want: &dto.Histogram{ SampleCount: proto.Uint64(9), SampleSum: proto.Float64(-15.5), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(1.189207115002721), ZeroCount: proto.Uint64(3), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(2), Length: proto.Uint32(7)}, }, NegativeDelta: []int64{2, -2, 2, -2, 0, 1, 0}, CreatedTimestamp: timestamppb.New(now), }, }, { name: "buckets limited by reset, negative observations", observations: []float64{0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3, -4}, factor: 1.2, maxBuckets: 4, maxZeroThreshold: 1.2, minResetDuration: 5 * time.Minute, want: &dto.Histogram{ SampleCount: proto.Uint64(2), SampleSum: proto.Float64(-7), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(0), NegativeSpan: []*dto.BucketSpan{ {Offset: proto.Int32(7), Length: proto.Uint32(2)}, }, NegativeDelta: []int64{1, 0}, CreatedTimestamp: timestamppb.New(now.Add(8 * time.Minute)), // We expect reset to happen after 8 observations. }, }, { name: "buckets limited by halving resolution, then reset", observations: []float64{0, 1, 1.1, 1.2, 1.4, 1.8, 2, 5, 5.1, 3, 4}, factor: 1.2, maxBuckets: 4, minResetDuration: 9 * time.Minute, want: &dto.Histogram{ SampleCount: proto.Uint64(3), SampleSum: proto.Float64(12.1), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(0), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(7), Length: proto.Uint32(4)}, }, PositiveDelta: []int64{1, 0, -1, 1}, CreatedTimestamp: timestamppb.New(now.Add(9 * time.Minute)), // We expect reset to happen after 8 minutes. }, }, { name: "buckets limited by widening the zero bucket, then reset", observations: []float64{0, 1, 1.1, 1.2, 1.4, 1.8, 2, 5, 5.1, 3, 4}, factor: 1.2, maxBuckets: 4, maxZeroThreshold: 1.2, minResetDuration: 9 * time.Minute, want: &dto.Histogram{ SampleCount: proto.Uint64(3), SampleSum: proto.Float64(12.1), Schema: proto.Int32(2), ZeroThreshold: proto.Float64(2.938735877055719e-39), ZeroCount: proto.Uint64(0), PositiveSpan: []*dto.BucketSpan{ {Offset: proto.Int32(7), Length: proto.Uint32(4)}, }, PositiveDelta: []int64{1, 0, -1, 1}, CreatedTimestamp: timestamppb.New(now.Add(9 * time.Minute)), // We expect reset to happen after 8 minutes. }, }, } for _, s := range scenarios { t.Run(s.name, func(t *testing.T) { var ( ts = now funcToCall func() whenToCall time.Duration ) his := NewHistogram(HistogramOpts{ Name: "name", Help: "help", NativeHistogramBucketFactor: s.factor, NativeHistogramZeroThreshold: s.zeroThreshold, NativeHistogramMaxBucketNumber: s.maxBuckets, NativeHistogramMinResetDuration: s.minResetDuration, NativeHistogramMaxZeroThreshold: s.maxZeroThreshold, now: func() time.Time { return ts }, afterFunc: func(d time.Duration, f func()) *time.Timer { funcToCall = f whenToCall = d return nil }, }) ts = ts.Add(time.Minute) for _, o := range s.observations { his.Observe(o) ts = ts.Add(time.Minute) whenToCall -= time.Minute if funcToCall != nil && whenToCall <= 0 { funcToCall() funcToCall = nil } } _his := his.(*histogram) n := atomic.LoadUint64(&_his.countAndHotIdx) hotIdx := n >> 63 cold := _his.counts[hotIdx] consthist, err := NewConstNativeHistogram(_his.Desc(), cold.count, math.Float64frombits(cold.sumBits), syncMapToMap(&cold.nativeHistogramBucketsPositive), syncMapToMap(&cold.nativeHistogramBucketsNegative), cold.nativeHistogramZeroBucket, cold.nativeHistogramSchema, math.Float64frombits(cold.nativeHistogramZeroThresholdBits), _his.lastResetTime, ) if err != nil { t.Fatal("unexpected error writing metric", err) } m2 := &dto.Metric{} if err := consthist.Write(m2); err != nil { t.Fatal("unexpected error writing metric", err) } got := m2.Histogram if !proto.Equal(s.want, got) { t.Errorf("want histogram %q, got %q", s.want, got) } }) } } client_golang-1.21.1/prometheus/internal/000077500000000000000000000000001476160432400204175ustar00rootroot00000000000000client_golang-1.21.1/prometheus/internal/almost_equal.go000066400000000000000000000042761476160432400234450ustar00rootroot00000000000000// Copyright (c) 2015 BjΓΆrn Rabenstein // // 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. // // The code in this package is copy/paste to avoid a dependency. Hence this file // carries the copyright of the original repo. // https://github.com/beorn7/floats package internal import ( "math" ) // minNormalFloat64 is the smallest positive normal value of type float64. var minNormalFloat64 = math.Float64frombits(0x0010000000000000) // AlmostEqualFloat64 returns true if a and b are equal within a relative error // of epsilon. See http://floating-point-gui.de/errors/comparison/ for the // details of the applied method. func AlmostEqualFloat64(a, b, epsilon float64) bool { if a == b { return true } absA := math.Abs(a) absB := math.Abs(b) diff := math.Abs(a - b) if a == 0 || b == 0 || absA+absB < minNormalFloat64 { return diff < epsilon*minNormalFloat64 } return diff/math.Min(absA+absB, math.MaxFloat64) < epsilon } // AlmostEqualFloat64s is the slice form of AlmostEqualFloat64. func AlmostEqualFloat64s(a, b []float64, epsilon float64) bool { if len(a) != len(b) { return false } for i := range a { if !AlmostEqualFloat64(a[i], b[i], epsilon) { return false } } return true } client_golang-1.21.1/prometheus/internal/difflib.go000066400000000000000000000466441476160432400223630ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // It provides tools to compare sequences of strings and generate textual diffs. // // Maintaining `GetUnifiedDiffString` here because original repository // (https://github.com/pmezard/go-difflib) is no longer maintained. package internal import ( "bufio" "bytes" "fmt" "io" "strconv" "strings" ) func minInt(a, b int) int { if a < b { return a } return b } func maxInt(a, b int) int { if a > b { return a } return b } func calculateRatio(matches, length int) float64 { if length > 0 { return 2.0 * float64(matches) / float64(length) } return 1.0 } type Match struct { A int B int Size int } type OpCode struct { Tag byte I1 int I2 int J1 int J2 int } // SequenceMatcher compares sequence of strings. The basic // algorithm predates, and is a little fancier than, an algorithm // published in the late 1980's by Ratcliff and Obershelp under the // hyperbolic name "gestalt pattern matching". The basic idea is to find // the longest contiguous matching subsequence that contains no "junk" // elements (R-O doesn't address junk). The same idea is then applied // recursively to the pieces of the sequences to the left and to the right // of the matching subsequence. This does not yield minimal edit // sequences, but does tend to yield matches that "look right" to people. // // SequenceMatcher tries to compute a "human-friendly diff" between two // sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the // longest *contiguous* & junk-free matching subsequence. That's what // catches peoples' eyes. The Windows(tm) windiff has another interesting // notion, pairing up elements that appear uniquely in each sequence. // That, and the method here, appear to yield more intuitive difference // reports than does diff. This method appears to be the least vulnerable // to synching up on blocks of "junk lines", though (like blank lines in // ordinary text files, or maybe "

" lines in HTML files). That may be // because this is the only method of the 3 that has a *concept* of // "junk" . // // Timing: Basic R-O is cubic time worst case and quadratic time expected // case. SequenceMatcher is quadratic time for the worst case and has // expected-case behavior dependent in a complicated way on how many // elements the sequences have in common; best case time is linear. type SequenceMatcher struct { a []string b []string b2j map[string][]int IsJunk func(string) bool autoJunk bool bJunk map[string]struct{} matchingBlocks []Match fullBCount map[string]int bPopular map[string]struct{} opCodes []OpCode } func NewMatcher(a, b []string) *SequenceMatcher { m := SequenceMatcher{autoJunk: true} m.SetSeqs(a, b) return &m } func NewMatcherWithJunk(a, b []string, autoJunk bool, isJunk func(string) bool, ) *SequenceMatcher { m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk} m.SetSeqs(a, b) return &m } // Set two sequences to be compared. func (m *SequenceMatcher) SetSeqs(a, b []string) { m.SetSeq1(a) m.SetSeq2(b) } // Set the first sequence to be compared. The second sequence to be compared is // not changed. // // SequenceMatcher computes and caches detailed information about the second // sequence, so if you want to compare one sequence S against many sequences, // use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other // sequences. // // See also SetSeqs() and SetSeq2(). func (m *SequenceMatcher) SetSeq1(a []string) { if &a == &m.a { return } m.a = a m.matchingBlocks = nil m.opCodes = nil } // Set the second sequence to be compared. The first sequence to be compared is // not changed. func (m *SequenceMatcher) SetSeq2(b []string) { if &b == &m.b { return } m.b = b m.matchingBlocks = nil m.opCodes = nil m.fullBCount = nil m.chainB() } func (m *SequenceMatcher) chainB() { // Populate line -> index mapping b2j := map[string][]int{} for i, s := range m.b { indices := b2j[s] indices = append(indices, i) b2j[s] = indices } // Purge junk elements m.bJunk = map[string]struct{}{} if m.IsJunk != nil { junk := m.bJunk for s := range b2j { if m.IsJunk(s) { junk[s] = struct{}{} } } for s := range junk { delete(b2j, s) } } // Purge remaining popular elements popular := map[string]struct{}{} n := len(m.b) if m.autoJunk && n >= 200 { ntest := n/100 + 1 for s, indices := range b2j { if len(indices) > ntest { popular[s] = struct{}{} } } for s := range popular { delete(b2j, s) } } m.bPopular = popular m.b2j = b2j } func (m *SequenceMatcher) isBJunk(s string) bool { _, ok := m.bJunk[s] return ok } // Find longest matching block in a[alo:ahi] and b[blo:bhi]. // // If IsJunk is not defined: // // Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where // // alo <= i <= i+k <= ahi // blo <= j <= j+k <= bhi // // and for all (i',j',k') meeting those conditions, // // k >= k' // i <= i' // and if i == i', j <= j' // // In other words, of all maximal matching blocks, return one that // starts earliest in a, and of all those maximal matching blocks that // start earliest in a, return the one that starts earliest in b. // // If IsJunk is defined, first the longest matching block is // determined as above, but with the additional restriction that no // junk element appears in the block. Then that block is extended as // far as possible by matching (only) junk elements on both sides. So // the resulting block never matches on junk except as identical junk // happens to be adjacent to an "interesting" match. // // If no blocks match, return (alo, blo, 0). func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match { // CAUTION: stripping common prefix or suffix would be incorrect. // E.g., // ab // acab // Longest matching block is "ab", but if common prefix is // stripped, it's "a" (tied with "b"). UNIX(tm) diff does so // strip, so ends up claiming that ab is changed to acab by // inserting "ca" in the middle. That's minimal but unintuitive: // "it's obvious" that someone inserted "ac" at the front. // Windiff ends up at the same place as diff, but by pairing up // the unique 'b's and then matching the first two 'a's. besti, bestj, bestsize := alo, blo, 0 // find longest junk-free match // during an iteration of the loop, j2len[j] = length of longest // junk-free match ending with a[i-1] and b[j] j2len := map[int]int{} for i := alo; i != ahi; i++ { // look at all instances of a[i] in b; note that because // b2j has no junk keys, the loop is skipped if a[i] is junk newj2len := map[int]int{} for _, j := range m.b2j[m.a[i]] { // a[i] matches b[j] if j < blo { continue } if j >= bhi { break } k := j2len[j-1] + 1 newj2len[j] = k if k > bestsize { besti, bestj, bestsize = i-k+1, j-k+1, k } } j2len = newj2len } // Extend the best by non-junk elements on each end. In particular, // "popular" non-junk elements aren't in b2j, which greatly speeds // the inner loop above, but also means "the best" match so far // doesn't contain any junk *or* popular non-junk elements. for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) && m.a[besti-1] == m.b[bestj-1] { besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 } for besti+bestsize < ahi && bestj+bestsize < bhi && !m.isBJunk(m.b[bestj+bestsize]) && m.a[besti+bestsize] == m.b[bestj+bestsize] { bestsize++ } // Now that we have a wholly interesting match (albeit possibly // empty!), we may as well suck up the matching junk on each // side of it too. Can't think of a good reason not to, and it // saves post-processing the (possibly considerable) expense of // figuring out what to do with it. In the case of an empty // interesting match, this is clearly the right thing to do, // because no other kind of match is possible in the regions. for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) && m.a[besti-1] == m.b[bestj-1] { besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 } for besti+bestsize < ahi && bestj+bestsize < bhi && m.isBJunk(m.b[bestj+bestsize]) && m.a[besti+bestsize] == m.b[bestj+bestsize] { bestsize++ } return Match{A: besti, B: bestj, Size: bestsize} } // Return list of triples describing matching subsequences. // // Each triple is of the form (i, j, n), and means that // a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in // i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are // adjacent triples in the list, and the second is not the last triple in the // list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe // adjacent equal blocks. // // The last triple is a dummy, (len(a), len(b), 0), and is the only // triple with n==0. func (m *SequenceMatcher) GetMatchingBlocks() []Match { if m.matchingBlocks != nil { return m.matchingBlocks } var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match { match := m.findLongestMatch(alo, ahi, blo, bhi) i, j, k := match.A, match.B, match.Size if match.Size > 0 { if alo < i && blo < j { matched = matchBlocks(alo, i, blo, j, matched) } matched = append(matched, match) if i+k < ahi && j+k < bhi { matched = matchBlocks(i+k, ahi, j+k, bhi, matched) } } return matched } matched := matchBlocks(0, len(m.a), 0, len(m.b), nil) // It's possible that we have adjacent equal blocks in the // matching_blocks list now. nonAdjacent := []Match{} i1, j1, k1 := 0, 0, 0 for _, b := range matched { // Is this block adjacent to i1, j1, k1? i2, j2, k2 := b.A, b.B, b.Size if i1+k1 == i2 && j1+k1 == j2 { // Yes, so collapse them -- this just increases the length of // the first block by the length of the second, and the first // block so lengthened remains the block to compare against. k1 += k2 } else { // Not adjacent. Remember the first block (k1==0 means it's // the dummy we started with), and make the second block the // new block to compare against. if k1 > 0 { nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) } i1, j1, k1 = i2, j2, k2 } } if k1 > 0 { nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) } nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0}) m.matchingBlocks = nonAdjacent return m.matchingBlocks } // Return list of 5-tuples describing how to turn a into b. // // Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple // has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the // tuple preceding it, and likewise for j1 == the previous j2. // // The tags are characters, with these meanings: // // 'r' (replace): a[i1:i2] should be replaced by b[j1:j2] // // 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case. // // 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case. // // 'e' (equal): a[i1:i2] == b[j1:j2] func (m *SequenceMatcher) GetOpCodes() []OpCode { if m.opCodes != nil { return m.opCodes } i, j := 0, 0 matching := m.GetMatchingBlocks() opCodes := make([]OpCode, 0, len(matching)) for _, m := range matching { // invariant: we've pumped out correct diffs to change // a[:i] into b[:j], and the next matching block is // a[ai:ai+size] == b[bj:bj+size]. So we need to pump // out a diff to change a[i:ai] into b[j:bj], pump out // the matching block, and move (i,j) beyond the match ai, bj, size := m.A, m.B, m.Size tag := byte(0) if i < ai && j < bj { tag = 'r' } else if i < ai { tag = 'd' } else if j < bj { tag = 'i' } if tag > 0 { opCodes = append(opCodes, OpCode{tag, i, ai, j, bj}) } i, j = ai+size, bj+size // the list of matching blocks is terminated by a // sentinel with size 0 if size > 0 { opCodes = append(opCodes, OpCode{'e', ai, i, bj, j}) } } m.opCodes = opCodes return m.opCodes } // Isolate change clusters by eliminating ranges with no changes. // // Return a generator of groups with up to n lines of context. // Each group is in the same format as returned by GetOpCodes(). func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { if n < 0 { n = 3 } codes := m.GetOpCodes() if len(codes) == 0 { codes = []OpCode{{'e', 0, 1, 0, 1}} } // Fixup leading and trailing groups if they show no changes. if codes[0].Tag == 'e' { c := codes[0] i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 codes[0] = OpCode{c.Tag, maxInt(i1, i2-n), i2, maxInt(j1, j2-n), j2} } if codes[len(codes)-1].Tag == 'e' { c := codes[len(codes)-1] i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 codes[len(codes)-1] = OpCode{c.Tag, i1, minInt(i2, i1+n), j1, minInt(j2, j1+n)} } nn := n + n groups := [][]OpCode{} group := []OpCode{} for _, c := range codes { i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 // End the current group and start a new one whenever // there is a large range with no changes. if c.Tag == 'e' && i2-i1 > nn { group = append(group, OpCode{ c.Tag, i1, minInt(i2, i1+n), j1, minInt(j2, j1+n), }) groups = append(groups, group) group = []OpCode{} i1, j1 = maxInt(i1, i2-n), maxInt(j1, j2-n) } group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) } if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') { groups = append(groups, group) } return groups } // Return a measure of the sequences' similarity (float in [0,1]). // // Where T is the total number of elements in both sequences, and // M is the number of matches, this is 2.0*M / T. // Note that this is 1 if the sequences are identical, and 0 if // they have nothing in common. // // .Ratio() is expensive to compute if you haven't already computed // .GetMatchingBlocks() or .GetOpCodes(), in which case you may // want to try .QuickRatio() or .RealQuickRation() first to get an // upper bound. func (m *SequenceMatcher) Ratio() float64 { matches := 0 for _, m := range m.GetMatchingBlocks() { matches += m.Size } return calculateRatio(matches, len(m.a)+len(m.b)) } // Return an upper bound on ratio() relatively quickly. // // This isn't defined beyond that it is an upper bound on .Ratio(), and // is faster to compute. func (m *SequenceMatcher) QuickRatio() float64 { // viewing a and b as multisets, set matches to the cardinality // of their intersection; this counts the number of matches // without regard to order, so is clearly an upper bound if m.fullBCount == nil { m.fullBCount = map[string]int{} for _, s := range m.b { m.fullBCount[s]++ } } // avail[x] is the number of times x appears in 'b' less the // number of times we've seen it in 'a' so far ... kinda avail := map[string]int{} matches := 0 for _, s := range m.a { n, ok := avail[s] if !ok { n = m.fullBCount[s] } avail[s] = n - 1 if n > 0 { matches++ } } return calculateRatio(matches, len(m.a)+len(m.b)) } // Return an upper bound on ratio() very quickly. // // This isn't defined beyond that it is an upper bound on .Ratio(), and // is faster to compute than either .Ratio() or .QuickRatio(). func (m *SequenceMatcher) RealQuickRatio() float64 { la, lb := len(m.a), len(m.b) return calculateRatio(minInt(la, lb), la+lb) } // Convert range to the "ed" format func formatRangeUnified(start, stop int) string { // Per the diff spec at http://www.unix.org/single_unix_specification/ beginning := start + 1 // lines start numbering with one length := stop - start if length == 1 { return strconv.Itoa(beginning) } if length == 0 { beginning-- // empty ranges begin at line just before the range } return fmt.Sprintf("%d,%d", beginning, length) } // Unified diff parameters type UnifiedDiff struct { A []string // First sequence lines FromFile string // First file name FromDate string // First file time B []string // Second sequence lines ToFile string // Second file name ToDate string // Second file time Eol string // Headers end of line, defaults to LF Context int // Number of context lines } // Compare two sequences of lines; generate the delta as a unified diff. // // Unified diffs are a compact way of showing line changes and a few // lines of context. The number of context lines is set by 'n' which // defaults to three. // // By default, the diff control lines (those with ---, +++, or @@) are // created with a trailing newline. This is helpful so that inputs // created from file.readlines() result in diffs that are suitable for // file.writelines() since both the inputs and outputs have trailing // newlines. // // For inputs that do not have trailing newlines, set the lineterm // argument to "" so that the output will be uniformly newline free. // // The unidiff format normally has a header for filenames and modification // times. Any or all of these may be specified using strings for // 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. // The modification times are normally expressed in the ISO 8601 format. func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { buf := bufio.NewWriter(writer) defer buf.Flush() wf := func(format string, args ...interface{}) error { _, err := buf.WriteString(fmt.Sprintf(format, args...)) return err } ws := func(s string) error { _, err := buf.WriteString(s) return err } if len(diff.Eol) == 0 { diff.Eol = "\n" } started := false m := NewMatcher(diff.A, diff.B) for _, g := range m.GetGroupedOpCodes(diff.Context) { if !started { started = true fromDate := "" if len(diff.FromDate) > 0 { fromDate = "\t" + diff.FromDate } toDate := "" if len(diff.ToDate) > 0 { toDate = "\t" + diff.ToDate } if diff.FromFile != "" || diff.ToFile != "" { err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) if err != nil { return err } err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) if err != nil { return err } } } first, last := g[0], g[len(g)-1] range1 := formatRangeUnified(first.I1, last.I2) range2 := formatRangeUnified(first.J1, last.J2) if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { return err } for _, c := range g { i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 if c.Tag == 'e' { for _, line := range diff.A[i1:i2] { if err := ws(" " + line); err != nil { return err } } continue } if c.Tag == 'r' || c.Tag == 'd' { for _, line := range diff.A[i1:i2] { if err := ws("-" + line); err != nil { return err } } } if c.Tag == 'r' || c.Tag == 'i' { for _, line := range diff.B[j1:j2] { if err := ws("+" + line); err != nil { return err } } } } } return nil } // Like WriteUnifiedDiff but returns the diff a string. func GetUnifiedDiffString(diff UnifiedDiff) (string, error) { w := &bytes.Buffer{} err := WriteUnifiedDiff(w, diff) return w.String(), err } // Split a string on "\n" while preserving them. The output can be used // as input for UnifiedDiff and ContextDiff structures. func SplitLines(s string) []string { lines := strings.SplitAfter(s, "\n") lines[len(lines)-1] += "\n" return lines } client_golang-1.21.1/prometheus/internal/difflib_test.go000066400000000000000000000154501476160432400234110ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package internal import ( "bytes" "fmt" "math" "reflect" "strings" "testing" ) func assertAlmostEqual(t *testing.T, a, b float64, places int) { if math.Abs(a-b) > math.Pow10(-places) { t.Errorf("%.7f != %.7f", a, b) } } func assertEqual(t *testing.T, a, b interface{}) { if !reflect.DeepEqual(a, b) { t.Errorf("%v != %v", a, b) } } func splitChars(s string) []string { chars := make([]string, 0, len(s)) // Assume ASCII inputs for i := 0; i != len(s); i++ { chars = append(chars, string(s[i])) } return chars } func TestSequenceMatcherRatio(t *testing.T) { s := NewMatcher(splitChars("abcd"), splitChars("bcde")) assertEqual(t, s.Ratio(), 0.75) assertEqual(t, s.QuickRatio(), 0.75) assertEqual(t, s.RealQuickRatio(), 1.0) } func TestGetOptCodes(t *testing.T) { a := "qabxcd" b := "abycdf" s := NewMatcher(splitChars(a), splitChars(b)) w := &bytes.Buffer{} for _, op := range s.GetOpCodes() { fmt.Fprintf(w, "%s a[%d:%d], (%s) b[%d:%d] (%s)\n", string(op.Tag), op.I1, op.I2, a[op.I1:op.I2], op.J1, op.J2, b[op.J1:op.J2]) } result := w.String() expected := `d a[0:1], (q) b[0:0] () e a[1:3], (ab) b[0:2] (ab) r a[3:4], (x) b[2:3] (y) e a[4:6], (cd) b[3:5] (cd) i a[6:6], () b[5:6] (f) ` if expected != result { t.Errorf("unexpected op codes: \n%s", result) } } func TestGroupedOpCodes(t *testing.T) { a := []string{} for i := 0; i != 39; i++ { a = append(a, fmt.Sprintf("%02d", i)) } b := []string{} b = append(b, a[:8]...) b = append(b, " i") b = append(b, a[8:19]...) b = append(b, " x") b = append(b, a[20:22]...) b = append(b, a[27:34]...) b = append(b, " y") b = append(b, a[35:]...) s := NewMatcher(a, b) w := &bytes.Buffer{} for _, g := range s.GetGroupedOpCodes(-1) { fmt.Fprintf(w, "group\n") for _, op := range g { fmt.Fprintf(w, " %s, %d, %d, %d, %d\n", string(op.Tag), op.I1, op.I2, op.J1, op.J2) } } result := w.String() expected := `group e, 5, 8, 5, 8 i, 8, 8, 8, 9 e, 8, 11, 9, 12 group e, 16, 19, 17, 20 r, 19, 20, 20, 21 e, 20, 22, 21, 23 d, 22, 27, 23, 23 e, 27, 30, 23, 26 group e, 31, 34, 27, 30 r, 34, 35, 30, 31 e, 35, 38, 31, 34 ` if expected != result { t.Errorf("unexpected op codes: \n%s", result) } } func ExampleGetUnifiedDiffCode() { a := `one two three four fmt.Printf("%s,%T",a,b)` b := `zero one three four` diff := UnifiedDiff{ A: SplitLines(a), B: SplitLines(b), FromFile: "Original", FromDate: "2005-01-26 23:30:50", ToFile: "Current", ToDate: "2010-04-02 10:20:52", Context: 3, } result, _ := GetUnifiedDiffString(diff) fmt.Println(strings.ReplaceAll(result, "\t", " ")) // Output: // --- Original 2005-01-26 23:30:50 // +++ Current 2010-04-02 10:20:52 // @@ -1,5 +1,4 @@ // +zero // one // -two // three // four // -fmt.Printf("%s,%T",a,b) } func rep(s string, count int) string { return strings.Repeat(s, count) } func TestWithAsciiOneInsert(t *testing.T) { sm := NewMatcher(splitChars(rep("b", 100)), splitChars("a"+rep("b", 100))) assertAlmostEqual(t, sm.Ratio(), 0.995, 3) assertEqual(t, sm.GetOpCodes(), []OpCode{{'i', 0, 0, 0, 1}, {'e', 0, 100, 1, 101}}) assertEqual(t, len(sm.bPopular), 0) sm = NewMatcher(splitChars(rep("b", 100)), splitChars(rep("b", 50)+"a"+rep("b", 50))) assertAlmostEqual(t, sm.Ratio(), 0.995, 3) assertEqual(t, sm.GetOpCodes(), []OpCode{{'e', 0, 50, 0, 50}, {'i', 50, 50, 50, 51}, {'e', 50, 100, 51, 101}}) assertEqual(t, len(sm.bPopular), 0) } func TestWithAsciiOnDelete(t *testing.T) { sm := NewMatcher(splitChars(rep("a", 40)+"c"+rep("b", 40)), splitChars(rep("a", 40)+rep("b", 40))) assertAlmostEqual(t, sm.Ratio(), 0.994, 3) assertEqual(t, sm.GetOpCodes(), []OpCode{{'e', 0, 40, 0, 40}, {'d', 40, 41, 40, 40}, {'e', 41, 81, 40, 80}}) } func TestWithAsciiBJunk(t *testing.T) { isJunk := func(s string) bool { return s == " " } sm := NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)), splitChars(rep("a", 44)+rep("b", 40)), true, isJunk) assertEqual(t, sm.bJunk, map[string]struct{}{}) sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)), splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk) assertEqual(t, sm.bJunk, map[string]struct{}{" ": {}}) isJunk = func(s string) bool { return s == " " || s == "b" } sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)), splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk) assertEqual(t, sm.bJunk, map[string]struct{}{" ": {}, "b": {}}) } func TestSFBugsRatioForNullSeqn(t *testing.T) { sm := NewMatcher(nil, nil) assertEqual(t, sm.Ratio(), 1.0) assertEqual(t, sm.QuickRatio(), 1.0) assertEqual(t, sm.RealQuickRatio(), 1.0) } func TestSFBugsComparingEmptyLists(t *testing.T) { groups := NewMatcher(nil, nil).GetGroupedOpCodes(-1) assertEqual(t, len(groups), 0) diff := UnifiedDiff{ FromFile: "Original", ToFile: "Current", Context: 3, } result, err := GetUnifiedDiffString(diff) assertEqual(t, err, nil) assertEqual(t, result, "") } func TestOutputFormatRangeFormatUnified(t *testing.T) { // Per the diff spec at http://www.unix.org/single_unix_specification/ // // Each field shall be of the form: // %1d", if the range contains exactly one line, // and: // "%1d,%1d", , otherwise. // If a range is empty, its beginning line number shall be the number of // the line just before the range, or 0 if the empty range starts the file. fm := formatRangeUnified assertEqual(t, fm(3, 3), "3,0") assertEqual(t, fm(3, 4), "4") assertEqual(t, fm(3, 5), "4,2") assertEqual(t, fm(3, 6), "4,3") assertEqual(t, fm(0, 0), "0,0") } func TestSplitLines(t *testing.T) { allTests := []struct { input string want []string }{ {"foo", []string{"foo\n"}}, {"foo\nbar", []string{"foo\n", "bar\n"}}, {"foo\nbar\n", []string{"foo\n", "bar\n", "\n"}}, } for _, test := range allTests { assertEqual(t, SplitLines(test.input), test.want) } } func benchmarkSplitLines(b *testing.B, count int) { str := strings.Repeat("foo\n", count) b.ResetTimer() n := 0 for i := 0; i < b.N; i++ { n += len(SplitLines(str)) } } func BenchmarkSplitLines100(b *testing.B) { benchmarkSplitLines(b, 100) } func BenchmarkSplitLines10000(b *testing.B) { benchmarkSplitLines(b, 10000) } client_golang-1.21.1/prometheus/internal/go_collector_options.go000066400000000000000000000024131476160432400251740ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package internal import "regexp" type GoCollectorRule struct { Matcher *regexp.Regexp Deny bool } // GoCollectorOptions should not be used be directly by anything, except `collectors` package. // Use it via collectors package instead. See issue // https://github.com/prometheus/client_golang/issues/1030. // // This is internal, so external users only can use it via `collector.WithGoCollector*` methods type GoCollectorOptions struct { DisableMemStatsLikeMetrics bool RuntimeMetricSumForHist map[string]string RuntimeMetricRules []GoCollectorRule } var GoCollectorDefaultRuntimeMetrics = regexp.MustCompile(`/gc/gogc:percent|/gc/gomemlimit:bytes|/sched/gomaxprocs:threads`) client_golang-1.21.1/prometheus/internal/go_runtime_metrics.go000066400000000000000000000114701476160432400246470ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build go1.17 // +build go1.17 package internal import ( "math" "path" "runtime/metrics" "strings" "github.com/prometheus/common/model" ) // RuntimeMetricsToProm produces a Prometheus metric name from a runtime/metrics // metric description and validates whether the metric is suitable for integration // with Prometheus. // // Returns false if a name could not be produced, or if Prometheus does not understand // the runtime/metrics Kind. // // Note that the main reason a name couldn't be produced is if the runtime/metrics // package exports a name with characters outside the valid Prometheus metric name // character set. This is theoretically possible, but should never happen in practice. // Still, don't rely on it. func RuntimeMetricsToProm(d *metrics.Description) (string, string, string, bool) { namespace := "go" comp := strings.SplitN(d.Name, ":", 2) key := comp[0] unit := comp[1] // The last path element in the key is the name, // the rest is the subsystem. subsystem := path.Dir(key[1:] /* remove leading / */) name := path.Base(key) // subsystem is translated by replacing all / and - with _. subsystem = strings.ReplaceAll(subsystem, "/", "_") subsystem = strings.ReplaceAll(subsystem, "-", "_") // unit is translated assuming that the unit contains no // non-ASCII characters. unit = strings.ReplaceAll(unit, "-", "_") unit = strings.ReplaceAll(unit, "*", "_") unit = strings.ReplaceAll(unit, "/", "_per_") // name has - replaced with _ and is concatenated with the unit and // other data. name = strings.ReplaceAll(name, "-", "_") name += "_" + unit if d.Cumulative && d.Kind != metrics.KindFloat64Histogram { name += "_total" } // Our current conversion moves to legacy naming, so use legacy validation. valid := model.IsValidLegacyMetricName(namespace + "_" + subsystem + "_" + name) switch d.Kind { case metrics.KindUint64: case metrics.KindFloat64: case metrics.KindFloat64Histogram: default: valid = false } return namespace, subsystem, name, valid } // RuntimeMetricsBucketsForUnit takes a set of buckets obtained for a runtime/metrics histogram // type (so, lower-bound inclusive) and a unit from a runtime/metrics name, and produces // a reduced set of buckets. This function always removes any -Inf bucket as it's represented // as the bottom-most upper-bound inclusive bucket in Prometheus. func RuntimeMetricsBucketsForUnit(buckets []float64, unit string) []float64 { switch unit { case "bytes": // Re-bucket as powers of 2. return reBucketExp(buckets, 2) case "seconds": // Re-bucket as powers of 10 and then merge all buckets greater // than 1 second into the +Inf bucket. b := reBucketExp(buckets, 10) for i := range b { if b[i] <= 1 { continue } b[i] = math.Inf(1) b = b[:i+1] break } return b } return buckets } // reBucketExp takes a list of bucket boundaries (lower bound inclusive) and // downsamples the buckets to those a multiple of base apart. The end result // is a roughly exponential (in many cases, perfectly exponential) bucketing // scheme. func reBucketExp(buckets []float64, base float64) []float64 { bucket := buckets[0] var newBuckets []float64 // We may see a -Inf here, in which case, add it and skip it // since we risk producing NaNs otherwise. // // We need to preserve -Inf values to maintain runtime/metrics // conventions. We'll strip it out later. if bucket == math.Inf(-1) { newBuckets = append(newBuckets, bucket) buckets = buckets[1:] bucket = buckets[0] } // From now on, bucket should always have a non-Inf value because // Infs are only ever at the ends of the bucket lists, so // arithmetic operations on it are non-NaN. for i := 1; i < len(buckets); i++ { if bucket >= 0 && buckets[i] < bucket*base { // The next bucket we want to include is at least bucket*base. continue } else if bucket < 0 && buckets[i] < bucket/base { // In this case the bucket we're targeting is negative, and since // we're ascending through buckets here, we need to divide to get // closer to zero exponentially. continue } // The +Inf bucket will always be the last one, and we'll always // end up including it here because bucket newBuckets = append(newBuckets, bucket) bucket = buckets[i] } return append(newBuckets, bucket) } client_golang-1.21.1/prometheus/internal/go_runtime_metrics_test.go000066400000000000000000000044351476160432400257110ustar00rootroot00000000000000// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build go1.17 // +build go1.17 package internal import ( "runtime/metrics" "testing" ) func TestRuntimeMetricsToProm(t *testing.T) { tests := []struct { got metrics.Description expect string }{ { metrics.Description{ Name: "/memory/live:bytes", Kind: metrics.KindUint64, }, "go_memory_live_bytes", }, { metrics.Description{ Name: "/memory/allocs:bytes", Kind: metrics.KindUint64, Cumulative: true, }, "go_memory_allocs_bytes_total", }, { metrics.Description{ Name: "/memory/alloc-rate:bytes/second", Kind: metrics.KindFloat64, }, "go_memory_alloc_rate_bytes_per_second", }, { metrics.Description{ Name: "/gc/time:cpu*seconds", Kind: metrics.KindFloat64, Cumulative: true, }, "go_gc_time_cpu_seconds_total", }, { metrics.Description{ Name: "/this/is/a/very/deep/metric:metrics", Kind: metrics.KindFloat64, }, "go_this_is_a_very_deep_metric_metrics", }, { metrics.Description{ Name: "/this*is*an*invalid...:Β΅name", Kind: metrics.KindUint64, }, "", }, { metrics.Description{ Name: "/this/is/a/valid/name:objects", Kind: metrics.KindBad, }, "", }, } for _, test := range tests { ns, ss, n, ok := RuntimeMetricsToProm(&test.got) name := ns + "_" + ss + "_" + n if test.expect == "" && ok { t.Errorf("bad input expected a bad output: input %s, got %s", test.got.Name, name) continue } if test.expect != "" && !ok { t.Errorf("unexpected bad output on good input: input %s", test.got.Name) continue } if test.expect != "" && name != test.expect { t.Errorf("expected %s, got %s", test.expect, name) continue } } } client_golang-1.21.1/prometheus/internal/metric.go000066400000000000000000000057711476160432400222430ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package internal import ( "sort" dto "github.com/prometheus/client_model/go" ) // LabelPairSorter implements sort.Interface. It is used to sort a slice of // dto.LabelPair pointers. type LabelPairSorter []*dto.LabelPair func (s LabelPairSorter) Len() int { return len(s) } func (s LabelPairSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s LabelPairSorter) Less(i, j int) bool { return s[i].GetName() < s[j].GetName() } // MetricSorter is a sortable slice of *dto.Metric. type MetricSorter []*dto.Metric func (s MetricSorter) Len() int { return len(s) } func (s MetricSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s MetricSorter) Less(i, j int) bool { if len(s[i].Label) != len(s[j].Label) { // This should not happen. The metrics are // inconsistent. However, we have to deal with the fact, as // people might use custom collectors or metric family injection // to create inconsistent metrics. So let's simply compare the // number of labels in this case. That will still yield // reproducible sorting. return len(s[i].Label) < len(s[j].Label) } for n, lp := range s[i].Label { vi := lp.GetValue() vj := s[j].Label[n].GetValue() if vi != vj { return vi < vj } } // We should never arrive here. Multiple metrics with the same // label set in the same scrape will lead to undefined ingestion // behavior. However, as above, we have to provide stable sorting // here, even for inconsistent metrics. So sort equal metrics // by their timestamp, with missing timestamps (implying "now") // coming last. if s[i].TimestampMs == nil { return false } if s[j].TimestampMs == nil { return true } return s[i].GetTimestampMs() < s[j].GetTimestampMs() } // NormalizeMetricFamilies returns a MetricFamily slice with empty // MetricFamilies pruned and the remaining MetricFamilies sorted by name within // the slice, with the contained Metrics sorted within each MetricFamily. func NormalizeMetricFamilies(metricFamiliesByName map[string]*dto.MetricFamily) []*dto.MetricFamily { for _, mf := range metricFamiliesByName { sort.Sort(MetricSorter(mf.Metric)) } names := make([]string, 0, len(metricFamiliesByName)) for name, mf := range metricFamiliesByName { if len(mf.Metric) > 0 { names = append(names, name) } } sort.Strings(names) result := make([]*dto.MetricFamily, 0, len(names)) for _, name := range names { result = append(result, metricFamiliesByName[name]) } return result } client_golang-1.21.1/prometheus/labels.go000066400000000000000000000120131476160432400203710ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "errors" "fmt" "strings" "unicode/utf8" "github.com/prometheus/common/model" ) // Labels represents a collection of label name -> value mappings. This type is // commonly used with the With(Labels) and GetMetricWith(Labels) methods of // metric vector Collectors, e.g.: // // myVec.With(Labels{"code": "404", "method": "GET"}).Add(42) // // The other use-case is the specification of constant label pairs in Opts or to // create a Desc. type Labels map[string]string // LabelConstraint normalizes label values. type LabelConstraint func(string) string // ConstrainedLabels represents a label name and its constrain function // to normalize label values. This type is commonly used when constructing // metric vector Collectors. type ConstrainedLabel struct { Name string Constraint LabelConstraint } // ConstrainableLabels is an interface that allows creating of labels that can // be optionally constrained. // // prometheus.V2().NewCounterVec(CounterVecOpts{ // CounterOpts: {...}, // Usual CounterOpts fields // VariableLabels: []ConstrainedLabels{ // {Name: "A"}, // {Name: "B", Constraint: func(v string) string { ... }}, // }, // }) type ConstrainableLabels interface { compile() *compiledLabels labelNames() []string } // ConstrainedLabels represents a collection of label name -> constrain function // to normalize label values. This type is commonly used when constructing // metric vector Collectors. type ConstrainedLabels []ConstrainedLabel func (cls ConstrainedLabels) compile() *compiledLabels { compiled := &compiledLabels{ names: make([]string, len(cls)), labelConstraints: map[string]LabelConstraint{}, } for i, label := range cls { compiled.names[i] = label.Name if label.Constraint != nil { compiled.labelConstraints[label.Name] = label.Constraint } } return compiled } func (cls ConstrainedLabels) labelNames() []string { names := make([]string, len(cls)) for i, label := range cls { names[i] = label.Name } return names } // UnconstrainedLabels represents collection of label without any constraint on // their value. Thus, it is simply a collection of label names. // // UnconstrainedLabels([]string{ "A", "B" }) // // is equivalent to // // ConstrainedLabels { // { Name: "A" }, // { Name: "B" }, // } type UnconstrainedLabels []string func (uls UnconstrainedLabels) compile() *compiledLabels { return &compiledLabels{ names: uls, } } func (uls UnconstrainedLabels) labelNames() []string { return uls } type compiledLabels struct { names []string labelConstraints map[string]LabelConstraint } func (cls *compiledLabels) compile() *compiledLabels { return cls } func (cls *compiledLabels) labelNames() []string { return cls.names } func (cls *compiledLabels) constrain(labelName, value string) string { if fn, ok := cls.labelConstraints[labelName]; ok && fn != nil { return fn(value) } return value } // reservedLabelPrefix is a prefix which is not legal in user-supplied // label names. const reservedLabelPrefix = "__" var errInconsistentCardinality = errors.New("inconsistent label cardinality") func makeInconsistentCardinalityError(fqName string, labels, labelValues []string) error { return fmt.Errorf( "%w: %q has %d variable labels named %q but %d values %q were provided", errInconsistentCardinality, fqName, len(labels), labels, len(labelValues), labelValues, ) } func validateValuesInLabels(labels Labels, expectedNumberOfValues int) error { if len(labels) != expectedNumberOfValues { return fmt.Errorf( "%w: expected %d label values but got %d in %#v", errInconsistentCardinality, expectedNumberOfValues, len(labels), labels, ) } for name, val := range labels { if !utf8.ValidString(val) { return fmt.Errorf("label %s: value %q is not valid UTF-8", name, val) } } return nil } func validateLabelValues(vals []string, expectedNumberOfValues int) error { if len(vals) != expectedNumberOfValues { // The call below makes vals escape, copy them to avoid that. vals := append([]string(nil), vals...) return fmt.Errorf( "%w: expected %d label values but got %d in %#v", errInconsistentCardinality, expectedNumberOfValues, len(vals), vals, ) } for _, val := range vals { if !utf8.ValidString(val) { return fmt.Errorf("label value %q is not valid UTF-8", val) } } return nil } func checkLabelName(l string) bool { return model.LabelName(l).IsValid() && !strings.HasPrefix(l, reservedLabelPrefix) } client_golang-1.21.1/prometheus/metric.go000066400000000000000000000217731476160432400204270ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "errors" "math" "sort" "strings" "time" dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/model" "google.golang.org/protobuf/proto" ) var separatorByteSlice = []byte{model.SeparatorByte} // For convenient use with xxhash. // A Metric models a single sample value with its meta data being exported to // Prometheus. Implementations of Metric in this package are Gauge, Counter, // Histogram, Summary, and Untyped. type Metric interface { // Desc returns the descriptor for the Metric. This method idempotently // returns the same descriptor throughout the lifetime of the // Metric. The returned descriptor is immutable by contract. A Metric // unable to describe itself must return an invalid descriptor (created // with NewInvalidDesc). Desc() *Desc // Write encodes the Metric into a "Metric" Protocol Buffer data // transmission object. // // Metric implementations must observe concurrency safety as reads of // this metric may occur at any time, and any blocking occurs at the // expense of total performance of rendering all registered // metrics. Ideally, Metric implementations should support concurrent // readers. // // While populating dto.Metric, it is the responsibility of the // implementation to ensure validity of the Metric protobuf (like valid // UTF-8 strings or syntactically valid metric and label names). It is // recommended to sort labels lexicographically. Callers of Write should // still make sure of sorting if they depend on it. Write(*dto.Metric) error // TODO(beorn7): The original rationale of passing in a pre-allocated // dto.Metric protobuf to save allocations has disappeared. The // signature of this method should be changed to "Write() (*dto.Metric, // error)". } // Opts bundles the options for creating most Metric types. Each metric // implementation XXX has its own XXXOpts type, but in most cases, it is just // an alias of this type (which might change when the requirement arises.) // // It is mandatory to set Name to a non-empty string. All other fields are // optional and can safely be left at their zero value, although it is strongly // encouraged to set a Help string. type Opts struct { // Namespace, Subsystem, and Name are components of the fully-qualified // name of the Metric (created by joining these components with // "_"). Only Name is mandatory, the others merely help structuring the // name. Note that the fully-qualified name of the metric must be a // valid Prometheus metric name. Namespace string Subsystem string Name string // Help provides information about this metric. // // Metrics with the same fully-qualified name must have the same Help // string. Help string // ConstLabels are used to attach fixed labels to this metric. Metrics // with the same fully-qualified name must have the same label names in // their ConstLabels. // // ConstLabels are only used rarely. In particular, do not use them to // attach the same labels to all your metrics. Those use cases are // better covered by target labels set by the scraping Prometheus // server, or by one specific metric (e.g. a build_info or a // machine_role metric). See also // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels ConstLabels Labels // now is for testing purposes, by default it's time.Now. now func() time.Time } // BuildFQName joins the given three name components by "_". Empty name // components are ignored. If the name parameter itself is empty, an empty // string is returned, no matter what. Metric implementations included in this // library use this function internally to generate the fully-qualified metric // name from the name component in their Opts. Users of the library will only // need this function if they implement their own Metric or instantiate a Desc // (with NewDesc) directly. func BuildFQName(namespace, subsystem, name string) string { if name == "" { return "" } sb := strings.Builder{} sb.Grow(len(namespace) + len(subsystem) + len(name) + 2) if namespace != "" { sb.WriteString(namespace) sb.WriteString("_") } if subsystem != "" { sb.WriteString(subsystem) sb.WriteString("_") } sb.WriteString(name) return sb.String() } type invalidMetric struct { desc *Desc err error } // NewInvalidMetric returns a metric whose Write method always returns the // provided error. It is useful if a Collector finds itself unable to collect // a metric and wishes to report an error to the registry. func NewInvalidMetric(desc *Desc, err error) Metric { return &invalidMetric{desc, err} } func (m *invalidMetric) Desc() *Desc { return m.desc } func (m *invalidMetric) Write(*dto.Metric) error { return m.err } type timestampedMetric struct { Metric t time.Time } func (m timestampedMetric) Write(pb *dto.Metric) error { e := m.Metric.Write(pb) pb.TimestampMs = proto.Int64(m.t.Unix()*1000 + int64(m.t.Nanosecond()/1000000)) return e } // NewMetricWithTimestamp returns a new Metric wrapping the provided Metric in a // way that it has an explicit timestamp set to the provided Time. This is only // useful in rare cases as the timestamp of a Prometheus metric should usually // be set by the Prometheus server during scraping. Exceptions include mirroring // metrics with given timestamps from other metric // sources. // // NewMetricWithTimestamp works best with MustNewConstMetric, // MustNewConstHistogram, and MustNewConstSummary, see example. // // Currently, the exposition formats used by Prometheus are limited to // millisecond resolution. Thus, the provided time will be rounded down to the // next full millisecond value. func NewMetricWithTimestamp(t time.Time, m Metric) Metric { return timestampedMetric{Metric: m, t: t} } type withExemplarsMetric struct { Metric exemplars []*dto.Exemplar } func (m *withExemplarsMetric) Write(pb *dto.Metric) error { if err := m.Metric.Write(pb); err != nil { return err } switch { case pb.Counter != nil: pb.Counter.Exemplar = m.exemplars[len(m.exemplars)-1] case pb.Histogram != nil: for _, e := range m.exemplars { // pb.Histogram.Bucket are sorted by UpperBound. i := sort.Search(len(pb.Histogram.Bucket), func(i int) bool { return pb.Histogram.Bucket[i].GetUpperBound() >= e.GetValue() }) if i < len(pb.Histogram.Bucket) { pb.Histogram.Bucket[i].Exemplar = e } else { // The +Inf bucket should be explicitly added if there is an exemplar for it, similar to non-const histogram logic in https://github.com/prometheus/client_golang/blob/main/prometheus/histogram.go#L357-L365. b := &dto.Bucket{ CumulativeCount: proto.Uint64(pb.Histogram.GetSampleCount()), UpperBound: proto.Float64(math.Inf(1)), Exemplar: e, } pb.Histogram.Bucket = append(pb.Histogram.Bucket, b) } } default: // TODO(bwplotka): Implement Gauge? return errors.New("cannot inject exemplar into Gauge, Summary or Untyped") } return nil } // Exemplar is easier to use, user-facing representation of *dto.Exemplar. type Exemplar struct { Value float64 Labels Labels // Optional. // Default value (time.Time{}) indicates its empty, which should be // understood as time.Now() time at the moment of creation of metric. Timestamp time.Time } // NewMetricWithExemplars returns a new Metric wrapping the provided Metric with given // exemplars. Exemplars are validated. // // Only last applicable exemplar is injected from the list. // For example for Counter it means last exemplar is injected. // For Histogram, it means last applicable exemplar for each bucket is injected. // // NewMetricWithExemplars works best with MustNewConstMetric and // MustNewConstHistogram, see example. func NewMetricWithExemplars(m Metric, exemplars ...Exemplar) (Metric, error) { if len(exemplars) == 0 { return nil, errors.New("no exemplar was passed for NewMetricWithExemplars") } var ( now = time.Now() exs = make([]*dto.Exemplar, len(exemplars)) err error ) for i, e := range exemplars { ts := e.Timestamp if ts.IsZero() { ts = now } exs[i], err = newExemplar(e.Value, ts, e.Labels) if err != nil { return nil, err } } return &withExemplarsMetric{Metric: m, exemplars: exs}, nil } // MustNewMetricWithExemplars is a version of NewMetricWithExemplars that panics where // NewMetricWithExemplars would have returned an error. func MustNewMetricWithExemplars(m Metric, exemplars ...Exemplar) Metric { ret, err := NewMetricWithExemplars(m, exemplars...) if err != nil { panic(err) } return ret } client_golang-1.21.1/prometheus/metric_test.go000066400000000000000000000056511476160432400214630ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "math" "testing" dto "github.com/prometheus/client_model/go" "google.golang.org/protobuf/proto" ) func TestBuildFQName(t *testing.T) { scenarios := []struct{ namespace, subsystem, name, result string }{ {"a", "b", "c", "a_b_c"}, {"", "b", "c", "b_c"}, {"a", "", "c", "a_c"}, {"", "", "c", "c"}, {"a", "b", "", ""}, {"a", "", "", ""}, {"", "b", "", ""}, {" ", "", "", ""}, } for i, s := range scenarios { if want, got := s.result, BuildFQName(s.namespace, s.subsystem, s.name); want != got { t.Errorf("%d. want %s, got %s", i, want, got) } } } func TestWithExemplarsMetric(t *testing.T) { t.Run("histogram", func(t *testing.T) { // Create a constant histogram from values we got from a 3rd party telemetry system. h := MustNewConstHistogram( NewDesc("http_request_duration_seconds", "A histogram of the HTTP request durations.", nil, nil), 4711, 403.34, // Four buckets, but we expect five as the +Inf bucket will be created if we see value outside of those buckets. map[float64]uint64{25: 121, 50: 2403, 100: 3221, 200: 4233}, ) m := &withExemplarsMetric{Metric: h, exemplars: []*dto.Exemplar{ {Value: proto.Float64(2000.0)}, // Unordered exemplars. {Value: proto.Float64(500.0)}, {Value: proto.Float64(42.0)}, {Value: proto.Float64(157.0)}, {Value: proto.Float64(100.0)}, {Value: proto.Float64(89.0)}, {Value: proto.Float64(24.0)}, {Value: proto.Float64(25.1)}, }} metric := dto.Metric{} if err := m.Write(&metric); err != nil { t.Fatal(err) } if want, got := 5, len(metric.GetHistogram().Bucket); want != got { t.Errorf("want %v, got %v", want, got) } expectedExemplarVals := []float64{24.0, 25.1, 89.0, 157.0, 500.0} for i, b := range metric.GetHistogram().Bucket { if b.Exemplar == nil { t.Errorf("Expected exemplar for bucket %v, got nil", i) } if want, got := expectedExemplarVals[i], *metric.GetHistogram().Bucket[i].Exemplar.Value; want != got { t.Errorf("%v: want %v, got %v", i, want, got) } } infBucket := metric.GetHistogram().Bucket[len(metric.GetHistogram().Bucket)-1] if want, got := math.Inf(1), infBucket.GetUpperBound(); want != got { t.Errorf("want %v, got %v", want, got) } if want, got := uint64(4711), infBucket.GetCumulativeCount(); want != got { t.Errorf("want %v, got %v", want, got) } }) } client_golang-1.21.1/prometheus/num_threads.go000066400000000000000000000015061476160432400214450ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build !js || wasm // +build !js wasm package prometheus import "runtime" // getRuntimeNumThreads returns the number of open OS threads. func getRuntimeNumThreads() float64 { n, _ := runtime.ThreadCreateProfile(nil) return float64(n) } client_golang-1.21.1/prometheus/num_threads_gopherjs.go000066400000000000000000000014011476160432400233400ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build js && !wasm // +build js,!wasm package prometheus // getRuntimeNumThreads returns the number of open OS threads. func getRuntimeNumThreads() float64 { return 1 } client_golang-1.21.1/prometheus/observer.go000066400000000000000000000050271476160432400207650ustar00rootroot00000000000000// Copyright 2017 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus // Observer is the interface that wraps the Observe method, which is used by // Histogram and Summary to add observations. type Observer interface { Observe(float64) } // The ObserverFunc type is an adapter to allow the use of ordinary // functions as Observers. If f is a function with the appropriate // signature, ObserverFunc(f) is an Observer that calls f. // // This adapter is usually used in connection with the Timer type, and there are // two general use cases: // // The most common one is to use a Gauge as the Observer for a Timer. // See the "Gauge" Timer example. // // The more advanced use case is to create a function that dynamically decides // which Observer to use for observing the duration. See the "Complex" Timer // example. type ObserverFunc func(float64) // Observe calls f(value). It implements Observer. func (f ObserverFunc) Observe(value float64) { f(value) } // ObserverVec is an interface implemented by `HistogramVec` and `SummaryVec`. type ObserverVec interface { GetMetricWith(Labels) (Observer, error) GetMetricWithLabelValues(lvs ...string) (Observer, error) With(Labels) Observer WithLabelValues(...string) Observer CurryWith(Labels) (ObserverVec, error) MustCurryWith(Labels) ObserverVec Collector } // ExemplarObserver is implemented by Observers that offer the option of // observing a value together with an exemplar. Its ObserveWithExemplar method // works like the Observe method of an Observer but also replaces the currently // saved exemplar (if any) with a new one, created from the provided value, the // current time as timestamp, and the provided Labels. Empty Labels will lead to // a valid (label-less) exemplar. But if Labels is nil, the current exemplar is // left in place. ObserveWithExemplar panics if any of the provided labels are // invalid or if the provided labels contain more than 128 runes in total. type ExemplarObserver interface { ObserveWithExemplar(value float64, exemplar Labels) } client_golang-1.21.1/prometheus/process_collector.go000066400000000000000000000121731476160432400226620ustar00rootroot00000000000000// Copyright 2015 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "errors" "fmt" "os" "strconv" "strings" ) type processCollector struct { collectFn func(chan<- Metric) describeFn func(chan<- *Desc) pidFn func() (int, error) reportErrors bool cpuTotal *Desc openFDs, maxFDs *Desc vsize, maxVsize *Desc rss *Desc startTime *Desc inBytes, outBytes *Desc } // ProcessCollectorOpts defines the behavior of a process metrics collector // created with NewProcessCollector. type ProcessCollectorOpts struct { // PidFn returns the PID of the process the collector collects metrics // for. It is called upon each collection. By default, the PID of the // current process is used, as determined on construction time by // calling os.Getpid(). PidFn func() (int, error) // If non-empty, each of the collected metrics is prefixed by the // provided string and an underscore ("_"). Namespace string // If true, any error encountered during collection is reported as an // invalid metric (see NewInvalidMetric). Otherwise, errors are ignored // and the collected metrics will be incomplete. (Possibly, no metrics // will be collected at all.) While that's usually not desired, it is // appropriate for the common "mix-in" of process metrics, where process // metrics are nice to have, but failing to collect them should not // disrupt the collection of the remaining metrics. ReportErrors bool } // NewProcessCollector is the obsolete version of collectors.NewProcessCollector. // See there for documentation. // // Deprecated: Use collectors.NewProcessCollector instead. func NewProcessCollector(opts ProcessCollectorOpts) Collector { ns := "" if len(opts.Namespace) > 0 { ns = opts.Namespace + "_" } c := &processCollector{ reportErrors: opts.ReportErrors, cpuTotal: NewDesc( ns+"process_cpu_seconds_total", "Total user and system CPU time spent in seconds.", nil, nil, ), openFDs: NewDesc( ns+"process_open_fds", "Number of open file descriptors.", nil, nil, ), maxFDs: NewDesc( ns+"process_max_fds", "Maximum number of open file descriptors.", nil, nil, ), vsize: NewDesc( ns+"process_virtual_memory_bytes", "Virtual memory size in bytes.", nil, nil, ), maxVsize: NewDesc( ns+"process_virtual_memory_max_bytes", "Maximum amount of virtual memory available in bytes.", nil, nil, ), rss: NewDesc( ns+"process_resident_memory_bytes", "Resident memory size in bytes.", nil, nil, ), startTime: NewDesc( ns+"process_start_time_seconds", "Start time of the process since unix epoch in seconds.", nil, nil, ), inBytes: NewDesc( ns+"process_network_receive_bytes_total", "Number of bytes received by the process over the network.", nil, nil, ), outBytes: NewDesc( ns+"process_network_transmit_bytes_total", "Number of bytes sent by the process over the network.", nil, nil, ), } if opts.PidFn == nil { c.pidFn = getPIDFn() } else { c.pidFn = opts.PidFn } // Set up process metric collection if supported by the runtime. if canCollectProcess() { c.collectFn = c.processCollect c.describeFn = c.describe } else { c.collectFn = c.errorCollectFn c.describeFn = c.errorDescribeFn } return c } func (c *processCollector) errorCollectFn(ch chan<- Metric) { c.reportError(ch, nil, errors.New("process metrics not supported on this platform")) } func (c *processCollector) errorDescribeFn(ch chan<- *Desc) { if c.reportErrors { ch <- NewInvalidDesc(errors.New("process metrics not supported on this platform")) } } // Collect returns the current state of all metrics of the collector. func (c *processCollector) Collect(ch chan<- Metric) { c.collectFn(ch) } // Describe returns all descriptions of the collector. func (c *processCollector) Describe(ch chan<- *Desc) { c.describeFn(ch) } func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) { if !c.reportErrors { return } if desc == nil { desc = NewInvalidDesc(err) } ch <- NewInvalidMetric(desc, err) } // NewPidFileFn returns a function that retrieves a pid from the specified file. // It is meant to be used for the PidFn field in ProcessCollectorOpts. func NewPidFileFn(pidFilePath string) func() (int, error) { return func() (int, error) { content, err := os.ReadFile(pidFilePath) if err != nil { return 0, fmt.Errorf("can't read pid file %q: %w", pidFilePath, err) } pid, err := strconv.Atoi(strings.TrimSpace(string(content))) if err != nil { return 0, fmt.Errorf("can't parse pid file %q: %w", pidFilePath, err) } return pid, nil } } client_golang-1.21.1/prometheus/process_collector_darwin.go000066400000000000000000000101471476160432400242250ustar00rootroot00000000000000// Copyright 2024 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build darwin && !ios package prometheus import ( "errors" "fmt" "os" "syscall" "time" "golang.org/x/sys/unix" ) // notImplementedErr is returned by stub functions that replace cgo functions, when cgo // isn't available. var notImplementedErr = errors.New("not implemented") type memoryInfo struct { vsize uint64 // Virtual memory size in bytes rss uint64 // Resident memory size in bytes } func canCollectProcess() bool { return true } func getSoftLimit(which int) (uint64, error) { rlimit := syscall.Rlimit{} if err := syscall.Getrlimit(which, &rlimit); err != nil { return 0, err } return rlimit.Cur, nil } func getOpenFileCount() (float64, error) { // Alternately, the undocumented proc_pidinfo(PROC_PIDLISTFDS) can be used to // return a list of open fds, but that requires a way to call C APIs. The // benefits, however, include fewer system calls and not failing when at the // open file soft limit. if dir, err := os.Open("/dev/fd"); err != nil { return 0.0, err } else { defer dir.Close() // Avoid ReadDir(), as it calls stat(2) on each descriptor. Not only is // that info not used, but KQUEUE descriptors fail stat(2), which causes // the whole method to fail. if names, err := dir.Readdirnames(0); err != nil { return 0.0, err } else { // Subtract 1 to ignore the open /dev/fd descriptor above. return float64(len(names) - 1), nil } } } func (c *processCollector) processCollect(ch chan<- Metric) { if procs, err := unix.SysctlKinfoProcSlice("kern.proc.pid", os.Getpid()); err == nil { if len(procs) == 1 { startTime := float64(procs[0].Proc.P_starttime.Nano() / 1e9) ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime) } else { err = fmt.Errorf("sysctl() returned %d proc structs (expected 1)", len(procs)) c.reportError(ch, c.startTime, err) } } else { c.reportError(ch, c.startTime, err) } // The proc structure returned by kern.proc.pid above has an Rusage member, // but it is not filled in, so it needs to be fetched by getrusage(2). For // that call, the UTime, STime, and Maxrss members are filled out, but not // Ixrss, Idrss, or Isrss for the memory usage. Memory stats will require // access to the C API to call task_info(TASK_BASIC_INFO). rusage := unix.Rusage{} if err := unix.Getrusage(syscall.RUSAGE_SELF, &rusage); err == nil { cpuTime := time.Duration(rusage.Stime.Nano() + rusage.Utime.Nano()).Seconds() ch <- MustNewConstMetric(c.cpuTotal, CounterValue, cpuTime) } else { c.reportError(ch, c.cpuTotal, err) } if memInfo, err := getMemory(); err == nil { ch <- MustNewConstMetric(c.rss, GaugeValue, float64(memInfo.rss)) ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(memInfo.vsize)) } else if !errors.Is(err, notImplementedErr) { // Don't report an error when support is not compiled in. c.reportError(ch, c.rss, err) c.reportError(ch, c.vsize, err) } if fds, err := getOpenFileCount(); err == nil { ch <- MustNewConstMetric(c.openFDs, GaugeValue, fds) } else { c.reportError(ch, c.openFDs, err) } if openFiles, err := getSoftLimit(syscall.RLIMIT_NOFILE); err == nil { ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(openFiles)) } else { c.reportError(ch, c.maxFDs, err) } if addressSpace, err := getSoftLimit(syscall.RLIMIT_AS); err == nil { ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(addressSpace)) } else { c.reportError(ch, c.maxVsize, err) } // TODO: socket(PF_SYSTEM) to fetch "com.apple.network.statistics" might // be able to get the per-process network send/receive counts. } client_golang-1.21.1/prometheus/process_collector_mem_cgo_darwin.c000066400000000000000000000057021476160432400255310ustar00rootroot00000000000000// Copyright 2024 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build darwin && !ios && cgo #include #include #include // The compiler warns that mach/shared_memory_server.h is deprecated, and to use // mach/shared_region.h instead. But that doesn't define // SHARED_DATA_REGION_SIZE or SHARED_TEXT_REGION_SIZE, so redefine them here and // avoid a warning message when running tests. #define GLOBAL_SHARED_TEXT_SEGMENT 0x90000000U #define SHARED_DATA_REGION_SIZE 0x10000000 #define SHARED_TEXT_REGION_SIZE 0x10000000 int get_memory_info(unsigned long long *rss, unsigned long long *vsize) { // This is lightly adapted from how ps(1) obtains its memory info. // https://github.com/apple-oss-distributions/adv_cmds/blob/8744084ea0ff41ca4bb96b0f9c22407d0e48e9b7/ps/tasks.c#L109 kern_return_t error; task_t task = MACH_PORT_NULL; mach_task_basic_info_data_t info; mach_msg_type_number_t info_count = MACH_TASK_BASIC_INFO_COUNT; error = task_info( mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t) &info, &info_count ); if( error != KERN_SUCCESS ) { return error; } *rss = info.resident_size; *vsize = info.virtual_size; { vm_region_basic_info_data_64_t b_info; mach_vm_address_t address = GLOBAL_SHARED_TEXT_SEGMENT; mach_vm_size_t size; mach_port_t object_name; /* * try to determine if this task has the split libraries * mapped in... if so, adjust its virtual size down by * the 2 segments that are used for split libraries */ info_count = VM_REGION_BASIC_INFO_COUNT_64; error = mach_vm_region( mach_task_self(), &address, &size, VM_REGION_BASIC_INFO_64, (vm_region_info_t) &b_info, &info_count, &object_name); if (error == KERN_SUCCESS) { if (b_info.reserved && size == (SHARED_TEXT_REGION_SIZE) && *vsize > (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE)) { *vsize -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE); } } } return 0; } client_golang-1.21.1/prometheus/process_collector_mem_cgo_darwin.go000066400000000000000000000030771476160432400257170ustar00rootroot00000000000000// Copyright 2024 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build darwin && !ios && cgo package prometheus /* int get_memory_info(unsigned long long *rss, unsigned long long *vs); */ import "C" import "fmt" func getMemory() (*memoryInfo, error) { var rss, vsize C.ulonglong if err := C.get_memory_info(&rss, &vsize); err != 0 { return nil, fmt.Errorf("task_info() failed with 0x%x", int(err)) } return &memoryInfo{vsize: uint64(vsize), rss: uint64(rss)}, nil } // describe returns all descriptions of the collector for Darwin. // Ensure that this list of descriptors is kept in sync with the metrics collected // in the processCollect method. Any changes to the metrics in processCollect // (such as adding or removing metrics) should be reflected in this list of descriptors. func (c *processCollector) describe(ch chan<- *Desc) { ch <- c.cpuTotal ch <- c.openFDs ch <- c.maxFDs ch <- c.maxVsize ch <- c.startTime ch <- c.rss ch <- c.vsize /* the process could be collected but not implemented yet ch <- c.inBytes ch <- c.outBytes */ } client_golang-1.21.1/prometheus/process_collector_mem_nocgo_darwin.go000066400000000000000000000024361476160432400262520ustar00rootroot00000000000000// Copyright 2024 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build darwin && !ios && !cgo package prometheus func getMemory() (*memoryInfo, error) { return nil, notImplementedErr } // describe returns all descriptions of the collector for Darwin. // Ensure that this list of descriptors is kept in sync with the metrics collected // in the processCollect method. Any changes to the metrics in processCollect // (such as adding or removing metrics) should be reflected in this list of descriptors. func (c *processCollector) describe(ch chan<- *Desc) { ch <- c.cpuTotal ch <- c.openFDs ch <- c.maxFDs ch <- c.maxVsize ch <- c.startTime /* the process could be collected but not implemented yet ch <- c.rss ch <- c.vsize ch <- c.inBytes ch <- c.outBytes */ } client_golang-1.21.1/prometheus/process_collector_not_supported.go000066400000000000000000000022701476160432400256440ustar00rootroot00000000000000// Copyright 2023 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build wasip1 || js || ios // +build wasip1 js ios package prometheus func canCollectProcess() bool { return false } func (c *processCollector) processCollect(ch chan<- Metric) { c.errorCollectFn(ch) } // describe returns all descriptions of the collector for wasip1 and js. // Ensure that this list of descriptors is kept in sync with the metrics collected // in the processCollect method. Any changes to the metrics in processCollect // (such as adding or removing metrics) should be reflected in this list of descriptors. func (c *processCollector) describe(ch chan<- *Desc) { c.errorDescribeFn(ch) } client_golang-1.21.1/prometheus/process_collector_procfsenabled.go000066400000000000000000000055701476160432400255540ustar00rootroot00000000000000// Copyright 2019 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build !windows && !js && !wasip1 && !darwin // +build !windows,!js,!wasip1,!darwin package prometheus import ( "github.com/prometheus/procfs" ) func canCollectProcess() bool { _, err := procfs.NewDefaultFS() return err == nil } func (c *processCollector) processCollect(ch chan<- Metric) { pid, err := c.pidFn() if err != nil { c.reportError(ch, nil, err) return } p, err := procfs.NewProc(pid) if err != nil { c.reportError(ch, nil, err) return } if stat, err := p.Stat(); err == nil { ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime()) ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory())) ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory())) if startTime, err := stat.StartTime(); err == nil { ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime) } else { c.reportError(ch, c.startTime, err) } } else { c.reportError(ch, nil, err) } if fds, err := p.FileDescriptorsLen(); err == nil { ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds)) } else { c.reportError(ch, c.openFDs, err) } if limits, err := p.Limits(); err == nil { ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles)) ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(limits.AddressSpace)) } else { c.reportError(ch, nil, err) } if netstat, err := p.Netstat(); err == nil { var inOctets, outOctets float64 if netstat.IpExt.InOctets != nil { inOctets = *netstat.IpExt.InOctets } if netstat.IpExt.OutOctets != nil { outOctets = *netstat.IpExt.OutOctets } ch <- MustNewConstMetric(c.inBytes, CounterValue, inOctets) ch <- MustNewConstMetric(c.outBytes, CounterValue, outOctets) } else { c.reportError(ch, nil, err) } } // describe returns all descriptions of the collector for others than windows, js, wasip1 and darwin. // Ensure that this list of descriptors is kept in sync with the metrics collected // in the processCollect method. Any changes to the metrics in processCollect // (such as adding or removing metrics) should be reflected in this list of descriptors. func (c *processCollector) describe(ch chan<- *Desc) { ch <- c.cpuTotal ch <- c.openFDs ch <- c.maxFDs ch <- c.vsize ch <- c.maxVsize ch <- c.rss ch <- c.startTime ch <- c.inBytes ch <- c.outBytes } client_golang-1.21.1/prometheus/process_collector_test.go000066400000000000000000000144661476160432400237300ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build linux // +build linux package prometheus import ( "bytes" "errors" "fmt" "os" "path/filepath" "regexp" "strings" "testing" "github.com/prometheus/common/expfmt" "github.com/prometheus/procfs" dto "github.com/prometheus/client_model/go" ) func TestProcessCollector(t *testing.T) { if _, err := procfs.Self(); err != nil { t.Skipf("skipping TestProcessCollector, procfs not available: %s", err) } registry := NewPedanticRegistry() if err := registry.Register(NewProcessCollector(ProcessCollectorOpts{})); err != nil { t.Fatal(err) } if err := registry.Register(NewProcessCollector(ProcessCollectorOpts{ PidFn: func() (int, error) { return os.Getpid(), nil }, Namespace: "foobar", ReportErrors: true, // No errors expected, just to see if none are reported. })); err != nil { t.Fatal(err) } mfs, err := registry.Gather() if err != nil { t.Fatal(err) } var buf bytes.Buffer for _, mf := range mfs { if _, err := expfmt.MetricFamilyToText(&buf, mf); err != nil { t.Fatal(err) } } for _, re := range []*regexp.Regexp{ regexp.MustCompile("\nprocess_cpu_seconds_total [0-9]"), regexp.MustCompile("\nprocess_max_fds [1-9]"), regexp.MustCompile("\nprocess_open_fds [1-9]"), regexp.MustCompile("\nprocess_virtual_memory_max_bytes (-1|[1-9])"), regexp.MustCompile("\nprocess_virtual_memory_bytes [1-9]"), regexp.MustCompile("\nprocess_resident_memory_bytes [1-9]"), regexp.MustCompile("\nprocess_start_time_seconds [0-9.]{10,}"), regexp.MustCompile("\nprocess_network_receive_bytes_total [0-9]+"), regexp.MustCompile("\nprocess_network_transmit_bytes_total [0-9]+"), regexp.MustCompile("\nfoobar_process_cpu_seconds_total [0-9]"), regexp.MustCompile("\nfoobar_process_max_fds [1-9]"), regexp.MustCompile("\nfoobar_process_open_fds [1-9]"), regexp.MustCompile("\nfoobar_process_virtual_memory_max_bytes (-1|[1-9])"), regexp.MustCompile("\nfoobar_process_virtual_memory_bytes [1-9]"), regexp.MustCompile("\nfoobar_process_resident_memory_bytes [1-9]"), regexp.MustCompile("\nfoobar_process_start_time_seconds [0-9.]{10,}"), regexp.MustCompile("\nfoobar_process_network_receive_bytes_total [0-9]+"), regexp.MustCompile("\nfoobar_process_network_transmit_bytes_total [0-9]+"), } { if !re.Match(buf.Bytes()) { t.Errorf("want body to match %s\n%s", re, buf.String()) } } brokenProcessCollector := NewProcessCollector(ProcessCollectorOpts{ PidFn: func() (int, error) { return 0, errors.New("boo") }, ReportErrors: true, }) ch := make(chan Metric) go func() { brokenProcessCollector.Collect(ch) close(ch) }() n := 0 for m := range ch { n++ pb := &dto.Metric{} err := m.Write(pb) if err == nil { t.Error("metric collected from broken process collector is unexpectedly valid") } } if n != 1 { t.Errorf("%d metrics collected, want 1", n) } } func TestNewPidFileFn(t *testing.T) { folderPath, err := os.Getwd() if err != nil { t.Error("failed to get current path") } mockPidFilePath := filepath.Join(folderPath, "mockPidFile") defer os.Remove(mockPidFilePath) testCases := []struct { mockPidFile func() expectedErrPrefix string expectedPid int desc string }{ { mockPidFile: func() { os.Remove(mockPidFilePath) }, expectedErrPrefix: "can't read pid file", expectedPid: 0, desc: "no existed pid file", }, { mockPidFile: func() { os.Remove(mockPidFilePath) f, _ := os.Create(mockPidFilePath) f.Write([]byte("abc")) f.Close() }, expectedErrPrefix: "can't parse pid file", expectedPid: 0, desc: "existed pid file, error pid number", }, { mockPidFile: func() { os.Remove(mockPidFilePath) f, _ := os.Create(mockPidFilePath) f.Write([]byte("123")) f.Close() }, expectedErrPrefix: "", expectedPid: 123, desc: "existed pid file, correct pid number", }, } for _, tc := range testCases { fn := NewPidFileFn(mockPidFilePath) if fn == nil { t.Error("Should not get nil PidFileFn") } tc.mockPidFile() if pid, err := fn(); pid != tc.expectedPid || (err != nil && !strings.HasPrefix(err.Error(), tc.expectedErrPrefix)) { fmt.Println(err.Error()) t.Error(tc.desc) } } } func TestDescribeAndCollectAlignment(t *testing.T) { collector := &processCollector{ pidFn: getPIDFn(), cpuTotal: NewDesc("cpu_total", "Total CPU usage", nil, nil), openFDs: NewDesc("open_fds", "Number of open file descriptors", nil, nil), maxFDs: NewDesc("max_fds", "Maximum file descriptors", nil, nil), vsize: NewDesc("vsize", "Virtual memory size", nil, nil), maxVsize: NewDesc("max_vsize", "Maximum virtual memory size", nil, nil), rss: NewDesc("rss", "Resident Set Size", nil, nil), startTime: NewDesc("start_time", "Process start time", nil, nil), inBytes: NewDesc("in_bytes", "Input bytes", nil, nil), outBytes: NewDesc("out_bytes", "Output bytes", nil, nil), } // Collect and get descriptors descCh := make(chan *Desc, 15) collector.describe(descCh) close(descCh) definedDescs := make(map[string]bool) for desc := range descCh { definedDescs[desc.String()] = true } // Collect and get metrics metricsCh := make(chan Metric, 15) collector.processCollect(metricsCh) close(metricsCh) collectedMetrics := make(map[string]bool) for metric := range metricsCh { collectedMetrics[metric.Desc().String()] = true } // Verify that all described metrics are collected for desc := range definedDescs { if !collectedMetrics[desc] { t.Errorf("Metric %s described but not collected", desc) } } // Verify that no extra metrics are collected for desc := range collectedMetrics { if !definedDescs[desc] { t.Errorf("Metric %s collected but not described", desc) } } } client_golang-1.21.1/prometheus/process_collector_windows.go000066400000000000000000000074371476160432400244430ustar00rootroot00000000000000// Copyright 2019 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "syscall" "unsafe" "golang.org/x/sys/windows" ) func canCollectProcess() bool { return true } var ( modpsapi = syscall.NewLazyDLL("psapi.dll") modkernel32 = syscall.NewLazyDLL("kernel32.dll") procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo") procGetProcessHandleCount = modkernel32.NewProc("GetProcessHandleCount") ) type processMemoryCounters struct { // System interface description // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-process_memory_counters_ex // Refer to the Golang internal implementation // https://golang.org/src/internal/syscall/windows/psapi_windows.go _ uint32 PageFaultCount uint32 PeakWorkingSetSize uintptr WorkingSetSize uintptr QuotaPeakPagedPoolUsage uintptr QuotaPagedPoolUsage uintptr QuotaPeakNonPagedPoolUsage uintptr QuotaNonPagedPoolUsage uintptr PagefileUsage uintptr PeakPagefileUsage uintptr PrivateUsage uintptr } func getProcessMemoryInfo(handle windows.Handle) (processMemoryCounters, error) { mem := processMemoryCounters{} r1, _, err := procGetProcessMemoryInfo.Call( uintptr(handle), uintptr(unsafe.Pointer(&mem)), uintptr(unsafe.Sizeof(mem)), ) if r1 != 1 { return mem, err } else { return mem, nil } } func getProcessHandleCount(handle windows.Handle) (uint32, error) { var count uint32 r1, _, err := procGetProcessHandleCount.Call( uintptr(handle), uintptr(unsafe.Pointer(&count)), ) if r1 != 1 { return 0, err } else { return count, nil } } func (c *processCollector) processCollect(ch chan<- Metric) { h := windows.CurrentProcess() var startTime, exitTime, kernelTime, userTime windows.Filetime err := windows.GetProcessTimes(h, &startTime, &exitTime, &kernelTime, &userTime) if err != nil { c.reportError(ch, nil, err) return } ch <- MustNewConstMetric(c.startTime, GaugeValue, float64(startTime.Nanoseconds()/1e9)) ch <- MustNewConstMetric(c.cpuTotal, CounterValue, fileTimeToSeconds(kernelTime)+fileTimeToSeconds(userTime)) mem, err := getProcessMemoryInfo(h) if err != nil { c.reportError(ch, nil, err) return } ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(mem.PrivateUsage)) ch <- MustNewConstMetric(c.rss, GaugeValue, float64(mem.WorkingSetSize)) handles, err := getProcessHandleCount(h) if err != nil { c.reportError(ch, nil, err) return } ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(handles)) ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(16*1024*1024)) // Windows has a hard-coded max limit, not per-process. } // describe returns all descriptions of the collector for windows. // Ensure that this list of descriptors is kept in sync with the metrics collected // in the processCollect method. Any changes to the metrics in processCollect // (such as adding or removing metrics) should be reflected in this list of descriptors. func (c *processCollector) describe(ch chan<- *Desc) { ch <- c.cpuTotal ch <- c.openFDs ch <- c.maxFDs ch <- c.vsize ch <- c.rss ch <- c.startTime } func fileTimeToSeconds(ft windows.Filetime) float64 { return float64(uint64(ft.HighDateTime)<<32+uint64(ft.LowDateTime)) / 1e7 } client_golang-1.21.1/prometheus/process_collector_windows_test.go000066400000000000000000000075571476160432400255050ustar00rootroot00000000000000// Copyright 2019 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "bytes" "os" "regexp" "testing" "github.com/prometheus/common/expfmt" ) func TestWindowsProcessCollector(t *testing.T) { registry := NewRegistry() if err := registry.Register(NewProcessCollector(ProcessCollectorOpts{})); err != nil { t.Fatal(err) } if err := registry.Register(NewProcessCollector(ProcessCollectorOpts{ PidFn: func() (int, error) { return os.Getpid(), nil }, Namespace: "foobar", ReportErrors: true, // No errors expected, just to see if none are reported. })); err != nil { t.Fatal(err) } mfs, err := registry.Gather() if err != nil { t.Fatal(err) } var buf bytes.Buffer for _, mf := range mfs { if _, err := expfmt.MetricFamilyToText(&buf, mf); err != nil { t.Fatal(err) } } for _, re := range []*regexp.Regexp{ regexp.MustCompile("\nprocess_cpu_seconds_total [0-9]"), regexp.MustCompile("\nprocess_max_fds [1-9]"), regexp.MustCompile("\nprocess_open_fds [1-9]"), regexp.MustCompile("\nprocess_virtual_memory_max_bytes (-1|[1-9])"), regexp.MustCompile("\nprocess_virtual_memory_bytes [1-9]"), regexp.MustCompile("\nprocess_resident_memory_bytes [1-9]"), regexp.MustCompile("\nprocess_start_time_seconds [0-9.]{10,}"), regexp.MustCompile("\nfoobar_process_cpu_seconds_total [0-9]"), regexp.MustCompile("\nfoobar_process_max_fds [1-9]"), regexp.MustCompile("\nfoobar_process_open_fds [1-9]"), regexp.MustCompile("\nfoobar_process_virtual_memory_max_bytes (-1|[1-9])"), regexp.MustCompile("\nfoobar_process_virtual_memory_bytes [1-9]"), regexp.MustCompile("\nfoobar_process_resident_memory_bytes [1-9]"), regexp.MustCompile("\nfoobar_process_start_time_seconds [0-9.]{10,}"), } { if !re.Match(buf.Bytes()) { t.Errorf("want body to match %s\n%s", re, buf.String()) } } } func TestWindowsDescribeAndCollectAlignment(t *testing.T) { collector := &processCollector{ pidFn: getPIDFn(), cpuTotal: NewDesc("cpu_total", "Total CPU usage", nil, nil), openFDs: NewDesc("open_fds", "Number of open file descriptors", nil, nil), maxFDs: NewDesc("max_fds", "Maximum file descriptors", nil, nil), vsize: NewDesc("vsize", "Virtual memory size", nil, nil), maxVsize: NewDesc("max_vsize", "Maximum virtual memory size", nil, nil), rss: NewDesc("rss", "Resident Set Size", nil, nil), startTime: NewDesc("start_time", "Process start time", nil, nil), inBytes: NewDesc("in_bytes", "Input bytes", nil, nil), outBytes: NewDesc("out_bytes", "Output bytes", nil, nil), } // Collect and get descriptors descCh := make(chan *Desc, 15) collector.describe(descCh) close(descCh) definedDescs := make(map[string]bool) for desc := range descCh { definedDescs[desc.String()] = true } // Collect and get metrics metricsCh := make(chan Metric, 15) collector.processCollect(metricsCh) close(metricsCh) collectedMetrics := make(map[string]bool) for metric := range metricsCh { collectedMetrics[metric.Desc().String()] = true } // Verify that all described metrics are collected for desc := range definedDescs { if !collectedMetrics[desc] { t.Errorf("Metric %s described but not collected", desc) } } // Verify that no extra metrics are collected for desc := range collectedMetrics { if !definedDescs[desc] { t.Errorf("Metric %s collected but not described", desc) } } } client_golang-1.21.1/prometheus/promauto/000077500000000000000000000000001476160432400204515ustar00rootroot00000000000000client_golang-1.21.1/prometheus/promauto/auto.go000066400000000000000000000360671476160432400217640ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package promauto provides alternative constructors for the fundamental // Prometheus metric types and their …Vec and …Func variants. The difference to // their counterparts in the prometheus package is that the promauto // constructors register the Collectors with a registry before returning them. // There are two sets of constructors. The constructors in the first set are // top-level functions, while the constructors in the other set are methods of // the Factory type. The top-level functions return Collectors registered with // the global registry (prometheus.DefaultRegisterer), while the methods return // Collectors registered with the registry the Factory was constructed with. All // constructors panic if the registration fails. // // The following example is a complete program to create a histogram of normally // distributed random numbers from the math/rand package: // // package main // // import ( // "math/rand" // "net/http" // // "github.com/prometheus/client_golang/prometheus" // "github.com/prometheus/client_golang/prometheus/promauto" // "github.com/prometheus/client_golang/prometheus/promhttp" // ) // // var histogram = promauto.NewHistogram(prometheus.HistogramOpts{ // Name: "random_numbers", // Help: "A histogram of normally distributed random numbers.", // Buckets: prometheus.LinearBuckets(-3, .1, 61), // }) // // func Random() { // for { // histogram.Observe(rand.NormFloat64()) // } // } // // func main() { // go Random() // http.Handle("/metrics", promhttp.Handler()) // http.ListenAndServe(":1971", nil) // } // // Prometheus's version of a minimal hello-world program: // // package main // // import ( // "fmt" // "net/http" // // "github.com/prometheus/client_golang/prometheus" // "github.com/prometheus/client_golang/prometheus/promauto" // "github.com/prometheus/client_golang/prometheus/promhttp" // ) // // func main() { // http.Handle("/", promhttp.InstrumentHandlerCounter( // promauto.NewCounterVec( // prometheus.CounterOpts{ // Name: "hello_requests_total", // Help: "Total number of hello-world requests by HTTP code.", // }, // []string{"code"}, // ), // http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // fmt.Fprint(w, "Hello, world!") // }), // )) // http.Handle("/metrics", promhttp.Handler()) // http.ListenAndServe(":1971", nil) // } // // A Factory is created with the With(prometheus.Registerer) function, which // enables two usage patterns. With(prometheus.Registerer) can be called once per // line: // // var ( // reg = prometheus.NewRegistry() // randomNumbers = promauto.With(reg).NewHistogram(prometheus.HistogramOpts{ // Name: "random_numbers", // Help: "A histogram of normally distributed random numbers.", // Buckets: prometheus.LinearBuckets(-3, .1, 61), // }) // requestCount = promauto.With(reg).NewCounterVec( // prometheus.CounterOpts{ // Name: "http_requests_total", // Help: "Total number of HTTP requests by status code and method.", // }, // []string{"code", "method"}, // ) // ) // // Or it can be used to create a Factory once to be used multiple times: // // var ( // reg = prometheus.NewRegistry() // factory = promauto.With(reg) // randomNumbers = factory.NewHistogram(prometheus.HistogramOpts{ // Name: "random_numbers", // Help: "A histogram of normally distributed random numbers.", // Buckets: prometheus.LinearBuckets(-3, .1, 61), // }) // requestCount = factory.NewCounterVec( // prometheus.CounterOpts{ // Name: "http_requests_total", // Help: "Total number of HTTP requests by status code and method.", // }, // []string{"code", "method"}, // ) // ) // // This appears very handy. So why are these constructors locked away in a // separate package? // // The main problem is that registration may fail, e.g. if a metric inconsistent // with or equal to the newly to be registered one is already registered. // Therefore, the Register method in the prometheus.Registerer interface returns // an error, and the same is the case for the top-level prometheus.Register // function that registers with the global registry. The prometheus package also // provides MustRegister versions for both. They panic if the registration // fails, and they clearly call this out by using the Must… idiom. Panicking is // problematic in this case because it doesn't just happen on input provided by // the caller that is invalid on its own. Things are a bit more subtle here: // Metric creation and registration tend to be spread widely over the // codebase. It can easily happen that an incompatible metric is added to an // unrelated part of the code, and suddenly code that used to work perfectly // fine starts to panic (provided that the registration of the newly added // metric happens before the registration of the previously existing // metric). This may come as an even bigger surprise with the global registry, // where simply importing another package can trigger a panic (if the newly // imported package registers metrics in its init function). At least, in the // prometheus package, creation of metrics and other collectors is separate from // registration. You first create the metric, and then you decide explicitly if // you want to register it with a local or the global registry, and if you want // to handle the error or risk a panic. With the constructors in the promauto // package, registration is automatic, and if it fails, it will always // panic. Furthermore, the constructors will often be called in the var section // of a file, which means that panicking will happen as a side effect of merely // importing a package. // // A separate package allows conservative users to entirely ignore it. And // whoever wants to use it will do so explicitly, with an opportunity to read // this warning. // // Enjoy promauto responsibly! package promauto import "github.com/prometheus/client_golang/prometheus" // NewCounter works like the function of the same name in the prometheus package // but it automatically registers the Counter with the // prometheus.DefaultRegisterer. If the registration fails, NewCounter panics. func NewCounter(opts prometheus.CounterOpts) prometheus.Counter { return With(prometheus.DefaultRegisterer).NewCounter(opts) } // NewCounterVec works like the function of the same name in the prometheus // package but it automatically registers the CounterVec with the // prometheus.DefaultRegisterer. If the registration fails, NewCounterVec // panics. func NewCounterVec(opts prometheus.CounterOpts, labelNames []string) *prometheus.CounterVec { return With(prometheus.DefaultRegisterer).NewCounterVec(opts, labelNames) } // NewCounterFunc works like the function of the same name in the prometheus // package but it automatically registers the CounterFunc with the // prometheus.DefaultRegisterer. If the registration fails, NewCounterFunc // panics. func NewCounterFunc(opts prometheus.CounterOpts, function func() float64) prometheus.CounterFunc { return With(prometheus.DefaultRegisterer).NewCounterFunc(opts, function) } // NewGauge works like the function of the same name in the prometheus package // but it automatically registers the Gauge with the // prometheus.DefaultRegisterer. If the registration fails, NewGauge panics. func NewGauge(opts prometheus.GaugeOpts) prometheus.Gauge { return With(prometheus.DefaultRegisterer).NewGauge(opts) } // NewGaugeVec works like the function of the same name in the prometheus // package but it automatically registers the GaugeVec with the // prometheus.DefaultRegisterer. If the registration fails, NewGaugeVec panics. func NewGaugeVec(opts prometheus.GaugeOpts, labelNames []string) *prometheus.GaugeVec { return With(prometheus.DefaultRegisterer).NewGaugeVec(opts, labelNames) } // NewGaugeFunc works like the function of the same name in the prometheus // package but it automatically registers the GaugeFunc with the // prometheus.DefaultRegisterer. If the registration fails, NewGaugeFunc panics. func NewGaugeFunc(opts prometheus.GaugeOpts, function func() float64) prometheus.GaugeFunc { return With(prometheus.DefaultRegisterer).NewGaugeFunc(opts, function) } // NewSummary works like the function of the same name in the prometheus package // but it automatically registers the Summary with the // prometheus.DefaultRegisterer. If the registration fails, NewSummary panics. func NewSummary(opts prometheus.SummaryOpts) prometheus.Summary { return With(prometheus.DefaultRegisterer).NewSummary(opts) } // NewSummaryVec works like the function of the same name in the prometheus // package but it automatically registers the SummaryVec with the // prometheus.DefaultRegisterer. If the registration fails, NewSummaryVec // panics. func NewSummaryVec(opts prometheus.SummaryOpts, labelNames []string) *prometheus.SummaryVec { return With(prometheus.DefaultRegisterer).NewSummaryVec(opts, labelNames) } // NewHistogram works like the function of the same name in the prometheus // package but it automatically registers the Histogram with the // prometheus.DefaultRegisterer. If the registration fails, NewHistogram panics. func NewHistogram(opts prometheus.HistogramOpts) prometheus.Histogram { return With(prometheus.DefaultRegisterer).NewHistogram(opts) } // NewHistogramVec works like the function of the same name in the prometheus // package but it automatically registers the HistogramVec with the // prometheus.DefaultRegisterer. If the registration fails, NewHistogramVec // panics. func NewHistogramVec(opts prometheus.HistogramOpts, labelNames []string) *prometheus.HistogramVec { return With(prometheus.DefaultRegisterer).NewHistogramVec(opts, labelNames) } // NewUntypedFunc works like the function of the same name in the prometheus // package but it automatically registers the UntypedFunc with the // prometheus.DefaultRegisterer. If the registration fails, NewUntypedFunc // panics. func NewUntypedFunc(opts prometheus.UntypedOpts, function func() float64) prometheus.UntypedFunc { return With(prometheus.DefaultRegisterer).NewUntypedFunc(opts, function) } // Factory provides factory methods to create Collectors that are automatically // registered with a Registerer. Create a Factory with the With function, // providing a Registerer to auto-register created Collectors with. The zero // value of a Factory creates Collectors that are not registered with any // Registerer. All methods of the Factory panic if the registration fails. type Factory struct { r prometheus.Registerer } // With creates a Factory using the provided Registerer for registration of the // created Collectors. If the provided Registerer is nil, the returned Factory // creates Collectors that are not registered with any Registerer. func With(r prometheus.Registerer) Factory { return Factory{r} } // NewCounter works like the function of the same name in the prometheus package // but it automatically registers the Counter with the Factory's Registerer. func (f Factory) NewCounter(opts prometheus.CounterOpts) prometheus.Counter { c := prometheus.NewCounter(opts) if f.r != nil { f.r.MustRegister(c) } return c } // NewCounterVec works like the function of the same name in the prometheus // package but it automatically registers the CounterVec with the Factory's // Registerer. func (f Factory) NewCounterVec(opts prometheus.CounterOpts, labelNames []string) *prometheus.CounterVec { c := prometheus.NewCounterVec(opts, labelNames) if f.r != nil { f.r.MustRegister(c) } return c } // NewCounterFunc works like the function of the same name in the prometheus // package but it automatically registers the CounterFunc with the Factory's // Registerer. func (f Factory) NewCounterFunc(opts prometheus.CounterOpts, function func() float64) prometheus.CounterFunc { c := prometheus.NewCounterFunc(opts, function) if f.r != nil { f.r.MustRegister(c) } return c } // NewGauge works like the function of the same name in the prometheus package // but it automatically registers the Gauge with the Factory's Registerer. func (f Factory) NewGauge(opts prometheus.GaugeOpts) prometheus.Gauge { g := prometheus.NewGauge(opts) if f.r != nil { f.r.MustRegister(g) } return g } // NewGaugeVec works like the function of the same name in the prometheus // package but it automatically registers the GaugeVec with the Factory's // Registerer. func (f Factory) NewGaugeVec(opts prometheus.GaugeOpts, labelNames []string) *prometheus.GaugeVec { g := prometheus.NewGaugeVec(opts, labelNames) if f.r != nil { f.r.MustRegister(g) } return g } // NewGaugeFunc works like the function of the same name in the prometheus // package but it automatically registers the GaugeFunc with the Factory's // Registerer. func (f Factory) NewGaugeFunc(opts prometheus.GaugeOpts, function func() float64) prometheus.GaugeFunc { g := prometheus.NewGaugeFunc(opts, function) if f.r != nil { f.r.MustRegister(g) } return g } // NewSummary works like the function of the same name in the prometheus package // but it automatically registers the Summary with the Factory's Registerer. func (f Factory) NewSummary(opts prometheus.SummaryOpts) prometheus.Summary { s := prometheus.NewSummary(opts) if f.r != nil { f.r.MustRegister(s) } return s } // NewSummaryVec works like the function of the same name in the prometheus // package but it automatically registers the SummaryVec with the Factory's // Registerer. func (f Factory) NewSummaryVec(opts prometheus.SummaryOpts, labelNames []string) *prometheus.SummaryVec { s := prometheus.NewSummaryVec(opts, labelNames) if f.r != nil { f.r.MustRegister(s) } return s } // NewHistogram works like the function of the same name in the prometheus // package but it automatically registers the Histogram with the Factory's // Registerer. func (f Factory) NewHistogram(opts prometheus.HistogramOpts) prometheus.Histogram { h := prometheus.NewHistogram(opts) if f.r != nil { f.r.MustRegister(h) } return h } // NewHistogramVec works like the function of the same name in the prometheus // package but it automatically registers the HistogramVec with the Factory's // Registerer. func (f Factory) NewHistogramVec(opts prometheus.HistogramOpts, labelNames []string) *prometheus.HistogramVec { h := prometheus.NewHistogramVec(opts, labelNames) if f.r != nil { f.r.MustRegister(h) } return h } // NewUntypedFunc works like the function of the same name in the prometheus // package but it automatically registers the UntypedFunc with the Factory's // Registerer. func (f Factory) NewUntypedFunc(opts prometheus.UntypedOpts, function func() float64) prometheus.UntypedFunc { u := prometheus.NewUntypedFunc(opts, function) if f.r != nil { f.r.MustRegister(u) } return u } client_golang-1.21.1/prometheus/promauto/auto_test.go000066400000000000000000000015151476160432400230110ustar00rootroot00000000000000// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package promauto import ( "testing" "github.com/prometheus/client_golang/prometheus" ) func TestNil(t *testing.T) { // A nil registerer should be treated as a no-op by promauto. With(nil).NewCounter(prometheus.CounterOpts{Name: "test"}).Inc() } client_golang-1.21.1/prometheus/promhttp/000077500000000000000000000000001476160432400204605ustar00rootroot00000000000000client_golang-1.21.1/prometheus/promhttp/delegator.go000066400000000000000000000273601476160432400227650ustar00rootroot00000000000000// Copyright 2017 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package promhttp import ( "bufio" "io" "net" "net/http" ) const ( closeNotifier = 1 << iota flusher hijacker readerFrom pusher ) type delegator interface { http.ResponseWriter Status() int Written() int64 } type responseWriterDelegator struct { http.ResponseWriter status int written int64 wroteHeader bool observeWriteHeader func(int) } func (r *responseWriterDelegator) Status() int { return r.status } func (r *responseWriterDelegator) Written() int64 { return r.written } func (r *responseWriterDelegator) WriteHeader(code int) { if r.observeWriteHeader != nil && !r.wroteHeader { // Only call observeWriteHeader for the 1st time. It's a bug if // WriteHeader is called more than once, but we want to protect // against it here. Note that we still delegate the WriteHeader // to the original ResponseWriter to not mask the bug from it. r.observeWriteHeader(code) } r.status = code r.wroteHeader = true r.ResponseWriter.WriteHeader(code) } func (r *responseWriterDelegator) Write(b []byte) (int, error) { // If applicable, call WriteHeader here so that observeWriteHeader is // handled appropriately. if !r.wroteHeader { r.WriteHeader(http.StatusOK) } n, err := r.ResponseWriter.Write(b) r.written += int64(n) return n, err } // Unwrap lets http.ResponseController get the underlying http.ResponseWriter, // by implementing the [rwUnwrapper](https://cs.opensource.google/go/go/+/refs/tags/go1.21.4:src/net/http/responsecontroller.go;l=42-44) interface. func (r *responseWriterDelegator) Unwrap() http.ResponseWriter { return r.ResponseWriter } type ( closeNotifierDelegator struct{ *responseWriterDelegator } flusherDelegator struct{ *responseWriterDelegator } hijackerDelegator struct{ *responseWriterDelegator } readerFromDelegator struct{ *responseWriterDelegator } pusherDelegator struct{ *responseWriterDelegator } ) func (d closeNotifierDelegator) CloseNotify() <-chan bool { //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users. return d.ResponseWriter.(http.CloseNotifier).CloseNotify() } func (d flusherDelegator) Flush() { // If applicable, call WriteHeader here so that observeWriteHeader is // handled appropriately. if !d.wroteHeader { d.WriteHeader(http.StatusOK) } d.ResponseWriter.(http.Flusher).Flush() } func (d hijackerDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) { return d.ResponseWriter.(http.Hijacker).Hijack() } func (d readerFromDelegator) ReadFrom(re io.Reader) (int64, error) { // If applicable, call WriteHeader here so that observeWriteHeader is // handled appropriately. if !d.wroteHeader { d.WriteHeader(http.StatusOK) } n, err := d.ResponseWriter.(io.ReaderFrom).ReadFrom(re) d.written += n return n, err } func (d pusherDelegator) Push(target string, opts *http.PushOptions) error { return d.ResponseWriter.(http.Pusher).Push(target, opts) } var pickDelegator = make([]func(*responseWriterDelegator) delegator, 32) func init() { // TODO(beorn7): Code generation would help here. pickDelegator[0] = func(d *responseWriterDelegator) delegator { // 0 return d } pickDelegator[closeNotifier] = func(d *responseWriterDelegator) delegator { // 1 return closeNotifierDelegator{d} } pickDelegator[flusher] = func(d *responseWriterDelegator) delegator { // 2 return flusherDelegator{d} } pickDelegator[flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 3 return struct { *responseWriterDelegator http.Flusher http.CloseNotifier }{d, flusherDelegator{d}, closeNotifierDelegator{d}} } pickDelegator[hijacker] = func(d *responseWriterDelegator) delegator { // 4 return hijackerDelegator{d} } pickDelegator[hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 5 return struct { *responseWriterDelegator http.Hijacker http.CloseNotifier }{d, hijackerDelegator{d}, closeNotifierDelegator{d}} } pickDelegator[hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 6 return struct { *responseWriterDelegator http.Hijacker http.Flusher }{d, hijackerDelegator{d}, flusherDelegator{d}} } pickDelegator[hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 7 return struct { *responseWriterDelegator http.Hijacker http.Flusher http.CloseNotifier }{d, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}} } pickDelegator[readerFrom] = func(d *responseWriterDelegator) delegator { // 8 return readerFromDelegator{d} } pickDelegator[readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 9 return struct { *responseWriterDelegator io.ReaderFrom http.CloseNotifier }{d, readerFromDelegator{d}, closeNotifierDelegator{d}} } pickDelegator[readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 10 return struct { *responseWriterDelegator io.ReaderFrom http.Flusher }{d, readerFromDelegator{d}, flusherDelegator{d}} } pickDelegator[readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 11 return struct { *responseWriterDelegator io.ReaderFrom http.Flusher http.CloseNotifier }{d, readerFromDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}} } pickDelegator[readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 12 return struct { *responseWriterDelegator io.ReaderFrom http.Hijacker }{d, readerFromDelegator{d}, hijackerDelegator{d}} } pickDelegator[readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 13 return struct { *responseWriterDelegator io.ReaderFrom http.Hijacker http.CloseNotifier }{d, readerFromDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}} } pickDelegator[readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 14 return struct { *responseWriterDelegator io.ReaderFrom http.Hijacker http.Flusher }{d, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}} } pickDelegator[readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 15 return struct { *responseWriterDelegator io.ReaderFrom http.Hijacker http.Flusher http.CloseNotifier }{d, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}} } pickDelegator[pusher] = func(d *responseWriterDelegator) delegator { // 16 return pusherDelegator{d} } pickDelegator[pusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 17 return struct { *responseWriterDelegator http.Pusher http.CloseNotifier }{d, pusherDelegator{d}, closeNotifierDelegator{d}} } pickDelegator[pusher+flusher] = func(d *responseWriterDelegator) delegator { // 18 return struct { *responseWriterDelegator http.Pusher http.Flusher }{d, pusherDelegator{d}, flusherDelegator{d}} } pickDelegator[pusher+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 19 return struct { *responseWriterDelegator http.Pusher http.Flusher http.CloseNotifier }{d, pusherDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}} } pickDelegator[pusher+hijacker] = func(d *responseWriterDelegator) delegator { // 20 return struct { *responseWriterDelegator http.Pusher http.Hijacker }{d, pusherDelegator{d}, hijackerDelegator{d}} } pickDelegator[pusher+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 21 return struct { *responseWriterDelegator http.Pusher http.Hijacker http.CloseNotifier }{d, pusherDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}} } pickDelegator[pusher+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 22 return struct { *responseWriterDelegator http.Pusher http.Hijacker http.Flusher }{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}} } pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 23 return struct { *responseWriterDelegator http.Pusher http.Hijacker http.Flusher http.CloseNotifier }{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}} } pickDelegator[pusher+readerFrom] = func(d *responseWriterDelegator) delegator { // 24 return struct { *responseWriterDelegator http.Pusher io.ReaderFrom }{d, pusherDelegator{d}, readerFromDelegator{d}} } pickDelegator[pusher+readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 25 return struct { *responseWriterDelegator http.Pusher io.ReaderFrom http.CloseNotifier }{d, pusherDelegator{d}, readerFromDelegator{d}, closeNotifierDelegator{d}} } pickDelegator[pusher+readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 26 return struct { *responseWriterDelegator http.Pusher io.ReaderFrom http.Flusher }{d, pusherDelegator{d}, readerFromDelegator{d}, flusherDelegator{d}} } pickDelegator[pusher+readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 27 return struct { *responseWriterDelegator http.Pusher io.ReaderFrom http.Flusher http.CloseNotifier }{d, pusherDelegator{d}, readerFromDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}} } pickDelegator[pusher+readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 28 return struct { *responseWriterDelegator http.Pusher io.ReaderFrom http.Hijacker }{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}} } pickDelegator[pusher+readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 29 return struct { *responseWriterDelegator http.Pusher io.ReaderFrom http.Hijacker http.CloseNotifier }{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}} } pickDelegator[pusher+readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 30 return struct { *responseWriterDelegator http.Pusher io.ReaderFrom http.Hijacker http.Flusher }{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}} } pickDelegator[pusher+readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 31 return struct { *responseWriterDelegator http.Pusher io.ReaderFrom http.Hijacker http.Flusher http.CloseNotifier }{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}} } } func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) delegator { d := &responseWriterDelegator{ ResponseWriter: w, observeWriteHeader: observeWriteHeaderFunc, } id := 0 //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users. if _, ok := w.(http.CloseNotifier); ok { id += closeNotifier } if _, ok := w.(http.Flusher); ok { id += flusher } if _, ok := w.(http.Hijacker); ok { id += hijacker } if _, ok := w.(io.ReaderFrom); ok { id += readerFrom } if _, ok := w.(http.Pusher); ok { id += pusher } return pickDelegator[id](d) } client_golang-1.21.1/prometheus/promhttp/delegator_test.go000066400000000000000000000041371476160432400240210ustar00rootroot00000000000000// Copyright 2024 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package promhttp import ( "net/http" "testing" "time" ) type responseWriter struct { flushErrorCalled bool setWriteDeadlineCalled time.Time setReadDeadlineCalled time.Time } func (rw *responseWriter) Header() http.Header { return nil } func (rw *responseWriter) Write(p []byte) (int, error) { return 0, nil } func (rw *responseWriter) WriteHeader(statusCode int) { } func (rw *responseWriter) FlushError() error { rw.flushErrorCalled = true return nil } func (rw *responseWriter) SetWriteDeadline(deadline time.Time) error { rw.setWriteDeadlineCalled = deadline return nil } func (rw *responseWriter) SetReadDeadline(deadline time.Time) error { rw.setReadDeadlineCalled = deadline return nil } func TestResponseWriterDelegatorUnwrap(t *testing.T) { w := &responseWriter{} rwd := &responseWriterDelegator{ResponseWriter: w} if rwd.Unwrap() != w { t.Error("unwrapped responsewriter must equal to the original responsewriter") } controller := http.NewResponseController(rwd) if err := controller.Flush(); err != nil || !w.flushErrorCalled { t.Error("FlushError must be propagated to the original responsewriter") } timeNow := time.Now() if err := controller.SetWriteDeadline(timeNow); err != nil || w.setWriteDeadlineCalled != timeNow { t.Error("SetWriteDeadline must be propagated to the original responsewriter") } if err := controller.SetReadDeadline(timeNow); err != nil || w.setReadDeadlineCalled != timeNow { t.Error("SetReadDeadline must be propagated to the original responsewriter") } } client_golang-1.21.1/prometheus/promhttp/http.go000066400000000000000000000465431476160432400220020ustar00rootroot00000000000000// Copyright 2016 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package promhttp provides tooling around HTTP servers and clients. // // First, the package allows the creation of http.Handler instances to expose // Prometheus metrics via HTTP. promhttp.Handler acts on the // prometheus.DefaultGatherer. With HandlerFor, you can create a handler for a // custom registry or anything that implements the Gatherer interface. It also // allows the creation of handlers that act differently on errors or allow to // log errors. // // Second, the package provides tooling to instrument instances of http.Handler // via middleware. Middleware wrappers follow the naming scheme // InstrumentHandlerX, where X describes the intended use of the middleware. // See each function's doc comment for specific details. // // Finally, the package allows for an http.RoundTripper to be instrumented via // middleware. Middleware wrappers follow the naming scheme // InstrumentRoundTripperX, where X describes the intended use of the // middleware. See each function's doc comment for specific details. package promhttp import ( "compress/gzip" "errors" "fmt" "io" "net/http" "strconv" "sync" "time" "github.com/klauspost/compress/zstd" "github.com/prometheus/common/expfmt" "github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil" "github.com/prometheus/client_golang/prometheus" ) const ( contentTypeHeader = "Content-Type" contentEncodingHeader = "Content-Encoding" acceptEncodingHeader = "Accept-Encoding" processStartTimeHeader = "Process-Start-Time-Unix" ) // Compression represents the content encodings handlers support for the HTTP // responses. type Compression string const ( Identity Compression = "identity" Gzip Compression = "gzip" Zstd Compression = "zstd" ) var defaultCompressionFormats = []Compression{Identity, Gzip, Zstd} var gzipPool = sync.Pool{ New: func() interface{} { return gzip.NewWriter(nil) }, } // Handler returns an http.Handler for the prometheus.DefaultGatherer, using // default HandlerOpts, i.e. it reports the first error as an HTTP error, it has // no error logging, and it applies compression if requested by the client. // // The returned http.Handler is already instrumented using the // InstrumentMetricHandler function and the prometheus.DefaultRegisterer. If you // create multiple http.Handlers by separate calls of the Handler function, the // metrics used for instrumentation will be shared between them, providing // global scrape counts. // // This function is meant to cover the bulk of basic use cases. If you are doing // anything that requires more customization (including using a non-default // Gatherer, different instrumentation, and non-default HandlerOpts), use the // HandlerFor function. See there for details. func Handler() http.Handler { return InstrumentMetricHandler( prometheus.DefaultRegisterer, HandlerFor(prometheus.DefaultGatherer, HandlerOpts{}), ) } // HandlerFor returns an uninstrumented http.Handler for the provided // Gatherer. The behavior of the Handler is defined by the provided // HandlerOpts. Thus, HandlerFor is useful to create http.Handlers for custom // Gatherers, with non-default HandlerOpts, and/or with custom (or no) // instrumentation. Use the InstrumentMetricHandler function to apply the same // kind of instrumentation as it is used by the Handler function. func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler { return HandlerForTransactional(prometheus.ToTransactionalGatherer(reg), opts) } // HandlerForTransactional is like HandlerFor, but it uses transactional gather, which // can safely change in-place returned *dto.MetricFamily before call to `Gather` and after // call to `done` of that `Gather`. func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerOpts) http.Handler { var ( inFlightSem chan struct{} errCnt = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "promhttp_metric_handler_errors_total", Help: "Total number of internal errors encountered by the promhttp metric handler.", }, []string{"cause"}, ) ) if opts.MaxRequestsInFlight > 0 { inFlightSem = make(chan struct{}, opts.MaxRequestsInFlight) } if opts.Registry != nil { // Initialize all possibilities that can occur below. errCnt.WithLabelValues("gathering") errCnt.WithLabelValues("encoding") if err := opts.Registry.Register(errCnt); err != nil { are := &prometheus.AlreadyRegisteredError{} if errors.As(err, are) { errCnt = are.ExistingCollector.(*prometheus.CounterVec) } else { panic(err) } } } // Select compression formats to offer based on default or user choice. var compressions []string if !opts.DisableCompression { offers := defaultCompressionFormats if len(opts.OfferedCompressions) > 0 { offers = opts.OfferedCompressions } for _, comp := range offers { compressions = append(compressions, string(comp)) } } h := http.HandlerFunc(func(rsp http.ResponseWriter, req *http.Request) { if !opts.ProcessStartTime.IsZero() { rsp.Header().Set(processStartTimeHeader, strconv.FormatInt(opts.ProcessStartTime.Unix(), 10)) } if inFlightSem != nil { select { case inFlightSem <- struct{}{}: // All good, carry on. defer func() { <-inFlightSem }() default: http.Error(rsp, fmt.Sprintf( "Limit of concurrent requests reached (%d), try again later.", opts.MaxRequestsInFlight, ), http.StatusServiceUnavailable) return } } mfs, done, err := reg.Gather() defer done() if err != nil { if opts.ErrorLog != nil { opts.ErrorLog.Println("error gathering metrics:", err) } errCnt.WithLabelValues("gathering").Inc() switch opts.ErrorHandling { case PanicOnError: panic(err) case ContinueOnError: if len(mfs) == 0 { // Still report the error if no metrics have been gathered. httpError(rsp, err) return } case HTTPErrorOnError: httpError(rsp, err) return } } var contentType expfmt.Format if opts.EnableOpenMetrics { contentType = expfmt.NegotiateIncludingOpenMetrics(req.Header) } else { contentType = expfmt.Negotiate(req.Header) } rsp.Header().Set(contentTypeHeader, string(contentType)) w, encodingHeader, closeWriter, err := negotiateEncodingWriter(req, rsp, compressions) if err != nil { if opts.ErrorLog != nil { opts.ErrorLog.Println("error getting writer", err) } w = io.Writer(rsp) encodingHeader = string(Identity) } defer closeWriter() // Set Content-Encoding only when data is compressed if encodingHeader != string(Identity) { rsp.Header().Set(contentEncodingHeader, encodingHeader) } var enc expfmt.Encoder if opts.EnableOpenMetricsTextCreatedSamples { enc = expfmt.NewEncoder(w, contentType, expfmt.WithCreatedLines()) } else { enc = expfmt.NewEncoder(w, contentType) } // handleError handles the error according to opts.ErrorHandling // and returns true if we have to abort after the handling. handleError := func(err error) bool { if err == nil { return false } if opts.ErrorLog != nil { opts.ErrorLog.Println("error encoding and sending metric family:", err) } errCnt.WithLabelValues("encoding").Inc() switch opts.ErrorHandling { case PanicOnError: panic(err) case HTTPErrorOnError: // We cannot really send an HTTP error at this // point because we most likely have written // something to rsp already. But at least we can // stop sending. return true } // Do nothing in all other cases, including ContinueOnError. return false } for _, mf := range mfs { if handleError(enc.Encode(mf)) { return } } if closer, ok := enc.(expfmt.Closer); ok { // This in particular takes care of the final "# EOF\n" line for OpenMetrics. if handleError(closer.Close()) { return } } }) if opts.Timeout <= 0 { return h } return http.TimeoutHandler(h, opts.Timeout, fmt.Sprintf( "Exceeded configured timeout of %v.\n", opts.Timeout, )) } // InstrumentMetricHandler is usually used with an http.Handler returned by the // HandlerFor function. It instruments the provided http.Handler with two // metrics: A counter vector "promhttp_metric_handler_requests_total" to count // scrapes partitioned by HTTP status code, and a gauge // "promhttp_metric_handler_requests_in_flight" to track the number of // simultaneous scrapes. This function idempotently registers collectors for // both metrics with the provided Registerer. It panics if the registration // fails. The provided metrics are useful to see how many scrapes hit the // monitored target (which could be from different Prometheus servers or other // scrapers), and how often they overlap (which would result in more than one // scrape in flight at the same time). Note that the scrapes-in-flight gauge // will contain the scrape by which it is exposed, while the scrape counter will // only get incremented after the scrape is complete (as only then the status // code is known). For tracking scrape durations, use the // "scrape_duration_seconds" gauge created by the Prometheus server upon each // scrape. func InstrumentMetricHandler(reg prometheus.Registerer, handler http.Handler) http.Handler { cnt := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "promhttp_metric_handler_requests_total", Help: "Total number of scrapes by HTTP status code.", }, []string{"code"}, ) // Initialize the most likely HTTP status codes. cnt.WithLabelValues("200") cnt.WithLabelValues("500") cnt.WithLabelValues("503") if err := reg.Register(cnt); err != nil { are := &prometheus.AlreadyRegisteredError{} if errors.As(err, are) { cnt = are.ExistingCollector.(*prometheus.CounterVec) } else { panic(err) } } gge := prometheus.NewGauge(prometheus.GaugeOpts{ Name: "promhttp_metric_handler_requests_in_flight", Help: "Current number of scrapes being served.", }) if err := reg.Register(gge); err != nil { are := &prometheus.AlreadyRegisteredError{} if errors.As(err, are) { gge = are.ExistingCollector.(prometheus.Gauge) } else { panic(err) } } return InstrumentHandlerCounter(cnt, InstrumentHandlerInFlight(gge, handler)) } // HandlerErrorHandling defines how a Handler serving metrics will handle // errors. type HandlerErrorHandling int // These constants cause handlers serving metrics to behave as described if // errors are encountered. const ( // Serve an HTTP status code 500 upon the first error // encountered. Report the error message in the body. Note that HTTP // errors cannot be served anymore once the beginning of a regular // payload has been sent. Thus, in the (unlikely) case that encoding the // payload into the negotiated wire format fails, serving the response // will simply be aborted. Set an ErrorLog in HandlerOpts to detect // those errors. HTTPErrorOnError HandlerErrorHandling = iota // Ignore errors and try to serve as many metrics as possible. However, // if no metrics can be served, serve an HTTP status code 500 and the // last error message in the body. Only use this in deliberate "best // effort" metrics collection scenarios. In this case, it is highly // recommended to provide other means of detecting errors: By setting an // ErrorLog in HandlerOpts, the errors are logged. By providing a // Registry in HandlerOpts, the exposed metrics include an error counter // "promhttp_metric_handler_errors_total", which can be used for // alerts. ContinueOnError // Panic upon the first error encountered (useful for "crash only" apps). PanicOnError ) // Logger is the minimal interface HandlerOpts needs for logging. Note that // log.Logger from the standard library implements this interface, and it is // easy to implement by custom loggers, if they don't do so already anyway. type Logger interface { Println(v ...interface{}) } // HandlerOpts specifies options how to serve metrics via an http.Handler. The // zero value of HandlerOpts is a reasonable default. type HandlerOpts struct { // ErrorLog specifies an optional Logger for errors collecting and // serving metrics. If nil, errors are not logged at all. Note that the // type of a reported error is often prometheus.MultiError, which // formats into a multi-line error string. If you want to avoid the // latter, create a Logger implementation that detects a // prometheus.MultiError and formats the contained errors into one line. ErrorLog Logger // ErrorHandling defines how errors are handled. Note that errors are // logged regardless of the configured ErrorHandling provided ErrorLog // is not nil. ErrorHandling HandlerErrorHandling // If Registry is not nil, it is used to register a metric // "promhttp_metric_handler_errors_total", partitioned by "cause". A // failed registration causes a panic. Note that this error counter is // different from the instrumentation you get from the various // InstrumentHandler... helpers. It counts errors that don't necessarily // result in a non-2xx HTTP status code. There are two typical cases: // (1) Encoding errors that only happen after streaming of the HTTP body // has already started (and the status code 200 has been sent). This // should only happen with custom collectors. (2) Collection errors with // no effect on the HTTP status code because ErrorHandling is set to // ContinueOnError. Registry prometheus.Registerer // DisableCompression disables the response encoding (compression) and // encoding negotiation. If true, the handler will // never compress the response, even if requested // by the client and the OfferedCompressions field is set. DisableCompression bool // OfferedCompressions is a set of encodings (compressions) handler will // try to offer when negotiating with the client. This defaults to identity, gzip // and zstd. // NOTE: If handler can't agree with the client on the encodings or // unsupported or empty encodings are set in OfferedCompressions, // handler always fallbacks to no compression (identity), for // compatibility reasons. In such cases ErrorLog will be used if set. OfferedCompressions []Compression // The number of concurrent HTTP requests is limited to // MaxRequestsInFlight. Additional requests are responded to with 503 // Service Unavailable and a suitable message in the body. If // MaxRequestsInFlight is 0 or negative, no limit is applied. MaxRequestsInFlight int // If handling a request takes longer than Timeout, it is responded to // with 503 ServiceUnavailable and a suitable Message. No timeout is // applied if Timeout is 0 or negative. Note that with the current // implementation, reaching the timeout simply ends the HTTP requests as // described above (and even that only if sending of the body hasn't // started yet), while the bulk work of gathering all the metrics keeps // running in the background (with the eventual result to be thrown // away). Until the implementation is improved, it is recommended to // implement a separate timeout in potentially slow Collectors. Timeout time.Duration // If true, the experimental OpenMetrics encoding is added to the // possible options during content negotiation. Note that Prometheus // 2.5.0+ will negotiate OpenMetrics as first priority. OpenMetrics is // the only way to transmit exemplars. However, the move to OpenMetrics // is not completely transparent. Most notably, the values of "quantile" // labels of Summaries and "le" labels of Histograms are formatted with // a trailing ".0" if they would otherwise look like integer numbers // (which changes the identity of the resulting series on the Prometheus // server). EnableOpenMetrics bool // EnableOpenMetricsTextCreatedSamples specifies if this handler should add, extra, synthetic // Created Timestamps for counters, histograms and summaries, which for the current // version of OpenMetrics are defined as extra series with the same name and "_created" // suffix. See also the OpenMetrics specification for more details // https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#counter-1 // // Created timestamps are used to improve the accuracy of reset detection, // but the way it's designed in OpenMetrics 1.0 it also dramatically increases cardinality // if the scraper does not handle those metrics correctly (converting to created timestamp // instead of leaving those series as-is). New OpenMetrics versions might improve // this situation. // // Prometheus introduced the feature flag 'created-timestamp-zero-ingestion' // in version 2.50.0 to handle this situation. EnableOpenMetricsTextCreatedSamples bool // ProcessStartTime allows setting process start timevalue that will be exposed // with "Process-Start-Time-Unix" response header along with the metrics // payload. This allow callers to have efficient transformations to cumulative // counters (e.g. OpenTelemetry) or generally _created timestamp estimation per // scrape target. // NOTE: This feature is experimental and not covered by OpenMetrics or Prometheus // exposition format. ProcessStartTime time.Time } // httpError removes any content-encoding header and then calls http.Error with // the provided error and http.StatusInternalServerError. Error contents is // supposed to be uncompressed plain text. Same as with a plain http.Error, this // must not be called if the header or any payload has already been sent. func httpError(rsp http.ResponseWriter, err error) { rsp.Header().Del(contentEncodingHeader) http.Error( rsp, "An error has occurred while serving metrics:\n\n"+err.Error(), http.StatusInternalServerError, ) } // negotiateEncodingWriter reads the Accept-Encoding header from a request and // selects the right compression based on an allow-list of supported // compressions. It returns a writer implementing the compression and an the // correct value that the caller can set in the response header. func negotiateEncodingWriter(r *http.Request, rw io.Writer, compressions []string) (_ io.Writer, encodingHeaderValue string, closeWriter func(), _ error) { if len(compressions) == 0 { return rw, string(Identity), func() {}, nil } // TODO(mrueg): Replace internal/github.com/gddo once https://github.com/golang/go/issues/19307 is implemented. selected := httputil.NegotiateContentEncoding(r, compressions) switch selected { case "zstd": // TODO(mrueg): Replace klauspost/compress with stdlib implementation once https://github.com/golang/go/issues/62513 is implemented. z, err := zstd.NewWriter(rw, zstd.WithEncoderLevel(zstd.SpeedFastest)) if err != nil { return nil, "", func() {}, err } z.Reset(rw) return z, selected, func() { _ = z.Close() }, nil case "gzip": gz := gzipPool.Get().(*gzip.Writer) gz.Reset(rw) return gz, selected, func() { _ = gz.Close(); gzipPool.Put(gz) }, nil case "identity": // This means the content is not compressed. return rw, selected, func() {}, nil default: // The content encoding was not implemented yet. return nil, "", func() {}, fmt.Errorf("content compression format not recognized: %s. Valid formats are: %s", selected, defaultCompressionFormats) } } client_golang-1.21.1/prometheus/promhttp/http_test.go000066400000000000000000000475641476160432400230450ustar00rootroot00000000000000// Copyright 2016 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package promhttp import ( "bytes" "compress/gzip" "errors" "fmt" "io" "log" "net/http" "net/http/httptest" "strings" "testing" "time" "github.com/klauspost/compress/zstd" dto "github.com/prometheus/client_model/go" "github.com/prometheus/client_golang/prometheus" ) type errorCollector struct{} const ( acceptHeader = "Accept" acceptTextPlain = "text/plain" ) func (e errorCollector) Describe(ch chan<- *prometheus.Desc) { ch <- prometheus.NewDesc("invalid_metric", "not helpful", nil, nil) } func (e errorCollector) Collect(ch chan<- prometheus.Metric) { ch <- prometheus.NewInvalidMetric( prometheus.NewDesc("invalid_metric", "not helpful", nil, nil), errors.New("collect error"), ) } type blockingCollector struct { CollectStarted, Block chan struct{} } func (b blockingCollector) Describe(ch chan<- *prometheus.Desc) { ch <- prometheus.NewDesc("dummy_desc", "not helpful", nil, nil) } func (b blockingCollector) Collect(ch chan<- prometheus.Metric) { select { case b.CollectStarted <- struct{}{}: default: } // Collects nothing, just waits for a channel receive. <-b.Block } type mockTransactionGatherer struct { g prometheus.Gatherer gatherInvoked int doneInvoked int } func (g *mockTransactionGatherer) Gather() (_ []*dto.MetricFamily, done func(), err error) { g.gatherInvoked++ mfs, err := g.g.Gather() return mfs, func() { g.doneInvoked++ }, err } func readCompressedBody(r io.Reader, comp Compression) (string, error) { switch comp { case Gzip: reader, err := gzip.NewReader(r) if err != nil { return "", err } defer reader.Close() got, err := io.ReadAll(reader) return string(got), err case Zstd: reader, err := zstd.NewReader(r) if err != nil { return "", err } defer reader.Close() got, err := io.ReadAll(reader) return string(got), err } return "", errors.New("Unsupported compression") } func TestHandlerErrorHandling(t *testing.T) { // Create a registry that collects a MetricFamily with two elements, // another with one, and reports an error. Further down, we'll use the // same registry in the HandlerOpts. reg := prometheus.NewRegistry() cnt := prometheus.NewCounter(prometheus.CounterOpts{ Name: "the_count", Help: "Ah-ah-ah! Thunder and lightning!", }) reg.MustRegister(cnt) cntVec := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "name", Help: "docstring", ConstLabels: prometheus.Labels{"constname": "constvalue"}, }, []string{"labelname"}, ) cntVec.WithLabelValues("val1").Inc() cntVec.WithLabelValues("val2").Inc() reg.MustRegister(cntVec) reg.MustRegister(errorCollector{}) logBuf := &bytes.Buffer{} logger := log.New(logBuf, "", 0) writer := httptest.NewRecorder() request, _ := http.NewRequest(http.MethodGet, "/", nil) request.Header.Add("Accept", "test/plain") mReg := &mockTransactionGatherer{g: reg} errorHandler := HandlerForTransactional(mReg, HandlerOpts{ ErrorLog: logger, ErrorHandling: HTTPErrorOnError, Registry: reg, }) continueHandler := HandlerForTransactional(mReg, HandlerOpts{ ErrorLog: logger, ErrorHandling: ContinueOnError, Registry: reg, }) panicHandler := HandlerForTransactional(mReg, HandlerOpts{ ErrorLog: logger, ErrorHandling: PanicOnError, Registry: reg, }) // Expect gatherer not touched. if got := mReg.gatherInvoked; got != 0 { t.Fatalf("unexpected number of gather invokes, want 0, got %d", got) } if got := mReg.doneInvoked; got != 0 { t.Fatalf("unexpected number of done invokes, want 0, got %d", got) } wantMsg := `error gathering metrics: error collecting metric Desc{fqName: "invalid_metric", help: "not helpful", constLabels: {}, variableLabels: {}}: collect error ` wantErrorBody := `An error has occurred while serving metrics: error collecting metric Desc{fqName: "invalid_metric", help: "not helpful", constLabels: {}, variableLabels: {}}: collect error ` wantOKBody1 := `# HELP name docstring # TYPE name counter name{constname="constvalue",labelname="val1"} 1 name{constname="constvalue",labelname="val2"} 1 # HELP promhttp_metric_handler_errors_total Total number of internal errors encountered by the promhttp metric handler. # TYPE promhttp_metric_handler_errors_total counter promhttp_metric_handler_errors_total{cause="encoding"} 0 promhttp_metric_handler_errors_total{cause="gathering"} 1 # HELP the_count Ah-ah-ah! Thunder and lightning! # TYPE the_count counter the_count 0 ` // It might happen that counting the gathering error makes it to the // promhttp_metric_handler_errors_total counter before it is gathered // itself. Thus, we have to bodies that are acceptable for the test. wantOKBody2 := `# HELP name docstring # TYPE name counter name{constname="constvalue",labelname="val1"} 1 name{constname="constvalue",labelname="val2"} 1 # HELP promhttp_metric_handler_errors_total Total number of internal errors encountered by the promhttp metric handler. # TYPE promhttp_metric_handler_errors_total counter promhttp_metric_handler_errors_total{cause="encoding"} 0 promhttp_metric_handler_errors_total{cause="gathering"} 2 # HELP the_count Ah-ah-ah! Thunder and lightning! # TYPE the_count counter the_count 0 ` errorHandler.ServeHTTP(writer, request) if got := mReg.gatherInvoked; got != 1 { t.Fatalf("unexpected number of gather invokes, want 1, got %d", got) } if got := mReg.doneInvoked; got != 1 { t.Fatalf("unexpected number of done invokes, want 1, got %d", got) } if got, want := writer.Code, http.StatusInternalServerError; got != want { t.Errorf("got HTTP status code %d, want %d", got, want) } if got, want := logBuf.String(), wantMsg; got != want { t.Errorf("got log buf %q, want %q", got, want) } if got, want := writer.Body.String(), wantErrorBody; got != want { t.Errorf("got body %q, want %q", got, want) } logBuf.Reset() writer.Body.Reset() writer.Code = http.StatusOK continueHandler.ServeHTTP(writer, request) if got := mReg.gatherInvoked; got != 2 { t.Fatalf("unexpected number of gather invokes, want 2, got %d", got) } if got := mReg.doneInvoked; got != 2 { t.Fatalf("unexpected number of done invokes, want 2, got %d", got) } if got, want := writer.Code, http.StatusOK; got != want { t.Errorf("got HTTP status code %d, want %d", got, want) } if got, want := logBuf.String(), wantMsg; got != want { t.Errorf("got log buf %q, want %q", got, want) } if got := writer.Body.String(); got != wantOKBody1 && got != wantOKBody2 { t.Errorf("got body %q, want either %q or %q", got, wantOKBody1, wantOKBody2) } defer func() { if err := recover(); err == nil { t.Error("expected panic from panicHandler") } if got := mReg.gatherInvoked; got != 3 { t.Fatalf("unexpected number of gather invokes, want 3, got %d", got) } if got := mReg.doneInvoked; got != 3 { t.Fatalf("unexpected number of done invokes, want 3, got %d", got) } }() panicHandler.ServeHTTP(writer, request) } func TestInstrumentMetricHandler(t *testing.T) { reg := prometheus.NewRegistry() mReg := &mockTransactionGatherer{g: reg} handler := InstrumentMetricHandler(reg, HandlerForTransactional(mReg, HandlerOpts{})) // Do it again to test idempotency. InstrumentMetricHandler(reg, HandlerForTransactional(mReg, HandlerOpts{})) writer := httptest.NewRecorder() request, _ := http.NewRequest(http.MethodGet, "/", nil) request.Header.Add(acceptHeader, acceptTextPlain) handler.ServeHTTP(writer, request) if got := mReg.gatherInvoked; got != 1 { t.Fatalf("unexpected number of gather invokes, want 1, got %d", got) } if got := mReg.doneInvoked; got != 1 { t.Fatalf("unexpected number of done invokes, want 1, got %d", got) } if got, want := writer.Code, http.StatusOK; got != want { t.Errorf("got HTTP status code %d, want %d", got, want) } if got, want := writer.Header().Get(contentEncodingHeader), ""; got != want { t.Errorf("got HTTP content encoding header %s, want %s", got, want) } want := "promhttp_metric_handler_requests_in_flight 1\n" if got := writer.Body.String(); !strings.Contains(got, want) { t.Errorf("got body %q, does not contain %q", got, want) } want = "promhttp_metric_handler_requests_total{code=\"200\"} 0\n" if got := writer.Body.String(); !strings.Contains(got, want) { t.Errorf("got body %q, does not contain %q", got, want) } for i := 0; i < 100; i++ { writer.Body.Reset() handler.ServeHTTP(writer, request) if got, want := mReg.gatherInvoked, i+2; got != want { t.Fatalf("unexpected number of gather invokes, want %d, got %d", want, got) } if got, want := mReg.doneInvoked, i+2; got != want { t.Fatalf("unexpected number of done invokes, want %d, got %d", want, got) } if got, want := writer.Code, http.StatusOK; got != want { t.Errorf("got HTTP status code %d, want %d", got, want) } want := "promhttp_metric_handler_requests_in_flight 1\n" if got := writer.Body.String(); !strings.Contains(got, want) { t.Errorf("got body %q, does not contain %q", got, want) } want = fmt.Sprintf("promhttp_metric_handler_requests_total{code=\"200\"} %d\n", i+1) if got := writer.Body.String(); !strings.Contains(got, want) { t.Errorf("got body %q, does not contain %q", got, want) } } } func TestHandlerMaxRequestsInFlight(t *testing.T) { reg := prometheus.NewRegistry() handler := HandlerFor(reg, HandlerOpts{MaxRequestsInFlight: 1}) w1 := httptest.NewRecorder() w2 := httptest.NewRecorder() w3 := httptest.NewRecorder() request, _ := http.NewRequest(http.MethodGet, "/", nil) request.Header.Add(acceptHeader, acceptTextPlain) c := blockingCollector{Block: make(chan struct{}), CollectStarted: make(chan struct{}, 1)} reg.MustRegister(c) rq1Done := make(chan struct{}) go func() { handler.ServeHTTP(w1, request) close(rq1Done) }() <-c.CollectStarted handler.ServeHTTP(w2, request) if got, want := w2.Code, http.StatusServiceUnavailable; got != want { t.Errorf("got HTTP status code %d, want %d", got, want) } if got, want := w2.Body.String(), "Limit of concurrent requests reached (1), try again later.\n"; got != want { t.Errorf("got body %q, want %q", got, want) } close(c.Block) <-rq1Done handler.ServeHTTP(w3, request) if got, want := w3.Code, http.StatusOK; got != want { t.Errorf("got HTTP status code %d, want %d", got, want) } } func TestHandlerTimeout(t *testing.T) { reg := prometheus.NewRegistry() handler := HandlerFor(reg, HandlerOpts{Timeout: time.Millisecond}) w := httptest.NewRecorder() request, _ := http.NewRequest(http.MethodGet, "/", nil) request.Header.Add("Accept", "test/plain") c := blockingCollector{Block: make(chan struct{}), CollectStarted: make(chan struct{}, 1)} reg.MustRegister(c) handler.ServeHTTP(w, request) if got, want := w.Code, http.StatusServiceUnavailable; got != want { t.Errorf("got HTTP status code %d, want %d", got, want) } if got, want := w.Body.String(), "Exceeded configured timeout of 1ms.\n"; got != want { t.Errorf("got body %q, want %q", got, want) } close(c.Block) // To not leak a goroutine. } func TestInstrumentMetricHandlerWithCompression(t *testing.T) { reg := prometheus.NewRegistry() mReg := &mockTransactionGatherer{g: reg} handler := InstrumentMetricHandler(reg, HandlerForTransactional(mReg, HandlerOpts{DisableCompression: false})) compression := Zstd writer := httptest.NewRecorder() request, _ := http.NewRequest(http.MethodGet, "/", nil) request.Header.Add(acceptHeader, acceptTextPlain) request.Header.Add(acceptEncodingHeader, string(compression)) handler.ServeHTTP(writer, request) if got := mReg.gatherInvoked; got != 1 { t.Fatalf("unexpected number of gather invokes, want 1, got %d", got) } if got := mReg.doneInvoked; got != 1 { t.Fatalf("unexpected number of done invokes, want 1, got %d", got) } if got, want := writer.Code, http.StatusOK; got != want { t.Errorf("got HTTP status code %d, want %d", got, want) } if got, want := writer.Header().Get(contentEncodingHeader), string(compression); got != want { t.Errorf("got HTTP content encoding header %s, want %s", got, want) } body, err := readCompressedBody(writer.Body, compression) want := "promhttp_metric_handler_requests_in_flight 1\n" if got := body; !strings.Contains(got, want) { t.Errorf("got body %q, does not contain %q, err: %v", got, want, err) } want = "promhttp_metric_handler_requests_total{code=\"200\"} 0\n" if got := body; !strings.Contains(got, want) { t.Errorf("got body %q, does not contain %q, err: %v", got, want, err) } for i := 0; i < 100; i++ { writer.Body.Reset() handler.ServeHTTP(writer, request) if got, want := mReg.gatherInvoked, i+2; got != want { t.Fatalf("unexpected number of gather invokes, want %d, got %d", want, got) } if got, want := mReg.doneInvoked, i+2; got != want { t.Fatalf("unexpected number of done invokes, want %d, got %d", want, got) } if got, want := writer.Code, http.StatusOK; got != want { t.Errorf("got HTTP status code %d, want %d", got, want) } body, err := readCompressedBody(writer.Body, compression) want := "promhttp_metric_handler_requests_in_flight 1\n" if got := body; !strings.Contains(got, want) { t.Errorf("got body %q, does not contain %q, err: %v", got, want, err) } want = fmt.Sprintf("promhttp_metric_handler_requests_total{code=\"200\"} %d\n", i+1) if got := body; !strings.Contains(got, want) { t.Errorf("got body %q, does not contain %q, err: %v", got, want, err) } } // Test with Zstd compression = Zstd request.Header.Set(acceptEncodingHeader, string(compression)) handler.ServeHTTP(writer, request) if got, want := writer.Code, http.StatusOK; got != want { t.Errorf("got HTTP status code %d, want %d", got, want) } if got, want := writer.Header().Get(contentEncodingHeader), string(compression); got != want { t.Errorf("got HTTP content encoding header %s, want %s", got, want) } body, err = readCompressedBody(writer.Body, compression) want = "promhttp_metric_handler_requests_in_flight 1\n" if got := body; !strings.Contains(got, want) { t.Errorf("got body %q, does not contain %q, err: %v", got, want, err) } want = "promhttp_metric_handler_requests_total{code=\"200\"} 101\n" if got := body; !strings.Contains(got, want) { t.Errorf("got body %q, does not contain %q, err: %v", got, want, err) } for i := 101; i < 201; i++ { writer.Body.Reset() handler.ServeHTTP(writer, request) if got, want := mReg.gatherInvoked, i+2; got != want { t.Fatalf("unexpected number of gather invokes, want %d, got %d", want, got) } if got, want := mReg.doneInvoked, i+2; got != want { t.Fatalf("unexpected number of done invokes, want %d, got %d", want, got) } if got, want := writer.Code, http.StatusOK; got != want { t.Errorf("got HTTP status code %d, want %d", got, want) } body, err := readCompressedBody(writer.Body, compression) want := "promhttp_metric_handler_requests_in_flight 1\n" if got := body; !strings.Contains(got, want) { t.Errorf("got body %q, does not contain %q, err: %v", got, want, err) } want = fmt.Sprintf("promhttp_metric_handler_requests_total{code=\"200\"} %d\n", i+1) if got := body; !strings.Contains(got, want) { t.Errorf("got body %q, does not contain %q, err: %v", got, want, err) } } } func TestNegotiateEncodingWriter(t *testing.T) { var defaultCompressions []string for _, comp := range defaultCompressionFormats { defaultCompressions = append(defaultCompressions, string(comp)) } testCases := []struct { name string offeredCompressions []string acceptEncoding string expectedCompression string err error }{ { name: "test without compression enabled", offeredCompressions: []string{}, acceptEncoding: "", expectedCompression: "identity", err: nil, }, { name: "test with compression enabled with empty accept-encoding header", offeredCompressions: defaultCompressions, acceptEncoding: "", expectedCompression: "identity", err: nil, }, { name: "test with gzip compression requested", offeredCompressions: defaultCompressions, acceptEncoding: "gzip", expectedCompression: "gzip", err: nil, }, { name: "test with gzip, zstd compression requested", offeredCompressions: defaultCompressions, acceptEncoding: "gzip,zstd", expectedCompression: "gzip", err: nil, }, { name: "test with zstd, gzip compression requested", offeredCompressions: defaultCompressions, acceptEncoding: "zstd,gzip", expectedCompression: "gzip", err: nil, }, } for _, test := range testCases { request, _ := http.NewRequest(http.MethodGet, "/", nil) request.Header.Add(acceptEncodingHeader, test.acceptEncoding) rr := httptest.NewRecorder() _, encodingHeader, _, err := negotiateEncodingWriter(request, rr, test.offeredCompressions) if !errors.Is(err, test.err) { t.Errorf("got error: %v, expected: %v", err, test.err) } if encodingHeader != test.expectedCompression { t.Errorf("got different compression type: %v, expected: %v", encodingHeader, test.expectedCompression) } } } func BenchmarkCompression(b *testing.B) { benchmarks := []struct { name string compressionType string }{ { name: "test with gzip compression", compressionType: "gzip", }, { name: "test with zstd compression", compressionType: "zstd", }, { name: "test with no compression", compressionType: "identity", }, } sizes := []struct { name string metricCount int labelCount int labelLength int metricLength int }{ { name: "small", metricCount: 50, labelCount: 5, labelLength: 5, metricLength: 5, }, { name: "medium", metricCount: 500, labelCount: 10, labelLength: 5, metricLength: 10, }, { name: "large", metricCount: 5000, labelCount: 10, labelLength: 5, metricLength: 10, }, { name: "extra-large", metricCount: 50000, labelCount: 20, labelLength: 5, metricLength: 10, }, } for _, size := range sizes { reg := prometheus.NewRegistry() handler := HandlerFor(reg, HandlerOpts{}) // Generate Metrics // Original source: https://github.com/prometheus-community/avalanche/blob/main/metrics/serve.go labelKeys := make([]string, size.labelCount) for idx := 0; idx < size.labelCount; idx++ { labelKeys[idx] = fmt.Sprintf("label_key_%s_%v", strings.Repeat("k", size.labelLength), idx) } labelValues := make([]string, size.labelCount) for idx := 0; idx < size.labelCount; idx++ { labelValues[idx] = fmt.Sprintf("label_val_%s_%v", strings.Repeat("v", size.labelLength), idx) } metrics := make([]*prometheus.GaugeVec, size.metricCount) for idx := 0; idx < size.metricCount; idx++ { gauge := prometheus.NewGaugeVec(prometheus.GaugeOpts{ Name: fmt.Sprintf("avalanche_metric_%s_%v_%v", strings.Repeat("m", size.metricLength), 0, idx), Help: "A tasty metric morsel", }, append([]string{"series_id", "cycle_id"}, labelKeys...)) reg.MustRegister(gauge) metrics[idx] = gauge } for _, benchmark := range benchmarks { b.Run(benchmark.name+"_"+size.name, func(b *testing.B) { for i := 0; i < b.N; i++ { writer := httptest.NewRecorder() request, _ := http.NewRequest(http.MethodGet, "/", nil) request.Header.Add(acceptEncodingHeader, benchmark.compressionType) handler.ServeHTTP(writer, request) } }) } } } client_golang-1.21.1/prometheus/promhttp/instrument_client.go000066400000000000000000000222341476160432400245600ustar00rootroot00000000000000// Copyright 2017 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package promhttp import ( "crypto/tls" "net/http" "net/http/httptrace" "time" "github.com/prometheus/client_golang/prometheus" ) // The RoundTripperFunc type is an adapter to allow the use of ordinary // functions as RoundTrippers. If f is a function with the appropriate // signature, RountTripperFunc(f) is a RoundTripper that calls f. type RoundTripperFunc func(req *http.Request) (*http.Response, error) // RoundTrip implements the RoundTripper interface. func (rt RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) { return rt(r) } // InstrumentRoundTripperInFlight is a middleware that wraps the provided // http.RoundTripper. It sets the provided prometheus.Gauge to the number of // requests currently handled by the wrapped http.RoundTripper. // // See the example for ExampleInstrumentRoundTripperDuration for example usage. func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripper) RoundTripperFunc { return func(r *http.Request) (*http.Response, error) { gauge.Inc() defer gauge.Dec() return next.RoundTrip(r) } } // InstrumentRoundTripperCounter is a middleware that wraps the provided // http.RoundTripper to observe the request result with the provided CounterVec. // The CounterVec must have zero, one, or two non-const non-curried labels. For // those, the only allowed label names are "code" and "method". The function // panics otherwise. For the "method" label a predefined default label value set // is used to filter given values. Values besides predefined values will count // as `unknown` method.`WithExtraMethods` can be used to add more // methods to the set. Partitioning of the CounterVec happens by HTTP status code // and/or HTTP method if the respective instance label names are present in the // CounterVec. For unpartitioned counting, use a CounterVec with zero labels. // // If the wrapped RoundTripper panics or returns a non-nil error, the Counter // is not incremented. // // Use with WithExemplarFromContext to instrument the exemplars on the counter of requests. // // See the example for ExampleInstrumentRoundTripperDuration for example usage. func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper, opts ...Option) RoundTripperFunc { rtOpts := defaultOptions() for _, o := range opts { o.apply(rtOpts) } // Curry the counter with dynamic labels before checking the remaining labels. code, method := checkLabels(counter.MustCurryWith(rtOpts.emptyDynamicLabels())) return func(r *http.Request) (*http.Response, error) { resp, err := next.RoundTrip(r) if err == nil { l := labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...) for label, resolve := range rtOpts.extraLabelsFromCtx { l[label] = resolve(resp.Request.Context()) } addWithExemplar(counter.With(l), 1, rtOpts.getExemplarFn(r.Context())) } return resp, err } } // InstrumentRoundTripperDuration is a middleware that wraps the provided // http.RoundTripper to observe the request duration with the provided // ObserverVec. The ObserverVec must have zero, one, or two non-const // non-curried labels. For those, the only allowed label names are "code" and // "method". The function panics otherwise. For the "method" label a predefined // default label value set is used to filter given values. Values besides // predefined values will count as `unknown` method. `WithExtraMethods` // can be used to add more methods to the set. The Observe method of the Observer // in the ObserverVec is called with the request duration in // seconds. Partitioning happens by HTTP status code and/or HTTP method if the // respective instance label names are present in the ObserverVec. For // unpartitioned observations, use an ObserverVec with zero labels. Note that // partitioning of Histograms is expensive and should be used judiciously. // // If the wrapped RoundTripper panics or returns a non-nil error, no values are // reported. // // Use with WithExemplarFromContext to instrument the exemplars on the duration histograms. // // Note that this method is only guaranteed to never observe negative durations // if used with Go1.9+. func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper, opts ...Option) RoundTripperFunc { rtOpts := defaultOptions() for _, o := range opts { o.apply(rtOpts) } // Curry the observer with dynamic labels before checking the remaining labels. code, method := checkLabels(obs.MustCurryWith(rtOpts.emptyDynamicLabels())) return func(r *http.Request) (*http.Response, error) { start := time.Now() resp, err := next.RoundTrip(r) if err == nil { l := labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...) for label, resolve := range rtOpts.extraLabelsFromCtx { l[label] = resolve(resp.Request.Context()) } observeWithExemplar(obs.With(l), time.Since(start).Seconds(), rtOpts.getExemplarFn(r.Context())) } return resp, err } } // InstrumentTrace is used to offer flexibility in instrumenting the available // httptrace.ClientTrace hook functions. Each function is passed a float64 // representing the time in seconds since the start of the http request. A user // may choose to use separately buckets Histograms, or implement custom // instance labels on a per function basis. type InstrumentTrace struct { GotConn func(float64) PutIdleConn func(float64) GotFirstResponseByte func(float64) Got100Continue func(float64) DNSStart func(float64) DNSDone func(float64) ConnectStart func(float64) ConnectDone func(float64) TLSHandshakeStart func(float64) TLSHandshakeDone func(float64) WroteHeaders func(float64) Wait100Continue func(float64) WroteRequest func(float64) } // InstrumentRoundTripperTrace is a middleware that wraps the provided // RoundTripper and reports times to hook functions provided in the // InstrumentTrace struct. Hook functions that are not present in the provided // InstrumentTrace struct are ignored. Times reported to the hook functions are // time since the start of the request. Only with Go1.9+, those times are // guaranteed to never be negative. (Earlier Go versions are not using a // monotonic clock.) Note that partitioning of Histograms is expensive and // should be used judiciously. // // For hook functions that receive an error as an argument, no observations are // made in the event of a non-nil error value. // // See the example for ExampleInstrumentRoundTripperDuration for example usage. func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) RoundTripperFunc { return func(r *http.Request) (*http.Response, error) { start := time.Now() trace := &httptrace.ClientTrace{ GotConn: func(_ httptrace.GotConnInfo) { if it.GotConn != nil { it.GotConn(time.Since(start).Seconds()) } }, PutIdleConn: func(err error) { if err != nil { return } if it.PutIdleConn != nil { it.PutIdleConn(time.Since(start).Seconds()) } }, DNSStart: func(_ httptrace.DNSStartInfo) { if it.DNSStart != nil { it.DNSStart(time.Since(start).Seconds()) } }, DNSDone: func(_ httptrace.DNSDoneInfo) { if it.DNSDone != nil { it.DNSDone(time.Since(start).Seconds()) } }, ConnectStart: func(_, _ string) { if it.ConnectStart != nil { it.ConnectStart(time.Since(start).Seconds()) } }, ConnectDone: func(_, _ string, err error) { if err != nil { return } if it.ConnectDone != nil { it.ConnectDone(time.Since(start).Seconds()) } }, GotFirstResponseByte: func() { if it.GotFirstResponseByte != nil { it.GotFirstResponseByte(time.Since(start).Seconds()) } }, Got100Continue: func() { if it.Got100Continue != nil { it.Got100Continue(time.Since(start).Seconds()) } }, TLSHandshakeStart: func() { if it.TLSHandshakeStart != nil { it.TLSHandshakeStart(time.Since(start).Seconds()) } }, TLSHandshakeDone: func(_ tls.ConnectionState, err error) { if err != nil { return } if it.TLSHandshakeDone != nil { it.TLSHandshakeDone(time.Since(start).Seconds()) } }, WroteHeaders: func() { if it.WroteHeaders != nil { it.WroteHeaders(time.Since(start).Seconds()) } }, Wait100Continue: func() { if it.Wait100Continue != nil { it.Wait100Continue(time.Since(start).Seconds()) } }, WroteRequest: func(_ httptrace.WroteRequestInfo) { if it.WroteRequest != nil { it.WroteRequest(time.Since(start).Seconds()) } }, } r = r.WithContext(httptrace.WithClientTrace(r.Context(), trace)) return next.RoundTrip(r) } } client_golang-1.21.1/prometheus/promhttp/instrument_client_test.go000066400000000000000000000257701476160432400256270ustar00rootroot00000000000000// Copyright 2017 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package promhttp import ( "context" "log" "net/http" "net/http/httptest" "reflect" "sort" "strings" "testing" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/testutil" dto "github.com/prometheus/client_model/go" "google.golang.org/protobuf/proto" ) func makeInstrumentedClient(opts ...Option) (*http.Client, *prometheus.Registry) { client := http.DefaultClient client.Timeout = 1 * time.Second reg := prometheus.NewRegistry() inFlightGauge := prometheus.NewGauge(prometheus.GaugeOpts{ Name: "client_in_flight_requests", Help: "A gauge of in-flight requests for the wrapped client.", }) counter := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "client_api_requests_total", Help: "A counter for requests from the wrapped client.", }, []string{"code", "method"}, ) dnsLatencyVec := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "dns_duration_seconds", Help: "Trace dns latency histogram.", Buckets: []float64{.005, .01, .025, .05}, }, []string{"event"}, ) tlsLatencyVec := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "tls_duration_seconds", Help: "Trace tls latency histogram.", Buckets: []float64{.05, .1, .25, .5}, }, []string{"event"}, ) histVec := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "request_duration_seconds", Help: "A histogram of request latencies.", Buckets: prometheus.DefBuckets, }, []string{"method"}, ) reg.MustRegister(counter, tlsLatencyVec, dnsLatencyVec, histVec, inFlightGauge) trace := &InstrumentTrace{ DNSStart: func(t float64) { dnsLatencyVec.WithLabelValues("dns_start").Observe(t) }, DNSDone: func(t float64) { dnsLatencyVec.WithLabelValues("dns_done").Observe(t) }, TLSHandshakeStart: func(t float64) { tlsLatencyVec.WithLabelValues("tls_handshake_start").Observe(t) }, TLSHandshakeDone: func(t float64) { tlsLatencyVec.WithLabelValues("tls_handshake_done").Observe(t) }, } client.Transport = InstrumentRoundTripperInFlight(inFlightGauge, InstrumentRoundTripperCounter(counter, InstrumentRoundTripperTrace(trace, InstrumentRoundTripperDuration(histVec, http.DefaultTransport, opts...), ), opts...), ) return client, reg } func labelsToLabelPair(l prometheus.Labels) []*dto.LabelPair { ret := make([]*dto.LabelPair, 0, len(l)) for k, v := range l { ret = append(ret, &dto.LabelPair{Name: proto.String(k), Value: proto.String(v)}) } sort.Slice(ret, func(i, j int) bool { return *ret[i].Name < *ret[j].Name }) return ret } func assetMetricAndExemplars( t *testing.T, reg *prometheus.Registry, expectedNumMetrics int, expectedExemplar []*dto.LabelPair, ) { t.Helper() mfs, err := reg.Gather() if err != nil { t.Fatal(err) } if want, got := expectedNumMetrics, len(mfs); want != got { t.Fatalf("unexpected number of metric families gathered, want %d, got %d", want, got) } for _, mf := range mfs { if len(mf.Metric) == 0 { t.Errorf("metric family %s must not be empty", mf.GetName()) } for _, m := range mf.GetMetric() { if c := m.GetCounter(); c != nil { if len(expectedExemplar) == 0 { if c.Exemplar != nil { t.Errorf("expected no exemplar on the counter %v%v, got %v", mf.GetName(), m.Label, c.Exemplar.String()) } continue } if c.Exemplar == nil { t.Errorf("expected exemplar %v on the counter %v%v, got none", expectedExemplar, mf.GetName(), m.Label) continue } if got := c.Exemplar.Label; !reflect.DeepEqual(expectedExemplar, got) { t.Errorf("expected exemplar %v on the counter %v%v, got %v", expectedExemplar, mf.GetName(), m.Label, got) } continue } if h := m.GetHistogram(); h != nil { found := false for _, b := range h.GetBucket() { if len(expectedExemplar) == 0 { if b.Exemplar != nil { t.Errorf("expected no exemplar on histogram %v%v bkt %v, got %v", mf.GetName(), m.Label, b.GetUpperBound(), b.Exemplar.String()) } continue } if b.Exemplar == nil { continue } if got := b.Exemplar.Label; !reflect.DeepEqual(expectedExemplar, got) { t.Errorf("expected exemplar %v on the histogram %v%v on bkt %v, got %v", expectedExemplar, mf.GetName(), m.Label, b.GetUpperBound(), got) continue } found = true break } if len(expectedExemplar) > 0 && !found { t.Errorf("expected exemplar %v on at least one bucket of the histogram %v%v, got none", expectedExemplar, mf.GetName(), m.Label) } } } } } func TestClientMiddlewareAPI(t *testing.T) { client, reg := makeInstrumentedClient() backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })) defer backend.Close() resp, err := client.Get(backend.URL) if err != nil { t.Fatal(err) } defer resp.Body.Close() assetMetricAndExemplars(t, reg, 3, nil) } func TestClientMiddlewareAPI_WithExemplars(t *testing.T) { exemplar := prometheus.Labels{"traceID": "example situation observed by this metric"} client, reg := makeInstrumentedClient(WithExemplarFromContext(func(_ context.Context) prometheus.Labels { return exemplar })) backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })) defer backend.Close() resp, err := client.Get(backend.URL) if err != nil { t.Fatal(err) } defer resp.Body.Close() assetMetricAndExemplars(t, reg, 3, labelsToLabelPair(exemplar)) } func TestClientMiddlewareAPI_WithRequestContext(t *testing.T) { client, reg := makeInstrumentedClient() backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })) defer backend.Close() req, err := http.NewRequest(http.MethodGet, backend.URL, nil) if err != nil { t.Fatalf("%v", err) } // Set a context with a long timeout. ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() req = req.WithContext(ctx) resp, err := client.Do(req) if err != nil { t.Fatal(err) } defer resp.Body.Close() mfs, err := reg.Gather() if err != nil { t.Fatal(err) } if want, got := 3, len(mfs); want != got { t.Fatalf("unexpected number of metric families gathered, want %d, got %d", want, got) } for _, mf := range mfs { if len(mf.Metric) == 0 { t.Errorf("metric family %s must not be empty", mf.GetName()) } } // make sure counters aren't double-incremented (see #1117) expected := ` # HELP client_api_requests_total A counter for requests from the wrapped client. # TYPE client_api_requests_total counter client_api_requests_total{code="200",method="get"} 1 ` if err := testutil.GatherAndCompare(reg, strings.NewReader(expected), "client_api_requests_total", ); err != nil { t.Fatal(err) } } func TestClientMiddlewareAPIWithRequestContextTimeout(t *testing.T) { client, _ := makeInstrumentedClient() // Slow testserver responding in 100ms. backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { time.Sleep(100 * time.Millisecond) w.WriteHeader(http.StatusOK) })) defer backend.Close() req, err := http.NewRequest(http.MethodGet, backend.URL, nil) if err != nil { t.Fatalf("%v", err) } // Set a context with a short timeout. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) defer cancel() req = req.WithContext(ctx) _, err = client.Do(req) if err == nil { t.Fatal("did not get timeout error") } expectedMsg := "context deadline exceeded" if !strings.Contains(err.Error(), expectedMsg) { t.Fatalf("unexpected error: %q, expect error: %q", err.Error(), expectedMsg) } } func ExampleInstrumentRoundTripperDuration() { client := http.DefaultClient client.Timeout = 1 * time.Second inFlightGauge := prometheus.NewGauge(prometheus.GaugeOpts{ Name: "client_in_flight_requests", Help: "A gauge of in-flight requests for the wrapped client.", }) counter := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "client_api_requests_total", Help: "A counter for requests from the wrapped client.", }, []string{"code", "method"}, ) // dnsLatencyVec uses custom buckets based on expected dns durations. // It has an instance label "event", which is set in the // DNSStart and DNSDonehook functions defined in the // InstrumentTrace struct below. dnsLatencyVec := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "dns_duration_seconds", Help: "Trace dns latency histogram.", Buckets: []float64{.005, .01, .025, .05}, }, []string{"event"}, ) // tlsLatencyVec uses custom buckets based on expected tls durations. // It has an instance label "event", which is set in the // TLSHandshakeStart and TLSHandshakeDone hook functions defined in the // InstrumentTrace struct below. tlsLatencyVec := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "tls_duration_seconds", Help: "Trace tls latency histogram.", Buckets: []float64{.05, .1, .25, .5}, }, []string{"event"}, ) // histVec has no labels, making it a zero-dimensional ObserverVec. histVec := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "request_duration_seconds", Help: "A histogram of request latencies.", Buckets: prometheus.DefBuckets, }, []string{}, ) // Register all of the metrics in the standard registry. prometheus.MustRegister(counter, tlsLatencyVec, dnsLatencyVec, histVec, inFlightGauge) // Define functions for the available httptrace.ClientTrace hook // functions that we want to instrument. trace := &InstrumentTrace{ DNSStart: func(t float64) { dnsLatencyVec.WithLabelValues("dns_start").Observe(t) }, DNSDone: func(t float64) { dnsLatencyVec.WithLabelValues("dns_done").Observe(t) }, TLSHandshakeStart: func(t float64) { tlsLatencyVec.WithLabelValues("tls_handshake_start").Observe(t) }, TLSHandshakeDone: func(t float64) { tlsLatencyVec.WithLabelValues("tls_handshake_done").Observe(t) }, } // Wrap the default RoundTripper with middleware. roundTripper := InstrumentRoundTripperInFlight(inFlightGauge, InstrumentRoundTripperCounter(counter, InstrumentRoundTripperTrace(trace, InstrumentRoundTripperDuration(histVec, http.DefaultTransport), ), ), ) // Set the RoundTripper on our client. client.Transport = roundTripper resp, err := client.Get("http://google.com") if err != nil { log.Printf("error: %v", err) } defer resp.Body.Close() } client_golang-1.21.1/prometheus/promhttp/instrument_server.go000066400000000000000000000450351476160432400246140ustar00rootroot00000000000000// Copyright 2017 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package promhttp import ( "errors" "net/http" "strconv" "strings" "time" dto "github.com/prometheus/client_model/go" "github.com/prometheus/client_golang/prometheus" ) // magicString is used for the hacky label test in checkLabels. Remove once fixed. const magicString = "zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa" // observeWithExemplar is a wrapper for [prometheus.ExemplarAdder.ExemplarObserver], // which falls back to [prometheus.Observer.Observe] if no labels are provided. func observeWithExemplar(obs prometheus.Observer, val float64, labels map[string]string) { if labels == nil { obs.Observe(val) return } obs.(prometheus.ExemplarObserver).ObserveWithExemplar(val, labels) } // addWithExemplar is a wrapper for [prometheus.ExemplarAdder.AddWithExemplar], // which falls back to [prometheus.Counter.Add] if no labels are provided. func addWithExemplar(obs prometheus.Counter, val float64, labels map[string]string) { if labels == nil { obs.Add(val) return } obs.(prometheus.ExemplarAdder).AddWithExemplar(val, labels) } // InstrumentHandlerInFlight is a middleware that wraps the provided // http.Handler. It sets the provided prometheus.Gauge to the number of // requests currently handled by the wrapped http.Handler. // // See the example for InstrumentHandlerDuration for example usage. func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { g.Inc() defer g.Dec() next.ServeHTTP(w, r) }) } // InstrumentHandlerDuration is a middleware that wraps the provided // http.Handler to observe the request duration with the provided ObserverVec. // The ObserverVec must have valid metric and label names and must have zero, // one, or two non-const non-curried labels. For those, the only allowed label // names are "code" and "method". The function panics otherwise. For the "method" // label a predefined default label value set is used to filter given values. // Values besides predefined values will count as `unknown` method. // `WithExtraMethods` can be used to add more methods to the set. The Observe // method of the Observer in the ObserverVec is called with the request duration // in seconds. Partitioning happens by HTTP status code and/or HTTP method if // the respective instance label names are present in the ObserverVec. For // unpartitioned observations, use an ObserverVec with zero labels. Note that // partitioning of Histograms is expensive and should be used judiciously. // // If the wrapped Handler does not set a status code, a status code of 200 is assumed. // // If the wrapped Handler panics, no values are reported. // // Note that this method is only guaranteed to never observe negative durations // if used with Go1.9+. func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc { hOpts := defaultOptions() for _, o := range opts { o.apply(hOpts) } // Curry the observer with dynamic labels before checking the remaining labels. code, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels())) if code { return func(w http.ResponseWriter, r *http.Request) { now := time.Now() d := newDelegator(w, nil) next.ServeHTTP(d, r) l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...) for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) } } return func(w http.ResponseWriter, r *http.Request) { now := time.Now() next.ServeHTTP(w, r) l := labels(code, method, r.Method, 0, hOpts.extraMethods...) for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) } } // InstrumentHandlerCounter is a middleware that wraps the provided http.Handler // to observe the request result with the provided CounterVec. The CounterVec // must have valid metric and label names and must have zero, one, or two // non-const non-curried labels. For those, the only allowed label names are // "code" and "method". The function panics otherwise. For the "method" // label a predefined default label value set is used to filter given values. // Values besides predefined values will count as `unknown` method. // `WithExtraMethods` can be used to add more methods to the set. Partitioning of the // CounterVec happens by HTTP status code and/or HTTP method if the respective // instance label names are present in the CounterVec. For unpartitioned // counting, use a CounterVec with zero labels. // // If the wrapped Handler does not set a status code, a status code of 200 is assumed. // // If the wrapped Handler panics, the Counter is not incremented. // // See the example for InstrumentHandlerDuration for example usage. func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, opts ...Option) http.HandlerFunc { hOpts := defaultOptions() for _, o := range opts { o.apply(hOpts) } // Curry the counter with dynamic labels before checking the remaining labels. code, method := checkLabels(counter.MustCurryWith(hOpts.emptyDynamicLabels())) if code { return func(w http.ResponseWriter, r *http.Request) { d := newDelegator(w, nil) next.ServeHTTP(d, r) l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...) for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } addWithExemplar(counter.With(l), 1, hOpts.getExemplarFn(r.Context())) } } return func(w http.ResponseWriter, r *http.Request) { next.ServeHTTP(w, r) l := labels(code, method, r.Method, 0, hOpts.extraMethods...) for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } addWithExemplar(counter.With(l), 1, hOpts.getExemplarFn(r.Context())) } } // InstrumentHandlerTimeToWriteHeader is a middleware that wraps the provided // http.Handler to observe with the provided ObserverVec the request duration // until the response headers are written. The ObserverVec must have valid // metric and label names and must have zero, one, or two non-const non-curried // labels. For those, the only allowed label names are "code" and "method". The // function panics otherwise. For the "method" label a predefined default label // value set is used to filter given values. Values besides predefined values // will count as `unknown` method.`WithExtraMethods` can be used to add more // methods to the set. The Observe method of the Observer in the // ObserverVec is called with the request duration in seconds. Partitioning // happens by HTTP status code and/or HTTP method if the respective instance // label names are present in the ObserverVec. For unpartitioned observations, // use an ObserverVec with zero labels. Note that partitioning of Histograms is // expensive and should be used judiciously. // // If the wrapped Handler panics before calling WriteHeader, no value is // reported. // // Note that this method is only guaranteed to never observe negative durations // if used with Go1.9+. // // See the example for InstrumentHandlerDuration for example usage. func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc { hOpts := defaultOptions() for _, o := range opts { o.apply(hOpts) } // Curry the observer with dynamic labels before checking the remaining labels. code, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels())) return func(w http.ResponseWriter, r *http.Request) { now := time.Now() d := newDelegator(w, func(status int) { l := labels(code, method, r.Method, status, hOpts.extraMethods...) for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) }) next.ServeHTTP(d, r) } } // InstrumentHandlerRequestSize is a middleware that wraps the provided // http.Handler to observe the request size with the provided ObserverVec. The // ObserverVec must have valid metric and label names and must have zero, one, // or two non-const non-curried labels. For those, the only allowed label names // are "code" and "method". The function panics otherwise. For the "method" // label a predefined default label value set is used to filter given values. // Values besides predefined values will count as `unknown` method. // `WithExtraMethods` can be used to add more methods to the set. The Observe // method of the Observer in the ObserverVec is called with the request size in // bytes. Partitioning happens by HTTP status code and/or HTTP method if the // respective instance label names are present in the ObserverVec. For // unpartitioned observations, use an ObserverVec with zero labels. Note that // partitioning of Histograms is expensive and should be used judiciously. // // If the wrapped Handler does not set a status code, a status code of 200 is assumed. // // If the wrapped Handler panics, no values are reported. // // See the example for InstrumentHandlerDuration for example usage. func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc { hOpts := defaultOptions() for _, o := range opts { o.apply(hOpts) } // Curry the observer with dynamic labels before checking the remaining labels. code, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels())) if code { return func(w http.ResponseWriter, r *http.Request) { d := newDelegator(w, nil) next.ServeHTTP(d, r) size := computeApproximateRequestSize(r) l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...) for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } observeWithExemplar(obs.With(l), float64(size), hOpts.getExemplarFn(r.Context())) } } return func(w http.ResponseWriter, r *http.Request) { next.ServeHTTP(w, r) size := computeApproximateRequestSize(r) l := labels(code, method, r.Method, 0, hOpts.extraMethods...) for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } observeWithExemplar(obs.With(l), float64(size), hOpts.getExemplarFn(r.Context())) } } // InstrumentHandlerResponseSize is a middleware that wraps the provided // http.Handler to observe the response size with the provided ObserverVec. The // ObserverVec must have valid metric and label names and must have zero, one, // or two non-const non-curried labels. For those, the only allowed label names // are "code" and "method". The function panics otherwise. For the "method" // label a predefined default label value set is used to filter given values. // Values besides predefined values will count as `unknown` method. // `WithExtraMethods` can be used to add more methods to the set. The Observe // method of the Observer in the ObserverVec is called with the response size in // bytes. Partitioning happens by HTTP status code and/or HTTP method if the // respective instance label names are present in the ObserverVec. For // unpartitioned observations, use an ObserverVec with zero labels. Note that // partitioning of Histograms is expensive and should be used judiciously. // // If the wrapped Handler does not set a status code, a status code of 200 is assumed. // // If the wrapped Handler panics, no values are reported. // // See the example for InstrumentHandlerDuration for example usage. func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.Handler { hOpts := defaultOptions() for _, o := range opts { o.apply(hOpts) } // Curry the observer with dynamic labels before checking the remaining labels. code, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels())) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { d := newDelegator(w, nil) next.ServeHTTP(d, r) l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...) for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } observeWithExemplar(obs.With(l), float64(d.Written()), hOpts.getExemplarFn(r.Context())) }) } // checkLabels returns whether the provided Collector has a non-const, // non-curried label named "code" and/or "method". It panics if the provided // Collector does not have a Desc or has more than one Desc or its Desc is // invalid. It also panics if the Collector has any non-const, non-curried // labels that are not named "code" or "method". func checkLabels(c prometheus.Collector) (code, method bool) { // TODO(beorn7): Remove this hacky way to check for instance labels // once Descriptors can have their dimensionality queried. var ( desc *prometheus.Desc m prometheus.Metric pm dto.Metric lvs []string ) // Get the Desc from the Collector. descc := make(chan *prometheus.Desc, 1) c.Describe(descc) select { case desc = <-descc: default: panic("no description provided by collector") } select { case <-descc: panic("more than one description provided by collector") default: } close(descc) // Make sure the Collector has a valid Desc by registering it with a // temporary registry. prometheus.NewRegistry().MustRegister(c) // Create a ConstMetric with the Desc. Since we don't know how many // variable labels there are, try for as long as it needs. for err := errors.New("dummy"); err != nil; lvs = append(lvs, magicString) { m, err = prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, lvs...) } // Write out the metric into a proto message and look at the labels. // If the value is not the magicString, it is a constLabel, which doesn't interest us. // If the label is curried, it doesn't interest us. // In all other cases, only "code" or "method" is allowed. if err := m.Write(&pm); err != nil { panic("error checking metric for labels") } for _, label := range pm.Label { name, value := label.GetName(), label.GetValue() if value != magicString || isLabelCurried(c, name) { continue } switch name { case "code": code = true case "method": method = true default: panic("metric partitioned with non-supported labels") } } return } func isLabelCurried(c prometheus.Collector, label string) bool { // This is even hackier than the label test above. // We essentially try to curry again and see if it works. // But for that, we need to type-convert to the two // types we use here, ObserverVec or *CounterVec. switch v := c.(type) { case *prometheus.CounterVec: if _, err := v.CurryWith(prometheus.Labels{label: "dummy"}); err == nil { return false } case prometheus.ObserverVec: if _, err := v.CurryWith(prometheus.Labels{label: "dummy"}); err == nil { return false } default: panic("unsupported metric vec type") } return true } func labels(code, method bool, reqMethod string, status int, extraMethods ...string) prometheus.Labels { labels := prometheus.Labels{} if !(code || method) { return labels } if code { labels["code"] = sanitizeCode(status) } if method { labels["method"] = sanitizeMethod(reqMethod, extraMethods...) } return labels } func computeApproximateRequestSize(r *http.Request) int { s := 0 if r.URL != nil { s += len(r.URL.String()) } s += len(r.Method) s += len(r.Proto) for name, values := range r.Header { s += len(name) for _, value := range values { s += len(value) } } s += len(r.Host) // N.B. r.Form and r.MultipartForm are assumed to be included in r.URL. if r.ContentLength != -1 { s += int(r.ContentLength) } return s } // If the wrapped http.Handler has a known method, it will be sanitized and returned. // Otherwise, "unknown" will be returned. The known method list can be extended // as needed by using extraMethods parameter. func sanitizeMethod(m string, extraMethods ...string) string { // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for // the methods chosen as default. switch m { case "GET", "get": return "get" case "PUT", "put": return "put" case "HEAD", "head": return "head" case "POST", "post": return "post" case "DELETE", "delete": return "delete" case "CONNECT", "connect": return "connect" case "OPTIONS", "options": return "options" case "NOTIFY", "notify": return "notify" case "TRACE", "trace": return "trace" case "PATCH", "patch": return "patch" default: for _, method := range extraMethods { if strings.EqualFold(m, method) { return strings.ToLower(m) } } return "unknown" } } // If the wrapped http.Handler has not set a status code, i.e. the value is // currently 0, sanitizeCode will return 200, for consistency with behavior in // the stdlib. func sanitizeCode(s int) string { // See for accepted codes https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml switch s { case 100: return "100" case 101: return "101" case 200, 0: return "200" case 201: return "201" case 202: return "202" case 203: return "203" case 204: return "204" case 205: return "205" case 206: return "206" case 300: return "300" case 301: return "301" case 302: return "302" case 304: return "304" case 305: return "305" case 307: return "307" case 400: return "400" case 401: return "401" case 402: return "402" case 403: return "403" case 404: return "404" case 405: return "405" case 406: return "406" case 407: return "407" case 408: return "408" case 409: return "409" case 410: return "410" case 411: return "411" case 412: return "412" case 413: return "413" case 414: return "414" case 415: return "415" case 416: return "416" case 417: return "417" case 418: return "418" case 500: return "500" case 501: return "501" case 502: return "502" case 503: return "503" case 504: return "504" case 505: return "505" case 428: return "428" case 429: return "429" case 431: return "431" case 511: return "511" default: if s >= 100 && s <= 599 { return strconv.Itoa(s) } return "unknown" } } client_golang-1.21.1/prometheus/promhttp/instrument_server_test.go000066400000000000000000000421601476160432400256470ustar00rootroot00000000000000// Copyright 2017 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package promhttp import ( "context" "io" "log" "net/http" "net/http/httptest" "testing" "github.com/prometheus/client_golang/prometheus" ) func TestLabelCheck(t *testing.T) { scenarios := map[string]struct { metricName string // Defaults to "c". varLabels []string constLabels []string curriedLabels []string dynamicLabels []string ok bool }{ "empty": { varLabels: []string{}, constLabels: []string{}, curriedLabels: []string{}, ok: true, }, "code as single var label": { varLabels: []string{"code"}, constLabels: []string{}, curriedLabels: []string{}, ok: true, }, "method as single var label": { varLabels: []string{"method"}, constLabels: []string{}, curriedLabels: []string{}, ok: true, }, "code and method as var labels": { varLabels: []string{"method", "code"}, constLabels: []string{}, curriedLabels: []string{}, ok: true, }, "valid case with all labels used": { varLabels: []string{"code", "method"}, constLabels: []string{"foo", "bar"}, curriedLabels: []string{"dings", "bums"}, dynamicLabels: []string{"dyn", "amics"}, ok: true, }, "all labels used with an invalid const label name": { varLabels: []string{"code", "method"}, constLabels: []string{"in\x80valid", "bar"}, curriedLabels: []string{"dings", "bums"}, dynamicLabels: []string{"dyn", "amics"}, ok: false, }, "unsupported var label": { varLabels: []string{"foo"}, constLabels: []string{}, curriedLabels: []string{}, ok: false, }, "mixed var labels": { varLabels: []string{"method", "foo", "code"}, constLabels: []string{}, curriedLabels: []string{}, ok: false, }, "unsupported var label but curried": { varLabels: []string{}, constLabels: []string{}, curriedLabels: []string{"foo"}, ok: true, }, "mixed var labels but unsupported curried": { varLabels: []string{"code", "method"}, constLabels: []string{}, curriedLabels: []string{"foo"}, ok: true, }, "supported label as const and curry": { varLabels: []string{}, constLabels: []string{"code"}, curriedLabels: []string{"method"}, ok: true, }, "supported label as const and dynamic": { varLabels: []string{}, constLabels: []string{"code"}, dynamicLabels: []string{"method"}, ok: true, }, "supported label as curried and dynamic": { varLabels: []string{}, curriedLabels: []string{"code"}, dynamicLabels: []string{"method"}, ok: true, }, "supported label as const and curry with unsupported as var": { varLabels: []string{"foo"}, constLabels: []string{"code"}, curriedLabels: []string{"method"}, ok: false, }, "invalid name and otherwise empty": { metricName: "in\x80valid", varLabels: []string{}, constLabels: []string{}, curriedLabels: []string{}, ok: false, }, "invalid name with all the otherwise valid labels": { metricName: "in\x80valid", varLabels: []string{"code", "method"}, constLabels: []string{"foo", "bar"}, curriedLabels: []string{"dings", "bums"}, dynamicLabels: []string{"dyn", "amics"}, ok: false, }, } for name, sc := range scenarios { t.Run(name, func(t *testing.T) { metricName := sc.metricName if metricName == "" { metricName = "c" } constLabels := prometheus.Labels{} for _, l := range sc.constLabels { constLabels[l] = "dummy" } labelNames := append(append(sc.varLabels, sc.curriedLabels...), sc.dynamicLabels...) c := prometheus.V2.NewCounterVec( prometheus.CounterVecOpts{ CounterOpts: prometheus.CounterOpts{ Name: metricName, Help: "c help", ConstLabels: constLabels, }, VariableLabels: prometheus.UnconstrainedLabels(labelNames), }, ) o := prometheus.ObserverVec(prometheus.V2.NewHistogramVec( prometheus.HistogramVecOpts{ HistogramOpts: prometheus.HistogramOpts{ Name: metricName, Help: "c help", ConstLabels: constLabels, }, VariableLabels: prometheus.UnconstrainedLabels(labelNames), }, )) for _, l := range sc.curriedLabels { c = c.MustCurryWith(prometheus.Labels{l: "dummy"}) o = o.MustCurryWith(prometheus.Labels{l: "dummy"}) } opts := []Option{} for _, l := range sc.dynamicLabels { opts = append(opts, WithLabelFromCtx(l, func(_ context.Context) string { return "foo" }, )) } func() { defer func() { if err := recover(); err != nil { if sc.ok { t.Error("unexpected panic:", err) } } else if !sc.ok { t.Error("expected panic") } }() InstrumentHandlerCounter(c, nil, opts...) }() func() { defer func() { if err := recover(); err != nil { if sc.ok { t.Error("unexpected panic:", err) } } else if !sc.ok { t.Error("expected panic") } }() InstrumentHandlerDuration(o, nil, opts...) }() if sc.ok { // Test if wantCode and wantMethod were detected correctly. var wantCode, wantMethod bool for _, l := range sc.varLabels { if l == "code" { wantCode = true } if l == "method" { wantMethod = true } } // Curry the dynamic labels since this is done normally behind the scenes for the check for _, l := range sc.dynamicLabels { c = c.MustCurryWith(prometheus.Labels{l: "dummy"}) o = o.MustCurryWith(prometheus.Labels{l: "dummy"}) } gotCode, gotMethod := checkLabels(c) if gotCode != wantCode { t.Errorf("wanted code=%t for counter, got code=%t", wantCode, gotCode) } if gotMethod != wantMethod { t.Errorf("wanted method=%t for counter, got method=%t", wantMethod, gotMethod) } gotCode, gotMethod = checkLabels(o) if gotCode != wantCode { t.Errorf("wanted code=%t for observer, got code=%t", wantCode, gotCode) } if gotMethod != wantMethod { t.Errorf("wanted method=%t for observer, got method=%t", wantMethod, gotMethod) } } }) } } func TestLabels(t *testing.T) { scenarios := map[string]struct { varLabels []string reqMethod string respStatus int extraMethods []string wantLabels prometheus.Labels ok bool }{ "empty": { varLabels: []string{}, wantLabels: prometheus.Labels{}, reqMethod: "GET", respStatus: 200, ok: true, }, "code as single var label": { varLabels: []string{"code"}, reqMethod: "GET", respStatus: 200, wantLabels: prometheus.Labels{"code": "200"}, ok: true, }, "code as single var label and out-of-range code": { varLabels: []string{"code"}, reqMethod: "GET", respStatus: 99, wantLabels: prometheus.Labels{"code": "unknown"}, ok: true, }, "code as single var label and in-range but unrecognized code": { varLabels: []string{"code"}, reqMethod: "GET", respStatus: 308, wantLabels: prometheus.Labels{"code": "308"}, ok: true, }, "method as single var label": { varLabels: []string{"method"}, reqMethod: "GET", respStatus: 200, wantLabels: prometheus.Labels{"method": "get"}, ok: true, }, "method as single var label and unknown method": { varLabels: []string{"method"}, reqMethod: "CUSTOM_METHOD", respStatus: 200, wantLabels: prometheus.Labels{"method": "unknown"}, ok: true, }, "code and method as var labels": { varLabels: []string{"method", "code"}, reqMethod: "GET", respStatus: 200, wantLabels: prometheus.Labels{"method": "get", "code": "200"}, ok: true, }, "method as single var label with extra methods specified": { varLabels: []string{"method"}, reqMethod: "CUSTOM_METHOD", respStatus: 200, extraMethods: []string{"CUSTOM_METHOD", "CUSTOM_METHOD_1"}, wantLabels: prometheus.Labels{"method": "custom_method"}, ok: true, }, "all labels used with an unknown method and out-of-range code": { varLabels: []string{"code", "method"}, reqMethod: "CUSTOM_METHOD", respStatus: 99, wantLabels: prometheus.Labels{"method": "unknown", "code": "unknown"}, ok: false, }, } checkLabels := func(labels []string) (gotCode, gotMethod bool) { for _, label := range labels { switch label { case "code": gotCode = true case "method": gotMethod = true default: panic("metric partitioned with non-supported labels for this test") } } return } equalLabels := func(gotLabels, wantLabels prometheus.Labels) bool { if len(gotLabels) != len(wantLabels) { return false } for ln, lv := range gotLabels { olv, ok := wantLabels[ln] if !ok { return false } if olv != lv { return false } } return true } for name, sc := range scenarios { t.Run(name, func(t *testing.T) { if sc.ok { gotCode, gotMethod := checkLabels(sc.varLabels) gotLabels := labels(gotCode, gotMethod, sc.reqMethod, sc.respStatus, sc.extraMethods...) if !equalLabels(gotLabels, sc.wantLabels) { t.Errorf("wanted labels=%v for counter, got code=%v", sc.wantLabels, gotLabels) } } }) } } func makeInstrumentedHandler(handler http.HandlerFunc, opts ...Option) (http.Handler, *prometheus.Registry) { reg := prometheus.NewRegistry() inFlightGauge := prometheus.NewGauge(prometheus.GaugeOpts{ Name: "in_flight_requests", Help: "A gauge of requests currently being served by the wrapped handler.", }) counter := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "api_requests_total", Help: "A counter for requests to the wrapped handler.", }, []string{"code", "method"}, ) histVec := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "response_duration_seconds", Help: "A histogram of request latencies.", Buckets: prometheus.DefBuckets, ConstLabels: prometheus.Labels{"handler": "api"}, }, []string{"method"}, ) writeHeaderVec := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "write_header_duration_seconds", Help: "A histogram of time to first write latencies.", Buckets: prometheus.DefBuckets, ConstLabels: prometheus.Labels{"handler": "api"}, }, []string{}, ) responseSize := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "push_request_size_bytes", Help: "A histogram of request sizes for requests.", Buckets: []float64{200, 500, 900, 1500}, }, []string{}, ) reg.MustRegister(inFlightGauge, counter, histVec, responseSize, writeHeaderVec) return InstrumentHandlerInFlight(inFlightGauge, InstrumentHandlerCounter(counter, InstrumentHandlerDuration(histVec, InstrumentHandlerTimeToWriteHeader(writeHeaderVec, InstrumentHandlerResponseSize(responseSize, handler, opts...), opts...), opts...), opts...), ), reg } func TestMiddlewareAPI(t *testing.T) { chain, reg := makeInstrumentedHandler(func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte("OK")) }) r, _ := http.NewRequest(http.MethodGet, "www.example.com", nil) w := httptest.NewRecorder() chain.ServeHTTP(w, r) assetMetricAndExemplars(t, reg, 5, nil) } func TestMiddlewareAPI_WithExemplars(t *testing.T) { exemplar := prometheus.Labels{"traceID": "example situation observed by this metric"} chain, reg := makeInstrumentedHandler(func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte("OK")) }, WithExemplarFromContext(func(_ context.Context) prometheus.Labels { return exemplar })) r, _ := http.NewRequest(http.MethodGet, "www.example.com", nil) w := httptest.NewRecorder() chain.ServeHTTP(w, r) assetMetricAndExemplars(t, reg, 5, labelsToLabelPair(exemplar)) } func TestInstrumentTimeToFirstWrite(t *testing.T) { var i int dobs := &responseWriterDelegator{ ResponseWriter: httptest.NewRecorder(), observeWriteHeader: func(status int) { i = status }, } d := newDelegator(dobs, nil) d.WriteHeader(http.StatusOK) if i != http.StatusOK { t.Fatalf("failed to execute observeWriteHeader") } } // testResponseWriter is an http.ResponseWriter that also implements // http.CloseNotifier, http.Flusher, and io.ReaderFrom. type testResponseWriter struct { closeNotifyCalled, flushCalled, readFromCalled bool } func (t *testResponseWriter) Header() http.Header { return nil } func (t *testResponseWriter) Write([]byte) (int, error) { return 0, nil } func (t *testResponseWriter) WriteHeader(int) {} func (t *testResponseWriter) CloseNotify() <-chan bool { t.closeNotifyCalled = true return nil } func (t *testResponseWriter) Flush() { t.flushCalled = true } func (t *testResponseWriter) ReadFrom(io.Reader) (int64, error) { t.readFromCalled = true return 0, nil } // testFlusher is an http.ResponseWriter that also implements http.Flusher. type testFlusher struct { flushCalled bool } func (t *testFlusher) Header() http.Header { return nil } func (t *testFlusher) Write([]byte) (int, error) { return 0, nil } func (t *testFlusher) WriteHeader(int) {} func (t *testFlusher) Flush() { t.flushCalled = true } func TestInterfaceUpgrade(t *testing.T) { w := &testResponseWriter{} d := newDelegator(w, nil) //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users. d.(http.CloseNotifier).CloseNotify() if !w.closeNotifyCalled { t.Error("CloseNotify not called") } d.(http.Flusher).Flush() if !w.flushCalled { t.Error("Flush not called") } d.(io.ReaderFrom).ReadFrom(nil) if !w.readFromCalled { t.Error("ReadFrom not called") } if _, ok := d.(http.Hijacker); ok { t.Error("delegator unexpectedly implements http.Hijacker") } f := &testFlusher{} d = newDelegator(f, nil) //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users. if _, ok := d.(http.CloseNotifier); ok { t.Error("delegator unexpectedly implements http.CloseNotifier") } d.(http.Flusher).Flush() if !w.flushCalled { t.Error("Flush not called") } if _, ok := d.(io.ReaderFrom); ok { t.Error("delegator unexpectedly implements io.ReaderFrom") } if _, ok := d.(http.Hijacker); ok { t.Error("delegator unexpectedly implements http.Hijacker") } } func ExampleInstrumentHandlerDuration() { inFlightGauge := prometheus.NewGauge(prometheus.GaugeOpts{ Name: "in_flight_requests", Help: "A gauge of requests currently being served by the wrapped handler.", }) counter := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "api_requests_total", Help: "A counter for requests to the wrapped handler.", }, []string{"code", "method"}, ) // duration is partitioned by the HTTP method and handler. It uses custom // buckets based on the expected request duration. duration := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "request_duration_seconds", Help: "A histogram of latencies for requests.", Buckets: []float64{.25, .5, 1, 2.5, 5, 10}, }, []string{"handler", "method"}, ) // responseSize has no labels, making it a zero-dimensional // ObserverVec. responseSize := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "response_size_bytes", Help: "A histogram of response sizes for requests.", Buckets: []float64{200, 500, 900, 1500}, }, []string{}, ) // Create the handlers that will be wrapped by the middleware. pushHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Push")) }) pullHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Pull")) }) // Register all of the metrics in the standard registry. prometheus.MustRegister(inFlightGauge, counter, duration, responseSize) // Instrument the handlers with all the metrics, injecting the "handler" // label by currying. pushChain := InstrumentHandlerInFlight(inFlightGauge, InstrumentHandlerDuration(duration.MustCurryWith(prometheus.Labels{"handler": "push"}), InstrumentHandlerCounter(counter, InstrumentHandlerResponseSize(responseSize, pushHandler), ), ), ) pullChain := InstrumentHandlerInFlight(inFlightGauge, InstrumentHandlerDuration(duration.MustCurryWith(prometheus.Labels{"handler": "pull"}), InstrumentHandlerCounter(counter, InstrumentHandlerResponseSize(responseSize, pullHandler), ), ), ) http.Handle("/metrics", Handler()) http.Handle("/push", pushChain) http.Handle("/pull", pullChain) if err := http.ListenAndServe(":3000", nil); err != nil { log.Fatal(err) } } client_golang-1.21.1/prometheus/promhttp/option.go000066400000000000000000000055371476160432400223310ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package promhttp import ( "context" "github.com/prometheus/client_golang/prometheus" ) // Option are used to configure both handler (middleware) or round tripper. type Option interface { apply(*options) } // LabelValueFromCtx are used to compute the label value from request context. // Context can be filled with values from request through middleware. type LabelValueFromCtx func(ctx context.Context) string // options store options for both a handler or round tripper. type options struct { extraMethods []string getExemplarFn func(requestCtx context.Context) prometheus.Labels extraLabelsFromCtx map[string]LabelValueFromCtx } func defaultOptions() *options { return &options{ getExemplarFn: func(ctx context.Context) prometheus.Labels { return nil }, extraLabelsFromCtx: map[string]LabelValueFromCtx{}, } } func (o *options) emptyDynamicLabels() prometheus.Labels { labels := prometheus.Labels{} for label := range o.extraLabelsFromCtx { labels[label] = "" } return labels } type optionApplyFunc func(*options) func (o optionApplyFunc) apply(opt *options) { o(opt) } // WithExtraMethods adds additional HTTP methods to the list of allowed methods. // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for the default list. // // See the example for ExampleInstrumentHandlerWithExtraMethods for example usage. func WithExtraMethods(methods ...string) Option { return optionApplyFunc(func(o *options) { o.extraMethods = methods }) } // WithExemplarFromContext allows to inject function that will get exemplar from context that will be put to counter and histogram metrics. // If the function returns nil labels or the metric does not support exemplars, no exemplar will be added (noop), but // metric will continue to observe/increment. func WithExemplarFromContext(getExemplarFn func(requestCtx context.Context) prometheus.Labels) Option { return optionApplyFunc(func(o *options) { o.getExemplarFn = getExemplarFn }) } // WithLabelFromCtx registers a label for dynamic resolution with access to context. // See the example for ExampleInstrumentHandlerWithLabelResolver for example usage func WithLabelFromCtx(name string, valueFn LabelValueFromCtx) Option { return optionApplyFunc(func(o *options) { o.extraLabelsFromCtx[name] = valueFn }) } client_golang-1.21.1/prometheus/promhttp/option_test.go000066400000000000000000000075261476160432400233700ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package promhttp import ( "context" "log" "net/http" "github.com/prometheus/client_golang/prometheus" ) type key int const ( CtxResolverKey key = iota ) func ExampleInstrumentHandlerWithExtraMethods() { counter := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "api_requests_total", Help: "A counter for requests to the wrapped handler.", }, []string{"code", "method"}, ) // duration is partitioned by the HTTP method and handler. It uses custom // buckets based on the expected request duration. duration := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "request_duration_seconds", Help: "A histogram of latencies for requests.", Buckets: []float64{.25, .5, 1, 2.5, 5, 10}, }, []string{"handler", "method"}, ) // Create the handlers that will be wrapped by the middleware. pullHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Pull")) }) // Specify additional HTTP methods to be added to the label allow list. opts := WithExtraMethods("CUSTOM_METHOD") // Instrument the handlers with all the metrics, injecting the "handler" // label by currying. pullChain := InstrumentHandlerDuration(duration.MustCurryWith(prometheus.Labels{"handler": "pull"}), InstrumentHandlerCounter(counter, pullHandler, opts), opts, ) http.Handle("/metrics", Handler()) http.Handle("/pull", pullChain) if err := http.ListenAndServe(":3000", nil); err != nil { log.Fatal(err) } } func ExampleInstrumentHandlerWithLabelResolver() { counter := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "api_requests_total", Help: "A counter for requests to the wrapped handler.", }, []string{"code", "method", "myheader"}, ) // duration is partitioned by the HTTP method, handler and request header // value. It uses custom buckets based on the expected request duration. // Beware to not have too high cardinality on the values of header. You // always should sanitize external inputs. duration := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "request_duration_seconds", Help: "A histogram of latencies for requests.", Buckets: []float64{.25, .5, 1, 2.5, 5, 10}, }, []string{"handler", "method", "myheader"}, ) // Create the handlers that will be wrapped by the middleware. pullHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Pull")) }) // Specify additional HTTP methods to be added to the label allow list. opts := WithLabelFromCtx("myheader", func(ctx context.Context) string { return ctx.Value(CtxResolverKey).(string) }, ) // Instrument the handlers with all the metrics, injecting the "handler" // label by currying. pullChain := InstrumentHandlerDuration(duration.MustCurryWith(prometheus.Labels{"handler": "pull"}), InstrumentHandlerCounter(counter, pullHandler, opts), opts, ) middleware := func(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := context.WithValue(r.Context(), CtxResolverKey, r.Header.Get("x-my-header")) next(w, r.WithContext(ctx)) } } http.Handle("/metrics", Handler()) http.Handle("/pull", middleware(pullChain)) if err := http.ListenAndServe(":3000", nil); err != nil { log.Fatal(err) } } client_golang-1.21.1/prometheus/push/000077500000000000000000000000001476160432400175625ustar00rootroot00000000000000client_golang-1.21.1/prometheus/push/example_add_from_gatherer_test.go000066400000000000000000000053211476160432400263200ustar00rootroot00000000000000// Copyright 2016 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package push_test import ( "fmt" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/push" ) var ( completionTime = prometheus.NewGauge(prometheus.GaugeOpts{ Name: "db_backup_last_completion_timestamp_seconds", Help: "The timestamp of the last completion of a DB backup, successful or not.", }) successTime = prometheus.NewGauge(prometheus.GaugeOpts{ Name: "db_backup_last_success_timestamp_seconds", Help: "The timestamp of the last successful completion of a DB backup.", }) duration = prometheus.NewGauge(prometheus.GaugeOpts{ Name: "db_backup_duration_seconds", Help: "The duration of the last DB backup in seconds.", }) records = prometheus.NewGauge(prometheus.GaugeOpts{ Name: "db_backup_records_processed", Help: "The number of records processed in the last DB backup.", }) ) func performBackup() (int, error) { // Perform the backup and return the number of backed up records and any // applicable error. // ... return 42, nil } func ExamplePusher_Add() { // We use a registry here to benefit from the consistency checks that // happen during registration. registry := prometheus.NewRegistry() registry.MustRegister(completionTime, duration, records) // Note that successTime is not registered. pusher := push.New("http://pushgateway:9091", "db_backup").Gatherer(registry) start := time.Now() n, err := performBackup() records.Set(float64(n)) // Note that time.Since only uses a monotonic clock in Go1.9+. duration.Set(time.Since(start).Seconds()) completionTime.SetToCurrentTime() if err != nil { fmt.Println("DB backup failed:", err) } else { // Add successTime to pusher only in case of success. // We could as well register it with the registry. // This example, however, demonstrates that you can // mix Gatherers and Collectors when handling a Pusher. pusher.Collector(successTime) successTime.SetToCurrentTime() } // Add is used here rather than Push to not delete a previously pushed // success timestamp in case of a failure of this backup. if err := pusher.Add(); err != nil { fmt.Println("Could not push to Pushgateway:", err) } } client_golang-1.21.1/prometheus/push/examples_test.go000066400000000000000000000022751476160432400227740ustar00rootroot00000000000000// Copyright 2016 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package push_test import ( "fmt" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/push" ) func ExamplePusher_Push() { completionTime := prometheus.NewGauge(prometheus.GaugeOpts{ Name: "db_backup_last_completion_timestamp_seconds", Help: "The timestamp of the last successful completion of a DB backup.", }) completionTime.SetToCurrentTime() if err := push.New("http://pushgateway:9091", "db_backup"). Collector(completionTime). Grouping("db", "customers"). Push(); err != nil { fmt.Println("Could not push completion time to Pushgateway:", err) } } client_golang-1.21.1/prometheus/push/push.go000066400000000000000000000272601476160432400210770ustar00rootroot00000000000000// Copyright 2015 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package push provides functions to push metrics to a Pushgateway. It uses a // builder approach. Create a Pusher with New and then add the various options // by using its methods, finally calling Add or Push, like this: // // // Easy case: // push.New("http://example.org/metrics", "my_job").Gatherer(myRegistry).Push() // // // Complex case: // push.New("http://example.org/metrics", "my_job"). // Collector(myCollector1). // Collector(myCollector2). // Grouping("zone", "xy"). // Client(&myHTTPClient). // BasicAuth("top", "secret"). // Add() // // See the examples section for more detailed examples. // // See the documentation of the Pushgateway to understand the meaning of // the grouping key and the differences between Push and Add: // https://github.com/prometheus/pushgateway package push import ( "bytes" "context" "encoding/base64" "errors" "fmt" "io" "net/http" "net/url" "strings" "github.com/prometheus/common/expfmt" "github.com/prometheus/common/model" "github.com/prometheus/client_golang/prometheus" ) const ( contentTypeHeader = "Content-Type" // base64Suffix is appended to a label name in the request URL path to // mark the following label value as base64 encoded. base64Suffix = "@base64" ) var errJobEmpty = errors.New("job name is empty") // HTTPDoer is an interface for the one method of http.Client that is used by Pusher type HTTPDoer interface { Do(*http.Request) (*http.Response, error) } // Pusher manages a push to the Pushgateway. Use New to create one, configure it // with its methods, and finally use the Add or Push method to push. type Pusher struct { error error url, job string grouping map[string]string gatherers prometheus.Gatherers registerer prometheus.Registerer client HTTPDoer header http.Header useBasicAuth bool username, password string expfmt expfmt.Format } // New creates a new Pusher to push to the provided URL with the provided job // name (which must not be empty). You can use just host:port or ip:port as url, // in which case β€œhttp://” is added automatically. Alternatively, include the // schema in the URL. However, do not include the β€œ/metrics/jobs/…” part. func New(url, job string) *Pusher { var ( reg = prometheus.NewRegistry() err error ) if job == "" { err = errJobEmpty } if !strings.Contains(url, "://") { url = "http://" + url } url = strings.TrimSuffix(url, "/") return &Pusher{ error: err, url: url, job: job, grouping: map[string]string{}, gatherers: prometheus.Gatherers{reg}, registerer: reg, client: &http.Client{}, expfmt: expfmt.NewFormat(expfmt.TypeProtoDelim), } } // Push collects/gathers all metrics from all Collectors and Gatherers added to // this Pusher. Then, it pushes them to the Pushgateway configured while // creating this Pusher, using the configured job name and any added grouping // labels as grouping key. All previously pushed metrics with the same job and // other grouping labels will be replaced with the metrics pushed by this // call. (It uses HTTP method β€œPUT” to push to the Pushgateway.) // // Push returns the first error encountered by any method call (including this // one) in the lifetime of the Pusher. func (p *Pusher) Push() error { return p.push(context.Background(), http.MethodPut) } // PushContext is like Push but includes a context. // // If the context expires before HTTP request is complete, an error is returned. func (p *Pusher) PushContext(ctx context.Context) error { return p.push(ctx, http.MethodPut) } // Add works like push, but only previously pushed metrics with the same name // (and the same job and other grouping labels) will be replaced. (It uses HTTP // method β€œPOST” to push to the Pushgateway.) func (p *Pusher) Add() error { return p.push(context.Background(), http.MethodPost) } // AddContext is like Add but includes a context. // // If the context expires before HTTP request is complete, an error is returned. func (p *Pusher) AddContext(ctx context.Context) error { return p.push(ctx, http.MethodPost) } // Gatherer adds a Gatherer to the Pusher, from which metrics will be gathered // to push them to the Pushgateway. The gathered metrics must not contain a job // label of their own. // // For convenience, this method returns a pointer to the Pusher itself. func (p *Pusher) Gatherer(g prometheus.Gatherer) *Pusher { p.gatherers = append(p.gatherers, g) return p } // Collector adds a Collector to the Pusher, from which metrics will be // collected to push them to the Pushgateway. The collected metrics must not // contain a job label of their own. // // For convenience, this method returns a pointer to the Pusher itself. func (p *Pusher) Collector(c prometheus.Collector) *Pusher { if p.error == nil { p.error = p.registerer.Register(c) } return p } // Error returns the error that was encountered. func (p *Pusher) Error() error { return p.error } // Grouping adds a label pair to the grouping key of the Pusher, replacing any // previously added label pair with the same label name. Note that setting any // labels in the grouping key that are already contained in the metrics to push // will lead to an error. // // For convenience, this method returns a pointer to the Pusher itself. func (p *Pusher) Grouping(name, value string) *Pusher { if p.error == nil { if !model.LabelName(name).IsValid() { p.error = fmt.Errorf("grouping label has invalid name: %s", name) return p } p.grouping[name] = value } return p } // Client sets a custom HTTP client for the Pusher. For convenience, this method // returns a pointer to the Pusher itself. // Pusher only needs one method of the custom HTTP client: Do(*http.Request). // Thus, rather than requiring a fully fledged http.Client, // the provided client only needs to implement the HTTPDoer interface. // Since *http.Client naturally implements that interface, it can still be used normally. func (p *Pusher) Client(c HTTPDoer) *Pusher { p.client = c return p } // Header sets a custom HTTP header for the Pusher's client. For convenience, this method // returns a pointer to the Pusher itself. func (p *Pusher) Header(header http.Header) *Pusher { p.header = header return p } // BasicAuth configures the Pusher to use HTTP Basic Authentication with the // provided username and password. For convenience, this method returns a // pointer to the Pusher itself. func (p *Pusher) BasicAuth(username, password string) *Pusher { p.useBasicAuth = true p.username = username p.password = password return p } // Format configures the Pusher to use an encoding format given by the // provided expfmt.Format. The default format is expfmt.FmtProtoDelim and // should be used with the standard Prometheus Pushgateway. Custom // implementations may require different formats. For convenience, this // method returns a pointer to the Pusher itself. func (p *Pusher) Format(format expfmt.Format) *Pusher { p.expfmt = format return p } // Delete sends a β€œDELETE” request to the Pushgateway configured while creating // this Pusher, using the configured job name and any added grouping labels as // grouping key. Any added Gatherers and Collectors added to this Pusher are // ignored by this method. // // Delete returns the first error encountered by any method call (including this // one) in the lifetime of the Pusher. func (p *Pusher) Delete() error { if p.error != nil { return p.error } req, err := http.NewRequest(http.MethodDelete, p.fullURL(), nil) if err != nil { return err } if p.header != nil { req.Header = p.header } if p.useBasicAuth { req.SetBasicAuth(p.username, p.password) } resp, err := p.client.Do(req) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != http.StatusAccepted { body, _ := io.ReadAll(resp.Body) // Ignore any further error as this is for an error message only. return fmt.Errorf("unexpected status code %d while deleting %s: %s", resp.StatusCode, p.fullURL(), body) } return nil } func (p *Pusher) push(ctx context.Context, method string) error { if p.error != nil { return p.error } mfs, err := p.gatherers.Gather() if err != nil { return err } buf := &bytes.Buffer{} enc := expfmt.NewEncoder(buf, p.expfmt) // Check for pre-existing grouping labels: for _, mf := range mfs { for _, m := range mf.GetMetric() { for _, l := range m.GetLabel() { if l.GetName() == "job" { return fmt.Errorf("pushed metric %s (%s) already contains a job label", mf.GetName(), m) } if _, ok := p.grouping[l.GetName()]; ok { return fmt.Errorf( "pushed metric %s (%s) already contains grouping label %s", mf.GetName(), m, l.GetName(), ) } } } if err := enc.Encode(mf); err != nil { return fmt.Errorf( "failed to encode metric family %s, error is %w", mf.GetName(), err) } } req, err := http.NewRequestWithContext(ctx, method, p.fullURL(), buf) if err != nil { return err } if p.header != nil { req.Header = p.header } if p.useBasicAuth { req.SetBasicAuth(p.username, p.password) } req.Header.Set(contentTypeHeader, string(p.expfmt)) resp, err := p.client.Do(req) if err != nil { return err } defer resp.Body.Close() // Depending on version and configuration of the PGW, StatusOK or StatusAccepted may be returned. if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusAccepted { body, _ := io.ReadAll(resp.Body) // Ignore any further error as this is for an error message only. return fmt.Errorf("unexpected status code %d while pushing to %s: %s", resp.StatusCode, p.fullURL(), body) } return nil } // fullURL assembles the URL used to push/delete metrics and returns it as a // string. The job name and any grouping label values containing a '/' will // trigger a base64 encoding of the affected component and proper suffixing of // the preceding component. Similarly, an empty grouping label value will be // encoded as base64 just with a single `=` padding character (to avoid an empty // path component). If the component does not contain a '/' but other special // characters, the usual url.QueryEscape is used for compatibility with older // versions of the Pushgateway and for better readability. func (p *Pusher) fullURL() string { urlComponents := []string{} if encodedJob, base64 := encodeComponent(p.job); base64 { urlComponents = append(urlComponents, "job"+base64Suffix, encodedJob) } else { urlComponents = append(urlComponents, "job", encodedJob) } for ln, lv := range p.grouping { if encodedLV, base64 := encodeComponent(lv); base64 { urlComponents = append(urlComponents, ln+base64Suffix, encodedLV) } else { urlComponents = append(urlComponents, ln, encodedLV) } } return fmt.Sprintf("%s/metrics/%s", p.url, strings.Join(urlComponents, "/")) } // encodeComponent encodes the provided string with base64.RawURLEncoding in // case it contains '/' and as "=" in case it is empty. If neither is the case, // it uses url.QueryEscape instead. It returns true in the former two cases. func encodeComponent(s string) (string, bool) { if s == "" { return "=", true } if strings.Contains(s, "/") { return base64.RawURLEncoding.EncodeToString([]byte(s)), true } return url.QueryEscape(s), false } client_golang-1.21.1/prometheus/push/push_test.go000066400000000000000000000204551476160432400221350ustar00rootroot00000000000000// Copyright 2016 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package push import ( "bytes" "errors" "io" "net/http" "net/http/httptest" "testing" "github.com/prometheus/common/expfmt" "github.com/prometheus/client_golang/prometheus" ) func TestPush(t *testing.T) { var ( lastMethod string lastBody []byte lastPath string lastHeader http.Header ) // Fake a Pushgateway that responds with 202 to DELETE and with 200 in // all other cases. pgwOK := httptest.NewServer( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { lastMethod = r.Method lastHeader = r.Header var err error lastBody, err = io.ReadAll(r.Body) if err != nil { t.Fatal(err) } lastPath = r.URL.EscapedPath() w.Header().Set("Content-Type", `text/plain; charset=utf-8`) if r.Method == http.MethodDelete { w.WriteHeader(http.StatusAccepted) return } w.WriteHeader(http.StatusOK) }), ) defer pgwOK.Close() // Fake a Pushgateway that always responds with 500. pgwErr := httptest.NewServer( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "fake error", http.StatusInternalServerError) }), ) defer pgwErr.Close() metric1 := prometheus.NewCounter(prometheus.CounterOpts{ Name: "testname1", Help: "testhelp1", }) metric2 := prometheus.NewGauge(prometheus.GaugeOpts{ Name: "testname2", Help: "testhelp2", ConstLabels: prometheus.Labels{"foo": "bar", "dings": "bums"}, }) reg := prometheus.NewRegistry() reg.MustRegister(metric1) reg.MustRegister(metric2) mfs, err := reg.Gather() if err != nil { t.Fatal(err) } buf := &bytes.Buffer{} enc := expfmt.NewEncoder(buf, expfmt.NewFormat(expfmt.TypeProtoDelim)) for _, mf := range mfs { if err := enc.Encode(mf); err != nil { t.Fatal(err) } } wantBody := buf.Bytes() // Push some Collectors, all good. if err := New(pgwOK.URL, "testjob"). Collector(metric1). Collector(metric2). Push(); err != nil { t.Fatal(err) } if lastMethod != http.MethodPut { t.Errorf("got method %q for Push, want %q", lastMethod, http.MethodPut) } if !bytes.Equal(lastBody, wantBody) { t.Errorf("got body %v, want %v", lastBody, wantBody) } if lastPath != "/metrics/job/testjob" { t.Error("unexpected path:", lastPath) } // Add some Collectors, with nil grouping, all good. if err := New(pgwOK.URL, "testjob"). Collector(metric1). Collector(metric2). Add(); err != nil { t.Fatal(err) } if lastMethod != http.MethodPost { t.Errorf("got method %q for Add, want %q", lastMethod, http.MethodPost) } if !bytes.Equal(lastBody, wantBody) { t.Errorf("got body %v, want %v", lastBody, wantBody) } if lastPath != "/metrics/job/testjob" { t.Error("unexpected path:", lastPath) } // Pushes that require base64 encoding. if err := New(pgwOK.URL, "test/job"). Collector(metric1). Collector(metric2). Push(); err != nil { t.Fatal(err) } if lastMethod != http.MethodPut { t.Errorf("got method %q for Push, want %q", lastMethod, http.MethodPut) } if !bytes.Equal(lastBody, wantBody) { t.Errorf("got body %v, want %v", lastBody, wantBody) } if lastPath != "/metrics/job@base64/dGVzdC9qb2I" { t.Error("unexpected path:", lastPath) } if err := New(pgwOK.URL, "testjob"). Grouping("foobar", "bu/ms"). Collector(metric1). Collector(metric2). Push(); err != nil { t.Fatal(err) } if lastMethod != http.MethodPut { t.Errorf("got method %q for Push, want %q", lastMethod, http.MethodPut) } if !bytes.Equal(lastBody, wantBody) { t.Errorf("got body %v, want %v", lastBody, wantBody) } if lastPath != "/metrics/job/testjob/foobar@base64/YnUvbXM" { t.Error("unexpected path:", lastPath) } // Push that requires URL encoding. if err := New(pgwOK.URL, "testjob"). Grouping("titan", "ΠρομηθΡύς"). Collector(metric1). Collector(metric2). Push(); err != nil { t.Fatal(err) } if lastMethod != http.MethodPut { t.Errorf("got method %q for Push, want %q", lastMethod, http.MethodPut) } if !bytes.Equal(lastBody, wantBody) { t.Errorf("got body %v, want %v", lastBody, wantBody) } if lastPath != "/metrics/job/testjob/titan/%CE%A0%CF%81%CE%BF%CE%BC%CE%B7%CE%B8%CE%B5%CF%8D%CF%82" { t.Error("unexpected path:", lastPath) } // Empty label value triggers special base64 encoding. if err := New(pgwOK.URL, "testjob"). Grouping("empty", ""). Collector(metric1). Collector(metric2). Push(); err != nil { t.Fatal(err) } if lastMethod != http.MethodPut { t.Errorf("got method %q for Push, want %q", lastMethod, http.MethodPut) } if !bytes.Equal(lastBody, wantBody) { t.Errorf("got body %v, want %v", lastBody, wantBody) } if lastPath != "/metrics/job/testjob/empty@base64/=" { t.Error("unexpected path:", lastPath) } // Empty job name results in error. if err := New(pgwErr.URL, ""). Collector(metric1). Collector(metric2). Push(); err == nil { t.Error("push with empty job succeeded") } else { if want := errJobEmpty; !errors.Is(err, want) { t.Errorf("got error %q, want %q", err, want) } } // Push some Collectors with a broken PGW. if err := New(pgwErr.URL, "testjob"). Collector(metric1). Collector(metric2). Push(); err == nil { t.Error("push to broken Pushgateway succeeded") } else { if got, want := err.Error(), "unexpected status code 500 while pushing to "+pgwErr.URL+"/metrics/job/testjob: fake error\n"; got != want { t.Errorf("got error %q, want %q", got, want) } } // Push some Collectors with invalid grouping or job. if err := New(pgwOK.URL, "testjob"). Grouping("foo", "bums"). Collector(metric1). Collector(metric2). Push(); err == nil { t.Error("push with grouping contained in metrics succeeded") } if err := New(pgwOK.URL, "testjob"). Grouping("foo\x80bar", "bums"). Collector(metric1). Collector(metric2). Push(); err == nil { t.Error("push with invalid grouping succeeded") } // Push registry, all good. if err := New(pgwOK.URL, "testjob"). Gatherer(reg). Push(); err != nil { t.Fatal(err) } if lastMethod != http.MethodPut { t.Errorf("got method %q for Push, want %q", lastMethod, http.MethodPut) } if !bytes.Equal(lastBody, wantBody) { t.Errorf("got body %v, want %v", lastBody, wantBody) } // Add registry, all good. if err := New(pgwOK.URL, "testjob"). Grouping("a", "x"). Grouping("b", "y"). Gatherer(reg). Add(); err != nil { t.Fatal(err) } if lastMethod != http.MethodPost { t.Errorf("got method %q for Add, want %q", lastMethod, http.MethodPost) } if !bytes.Equal(lastBody, wantBody) { t.Errorf("got body %v, want %v", lastBody, wantBody) } if lastPath != "/metrics/job/testjob/a/x/b/y" && lastPath != "/metrics/job/testjob/b/y/a/x" { t.Error("unexpected path:", lastPath) } // Delete, all good. if err := New(pgwOK.URL, "testjob"). Grouping("a", "x"). Grouping("b", "y"). Delete(); err != nil { t.Fatal(err) } if lastMethod != http.MethodDelete { t.Errorf("got method %q for Delete, want %q", lastMethod, http.MethodDelete) } if len(lastBody) != 0 { t.Errorf("got body of length %d, want empty body", len(lastBody)) } if lastPath != "/metrics/job/testjob/a/x/b/y" && lastPath != "/metrics/job/testjob/b/y/a/x" { t.Error("unexpected path:", lastPath) } // Push some Collectors with custom header, all good. header := make(http.Header) header.Set("Authorization", "Bearer Token") if err := New(pgwOK.URL, "testjob"). Collector(metric1). Collector(metric2). Header(header). Push(); err != nil { t.Fatal(err) } if lastMethod != http.MethodPut { t.Errorf("got method %q for Add, want %q", lastMethod, http.MethodPut) } if !bytes.Equal(lastBody, wantBody) { t.Errorf("got body %v, want %v", lastBody, wantBody) } if lastPath != "/metrics/job/testjob" { t.Error("unexpected path:", lastPath) } if lastHeader == nil || lastHeader.Get("Authorization") == "" { t.Error("empty Authorization header") } } client_golang-1.21.1/prometheus/registry.go000066400000000000000000001064561476160432400210160ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "bytes" "errors" "fmt" "os" "path/filepath" "runtime" "sort" "strconv" "strings" "sync" "unicode/utf8" "github.com/prometheus/client_golang/prometheus/internal" "github.com/cespare/xxhash/v2" dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" "google.golang.org/protobuf/proto" ) const ( // Capacity for the channel to collect metrics and descriptors. capMetricChan = 1000 capDescChan = 10 ) // DefaultRegisterer and DefaultGatherer are the implementations of the // Registerer and Gatherer interface a number of convenience functions in this // package act on. Initially, both variables point to the same Registry, which // has a process collector (currently on Linux only, see NewProcessCollector) // and a Go collector (see NewGoCollector, in particular the note about // stop-the-world implication with Go versions older than 1.9) already // registered. This approach to keep default instances as global state mirrors // the approach of other packages in the Go standard library. Note that there // are caveats. Change the variables with caution and only if you understand the // consequences. Users who want to avoid global state altogether should not use // the convenience functions and act on custom instances instead. var ( defaultRegistry = NewRegistry() DefaultRegisterer Registerer = defaultRegistry DefaultGatherer Gatherer = defaultRegistry ) func init() { MustRegister(NewProcessCollector(ProcessCollectorOpts{})) MustRegister(NewGoCollector()) } // NewRegistry creates a new vanilla Registry without any Collectors // pre-registered. func NewRegistry() *Registry { return &Registry{ collectorsByID: map[uint64]Collector{}, descIDs: map[uint64]struct{}{}, dimHashesByName: map[string]uint64{}, } } // NewPedanticRegistry returns a registry that checks during collection if each // collected Metric is consistent with its reported Desc, and if the Desc has // actually been registered with the registry. Unchecked Collectors (those whose // Describe method does not yield any descriptors) are excluded from the check. // // Usually, a Registry will be happy as long as the union of all collected // Metrics is consistent and valid even if some metrics are not consistent with // their own Desc or a Desc provided by their registered Collector. Well-behaved // Collectors and Metrics will only provide consistent Descs. This Registry is // useful to test the implementation of Collectors and Metrics. func NewPedanticRegistry() *Registry { r := NewRegistry() r.pedanticChecksEnabled = true return r } // Registerer is the interface for the part of a registry in charge of // registering and unregistering. Users of custom registries should use // Registerer as type for registration purposes (rather than the Registry type // directly). In that way, they are free to use custom Registerer implementation // (e.g. for testing purposes). type Registerer interface { // Register registers a new Collector to be included in metrics // collection. It returns an error if the descriptors provided by the // Collector are invalid or if they β€” in combination with descriptors of // already registered Collectors β€” do not fulfill the consistency and // uniqueness criteria described in the documentation of metric.Desc. // // If the provided Collector is equal to a Collector already registered // (which includes the case of re-registering the same Collector), the // returned error is an instance of AlreadyRegisteredError, which // contains the previously registered Collector. // // A Collector whose Describe method does not yield any Desc is treated // as unchecked. Registration will always succeed. No check for // re-registering (see previous paragraph) is performed. Thus, the // caller is responsible for not double-registering the same unchecked // Collector, and for providing a Collector that will not cause // inconsistent metrics on collection. (This would lead to scrape // errors.) Register(Collector) error // MustRegister works like Register but registers any number of // Collectors and panics upon the first registration that causes an // error. MustRegister(...Collector) // Unregister unregisters the Collector that equals the Collector passed // in as an argument. (Two Collectors are considered equal if their // Describe method yields the same set of descriptors.) The function // returns whether a Collector was unregistered. Note that an unchecked // Collector cannot be unregistered (as its Describe method does not // yield any descriptor). // // Note that even after unregistering, it will not be possible to // register a new Collector that is inconsistent with the unregistered // Collector, e.g. a Collector collecting metrics with the same name but // a different help string. The rationale here is that the same registry // instance must only collect consistent metrics throughout its // lifetime. Unregister(Collector) bool } // Gatherer is the interface for the part of a registry in charge of gathering // the collected metrics into a number of MetricFamilies. The Gatherer interface // comes with the same general implication as described for the Registerer // interface. type Gatherer interface { // Gather calls the Collect method of the registered Collectors and then // gathers the collected metrics into a lexicographically sorted slice // of uniquely named MetricFamily protobufs. Gather ensures that the // returned slice is valid and self-consistent so that it can be used // for valid exposition. As an exception to the strict consistency // requirements described for metric.Desc, Gather will tolerate // different sets of label names for metrics of the same metric family. // // Even if an error occurs, Gather attempts to gather as many metrics as // possible. Hence, if a non-nil error is returned, the returned // MetricFamily slice could be nil (in case of a fatal error that // prevented any meaningful metric collection) or contain a number of // MetricFamily protobufs, some of which might be incomplete, and some // might be missing altogether. The returned error (which might be a // MultiError) explains the details. Note that this is mostly useful for // debugging purposes. If the gathered protobufs are to be used for // exposition in actual monitoring, it is almost always better to not // expose an incomplete result and instead disregard the returned // MetricFamily protobufs in case the returned error is non-nil. Gather() ([]*dto.MetricFamily, error) } // Register registers the provided Collector with the DefaultRegisterer. // // Register is a shortcut for DefaultRegisterer.Register(c). See there for more // details. func Register(c Collector) error { return DefaultRegisterer.Register(c) } // MustRegister registers the provided Collectors with the DefaultRegisterer and // panics if any error occurs. // // MustRegister is a shortcut for DefaultRegisterer.MustRegister(cs...). See // there for more details. func MustRegister(cs ...Collector) { DefaultRegisterer.MustRegister(cs...) } // Unregister removes the registration of the provided Collector from the // DefaultRegisterer. // // Unregister is a shortcut for DefaultRegisterer.Unregister(c). See there for // more details. func Unregister(c Collector) bool { return DefaultRegisterer.Unregister(c) } // GathererFunc turns a function into a Gatherer. type GathererFunc func() ([]*dto.MetricFamily, error) // Gather implements Gatherer. func (gf GathererFunc) Gather() ([]*dto.MetricFamily, error) { return gf() } // AlreadyRegisteredError is returned by the Register method if the Collector to // be registered has already been registered before, or a different Collector // that collects the same metrics has been registered before. Registration fails // in that case, but you can detect from the kind of error what has // happened. The error contains fields for the existing Collector and the // (rejected) new Collector that equals the existing one. This can be used to // find out if an equal Collector has been registered before and switch over to // using the old one, as demonstrated in the example. type AlreadyRegisteredError struct { ExistingCollector, NewCollector Collector } func (err AlreadyRegisteredError) Error() string { return "duplicate metrics collector registration attempted" } // MultiError is a slice of errors implementing the error interface. It is used // by a Gatherer to report multiple errors during MetricFamily gathering. type MultiError []error // Error formats the contained errors as a bullet point list, preceded by the // total number of errors. Note that this results in a multi-line string. func (errs MultiError) Error() string { if len(errs) == 0 { return "" } buf := &bytes.Buffer{} fmt.Fprintf(buf, "%d error(s) occurred:", len(errs)) for _, err := range errs { fmt.Fprintf(buf, "\n* %s", err) } return buf.String() } // Append appends the provided error if it is not nil. func (errs *MultiError) Append(err error) { if err != nil { *errs = append(*errs, err) } } // MaybeUnwrap returns nil if len(errs) is 0. It returns the first and only // contained error as error if len(errs is 1). In all other cases, it returns // the MultiError directly. This is helpful for returning a MultiError in a way // that only uses the MultiError if needed. func (errs MultiError) MaybeUnwrap() error { switch len(errs) { case 0: return nil case 1: return errs[0] default: return errs } } // Registry registers Prometheus collectors, collects their metrics, and gathers // them into MetricFamilies for exposition. It implements Registerer, Gatherer, // and Collector. The zero value is not usable. Create instances with // NewRegistry or NewPedanticRegistry. // // Registry implements Collector to allow it to be used for creating groups of // metrics. See the Grouping example for how this can be done. type Registry struct { mtx sync.RWMutex collectorsByID map[uint64]Collector // ID is a hash of the descIDs. descIDs map[uint64]struct{} dimHashesByName map[string]uint64 uncheckedCollectors []Collector pedanticChecksEnabled bool } // Register implements Registerer. func (r *Registry) Register(c Collector) error { var ( descChan = make(chan *Desc, capDescChan) newDescIDs = map[uint64]struct{}{} newDimHashesByName = map[string]uint64{} collectorID uint64 // All desc IDs XOR'd together. duplicateDescErr error ) go func() { c.Describe(descChan) close(descChan) }() r.mtx.Lock() defer func() { // Drain channel in case of premature return to not leak a goroutine. for range descChan { } r.mtx.Unlock() }() // Conduct various tests... for desc := range descChan { // Is the descriptor valid at all? if desc.err != nil { return fmt.Errorf("descriptor %s is invalid: %w", desc, desc.err) } // Is the descID unique? // (In other words: Is the fqName + constLabel combination unique?) if _, exists := r.descIDs[desc.id]; exists { duplicateDescErr = fmt.Errorf("descriptor %s already exists with the same fully-qualified name and const label values", desc) } // If it is not a duplicate desc in this collector, XOR it to // the collectorID. (We allow duplicate descs within the same // collector, but their existence must be a no-op.) if _, exists := newDescIDs[desc.id]; !exists { newDescIDs[desc.id] = struct{}{} collectorID ^= desc.id } // Are all the label names and the help string consistent with // previous descriptors of the same name? // First check existing descriptors... if dimHash, exists := r.dimHashesByName[desc.fqName]; exists { if dimHash != desc.dimHash { return fmt.Errorf("a previously registered descriptor with the same fully-qualified name as %s has different label names or a different help string", desc) } continue } // ...then check the new descriptors already seen. if dimHash, exists := newDimHashesByName[desc.fqName]; exists { if dimHash != desc.dimHash { return fmt.Errorf("descriptors reported by collector have inconsistent label names or help strings for the same fully-qualified name, offender is %s", desc) } continue } newDimHashesByName[desc.fqName] = desc.dimHash } // A Collector yielding no Desc at all is considered unchecked. if len(newDescIDs) == 0 { r.uncheckedCollectors = append(r.uncheckedCollectors, c) return nil } if existing, exists := r.collectorsByID[collectorID]; exists { switch e := existing.(type) { case *wrappingCollector: return AlreadyRegisteredError{ ExistingCollector: e.unwrapRecursively(), NewCollector: c, } default: return AlreadyRegisteredError{ ExistingCollector: e, NewCollector: c, } } } // If the collectorID is new, but at least one of the descs existed // before, we are in trouble. if duplicateDescErr != nil { return duplicateDescErr } // Only after all tests have passed, actually register. r.collectorsByID[collectorID] = c for hash := range newDescIDs { r.descIDs[hash] = struct{}{} } for name, dimHash := range newDimHashesByName { r.dimHashesByName[name] = dimHash } return nil } // Unregister implements Registerer. func (r *Registry) Unregister(c Collector) bool { var ( descChan = make(chan *Desc, capDescChan) descIDs = map[uint64]struct{}{} collectorID uint64 // All desc IDs XOR'd together. ) go func() { c.Describe(descChan) close(descChan) }() for desc := range descChan { if _, exists := descIDs[desc.id]; !exists { collectorID ^= desc.id descIDs[desc.id] = struct{}{} } } r.mtx.RLock() if _, exists := r.collectorsByID[collectorID]; !exists { r.mtx.RUnlock() return false } r.mtx.RUnlock() r.mtx.Lock() defer r.mtx.Unlock() delete(r.collectorsByID, collectorID) for id := range descIDs { delete(r.descIDs, id) } // dimHashesByName is left untouched as those must be consistent // throughout the lifetime of a program. return true } // MustRegister implements Registerer. func (r *Registry) MustRegister(cs ...Collector) { for _, c := range cs { if err := r.Register(c); err != nil { panic(err) } } } // Gather implements Gatherer. func (r *Registry) Gather() ([]*dto.MetricFamily, error) { r.mtx.RLock() if len(r.collectorsByID) == 0 && len(r.uncheckedCollectors) == 0 { // Fast path. r.mtx.RUnlock() return nil, nil } var ( checkedMetricChan = make(chan Metric, capMetricChan) uncheckedMetricChan = make(chan Metric, capMetricChan) metricHashes = map[uint64]struct{}{} wg sync.WaitGroup errs MultiError // The collected errors to return in the end. registeredDescIDs map[uint64]struct{} // Only used for pedantic checks ) goroutineBudget := len(r.collectorsByID) + len(r.uncheckedCollectors) metricFamiliesByName := make(map[string]*dto.MetricFamily, len(r.dimHashesByName)) checkedCollectors := make(chan Collector, len(r.collectorsByID)) uncheckedCollectors := make(chan Collector, len(r.uncheckedCollectors)) for _, collector := range r.collectorsByID { checkedCollectors <- collector } for _, collector := range r.uncheckedCollectors { uncheckedCollectors <- collector } // In case pedantic checks are enabled, we have to copy the map before // giving up the RLock. if r.pedanticChecksEnabled { registeredDescIDs = make(map[uint64]struct{}, len(r.descIDs)) for id := range r.descIDs { registeredDescIDs[id] = struct{}{} } } r.mtx.RUnlock() wg.Add(goroutineBudget) collectWorker := func() { for { select { case collector := <-checkedCollectors: collector.Collect(checkedMetricChan) case collector := <-uncheckedCollectors: collector.Collect(uncheckedMetricChan) default: return } wg.Done() } } // Start the first worker now to make sure at least one is running. go collectWorker() goroutineBudget-- // Close checkedMetricChan and uncheckedMetricChan once all collectors // are collected. go func() { wg.Wait() close(checkedMetricChan) close(uncheckedMetricChan) }() // Drain checkedMetricChan and uncheckedMetricChan in case of premature return. defer func() { if checkedMetricChan != nil { for range checkedMetricChan { } } if uncheckedMetricChan != nil { for range uncheckedMetricChan { } } }() // Copy the channel references so we can nil them out later to remove // them from the select statements below. cmc := checkedMetricChan umc := uncheckedMetricChan for { select { case metric, ok := <-cmc: if !ok { cmc = nil break } errs.Append(processMetric( metric, metricFamiliesByName, metricHashes, registeredDescIDs, )) case metric, ok := <-umc: if !ok { umc = nil break } errs.Append(processMetric( metric, metricFamiliesByName, metricHashes, nil, )) default: if goroutineBudget <= 0 || len(checkedCollectors)+len(uncheckedCollectors) == 0 { // All collectors are already being worked on or // we have already as many goroutines started as // there are collectors. Do the same as above, // just without the default. select { case metric, ok := <-cmc: if !ok { cmc = nil break } errs.Append(processMetric( metric, metricFamiliesByName, metricHashes, registeredDescIDs, )) case metric, ok := <-umc: if !ok { umc = nil break } errs.Append(processMetric( metric, metricFamiliesByName, metricHashes, nil, )) } break } // Start more workers. go collectWorker() goroutineBudget-- runtime.Gosched() } // Once both checkedMetricChan and uncheckedMetricChan are closed // and drained, the contraption above will nil out cmc and umc, // and then we can leave the collect loop here. if cmc == nil && umc == nil { break } } return internal.NormalizeMetricFamilies(metricFamiliesByName), errs.MaybeUnwrap() } // Describe implements Collector. func (r *Registry) Describe(ch chan<- *Desc) { r.mtx.RLock() defer r.mtx.RUnlock() // Only report the checked Collectors; unchecked collectors don't report any // Desc. for _, c := range r.collectorsByID { c.Describe(ch) } } // Collect implements Collector. func (r *Registry) Collect(ch chan<- Metric) { r.mtx.RLock() defer r.mtx.RUnlock() for _, c := range r.collectorsByID { c.Collect(ch) } for _, c := range r.uncheckedCollectors { c.Collect(ch) } } // WriteToTextfile calls Gather on the provided Gatherer, encodes the result in the // Prometheus text format, and writes it to a temporary file. Upon success, the // temporary file is renamed to the provided filename. // // This is intended for use with the textfile collector of the node exporter. // Note that the node exporter expects the filename to be suffixed with ".prom". func WriteToTextfile(filename string, g Gatherer) error { tmp, err := os.CreateTemp(filepath.Dir(filename), filepath.Base(filename)) if err != nil { return err } defer os.Remove(tmp.Name()) mfs, err := g.Gather() if err != nil { return err } for _, mf := range mfs { if _, err := expfmt.MetricFamilyToText(tmp, mf); err != nil { return err } } if err := tmp.Close(); err != nil { return err } if err := os.Chmod(tmp.Name(), 0o644); err != nil { return err } return os.Rename(tmp.Name(), filename) } // processMetric is an internal helper method only used by the Gather method. func processMetric( metric Metric, metricFamiliesByName map[string]*dto.MetricFamily, metricHashes map[uint64]struct{}, registeredDescIDs map[uint64]struct{}, ) error { desc := metric.Desc() // Wrapped metrics collected by an unchecked Collector can have an // invalid Desc. if desc.err != nil { return desc.err } dtoMetric := &dto.Metric{} if err := metric.Write(dtoMetric); err != nil { return fmt.Errorf("error collecting metric %v: %w", desc, err) } metricFamily, ok := metricFamiliesByName[desc.fqName] if ok { // Existing name. if metricFamily.GetHelp() != desc.help { return fmt.Errorf( "collected metric %s %s has help %q but should have %q", desc.fqName, dtoMetric, desc.help, metricFamily.GetHelp(), ) } // TODO(beorn7): Simplify switch once Desc has type. switch metricFamily.GetType() { case dto.MetricType_COUNTER: if dtoMetric.Counter == nil { return fmt.Errorf( "collected metric %s %s should be a Counter", desc.fqName, dtoMetric, ) } case dto.MetricType_GAUGE: if dtoMetric.Gauge == nil { return fmt.Errorf( "collected metric %s %s should be a Gauge", desc.fqName, dtoMetric, ) } case dto.MetricType_SUMMARY: if dtoMetric.Summary == nil { return fmt.Errorf( "collected metric %s %s should be a Summary", desc.fqName, dtoMetric, ) } case dto.MetricType_UNTYPED: if dtoMetric.Untyped == nil { return fmt.Errorf( "collected metric %s %s should be Untyped", desc.fqName, dtoMetric, ) } case dto.MetricType_HISTOGRAM: if dtoMetric.Histogram == nil { return fmt.Errorf( "collected metric %s %s should be a Histogram", desc.fqName, dtoMetric, ) } default: panic("encountered MetricFamily with invalid type") } } else { // New name. metricFamily = &dto.MetricFamily{} metricFamily.Name = proto.String(desc.fqName) metricFamily.Help = proto.String(desc.help) // TODO(beorn7): Simplify switch once Desc has type. switch { case dtoMetric.Gauge != nil: metricFamily.Type = dto.MetricType_GAUGE.Enum() case dtoMetric.Counter != nil: metricFamily.Type = dto.MetricType_COUNTER.Enum() case dtoMetric.Summary != nil: metricFamily.Type = dto.MetricType_SUMMARY.Enum() case dtoMetric.Untyped != nil: metricFamily.Type = dto.MetricType_UNTYPED.Enum() case dtoMetric.Histogram != nil: metricFamily.Type = dto.MetricType_HISTOGRAM.Enum() default: return fmt.Errorf("empty metric collected: %s", dtoMetric) } if err := checkSuffixCollisions(metricFamily, metricFamiliesByName); err != nil { return err } metricFamiliesByName[desc.fqName] = metricFamily } if err := checkMetricConsistency(metricFamily, dtoMetric, metricHashes); err != nil { return err } if registeredDescIDs != nil { // Is the desc registered at all? if _, exist := registeredDescIDs[desc.id]; !exist { return fmt.Errorf( "collected metric %s %s with unregistered descriptor %s", metricFamily.GetName(), dtoMetric, desc, ) } if err := checkDescConsistency(metricFamily, dtoMetric, desc); err != nil { return err } } metricFamily.Metric = append(metricFamily.Metric, dtoMetric) return nil } // Gatherers is a slice of Gatherer instances that implements the Gatherer // interface itself. Its Gather method calls Gather on all Gatherers in the // slice in order and returns the merged results. Errors returned from the // Gather calls are all returned in a flattened MultiError. Duplicate and // inconsistent Metrics are skipped (first occurrence in slice order wins) and // reported in the returned error. // // Gatherers can be used to merge the Gather results from multiple // Registries. It also provides a way to directly inject existing MetricFamily // protobufs into the gathering by creating a custom Gatherer with a Gather // method that simply returns the existing MetricFamily protobufs. Note that no // registration is involved (in contrast to Collector registration), so // obviously registration-time checks cannot happen. Any inconsistencies between // the gathered MetricFamilies are reported as errors by the Gather method, and // inconsistent Metrics are dropped. Invalid parts of the MetricFamilies // (e.g. syntactically invalid metric or label names) will go undetected. type Gatherers []Gatherer // Gather implements Gatherer. func (gs Gatherers) Gather() ([]*dto.MetricFamily, error) { var ( metricFamiliesByName = map[string]*dto.MetricFamily{} metricHashes = map[uint64]struct{}{} errs MultiError // The collected errors to return in the end. ) for i, g := range gs { mfs, err := g.Gather() if err != nil { multiErr := MultiError{} if errors.As(err, &multiErr) { for _, err := range multiErr { errs = append(errs, fmt.Errorf("[from Gatherer #%d] %w", i+1, err)) } } else { errs = append(errs, fmt.Errorf("[from Gatherer #%d] %w", i+1, err)) } } for _, mf := range mfs { existingMF, exists := metricFamiliesByName[mf.GetName()] if exists { if existingMF.GetHelp() != mf.GetHelp() { errs = append(errs, fmt.Errorf( "gathered metric family %s has help %q but should have %q", mf.GetName(), mf.GetHelp(), existingMF.GetHelp(), )) continue } if existingMF.GetType() != mf.GetType() { errs = append(errs, fmt.Errorf( "gathered metric family %s has type %s but should have %s", mf.GetName(), mf.GetType(), existingMF.GetType(), )) continue } } else { existingMF = &dto.MetricFamily{} existingMF.Name = mf.Name existingMF.Help = mf.Help existingMF.Type = mf.Type if err := checkSuffixCollisions(existingMF, metricFamiliesByName); err != nil { errs = append(errs, err) continue } metricFamiliesByName[mf.GetName()] = existingMF } for _, m := range mf.Metric { if err := checkMetricConsistency(existingMF, m, metricHashes); err != nil { errs = append(errs, err) continue } existingMF.Metric = append(existingMF.Metric, m) } } } return internal.NormalizeMetricFamilies(metricFamiliesByName), errs.MaybeUnwrap() } // checkSuffixCollisions checks for collisions with the β€œmagic” suffixes the // Prometheus text format and the internal metric representation of the // Prometheus server add while flattening Summaries and Histograms. func checkSuffixCollisions(mf *dto.MetricFamily, mfs map[string]*dto.MetricFamily) error { var ( newName = mf.GetName() newType = mf.GetType() newNameWithoutSuffix = "" ) switch { case strings.HasSuffix(newName, "_count"): newNameWithoutSuffix = newName[:len(newName)-6] case strings.HasSuffix(newName, "_sum"): newNameWithoutSuffix = newName[:len(newName)-4] case strings.HasSuffix(newName, "_bucket"): newNameWithoutSuffix = newName[:len(newName)-7] } if newNameWithoutSuffix != "" { if existingMF, ok := mfs[newNameWithoutSuffix]; ok { switch existingMF.GetType() { case dto.MetricType_SUMMARY: if !strings.HasSuffix(newName, "_bucket") { return fmt.Errorf( "collected metric named %q collides with previously collected summary named %q", newName, newNameWithoutSuffix, ) } case dto.MetricType_HISTOGRAM: return fmt.Errorf( "collected metric named %q collides with previously collected histogram named %q", newName, newNameWithoutSuffix, ) } } } if newType == dto.MetricType_SUMMARY || newType == dto.MetricType_HISTOGRAM { if _, ok := mfs[newName+"_count"]; ok { return fmt.Errorf( "collected histogram or summary named %q collides with previously collected metric named %q", newName, newName+"_count", ) } if _, ok := mfs[newName+"_sum"]; ok { return fmt.Errorf( "collected histogram or summary named %q collides with previously collected metric named %q", newName, newName+"_sum", ) } } if newType == dto.MetricType_HISTOGRAM { if _, ok := mfs[newName+"_bucket"]; ok { return fmt.Errorf( "collected histogram named %q collides with previously collected metric named %q", newName, newName+"_bucket", ) } } return nil } // checkMetricConsistency checks if the provided Metric is consistent with the // provided MetricFamily. It also hashes the Metric labels and the MetricFamily // name. If the resulting hash is already in the provided metricHashes, an error // is returned. If not, it is added to metricHashes. func checkMetricConsistency( metricFamily *dto.MetricFamily, dtoMetric *dto.Metric, metricHashes map[uint64]struct{}, ) error { name := metricFamily.GetName() // Type consistency with metric family. if metricFamily.GetType() == dto.MetricType_GAUGE && dtoMetric.Gauge == nil || metricFamily.GetType() == dto.MetricType_COUNTER && dtoMetric.Counter == nil || metricFamily.GetType() == dto.MetricType_SUMMARY && dtoMetric.Summary == nil || metricFamily.GetType() == dto.MetricType_HISTOGRAM && dtoMetric.Histogram == nil || metricFamily.GetType() == dto.MetricType_UNTYPED && dtoMetric.Untyped == nil { return fmt.Errorf( "collected metric %q { %s} is not a %s", name, dtoMetric, metricFamily.GetType(), ) } previousLabelName := "" for _, labelPair := range dtoMetric.GetLabel() { labelName := labelPair.GetName() if labelName == previousLabelName { return fmt.Errorf( "collected metric %q { %s} has two or more labels with the same name: %s", name, dtoMetric, labelName, ) } if !checkLabelName(labelName) { return fmt.Errorf( "collected metric %q { %s} has a label with an invalid name: %s", name, dtoMetric, labelName, ) } if dtoMetric.Summary != nil && labelName == quantileLabel { return fmt.Errorf( "collected metric %q { %s} must not have an explicit %q label", name, dtoMetric, quantileLabel, ) } if !utf8.ValidString(labelPair.GetValue()) { return fmt.Errorf( "collected metric %q { %s} has a label named %q whose value is not utf8: %#v", name, dtoMetric, labelName, labelPair.GetValue()) } previousLabelName = labelName } // Is the metric unique (i.e. no other metric with the same name and the same labels)? h := xxhash.New() h.WriteString(name) h.Write(separatorByteSlice) // Make sure label pairs are sorted. We depend on it for the consistency // check. if !sort.IsSorted(internal.LabelPairSorter(dtoMetric.Label)) { // We cannot sort dtoMetric.Label in place as it is immutable by contract. copiedLabels := make([]*dto.LabelPair, len(dtoMetric.Label)) copy(copiedLabels, dtoMetric.Label) sort.Sort(internal.LabelPairSorter(copiedLabels)) dtoMetric.Label = copiedLabels } for _, lp := range dtoMetric.Label { h.WriteString(lp.GetName()) h.Write(separatorByteSlice) h.WriteString(lp.GetValue()) h.Write(separatorByteSlice) } if dtoMetric.TimestampMs != nil { h.WriteString(strconv.FormatInt(*(dtoMetric.TimestampMs), 10)) h.Write(separatorByteSlice) } hSum := h.Sum64() if _, exists := metricHashes[hSum]; exists { return fmt.Errorf( "collected metric %q { %s} was collected before with the same name and label values", name, dtoMetric, ) } metricHashes[hSum] = struct{}{} return nil } func checkDescConsistency( metricFamily *dto.MetricFamily, dtoMetric *dto.Metric, desc *Desc, ) error { // Desc help consistency with metric family help. if metricFamily.GetHelp() != desc.help { return fmt.Errorf( "collected metric %s %s has help %q but should have %q", metricFamily.GetName(), dtoMetric, metricFamily.GetHelp(), desc.help, ) } // Is the desc consistent with the content of the metric? lpsFromDesc := make([]*dto.LabelPair, len(desc.constLabelPairs), len(dtoMetric.Label)) copy(lpsFromDesc, desc.constLabelPairs) for _, l := range desc.variableLabels.names { lpsFromDesc = append(lpsFromDesc, &dto.LabelPair{ Name: proto.String(l), }) } if len(lpsFromDesc) != len(dtoMetric.Label) { return fmt.Errorf( "labels in collected metric %s %s are inconsistent with descriptor %s", metricFamily.GetName(), dtoMetric, desc, ) } sort.Sort(internal.LabelPairSorter(lpsFromDesc)) for i, lpFromDesc := range lpsFromDesc { lpFromMetric := dtoMetric.Label[i] if lpFromDesc.GetName() != lpFromMetric.GetName() || lpFromDesc.Value != nil && lpFromDesc.GetValue() != lpFromMetric.GetValue() { return fmt.Errorf( "labels in collected metric %s %s are inconsistent with descriptor %s", metricFamily.GetName(), dtoMetric, desc, ) } } return nil } var _ TransactionalGatherer = &MultiTRegistry{} // MultiTRegistry is a TransactionalGatherer that joins gathered metrics from multiple // transactional gatherers. // // It is caller responsibility to ensure two registries have mutually exclusive metric families, // no deduplication will happen. type MultiTRegistry struct { tGatherers []TransactionalGatherer } // NewMultiTRegistry creates MultiTRegistry. func NewMultiTRegistry(tGatherers ...TransactionalGatherer) *MultiTRegistry { return &MultiTRegistry{ tGatherers: tGatherers, } } // Gather implements TransactionalGatherer interface. func (r *MultiTRegistry) Gather() (mfs []*dto.MetricFamily, done func(), err error) { errs := MultiError{} dFns := make([]func(), 0, len(r.tGatherers)) // TODO(bwplotka): Implement concurrency for those? for _, g := range r.tGatherers { // TODO(bwplotka): Check for duplicates? m, d, err := g.Gather() errs.Append(err) mfs = append(mfs, m...) dFns = append(dFns, d) } // TODO(bwplotka): Consider sort in place, given metric family in gather is sorted already. sort.Slice(mfs, func(i, j int) bool { return *mfs[i].Name < *mfs[j].Name }) return mfs, func() { for _, d := range dFns { d() } }, errs.MaybeUnwrap() } // TransactionalGatherer represents transactional gatherer that can be triggered to notify gatherer that memory // used by metric family is no longer used by a caller. This allows implementations with cache. type TransactionalGatherer interface { // Gather returns metrics in a lexicographically sorted slice // of uniquely named MetricFamily protobufs. Gather ensures that the // returned slice is valid and self-consistent so that it can be used // for valid exposition. As an exception to the strict consistency // requirements described for metric.Desc, Gather will tolerate // different sets of label names for metrics of the same metric family. // // Even if an error occurs, Gather attempts to gather as many metrics as // possible. Hence, if a non-nil error is returned, the returned // MetricFamily slice could be nil (in case of a fatal error that // prevented any meaningful metric collection) or contain a number of // MetricFamily protobufs, some of which might be incomplete, and some // might be missing altogether. The returned error (which might be a // MultiError) explains the details. Note that this is mostly useful for // debugging purposes. If the gathered protobufs are to be used for // exposition in actual monitoring, it is almost always better to not // expose an incomplete result and instead disregard the returned // MetricFamily protobufs in case the returned error is non-nil. // // Important: done is expected to be triggered (even if the error occurs!) // once caller does not need returned slice of dto.MetricFamily. Gather() (_ []*dto.MetricFamily, done func(), err error) } // ToTransactionalGatherer transforms Gatherer to transactional one with noop as done function. func ToTransactionalGatherer(g Gatherer) TransactionalGatherer { return &noTransactionGatherer{g: g} } type noTransactionGatherer struct { g Gatherer } // Gather implements TransactionalGatherer interface. func (g *noTransactionGatherer) Gather() (_ []*dto.MetricFamily, done func(), err error) { mfs, err := g.g.Gather() return mfs, func() {}, err } client_golang-1.21.1/prometheus/registry_test.go000066400000000000000000001121731476160432400220460ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Copyright (c) 2013, The Prometheus Authors // All rights reserved. // // Use of this source code is governed by a BSD-style license that can be found // in the LICENSE file. package prometheus_test import ( "bytes" "errors" "fmt" "math/rand" "net/http" "net/http/httptest" "os" "strconv" "sync" "testing" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" ) // uncheckedCollector wraps a Collector but its Describe method yields no Desc. type uncheckedCollector struct { c prometheus.Collector } func (u uncheckedCollector) Describe(_ chan<- *prometheus.Desc) {} func (u uncheckedCollector) Collect(c chan<- prometheus.Metric) { u.c.Collect(c) } func testHandler(t testing.TB) { // TODO(beorn7): This test is a bit too "end-to-end". It tests quite a // few moving parts that are not strongly coupled. They could/should be // tested separately. However, the changes planned for v2 will // require a major rework of this test anyway, at which time I will // structure it in a better way. metricVec := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "name", Help: "docstring", ConstLabels: prometheus.Labels{"constname": "constvalue"}, }, []string{"labelname"}, ) metricVec.WithLabelValues("val1").Inc() metricVec.WithLabelValues("val2").Inc() externalMetricFamily := &dto.MetricFamily{ Name: proto.String("externalname"), Help: proto.String("externaldocstring"), Type: dto.MetricType_COUNTER.Enum(), Metric: []*dto.Metric{ { Label: []*dto.LabelPair{ { Name: proto.String("externalconstname"), Value: proto.String("externalconstvalue"), }, { Name: proto.String("externallabelname"), Value: proto.String("externalval1"), }, }, Counter: &dto.Counter{ Value: proto.Float64(1), }, }, }, } externalBuf := &bytes.Buffer{} enc := expfmt.NewEncoder(externalBuf, expfmt.NewFormat(expfmt.TypeProtoDelim)) if err := enc.Encode(externalMetricFamily); err != nil { t.Fatal(err) } externalMetricFamilyAsBytes := externalBuf.Bytes() externalMetricFamilyAsText := []byte(`# HELP externalname externaldocstring # TYPE externalname counter externalname{externalconstname="externalconstvalue",externallabelname="externalval1"} 1 `) externalMetricFamilyAsProtoText := []byte(`name: "externalname" help: "externaldocstring" type: COUNTER metric: < label: < name: "externalconstname" value: "externalconstvalue" > label: < name: "externallabelname" value: "externalval1" > counter: < value: 1 > > `) externalMetricFamilyAsProtoCompactText := []byte(`name:"externalname" help:"externaldocstring" type:COUNTER metric: label: counter: >`) externalMetricFamilyAsProtoCompactText = append(externalMetricFamilyAsProtoCompactText, []byte(" \n")...) expectedMetricFamily := &dto.MetricFamily{ Name: proto.String("name"), Help: proto.String("docstring"), Type: dto.MetricType_COUNTER.Enum(), Metric: []*dto.Metric{ { Label: []*dto.LabelPair{ { Name: proto.String("constname"), Value: proto.String("constvalue"), }, { Name: proto.String("labelname"), Value: proto.String("val1"), }, }, Counter: &dto.Counter{ Value: proto.Float64(1), CreatedTimestamp: timestamppb.New(time.Now()), }, }, { Label: []*dto.LabelPair{ { Name: proto.String("constname"), Value: proto.String("constvalue"), }, { Name: proto.String("labelname"), Value: proto.String("val2"), }, }, Counter: &dto.Counter{ Value: proto.Float64(1), CreatedTimestamp: timestamppb.New(time.Now()), }, }, }, } buf := &bytes.Buffer{} enc = expfmt.NewEncoder(buf, expfmt.NewFormat(expfmt.TypeProtoDelim)) if err := enc.Encode(expectedMetricFamily); err != nil { t.Fatal(err) } expectedMetricFamilyAsBytes := buf.Bytes() expectedMetricFamilyAsText := []byte(`# HELP name docstring # TYPE name counter name{constname="constvalue",labelname="val1"} 1 name{constname="constvalue",labelname="val2"} 1 `) expectedMetricFamilyAsProtoText := []byte(`name: "name" help: "docstring" type: COUNTER metric: < label: < name: "constname" value: "constvalue" > label: < name: "labelname" value: "val1" > counter: < value: 1 > > metric: < label: < name: "constname" value: "constvalue" > label: < name: "labelname" value: "val2" > counter: < value: 1 > > `) expectedMetricFamilyAsProtoCompactText := []byte(`name:"name" help:"docstring" type:COUNTER metric: label: counter: > metric: label: counter: >`) expectedMetricFamilyAsProtoCompactText = append(expectedMetricFamilyAsProtoCompactText, []byte(" \n")...) externalMetricFamilyWithSameName := &dto.MetricFamily{ Name: proto.String("name"), Help: proto.String("docstring"), Type: dto.MetricType_COUNTER.Enum(), Metric: []*dto.Metric{ { Label: []*dto.LabelPair{ { Name: proto.String("constname"), Value: proto.String("constvalue"), }, { Name: proto.String("labelname"), Value: proto.String("different_val"), }, }, Counter: &dto.Counter{ Value: proto.Float64(42), }, }, }, } expectedMetricFamilyMergedWithExternalAsProtoCompactText := []byte(`name:"name" help:"docstring" type:COUNTER metric: label: counter: > metric: label: counter: > metric: label: counter: >`) expectedMetricFamilyMergedWithExternalAsProtoCompactText = append(expectedMetricFamilyMergedWithExternalAsProtoCompactText, []byte(" \n")...) externalMetricFamilyWithInvalidLabelValue := &dto.MetricFamily{ Name: proto.String("name"), Help: proto.String("docstring"), Type: dto.MetricType_COUNTER.Enum(), Metric: []*dto.Metric{ { Label: []*dto.LabelPair{ { Name: proto.String("constname"), Value: proto.String("\xFF"), }, { Name: proto.String("labelname"), Value: proto.String("different_val"), }, }, Counter: &dto.Counter{ Value: proto.Float64(42), }, }, }, } expectedMetricFamilyInvalidLabelValueAsText := []byte(`An error has occurred while serving metrics: collected metric "name" { label: label: counter: } has a label named "constname" whose value is not utf8: "\xff" `) summary := prometheus.NewSummary(prometheus.SummaryOpts{ Name: "complex", Help: "A metric to check collisions with _sum and _count.", Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, }) summaryAsText := []byte(`# HELP complex A metric to check collisions with _sum and _count. # TYPE complex summary complex{quantile="0.5"} NaN complex{quantile="0.9"} NaN complex{quantile="0.99"} NaN complex_sum 0 complex_count 0 `) histogram := prometheus.NewHistogram(prometheus.HistogramOpts{ Name: "complex", Help: "A metric to check collisions with _sun, _count, and _bucket.", }) externalMetricFamilyWithBucketSuffix := &dto.MetricFamily{ Name: proto.String("complex_bucket"), Help: proto.String("externaldocstring"), Type: dto.MetricType_COUNTER.Enum(), Metric: []*dto.Metric{ { Counter: &dto.Counter{ Value: proto.Float64(1), }, }, }, } externalMetricFamilyWithBucketSuffixAsText := []byte(`# HELP complex_bucket externaldocstring # TYPE complex_bucket counter complex_bucket 1 `) externalMetricFamilyWithCountSuffix := &dto.MetricFamily{ Name: proto.String("complex_count"), Help: proto.String("externaldocstring"), Type: dto.MetricType_COUNTER.Enum(), Metric: []*dto.Metric{ { Counter: &dto.Counter{ Value: proto.Float64(1), }, }, }, } bucketCollisionMsg := []byte(`An error has occurred while serving metrics: collected metric named "complex_bucket" collides with previously collected histogram named "complex" `) summaryCountCollisionMsg := []byte(`An error has occurred while serving metrics: collected metric named "complex_count" collides with previously collected summary named "complex" `) histogramCountCollisionMsg := []byte(`An error has occurred while serving metrics: collected metric named "complex_count" collides with previously collected histogram named "complex" `) externalMetricFamilyWithDuplicateLabel := &dto.MetricFamily{ Name: proto.String("broken_metric"), Help: proto.String("The registry should detect the duplicate label."), Type: dto.MetricType_COUNTER.Enum(), Metric: []*dto.Metric{ { Label: []*dto.LabelPair{ { Name: proto.String("foo"), Value: proto.String("bar"), }, { Name: proto.String("foo"), Value: proto.String("baz"), }, }, Counter: &dto.Counter{ Value: proto.Float64(2.7), }, }, }, } duplicateLabelMsg := []byte(`An error has occurred while serving metrics: collected metric "broken_metric" { label: label: counter: } has two or more labels with the same name: foo `) type output struct { headers map[string]string body []byte } scenarios := []struct { headers map[string]string out output collector prometheus.Collector externalMF []*dto.MetricFamily }{ { // 0 headers: map[string]string{ "Accept": "foo/bar;q=0.2, dings/bums;q=0.8", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4; charset=utf-8; escaping=underscores`, }, body: []byte{}, }, }, { // 1 headers: map[string]string{ "Accept": "foo/bar;q=0.2, application/quark;q=0.8", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4; charset=utf-8; escaping=underscores`, }, body: []byte{}, }, }, { // 2 headers: map[string]string{ "Accept": "foo/bar;q=0.2, application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=bla;q=0.8", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4; charset=utf-8; escaping=underscores`, }, body: []byte{}, }, }, { // 3 headers: map[string]string{ "Accept": "text/plain;q=0.2, application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited;q=0.8", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited; escaping=underscores`, }, body: []byte{}, }, }, { // 4 headers: map[string]string{ "Accept": "application/json", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4; charset=utf-8; escaping=underscores`, }, body: expectedMetricFamilyAsText, }, collector: metricVec, }, { // 5 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited; escaping=underscores`, }, body: expectedMetricFamilyAsBytes, }, collector: metricVec, }, { // 6 headers: map[string]string{ "Accept": "application/json", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4; charset=utf-8; escaping=underscores`, }, body: externalMetricFamilyAsText, }, externalMF: []*dto.MetricFamily{externalMetricFamily}, }, { // 7 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited; escaping=underscores`, }, body: externalMetricFamilyAsBytes, }, externalMF: []*dto.MetricFamily{externalMetricFamily}, }, { // 8 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited; escaping=underscores`, }, body: bytes.Join( [][]byte{ externalMetricFamilyAsBytes, expectedMetricFamilyAsBytes, }, []byte{}, ), }, collector: metricVec, externalMF: []*dto.MetricFamily{externalMetricFamily}, }, { // 9 headers: map[string]string{ "Accept": "text/plain", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4; charset=utf-8; escaping=underscores`, }, body: []byte{}, }, }, { // 10 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=bla;q=0.2, text/plain;q=0.5", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4; charset=utf-8; escaping=underscores`, }, body: expectedMetricFamilyAsText, }, collector: metricVec, }, { // 11 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=bla;q=0.2, text/plain;q=0.5;version=0.0.4", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4; charset=utf-8; escaping=underscores`, }, body: bytes.Join( [][]byte{ externalMetricFamilyAsText, expectedMetricFamilyAsText, }, []byte{}, ), }, collector: metricVec, externalMF: []*dto.MetricFamily{externalMetricFamily}, }, { // 12 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited;q=0.2, text/plain;q=0.5;version=0.0.2", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited; escaping=underscores`, }, body: bytes.Join( [][]byte{ externalMetricFamilyAsBytes, expectedMetricFamilyAsBytes, }, []byte{}, ), }, collector: metricVec, externalMF: []*dto.MetricFamily{externalMetricFamily}, }, { // 13 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=text;q=0.5, application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited;q=0.4", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=text; escaping=underscores`, }, body: bytes.Join( [][]byte{ externalMetricFamilyAsProtoText, expectedMetricFamilyAsProtoText, }, []byte{}, ), }, collector: metricVec, externalMF: []*dto.MetricFamily{externalMetricFamily}, }, { // 14 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=compact-text", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=compact-text; escaping=underscores`, }, body: bytes.Join( [][]byte{ externalMetricFamilyAsProtoCompactText, expectedMetricFamilyAsProtoCompactText, }, []byte{}, ), }, collector: metricVec, externalMF: []*dto.MetricFamily{externalMetricFamily}, }, { // 15 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=compact-text", }, out: output{ headers: map[string]string{ "Content-Type": `application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=compact-text; escaping=underscores`, }, body: bytes.Join( [][]byte{ externalMetricFamilyAsProtoCompactText, expectedMetricFamilyMergedWithExternalAsProtoCompactText, }, []byte{}, ), }, collector: metricVec, externalMF: []*dto.MetricFamily{ externalMetricFamily, externalMetricFamilyWithSameName, }, }, { // 16 headers: map[string]string{ "Accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=compact-text", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; charset=utf-8`, }, body: expectedMetricFamilyInvalidLabelValueAsText, }, collector: metricVec, externalMF: []*dto.MetricFamily{ externalMetricFamily, externalMetricFamilyWithInvalidLabelValue, }, }, { // 17 headers: map[string]string{ "Accept": "text/plain", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4; charset=utf-8; escaping=underscores`, }, body: expectedMetricFamilyAsText, }, collector: uncheckedCollector{metricVec}, }, { // 18 headers: map[string]string{ "Accept": "text/plain", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; charset=utf-8`, }, body: histogramCountCollisionMsg, }, collector: histogram, externalMF: []*dto.MetricFamily{ externalMetricFamilyWithCountSuffix, }, }, { // 19 headers: map[string]string{ "Accept": "text/plain", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; charset=utf-8`, }, body: bucketCollisionMsg, }, collector: histogram, externalMF: []*dto.MetricFamily{ externalMetricFamilyWithBucketSuffix, }, }, { // 20 headers: map[string]string{ "Accept": "text/plain", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; charset=utf-8`, }, body: summaryCountCollisionMsg, }, collector: summary, externalMF: []*dto.MetricFamily{ externalMetricFamilyWithCountSuffix, }, }, { // 21 headers: map[string]string{ "Accept": "text/plain", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; version=0.0.4; charset=utf-8; escaping=underscores`, }, body: bytes.Join( [][]byte{ summaryAsText, externalMetricFamilyWithBucketSuffixAsText, }, []byte{}, ), }, collector: summary, externalMF: []*dto.MetricFamily{ externalMetricFamilyWithBucketSuffix, }, }, { // 22 headers: map[string]string{ "Accept": "text/plain", }, out: output{ headers: map[string]string{ "Content-Type": `text/plain; charset=utf-8`, }, body: duplicateLabelMsg, }, externalMF: []*dto.MetricFamily{ externalMetricFamilyWithDuplicateLabel, }, }, } for i, scenario := range scenarios { registry := prometheus.NewPedanticRegistry() gatherer := prometheus.Gatherer(registry) if scenario.externalMF != nil { gatherer = prometheus.Gatherers{ registry, prometheus.GathererFunc(func() ([]*dto.MetricFamily, error) { return scenario.externalMF, nil }), } } if scenario.collector != nil { registry.MustRegister(scenario.collector) } writer := httptest.NewRecorder() handler := promhttp.HandlerFor(gatherer, promhttp.HandlerOpts{}) request, _ := http.NewRequest(http.MethodGet, "/", nil) for key, value := range scenario.headers { request.Header.Add(key, value) } handler.ServeHTTP(writer, request) for key, value := range scenario.out.headers { if writer.Header().Get(key) != value { t.Errorf( "%d. expected %q for header %q, got %q", i, value, key, writer.Header().Get(key), ) } } var outMF dto.MetricFamily var writerMF dto.MetricFamily proto.Unmarshal(scenario.out.body, &outMF) proto.Unmarshal(writer.Body.Bytes(), &writerMF) if !proto.Equal(&outMF, &writerMF) { t.Errorf( "%d. expected body:\n%s\ngot body:\n%s\n", i, scenario.out.body, writer.Body.Bytes(), ) } } } func TestHandler(t *testing.T) { testHandler(t) } func BenchmarkHandler(b *testing.B) { for i := 0; i < b.N; i++ { testHandler(b) } } func TestAlreadyRegistered(t *testing.T) { original := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "test", Help: "help", ConstLabels: prometheus.Labels{"const": "label"}, }, []string{"foo", "bar"}, ) equalButNotSame := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "test", Help: "help", ConstLabels: prometheus.Labels{"const": "label"}, }, []string{"foo", "bar"}, ) originalWithoutConstLabel := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "test", Help: "help", }, []string{"foo", "bar"}, ) equalButNotSameWithoutConstLabel := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "test", Help: "help", }, []string{"foo", "bar"}, ) scenarios := []struct { name string originalCollector prometheus.Collector registerWith func(prometheus.Registerer) prometheus.Registerer newCollector prometheus.Collector reRegisterWith func(prometheus.Registerer) prometheus.Registerer }{ { "RegisterNormallyReregisterNormally", original, func(r prometheus.Registerer) prometheus.Registerer { return r }, equalButNotSame, func(r prometheus.Registerer) prometheus.Registerer { return r }, }, { "RegisterNormallyReregisterWrapped", original, func(r prometheus.Registerer) prometheus.Registerer { return r }, equalButNotSameWithoutConstLabel, func(r prometheus.Registerer) prometheus.Registerer { return prometheus.WrapRegistererWith(prometheus.Labels{"const": "label"}, r) }, }, { "RegisterWrappedReregisterWrapped", originalWithoutConstLabel, func(r prometheus.Registerer) prometheus.Registerer { return prometheus.WrapRegistererWith(prometheus.Labels{"const": "label"}, r) }, equalButNotSameWithoutConstLabel, func(r prometheus.Registerer) prometheus.Registerer { return prometheus.WrapRegistererWith(prometheus.Labels{"const": "label"}, r) }, }, { "RegisterWrappedReregisterNormally", originalWithoutConstLabel, func(r prometheus.Registerer) prometheus.Registerer { return prometheus.WrapRegistererWith(prometheus.Labels{"const": "label"}, r) }, equalButNotSame, func(r prometheus.Registerer) prometheus.Registerer { return r }, }, { "RegisterDoublyWrappedReregisterDoublyWrapped", originalWithoutConstLabel, func(r prometheus.Registerer) prometheus.Registerer { return prometheus.WrapRegistererWithPrefix( "wrap_", prometheus.WrapRegistererWith(prometheus.Labels{"const": "label"}, r), ) }, equalButNotSameWithoutConstLabel, func(r prometheus.Registerer) prometheus.Registerer { return prometheus.WrapRegistererWithPrefix( "wrap_", prometheus.WrapRegistererWith(prometheus.Labels{"const": "label"}, r), ) }, }, } for _, s := range scenarios { t.Run(s.name, func(t *testing.T) { var err error reg := prometheus.NewRegistry() if err = s.registerWith(reg).Register(s.originalCollector); err != nil { t.Fatal(err) } if err = s.reRegisterWith(reg).Register(s.newCollector); err == nil { t.Fatal("expected error when registering new collector") } are := &prometheus.AlreadyRegisteredError{} if errors.As(err, are) { if are.ExistingCollector != s.originalCollector { t.Error("expected original collector but got something else") } if are.ExistingCollector == s.newCollector { t.Error("expected original collector but got new one") } } else { t.Error("unexpected error:", err) } }) } } // TestRegisterUnregisterCollector ensures registering and unregistering a // collector doesn't leave any dangling metrics. // We use NewGoCollector as a nice concrete example of a collector with // multiple metrics. func TestRegisterUnregisterCollector(t *testing.T) { col := prometheus.NewGoCollector() reg := prometheus.NewRegistry() reg.MustRegister(col) reg.Unregister(col) if metrics, err := reg.Gather(); err != nil { t.Error("error gathering sample metric") } else if len(metrics) != 0 { t.Error("should have unregistered metric") } } // TestHistogramVecRegisterGatherConcurrency is an end-to-end test that // concurrently calls Observe on random elements of a HistogramVec while the // same HistogramVec is registered concurrently and the Gather method of the // registry is called concurrently. func TestHistogramVecRegisterGatherConcurrency(t *testing.T) { labelNames := make([]string, 16) // Need at least 13 to expose #512. for i := range labelNames { labelNames[i] = fmt.Sprint("label_", i) } var ( reg = prometheus.NewPedanticRegistry() hv = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "test_histogram", Help: "This helps testing.", ConstLabels: prometheus.Labels{"foo": "bar"}, }, labelNames, ) labelValues = []string{"a", "b", "c", "alpha", "beta", "gamma", "aleph", "beth", "gimel"} quit = make(chan struct{}) wg sync.WaitGroup ) observe := func() { defer wg.Done() for { select { case <-quit: return default: obs := rand.NormFloat64()*.1 + .2 values := make([]string, 0, len(labelNames)) for range labelNames { values = append(values, labelValues[rand.Intn(len(labelValues))]) } hv.WithLabelValues(values...).Observe(obs) } } } register := func() { defer wg.Done() for { select { case <-quit: return default: if err := reg.Register(hv); err != nil { if !errors.As(err, &prometheus.AlreadyRegisteredError{}) { t.Error("Registering failed:", err) } } time.Sleep(7 * time.Millisecond) } } } gather := func() { defer wg.Done() for { select { case <-quit: return default: if g, err := reg.Gather(); err != nil { t.Error("Gathering failed:", err) } else { if len(g) == 0 { continue } if len(g) != 1 { t.Error("Gathered unexpected number of metric families:", len(g)) } if len(g[0].Metric[0].Label) != len(labelNames)+1 { t.Error("Gathered unexpected number of label pairs:", len(g[0].Metric[0].Label)) } } time.Sleep(4 * time.Millisecond) } } } wg.Add(10) go observe() go observe() go register() go observe() go gather() go observe() go register() go observe() go gather() go observe() time.Sleep(time.Second) close(quit) wg.Wait() } func TestWriteToTextfile(t *testing.T) { expectedOut := `# HELP test_counter test counter # TYPE test_counter counter test_counter{name="qux"} 1 # HELP test_gauge test gauge # TYPE test_gauge gauge test_gauge{name="baz"} 1.1 # HELP test_hist test histogram # TYPE test_hist histogram test_hist_bucket{name="bar",le="0.005"} 0 test_hist_bucket{name="bar",le="0.01"} 0 test_hist_bucket{name="bar",le="0.025"} 0 test_hist_bucket{name="bar",le="0.05"} 0 test_hist_bucket{name="bar",le="0.1"} 0 test_hist_bucket{name="bar",le="0.25"} 0 test_hist_bucket{name="bar",le="0.5"} 0 test_hist_bucket{name="bar",le="1"} 1 test_hist_bucket{name="bar",le="2.5"} 1 test_hist_bucket{name="bar",le="5"} 2 test_hist_bucket{name="bar",le="10"} 2 test_hist_bucket{name="bar",le="+Inf"} 2 test_hist_sum{name="bar"} 3.64 test_hist_count{name="bar"} 2 # HELP test_summary test summary # TYPE test_summary summary test_summary{name="foo",quantile="0.5"} 10 test_summary{name="foo",quantile="0.9"} 20 test_summary{name="foo",quantile="0.99"} 20 test_summary_sum{name="foo"} 30 test_summary_count{name="foo"} 2 ` registry := prometheus.NewRegistry() summary := prometheus.NewSummaryVec( prometheus.SummaryOpts{ Name: "test_summary", Help: "test summary", Objectives: map[float64]float64{ 0.5: 0.05, 0.9: 0.01, 0.99: 0.001, }, }, []string{"name"}, ) histogram := prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "test_hist", Help: "test histogram", }, []string{"name"}, ) gauge := prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "test_gauge", Help: "test gauge", }, []string{"name"}, ) counter := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "test_counter", Help: "test counter", }, []string{"name"}, ) registry.MustRegister(summary) registry.MustRegister(histogram) registry.MustRegister(gauge) registry.MustRegister(counter) summary.With(prometheus.Labels{"name": "foo"}).Observe(10) summary.With(prometheus.Labels{"name": "foo"}).Observe(20) histogram.With(prometheus.Labels{"name": "bar"}).Observe(0.93) histogram.With(prometheus.Labels{"name": "bar"}).Observe(2.71) gauge.With(prometheus.Labels{"name": "baz"}).Set(1.1) counter.With(prometheus.Labels{"name": "qux"}).Inc() tmpfile, err := os.CreateTemp("", "prom_registry_test") if err != nil { t.Fatal(err) } defer os.Remove(tmpfile.Name()) if err := prometheus.WriteToTextfile(tmpfile.Name(), registry); err != nil { t.Fatal(err) } fileBytes, err := os.ReadFile(tmpfile.Name()) if err != nil { t.Fatal(err) } fileContents := string(fileBytes) if fileContents != expectedOut { t.Errorf( "files don't match, got:\n%s\nwant:\n%s", fileContents, expectedOut, ) } } // collidingCollector is a collection of prometheus.Collectors, // and is itself a prometheus.Collector. type collidingCollector struct { i int name string a, b, c, d prometheus.Collector } // Describe satisfies part of the prometheus.Collector interface. func (m *collidingCollector) Describe(desc chan<- *prometheus.Desc) { m.a.Describe(desc) m.b.Describe(desc) m.c.Describe(desc) m.d.Describe(desc) } // Collect satisfies part of the prometheus.Collector interface. func (m *collidingCollector) Collect(metric chan<- prometheus.Metric) { m.a.Collect(metric) m.b.Collect(metric) m.c.Collect(metric) m.d.Collect(metric) } // TestAlreadyRegistered will fail with the old, weaker hash function. It is // taken from https://play.golang.org/p/HpV7YE6LI_4 , authored by @awilliams. func TestAlreadyRegisteredCollision(t *testing.T) { reg := prometheus.NewRegistry() for i := 0; i < 10000; i++ { // A collector should be considered unique if its name and const // label values are unique. name := fmt.Sprintf("test-collector-%010d", i) collector := collidingCollector{ i: i, name: name, a: prometheus.NewCounter(prometheus.CounterOpts{ Name: "my_collector_a", ConstLabels: prometheus.Labels{ "name": name, "type": "test", }, }), b: prometheus.NewCounter(prometheus.CounterOpts{ Name: "my_collector_b", ConstLabels: prometheus.Labels{ "name": name, "type": "test", }, }), c: prometheus.NewCounter(prometheus.CounterOpts{ Name: "my_collector_c", ConstLabels: prometheus.Labels{ "name": name, "type": "test", }, }), d: prometheus.NewCounter(prometheus.CounterOpts{ Name: "my_collector_d", ConstLabels: prometheus.Labels{ "name": name, "type": "test", }, }), } // Register should not fail, since each collector has a unique // set of sub-collectors, determined by their names and const label values. if err := reg.Register(&collector); err != nil { are := &prometheus.AlreadyRegisteredError{} if !errors.As(err, are) { t.Fatal(err) } previous := are.ExistingCollector.(*collidingCollector) current := are.NewCollector.(*collidingCollector) t.Errorf("Unexpected registration error: %q\nprevious collector: %s (i=%d)\ncurrent collector %s (i=%d)", are, previous.name, previous.i, current.name, current.i) } } } type tGatherer struct { done bool err error } func (g *tGatherer) Gather() (_ []*dto.MetricFamily, done func(), err error) { name := "g1" val := 1.0 return []*dto.MetricFamily{ {Name: &name, Metric: []*dto.Metric{{Gauge: &dto.Gauge{Value: &val}}}}, }, func() { g.done = true }, g.err } func TestNewMultiTRegistry(t *testing.T) { treg := &tGatherer{} t.Run("one registry", func(t *testing.T) { m := prometheus.NewMultiTRegistry(treg) ret, done, err := m.Gather() if err != nil { t.Error("gather failed:", err) } done() if len(ret) != 1 { t.Error("unexpected number of metric families, expected 1, got", ret) } if !treg.done { t.Error("inner transactional registry not marked as done") } }) reg := prometheus.NewRegistry() if err := reg.Register(prometheus.NewCounter(prometheus.CounterOpts{Name: "c1", Help: "help c1"})); err != nil { t.Error("registration failed:", err) } // Note on purpose two registries will have exactly same metric family name (but with different string). // This behaviour is undefined at the moment. if err := reg.Register(prometheus.NewGauge(prometheus.GaugeOpts{Name: "g1", Help: "help g1"})); err != nil { t.Error("registration failed:", err) } treg.done = false t.Run("two registries", func(t *testing.T) { m := prometheus.NewMultiTRegistry(prometheus.ToTransactionalGatherer(reg), treg) ret, done, err := m.Gather() if err != nil { t.Error("gather failed:", err) } done() if len(ret) != 3 { t.Error("unexpected number of metric families, expected 3, got", ret) } if !treg.done { t.Error("inner transactional registry not marked as done") } }) treg.done = false // Inject error. treg.err = errors.New("test err") t.Run("two registries, one with error", func(t *testing.T) { m := prometheus.NewMultiTRegistry(prometheus.ToTransactionalGatherer(reg), treg) ret, done, err := m.Gather() if !errors.Is(err, treg.err) { t.Error("unexpected error:", err) } done() if len(ret) != 3 { t.Error("unexpected number of metric families, expected 3, got", ret) } // Still on error, we expect done to be triggered. if !treg.done { t.Error("inner transactional registry not marked as done") } }) } // This example shows how to use multiple registries for registering and // unregistering groups of metrics. func ExampleRegistry_grouping() { // Create a global registry. globalReg := prometheus.NewRegistry() // Spawn 10 workers, each of which will have their own group of metrics. for i := 0; i < 10; i++ { // Create a new registry for each worker, which acts as a group of // worker-specific metrics. workerReg := prometheus.NewRegistry() globalReg.Register(workerReg) go func(workerID int) { // Once the worker is done, it can unregister itself. defer globalReg.Unregister(workerReg) workTime := prometheus.NewCounter(prometheus.CounterOpts{ Name: "worker_total_work_time_milliseconds", ConstLabels: prometheus.Labels{ // Generate a label unique to this worker so its metric doesn't // collide with the metrics from other workers. "worker_id": strconv.Itoa(workerID), }, }) workerReg.MustRegister(workTime) start := time.Now() time.Sleep(time.Millisecond * time.Duration(rand.Intn(100))) workTime.Add(float64(time.Since(start).Milliseconds())) }(i) } } type customCollector struct { collectFunc func(ch chan<- prometheus.Metric) } func (co *customCollector) Describe(_ chan<- *prometheus.Desc) {} func (co *customCollector) Collect(ch chan<- prometheus.Metric) { co.collectFunc(ch) } // TestCheckMetricConsistency func TestCheckMetricConsistency(t *testing.T) { reg := prometheus.NewRegistry() timestamp := time.Now() desc := prometheus.NewDesc("metric_a", "", nil, nil) metric := prometheus.MustNewConstMetric(desc, prometheus.CounterValue, 1) validCollector := &customCollector{ collectFunc: func(ch chan<- prometheus.Metric) { ch <- prometheus.NewMetricWithTimestamp(timestamp.Add(-1*time.Minute), metric) ch <- prometheus.NewMetricWithTimestamp(timestamp, metric) }, } reg.MustRegister(validCollector) _, err := reg.Gather() if err != nil { t.Error("metric validation should succeed:", err) } reg.Unregister(validCollector) invalidCollector := &customCollector{ collectFunc: func(ch chan<- prometheus.Metric) { ch <- prometheus.NewMetricWithTimestamp(timestamp, metric) ch <- prometheus.NewMetricWithTimestamp(timestamp, metric) }, } reg.MustRegister(invalidCollector) _, err = reg.Gather() if err == nil { t.Error("metric validation should return an error") } reg.Unregister(invalidCollector) } client_golang-1.21.1/prometheus/summary.go000066400000000000000000000650101476160432400206310ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "fmt" "math" "runtime" "sort" "sync" "sync/atomic" "time" dto "github.com/prometheus/client_model/go" "github.com/beorn7/perks/quantile" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" ) // quantileLabel is used for the label that defines the quantile in a // summary. const quantileLabel = "quantile" // A Summary captures individual observations from an event or sample stream and // summarizes them in a manner similar to traditional summary statistics: 1. sum // of observations, 2. observation count, 3. rank estimations. // // A typical use-case is the observation of request latencies. By default, a // Summary provides the median, the 90th and the 99th percentile of the latency // as rank estimations. However, the default behavior will change in the // upcoming v1.0.0 of the library. There will be no rank estimations at all by // default. For a sane transition, it is recommended to set the desired rank // estimations explicitly. // // Note that the rank estimations cannot be aggregated in a meaningful way with // the Prometheus query language (i.e. you cannot average or add them). If you // need aggregatable quantiles (e.g. you want the 99th percentile latency of all // queries served across all instances of a service), consider the Histogram // metric type. See the Prometheus documentation for more details. // // To create Summary instances, use NewSummary. type Summary interface { Metric Collector // Observe adds a single observation to the summary. Observations are // usually positive or zero. Negative observations are accepted but // prevent current versions of Prometheus from properly detecting // counter resets in the sum of observations. See // https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations // for details. Observe(float64) } var errQuantileLabelNotAllowed = fmt.Errorf( "%q is not allowed as label name in summaries", quantileLabel, ) // Default values for SummaryOpts. const ( // DefMaxAge is the default duration for which observations stay // relevant. DefMaxAge time.Duration = 10 * time.Minute // DefAgeBuckets is the default number of buckets used to calculate the // age of observations. DefAgeBuckets = 5 // DefBufCap is the standard buffer size for collecting Summary observations. DefBufCap = 500 ) // SummaryOpts bundles the options for creating a Summary metric. It is // mandatory to set Name to a non-empty string. While all other fields are // optional and can safely be left at their zero value, it is recommended to set // a help string and to explicitly set the Objectives field to the desired value // as the default value will change in the upcoming v1.0.0 of the library. type SummaryOpts struct { // Namespace, Subsystem, and Name are components of the fully-qualified // name of the Summary (created by joining these components with // "_"). Only Name is mandatory, the others merely help structuring the // name. Note that the fully-qualified name of the Summary must be a // valid Prometheus metric name. Namespace string Subsystem string Name string // Help provides information about this Summary. // // Metrics with the same fully-qualified name must have the same Help // string. Help string // ConstLabels are used to attach fixed labels to this metric. Metrics // with the same fully-qualified name must have the same label names in // their ConstLabels. // // Due to the way a Summary is represented in the Prometheus text format // and how it is handled by the Prometheus server internally, β€œquantile” // is an illegal label name. Construction of a Summary or SummaryVec // will panic if this label name is used in ConstLabels. // // ConstLabels are only used rarely. In particular, do not use them to // attach the same labels to all your metrics. Those use cases are // better covered by target labels set by the scraping Prometheus // server, or by one specific metric (e.g. a build_info or a // machine_role metric). See also // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels ConstLabels Labels // Objectives defines the quantile rank estimates with their respective // absolute error. If Objectives[q] = e, then the value reported for q // will be the Ο†-quantile value for some Ο† between q-e and q+e. The // default value is an empty map, resulting in a summary without // quantiles. Objectives map[float64]float64 // MaxAge defines the duration for which an observation stays relevant // for the summary. Only applies to pre-calculated quantiles, does not // apply to _sum and _count. Must be positive. The default value is // DefMaxAge. MaxAge time.Duration // AgeBuckets is the number of buckets used to exclude observations that // are older than MaxAge from the summary. A higher number has a // resource penalty, so only increase it if the higher resolution is // really required. For very high observation rates, you might want to // reduce the number of age buckets. With only one age bucket, you will // effectively see a complete reset of the summary each time MaxAge has // passed. The default value is DefAgeBuckets. AgeBuckets uint32 // BufCap defines the default sample stream buffer size. The default // value of DefBufCap should suffice for most uses. If there is a need // to increase the value, a multiple of 500 is recommended (because that // is the internal buffer size of the underlying package // "github.com/bmizerany/perks/quantile"). BufCap uint32 // now is for testing purposes, by default it's time.Now. now func() time.Time } // SummaryVecOpts bundles the options to create a SummaryVec metric. // It is mandatory to set SummaryOpts, see there for mandatory fields. VariableLabels // is optional and can safely be left to its default value. type SummaryVecOpts struct { SummaryOpts // VariableLabels are used to partition the metric vector by the given set // of labels. Each label value will be constrained with the optional Constraint // function, if provided. VariableLabels ConstrainableLabels } // Problem with the sliding-window decay algorithm... The Merge method of // perk/quantile is actually not working as advertised - and it might be // unfixable, as the underlying algorithm is apparently not capable of merging // summaries in the first place. To avoid using Merge, we are currently adding // observations to _each_ age bucket, i.e. the effort to add a sample is // essentially multiplied by the number of age buckets. When rotating age // buckets, we empty the previous head stream. On scrape time, we simply take // the quantiles from the head stream (no merging required). Result: More effort // on observation time, less effort on scrape time, which is exactly the // opposite of what we try to accomplish, but at least the results are correct. // // The quite elegant previous contraption to merge the age buckets efficiently // on scrape time (see code up commit 6b9530d72ea715f0ba612c0120e6e09fbf1d49d0) // can't be used anymore. // NewSummary creates a new Summary based on the provided SummaryOpts. func NewSummary(opts SummaryOpts) Summary { return newSummary( NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, nil, opts.ConstLabels, ), opts, ) } func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary { if len(desc.variableLabels.names) != len(labelValues) { panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, labelValues)) } for _, n := range desc.variableLabels.names { if n == quantileLabel { panic(errQuantileLabelNotAllowed) } } for _, lp := range desc.constLabelPairs { if lp.GetName() == quantileLabel { panic(errQuantileLabelNotAllowed) } } if opts.Objectives == nil { opts.Objectives = map[float64]float64{} } if opts.MaxAge < 0 { panic(fmt.Errorf("illegal max age MaxAge=%v", opts.MaxAge)) } if opts.MaxAge == 0 { opts.MaxAge = DefMaxAge } if opts.AgeBuckets == 0 { opts.AgeBuckets = DefAgeBuckets } if opts.BufCap == 0 { opts.BufCap = DefBufCap } if opts.now == nil { opts.now = time.Now } if len(opts.Objectives) == 0 { // Use the lock-free implementation of a Summary without objectives. s := &noObjectivesSummary{ desc: desc, labelPairs: MakeLabelPairs(desc, labelValues), counts: [2]*summaryCounts{{}, {}}, } s.init(s) // Init self-collection. s.createdTs = timestamppb.New(opts.now()) return s } s := &summary{ desc: desc, now: opts.now, objectives: opts.Objectives, sortedObjectives: make([]float64, 0, len(opts.Objectives)), labelPairs: MakeLabelPairs(desc, labelValues), hotBuf: make([]float64, 0, opts.BufCap), coldBuf: make([]float64, 0, opts.BufCap), streamDuration: opts.MaxAge / time.Duration(opts.AgeBuckets), } s.headStreamExpTime = opts.now().Add(s.streamDuration) s.hotBufExpTime = s.headStreamExpTime for i := uint32(0); i < opts.AgeBuckets; i++ { s.streams = append(s.streams, s.newStream()) } s.headStream = s.streams[0] for qu := range s.objectives { s.sortedObjectives = append(s.sortedObjectives, qu) } sort.Float64s(s.sortedObjectives) s.init(s) // Init self-collection. s.createdTs = timestamppb.New(opts.now()) return s } type summary struct { selfCollector bufMtx sync.Mutex // Protects hotBuf and hotBufExpTime. mtx sync.Mutex // Protects every other moving part. // Lock bufMtx before mtx if both are needed. desc *Desc now func() time.Time objectives map[float64]float64 sortedObjectives []float64 labelPairs []*dto.LabelPair sum float64 cnt uint64 hotBuf, coldBuf []float64 streams []*quantile.Stream streamDuration time.Duration headStream *quantile.Stream headStreamIdx int headStreamExpTime, hotBufExpTime time.Time createdTs *timestamppb.Timestamp } func (s *summary) Desc() *Desc { return s.desc } func (s *summary) Observe(v float64) { s.bufMtx.Lock() defer s.bufMtx.Unlock() now := s.now() if now.After(s.hotBufExpTime) { s.asyncFlush(now) } s.hotBuf = append(s.hotBuf, v) if len(s.hotBuf) == cap(s.hotBuf) { s.asyncFlush(now) } } func (s *summary) Write(out *dto.Metric) error { sum := &dto.Summary{ CreatedTimestamp: s.createdTs, } qs := make([]*dto.Quantile, 0, len(s.objectives)) s.bufMtx.Lock() s.mtx.Lock() // Swap bufs even if hotBuf is empty to set new hotBufExpTime. s.swapBufs(s.now()) s.bufMtx.Unlock() s.flushColdBuf() sum.SampleCount = proto.Uint64(s.cnt) sum.SampleSum = proto.Float64(s.sum) for _, rank := range s.sortedObjectives { var q float64 if s.headStream.Count() == 0 { q = math.NaN() } else { q = s.headStream.Query(rank) } qs = append(qs, &dto.Quantile{ Quantile: proto.Float64(rank), Value: proto.Float64(q), }) } s.mtx.Unlock() if len(qs) > 0 { sort.Sort(quantSort(qs)) } sum.Quantile = qs out.Summary = sum out.Label = s.labelPairs return nil } func (s *summary) newStream() *quantile.Stream { return quantile.NewTargeted(s.objectives) } // asyncFlush needs bufMtx locked. func (s *summary) asyncFlush(now time.Time) { s.mtx.Lock() s.swapBufs(now) // Unblock the original goroutine that was responsible for the mutation // that triggered the compaction. But hold onto the global non-buffer // state mutex until the operation finishes. go func() { s.flushColdBuf() s.mtx.Unlock() }() } // rotateStreams needs mtx AND bufMtx locked. func (s *summary) maybeRotateStreams() { for !s.hotBufExpTime.Equal(s.headStreamExpTime) { s.headStream.Reset() s.headStreamIdx++ if s.headStreamIdx >= len(s.streams) { s.headStreamIdx = 0 } s.headStream = s.streams[s.headStreamIdx] s.headStreamExpTime = s.headStreamExpTime.Add(s.streamDuration) } } // flushColdBuf needs mtx locked. func (s *summary) flushColdBuf() { for _, v := range s.coldBuf { for _, stream := range s.streams { stream.Insert(v) } s.cnt++ s.sum += v } s.coldBuf = s.coldBuf[0:0] s.maybeRotateStreams() } // swapBufs needs mtx AND bufMtx locked, coldBuf must be empty. func (s *summary) swapBufs(now time.Time) { if len(s.coldBuf) != 0 { panic("coldBuf is not empty") } s.hotBuf, s.coldBuf = s.coldBuf, s.hotBuf // hotBuf is now empty and gets new expiration set. for now.After(s.hotBufExpTime) { s.hotBufExpTime = s.hotBufExpTime.Add(s.streamDuration) } } type summaryCounts struct { // sumBits contains the bits of the float64 representing the sum of all // observations. sumBits and count have to go first in the struct to // guarantee alignment for atomic operations. // http://golang.org/pkg/sync/atomic/#pkg-note-BUG sumBits uint64 count uint64 } type noObjectivesSummary struct { // countAndHotIdx enables lock-free writes with use of atomic updates. // The most significant bit is the hot index [0 or 1] of the count field // below. Observe calls update the hot one. All remaining bits count the // number of Observe calls. Observe starts by incrementing this counter, // and finish by incrementing the count field in the respective // summaryCounts, as a marker for completion. // // Calls of the Write method (which are non-mutating reads from the // perspective of the summary) swap the hot–cold under the writeMtx // lock. A cooldown is awaited (while locked) by comparing the number of // observations with the initiation count. Once they match, then the // last observation on the now cool one has completed. All cool fields must // be merged into the new hot before releasing writeMtx. // Fields with atomic access first! See alignment constraint: // http://golang.org/pkg/sync/atomic/#pkg-note-BUG countAndHotIdx uint64 selfCollector desc *Desc writeMtx sync.Mutex // Only used in the Write method. // Two counts, one is "hot" for lock-free observations, the other is // "cold" for writing out a dto.Metric. It has to be an array of // pointers to guarantee 64bit alignment of the histogramCounts, see // http://golang.org/pkg/sync/atomic/#pkg-note-BUG. counts [2]*summaryCounts labelPairs []*dto.LabelPair createdTs *timestamppb.Timestamp } func (s *noObjectivesSummary) Desc() *Desc { return s.desc } func (s *noObjectivesSummary) Observe(v float64) { // We increment h.countAndHotIdx so that the counter in the lower // 63 bits gets incremented. At the same time, we get the new value // back, which we can use to find the currently-hot counts. n := atomic.AddUint64(&s.countAndHotIdx, 1) hotCounts := s.counts[n>>63] for { oldBits := atomic.LoadUint64(&hotCounts.sumBits) newBits := math.Float64bits(math.Float64frombits(oldBits) + v) if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) { break } } // Increment count last as we take it as a signal that the observation // is complete. atomic.AddUint64(&hotCounts.count, 1) } func (s *noObjectivesSummary) Write(out *dto.Metric) error { // For simplicity, we protect this whole method by a mutex. It is not in // the hot path, i.e. Observe is called much more often than Write. The // complication of making Write lock-free isn't worth it, if possible at // all. s.writeMtx.Lock() defer s.writeMtx.Unlock() // Adding 1<<63 switches the hot index (from 0 to 1 or from 1 to 0) // without touching the count bits. See the struct comments for a full // description of the algorithm. n := atomic.AddUint64(&s.countAndHotIdx, 1<<63) // count is contained unchanged in the lower 63 bits. count := n & ((1 << 63) - 1) // The most significant bit tells us which counts is hot. The complement // is thus the cold one. hotCounts := s.counts[n>>63] coldCounts := s.counts[(^n)>>63] // Await cooldown. for count != atomic.LoadUint64(&coldCounts.count) { runtime.Gosched() // Let observations get work done. } sum := &dto.Summary{ SampleCount: proto.Uint64(count), SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))), CreatedTimestamp: s.createdTs, } out.Summary = sum out.Label = s.labelPairs // Finally add all the cold counts to the new hot counts and reset the cold counts. atomic.AddUint64(&hotCounts.count, count) atomic.StoreUint64(&coldCounts.count, 0) for { oldBits := atomic.LoadUint64(&hotCounts.sumBits) newBits := math.Float64bits(math.Float64frombits(oldBits) + sum.GetSampleSum()) if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) { atomic.StoreUint64(&coldCounts.sumBits, 0) break } } return nil } type quantSort []*dto.Quantile func (s quantSort) Len() int { return len(s) } func (s quantSort) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s quantSort) Less(i, j int) bool { return s[i].GetQuantile() < s[j].GetQuantile() } // SummaryVec is a Collector that bundles a set of Summaries that all share the // same Desc, but have different values for their variable labels. This is used // if you want to count the same thing partitioned by various dimensions // (e.g. HTTP request latencies, partitioned by status code and method). Create // instances with NewSummaryVec. type SummaryVec struct { *MetricVec } // NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and // partitioned by the given label names. // // Due to the way a Summary is represented in the Prometheus text format and how // it is handled by the Prometheus server internally, β€œquantile” is an illegal // label name. NewSummaryVec will panic if this label name is used. func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec { return V2.NewSummaryVec(SummaryVecOpts{ SummaryOpts: opts, VariableLabels: UnconstrainedLabels(labelNames), }) } // NewSummaryVec creates a new SummaryVec based on the provided SummaryVecOpts. func (v2) NewSummaryVec(opts SummaryVecOpts) *SummaryVec { for _, ln := range opts.VariableLabels.labelNames() { if ln == quantileLabel { panic(errQuantileLabelNotAllowed) } } desc := V2.NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, opts.VariableLabels, opts.ConstLabels, ) return &SummaryVec{ MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { return newSummary(desc, opts.SummaryOpts, lvs...) }), } } // GetMetricWithLabelValues returns the Summary for the given slice of label // values (same order as the variable labels in Desc). If that combination of // label values is accessed for the first time, a new Summary is created. // // It is possible to call this method without using the returned Summary to only // create the new Summary but leave it at its starting value, a Summary without // any observations. // // Keeping the Summary for later use is possible (and should be considered if // performance is critical), but keep in mind that Reset, DeleteLabelValues and // Delete can be used to delete the Summary from the SummaryVec. In that case, // the Summary will still exist, but it will not be exported anymore, even if a // Summary with the same label values is created later. See also the CounterVec // example. // // An error is returned if the number of label values is not the same as the // number of variable labels in Desc (minus any curried labels). // // Note that for more than one label value, this method is prone to mistakes // caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as // an alternative to avoid that type of mistake. For higher label numbers, the // latter has a much more readable (albeit more verbose) syntax, but it comes // with a performance overhead (for creating and processing the Labels map). // See also the GaugeVec example. func (v *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) { metric, err := v.MetricVec.GetMetricWithLabelValues(lvs...) if metric != nil { return metric.(Observer), err } return nil, err } // GetMetricWith returns the Summary for the given Labels map (the label names // must match those of the variable labels in Desc). If that label map is // accessed for the first time, a new Summary is created. Implications of // creating a Summary without using it and keeping the Summary for later use are // the same as for GetMetricWithLabelValues. // // An error is returned if the number and names of the Labels are inconsistent // with those of the variable labels in Desc (minus any curried labels). // // This method is used for the same purpose as // GetMetricWithLabelValues(...string). See there for pros and cons of the two // methods. func (v *SummaryVec) GetMetricWith(labels Labels) (Observer, error) { metric, err := v.MetricVec.GetMetricWith(labels) if metric != nil { return metric.(Observer), err } return nil, err } // WithLabelValues works as GetMetricWithLabelValues, but panics where // GetMetricWithLabelValues would have returned an error. Not returning an // error allows shortcuts like // // myVec.WithLabelValues("404", "GET").Observe(42.21) func (v *SummaryVec) WithLabelValues(lvs ...string) Observer { s, err := v.GetMetricWithLabelValues(lvs...) if err != nil { panic(err) } return s } // With works as GetMetricWith, but panics where GetMetricWithLabels would have // returned an error. Not returning an error allows shortcuts like // // myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21) func (v *SummaryVec) With(labels Labels) Observer { s, err := v.GetMetricWith(labels) if err != nil { panic(err) } return s } // CurryWith returns a vector curried with the provided labels, i.e. the // returned vector has those labels pre-set for all labeled operations performed // on it. The cardinality of the curried vector is reduced accordingly. The // order of the remaining labels stays the same (just with the curried labels // taken out of the sequence – which is relevant for the // (GetMetric)WithLabelValues methods). It is possible to curry a curried // vector, but only with labels not yet used for currying before. // // The metrics contained in the SummaryVec are shared between the curried and // uncurried vectors. They are just accessed differently. Curried and uncurried // vectors behave identically in terms of collection. Only one must be // registered with a given registry (usually the uncurried version). The Reset // method deletes all metrics, even if called on a curried vector. func (v *SummaryVec) CurryWith(labels Labels) (ObserverVec, error) { vec, err := v.MetricVec.CurryWith(labels) if vec != nil { return &SummaryVec{vec}, err } return nil, err } // MustCurryWith works as CurryWith but panics where CurryWith would have // returned an error. func (v *SummaryVec) MustCurryWith(labels Labels) ObserverVec { vec, err := v.CurryWith(labels) if err != nil { panic(err) } return vec } type constSummary struct { desc *Desc count uint64 sum float64 quantiles map[float64]float64 labelPairs []*dto.LabelPair createdTs *timestamppb.Timestamp } func (s *constSummary) Desc() *Desc { return s.desc } func (s *constSummary) Write(out *dto.Metric) error { sum := &dto.Summary{ CreatedTimestamp: s.createdTs, } qs := make([]*dto.Quantile, 0, len(s.quantiles)) sum.SampleCount = proto.Uint64(s.count) sum.SampleSum = proto.Float64(s.sum) for rank, q := range s.quantiles { qs = append(qs, &dto.Quantile{ Quantile: proto.Float64(rank), Value: proto.Float64(q), }) } if len(qs) > 0 { sort.Sort(quantSort(qs)) } sum.Quantile = qs out.Summary = sum out.Label = s.labelPairs return nil } // NewConstSummary returns a metric representing a Prometheus summary with fixed // values for the count, sum, and quantiles. As those parameters cannot be // changed, the returned value does not implement the Summary interface (but // only the Metric interface). Users of this package will not have much use for // it in regular operations. However, when implementing custom Collectors, it is // useful as a throw-away metric that is generated on the fly to send it to // Prometheus in the Collect method. // // quantiles maps ranks to quantile values. For example, a median latency of // 0.23s and a 99th percentile latency of 0.56s would be expressed as: // // map[float64]float64{0.5: 0.23, 0.99: 0.56} // // NewConstSummary returns an error if the length of labelValues is not // consistent with the variable labels in Desc or if Desc is invalid. func NewConstSummary( desc *Desc, count uint64, sum float64, quantiles map[float64]float64, labelValues ...string, ) (Metric, error) { if desc.err != nil { return nil, desc.err } if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { return nil, err } return &constSummary{ desc: desc, count: count, sum: sum, quantiles: quantiles, labelPairs: MakeLabelPairs(desc, labelValues), }, nil } // MustNewConstSummary is a version of NewConstSummary that panics where // NewConstMetric would have returned an error. func MustNewConstSummary( desc *Desc, count uint64, sum float64, quantiles map[float64]float64, labelValues ...string, ) Metric { m, err := NewConstSummary(desc, count, sum, quantiles, labelValues...) if err != nil { panic(err) } return m } // NewConstSummaryWithCreatedTimestamp does the same thing as NewConstSummary but sets the created timestamp. func NewConstSummaryWithCreatedTimestamp( desc *Desc, count uint64, sum float64, quantiles map[float64]float64, ct time.Time, labelValues ...string, ) (Metric, error) { if desc.err != nil { return nil, desc.err } if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { return nil, err } return &constSummary{ desc: desc, count: count, sum: sum, quantiles: quantiles, labelPairs: MakeLabelPairs(desc, labelValues), createdTs: timestamppb.New(ct), }, nil } // MustNewConstSummaryWithCreatedTimestamp is a version of NewConstSummaryWithCreatedTimestamp that panics where // NewConstSummaryWithCreatedTimestamp would have returned an error. func MustNewConstSummaryWithCreatedTimestamp( desc *Desc, count uint64, sum float64, quantiles map[float64]float64, ct time.Time, labelValues ...string, ) Metric { m, err := NewConstSummaryWithCreatedTimestamp(desc, count, sum, quantiles, ct, labelValues...) if err != nil { panic(err) } return m } client_golang-1.21.1/prometheus/summary_test.go000066400000000000000000000274131476160432400216750ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "math" "math/rand" "sort" "sync" "testing" "testing/quick" "time" dto "github.com/prometheus/client_model/go" ) func TestSummaryWithDefaultObjectives(t *testing.T) { now := time.Now() reg := NewRegistry() summaryWithDefaultObjectives := NewSummary(SummaryOpts{ Name: "default_objectives", Help: "Test help.", now: func() time.Time { return now }, }) if err := reg.Register(summaryWithDefaultObjectives); err != nil { t.Error(err) } m := &dto.Metric{} if err := summaryWithDefaultObjectives.Write(m); err != nil { t.Error(err) } if len(m.GetSummary().Quantile) != 0 { t.Error("expected no objectives in summary") } if !m.Summary.CreatedTimestamp.AsTime().Equal(now) { t.Errorf("expected created timestamp %s, got %s", now, m.Summary.CreatedTimestamp.AsTime()) } } func TestSummaryWithoutObjectives(t *testing.T) { reg := NewRegistry() summaryWithEmptyObjectives := NewSummary(SummaryOpts{ Name: "empty_objectives", Help: "Test help.", Objectives: map[float64]float64{}, }) if err := reg.Register(summaryWithEmptyObjectives); err != nil { t.Error(err) } summaryWithEmptyObjectives.Observe(3) summaryWithEmptyObjectives.Observe(0.14) m := &dto.Metric{} if err := summaryWithEmptyObjectives.Write(m); err != nil { t.Error(err) } if got, want := m.GetSummary().GetSampleSum(), 3.14; got != want { t.Errorf("got sample sum %f, want %f", got, want) } if got, want := m.GetSummary().GetSampleCount(), uint64(2); got != want { t.Errorf("got sample sum %d, want %d", got, want) } if len(m.GetSummary().Quantile) != 0 { t.Error("expected no objectives in summary") } } func TestSummaryWithQuantileLabel(t *testing.T) { defer func() { if r := recover(); r == nil { t.Error("Attempt to create Summary with 'quantile' label did not panic.") } }() _ = NewSummary(SummaryOpts{ Name: "test_summary", Help: "less", ConstLabels: Labels{"quantile": "test"}, }) } func TestSummaryVecWithQuantileLabel(t *testing.T) { defer func() { if r := recover(); r == nil { t.Error("Attempt to create SummaryVec with 'quantile' label did not panic.") } }() _ = NewSummaryVec(SummaryOpts{ Name: "test_summary", Help: "less", }, []string{"quantile"}) } func benchmarkSummaryObserve(w int, b *testing.B) { b.StopTimer() wg := new(sync.WaitGroup) wg.Add(w) g := new(sync.WaitGroup) g.Add(1) s := NewSummary(SummaryOpts{}) for i := 0; i < w; i++ { go func() { g.Wait() for i := 0; i < b.N; i++ { s.Observe(float64(i)) } wg.Done() }() } b.StartTimer() g.Done() wg.Wait() } func BenchmarkSummaryObserve1(b *testing.B) { benchmarkSummaryObserve(1, b) } func BenchmarkSummaryObserve2(b *testing.B) { benchmarkSummaryObserve(2, b) } func BenchmarkSummaryObserve4(b *testing.B) { benchmarkSummaryObserve(4, b) } func BenchmarkSummaryObserve8(b *testing.B) { benchmarkSummaryObserve(8, b) } func benchmarkSummaryWrite(w int, b *testing.B) { b.StopTimer() wg := new(sync.WaitGroup) wg.Add(w) g := new(sync.WaitGroup) g.Add(1) s := NewSummary(SummaryOpts{}) for i := 0; i < 1000000; i++ { s.Observe(float64(i)) } for j := 0; j < w; j++ { outs := make([]dto.Metric, b.N) go func(o []dto.Metric) { g.Wait() for i := 0; i < b.N; i++ { s.Write(&o[i]) } wg.Done() }(outs) } b.StartTimer() g.Done() wg.Wait() } func BenchmarkSummaryWrite1(b *testing.B) { benchmarkSummaryWrite(1, b) } func BenchmarkSummaryWrite2(b *testing.B) { benchmarkSummaryWrite(2, b) } func BenchmarkSummaryWrite4(b *testing.B) { benchmarkSummaryWrite(4, b) } func BenchmarkSummaryWrite8(b *testing.B) { benchmarkSummaryWrite(8, b) } func TestSummaryConcurrency(t *testing.T) { if testing.Short() { t.Skip("Skipping test in short mode.") } rand.New(rand.NewSource(42)) objMap := map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001} it := func(n uint32) bool { mutations := int(n%1e4 + 1e4) concLevel := int(n%5 + 1) total := mutations * concLevel var start, end sync.WaitGroup start.Add(1) end.Add(concLevel) sum := NewSummary(SummaryOpts{ Name: "test_summary", Help: "helpless", Objectives: objMap, }) allVars := make([]float64, total) var sampleSum float64 for i := 0; i < concLevel; i++ { vals := make([]float64, mutations) for j := 0; j < mutations; j++ { v := rand.NormFloat64() vals[j] = v allVars[i*mutations+j] = v sampleSum += v } go func(vals []float64) { start.Wait() for _, v := range vals { sum.Observe(v) } end.Done() }(vals) } sort.Float64s(allVars) start.Done() end.Wait() m := &dto.Metric{} sum.Write(m) if got, want := int(*m.Summary.SampleCount), total; got != want { t.Errorf("got sample count %d, want %d", got, want) } if got, want := *m.Summary.SampleSum, sampleSum; math.Abs((got-want)/want) > 0.001 { t.Errorf("got sample sum %f, want %f", got, want) } objSlice := make([]float64, 0, len(objMap)) for qu := range objMap { objSlice = append(objSlice, qu) } sort.Float64s(objSlice) for i, wantQ := range objSlice { Ξ΅ := objMap[wantQ] gotQ := *m.Summary.Quantile[i].Quantile gotV := *m.Summary.Quantile[i].Value minBound, maxBound := getBounds(allVars, wantQ, Ξ΅) if gotQ != wantQ { t.Errorf("got quantile %f, want %f", gotQ, wantQ) } if gotV < minBound || gotV > maxBound { t.Errorf("got %f for quantile %f, want [%f,%f]", gotV, gotQ, minBound, maxBound) } } return true } if err := quick.Check(it, nil); err != nil { t.Error(err) } } func TestSummaryVecConcurrency(t *testing.T) { if testing.Short() { t.Skip("Skipping test in short mode.") } rand.New(rand.NewSource(42)) objMap := map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001} objSlice := make([]float64, 0, len(objMap)) for qu := range objMap { objSlice = append(objSlice, qu) } sort.Float64s(objSlice) it := func(n uint32) bool { mutations := int(n%1e4 + 1e4) concLevel := int(n%7 + 1) vecLength := int(n%3 + 1) var start, end sync.WaitGroup start.Add(1) end.Add(concLevel) sum := NewSummaryVec( SummaryOpts{ Name: "test_summary", Help: "helpless", Objectives: objMap, }, []string{"label"}, ) allVars := make([][]float64, vecLength) sampleSums := make([]float64, vecLength) for i := 0; i < concLevel; i++ { vals := make([]float64, mutations) picks := make([]int, mutations) for j := 0; j < mutations; j++ { v := rand.NormFloat64() vals[j] = v pick := rand.Intn(vecLength) picks[j] = pick allVars[pick] = append(allVars[pick], v) sampleSums[pick] += v } go func(vals []float64) { start.Wait() for i, v := range vals { sum.WithLabelValues(string('A' + rune(picks[i]))).Observe(v) } end.Done() }(vals) } for _, vars := range allVars { sort.Float64s(vars) } start.Done() end.Wait() for i := 0; i < vecLength; i++ { m := &dto.Metric{} s := sum.WithLabelValues(string('A' + rune(i))) s.(Summary).Write(m) if got, want := int(*m.Summary.SampleCount), len(allVars[i]); got != want { t.Errorf("got sample count %d for label %c, want %d", got, 'A'+i, want) } if got, want := *m.Summary.SampleSum, sampleSums[i]; math.Abs((got-want)/want) > 0.001 { t.Errorf("got sample sum %f for label %c, want %f", got, 'A'+i, want) } for j, wantQ := range objSlice { Ξ΅ := objMap[wantQ] gotQ := *m.Summary.Quantile[j].Quantile gotV := *m.Summary.Quantile[j].Value minBound, maxBound := getBounds(allVars[i], wantQ, Ξ΅) if gotQ != wantQ { t.Errorf("got quantile %f for label %c, want %f", gotQ, 'A'+i, wantQ) } if gotV < minBound || gotV > maxBound { t.Errorf("got %f for quantile %f for label %c, want [%f,%f]", gotV, gotQ, 'A'+i, minBound, maxBound) } } } return true } if err := quick.Check(it, nil); err != nil { t.Error(err) } } func TestSummaryDecay(t *testing.T) { now := time.Now() sum := NewSummary(SummaryOpts{ Name: "test_summary", Help: "helpless", MaxAge: 100 * time.Millisecond, Objectives: map[float64]float64{0.1: 0.001}, AgeBuckets: 10, now: func() time.Time { return now }, }) m := &dto.Metric{} for i := 1; i <= 1000; i++ { now = now.Add(time.Millisecond) sum.Observe(float64(i)) if i%10 == 0 { sum.Write(m) got := *m.Summary.Quantile[0].Value want := math.Max(float64(i)/10, float64(i-90)) if math.Abs(got-want) > 20 { t.Errorf("%d. got %f, want %f", i, got, want) } m.Reset() } } // Simulate waiting for MaxAge without observations now = now.Add(100 * time.Millisecond) sum.Write(m) if got := *m.Summary.Quantile[0].Value; !math.IsNaN(got) { t.Errorf("got %f, want NaN after expiration", got) } } func getBounds(vars []float64, q, Ξ΅ float64) (minBound, maxBound float64) { // TODO(beorn7): This currently tolerates an error of up to 2*Ξ΅. The // error must be at most Ξ΅, but for some reason, it's sometimes slightly // higher. That's a bug. n := float64(len(vars)) lower := int((q - 2*Ξ΅) * n) upper := int(math.Ceil((q + 2*Ξ΅) * n)) minBound = vars[0] if lower > 1 { minBound = vars[lower-1] } maxBound = vars[len(vars)-1] if upper < len(vars) { maxBound = vars[upper-1] } return } func TestSummaryVecCreatedTimestampWithDeletes(t *testing.T) { for _, tcase := range []struct { desc string objectives map[float64]float64 }{ {desc: "summary with objectives", objectives: map[float64]float64{1.0: 1.0}}, {desc: "no objectives summary", objectives: nil}, } { now := time.Now() t.Run(tcase.desc, func(t *testing.T) { summaryVec := NewSummaryVec(SummaryOpts{ Name: "test", Help: "test help", Objectives: tcase.objectives, now: func() time.Time { return now }, }, []string{"label"}) // First use of "With" should populate CT. summaryVec.WithLabelValues("1") expected := map[string]time.Time{"1": now} now = now.Add(1 * time.Hour) expectCTsForMetricVecValues(t, summaryVec.MetricVec, dto.MetricType_SUMMARY, expected) // Two more labels at different times. summaryVec.WithLabelValues("2") expected["2"] = now now = now.Add(1 * time.Hour) summaryVec.WithLabelValues("3") expected["3"] = now now = now.Add(1 * time.Hour) expectCTsForMetricVecValues(t, summaryVec.MetricVec, dto.MetricType_SUMMARY, expected) // Recreate metric instance should reset created timestamp to now. summaryVec.DeleteLabelValues("1") summaryVec.WithLabelValues("1") expected["1"] = now now = now.Add(1 * time.Hour) expectCTsForMetricVecValues(t, summaryVec.MetricVec, dto.MetricType_SUMMARY, expected) }) } } func TestNewConstSummaryWithCreatedTimestamp(t *testing.T) { metricDesc := NewDesc( "sample_value", "sample value", nil, nil, ) quantiles := map[float64]float64{50: 200.12, 99: 500.342} createdTs := time.Unix(1719670764, 123) s, err := NewConstSummaryWithCreatedTimestamp(metricDesc, 100, 200, quantiles, createdTs) if err != nil { t.Fatal(err) } var metric dto.Metric if err := s.Write(&metric); err != nil { t.Fatal(err) } if metric.Summary.CreatedTimestamp.AsTime().UnixMicro() != createdTs.UnixMicro() { t.Errorf("Expected created timestamp %v, got %v", createdTs, &metric.Summary.CreatedTimestamp) } } client_golang-1.21.1/prometheus/testutil/000077500000000000000000000000001476160432400204605ustar00rootroot00000000000000client_golang-1.21.1/prometheus/testutil/lint.go000066400000000000000000000033231476160432400217560ustar00rootroot00000000000000// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package testutil import ( "fmt" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/testutil/promlint" ) // CollectAndLint registers the provided Collector with a newly created pedantic // Registry. It then calls GatherAndLint with that Registry and with the // provided metricNames. func CollectAndLint(c prometheus.Collector, metricNames ...string) ([]promlint.Problem, error) { reg := prometheus.NewPedanticRegistry() if err := reg.Register(c); err != nil { return nil, fmt.Errorf("registering collector failed: %w", err) } return GatherAndLint(reg, metricNames...) } // GatherAndLint gathers all metrics from the provided Gatherer and checks them // with the linter in the promlint package. If any metricNames are provided, // only metrics with those names are checked. func GatherAndLint(g prometheus.Gatherer, metricNames ...string) ([]promlint.Problem, error) { got, err := g.Gather() if err != nil { return nil, fmt.Errorf("gathering metrics failed: %w", err) } if metricNames != nil { got = filterMetrics(got, metricNames) } return promlint.NewWithMetricFamilies(got).Lint() } client_golang-1.21.1/prometheus/testutil/lint_test.go000066400000000000000000000037001476160432400230140ustar00rootroot00000000000000// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package testutil import ( "testing" "github.com/prometheus/client_golang/prometheus" ) func TestCollectAndLintGood(t *testing.T) { cnt := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "some_total", Help: "A value that represents a counter.", ConstLabels: prometheus.Labels{ "label1": "value1", }, }, []string{"foo"}, ) cnt.WithLabelValues("bar") cnt.WithLabelValues("baz") problems, err := CollectAndLint(cnt) if err != nil { t.Error("Unexpected error:", err) } if len(problems) > 0 { t.Error("Unexpected lint problems:", problems) } } func TestCollectAndLintBad(t *testing.T) { cnt := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "someThing_ms", Help: "A value that represents a counter.", ConstLabels: prometheus.Labels{ "label1": "value1", }, }, []string{"fooBar"}, ) cnt.WithLabelValues("bar") cnt.WithLabelValues("baz") problems, err := CollectAndLint(cnt) if err != nil { t.Error("Unexpected error:", err) } if len(problems) < 5 { // The exact nature of the lint problems found is tested within // the promlint package itself. Here we only want to make sure // that the collector successfully hits the linter and that at // least the five problems that the linter could recognize at // the time of writing this test are flagged. t.Error("Not enough lint problems found.") } } client_golang-1.21.1/prometheus/testutil/promlint/000077500000000000000000000000001476160432400223245ustar00rootroot00000000000000client_golang-1.21.1/prometheus/testutil/promlint/problem.go000066400000000000000000000020301476160432400243060ustar00rootroot00000000000000// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package promlint import dto "github.com/prometheus/client_model/go" // A Problem is an issue detected by a linter. type Problem struct { // The name of the metric indicated by this Problem. Metric string // A description of the issue for this Problem. Text string } // newProblem is helper function to create a Problem. func newProblem(mf *dto.MetricFamily, text string) Problem { return Problem{ Metric: mf.GetName(), Text: text, } } client_golang-1.21.1/prometheus/testutil/promlint/promlint.go000066400000000000000000000065701476160432400245270ustar00rootroot00000000000000// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package promlint provides a linter for Prometheus metrics. package promlint import ( "errors" "io" "sort" dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" ) // A Linter is a Prometheus metrics linter. It identifies issues with metric // names, types, and metadata, and reports them to the caller. type Linter struct { // The linter will read metrics in the Prometheus text format from r and // then lint it, _and_ it will lint the metrics provided directly as // MetricFamily proto messages in mfs. Note, however, that the current // constructor functions New and NewWithMetricFamilies only ever set one // of them. r io.Reader mfs []*dto.MetricFamily customValidations []Validation } // New creates a new Linter that reads an input stream of Prometheus metrics in // the Prometheus text exposition format. func New(r io.Reader) *Linter { return &Linter{ r: r, } } // NewWithMetricFamilies creates a new Linter that reads from a slice of // MetricFamily protobuf messages. func NewWithMetricFamilies(mfs []*dto.MetricFamily) *Linter { return &Linter{ mfs: mfs, } } // AddCustomValidations adds custom validations to the linter. func (l *Linter) AddCustomValidations(vs ...Validation) { if l.customValidations == nil { l.customValidations = make([]Validation, 0, len(vs)) } l.customValidations = append(l.customValidations, vs...) } // Lint performs a linting pass, returning a slice of Problems indicating any // issues found in the metrics stream. The slice is sorted by metric name // and issue description. func (l *Linter) Lint() ([]Problem, error) { var problems []Problem if l.r != nil { d := expfmt.NewDecoder(l.r, expfmt.NewFormat(expfmt.TypeTextPlain)) mf := &dto.MetricFamily{} for { if err := d.Decode(mf); err != nil { if errors.Is(err, io.EOF) { break } return nil, err } problems = append(problems, l.lint(mf)...) } } for _, mf := range l.mfs { problems = append(problems, l.lint(mf)...) } // Ensure deterministic output. sort.SliceStable(problems, func(i, j int) bool { if problems[i].Metric == problems[j].Metric { return problems[i].Text < problems[j].Text } return problems[i].Metric < problems[j].Metric }) return problems, nil } // lint is the entry point for linting a single metric. func (l *Linter) lint(mf *dto.MetricFamily) []Problem { var problems []Problem for _, fn := range defaultValidations { errs := fn(mf) for _, err := range errs { problems = append(problems, newProblem(mf, err.Error())) } } if l.customValidations != nil { for _, fn := range l.customValidations { errs := fn(mf) for _, err := range errs { problems = append(problems, newProblem(mf, err.Error())) } } } // TODO(mdlayher): lint rules for specific metrics types. return problems } client_golang-1.21.1/prometheus/testutil/promlint/promlint_test.go000066400000000000000000000453631476160432400255710ustar00rootroot00000000000000// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package promlint_test import ( "errors" "fmt" "reflect" "strings" "testing" dto "github.com/prometheus/client_model/go" "github.com/prometheus/client_golang/prometheus/testutil/promlint" ) type test struct { name string in string problems []promlint.Problem } func TestLintNoHelpText(t *testing.T) { const msg = "no help text" tests := []test{ { name: "no help", in: ` # TYPE go_goroutines gauge go_goroutines 24 `, problems: []promlint.Problem{{ Metric: "go_goroutines", Text: msg, }}, }, { name: "empty help", in: ` # HELP go_goroutines # TYPE go_goroutines gauge go_goroutines 24 `, problems: []promlint.Problem{{ Metric: "go_goroutines", Text: msg, }}, }, { name: "no help and empty help", in: ` # HELP go_goroutines # TYPE go_goroutines gauge go_goroutines 24 # TYPE go_threads gauge go_threads 10 `, problems: []promlint.Problem{ { Metric: "go_goroutines", Text: msg, }, { Metric: "go_threads", Text: msg, }, }, }, { name: "OK", in: ` # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge go_goroutines 24 `, }, } runTests(t, tests) } func TestLintMetricUnits(t *testing.T) { tests := []struct { name string in string problems []promlint.Problem }{ // good cases. { name: "amperes", in: ` # HELP x_amperes Test metric. # TYPE x_amperes untyped x_amperes 10 `, }, { name: "bytes", in: ` # HELP x_bytes Test metric. # TYPE x_bytes untyped x_bytes 10 `, }, { name: "grams", in: ` # HELP x_grams Test metric. # TYPE x_grams untyped x_grams 10 `, }, { name: "celsius", in: ` # HELP x_celsius Test metric. # TYPE x_celsius untyped x_celsius 10 `, }, { name: "meters", in: ` # HELP x_meters Test metric. # TYPE x_meters untyped x_meters 10 `, }, { name: "metres", in: ` # HELP x_metres Test metric. # TYPE x_metres untyped x_metres 10 `, }, { name: "moles", in: ` # HELP x_moles Test metric. # TYPE x_moles untyped x_moles 10 `, }, { name: "seconds", in: ` # HELP x_seconds Test metric. # TYPE x_seconds untyped x_seconds 10 `, }, { name: "joules", in: ` # HELP x_joules Test metric. # TYPE x_joules untyped x_joules 10 `, }, { name: "kelvin", in: ` # HELP x_kelvin Test metric. # TYPE x_kelvin untyped x_kelvin 10 `, }, // bad cases. { name: "milliamperes", in: ` # HELP x_milliamperes Test metric. # TYPE x_milliamperes untyped x_milliamperes 10 `, problems: []promlint.Problem{{ Metric: "x_milliamperes", Text: `use base unit "amperes" instead of "milliamperes"`, }}, }, { name: "gigabytes", in: ` # HELP x_gigabytes Test metric. # TYPE x_gigabytes untyped x_gigabytes 10 `, problems: []promlint.Problem{{ Metric: "x_gigabytes", Text: `use base unit "bytes" instead of "gigabytes"`, }}, }, { name: "kilograms", in: ` # HELP x_kilograms Test metric. # TYPE x_kilograms untyped x_kilograms 10 `, problems: []promlint.Problem{{ Metric: "x_kilograms", Text: `use base unit "grams" instead of "kilograms"`, }}, }, { name: "nanocelsius", in: ` # HELP x_nanocelsius Test metric. # TYPE x_nanocelsius untyped x_nanocelsius 10 `, problems: []promlint.Problem{{ Metric: "x_nanocelsius", Text: `use base unit "celsius" instead of "nanocelsius"`, }}, }, { name: "kilometers", in: ` # HELP x_kilometers Test metric. # TYPE x_kilometers untyped x_kilometers 10 `, problems: []promlint.Problem{{ Metric: "x_kilometers", Text: `use base unit "meters" instead of "kilometers"`, }}, }, { name: "picometers", in: ` # HELP x_picometers Test metric. # TYPE x_picometers untyped x_picometers 10 `, problems: []promlint.Problem{{ Metric: "x_picometers", Text: `use base unit "meters" instead of "picometers"`, }}, }, { name: "microseconds", in: ` # HELP x_microseconds Test metric. # TYPE x_microseconds untyped x_microseconds 10 `, problems: []promlint.Problem{{ Metric: "x_microseconds", Text: `use base unit "seconds" instead of "microseconds"`, }}, }, { name: "minutes", in: ` # HELP x_minutes Test metric. # TYPE x_minutes untyped x_minutes 10 `, problems: []promlint.Problem{{ Metric: "x_minutes", Text: `use base unit "seconds" instead of "minutes"`, }}, }, { name: "hours", in: ` # HELP x_hours Test metric. # TYPE x_hours untyped x_hours 10 `, problems: []promlint.Problem{{ Metric: "x_hours", Text: `use base unit "seconds" instead of "hours"`, }}, }, { name: "days", in: ` # HELP x_days Test metric. # TYPE x_days untyped x_days 10 `, problems: []promlint.Problem{{ Metric: "x_days", Text: `use base unit "seconds" instead of "days"`, }}, }, { name: "kelvins", in: ` # HELP x_kelvins Test metric. # TYPE x_kelvins untyped x_kelvins 10 `, problems: []promlint.Problem{{ Metric: "x_kelvins", Text: `use base unit "kelvin" instead of "kelvins"`, }}, }, { name: "fahrenheit", in: ` # HELP thermometers_fahrenheit Test metric. # TYPE thermometers_fahrenheit untyped thermometers_fahrenheit 10 `, problems: []promlint.Problem{{ Metric: "thermometers_fahrenheit", Text: `use base unit "celsius" instead of "fahrenheit"`, }}, }, { name: "rankine", in: ` # HELP thermometers_rankine Test metric. # TYPE thermometers_rankine untyped thermometers_rankine 10 `, problems: []promlint.Problem{{ Metric: "thermometers_rankine", Text: `use base unit "celsius" instead of "rankine"`, }}, }, { name: "inches", in: ` # HELP x_inches Test metric. # TYPE x_inches untyped x_inches 10 `, problems: []promlint.Problem{{ Metric: "x_inches", Text: `use base unit "meters" instead of "inches"`, }}, }, { name: "yards", in: ` # HELP x_yards Test metric. # TYPE x_yards untyped x_yards 10 `, problems: []promlint.Problem{{ Metric: "x_yards", Text: `use base unit "meters" instead of "yards"`, }}, }, { name: "miles", in: ` # HELP x_miles Test metric. # TYPE x_miles untyped x_miles 10 `, problems: []promlint.Problem{{ Metric: "x_miles", Text: `use base unit "meters" instead of "miles"`, }}, }, { name: "bits", in: ` # HELP x_bits Test metric. # TYPE x_bits untyped x_bits 10 `, problems: []promlint.Problem{{ Metric: "x_bits", Text: `use base unit "bytes" instead of "bits"`, }}, }, { name: "calories", in: ` # HELP x_calories Test metric. # TYPE x_calories untyped x_calories 10 `, problems: []promlint.Problem{{ Metric: "x_calories", Text: `use base unit "joules" instead of "calories"`, }}, }, { name: "pounds", in: ` # HELP x_pounds Test metric. # TYPE x_pounds untyped x_pounds 10 `, problems: []promlint.Problem{{ Metric: "x_pounds", Text: `use base unit "grams" instead of "pounds"`, }}, }, { name: "ounces", in: ` # HELP x_ounces Test metric. # TYPE x_ounces untyped x_ounces 10 `, problems: []promlint.Problem{{ Metric: "x_ounces", Text: `use base unit "grams" instead of "ounces"`, }}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { l := promlint.New(strings.NewReader(tt.in)) problems, err := l.Lint() if err != nil { t.Fatalf("unexpected error: %v", err) } if want, got := tt.problems, problems; !reflect.DeepEqual(want, got) { t.Fatalf("unexpected problems:\n- want: %v\n- got: %v", want, got) } }) } } func TestLintCounter(t *testing.T) { tests := []test{ { name: "counter without _total suffix", in: ` # HELP x_bytes Test metric. # TYPE x_bytes counter x_bytes 10 `, problems: []promlint.Problem{{ Metric: "x_bytes", Text: `counter metrics should have "_total" suffix`, }}, }, { name: "gauge with _total suffix", in: ` # HELP x_bytes_total Test metric. # TYPE x_bytes_total gauge x_bytes_total 10 `, problems: []promlint.Problem{{ Metric: "x_bytes_total", Text: `non-counter metrics should not have "_total" suffix`, }}, }, { name: "counter with _total suffix", in: ` # HELP x_bytes_total Test metric. # TYPE x_bytes_total counter x_bytes_total 10 `, }, { name: "gauge without _total suffix", in: ` # HELP x_bytes Test metric. # TYPE x_bytes gauge x_bytes 10 `, }, { name: "untyped with _total suffix", in: ` # HELP x_bytes_total Test metric. # TYPE x_bytes_total untyped x_bytes_total 10 `, }, { name: "untyped without _total suffix", in: ` # HELP x_bytes Test metric. # TYPE x_bytes untyped x_bytes 10 `, }, } runTests(t, tests) } func TestLintHistogramSummaryReserved(t *testing.T) { tests := []test{ { name: "gauge with _bucket suffix", in: ` # HELP x_bytes_bucket Test metric. # TYPE x_bytes_bucket gauge x_bytes_bucket 10 `, problems: []promlint.Problem{{ Metric: "x_bytes_bucket", Text: `non-histogram metrics should not have "_bucket" suffix`, }}, }, { name: "gauge with _count suffix", in: ` # HELP x_bytes_count Test metric. # TYPE x_bytes_count gauge x_bytes_count 10 `, problems: []promlint.Problem{{ Metric: "x_bytes_count", Text: `non-histogram and non-summary metrics should not have "_count" suffix`, }}, }, { name: "gauge with _sum suffix", in: ` # HELP x_bytes_sum Test metric. # TYPE x_bytes_sum gauge x_bytes_sum 10 `, problems: []promlint.Problem{{ Metric: "x_bytes_sum", Text: `non-histogram and non-summary metrics should not have "_sum" suffix`, }}, }, { name: "gauge with le label", in: ` # HELP x_bytes Test metric. # TYPE x_bytes gauge x_bytes{le="1"} 10 `, problems: []promlint.Problem{{ Metric: "x_bytes", Text: `non-histogram metrics should not have "le" label`, }}, }, { name: "gauge with quantile label", in: ` # HELP x_bytes Test metric. # TYPE x_bytes gauge x_bytes{quantile="1"} 10 `, problems: []promlint.Problem{{ Metric: "x_bytes", Text: `non-summary metrics should not have "quantile" label`, }}, }, { name: "histogram with quantile label", in: ` # HELP tsdb_compaction_duration Duration of compaction runs. # TYPE tsdb_compaction_duration histogram tsdb_compaction_duration_bucket{le="0.005",quantile="0.01"} 0 tsdb_compaction_duration_bucket{le="0.01",quantile="0.01"} 0 tsdb_compaction_duration_bucket{le="0.025",quantile="0.01"} 0 tsdb_compaction_duration_bucket{le="0.05",quantile="0.01"} 0 tsdb_compaction_duration_bucket{le="0.1",quantile="0.01"} 0 tsdb_compaction_duration_bucket{le="0.25",quantile="0.01"} 0 tsdb_compaction_duration_bucket{le="0.5",quantile="0.01"} 57 tsdb_compaction_duration_bucket{le="1",quantile="0.01"} 68 tsdb_compaction_duration_bucket{le="2.5",quantile="0.01"} 69 tsdb_compaction_duration_bucket{le="5",quantile="0.01"} 69 tsdb_compaction_duration_bucket{le="10",quantile="0.01"} 69 tsdb_compaction_duration_bucket{le="+Inf",quantile="0.01"} 69 tsdb_compaction_duration_sum 28.740810936000006 tsdb_compaction_duration_count 69 `, problems: []promlint.Problem{{ Metric: "tsdb_compaction_duration", Text: `non-summary metrics should not have "quantile" label`, }}, }, { name: "summary with le label", in: ` # HELP go_gc_duration_seconds A summary of the GC invocation durations. # TYPE go_gc_duration_seconds summary go_gc_duration_seconds{quantile="0",le="0.01"} 4.2365e-05 go_gc_duration_seconds{quantile="0.25",le="0.01"} 8.1492e-05 go_gc_duration_seconds{quantile="0.5",le="0.01"} 0.000100656 go_gc_duration_seconds{quantile="0.75",le="0.01"} 0.000113913 go_gc_duration_seconds{quantile="1",le="0.01"} 0.021754305 go_gc_duration_seconds_sum 1.769429004 go_gc_duration_seconds_count 5962 `, problems: []promlint.Problem{{ Metric: "go_gc_duration_seconds", Text: `non-histogram metrics should not have "le" label`, }}, }, { name: "histogram OK", in: ` # HELP tsdb_compaction_duration Duration of compaction runs. # TYPE tsdb_compaction_duration histogram tsdb_compaction_duration_bucket{le="0.005"} 0 tsdb_compaction_duration_bucket{le="0.01"} 0 tsdb_compaction_duration_bucket{le="0.025"} 0 tsdb_compaction_duration_bucket{le="0.05"} 0 tsdb_compaction_duration_bucket{le="0.1"} 0 tsdb_compaction_duration_bucket{le="0.25"} 0 tsdb_compaction_duration_bucket{le="0.5"} 57 tsdb_compaction_duration_bucket{le="1"} 68 tsdb_compaction_duration_bucket{le="2.5"} 69 tsdb_compaction_duration_bucket{le="5"} 69 tsdb_compaction_duration_bucket{le="10"} 69 tsdb_compaction_duration_bucket{le="+Inf"} 69 tsdb_compaction_duration_sum 28.740810936000006 tsdb_compaction_duration_count 69 `, }, { name: "summary OK", in: ` # HELP go_gc_duration_seconds A summary of the GC invocation durations. # TYPE go_gc_duration_seconds summary go_gc_duration_seconds{quantile="0"} 4.2365e-05 go_gc_duration_seconds{quantile="0.25"} 8.1492e-05 go_gc_duration_seconds{quantile="0.5"} 0.000100656 go_gc_duration_seconds{quantile="0.75"} 0.000113913 go_gc_duration_seconds{quantile="1"} 0.021754305 go_gc_duration_seconds_sum 1.769429004 go_gc_duration_seconds_count 5962 `, }, } runTests(t, tests) } func TestLintMetricTypeInName(t *testing.T) { genTest := func(n, t, err string, problems ...promlint.Problem) test { return test{ name: fmt.Sprintf("%s with _%s suffix", t, t), in: fmt.Sprintf(` # HELP %s Test metric. # TYPE %s %s %s 10 `, n, n, t, n), problems: append(problems, promlint.Problem{ Metric: n, Text: fmt.Sprintf(`metric name should not include type '%s'`, err), }), } } twoProbTest := genTest("http_requests_counter", "counter", "counter", promlint.Problem{ Metric: "http_requests_counter", Text: `counter metrics should have "_total" suffix`, }) tests := []test{ twoProbTest, genTest("instance_memory_limit_bytes_gauge", "gauge", "gauge"), genTest("request_duration_seconds_summary", "summary", "summary"), genTest("request_duration_seconds_histogram", "histogram", "histogram"), genTest("request_duration_seconds_HISTOGRAM", "histogram", "histogram"), genTest("instance_memory_limit_gauge_bytes", "gauge", "gauge"), } runTests(t, tests) } func TestLintReservedChars(t *testing.T) { tests := []test{ { name: "request_duration::_seconds", in: ` # HELP request_duration::_seconds Test metric. # TYPE request_duration::_seconds histogram request_duration::_seconds 10 `, problems: []promlint.Problem{ { Metric: "request_duration::_seconds", Text: "metric names should not contain ':'", }, }, }, } runTests(t, tests) } func TestLintCamelCase(t *testing.T) { tests := []test{ { name: "requestDuration_seconds", in: ` # HELP requestDuration_seconds Test metric. # TYPE requestDuration_seconds histogram requestDuration_seconds 10 `, problems: []promlint.Problem{ { Metric: "requestDuration_seconds", Text: "metric names should be written in 'snake_case' not 'camelCase'", }, }, }, { name: "request_duration_seconds", in: ` # HELP request_duration_seconds Test metric. # TYPE request_duration_seconds histogram request_duration_seconds{httpService="foo"} 10 `, problems: []promlint.Problem{ { Metric: "request_duration_seconds", Text: "label names should be written in 'snake_case' not 'camelCase'", }, }, }, } runTests(t, tests) } func TestLintUnitAbbreviations(t *testing.T) { genTest := func(n string) test { return test{ name: n + " with abbreviated unit", in: fmt.Sprintf(` # HELP %s Test metric. # TYPE %s gauge %s 10 `, n, n, n), problems: []promlint.Problem{ { Metric: n, Text: "metric names should not contain abbreviated units", }, }, } } tests := []test{ genTest("instance_memory_limit_b"), genTest("instance_memory_limit_kb"), genTest("instance_memory_limit_mb"), genTest("instance_memory_limit_MB"), genTest("instance_memory_limit_gb"), genTest("instance_memory_limit_tb"), genTest("instance_memory_limit_pb"), genTest("request_duration_s"), genTest("request_duration_ms"), genTest("request_duration_us"), genTest("request_duration_ns"), genTest("request_duration_sec"), genTest("request_sec_duration"), genTest("request_duration_m"), genTest("request_duration_h"), genTest("request_duration_d"), } runTests(t, tests) } func runTests(t *testing.T, tests []test) { t.Helper() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { l := promlint.New(strings.NewReader(tt.in)) problems, err := l.Lint() if err != nil { t.Fatalf("unexpected error: %v", err) } if want, got := tt.problems, problems; !reflect.DeepEqual(want, got) { t.Fatalf("unexpected problems:\n- want: %v\n- got: %v", want, got) } }) } } func TestCustomValidations(t *testing.T) { lintAndVerify := func(l *promlint.Linter, cv test) { problems, err := l.Lint() if err != nil { t.Fatalf("unexpected error: %v", err) } if want, got := cv.problems, problems; !reflect.DeepEqual(want, got) { t.Fatalf("unexpected problems:\n- want: %v\n- got: %v", want, got) } } prob := []promlint.Problem{ { Metric: "mc_something_total", Text: "expected metric name to start with 'memcached_'", }, } cv := test{ name: "metric without necessary prefix", in: ` # HELP mc_something_total Test metric. # TYPE mc_something_total counter mc_something_total 10 `, problems: nil, } prefixValidation := func(mf *dto.MetricFamily) []error { if !strings.HasPrefix(mf.GetName(), "memcached_") { return []error{errors.New("expected metric name to start with 'memcached_'")} } return nil } t.Helper() t.Run(cv.name, func(t *testing.T) { // no problems l1 := promlint.New(strings.NewReader(cv.in)) lintAndVerify(l1, cv) }) t.Run(cv.name, func(t *testing.T) { // prefix problems l2 := promlint.New(strings.NewReader(cv.in)) l2.AddCustomValidations(prefixValidation) cv.problems = prob lintAndVerify(l2, cv) }) } func TestLintDuplicateMetric(t *testing.T) { const msg = "metric not unique" tests := []test{ { name: "metric not unique", in: ` # HELP not_unique_total the helptext # TYPE not_unique_total counter not_unique_total{bar="abc", spam="xyz"} 1 not_unique_total{bar="abc", spam="xyz"} 2 `, problems: []promlint.Problem{ { Metric: "not_unique_total", Text: msg, }, }, }, } runTests(t, tests) } client_golang-1.21.1/prometheus/testutil/promlint/validation.go000066400000000000000000000021571476160432400250120ustar00rootroot00000000000000// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package promlint import ( dto "github.com/prometheus/client_model/go" "github.com/prometheus/client_golang/prometheus/testutil/promlint/validations" ) type Validation = func(mf *dto.MetricFamily) []error var defaultValidations = []Validation{ validations.LintHelp, validations.LintMetricUnits, validations.LintCounter, validations.LintHistogramSummaryReserved, validations.LintMetricTypeInName, validations.LintReservedChars, validations.LintCamelCase, validations.LintUnitAbbreviations, validations.LintDuplicateMetric, } client_golang-1.21.1/prometheus/testutil/promlint/validations/000077500000000000000000000000001476160432400246415ustar00rootroot00000000000000client_golang-1.21.1/prometheus/testutil/promlint/validations/counter_validations.go000066400000000000000000000025151476160432400312470ustar00rootroot00000000000000// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package validations import ( "errors" "strings" dto "github.com/prometheus/client_model/go" ) // LintCounter detects issues specific to counters, as well as patterns that should // only be used with counters. func LintCounter(mf *dto.MetricFamily) []error { var problems []error isCounter := mf.GetType() == dto.MetricType_COUNTER isUntyped := mf.GetType() == dto.MetricType_UNTYPED hasTotalSuffix := strings.HasSuffix(mf.GetName(), "_total") switch { case isCounter && !hasTotalSuffix: problems = append(problems, errors.New(`counter metrics should have "_total" suffix`)) case !isUntyped && !isCounter && hasTotalSuffix: problems = append(problems, errors.New(`non-counter metrics should not have "_total" suffix`)) } return problems } client_golang-1.21.1/prometheus/testutil/promlint/validations/duplicate_validations.go000066400000000000000000000020261476160432400315370ustar00rootroot00000000000000// Copyright 2024 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package validations import ( "errors" "reflect" dto "github.com/prometheus/client_model/go" ) // LintDuplicateMetric detects duplicate metric. func LintDuplicateMetric(mf *dto.MetricFamily) []error { var problems []error for i, m := range mf.Metric { for _, k := range mf.Metric[i+1:] { if reflect.DeepEqual(m.Label, k.Label) { problems = append(problems, errors.New("metric not unique")) break } } } return problems } client_golang-1.21.1/prometheus/testutil/promlint/validations/generic_name_validations.go000066400000000000000000000056121476160432400322050ustar00rootroot00000000000000// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package validations import ( "errors" "fmt" "regexp" "strings" dto "github.com/prometheus/client_model/go" ) var camelCase = regexp.MustCompile(`[a-z][A-Z]`) // LintMetricUnits detects issues with metric unit names. func LintMetricUnits(mf *dto.MetricFamily) []error { var problems []error unit, base, ok := metricUnits(*mf.Name) if !ok { // No known units detected. return nil } // Unit is already a base unit. if unit == base { return nil } problems = append(problems, fmt.Errorf("use base unit %q instead of %q", base, unit)) return problems } // LintMetricTypeInName detects when the metric type is included in the metric name. func LintMetricTypeInName(mf *dto.MetricFamily) []error { if mf.GetType() == dto.MetricType_UNTYPED { return nil } var problems []error n := strings.ToLower(mf.GetName()) typename := strings.ToLower(mf.GetType().String()) if strings.Contains(n, "_"+typename+"_") || strings.HasSuffix(n, "_"+typename) { problems = append(problems, fmt.Errorf(`metric name should not include type '%s'`, typename)) } return problems } // LintReservedChars detects colons in metric names. func LintReservedChars(mf *dto.MetricFamily) []error { var problems []error if strings.Contains(mf.GetName(), ":") { problems = append(problems, errors.New("metric names should not contain ':'")) } return problems } // LintCamelCase detects metric names and label names written in camelCase. func LintCamelCase(mf *dto.MetricFamily) []error { var problems []error if camelCase.FindString(mf.GetName()) != "" { problems = append(problems, errors.New("metric names should be written in 'snake_case' not 'camelCase'")) } for _, m := range mf.GetMetric() { for _, l := range m.GetLabel() { if camelCase.FindString(l.GetName()) != "" { problems = append(problems, errors.New("label names should be written in 'snake_case' not 'camelCase'")) } } } return problems } // LintUnitAbbreviations detects abbreviated units in the metric name. func LintUnitAbbreviations(mf *dto.MetricFamily) []error { var problems []error n := strings.ToLower(mf.GetName()) for _, s := range unitAbbreviations { if strings.Contains(n, "_"+s+"_") || strings.HasSuffix(n, "_"+s) { problems = append(problems, errors.New("metric names should not contain abbreviated units")) } } return problems } client_golang-1.21.1/prometheus/testutil/promlint/validations/help_validations.go000066400000000000000000000017171476160432400305230ustar00rootroot00000000000000// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package validations import ( "errors" dto "github.com/prometheus/client_model/go" ) // LintHelp detects issues related to the help text for a metric. func LintHelp(mf *dto.MetricFamily) []error { var problems []error // Expect all metrics to have help text available. if mf.Help == nil { problems = append(problems, errors.New("no help text")) } return problems } client_golang-1.21.1/prometheus/testutil/promlint/validations/histogram_validations.go000066400000000000000000000040361476160432400315650ustar00rootroot00000000000000// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package validations import ( "errors" "strings" dto "github.com/prometheus/client_model/go" ) // LintHistogramSummaryReserved detects when other types of metrics use names or labels // reserved for use by histograms and/or summaries. func LintHistogramSummaryReserved(mf *dto.MetricFamily) []error { // These rules do not apply to untyped metrics. t := mf.GetType() if t == dto.MetricType_UNTYPED { return nil } var problems []error isHistogram := t == dto.MetricType_HISTOGRAM isSummary := t == dto.MetricType_SUMMARY n := mf.GetName() if !isHistogram && strings.HasSuffix(n, "_bucket") { problems = append(problems, errors.New(`non-histogram metrics should not have "_bucket" suffix`)) } if !isHistogram && !isSummary && strings.HasSuffix(n, "_count") { problems = append(problems, errors.New(`non-histogram and non-summary metrics should not have "_count" suffix`)) } if !isHistogram && !isSummary && strings.HasSuffix(n, "_sum") { problems = append(problems, errors.New(`non-histogram and non-summary metrics should not have "_sum" suffix`)) } for _, m := range mf.GetMetric() { for _, l := range m.GetLabel() { ln := l.GetName() if !isHistogram && ln == "le" { problems = append(problems, errors.New(`non-histogram metrics should not have "le" label`)) } if !isSummary && ln == "quantile" { problems = append(problems, errors.New(`non-summary metrics should not have "quantile" label`)) } } } return problems } client_golang-1.21.1/prometheus/testutil/promlint/validations/units.go000066400000000000000000000051111476160432400263300ustar00rootroot00000000000000// Copyright 2020 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package validations import "strings" // Units and their possible prefixes recognized by this library. More can be // added over time as needed. var ( // map a unit to the appropriate base unit. units = map[string]string{ // Base units. "amperes": "amperes", "bytes": "bytes", "celsius": "celsius", // Also allow Celsius because it is common in typical Prometheus use cases. "grams": "grams", "joules": "joules", "kelvin": "kelvin", // SI base unit, used in special cases (e.g. color temperature, scientific measurements). "meters": "meters", // Both American and international spelling permitted. "metres": "metres", "seconds": "seconds", "volts": "volts", // Non base units. // Time. "minutes": "seconds", "hours": "seconds", "days": "seconds", "weeks": "seconds", // Temperature. "kelvins": "kelvin", "fahrenheit": "celsius", "rankine": "celsius", // Length. "inches": "meters", "yards": "meters", "miles": "meters", // Bytes. "bits": "bytes", // Energy. "calories": "joules", // Mass. "pounds": "grams", "ounces": "grams", } unitPrefixes = []string{ "pico", "nano", "micro", "milli", "centi", "deci", "deca", "hecto", "kilo", "kibi", "mega", "mibi", "giga", "gibi", "tera", "tebi", "peta", "pebi", } // Common abbreviations that we'd like to discourage. unitAbbreviations = []string{ "s", "ms", "us", "ns", "sec", "b", "kb", "mb", "gb", "tb", "pb", "m", "h", "d", } ) // metricUnits attempts to detect known unit types used as part of a metric name, // e.g. "foo_bytes_total" or "bar_baz_milligrams". func metricUnits(m string) (unit, base string, ok bool) { ss := strings.Split(m, "_") for _, s := range ss { if base, found := units[s]; found { return s, base, true } for _, p := range unitPrefixes { if strings.HasPrefix(s, p) { if base, found := units[s[len(p):]]; found { return s, base, true } } } } return "", "", false } client_golang-1.21.1/prometheus/testutil/testutil.go000066400000000000000000000315501476160432400226700ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package testutil provides helpers to test code using the prometheus package // of client_golang. // // While writing unit tests to verify correct instrumentation of your code, it's // a common mistake to mostly test the instrumentation library instead of your // own code. Rather than verifying that a prometheus.Counter's value has changed // as expected or that it shows up in the exposition after registration, it is // in general more robust and more faithful to the concept of unit tests to use // mock implementations of the prometheus.Counter and prometheus.Registerer // interfaces that simply assert that the Add or Register methods have been // called with the expected arguments. However, this might be overkill in simple // scenarios. The ToFloat64 function is provided for simple inspection of a // single-value metric, but it has to be used with caution. // // End-to-end tests to verify all or larger parts of the metrics exposition can // be implemented with the CollectAndCompare or GatherAndCompare functions. The // most appropriate use is not so much testing instrumentation of your code, but // testing custom prometheus.Collector implementations and in particular whole // exporters, i.e. programs that retrieve telemetry data from a 3rd party source // and convert it into Prometheus metrics. // // In a similar pattern, CollectAndLint and GatherAndLint can be used to detect // metrics that have issues with their name, type, or metadata without being // necessarily invalid, e.g. a counter with a name missing the β€œ_total” suffix. package testutil import ( "bytes" "errors" "fmt" "io" "net/http" "github.com/kylelemons/godebug/diff" dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" "github.com/prometheus/common/model" "google.golang.org/protobuf/proto" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/internal" ) // ToFloat64 collects all Metrics from the provided Collector. It expects that // this results in exactly one Metric being collected, which must be a Gauge, // Counter, or Untyped. In all other cases, ToFloat64 panics. ToFloat64 returns // the value of the collected Metric. // // The Collector provided is typically a simple instance of Gauge or Counter, or // – less commonly – a GaugeVec or CounterVec with exactly one element. But any // Collector fulfilling the prerequisites described above will do. // // Use this function with caution. It is computationally very expensive and thus // not suited at all to read values from Metrics in regular code. This is really // only for testing purposes, and even for testing, other approaches are often // more appropriate (see this package's documentation). // // A clear anti-pattern would be to use a metric type from the prometheus // package to track values that are also needed for something else than the // exposition of Prometheus metrics. For example, you would like to track the // number of items in a queue because your code should reject queuing further // items if a certain limit is reached. It is tempting to track the number of // items in a prometheus.Gauge, as it is then easily available as a metric for // exposition, too. However, then you would need to call ToFloat64 in your // regular code, potentially quite often. The recommended way is to track the // number of items conventionally (in the way you would have done it without // considering Prometheus metrics) and then expose the number with a // prometheus.GaugeFunc. func ToFloat64(c prometheus.Collector) float64 { var ( m prometheus.Metric mCount int mChan = make(chan prometheus.Metric) done = make(chan struct{}) ) go func() { for m = range mChan { mCount++ } close(done) }() c.Collect(mChan) close(mChan) <-done if mCount != 1 { panic(fmt.Errorf("collected %d metrics instead of exactly 1", mCount)) } pb := &dto.Metric{} if err := m.Write(pb); err != nil { panic(fmt.Errorf("error happened while collecting metrics: %w", err)) } if pb.Gauge != nil { return pb.Gauge.GetValue() } if pb.Counter != nil { return pb.Counter.GetValue() } if pb.Untyped != nil { return pb.Untyped.GetValue() } panic(fmt.Errorf("collected a non-gauge/counter/untyped metric: %s", pb)) } // CollectAndCount registers the provided Collector with a newly created // pedantic Registry. It then calls GatherAndCount with that Registry and with // the provided metricNames. In the unlikely case that the registration or the // gathering fails, this function panics. (This is inconsistent with the other // CollectAnd… functions in this package and has historical reasons. Changing // the function signature would be a breaking change and will therefore only // happen with the next major version bump.) func CollectAndCount(c prometheus.Collector, metricNames ...string) int { reg := prometheus.NewPedanticRegistry() if err := reg.Register(c); err != nil { panic(fmt.Errorf("registering collector failed: %w", err)) } result, err := GatherAndCount(reg, metricNames...) if err != nil { panic(err) } return result } // GatherAndCount gathers all metrics from the provided Gatherer and counts // them. It returns the number of metric children in all gathered metric // families together. If any metricNames are provided, only metrics with those // names are counted. func GatherAndCount(g prometheus.Gatherer, metricNames ...string) (int, error) { got, err := g.Gather() if err != nil { return 0, fmt.Errorf("gathering metrics failed: %w", err) } if metricNames != nil { got = filterMetrics(got, metricNames) } result := 0 for _, mf := range got { result += len(mf.GetMetric()) } return result, nil } // ScrapeAndCompare calls a remote exporter's endpoint which is expected to return some metrics in // plain text format. Then it compares it with the results that the `expected` would return. // If the `metricNames` is not empty it would filter the comparison only to the given metric names. // // NOTE: Be mindful of accidental discrepancies between expected and metricNames; metricNames filter // both expected and scraped metrics. See https://github.com/prometheus/client_golang/issues/1351. func ScrapeAndCompare(url string, expected io.Reader, metricNames ...string) error { resp, err := http.Get(url) if err != nil { return fmt.Errorf("scraping metrics failed: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return fmt.Errorf("the scraping target returned a status code other than 200: %d", resp.StatusCode) } scraped, err := convertReaderToMetricFamily(resp.Body) if err != nil { return err } wanted, err := convertReaderToMetricFamily(expected) if err != nil { return err } return compareMetricFamilies(scraped, wanted, metricNames...) } // CollectAndCompare collects the metrics identified by `metricNames` and compares them in the Prometheus text // exposition format to the data read from expected. // // NOTE: Be mindful of accidental discrepancies between expected and metricNames; metricNames filter // both expected and collected metrics. See https://github.com/prometheus/client_golang/issues/1351. func CollectAndCompare(c prometheus.Collector, expected io.Reader, metricNames ...string) error { reg := prometheus.NewPedanticRegistry() if err := reg.Register(c); err != nil { return fmt.Errorf("registering collector failed: %w", err) } return GatherAndCompare(reg, expected, metricNames...) } // GatherAndCompare gathers all metrics from the provided Gatherer and compares // it to an expected output read from the provided Reader in the Prometheus text // exposition format. If any metricNames are provided, only metrics with those // names are compared. // // NOTE: Be mindful of accidental discrepancies between expected and metricNames; metricNames filter // both expected and gathered metrics. See https://github.com/prometheus/client_golang/issues/1351. func GatherAndCompare(g prometheus.Gatherer, expected io.Reader, metricNames ...string) error { return TransactionalGatherAndCompare(prometheus.ToTransactionalGatherer(g), expected, metricNames...) } // TransactionalGatherAndCompare gathers all metrics from the provided Gatherer and compares // it to an expected output read from the provided Reader in the Prometheus text // exposition format. If any metricNames are provided, only metrics with those // names are compared. // // NOTE: Be mindful of accidental discrepancies between expected and metricNames; metricNames filter // both expected and gathered metrics. See https://github.com/prometheus/client_golang/issues/1351. func TransactionalGatherAndCompare(g prometheus.TransactionalGatherer, expected io.Reader, metricNames ...string) error { got, done, err := g.Gather() defer done() if err != nil { return fmt.Errorf("gathering metrics failed: %w", err) } wanted, err := convertReaderToMetricFamily(expected) if err != nil { return err } return compareMetricFamilies(got, wanted, metricNames...) } // CollectAndFormat collects the metrics identified by `metricNames` and returns them in the given format. func CollectAndFormat(c prometheus.Collector, format expfmt.FormatType, metricNames ...string) ([]byte, error) { reg := prometheus.NewPedanticRegistry() if err := reg.Register(c); err != nil { return nil, fmt.Errorf("registering collector failed: %w", err) } gotFiltered, err := reg.Gather() if err != nil { return nil, fmt.Errorf("gathering metrics failed: %w", err) } gotFiltered = filterMetrics(gotFiltered, metricNames) var gotFormatted bytes.Buffer enc := expfmt.NewEncoder(&gotFormatted, expfmt.NewFormat(format)) for _, mf := range gotFiltered { if err := enc.Encode(mf); err != nil { return nil, fmt.Errorf("encoding gathered metrics failed: %w", err) } } return gotFormatted.Bytes(), nil } // convertReaderToMetricFamily would read from a io.Reader object and convert it to a slice of // dto.MetricFamily. func convertReaderToMetricFamily(reader io.Reader) ([]*dto.MetricFamily, error) { var tp expfmt.TextParser notNormalized, err := tp.TextToMetricFamilies(reader) if err != nil { return nil, fmt.Errorf("converting reader to metric families failed: %w", err) } // The text protocol handles empty help fields inconsistently. When // encoding, any non-nil value, include the empty string, produces a // "# HELP" line. But when decoding, the help field is only set to a // non-nil value if the "# HELP" line contains a non-empty value. // // Because metrics in a registry always have non-nil help fields, populate // any nil help fields in the parsed metrics with the empty string so that // when we compare text encodings, the results are consistent. for _, metric := range notNormalized { if metric.Help == nil { metric.Help = proto.String("") } } return internal.NormalizeMetricFamilies(notNormalized), nil } // compareMetricFamilies would compare 2 slices of metric families, and optionally filters both of // them to the `metricNames` provided. func compareMetricFamilies(got, expected []*dto.MetricFamily, metricNames ...string) error { if metricNames != nil { got = filterMetrics(got, metricNames) expected = filterMetrics(expected, metricNames) } return compare(got, expected) } // compare encodes both provided slices of metric families into the text format, // compares their string message, and returns an error if they do not match. // The error contains the encoded text of both the desired and the actual // result. func compare(got, want []*dto.MetricFamily) error { var gotBuf, wantBuf bytes.Buffer enc := expfmt.NewEncoder(&gotBuf, expfmt.NewFormat(expfmt.TypeTextPlain).WithEscapingScheme(model.NoEscaping)) for _, mf := range got { if err := enc.Encode(mf); err != nil { return fmt.Errorf("encoding gathered metrics failed: %w", err) } } enc = expfmt.NewEncoder(&wantBuf, expfmt.NewFormat(expfmt.TypeTextPlain).WithEscapingScheme(model.NoEscaping)) for _, mf := range want { if err := enc.Encode(mf); err != nil { return fmt.Errorf("encoding expected metrics failed: %w", err) } } if diffErr := diff.Diff(gotBuf.String(), wantBuf.String()); diffErr != "" { return errors.New(diffErr) } return nil } func filterMetrics(metrics []*dto.MetricFamily, names []string) []*dto.MetricFamily { var filtered []*dto.MetricFamily for _, m := range metrics { for _, name := range names { if m.GetName() == name { filtered = append(filtered, m) break } } } return filtered } client_golang-1.21.1/prometheus/testutil/testutil_test.go000066400000000000000000000276451476160432400237410ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package testutil import ( "fmt" "net/http" "net/http/httptest" "strings" "testing" "github.com/prometheus/common/expfmt" "github.com/prometheus/client_golang/prometheus" ) type untypedCollector struct{} func (u untypedCollector) Describe(c chan<- *prometheus.Desc) { c <- prometheus.NewDesc("name", "help", nil, nil) } func (u untypedCollector) Collect(c chan<- prometheus.Metric) { c <- prometheus.MustNewConstMetric( prometheus.NewDesc("name", "help", nil, nil), prometheus.UntypedValue, 2001, ) } func TestToFloat64(t *testing.T) { gaugeWithAValueSet := prometheus.NewGauge(prometheus.GaugeOpts{}) gaugeWithAValueSet.Set(3.14) counterVecWithOneElement := prometheus.NewCounterVec(prometheus.CounterOpts{}, []string{"foo"}) counterVecWithOneElement.WithLabelValues("bar").Inc() counterVecWithTwoElements := prometheus.NewCounterVec(prometheus.CounterOpts{}, []string{"foo"}) counterVecWithTwoElements.WithLabelValues("bar").Add(42) counterVecWithTwoElements.WithLabelValues("baz").Inc() histogramVecWithOneElement := prometheus.NewHistogramVec(prometheus.HistogramOpts{}, []string{"foo"}) histogramVecWithOneElement.WithLabelValues("bar").Observe(2.7) scenarios := map[string]struct { collector prometheus.Collector panics bool want float64 }{ "simple counter": { collector: prometheus.NewCounter(prometheus.CounterOpts{}), panics: false, want: 0, }, "simple gauge": { collector: prometheus.NewGauge(prometheus.GaugeOpts{}), panics: false, want: 0, }, "simple untyped": { collector: untypedCollector{}, panics: false, want: 2001, }, "simple histogram": { collector: prometheus.NewHistogram(prometheus.HistogramOpts{}), panics: true, }, "simple summary": { collector: prometheus.NewSummary(prometheus.SummaryOpts{}), panics: true, }, "simple gauge with an actual value set": { collector: gaugeWithAValueSet, panics: false, want: 3.14, }, "counter vec with zero elements": { collector: prometheus.NewCounterVec(prometheus.CounterOpts{}, nil), panics: true, }, "counter vec with one element": { collector: counterVecWithOneElement, panics: false, want: 1, }, "counter vec with two elements": { collector: counterVecWithTwoElements, panics: true, }, "histogram vec with one element": { collector: histogramVecWithOneElement, panics: true, }, } for n, s := range scenarios { t.Run(n, func(t *testing.T) { defer func() { r := recover() if r == nil && s.panics { t.Error("expected panic") } else if r != nil && !s.panics { t.Error("unexpected panic: ", r) } // Any other combination is the expected outcome. }() if got := ToFloat64(s.collector); got != s.want { t.Errorf("want %f, got %f", s.want, got) } }) } } func TestCollectAndCompare(t *testing.T) { const metadata = ` # HELP some_total A value that represents a counter. # TYPE some_total counter ` c := prometheus.NewCounter(prometheus.CounterOpts{ Name: "some_total", Help: "A value that represents a counter.", ConstLabels: prometheus.Labels{ "label1": "value1", }, }) c.Inc() expected := ` some_total{ label1 = "value1" } 1 ` if err := CollectAndCompare(c, strings.NewReader(metadata+expected), "some_total"); err != nil { t.Errorf("unexpected collecting result:\n%s", err) } } func TestCollectAndCompareNoLabel(t *testing.T) { const metadata = ` # HELP some_total A value that represents a counter. # TYPE some_total counter ` c := prometheus.NewCounter(prometheus.CounterOpts{ Name: "some_total", Help: "A value that represents a counter.", }) c.Inc() expected := ` some_total 1 ` if err := CollectAndCompare(c, strings.NewReader(metadata+expected), "some_total"); err != nil { t.Errorf("unexpected collecting result:\n%s", err) } } func TestCollectAndCompareNoHelp(t *testing.T) { const metadata = ` # TYPE some_total counter ` c := prometheus.NewCounter(prometheus.CounterOpts{ Name: "some_total", }) c.Inc() expected := ` some_total 1 ` if err := CollectAndCompare(c, strings.NewReader(metadata+expected), "some_total"); err != nil { t.Errorf("unexpected collecting result:\n%s", err) } } func TestCollectAndCompareHistogram(t *testing.T) { inputs := []struct { name string c prometheus.Collector metadata string expect string observation float64 }{ { name: "Testing Histogram Collector", c: prometheus.NewHistogram(prometheus.HistogramOpts{ Name: "some_histogram", Help: "An example of a histogram", Buckets: []float64{1, 2, 3}, }), metadata: ` # HELP some_histogram An example of a histogram # TYPE some_histogram histogram `, expect: ` some_histogram{le="1"} 0 some_histogram{le="2"} 0 some_histogram{le="3"} 1 some_histogram_bucket{le="+Inf"} 1 some_histogram_sum 2.5 some_histogram_count 1 `, observation: 2.5, }, { name: "Testing HistogramVec Collector", c: prometheus.NewHistogramVec(prometheus.HistogramOpts{ Name: "some_histogram", Help: "An example of a histogram", Buckets: []float64{1, 2, 3}, }, []string{"test"}), metadata: ` # HELP some_histogram An example of a histogram # TYPE some_histogram histogram `, expect: ` some_histogram_bucket{test="test",le="1"} 0 some_histogram_bucket{test="test",le="2"} 0 some_histogram_bucket{test="test",le="3"} 1 some_histogram_bucket{test="test",le="+Inf"} 1 some_histogram_sum{test="test"} 2.5 some_histogram_count{test="test"} 1 `, observation: 2.5, }, } for _, input := range inputs { switch collector := input.c.(type) { case prometheus.Histogram: collector.Observe(input.observation) case *prometheus.HistogramVec: collector.WithLabelValues("test").Observe(input.observation) default: t.Fatalf("unsupported collector tested") } t.Run(input.name, func(t *testing.T) { if err := CollectAndCompare(input.c, strings.NewReader(input.metadata+input.expect)); err != nil { t.Errorf("unexpected collecting result:\n%s", err) } }) } } func TestNoMetricFilter(t *testing.T) { const metadata = ` # HELP some_total A value that represents a counter. # TYPE some_total counter ` c := prometheus.NewCounter(prometheus.CounterOpts{ Name: "some_total", Help: "A value that represents a counter.", ConstLabels: prometheus.Labels{ "label1": "value1", }, }) c.Inc() expected := ` some_total{label1="value1"} 1 ` if err := CollectAndCompare(c, strings.NewReader(metadata+expected)); err != nil { t.Errorf("unexpected collecting result:\n%s", err) } } func TestMetricNotFound(t *testing.T) { const metadata = ` # HELP some_other_metric A value that represents a counter. # TYPE some_other_metric counter ` c := prometheus.NewCounter(prometheus.CounterOpts{ Name: "some_total", Help: "A value that represents a counter.", ConstLabels: prometheus.Labels{ "label1": "value1", }, }) c.Inc() expected := ` some_other_metric{label1="value1"} 1 ` expectedError := `-# HELP some_total A value that represents a counter. -# TYPE some_total counter -some_total{label1="value1"} 1 +# HELP some_other_metric A value that represents a counter. +# TYPE some_other_metric counter +some_other_metric{label1="value1"} 1 ` err := CollectAndCompare(c, strings.NewReader(metadata+expected)) if err == nil { t.Error("Expected error, got no error.") } if err.Error() != expectedError { t.Errorf("Expected\n%#+v\nGot:\n%#+v", expectedError, err.Error()) } } func TestScrapeAndCompare(t *testing.T) { const expected = ` # HELP some_total A value that represents a counter. # TYPE some_total counter some_total{ label1 = "value1" } 1 ` expectedReader := strings.NewReader(expected) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, expected) })) defer ts.Close() if err := ScrapeAndCompare(ts.URL, expectedReader, "some_total"); err != nil { t.Errorf("unexpected scraping result:\n%s", err) } } func TestScrapeAndCompareWithMultipleExpected(t *testing.T) { const expected = ` # HELP some_total A value that represents a counter. # TYPE some_total counter some_total{ label1 = "value1" } 1 # HELP some_total2 A value that represents a counter. # TYPE some_total2 counter some_total2{ label2 = "value2" } 1 ` expectedReader := strings.NewReader(expected) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, expected) })) defer ts.Close() if err := ScrapeAndCompare(ts.URL, expectedReader, "some_total2"); err != nil { t.Errorf("unexpected scraping result:\n%s", err) } } func TestScrapeAndCompareFetchingFail(t *testing.T) { err := ScrapeAndCompare("some_url", strings.NewReader("some expectation"), "some_total") if err == nil { t.Errorf("expected an error but got nil") } if !strings.HasPrefix(err.Error(), "scraping metrics failed") { t.Errorf("unexpected error happened: %s", err) } } func TestScrapeAndCompareBadStatusCode(t *testing.T) { const expected = ` # HELP some_total A value that represents a counter. # TYPE some_total counter some_total{ label1 = "value1" } 1 ` expectedReader := strings.NewReader(expected) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusBadGateway) fmt.Fprintln(w, expected) })) defer ts.Close() err := ScrapeAndCompare(ts.URL, expectedReader, "some_total") if err == nil { t.Errorf("expected an error but got nil") } if !strings.HasPrefix(err.Error(), "the scraping target returned a status code other than 200") { t.Errorf("unexpected error happened: %s", err) } } func TestCollectAndCount(t *testing.T) { c := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "some_total", Help: "A value that represents a counter.", }, []string{"foo"}, ) if got, want := CollectAndCount(c), 0; got != want { t.Errorf("unexpected metric count, got %d, want %d", got, want) } c.WithLabelValues("bar") if got, want := CollectAndCount(c), 1; got != want { t.Errorf("unexpected metric count, got %d, want %d", got, want) } c.WithLabelValues("baz") if got, want := CollectAndCount(c), 2; got != want { t.Errorf("unexpected metric count, got %d, want %d", got, want) } if got, want := CollectAndCount(c, "some_total"), 2; got != want { t.Errorf("unexpected metric count, got %d, want %d", got, want) } if got, want := CollectAndCount(c, "some_other_total"), 0; got != want { t.Errorf("unexpected metric count, got %d, want %d", got, want) } } func TestCollectAndFormat(t *testing.T) { const expected = `# HELP foo_bar A value that represents the number of bars in foo. # TYPE foo_bar counter foo_bar{fizz="bang"} 1 ` c := prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "foo_bar", Help: "A value that represents the number of bars in foo.", }, []string{"fizz"}, ) c.WithLabelValues("bang").Inc() got, err := CollectAndFormat(c, expfmt.TypeTextPlain, "foo_bar") if err != nil { t.Errorf("unexpected error: %s", err.Error()) } gotS := string(got) if err != nil { t.Errorf("unexpected error: %s", err.Error()) } if gotS != expected { t.Errorf("unexpected metric output, got %q, expected %q", gotS, expected) } } client_golang-1.21.1/prometheus/timer.go000066400000000000000000000047321476160432400202600ustar00rootroot00000000000000// Copyright 2016 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import "time" // Timer is a helper type to time functions. Use NewTimer to create new // instances. type Timer struct { begin time.Time observer Observer } // NewTimer creates a new Timer. The provided Observer is used to observe a // duration in seconds. If the Observer implements ExemplarObserver, passing exemplar // later on will be also supported. // Timer is usually used to time a function call in the // following way: // // func TimeMe() { // timer := NewTimer(myHistogram) // defer timer.ObserveDuration() // // Do actual work. // } // // or // // func TimeMeWithExemplar() { // timer := NewTimer(myHistogram) // defer timer.ObserveDurationWithExemplar(exemplar) // // Do actual work. // } func NewTimer(o Observer) *Timer { return &Timer{ begin: time.Now(), observer: o, } } // ObserveDuration records the duration passed since the Timer was created with // NewTimer. It calls the Observe method of the Observer provided during // construction with the duration in seconds as an argument. The observed // duration is also returned. ObserveDuration is usually called with a defer // statement. // // Note that this method is only guaranteed to never observe negative durations // if used with Go1.9+. func (t *Timer) ObserveDuration() time.Duration { d := time.Since(t.begin) if t.observer != nil { t.observer.Observe(d.Seconds()) } return d } // ObserveDurationWithExemplar is like ObserveDuration, but it will also // observe exemplar with the duration unless exemplar is nil or provided Observer can't // be casted to ExemplarObserver. func (t *Timer) ObserveDurationWithExemplar(exemplar Labels) time.Duration { d := time.Since(t.begin) eo, ok := t.observer.(ExemplarObserver) if ok && exemplar != nil { eo.ObserveWithExemplar(d.Seconds(), exemplar) return d } if t.observer != nil { t.observer.Observe(d.Seconds()) } return d } client_golang-1.21.1/prometheus/timer_test.go000066400000000000000000000132311476160432400213110ustar00rootroot00000000000000// Copyright 2016 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "reflect" "testing" "google.golang.org/protobuf/proto" dto "github.com/prometheus/client_model/go" ) func TestTimerObserve(t *testing.T) { var ( his = NewHistogram(HistogramOpts{Name: "test_histogram"}) sum = NewSummary(SummaryOpts{Name: "test_summary"}) gauge = NewGauge(GaugeOpts{Name: "test_gauge"}) ) func() { hisTimer := NewTimer(his) sumTimer := NewTimer(sum) gaugeTimer := NewTimer(ObserverFunc(gauge.Set)) defer hisTimer.ObserveDuration() defer sumTimer.ObserveDuration() defer gaugeTimer.ObserveDuration() }() m := &dto.Metric{} his.Write(m) if want, got := uint64(1), m.GetHistogram().GetSampleCount(); want != got { t.Errorf("want %d observations for histogram, got %d", want, got) } m.Reset() sum.Write(m) if want, got := uint64(1), m.GetSummary().GetSampleCount(); want != got { t.Errorf("want %d observations for summary, got %d", want, got) } m.Reset() gauge.Write(m) if got := m.GetGauge().GetValue(); got <= 0 { t.Errorf("want value > 0 for gauge, got %f", got) } } func TestTimerObserveWithExemplar(t *testing.T) { var ( exemplar = Labels{"foo": "bar"} his = NewHistogram(HistogramOpts{Name: "test_histogram"}) sum = NewSummary(SummaryOpts{Name: "test_summary"}) gauge = NewGauge(GaugeOpts{Name: "test_gauge"}) ) func() { hisTimer := NewTimer(his) sumTimer := NewTimer(sum) gaugeTimer := NewTimer(ObserverFunc(gauge.Set)) defer hisTimer.ObserveDurationWithExemplar(exemplar) // Gauges and summaries does not implement ExemplarObserver, so we expect them to ignore exemplar. defer sumTimer.ObserveDurationWithExemplar(exemplar) defer gaugeTimer.ObserveDurationWithExemplar(exemplar) }() m := &dto.Metric{} his.Write(m) if want, got := uint64(1), m.GetHistogram().GetSampleCount(); want != got { t.Errorf("want %d observations for histogram, got %d", want, got) } var got []*dto.LabelPair for _, b := range m.GetHistogram().GetBucket() { if b.Exemplar != nil { got = b.Exemplar.GetLabel() break } } want := []*dto.LabelPair{{Name: proto.String("foo"), Value: proto.String("bar")}} if !reflect.DeepEqual(got, want) { t.Errorf("expected %v exemplar labels, got %v", want, got) } m.Reset() sum.Write(m) if want, got := uint64(1), m.GetSummary().GetSampleCount(); want != got { t.Errorf("want %d observations for summary, got %d", want, got) } m.Reset() gauge.Write(m) if got := m.GetGauge().GetValue(); got <= 0 { t.Errorf("want value > 0 for gauge, got %f", got) } } func TestTimerEmpty(t *testing.T) { emptyTimer := NewTimer(nil) emptyTimer.ObserveDuration() // Do nothing, just demonstrate it works without panic. } func TestTimerConditionalTiming(t *testing.T) { var ( his = NewHistogram(HistogramOpts{ Name: "test_histogram", }) timeMe = true m = &dto.Metric{} ) timedFunc := func() { timer := NewTimer(ObserverFunc(func(v float64) { if timeMe { his.Observe(v) } })) defer timer.ObserveDuration() } timedFunc() // This will time. his.Write(m) if want, got := uint64(1), m.GetHistogram().GetSampleCount(); want != got { t.Errorf("want %d observations for histogram, got %d", want, got) } timeMe = false timedFunc() // This will not time again. m.Reset() his.Write(m) if want, got := uint64(1), m.GetHistogram().GetSampleCount(); want != got { t.Errorf("want %d observations for histogram, got %d", want, got) } } func TestTimerByOutcome(t *testing.T) { var ( his = NewHistogramVec( HistogramOpts{Name: "test_histogram"}, []string{"outcome"}, ) outcome = "foo" m = &dto.Metric{} ) timedFunc := func() { timer := NewTimer(ObserverFunc(func(v float64) { his.WithLabelValues(outcome).Observe(v) })) defer timer.ObserveDuration() if outcome == "foo" { outcome = "bar" return } outcome = "foo" } timedFunc() his.WithLabelValues("foo").(Histogram).Write(m) if want, got := uint64(0), m.GetHistogram().GetSampleCount(); want != got { t.Errorf("want %d observations for 'foo' histogram, got %d", want, got) } m.Reset() his.WithLabelValues("bar").(Histogram).Write(m) if want, got := uint64(1), m.GetHistogram().GetSampleCount(); want != got { t.Errorf("want %d observations for 'bar' histogram, got %d", want, got) } timedFunc() m.Reset() his.WithLabelValues("foo").(Histogram).Write(m) if want, got := uint64(1), m.GetHistogram().GetSampleCount(); want != got { t.Errorf("want %d observations for 'foo' histogram, got %d", want, got) } m.Reset() his.WithLabelValues("bar").(Histogram).Write(m) if want, got := uint64(1), m.GetHistogram().GetSampleCount(); want != got { t.Errorf("want %d observations for 'bar' histogram, got %d", want, got) } timedFunc() m.Reset() his.WithLabelValues("foo").(Histogram).Write(m) if want, got := uint64(1), m.GetHistogram().GetSampleCount(); want != got { t.Errorf("want %d observations for 'foo' histogram, got %d", want, got) } m.Reset() his.WithLabelValues("bar").(Histogram).Write(m) if want, got := uint64(2), m.GetHistogram().GetSampleCount(); want != got { t.Errorf("want %d observations for 'bar' histogram, got %d", want, got) } } client_golang-1.21.1/prometheus/untyped.go000066400000000000000000000031341476160432400206230ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus // UntypedOpts is an alias for Opts. See there for doc comments. type UntypedOpts Opts // UntypedFunc works like GaugeFunc but the collected metric is of type // "Untyped". UntypedFunc is useful to mirror an external metric of unknown // type. // // To create UntypedFunc instances, use NewUntypedFunc. type UntypedFunc interface { Metric Collector } // NewUntypedFunc creates a new UntypedFunc based on the provided // UntypedOpts. The value reported is determined by calling the given function // from within the Write method. Take into account that metric collection may // happen concurrently. If that results in concurrent calls to Write, like in // the case where an UntypedFunc is directly registered with Prometheus, the // provided function must be concurrency-safe. func NewUntypedFunc(opts UntypedOpts, function func() float64) UntypedFunc { return newValueFunc(NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, nil, opts.ConstLabels, ), UntypedValue, function) } client_golang-1.21.1/prometheus/utils_test.go000066400000000000000000000042541476160432400213360ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus_test import ( "bytes" "encoding/json" "time" dto "github.com/prometheus/client_model/go" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" ) // sanitizeMetric injects expected fake created timestamp value "1970-01-01T00:00:10Z", // so we can compare it in examples. It modifies metric in-place, the returned pointer // is for convenience. func sanitizeMetric(metric *dto.Metric) *dto.Metric { if metric.Counter != nil && metric.Counter.CreatedTimestamp != nil { metric.Counter.CreatedTimestamp = timestamppb.New(time.Unix(10, 0)) } if metric.Summary != nil && metric.Summary.CreatedTimestamp != nil { metric.Summary.CreatedTimestamp = timestamppb.New(time.Unix(10, 0)) } if metric.Histogram != nil && metric.Histogram.CreatedTimestamp != nil { metric.Histogram.CreatedTimestamp = timestamppb.New(time.Unix(10, 0)) } return metric } // sanitizeMetricFamily is like sanitizeMetric, but for multiple metrics. func sanitizeMetricFamily(f *dto.MetricFamily) *dto.MetricFamily { for _, m := range f.Metric { sanitizeMetric(m) } return f } // toNormalizedJSON removes fake random space from proto JSON original marshaller. // It is required, so we can compare proto messages in json format. // Read more in https://github.com/golang/protobuf/issues/1121 func toNormalizedJSON(m proto.Message) string { mAsJSON, err := protojson.Marshal(m) if err != nil { panic(err) } buffer := new(bytes.Buffer) if err := json.Compact(buffer, mAsJSON); err != nil { panic(err) } return buffer.String() } client_golang-1.21.1/prometheus/value.go000066400000000000000000000210171476160432400202470ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "errors" "fmt" "sort" "time" "unicode/utf8" "github.com/prometheus/client_golang/prometheus/internal" dto "github.com/prometheus/client_model/go" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" ) // ValueType is an enumeration of metric types that represent a simple value. type ValueType int // Possible values for the ValueType enum. Use UntypedValue to mark a metric // with an unknown type. const ( _ ValueType = iota CounterValue GaugeValue UntypedValue ) var ( CounterMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_COUNTER; return &d }() GaugeMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_GAUGE; return &d }() UntypedMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_UNTYPED; return &d }() ) func (v ValueType) ToDTO() *dto.MetricType { switch v { case CounterValue: return CounterMetricTypePtr case GaugeValue: return GaugeMetricTypePtr default: return UntypedMetricTypePtr } } // valueFunc is a generic metric for simple values retrieved on collect time // from a function. It implements Metric and Collector. Its effective type is // determined by ValueType. This is a low-level building block used by the // library to back the implementations of CounterFunc, GaugeFunc, and // UntypedFunc. type valueFunc struct { selfCollector desc *Desc valType ValueType function func() float64 labelPairs []*dto.LabelPair } // newValueFunc returns a newly allocated valueFunc with the given Desc and // ValueType. The value reported is determined by calling the given function // from within the Write method. Take into account that metric collection may // happen concurrently. If that results in concurrent calls to Write, like in // the case where a valueFunc is directly registered with Prometheus, the // provided function must be concurrency-safe. func newValueFunc(desc *Desc, valueType ValueType, function func() float64) *valueFunc { result := &valueFunc{ desc: desc, valType: valueType, function: function, labelPairs: MakeLabelPairs(desc, nil), } result.init(result) return result } func (v *valueFunc) Desc() *Desc { return v.desc } func (v *valueFunc) Write(out *dto.Metric) error { return populateMetric(v.valType, v.function(), v.labelPairs, nil, out, nil) } // NewConstMetric returns a metric with one fixed value that cannot be // changed. Users of this package will not have much use for it in regular // operations. However, when implementing custom Collectors, it is useful as a // throw-away metric that is generated on the fly to send it to Prometheus in // the Collect method. NewConstMetric returns an error if the length of // labelValues is not consistent with the variable labels in Desc or if Desc is // invalid. func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) { if desc.err != nil { return nil, desc.err } if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { return nil, err } metric := &dto.Metric{} if err := populateMetric(valueType, value, MakeLabelPairs(desc, labelValues), nil, metric, nil); err != nil { return nil, err } return &constMetric{ desc: desc, metric: metric, }, nil } // MustNewConstMetric is a version of NewConstMetric that panics where // NewConstMetric would have returned an error. func MustNewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) Metric { m, err := NewConstMetric(desc, valueType, value, labelValues...) if err != nil { panic(err) } return m } // NewConstMetricWithCreatedTimestamp does the same thing as NewConstMetric, but generates Counters // with created timestamp set and returns an error for other metric types. func NewConstMetricWithCreatedTimestamp(desc *Desc, valueType ValueType, value float64, ct time.Time, labelValues ...string) (Metric, error) { if desc.err != nil { return nil, desc.err } if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { return nil, err } switch valueType { case CounterValue: break default: return nil, errors.New("created timestamps are only supported for counters") } metric := &dto.Metric{} if err := populateMetric(valueType, value, MakeLabelPairs(desc, labelValues), nil, metric, timestamppb.New(ct)); err != nil { return nil, err } return &constMetric{ desc: desc, metric: metric, }, nil } // MustNewConstMetricWithCreatedTimestamp is a version of NewConstMetricWithCreatedTimestamp that panics where // NewConstMetricWithCreatedTimestamp would have returned an error. func MustNewConstMetricWithCreatedTimestamp(desc *Desc, valueType ValueType, value float64, ct time.Time, labelValues ...string) Metric { m, err := NewConstMetricWithCreatedTimestamp(desc, valueType, value, ct, labelValues...) if err != nil { panic(err) } return m } type constMetric struct { desc *Desc metric *dto.Metric } func (m *constMetric) Desc() *Desc { return m.desc } func (m *constMetric) Write(out *dto.Metric) error { out.Label = m.metric.Label out.Counter = m.metric.Counter out.Gauge = m.metric.Gauge out.Untyped = m.metric.Untyped return nil } func populateMetric( t ValueType, v float64, labelPairs []*dto.LabelPair, e *dto.Exemplar, m *dto.Metric, ct *timestamppb.Timestamp, ) error { m.Label = labelPairs switch t { case CounterValue: m.Counter = &dto.Counter{Value: proto.Float64(v), Exemplar: e, CreatedTimestamp: ct} case GaugeValue: m.Gauge = &dto.Gauge{Value: proto.Float64(v)} case UntypedValue: m.Untyped = &dto.Untyped{Value: proto.Float64(v)} default: return fmt.Errorf("encountered unknown type %v", t) } return nil } // MakeLabelPairs is a helper function to create protobuf LabelPairs from the // variable and constant labels in the provided Desc. The values for the // variable labels are defined by the labelValues slice, which must be in the // same order as the corresponding variable labels in the Desc. // // This function is only needed for custom Metric implementations. See MetricVec // example. func MakeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair { totalLen := len(desc.variableLabels.names) + len(desc.constLabelPairs) if totalLen == 0 { // Super fast path. return nil } if len(desc.variableLabels.names) == 0 { // Moderately fast path. return desc.constLabelPairs } labelPairs := make([]*dto.LabelPair, 0, totalLen) for i, l := range desc.variableLabels.names { labelPairs = append(labelPairs, &dto.LabelPair{ Name: proto.String(l), Value: proto.String(labelValues[i]), }) } labelPairs = append(labelPairs, desc.constLabelPairs...) sort.Sort(internal.LabelPairSorter(labelPairs)) return labelPairs } // ExemplarMaxRunes is the max total number of runes allowed in exemplar labels. const ExemplarMaxRunes = 128 // newExemplar creates a new dto.Exemplar from the provided values. An error is // returned if any of the label names or values are invalid or if the total // number of runes in the label names and values exceeds ExemplarMaxRunes. func newExemplar(value float64, ts time.Time, l Labels) (*dto.Exemplar, error) { e := &dto.Exemplar{} e.Value = proto.Float64(value) tsProto := timestamppb.New(ts) if err := tsProto.CheckValid(); err != nil { return nil, err } e.Timestamp = tsProto labelPairs := make([]*dto.LabelPair, 0, len(l)) var runes int for name, value := range l { if !checkLabelName(name) { return nil, fmt.Errorf("exemplar label name %q is invalid", name) } runes += utf8.RuneCountInString(name) if !utf8.ValidString(value) { return nil, fmt.Errorf("exemplar label value %q is not valid UTF-8", value) } runes += utf8.RuneCountInString(value) labelPairs = append(labelPairs, &dto.LabelPair{ Name: proto.String(name), Value: proto.String(value), }) } if runes > ExemplarMaxRunes { return nil, fmt.Errorf("exemplar labels have %d runes, exceeding the limit of %d", runes, ExemplarMaxRunes) } e.Label = labelPairs return e, nil } client_golang-1.21.1/prometheus/value_test.go000066400000000000000000000055311476160432400213110ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "testing" "time" dto "github.com/prometheus/client_model/go" "google.golang.org/protobuf/types/known/timestamppb" ) func TestNewConstMetricInvalidLabelValues(t *testing.T) { testCases := []struct { desc string labels Labels }{ { desc: "non utf8 label value", labels: Labels{"a": "\xFF"}, }, { desc: "not enough label values", labels: Labels{}, }, { desc: "too many label values", labels: Labels{"a": "1", "b": "2"}, }, } for _, test := range testCases { metricDesc := NewDesc( "sample_value", "sample value", []string{"a"}, Labels{}, ) expectPanic(t, func() { MustNewConstMetric(metricDesc, CounterValue, 0.3, "\xFF") }, "WithLabelValues: expected panic because: "+test.desc) if _, err := NewConstMetric(metricDesc, CounterValue, 0.3, "\xFF"); err == nil { t.Errorf("NewConstMetric: expected error because: %s", test.desc) } } } func TestNewConstMetricWithCreatedTimestamp(t *testing.T) { now := time.Now() for _, tcase := range []struct { desc string metricType ValueType createdTimestamp time.Time expecErr bool expectedCt *timestamppb.Timestamp }{ { desc: "gauge with CT", metricType: GaugeValue, createdTimestamp: now, expecErr: true, expectedCt: nil, }, { desc: "counter with CT", metricType: CounterValue, createdTimestamp: now, expecErr: false, expectedCt: timestamppb.New(now), }, } { t.Run(tcase.desc, func(t *testing.T) { metricDesc := NewDesc( "sample_value", "sample value", nil, nil, ) m, err := NewConstMetricWithCreatedTimestamp(metricDesc, tcase.metricType, float64(1), tcase.createdTimestamp) if tcase.expecErr && err == nil { t.Errorf("Expected error is test %s, got no err", tcase.desc) } if !tcase.expecErr && err != nil { t.Errorf("Didn't expect error in test %s, got %s", tcase.desc, err.Error()) } if tcase.expectedCt != nil { var metric dto.Metric m.Write(&metric) if metric.Counter.CreatedTimestamp.AsTime() != tcase.expectedCt.AsTime() { t.Errorf("Expected timestamp %v, got %v", tcase.expectedCt, &metric.Counter.CreatedTimestamp) } } }) } } client_golang-1.21.1/prometheus/vec.go000066400000000000000000000532121476160432400177120ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "fmt" "sync" "github.com/prometheus/common/model" ) // MetricVec is a Collector to bundle metrics of the same name that differ in // their label values. MetricVec is not used directly but as a building block // for implementations of vectors of a given metric type, like GaugeVec, // CounterVec, SummaryVec, and HistogramVec. It is exported so that it can be // used for custom Metric implementations. // // To create a FooVec for custom Metric Foo, embed a pointer to MetricVec in // FooVec and initialize it with NewMetricVec. Implement wrappers for // GetMetricWithLabelValues and GetMetricWith that return (Foo, error) rather // than (Metric, error). Similarly, create a wrapper for CurryWith that returns // (*FooVec, error) rather than (*MetricVec, error). It is recommended to also // add the convenience methods WithLabelValues, With, and MustCurryWith, which // panic instead of returning errors. See also the MetricVec example. type MetricVec struct { *metricMap curry []curriedLabelValue // hashAdd and hashAddByte can be replaced for testing collision handling. hashAdd func(h uint64, s string) uint64 hashAddByte func(h uint64, b byte) uint64 } // NewMetricVec returns an initialized metricVec. func NewMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *MetricVec { return &MetricVec{ metricMap: &metricMap{ metrics: map[uint64][]metricWithLabelValues{}, desc: desc, newMetric: newMetric, }, hashAdd: hashAdd, hashAddByte: hashAddByte, } } // DeleteLabelValues removes the metric where the variable labels are the same // as those passed in as labels (same order as the VariableLabels in Desc). It // returns true if a metric was deleted. // // It is not an error if the number of label values is not the same as the // number of VariableLabels in Desc. However, such inconsistent label count can // never match an actual metric, so the method will always return false in that // case. // // Note that for more than one label value, this method is prone to mistakes // caused by an incorrect order of arguments. Consider Delete(Labels) as an // alternative to avoid that type of mistake. For higher label numbers, the // latter has a much more readable (albeit more verbose) syntax, but it comes // with a performance overhead (for creating and processing the Labels map). // See also the CounterVec example. func (m *MetricVec) DeleteLabelValues(lvs ...string) bool { lvs = constrainLabelValues(m.desc, lvs, m.curry) h, err := m.hashLabelValues(lvs) if err != nil { return false } return m.metricMap.deleteByHashWithLabelValues(h, lvs, m.curry) } // Delete deletes the metric where the variable labels are the same as those // passed in as labels. It returns true if a metric was deleted. // // It is not an error if the number and names of the Labels are inconsistent // with those of the VariableLabels in Desc. However, such inconsistent Labels // can never match an actual metric, so the method will always return false in // that case. // // This method is used for the same purpose as DeleteLabelValues(...string). See // there for pros and cons of the two methods. func (m *MetricVec) Delete(labels Labels) bool { labels, closer := constrainLabels(m.desc, labels) defer closer() h, err := m.hashLabels(labels) if err != nil { return false } return m.metricMap.deleteByHashWithLabels(h, labels, m.curry) } // DeletePartialMatch deletes all metrics where the variable labels contain all of those // passed in as labels. The order of the labels does not matter. // It returns the number of metrics deleted. // // Note that curried labels will never be matched if deleting from the curried vector. // To match curried labels with DeletePartialMatch, it must be called on the base vector. func (m *MetricVec) DeletePartialMatch(labels Labels) int { labels, closer := constrainLabels(m.desc, labels) defer closer() return m.metricMap.deleteByLabels(labels, m.curry) } // Without explicit forwarding of Describe, Collect, Reset, those methods won't // show up in GoDoc. // Describe implements Collector. func (m *MetricVec) Describe(ch chan<- *Desc) { m.metricMap.Describe(ch) } // Collect implements Collector. func (m *MetricVec) Collect(ch chan<- Metric) { m.metricMap.Collect(ch) } // Reset deletes all metrics in this vector. func (m *MetricVec) Reset() { m.metricMap.Reset() } // CurryWith returns a vector curried with the provided labels, i.e. the // returned vector has those labels pre-set for all labeled operations performed // on it. The cardinality of the curried vector is reduced accordingly. The // order of the remaining labels stays the same (just with the curried labels // taken out of the sequence – which is relevant for the // (GetMetric)WithLabelValues methods). It is possible to curry a curried // vector, but only with labels not yet used for currying before. // // The metrics contained in the MetricVec are shared between the curried and // uncurried vectors. They are just accessed differently. Curried and uncurried // vectors behave identically in terms of collection. Only one must be // registered with a given registry (usually the uncurried version). The Reset // method deletes all metrics, even if called on a curried vector. // // Note that CurryWith is usually not called directly but through a wrapper // around MetricVec, implementing a vector for a specific Metric // implementation, for example GaugeVec. func (m *MetricVec) CurryWith(labels Labels) (*MetricVec, error) { var ( newCurry []curriedLabelValue oldCurry = m.curry iCurry int ) for i, labelName := range m.desc.variableLabels.names { val, ok := labels[labelName] if iCurry < len(oldCurry) && oldCurry[iCurry].index == i { if ok { return nil, fmt.Errorf("label name %q is already curried", labelName) } newCurry = append(newCurry, oldCurry[iCurry]) iCurry++ } else { if !ok { continue // Label stays uncurried. } newCurry = append(newCurry, curriedLabelValue{ i, m.desc.variableLabels.constrain(labelName, val), }) } } if l := len(oldCurry) + len(labels) - len(newCurry); l > 0 { return nil, fmt.Errorf("%d unknown label(s) found during currying", l) } return &MetricVec{ metricMap: m.metricMap, curry: newCurry, hashAdd: m.hashAdd, hashAddByte: m.hashAddByte, }, nil } // GetMetricWithLabelValues returns the Metric for the given slice of label // values (same order as the variable labels in Desc). If that combination of // label values is accessed for the first time, a new Metric is created (by // calling the newMetric function provided during construction of the // MetricVec). // // It is possible to call this method without using the returned Metric to only // create the new Metric but leave it in its initial state. // // Keeping the Metric for later use is possible (and should be considered if // performance is critical), but keep in mind that Reset, DeleteLabelValues and // Delete can be used to delete the Metric from the MetricVec. In that case, the // Metric will still exist, but it will not be exported anymore, even if a // Metric with the same label values is created later. // // An error is returned if the number of label values is not the same as the // number of variable labels in Desc (minus any curried labels). // // Note that for more than one label value, this method is prone to mistakes // caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as // an alternative to avoid that type of mistake. For higher label numbers, the // latter has a much more readable (albeit more verbose) syntax, but it comes // with a performance overhead (for creating and processing the Labels map). // // Note that GetMetricWithLabelValues is usually not called directly but through // a wrapper around MetricVec, implementing a vector for a specific Metric // implementation, for example GaugeVec. func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) { lvs = constrainLabelValues(m.desc, lvs, m.curry) h, err := m.hashLabelValues(lvs) if err != nil { return nil, err } return m.metricMap.getOrCreateMetricWithLabelValues(h, lvs, m.curry), nil } // GetMetricWith returns the Metric for the given Labels map (the label names // must match those of the variable labels in Desc). If that label map is // accessed for the first time, a new Metric is created. Implications of // creating a Metric without using it and keeping the Metric for later use // are the same as for GetMetricWithLabelValues. // // An error is returned if the number and names of the Labels are inconsistent // with those of the variable labels in Desc (minus any curried labels). // // This method is used for the same purpose as // GetMetricWithLabelValues(...string). See there for pros and cons of the two // methods. // // Note that GetMetricWith is usually not called directly but through a wrapper // around MetricVec, implementing a vector for a specific Metric implementation, // for example GaugeVec. func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) { labels, closer := constrainLabels(m.desc, labels) defer closer() h, err := m.hashLabels(labels) if err != nil { return nil, err } return m.metricMap.getOrCreateMetricWithLabels(h, labels, m.curry), nil } func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) { if err := validateLabelValues(vals, len(m.desc.variableLabels.names)-len(m.curry)); err != nil { return 0, err } var ( h = hashNew() curry = m.curry iVals, iCurry int ) for i := 0; i < len(m.desc.variableLabels.names); i++ { if iCurry < len(curry) && curry[iCurry].index == i { h = m.hashAdd(h, curry[iCurry].value) iCurry++ } else { h = m.hashAdd(h, vals[iVals]) iVals++ } h = m.hashAddByte(h, model.SeparatorByte) } return h, nil } func (m *MetricVec) hashLabels(labels Labels) (uint64, error) { if err := validateValuesInLabels(labels, len(m.desc.variableLabels.names)-len(m.curry)); err != nil { return 0, err } var ( h = hashNew() curry = m.curry iCurry int ) for i, labelName := range m.desc.variableLabels.names { val, ok := labels[labelName] if iCurry < len(curry) && curry[iCurry].index == i { if ok { return 0, fmt.Errorf("label name %q is already curried", labelName) } h = m.hashAdd(h, curry[iCurry].value) iCurry++ } else { if !ok { return 0, fmt.Errorf("label name %q missing in label map", labelName) } h = m.hashAdd(h, val) } h = m.hashAddByte(h, model.SeparatorByte) } return h, nil } // metricWithLabelValues provides the metric and its label values for // disambiguation on hash collision. type metricWithLabelValues struct { values []string metric Metric } // curriedLabelValue sets the curried value for a label at the given index. type curriedLabelValue struct { index int value string } // metricMap is a helper for metricVec and shared between differently curried // metricVecs. type metricMap struct { mtx sync.RWMutex // Protects metrics. metrics map[uint64][]metricWithLabelValues desc *Desc newMetric func(labelValues ...string) Metric } // Describe implements Collector. It will send exactly one Desc to the provided // channel. func (m *metricMap) Describe(ch chan<- *Desc) { ch <- m.desc } // Collect implements Collector. func (m *metricMap) Collect(ch chan<- Metric) { m.mtx.RLock() defer m.mtx.RUnlock() for _, metrics := range m.metrics { for _, metric := range metrics { ch <- metric.metric } } } // Reset deletes all metrics in this vector. func (m *metricMap) Reset() { m.mtx.Lock() defer m.mtx.Unlock() for h := range m.metrics { delete(m.metrics, h) } } // deleteByHashWithLabelValues removes the metric from the hash bucket h. If // there are multiple matches in the bucket, use lvs to select a metric and // remove only that metric. func (m *metricMap) deleteByHashWithLabelValues( h uint64, lvs []string, curry []curriedLabelValue, ) bool { m.mtx.Lock() defer m.mtx.Unlock() metrics, ok := m.metrics[h] if !ok { return false } i := findMetricWithLabelValues(metrics, lvs, curry) if i >= len(metrics) { return false } if len(metrics) > 1 { old := metrics m.metrics[h] = append(metrics[:i], metrics[i+1:]...) old[len(old)-1] = metricWithLabelValues{} } else { delete(m.metrics, h) } return true } // deleteByHashWithLabels removes the metric from the hash bucket h. If there // are multiple matches in the bucket, use lvs to select a metric and remove // only that metric. func (m *metricMap) deleteByHashWithLabels( h uint64, labels Labels, curry []curriedLabelValue, ) bool { m.mtx.Lock() defer m.mtx.Unlock() metrics, ok := m.metrics[h] if !ok { return false } i := findMetricWithLabels(m.desc, metrics, labels, curry) if i >= len(metrics) { return false } if len(metrics) > 1 { old := metrics m.metrics[h] = append(metrics[:i], metrics[i+1:]...) old[len(old)-1] = metricWithLabelValues{} } else { delete(m.metrics, h) } return true } // deleteByLabels deletes a metric if the given labels are present in the metric. func (m *metricMap) deleteByLabels(labels Labels, curry []curriedLabelValue) int { m.mtx.Lock() defer m.mtx.Unlock() var numDeleted int for h, metrics := range m.metrics { i := findMetricWithPartialLabels(m.desc, metrics, labels, curry) if i >= len(metrics) { // Didn't find matching labels in this metric slice. continue } delete(m.metrics, h) numDeleted++ } return numDeleted } // findMetricWithPartialLabel returns the index of the matching metric or // len(metrics) if not found. func findMetricWithPartialLabels( desc *Desc, metrics []metricWithLabelValues, labels Labels, curry []curriedLabelValue, ) int { for i, metric := range metrics { if matchPartialLabels(desc, metric.values, labels, curry) { return i } } return len(metrics) } // indexOf searches the given slice of strings for the target string and returns // the index or len(items) as well as a boolean whether the search succeeded. func indexOf(target string, items []string) (int, bool) { for i, l := range items { if l == target { return i, true } } return len(items), false } // valueMatchesVariableOrCurriedValue determines if a value was previously curried, // and returns whether it matches either the "base" value or the curried value accordingly. // It also indicates whether the match is against a curried or uncurried value. func valueMatchesVariableOrCurriedValue(targetValue string, index int, values []string, curry []curriedLabelValue) (bool, bool) { for _, curriedValue := range curry { if curriedValue.index == index { // This label was curried. See if the curried value matches our target. return curriedValue.value == targetValue, true } } // This label was not curried. See if the current value matches our target label. return values[index] == targetValue, false } // matchPartialLabels searches the current metric and returns whether all of the target label:value pairs are present. func matchPartialLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool { for l, v := range labels { // Check if the target label exists in our metrics and get the index. varLabelIndex, validLabel := indexOf(l, desc.variableLabels.names) if validLabel { // Check the value of that label against the target value. // We don't consider curried values in partial matches. matches, curried := valueMatchesVariableOrCurriedValue(v, varLabelIndex, values, curry) if matches && !curried { continue } } return false } return true } // getOrCreateMetricWithLabelValues retrieves the metric by hash and label value // or creates it and returns the new one. // // This function holds the mutex. func (m *metricMap) getOrCreateMetricWithLabelValues( hash uint64, lvs []string, curry []curriedLabelValue, ) Metric { m.mtx.RLock() metric, ok := m.getMetricWithHashAndLabelValues(hash, lvs, curry) m.mtx.RUnlock() if ok { return metric } m.mtx.Lock() defer m.mtx.Unlock() metric, ok = m.getMetricWithHashAndLabelValues(hash, lvs, curry) if !ok { inlinedLVs := inlineLabelValues(lvs, curry) metric = m.newMetric(inlinedLVs...) m.metrics[hash] = append(m.metrics[hash], metricWithLabelValues{values: inlinedLVs, metric: metric}) } return metric } // getOrCreateMetricWithLabels retrieves the metric by hash and label value // or creates it and returns the new one. // // This function holds the mutex. func (m *metricMap) getOrCreateMetricWithLabels( hash uint64, labels Labels, curry []curriedLabelValue, ) Metric { m.mtx.RLock() metric, ok := m.getMetricWithHashAndLabels(hash, labels, curry) m.mtx.RUnlock() if ok { return metric } m.mtx.Lock() defer m.mtx.Unlock() metric, ok = m.getMetricWithHashAndLabels(hash, labels, curry) if !ok { lvs := extractLabelValues(m.desc, labels, curry) metric = m.newMetric(lvs...) m.metrics[hash] = append(m.metrics[hash], metricWithLabelValues{values: lvs, metric: metric}) } return metric } // getMetricWithHashAndLabelValues gets a metric while handling possible // collisions in the hash space. Must be called while holding the read mutex. func (m *metricMap) getMetricWithHashAndLabelValues( h uint64, lvs []string, curry []curriedLabelValue, ) (Metric, bool) { metrics, ok := m.metrics[h] if ok { if i := findMetricWithLabelValues(metrics, lvs, curry); i < len(metrics) { return metrics[i].metric, true } } return nil, false } // getMetricWithHashAndLabels gets a metric while handling possible collisions in // the hash space. Must be called while holding read mutex. func (m *metricMap) getMetricWithHashAndLabels( h uint64, labels Labels, curry []curriedLabelValue, ) (Metric, bool) { metrics, ok := m.metrics[h] if ok { if i := findMetricWithLabels(m.desc, metrics, labels, curry); i < len(metrics) { return metrics[i].metric, true } } return nil, false } // findMetricWithLabelValues returns the index of the matching metric or // len(metrics) if not found. func findMetricWithLabelValues( metrics []metricWithLabelValues, lvs []string, curry []curriedLabelValue, ) int { for i, metric := range metrics { if matchLabelValues(metric.values, lvs, curry) { return i } } return len(metrics) } // findMetricWithLabels returns the index of the matching metric or len(metrics) // if not found. func findMetricWithLabels( desc *Desc, metrics []metricWithLabelValues, labels Labels, curry []curriedLabelValue, ) int { for i, metric := range metrics { if matchLabels(desc, metric.values, labels, curry) { return i } } return len(metrics) } func matchLabelValues(values, lvs []string, curry []curriedLabelValue) bool { if len(values) != len(lvs)+len(curry) { return false } var iLVs, iCurry int for i, v := range values { if iCurry < len(curry) && curry[iCurry].index == i { if v != curry[iCurry].value { return false } iCurry++ continue } if v != lvs[iLVs] { return false } iLVs++ } return true } func matchLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool { if len(values) != len(labels)+len(curry) { return false } iCurry := 0 for i, k := range desc.variableLabels.names { if iCurry < len(curry) && curry[iCurry].index == i { if values[i] != curry[iCurry].value { return false } iCurry++ continue } if values[i] != labels[k] { return false } } return true } func extractLabelValues(desc *Desc, labels Labels, curry []curriedLabelValue) []string { labelValues := make([]string, len(labels)+len(curry)) iCurry := 0 for i, k := range desc.variableLabels.names { if iCurry < len(curry) && curry[iCurry].index == i { labelValues[i] = curry[iCurry].value iCurry++ continue } labelValues[i] = labels[k] } return labelValues } func inlineLabelValues(lvs []string, curry []curriedLabelValue) []string { labelValues := make([]string, len(lvs)+len(curry)) var iCurry, iLVs int for i := range labelValues { if iCurry < len(curry) && curry[iCurry].index == i { labelValues[i] = curry[iCurry].value iCurry++ continue } labelValues[i] = lvs[iLVs] iLVs++ } return labelValues } var labelsPool = &sync.Pool{ New: func() interface{} { return make(Labels) }, } func constrainLabels(desc *Desc, labels Labels) (Labels, func()) { if len(desc.variableLabels.labelConstraints) == 0 { // Fast path when there's no constraints return labels, func() {} } constrainedLabels := labelsPool.Get().(Labels) for l, v := range labels { constrainedLabels[l] = desc.variableLabels.constrain(l, v) } return constrainedLabels, func() { for k := range constrainedLabels { delete(constrainedLabels, k) } labelsPool.Put(constrainedLabels) } } func constrainLabelValues(desc *Desc, lvs []string, curry []curriedLabelValue) []string { if len(desc.variableLabels.labelConstraints) == 0 { // Fast path when there's no constraints return lvs } constrainedValues := make([]string, len(lvs)) var iCurry, iLVs int for i := 0; i < len(lvs)+len(curry); i++ { if iCurry < len(curry) && curry[iCurry].index == i { iCurry++ continue } if i < len(desc.variableLabels.names) { constrainedValues[iLVs] = desc.variableLabels.constrain( desc.variableLabels.names[i], lvs[iLVs], ) } else { constrainedValues[iLVs] = lvs[iLVs] } iLVs++ } return constrainedValues } client_golang-1.21.1/prometheus/vec_test.go000066400000000000000000000713711476160432400207570ustar00rootroot00000000000000// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "fmt" "reflect" "strconv" "testing" dto "github.com/prometheus/client_model/go" ) func TestDelete(t *testing.T) { vec := NewGaugeVec( GaugeOpts{ Name: "test", Help: "helpless", }, []string{"l1", "l2"}, ) testDelete(t, vec) } func TestDeleteWithCollisions(t *testing.T) { vec := NewGaugeVec( GaugeOpts{ Name: "test", Help: "helpless", }, []string{"l1", "l2"}, ) vec.hashAdd = func(h uint64, s string) uint64 { return 1 } vec.hashAddByte = func(h uint64, b byte) uint64 { return 1 } testDelete(t, vec) } func TestDeleteWithConstraints(t *testing.T) { vec := V2.NewGaugeVec(GaugeVecOpts{ GaugeOpts{ Name: "test", Help: "helpless", }, ConstrainedLabels{ {Name: "l1"}, {Name: "l2", Constraint: func(s string) string { return "x" + s }}, }, }) testDelete(t, vec) } func testDelete(t *testing.T, vec *GaugeVec) { if got, want := vec.Delete(Labels{"l1": "v1", "l2": "v2"}), false; got != want { t.Errorf("got %v, want %v", got, want) } vec.With(Labels{"l1": "v1", "l2": "v2"}).Set(42) if got, want := vec.Delete(Labels{"l1": "v1", "l2": "v2"}), true; got != want { t.Errorf("got %v, want %v", got, want) } if got, want := vec.Delete(Labels{"l1": "v1", "l2": "v2"}), false; got != want { t.Errorf("got %v, want %v", got, want) } vec.With(Labels{"l1": "v1", "l2": "v2"}).Set(42) if got, want := vec.Delete(Labels{"l2": "v2", "l1": "v1"}), true; got != want { t.Errorf("got %v, want %v", got, want) } if got, want := vec.Delete(Labels{"l2": "v2", "l1": "v1"}), false; got != want { t.Errorf("got %v, want %v", got, want) } vec.With(Labels{"l1": "v1", "l2": "v2"}).Set(42) if got, want := vec.Delete(Labels{"l2": "v1", "l1": "v2"}), false; got != want { t.Errorf("got %v, want %v", got, want) } if got, want := vec.Delete(Labels{"l1": "v1"}), false; got != want { t.Errorf("got %v, want %v", got, want) } } func TestDeleteLabelValues(t *testing.T) { vec := NewGaugeVec( GaugeOpts{ Name: "test", Help: "helpless", }, []string{"l1", "l2"}, ) testDeleteLabelValues(t, vec) } func TestDeleteLabelValuesWithCollisions(t *testing.T) { vec := NewGaugeVec( GaugeOpts{ Name: "test", Help: "helpless", }, []string{"l1", "l2"}, ) vec.hashAdd = func(h uint64, s string) uint64 { return 1 } vec.hashAddByte = func(h uint64, b byte) uint64 { return 1 } testDeleteLabelValues(t, vec) } func TestDeleteLabelValuesWithConstraints(t *testing.T) { vec := V2.NewGaugeVec(GaugeVecOpts{ GaugeOpts{ Name: "test", Help: "helpless", }, ConstrainedLabels{ {Name: "l1"}, {Name: "l2", Constraint: func(s string) string { return "x" + s }}, }, }) testDeleteLabelValues(t, vec) } func testDeleteLabelValues(t *testing.T, vec *GaugeVec) { if got, want := vec.DeleteLabelValues("v1", "v2"), false; got != want { t.Errorf("got %v, want %v", got, want) } vec.With(Labels{"l1": "v1", "l2": "v2"}).Set(42) vec.With(Labels{"l1": "v1", "l2": "v3"}).Set(42) // Add junk data for collision. if got, want := vec.DeleteLabelValues("v1", "v2"), true; got != want { t.Errorf("got %v, want %v", got, want) } if got, want := vec.DeleteLabelValues("v1", "v2"), false; got != want { t.Errorf("got %v, want %v", got, want) } if got, want := vec.DeleteLabelValues("v1", "v3"), true; got != want { t.Errorf("got %v, want %v", got, want) } vec.With(Labels{"l1": "v1", "l2": "v2"}).Set(42) // Delete out of order. if got, want := vec.DeleteLabelValues("v2", "v1"), false; got != want { t.Errorf("got %v, want %v", got, want) } if got, want := vec.DeleteLabelValues("v1"), false; got != want { t.Errorf("got %v, want %v", got, want) } } func TestDeletePartialMatch(t *testing.T) { vec := NewGaugeVec( GaugeOpts{ Name: "test", Help: "helpless", }, []string{"l1", "l2", "l3"}, ) testDeletePartialMatch(t, vec) } func TestDeletePartialMatchWithConstraints(t *testing.T) { vec := V2.NewGaugeVec(GaugeVecOpts{ GaugeOpts{ Name: "test", Help: "helpless", }, ConstrainedLabels{ {Name: "l1"}, {Name: "l2", Constraint: func(s string) string { return "x" + s }}, {Name: "l3"}, }, }) testDeletePartialMatch(t, vec) } func testDeletePartialMatch(t *testing.T, baseVec *GaugeVec) { assertNoMetric := func(t *testing.T) { if n := len(baseVec.metricMap.metrics); n != 0 { t.Error("expected no metrics, got", n) } } // No metric value is set. if got, want := baseVec.DeletePartialMatch(Labels{"l1": "v1", "l2": "v2"}), 0; got != want { t.Errorf("got %v, want %v", got, want) } baseVec.With(Labels{"l1": "baseValue1", "l2": "baseValue2", "l3": "baseValue3"}).Inc() baseVec.With(Labels{"l1": "multiDeleteV1", "l2": "diff1BaseValue2", "l3": "v3"}).Set(42) baseVec.With(Labels{"l1": "multiDeleteV1", "l2": "diff2BaseValue2", "l3": "v3"}).Set(84) baseVec.With(Labels{"l1": "multiDeleteV1", "l2": "diff3BaseValue2", "l3": "v3"}).Set(168) curriedVec := baseVec.MustCurryWith(Labels{"l2": "curriedValue2"}) curriedVec.WithLabelValues("curriedValue1", "curriedValue3").Inc() curriedVec.WithLabelValues("curriedValue1", "differentCurriedValue3").Inc() curriedVec.WithLabelValues("differentCurriedValue1", "differentCurriedValue3").Inc() // Try to delete nonexistent label with existent value from curried vector. if got, want := curriedVec.DeletePartialMatch(Labels{"lx": "curriedValue1"}), 0; got != want { t.Errorf("got %v, want %v", got, want) } // Try to delete valid label with nonexistent value from curried vector. if got, want := curriedVec.DeletePartialMatch(Labels{"l1": "badValue1"}), 0; got != want { t.Errorf("got %v, want %v", got, want) } // Try to delete from a curried vector based on labels which were curried. // This operation succeeds when run against the base vector below. if got, want := curriedVec.DeletePartialMatch(Labels{"l2": "curriedValue2"}), 0; got != want { t.Errorf("got %v, want %v", got, want) } // Try to delete from a curried vector based on labels which were curried, // but the value actually exists in the base vector. if got, want := curriedVec.DeletePartialMatch(Labels{"l2": "baseValue2"}), 0; got != want { t.Errorf("got %v, want %v", got, want) } // Delete multiple matching metrics from a curried vector based on partial values. if got, want := curriedVec.DeletePartialMatch(Labels{"l1": "curriedValue1"}), 2; got != want { t.Errorf("got %v, want %v", got, want) } // Try to delete nonexistent label with existent value from base vector. if got, want := baseVec.DeletePartialMatch(Labels{"lx": "curriedValue1"}), 0; got != want { t.Errorf("got %v, want %v", got, want) } // Try to delete partially invalid labels from base vector. if got, want := baseVec.DeletePartialMatch(Labels{"l1": "baseValue1", "l2": "badValue2"}), 0; got != want { t.Errorf("got %v, want %v", got, want) } // Delete from the base vector based on values which were curried. // This operation fails when run against a curried vector above. if got, want := baseVec.DeletePartialMatch(Labels{"l2": "curriedValue2"}), 1; got != want { t.Errorf("got %v, want %v", got, want) } // Delete multiple metrics from the base vector based on a single valid label. if got, want := baseVec.DeletePartialMatch(Labels{"l1": "multiDeleteV1"}), 3; got != want { t.Errorf("got %v, want %v", got, want) } // Delete from the base vector based on values which were not curried. if got, want := baseVec.DeletePartialMatch(Labels{"l3": "baseValue3"}), 1; got != want { t.Errorf("got %v, want %v", got, want) } // All metrics should have been deleted now. assertNoMetric(t) } func TestMetricVec(t *testing.T) { vec := NewGaugeVec( GaugeOpts{ Name: "test", Help: "helpless", }, []string{"l1", "l2"}, ) testMetricVec(t, vec) } func TestMetricVecWithCollisions(t *testing.T) { vec := NewGaugeVec( GaugeOpts{ Name: "test", Help: "helpless", }, []string{"l1", "l2"}, ) vec.hashAdd = func(h uint64, s string) uint64 { return 1 } vec.hashAddByte = func(h uint64, b byte) uint64 { return 1 } testMetricVec(t, vec) } func testMetricVec(t *testing.T, vec *GaugeVec) { vec.Reset() // Actually test Reset now! var pair [2]string // Keep track of metrics. expected := map[[2]string]int{} for i := 0; i < 1000; i++ { pair[0], pair[1] = strconv.Itoa(i%4), strconv.Itoa(i%5) // Varying combinations multiples. expected[pair]++ vec.WithLabelValues(pair[0], pair[1]).Inc() expected[[2]string{"v1", "v2"}]++ vec.WithLabelValues("v1", "v2").Inc() } var total int for _, metrics := range vec.metricMap.metrics { for _, metric := range metrics { total++ copy(pair[:], metric.values) var metricOut dto.Metric if err := metric.metric.Write(&metricOut); err != nil { t.Fatal(err) } actual := *metricOut.Gauge.Value var actualPair [2]string for i, label := range metricOut.Label { actualPair[i] = *label.Value } // Test output pair against metric.values to ensure we've selected // the right one. We check this to ensure the below check means // anything at all. if actualPair != pair { t.Fatalf("unexpected pair association in metric map: %v != %v", actualPair, pair) } if actual != float64(expected[pair]) { t.Fatalf("incorrect counter value for %v: %v != %v", pair, actual, expected[pair]) } } } if total != len(expected) { t.Fatalf("unexpected number of metrics: %v != %v", total, len(expected)) } vec.Reset() if len(vec.metricMap.metrics) > 0 { t.Fatalf("reset failed") } } func TestMetricVecWithConstraints(t *testing.T) { constraint := func(s string) string { return "x" + s } vec := V2.NewGaugeVec(GaugeVecOpts{ GaugeOpts{ Name: "test", Help: "helpless", }, ConstrainedLabels{ {Name: "l1"}, {Name: "l2", Constraint: constraint}, }, }) testConstrainedMetricVec(t, vec, constraint) } func testConstrainedMetricVec(t *testing.T, vec *GaugeVec, constrain func(string) string) { vec.Reset() // Actually test Reset now! var pair [2]string // Keep track of metrics. expected := map[[2]string]int{} for i := 0; i < 1000; i++ { pair[0], pair[1] = strconv.Itoa(i%4), strconv.Itoa(i%5) // Varying combinations multiples. expected[[2]string{pair[0], constrain(pair[1])}]++ vec.WithLabelValues(pair[0], pair[1]).Inc() expected[[2]string{"v1", constrain("v2")}]++ vec.WithLabelValues("v1", "v2").Inc() } var total int for _, metrics := range vec.metricMap.metrics { for _, metric := range metrics { total++ copy(pair[:], metric.values) var metricOut dto.Metric if err := metric.metric.Write(&metricOut); err != nil { t.Fatal(err) } actual := *metricOut.Gauge.Value var actualPair [2]string for i, label := range metricOut.Label { actualPair[i] = *label.Value } // Test output pair against metric.values to ensure we've selected // the right one. We check this to ensure the below check means // anything at all. if actualPair != pair { t.Fatalf("unexpected pair association in metric map: %v != %v", actualPair, pair) } if actual != float64(expected[pair]) { t.Fatalf("incorrect counter value for %v: %v != %v", pair, actual, expected[pair]) } } } if total != len(expected) { t.Fatalf("unexpected number of metrics: %v != %v", total, len(expected)) } vec.Reset() if len(vec.metricMap.metrics) > 0 { t.Fatalf("reset failed") } } func TestCounterVecEndToEndWithCollision(t *testing.T) { vec := NewCounterVec( CounterOpts{ Name: "test", Help: "helpless", }, []string{"labelname"}, ) vec.WithLabelValues("77kepQFQ8Kl").Inc() vec.WithLabelValues("!0IC=VloaY").Add(2) m := &dto.Metric{} if err := vec.WithLabelValues("77kepQFQ8Kl").Write(m); err != nil { t.Fatal(err) } if got, want := m.GetLabel()[0].GetValue(), "77kepQFQ8Kl"; got != want { t.Errorf("got label value %q, want %q", got, want) } if got, want := m.GetCounter().GetValue(), 1.; got != want { t.Errorf("got value %f, want %f", got, want) } m.Reset() if err := vec.WithLabelValues("!0IC=VloaY").Write(m); err != nil { t.Fatal(err) } if got, want := m.GetLabel()[0].GetValue(), "!0IC=VloaY"; got != want { t.Errorf("got label value %q, want %q", got, want) } if got, want := m.GetCounter().GetValue(), 2.; got != want { t.Errorf("got value %f, want %f", got, want) } } func TestCurryVec(t *testing.T) { vec := NewCounterVec( CounterOpts{ Name: "test", Help: "helpless", }, []string{"one", "two", "three"}, ) testCurryVec(t, vec) } func TestCurryVecWithCollisions(t *testing.T) { vec := NewCounterVec( CounterOpts{ Name: "test", Help: "helpless", }, []string{"one", "two", "three"}, ) vec.hashAdd = func(h uint64, s string) uint64 { return 1 } vec.hashAddByte = func(h uint64, b byte) uint64 { return 1 } testCurryVec(t, vec) } func TestCurryVecWithConstraints(t *testing.T) { constraint := func(s string) string { return "x" + s } t.Run("constrainedLabels overlap variableLabels", func(t *testing.T) { vec := V2.NewCounterVec(CounterVecOpts{ CounterOpts{ Name: "test", Help: "helpless", }, ConstrainedLabels{ {Name: "one"}, {Name: "two"}, {Name: "three", Constraint: constraint}, }, }) testCurryVec(t, vec) }) t.Run("constrainedLabels reducing cardinality", func(t *testing.T) { constraint := func(s string) string { return "x" } vec := V2.NewCounterVec(CounterVecOpts{ CounterOpts{ Name: "test", Help: "helpless", }, ConstrainedLabels{ {Name: "one"}, {Name: "two"}, {Name: "three", Constraint: constraint}, }, }) testConstrainedCurryVec(t, vec, constraint) }) } func testCurryVec(t *testing.T, vec *CounterVec) { assertMetrics := func(t *testing.T) { n := 0 for _, m := range vec.metricMap.metrics { n += len(m) } if n != 2 { t.Error("expected two metrics, got", n) } m := &dto.Metric{} c1, err := vec.GetMetricWithLabelValues("1", "2", "3") if err != nil { t.Fatal("unexpected error getting metric:", err) } c1.Write(m) if want, got := 1., m.GetCounter().GetValue(); want != got { t.Errorf("want %f as counter value, got %f", want, got) } m.Reset() c2, err := vec.GetMetricWithLabelValues("11", "22", "33") if err != nil { t.Fatal("unexpected error getting metric:", err) } c2.Write(m) if want, got := 1., m.GetCounter().GetValue(); want != got { t.Errorf("want %f as counter value, got %f", want, got) } } assertNoMetric := func(t *testing.T) { if n := len(vec.metricMap.metrics); n != 0 { t.Error("expected no metrics, got", n) } } t.Run("zero labels", func(t *testing.T) { c1 := vec.MustCurryWith(nil) c2 := vec.MustCurryWith(nil) c1.WithLabelValues("1", "2", "3").Inc() c2.With(Labels{"one": "11", "two": "22", "three": "33"}).Inc() assertMetrics(t) if !c1.Delete(Labels{"one": "1", "two": "2", "three": "3"}) { t.Error("deletion failed") } if !c2.DeleteLabelValues("11", "22", "33") { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("first label", func(t *testing.T) { c1 := vec.MustCurryWith(Labels{"one": "1"}) c2 := vec.MustCurryWith(Labels{"one": "11"}) c1.WithLabelValues("2", "3").Inc() c2.With(Labels{"two": "22", "three": "33"}).Inc() assertMetrics(t) if c1.Delete(Labels{"two": "22", "three": "33"}) { t.Error("deletion unexpectedly succeeded") } if c2.DeleteLabelValues("2", "3") { t.Error("deletion unexpectedly succeeded") } if !c1.Delete(Labels{"two": "2", "three": "3"}) { t.Error("deletion failed") } if !c2.DeleteLabelValues("22", "33") { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("middle label", func(t *testing.T) { c1 := vec.MustCurryWith(Labels{"two": "2"}) c2 := vec.MustCurryWith(Labels{"two": "22"}) c1.WithLabelValues("1", "3").Inc() c2.With(Labels{"one": "11", "three": "33"}).Inc() assertMetrics(t) if c1.Delete(Labels{"one": "11", "three": "33"}) { t.Error("deletion unexpectedly succeeded") } if c2.DeleteLabelValues("1", "3") { t.Error("deletion unexpectedly succeeded") } if !c1.Delete(Labels{"one": "1", "three": "3"}) { t.Error("deletion failed") } if !c2.DeleteLabelValues("11", "33") { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("last label", func(t *testing.T) { c1 := vec.MustCurryWith(Labels{"three": "3"}) c2 := vec.MustCurryWith(Labels{"three": "33"}) c1.WithLabelValues("1", "2").Inc() c2.With(Labels{"one": "11", "two": "22"}).Inc() assertMetrics(t) if c1.Delete(Labels{"two": "22", "one": "11"}) { t.Error("deletion unexpectedly succeeded") } if c2.DeleteLabelValues("1", "2") { t.Error("deletion unexpectedly succeeded") } if !c1.Delete(Labels{"two": "2", "one": "1"}) { t.Error("deletion failed") } if !c2.DeleteLabelValues("11", "22") { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("two labels", func(t *testing.T) { c1 := vec.MustCurryWith(Labels{"three": "3", "one": "1"}) c2 := vec.MustCurryWith(Labels{"three": "33", "one": "11"}) c1.WithLabelValues("2").Inc() c2.With(Labels{"two": "22"}).Inc() assertMetrics(t) if c1.Delete(Labels{"two": "22"}) { t.Error("deletion unexpectedly succeeded") } if c2.DeleteLabelValues("2") { t.Error("deletion unexpectedly succeeded") } if !c1.Delete(Labels{"two": "2"}) { t.Error("deletion failed") } if !c2.DeleteLabelValues("22") { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("all labels", func(t *testing.T) { c1 := vec.MustCurryWith(Labels{"three": "3", "two": "2", "one": "1"}) c2 := vec.MustCurryWith(Labels{"three": "33", "one": "11", "two": "22"}) c1.WithLabelValues().Inc() c2.With(nil).Inc() assertMetrics(t) if !c1.Delete(Labels{}) { t.Error("deletion failed") } if !c2.DeleteLabelValues() { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("double curry", func(t *testing.T) { c1 := vec.MustCurryWith(Labels{"three": "3"}).MustCurryWith(Labels{"one": "1"}) c2 := vec.MustCurryWith(Labels{"three": "33"}).MustCurryWith(Labels{"one": "11"}) c1.WithLabelValues("2").Inc() c2.With(Labels{"two": "22"}).Inc() assertMetrics(t) if c1.Delete(Labels{"two": "22"}) { t.Error("deletion unexpectedly succeeded") } if c2.DeleteLabelValues("2") { t.Error("deletion unexpectedly succeeded") } if !c1.Delete(Labels{"two": "2"}) { t.Error("deletion failed") } if !c2.DeleteLabelValues("22") { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("use already curried label", func(t *testing.T) { c1 := vec.MustCurryWith(Labels{"three": "3"}) if _, err := c1.GetMetricWithLabelValues("1", "2", "3"); err == nil { t.Error("expected error when using already curried label") } if _, err := c1.GetMetricWith(Labels{"one": "1", "two": "2", "three": "3"}); err == nil { t.Error("expected error when using already curried label") } assertNoMetric(t) c1.WithLabelValues("1", "2").Inc() if c1.Delete(Labels{"one": "1", "two": "2", "three": "3"}) { t.Error("deletion unexpectedly succeeded") } if !c1.Delete(Labels{"one": "1", "two": "2"}) { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("curry already curried label", func(t *testing.T) { if _, err := vec.MustCurryWith(Labels{"three": "3"}).CurryWith(Labels{"three": "33"}); err == nil { t.Error("currying unexpectedly succeeded") } else if err.Error() != `label name "three" is already curried` { t.Error("currying returned unexpected error:", err) } }) t.Run("unknown label", func(t *testing.T) { if _, err := vec.CurryWith(Labels{"foo": "bar"}); err == nil { t.Error("currying unexpectedly succeeded") } else if err.Error() != "1 unknown label(s) found during currying" { t.Error("currying returned unexpected error:", err) } }) } func testConstrainedCurryVec(t *testing.T, vec *CounterVec, constraint func(string) string) { assertMetrics := func(t *testing.T) { n := 0 for _, m := range vec.metricMap.metrics { n += len(m) } if n != 2 { t.Error("expected two metrics, got", n) } m := &dto.Metric{} c1, err := vec.GetMetricWithLabelValues("1", "2", "3") if err != nil { t.Fatal("unexpected error getting metric:", err) } c1.Write(m) if want, got := 1., m.GetCounter().GetValue(); want != got { t.Errorf("want %f as counter value, got %f", want, got) } values := map[string]string{} for _, label := range m.Label { values[*label.Name] = *label.Value } if want, got := map[string]string{"one": "1", "two": "2", "three": constraint("3")}, values; !reflect.DeepEqual(want, got) { t.Errorf("want %v as label values, got %v", want, got) } m.Reset() c2, err := vec.GetMetricWithLabelValues("11", "22", "33") if err != nil { t.Fatal("unexpected error getting metric:", err) } c2.Write(m) if want, got := 1., m.GetCounter().GetValue(); want != got { t.Errorf("want %f as counter value, got %f", want, got) } values = map[string]string{} for _, label := range m.Label { values[*label.Name] = *label.Value } if want, got := map[string]string{"one": "11", "two": "22", "three": constraint("33")}, values; !reflect.DeepEqual(want, got) { t.Errorf("want %v as label values, got %v", want, got) } } assertNoMetric := func(t *testing.T) { if n := len(vec.metricMap.metrics); n != 0 { t.Error("expected no metrics, got", n) } } t.Run("zero labels", func(t *testing.T) { c1 := vec.MustCurryWith(nil) c2 := vec.MustCurryWith(nil) c1.WithLabelValues("1", "2", "3").Inc() c2.With(Labels{"one": "11", "two": "22", "three": "33"}).Inc() assertMetrics(t) if !c1.Delete(Labels{"one": "1", "two": "2", "three": "3"}) { t.Error("deletion failed") } if !c2.DeleteLabelValues("11", "22", "33") { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("first label", func(t *testing.T) { c1 := vec.MustCurryWith(Labels{"one": "1"}) c2 := vec.MustCurryWith(Labels{"one": "11"}) c1.WithLabelValues("2", "3").Inc() c2.With(Labels{"two": "22", "three": "33"}).Inc() assertMetrics(t) if c1.Delete(Labels{"two": "22", "three": "33"}) { t.Error("deletion unexpectedly succeeded") } if c2.DeleteLabelValues("2", "3") { t.Error("deletion unexpectedly succeeded") } if !c1.Delete(Labels{"two": "2", "three": "3"}) { t.Error("deletion failed") } if !c2.DeleteLabelValues("22", "33") { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("middle label", func(t *testing.T) { c1 := vec.MustCurryWith(Labels{"two": "2"}) c2 := vec.MustCurryWith(Labels{"two": "22"}) c1.WithLabelValues("1", "3").Inc() c2.With(Labels{"one": "11", "three": "33"}).Inc() assertMetrics(t) if c1.Delete(Labels{"one": "11", "three": "33"}) { t.Error("deletion unexpectedly succeeded") } if c2.DeleteLabelValues("1", "3") { t.Error("deletion unexpectedly succeeded") } if !c1.Delete(Labels{"one": "1", "three": "3"}) { t.Error("deletion failed") } if !c2.DeleteLabelValues("11", "33") { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("last label (constrained to static value)", func(t *testing.T) { c1 := vec.MustCurryWith(Labels{"three": "3"}) c2 := vec.MustCurryWith(Labels{"three": "33"}) c1.WithLabelValues("1", "2").Inc() c2.With(Labels{"one": "11", "two": "22"}).Inc() assertMetrics(t) if !c1.Delete(Labels{"two": "22", "one": "11"}) { t.Error("deletion failed") } if !c2.DeleteLabelValues("1", "2") { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("two labels", func(t *testing.T) { c1 := vec.MustCurryWith(Labels{"three": "3", "one": "1"}) c2 := vec.MustCurryWith(Labels{"three": "33", "one": "11"}) c1.WithLabelValues("2").Inc() c2.With(Labels{"two": "22"}).Inc() assertMetrics(t) if c1.Delete(Labels{"two": "22"}) { t.Error("deletion unexpectedly succeeded") } if c2.DeleteLabelValues("2") { t.Error("deletion unexpectedly succeeded") } if !c1.Delete(Labels{"two": "2"}) { t.Error("deletion failed") } if !c2.DeleteLabelValues("22") { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("all labels", func(t *testing.T) { c1 := vec.MustCurryWith(Labels{"three": "3", "two": "2", "one": "1"}) c2 := vec.MustCurryWith(Labels{"three": "33", "one": "11", "two": "22"}) c1.WithLabelValues().Inc() c2.With(nil).Inc() assertMetrics(t) if !c1.Delete(Labels{}) { t.Error("deletion failed") } if !c2.DeleteLabelValues() { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("double curry", func(t *testing.T) { c1 := vec.MustCurryWith(Labels{"three": "3"}).MustCurryWith(Labels{"one": "1"}) c2 := vec.MustCurryWith(Labels{"three": "33"}).MustCurryWith(Labels{"one": "11"}) c1.WithLabelValues("2").Inc() c2.With(Labels{"two": "22"}).Inc() assertMetrics(t) if c1.Delete(Labels{"two": "22"}) { t.Error("deletion unexpectedly succeeded") } if c2.DeleteLabelValues("2") { t.Error("deletion unexpectedly succeeded") } if !c1.Delete(Labels{"two": "2"}) { t.Error("deletion failed") } if !c2.DeleteLabelValues("22") { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("use already curried label", func(t *testing.T) { c1 := vec.MustCurryWith(Labels{"three": "3"}) if _, err := c1.GetMetricWithLabelValues("1", "2", "3"); err == nil { t.Error("expected error when using already curried label") } if _, err := c1.GetMetricWith(Labels{"one": "1", "two": "2", "three": "3"}); err == nil { t.Error("expected error when using already curried label") } assertNoMetric(t) c1.WithLabelValues("1", "2").Inc() if c1.Delete(Labels{"one": "1", "two": "2", "three": "3"}) { t.Error("deletion unexpectedly succeeded") } if !c1.Delete(Labels{"one": "1", "two": "2"}) { t.Error("deletion failed") } assertNoMetric(t) }) t.Run("curry already curried label", func(t *testing.T) { if _, err := vec.MustCurryWith(Labels{"three": "3"}).CurryWith(Labels{"three": "33"}); err == nil { t.Error("currying unexpectedly succeeded") } else if err.Error() != `label name "three" is already curried` { t.Error("currying returned unexpected error:", err) } }) t.Run("unknown label", func(t *testing.T) { if _, err := vec.CurryWith(Labels{"foo": "bar"}); err == nil { t.Error("currying unexpectedly succeeded") } else if err.Error() != "1 unknown label(s) found during currying" { t.Error("currying returned unexpected error:", err) } }) } func BenchmarkMetricVecWithBasic(b *testing.B) { benchmarkMetricVecWith(b, Labels{ "l1": "onevalue", "l2": "twovalue", }) } func BenchmarkMetricVecWithLabelValuesBasic(b *testing.B) { benchmarkMetricVecWithLabelValues(b, map[string][]string{ "l1": {"onevalue"}, "l2": {"twovalue"}, }) } func BenchmarkMetricVecWithLabelValues2Keys10ValueCardinality(b *testing.B) { benchmarkMetricVecWithLabelValuesCardinality(b, 2, 10) } func BenchmarkMetricVecWithLabelValues4Keys10ValueCardinality(b *testing.B) { benchmarkMetricVecWithLabelValuesCardinality(b, 4, 10) } func BenchmarkMetricVecWithLabelValues2Keys100ValueCardinality(b *testing.B) { benchmarkMetricVecWithLabelValuesCardinality(b, 2, 100) } func BenchmarkMetricVecWithLabelValues10Keys100ValueCardinality(b *testing.B) { benchmarkMetricVecWithLabelValuesCardinality(b, 10, 100) } func BenchmarkMetricVecWithLabelValues10Keys1000ValueCardinality(b *testing.B) { benchmarkMetricVecWithLabelValuesCardinality(b, 10, 1000) } func benchmarkMetricVecWithLabelValuesCardinality(b *testing.B, nkeys, nvalues int) { labels := map[string][]string{} for i := 0; i < nkeys; i++ { var ( k = fmt.Sprintf("key-%v", i) vs = make([]string, 0, nvalues) ) for j := 0; j < nvalues; j++ { vs = append(vs, fmt.Sprintf("value-%v", j)) } labels[k] = vs } benchmarkMetricVecWithLabelValues(b, labels) } func benchmarkMetricVecWith(b *testing.B, labels map[string]string) { var keys []string for k := range labels { keys = append(keys, k) } vec := NewGaugeVec( GaugeOpts{ Name: "test", Help: "helpless", }, keys, ) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { vec.With(labels) } } func benchmarkMetricVecWithLabelValues(b *testing.B, labels map[string][]string) { var keys []string for k := range labels { // Map order dependent, who cares though. keys = append(keys, k) } values := make([]string, len(labels)) // Value cache for permutations. vec := NewGaugeVec( GaugeOpts{ Name: "test", Help: "helpless", }, keys, ) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { // Varies input across provide map entries based on key size. for j, k := range keys { candidates := labels[k] values[j] = candidates[i%len(candidates)] } vec.WithLabelValues(values...) } } client_golang-1.21.1/prometheus/vnext.go000066400000000000000000000017331476160432400203020ustar00rootroot00000000000000// Copyright 2022 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus type v2 struct{} // V2 is a struct that can be referenced to access experimental API that might // be present in v2 of client golang someday. It offers extended functionality // of v1 with slightly changed API. It is acceptable to use some pieces from v1 // and e.g `prometheus.NewGauge` and some from v2 e.g. `prometheus.V2.NewDesc` // in the same codebase. var V2 = v2{} client_golang-1.21.1/prometheus/wrap.go000066400000000000000000000151731476160432400201120ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "fmt" "sort" "github.com/prometheus/client_golang/prometheus/internal" dto "github.com/prometheus/client_model/go" "google.golang.org/protobuf/proto" ) // WrapRegistererWith returns a Registerer wrapping the provided // Registerer. Collectors registered with the returned Registerer will be // registered with the wrapped Registerer in a modified way. The modified // Collector adds the provided Labels to all Metrics it collects (as // ConstLabels). The Metrics collected by the unmodified Collector must not // duplicate any of those labels. Wrapping a nil value is valid, resulting // in a no-op Registerer. // // WrapRegistererWith provides a way to add fixed labels to a subset of // Collectors. It should not be used to add fixed labels to all metrics // exposed. See also // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels // // Conflicts between Collectors registered through the original Registerer with // Collectors registered through the wrapping Registerer will still be // detected. Any AlreadyRegisteredError returned by the Register method of // either Registerer will contain the ExistingCollector in the form it was // provided to the respective registry. // // The Collector example demonstrates a use of WrapRegistererWith. func WrapRegistererWith(labels Labels, reg Registerer) Registerer { return &wrappingRegisterer{ wrappedRegisterer: reg, labels: labels, } } // WrapRegistererWithPrefix returns a Registerer wrapping the provided // Registerer. Collectors registered with the returned Registerer will be // registered with the wrapped Registerer in a modified way. The modified // Collector adds the provided prefix to the name of all Metrics it collects. // Wrapping a nil value is valid, resulting in a no-op Registerer. // // WrapRegistererWithPrefix is useful to have one place to prefix all metrics of // a sub-system. To make this work, register metrics of the sub-system with the // wrapping Registerer returned by WrapRegistererWithPrefix. It is rarely useful // to use the same prefix for all metrics exposed. In particular, do not prefix // metric names that are standardized across applications, as that would break // horizontal monitoring, for example the metrics provided by the Go collector // (see NewGoCollector) and the process collector (see NewProcessCollector). (In // fact, those metrics are already prefixed with β€œgo_” or β€œprocess_”, // respectively.) // // Conflicts between Collectors registered through the original Registerer with // Collectors registered through the wrapping Registerer will still be // detected. Any AlreadyRegisteredError returned by the Register method of // either Registerer will contain the ExistingCollector in the form it was // provided to the respective registry. func WrapRegistererWithPrefix(prefix string, reg Registerer) Registerer { return &wrappingRegisterer{ wrappedRegisterer: reg, prefix: prefix, } } type wrappingRegisterer struct { wrappedRegisterer Registerer prefix string labels Labels } func (r *wrappingRegisterer) Register(c Collector) error { if r.wrappedRegisterer == nil { return nil } return r.wrappedRegisterer.Register(&wrappingCollector{ wrappedCollector: c, prefix: r.prefix, labels: r.labels, }) } func (r *wrappingRegisterer) MustRegister(cs ...Collector) { if r.wrappedRegisterer == nil { return } for _, c := range cs { if err := r.Register(c); err != nil { panic(err) } } } func (r *wrappingRegisterer) Unregister(c Collector) bool { if r.wrappedRegisterer == nil { return false } return r.wrappedRegisterer.Unregister(&wrappingCollector{ wrappedCollector: c, prefix: r.prefix, labels: r.labels, }) } type wrappingCollector struct { wrappedCollector Collector prefix string labels Labels } func (c *wrappingCollector) Collect(ch chan<- Metric) { wrappedCh := make(chan Metric) go func() { c.wrappedCollector.Collect(wrappedCh) close(wrappedCh) }() for m := range wrappedCh { ch <- &wrappingMetric{ wrappedMetric: m, prefix: c.prefix, labels: c.labels, } } } func (c *wrappingCollector) Describe(ch chan<- *Desc) { wrappedCh := make(chan *Desc) go func() { c.wrappedCollector.Describe(wrappedCh) close(wrappedCh) }() for desc := range wrappedCh { ch <- wrapDesc(desc, c.prefix, c.labels) } } func (c *wrappingCollector) unwrapRecursively() Collector { switch wc := c.wrappedCollector.(type) { case *wrappingCollector: return wc.unwrapRecursively() default: return wc } } type wrappingMetric struct { wrappedMetric Metric prefix string labels Labels } func (m *wrappingMetric) Desc() *Desc { return wrapDesc(m.wrappedMetric.Desc(), m.prefix, m.labels) } func (m *wrappingMetric) Write(out *dto.Metric) error { if err := m.wrappedMetric.Write(out); err != nil { return err } if len(m.labels) == 0 { // No wrapping labels. return nil } for ln, lv := range m.labels { out.Label = append(out.Label, &dto.LabelPair{ Name: proto.String(ln), Value: proto.String(lv), }) } sort.Sort(internal.LabelPairSorter(out.Label)) return nil } func wrapDesc(desc *Desc, prefix string, labels Labels) *Desc { constLabels := Labels{} for _, lp := range desc.constLabelPairs { constLabels[*lp.Name] = *lp.Value } for ln, lv := range labels { if _, alreadyUsed := constLabels[ln]; alreadyUsed { return &Desc{ fqName: desc.fqName, help: desc.help, variableLabels: desc.variableLabels, constLabelPairs: desc.constLabelPairs, err: fmt.Errorf("attempted wrapping with already existing label name %q", ln), } } constLabels[ln] = lv } // NewDesc will do remaining validations. newDesc := V2.NewDesc(prefix+desc.fqName, desc.help, desc.variableLabels, constLabels) // Propagate errors if there was any. This will override any errer // created by NewDesc above, i.e. earlier errors get precedence. if desc.err != nil { newDesc.err = desc.err } return newDesc } client_golang-1.21.1/prometheus/wrap_test.go000066400000000000000000000236011476160432400211440ustar00rootroot00000000000000// Copyright 2018 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package prometheus import ( "fmt" "strings" "testing" "time" dto "github.com/prometheus/client_model/go" "google.golang.org/protobuf/proto" ) // uncheckedCollector wraps a Collector but its Describe method yields no Desc. type uncheckedCollector struct { c Collector } func (u uncheckedCollector) Describe(_ chan<- *Desc) {} func (u uncheckedCollector) Collect(c chan<- Metric) { u.c.Collect(c) } func toMetricFamilies(cs ...Collector) []*dto.MetricFamily { reg := NewRegistry() reg.MustRegister(cs...) out, err := reg.Gather() if err != nil { panic(err) } return out } func TestWrap(t *testing.T) { now := time.Now() nowFn := func() time.Time { return now } simpleCnt := NewCounter(CounterOpts{ Name: "simpleCnt", Help: "helpSimpleCnt", now: nowFn, }) simpleCnt.Inc() simpleGge := NewGauge(GaugeOpts{ Name: "simpleGge", Help: "helpSimpleGge", }) simpleGge.Set(3.14) preCnt := NewCounter(CounterOpts{ Name: "pre_simpleCnt", Help: "helpSimpleCnt", now: nowFn, }) preCnt.Inc() barLabeledCnt := NewCounter(CounterOpts{ Name: "simpleCnt", Help: "helpSimpleCnt", ConstLabels: Labels{"foo": "bar"}, now: nowFn, }) barLabeledCnt.Inc() bazLabeledCnt := NewCounter(CounterOpts{ Name: "simpleCnt", Help: "helpSimpleCnt", ConstLabels: Labels{"foo": "baz"}, now: nowFn, }) bazLabeledCnt.Inc() labeledPreCnt := NewCounter(CounterOpts{ Name: "pre_simpleCnt", Help: "helpSimpleCnt", ConstLabels: Labels{"foo": "bar"}, now: nowFn, }) labeledPreCnt.Inc() twiceLabeledPreCnt := NewCounter(CounterOpts{ Name: "pre_simpleCnt", Help: "helpSimpleCnt", ConstLabels: Labels{"foo": "bar", "dings": "bums"}, now: nowFn, }) twiceLabeledPreCnt.Inc() barLabeledUncheckedCollector := uncheckedCollector{barLabeledCnt} scenarios := map[string]struct { prefix string // First wrap with this prefix. labels Labels // Then wrap the result with these labels. labels2 Labels // If any, wrap the prefix-wrapped one again. preRegister []Collector toRegister []struct { // If there are any labels2, register every other with that one. collector Collector registrationFails bool } gatherFails bool output []Collector }{ "wrap nothing": { prefix: "pre_", labels: Labels{"foo": "bar"}, }, "wrap with nothing": { preRegister: []Collector{simpleGge}, toRegister: []struct { collector Collector registrationFails bool }{{simpleCnt, false}}, output: []Collector{simpleGge, simpleCnt}, }, "wrap counter with prefix": { prefix: "pre_", preRegister: []Collector{simpleGge}, toRegister: []struct { collector Collector registrationFails bool }{{simpleCnt, false}}, output: []Collector{simpleGge, preCnt}, }, "wrap counter with label pair": { labels: Labels{"foo": "bar"}, preRegister: []Collector{simpleGge}, toRegister: []struct { collector Collector registrationFails bool }{{simpleCnt, false}}, output: []Collector{simpleGge, barLabeledCnt}, }, "wrap counter with label pair and prefix": { prefix: "pre_", labels: Labels{"foo": "bar"}, preRegister: []Collector{simpleGge}, toRegister: []struct { collector Collector registrationFails bool }{{simpleCnt, false}}, output: []Collector{simpleGge, labeledPreCnt}, }, "wrap counter with invalid prefix": { prefix: "1\x801", preRegister: []Collector{simpleGge}, toRegister: []struct { collector Collector registrationFails bool }{{simpleCnt, true}}, output: []Collector{simpleGge}, }, "wrap counter with invalid label": { preRegister: []Collector{simpleGge}, labels: Labels{"\x80": "bar"}, toRegister: []struct { collector Collector registrationFails bool }{{simpleCnt, true}}, output: []Collector{simpleGge}, }, "counter registered twice but wrapped with different label values": { labels: Labels{"foo": "bar"}, labels2: Labels{"foo": "baz"}, toRegister: []struct { collector Collector registrationFails bool }{{simpleCnt, false}, {simpleCnt, false}}, output: []Collector{barLabeledCnt, bazLabeledCnt}, }, "counter registered twice but wrapped with different inconsistent label values": { labels: Labels{"foo": "bar"}, labels2: Labels{"bar": "baz"}, toRegister: []struct { collector Collector registrationFails bool }{{simpleCnt, false}, {simpleCnt, true}}, output: []Collector{barLabeledCnt}, }, "wrap counter with prefix and two labels": { prefix: "pre_", labels: Labels{"foo": "bar", "dings": "bums"}, preRegister: []Collector{simpleGge}, toRegister: []struct { collector Collector registrationFails bool }{{simpleCnt, false}}, output: []Collector{simpleGge, twiceLabeledPreCnt}, }, "wrap labeled counter with prefix and another label": { prefix: "pre_", labels: Labels{"dings": "bums"}, preRegister: []Collector{simpleGge}, toRegister: []struct { collector Collector registrationFails bool }{{barLabeledCnt, false}}, output: []Collector{simpleGge, twiceLabeledPreCnt}, }, "wrap labeled counter with prefix and inconsistent label": { prefix: "pre_", labels: Labels{"foo": "bums"}, preRegister: []Collector{simpleGge}, toRegister: []struct { collector Collector registrationFails bool }{{barLabeledCnt, true}}, output: []Collector{simpleGge}, }, "wrap labeled counter with prefix and the same label again": { prefix: "pre_", labels: Labels{"foo": "bar"}, preRegister: []Collector{simpleGge}, toRegister: []struct { collector Collector registrationFails bool }{{barLabeledCnt, true}}, output: []Collector{simpleGge}, }, "wrap labeled unchecked collector with prefix and another label": { prefix: "pre_", labels: Labels{"dings": "bums"}, preRegister: []Collector{simpleGge}, toRegister: []struct { collector Collector registrationFails bool }{{barLabeledUncheckedCollector, false}}, output: []Collector{simpleGge, twiceLabeledPreCnt}, }, "wrap labeled unchecked collector with prefix and inconsistent label": { prefix: "pre_", labels: Labels{"foo": "bums"}, preRegister: []Collector{simpleGge}, toRegister: []struct { collector Collector registrationFails bool }{{barLabeledUncheckedCollector, false}}, gatherFails: true, output: []Collector{simpleGge}, }, "wrap labeled unchecked collector with prefix and the same label again": { prefix: "pre_", labels: Labels{"foo": "bar"}, preRegister: []Collector{simpleGge}, toRegister: []struct { collector Collector registrationFails bool }{{barLabeledUncheckedCollector, false}}, gatherFails: true, output: []Collector{simpleGge}, }, "wrap labeled unchecked collector with prefix and another label resulting in collision with pre-registered counter": { prefix: "pre_", labels: Labels{"dings": "bums"}, preRegister: []Collector{twiceLabeledPreCnt}, toRegister: []struct { collector Collector registrationFails bool }{{barLabeledUncheckedCollector, false}}, gatherFails: true, output: []Collector{twiceLabeledPreCnt}, }, } for n, s := range scenarios { t.Run(n, func(t *testing.T) { reg := NewPedanticRegistry() for _, c := range s.preRegister { if err := reg.Register(c); err != nil { t.Fatal("error registering with unwrapped registry:", err) } } preReg := WrapRegistererWithPrefix(s.prefix, reg) lReg := WrapRegistererWith(s.labels, preReg) l2Reg := WrapRegistererWith(s.labels2, preReg) for i, tr := range s.toRegister { var err error if i%2 != 0 && len(s.labels2) != 0 { err = l2Reg.Register(tr.collector) } else { err = lReg.Register(tr.collector) } if tr.registrationFails && err == nil { t.Fatalf("registration with wrapping registry unexpectedly succeeded for collector #%d", i) } if !tr.registrationFails && err != nil { t.Fatalf("registration with wrapping registry failed for collector #%d: %s", i, err) } } wantMF := toMetricFamilies(s.output...) gotMF, err := reg.Gather() if s.gatherFails && err == nil { t.Fatal("gathering unexpectedly succeeded") } if !s.gatherFails && err != nil { t.Fatal("gathering failed:", err) } if len(wantMF) != len(gotMF) { t.Fatalf("Expected %d metricFamilies, got %d", len(wantMF), len(gotMF)) } for i := range gotMF { if !proto.Equal(gotMF[i], wantMF[i]) { var want, got []string for i, mf := range wantMF { want = append(want, fmt.Sprintf("%3d: %s", i, mf)) } for i, mf := range gotMF { got = append(got, fmt.Sprintf("%3d: %s", i, mf)) } t.Fatalf( "unexpected output of gathering:\n\nWANT:\n%s\n\nGOT:\n%s\n", strings.Join(want, "\n"), strings.Join(got, "\n"), ) } } }) } } func TestNil(t *testing.T) { // A wrapped nil registerer should be treated as a no-op, and not panic. c := NewCounter(CounterOpts{Name: "test"}) err := WrapRegistererWith(Labels{"foo": "bar"}, nil).Register(c) if err != nil { t.Fatal("registering failed:", err) } } client_golang-1.21.1/supported_go_versions.txt000066400000000000000000000000171476160432400216110ustar00rootroot000000000000001.23 1.22 1.21 client_golang-1.21.1/tutorials/000077500000000000000000000000001476160432400164365ustar00rootroot00000000000000client_golang-1.21.1/tutorials/whatsup/000077500000000000000000000000001476160432400201315ustar00rootroot00000000000000client_golang-1.21.1/tutorials/whatsup/.gitignore000066400000000000000000000000341476160432400221160ustar00rootroot00000000000000internal/e2e_* whatsup.yaml client_golang-1.21.1/tutorials/whatsup/ContribFest.pdf000066400000000000000000036561011476160432400230620ustar00rootroot00000000000000%PDF-1.4 % βγΟΣ 3 0 obj << /Type /Catalog /Names << >> /PageLabels << /Nums [ 0 << /S /D /St 1 >> ] >> /Outlines 2 0 R /Pages 1 0 R >> endobj 4 0 obj << /Creator (ώGoogle) /Title (ώKubeCon 2023 EU: Prometheus ContribFest) >> endobj 5 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 6 0 R /Resources 7 0 R /Annots 9 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 6 0 obj << /Filter /FlateDecode /Length 8 0 R >> stream xœ½UΝn1ήν©σˆSPRγρŒE€JH+υ@9D@‘€%…GΰΝx‰άΚ9OΑxΓf7Ω4΄ °–ΧžρxΎρ7ώ™* ©<^tX[i?L` ZiΡ«Ή΄X—Ε(5 g½Σετq-m=§ΞΦ„τΑ)\ΘϊΟΖ_F Γ―‚`Rυ C‘ŽAS$Έξ5‚σ#x+eΪ@Β©,βα@bδ#«Γ2MΥΈ‘ŠΩ•Ίzf­[&H ·u―$ΆRΛΖ)vl½¬FΝήPΕΎPνŒg+]‚!K%9l…“b^ˆ“β ϊ///ΎpQQϊη«iR½x‘‘EΊπΊΩχό€”F»ω£Ό“Νσ³³όž4ƒΌθΑ{(^ΓqqηHhK$Μ¨Π γV<έƒYŠΟΠ‘bboΫ€\2«jΫ΅ ’ήD("©Φ½ίΰσabσ$?Μ³'Βi!bMκ ‰`Omθ½ΧΒ~‡ΚsΆΡa$Εkά #Ε‚“AΉΩA³μioαG8K{ΰ6 mA6²ΓšΘέ,ΟίHy ‰ψ™ύHψ‡)9{,ΠX­‚ή΅Αn™Ύ)x/#ήύLάBšώ™Uε}SεzνΎ9˜‰Ν{²uΈdͺ#ͺdΣ‘4—M³Χ•DnC $‰Τhuh‡»δδ·ωΆ·…΅±fq‘/ rD +Κq­DΛheύF”Υμ¦ρ ύ η§Gε›Œ:η–Dι 9¨7Lϊ―&ƒα'†—Ώ©Jε’š_ endstream endobj 8 0 obj 586 endobj 9 0 obj [ ] endobj 10 0 obj << /CA 1.0 /ca 1.0 >> endobj 11 0 obj << /CA 0 /ca 0 >> endobj 14 0 obj << /Subtype /Image /Interpolate true /Width 400 /Height 397 /ColorSpace /DeviceRGB /BitsPerComponent 8 /SMask 15 0 R /Filter /DCTDecode /Length 16 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐ"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωRŠ( Š( Š( Š( Š( Š( Š( Š*晦^κ“ω:}¬Χ–€…Ιΐ$τάρI΅vT!)ΎX«²θGΓ NεCκW0Ψ©SςζΈ9ΰ\cœ†=ΏγIπ§0slΧ’$5ΣoŒm)Qύ+ŠcFž‰έωΎ"ΕΦΦK•y–η‡YΪ\ήΝεYΫΝq.3²$.Ψυΐ‡Mπ'ˆo„L,MΌNOΟpΑ6γΥ~πιι^νkm€ ¬1Α ηlq¨U98ή₯™¬ίΑΝ₯:³oΣOσ<’ΗαUλ‡ϋ~₯o1³ΙF—=sœνΗo_Β΅,~Y&·κW3g<”X±λœξΟoJτz+–Y†"_hτ)δx(}‹ϊ·ώv8›?†š o”ή\1εΛ( υω@?­]„Γ?τ ΘςρUΤΡY {b;‘ωκ?M΅Γk^ΥτbζϊΖU‰FLΘ7Η‚p>aΐΙμpys^…,]*ΊFZž.'+ΕaUκCNλTcQEΠyαEPEPEPEPEPEPEPEPEPEPEPEPEwIοu{Αk¦Ϋ΄σ[h rO}}E&ΤUΩQŒ¦ΤbΩJ΅τκzτ‘tλfhΓmi›ε:g-κ2N;W¦x[ὝŽΩυ²—· δD€ωKƒΑμ[§~9#­wΡFΔ‘D‹h‘U`(…yUσHΗJJώg`Έrs΄ρΛ²ίώβpZΓ=6Φ-ϊΛ΅τμΈ(¬ΡΖ‡Ž˜ ’#$ƒ»«[h- XmaŽW;cB¨ΙΙΐυ-δU―R³ΌέΟ©Γ`θaU¨Ε/Οο (’²:BŠ( Š( Š+?\ΥμτM>K»ωBF£…ouGsλ8ši9;"g8Β.RvHΠ’ΈψŽΔχ—·RBΆΊ|GAKovΑ$Θq’Έθϋγ=vuiΚ”Ή%Ήž D=₯=žήaEVfΑEPEPEP)―ψEΥ’ύΥΊX\*νI- οΚ8<Ÿcΐ―0ρ'υ}|ΎWΪμΧ'Ο€ghδε—ͺπ2O g­{ΥΩCVŽ—Ίσ<œfK†ΕknYw_δ|ΉE{Χ‰|€λ{εςΎΙxΩ>|',½“’x'kΘ|Iα}OΓΜ¦ώ%09Ϊ“ΔΫ‘Ž3Pzυ88Ξ+ΪΓγiΧΡhϋ#ŽΚ+ΰύζ―λυμaΡEΨyaEPEPEPEPEPEPEPEPEPE>(ήiR(Q€‘Ψ*’Œ–' Ή―aπ7€SJš GVe–ω@d€ ¬žΉώ&{œgƒ\ψŒL0ρΌΎγ»—ΥΖΟ–šΣ«νύv9xχYXξ―ΛYιξ‘Ρ° Κ3ό#ψFSκW°i]–‘f-tΫu‚ΕΆ‚I$χ$ςOΧΠUΪ+η±Ί˜‡οmΨϋœYGq^][ίώQEΜz!EPEPEPEPWSΗkk5ΔνΆQ€vΑ8P2N=|χβ―^xPσ)‘ εbω““ί€ήόf՚8,τ¨dΗ›™ηQJƒ„θA;Ž9εAγΏ”W»–a”aνe»ΨψΎ!ΗΊ•>­€wσπ?3ά~Ϊ}›ΑρKΏwΪ¦’lmΖά˜χϋ™όk²ΰύΤ“ψQα‘Γ {‡Ž5ΐT€έΊόΜܟι]ΕyX»ϋiίΉτΩeΎ©O—² (’ΉΞΰ’Š(’Š(’Š(’Š(¦KMΕ2,‘Ί•daΐυwϊ( Ο5ρgΓX§έsαβ±JK3ΫHΨB1ΐCŽ #‘8ωΊ¨ε2ΖπΚρLˆΕY`©A}A\χ‹|)aβXά†κ0DsΖ@η†ΔΉηwΑ5κasv«ΉσyžCΧ«†]Ί?ς>}’΄΅έCΌk}BŒξ!$μ r­άr>™η³k݌”•ΦΗΖΞ§' «4QE2BŠ( Š( Š( Š( Š( Š( ¬XYάj‘ZΩDΣ\JΫQ©?ΠwΟj]6Κ}Jώ ;D/<Μ@©φIμ}ᏠΨxvΜCf»ζ`· 0Ÿ\v€~§$ρβρ‘Γ«nΩλey\±ςm»EnDSπG…-ό5dK›P•q4ΐp]‹θΏΜŒžΐtΤQ_9R€ͺIΚNμϋΪ!B 5d‚Š(¨5 (’€ (’€ (’€ (’€ (¨§ŠΦΪk‹‡Ω HdwΑ;T “ΟJΈ›I]Ÿ=ψΚϋϋKΕ:ΘhΩ Ε£9VUωTƒί!AΝbΡE}„"‘Πό­GVnovοχžπsRΪνΝƒ• yW‚ItΙ€m.yτ±ΧΝ:5ϋιz΅₯τ[‹A*Ι΅[nΰ+ŸB2?ϊFβ+»Xn-Ϋ|3"ȍ‚2€dc^iK–’šκ}Ÿbyθ:/xΏΑΑΉ-Q^aτAEPEaιzθΥ&Υo<#ρξκΦ%[[‘― ,λ€ρΡ·ηΞz‚sΎƒάbυ±ΕΖΗԚΌ[³ςσ=zŠ‘‘κ֚ޝν„›βn<27ua؏ώΈΰƒWλEΕΩξuΒqœT’ξ˜V_ŠΏδWΦ?λΞoύΦ₯ex±‚ψ[X,@c”sώαͺ§ρ―R+ ^ŒωƊ(――?, φΏ„š³_ψuν&“|ΦO°g$ωg•Ι>α€ Q^)]oΓ TιΎ+·ά,cμοO'ξ`ϋ€=‰ϊΧ:΅’νΊΤυrlOΥρqoihώ{~6=ڊ(―™?C δ~%x…΄=GlqyyΊ(Θ$\|Ξξ21ΘδηœW]^ρ V]cΕ7SC'™m „ρ«Τ‚:‚Εˆ>„}+·CΫUΧe©δgXΧ…Γ>_ŠZ/Υ]ΞχΰΌ.}p©‰€ΉςΩςyUE*1Σ‚Νωύ+Π«‚ψ3"½Χύ~7ώ€•ήΤc]λΘΫ)I`ιΫ°QEΚz!EPEPEPEPM[OƒUΣn,nԘg]­Ž£ΠppGΈ―ρW‡ό9¨›k‘Ύ&Ι†uYϊάvχτMexŸDƒΔDΆ7 Sq €dΖγ‘Ηζ±=+·‹xyYό/σ<œΫ,Ž:ΧΖΆ/λcη*ή©c>™¨άY].&Κ7θF@8#}ͺ•τ‰¦Ο₯βχAESQEQEQElxOG}w^΅±ό¦mΣ2πV1χŽpp{F2ELδ‘'².9Uš„wzoΒo «Α¬ήFΒήώŽY_[Ÿξφ }ξ‡ε"½z’΅‚;[Xmΰ]°Β‹.I€2yθ*ZωlMw^£›ω€eψ(ΰ¨ͺQί«ξŠ(¬Π’Š(’Š(’Š(’Š(―ψΝ#E―ύy―ώ†υμΥα_.%›Ζ—qΘΫ’Ž8ΖΪ»cί–cΟ­z9Z½kωIG gկ՚?υΑc«Ι¦\IΆήχ˜χQΣ©n $ ―d―—β‘α•$‰Ω$B]N ‘ΠƒΨך5ϊjšM₯τ{άD²W‘Κδw ϋŠΣ4£Λ5Qu9ψsηNT%φu^όŸζ\S⌈žΏWtVs f±σΰzœ~€ΧW^qρͺοf—¦ΩμΟ›3MΏ=6.1}₯qΰγΝ^+ΟςΤυ³ZŠž€Ÿk}ϊ~§‘ΡEυ'ζΑEP^Τ—WΠμoՐ΄Ρ}ŠB‡θΐΟ ό:ž΅£^aπ[R-CKr‘ƒ ˜ΖH8VΙ遄όΟ^ޟ_)‰₯μjΈ₯ε؟­a‘UοΧΥ-Ԏ‘α½Bυ #ˆˆΩ@%]ΎU8<`1όkη:υύW{4½6ΟΛϝ3KΏ=6.13τχ―#―g+§ΛK›Ής|E_ΪbU>‘_‹ΧόLψ'qέjΦΜؚDŽE\UKsυuόλΥλΑ~jΩώ0²έ'—ΖmίεΞνΓεί8^¦kή«ΟΜαΛ^ύαw‡«)ΰΤ?•΅ϊώ‘EWž{EPEPEPEPEPρ+Βۚp»΅βώΡͺ„Ι™z”ΰg<|ΎδŽω_Q׌όUπίφn₯ύ©jΈ΄ΌsζeςVc’xτ={σžƒμeΈ―ωs/—ω)ΔuΧΦ©―_σ3‚’Š+Ϊ>H(’Š(’Š+έ~ψy΄=Λr1yyΆY(ΈωPƒάdηΙΗ8ΌΟαΦ…ύ·β(Όδέgk‰¦ΘΚΆ>κδφ=@jχͺρ³LFΤcσ>―‡0WΎ*kΙ~―τϋŠ(―ϊΠ’Š(’Š(’Š(’Š(’Š(―™υ[Ώ·κ——›<Ώ΄LσlΞvξbqžύkάΎ#κCMπιΚω—+φd Ώ Σ‘ΫΈσΗ…x{yM;FS}t>?‰«§8Q]5=Ώ―0―hψ;zn<55«Κ­g!S(ŒΝ·Χ‹Χ€|» ©κV~^LΠ¬ΫχtΨΨΖ=όΟΣήΊssP~Zž~EWΩγ"»έ_3ΦλΕ>/_}§Ε"ΩZMΆͺcςξo˜•ξ Œϋ{ φ‰dHbyfuŽ4RΜμp€žΒΎlΦ΅Υuk»ιwžVp¬ϋŠ‚x\ϊ€=…yωU;ΤsνϊžοWδ‘Ky?ΑΑ±JŠ(―xψ ’Š(©ψi¨}ƒΖ[₯ςβΈΝ»όΉέΈ|£§8N¦kή«ζ}*ομ₯ζΟ3μσ$Ϋ3ΫXg·JϊbΌ,ΪœeέgΓ5y¨ΞŸgΏώρ/‹ΧQάx»ΚŒ8kkt‰χbKρΟL8τη5ΔΦߍn%Ήρnχ ΉΦεβϋ aPνQΗ P+½|49)F>GΛγͺ{\MIχl|2ΙΙ,.ρΛGC†R9ΠΧΡήΤ†―‘Xί‚₯¦ˆΪΗ <ΰ0#π―›«Ρώλ~Eτϊ<Ηχwš:HΜ:wQžNίzδΜ¨{J\λxώG§c=†#ΩKiισιώGQEσΗέQ@Q@Q@Q@Q@TΥ΄ψ5]6βΖμ λ΅±ΤzξχnŠi΄ξ…(©+=™΅KτΝFβΚιvΝ”nЌγ‚9Њ«^·ρ‡CY¬aΦ @%€ˆ§#ψŸ”υμάp2wz ςJϊœ-u^š™ωΆcƒx:ξ—MΧ§υ QEΠp…WEΰ!΅ZDUX\LC)E#‚PNΏ^•&©ΕΙτ4£JUͺFœwnΗ¬|9ΠΏ±<;œ›o.±4ΩeΟέCΐ<Η‘-]MWΙΤ¨κIΞ[³τκcBœiCdQEA°QEQEQEQEQE2YžYc³;©'° 6<Ÿγ>§ζκ6Zlo” “#sp/bΘΟgόόή΄5ύN]gXΊΤ'^wΘ^>U*πpΗ8¬ϊϊΌ5/eJ0?3Ηβ~΅ˆ^ιιΣπ μ>]=ΏŒ­β@₯nc’'Θδ»ψχΚΦΈϊι>άΑiγ>{©£‚σ7I#Q˜Ψ “οOΉ¨Ιy1`%Ɋ¦οoy~g¦|SΦ²ό:Φ±\ίζ!νρž„t!{›#₯x}oψηZώέρΝΜlΩ?s¬jN I-Ο#8νX– ‡±€“έκΌίυΌK”~’?˜QEΦyEP_LΪίAq¦E~Εk$"pαv‘]Ωnp0:σ_3WΌG"Kπ΄΄N£H*JœŒˆpGΤGΤW•šC›“ΦίyτΌ9UΑΥ·kύΧ<Š(―Tω ©m.%΄Ί†ζέΆM ‰°ƒƒοQQCWэ6Ρτ‡΅{}oI‚φΥΠ‡Qζ"œωoΉ‘τηƒΠŠ―ψIύƒX}6αρm{χ7QΣ©ΐά8θI!E{5|Ά.‡°¨γΣ‘ϊ>YϊζT{μύBŠ(cΠ (’€ (’€ (’€ (’€ (’€"»·ŠξΦkk…έ ΘѺ䌩##ΨΧΝΊΕ„Ί^©uc>wΑ!L•+ΈΓ`φ#{ϊ^Ό§γ6’±ΟgͺΓ<άΑ; X ‘ΗRHά3Ο ύ,²·%NG³όϟβ,/΅ «%¬&y•Q_@|8W°όVίGŸS’ά(’Š(’Š(’Š(’Š(’Š+”ψ¨Άα ―/x{¦ͺΑAvKŸUVΌώ5Υ׎όdΤΦη\Ά°M„YΖYΘ0wΑ η‚6„#§ŸN¬/iZ+’Τσ3ŒOΥπ“kw’ωΐΉηΤQE}AωΠQEQEQEQEWͺG#Επ@΄nΘΔ%N ΖϊHόkΚλ½Σn?βΟκ±Ν7όΎ,q+·Όm΅Asλ\˜Έσ(‰¦W>GWΞ8*(’ΊΟ,(’Š|R<2€°»G"0eu8*GBc_Hθ:œZΏk¨@6€ιΈ―'kteΙ8 ŒγœWΝuλŸu?7N½ΣdžFL­Α{FN;Ώηζf”Ή©)­Ρτ<;‰φx‡Iν%ψ―ψ=Š(―ϋp’Š(’Š(’Š(’Š(’Š(¬ι§Wπή‘dŒ’DLj¬gSΉFO,Z΅θ§8ΙIt"₯5RΩ«.Q[ώ:Σ?²|Sn©Ά6,G±v·8Qθ2Wξώ__ ©ΕIu?.­JTjJœ·NΗIπξΗνώ0Ӑ¬…"=™έΨ7}ΰ£ρ――&ψ)jͺ]’ήlQ€JγI9χωλ^³_?™Οš·/eϋ~£Ι„ηώfίιϊQ^yξ…Q@Q@Q@Q@Q@|Χ―ίiλwΧ‘€ežftσX.~Pzτφ―}ρuΰ°πΖ§pehYmέRDΞUΨm\Θ;ˆη΅|η^ΞS %?‘ς\M[Zt—›ύκQE{'ΚQ@Q@Q@Q@[Žοf—qg³>lΡMΏ=6,ƒχσ?J©E&“άq“‹Ί (’˜‚Š( »„χR[ψΚή(ΥJάΕ$O‘Θwδ{εαšγ«OΓ.‘x“I’WHγKΈ™Ψ*¨2I<οYWŠ9Eφ:pu=–"μΧζ}!EWΙ§…Q@Q@Q@Q@Q@Q@[ρ«O;΄νIγ o#ξΰ ί|υ«Λ«ή>(Y­ίƒoΙid€€ΡνΞT†›ΡKuγφ――£ΛgΝBέ΄> ˆ(ϋωCϊWkXž΅ŽΟΒ:LP—*Φλ)άA;œo=ΊeŽ=½knΌ,DΉκΚ^gΩ`)ϋ,58y ’Š+¬(’Š(’Š(’Š(’Š(’Šδ>*άΗƒ.£ΧGqΥƒώJkΒλΩΎ3Θ―k_‹ =xΝ}V­BώgΒρœ±vμ—κP’Š+Ρ<’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(κ:(’Ύ4ύ`(’Š(’Š(’Š(’Š(’Š(’Š«ͺΪ}ΏKΌ³ίεύ’‡~3·r‘œwλ_3WΤuσgˆ-β΄Χ΅+kuΩ 72F‹’p‘ˆ'Ϊ½Œ¦_}”βzzS©κΏ/ψ'ΡZm’ΨiΦΆhΕ’ή$ˆ1κB€3ϊUš(―»»³κ’IYQ@Š( Š( Š( Š( Š( ;βΕ’άx:iYˆ6Η*ά“³πsωW†ΧΡΎ+±ώπή₯iε]ΰc‚\ §ώ<|ε^φU;qμϊβZN8ˆΤΆ~)ΑAEW¨|ΰQEQEQEQEQEQEQESΰŠIζŽ#y%‘‚" %™‰ΐ€Σ+sΐφ―yβν&(І[…”–ι„ωΟγ…?EIrEΛ±₯~Φ€`Ί΄Ύσθz(’Ύ@ύP(’Š(’Š(’Š(’Š(’Š(’Š+ΐ>"ΫΕmγMQ ]¨]d#$ό̊Μyυ$šχϊπ_‰ίςw‰Rϊ΄_χΏF{ΥQ^aτAEPEPEPEPEPEP_:ψΏJ:7ˆο¬Β‰d/‘ε·*2y8άϊ*Όγγ‰ηΨΑ¬B>{|C7=PŸ”υμΗ ήΥθe΅½^W³ώ‘αηψ_o†ηŠΦόΊŸΘς:(’Ύˆψ0’Š(’Š(’Š(’Š(’Š(’Š(’Š(―Gψ3¦yΊζ§"e`Ae£Θάά’±`ϋ?ηητ?‚΄ƒ’xnΞΞUQq΄Ι6½ŽH$’8\χΪ+ΟΜ«{:<«v{™ΫbΉήΠΧηΣόώFεQ_:}ΰQEQEQEQEQEQEWŒόf‘’ΧώΌΧCzφjρŒ¬Šmΐ •΄@qΫηzτ2Ογό™βqϋ›υG³ΡUt«Ώ·ιvw›<Ώ΄B“lΞvξPqžύjΥp4Σ³=¨ΙI)-˜QE†QEQEΞxλUΤ4=j:jE/”α%IFP+q»‚AΪρƒΑAj—Ά6’³¬w4LPΰ€ΐƒΐΥ’ŒΣ’Ί1ΔBU)J0vvΡωžeaρYΒΔΊ†–¬ΫΏy$γŒυAη·sν] Δάο󀹴یyΠ“»ι³wO|u―Υl'υ‹+΅Ϋ4QΈ B2Α χUJϊ eΨy«₯oCβ!žγhΎY΄νέ•₯μυ]>φfŠΚώζUŠΓ2Ή¦pNE\―—+bΗΔΊέ‹Dm΅K΅X—j#H]cmlιΗΙ<₯ύ‰}η₯K‰Χό½§χ?σ3躊ξή+»Y­|3#Fλ’2€`Œc^9aρ;ZbK¨­.•[ηvBŽγ=2§h8γ;:θl~*Ω>·i·0γ<—YsλœνΗoZε–_ˆ†©_Πτιη˜*ͺΞVΏuύ#Ξ|S£K λw2e‘Nθœƒσ‘θzsθqΖA“^Ήβ_Γ^0’΅MN;Kυύμ-q@΄εΘΐΎP:ΰδuναjΚ€=υi-ϏΜpτθΥnŒ” φ΅ΎοQEyαEPEPEPEPEPEwF²MGS‚Φ[¨,γόΣΜΨTdŸ―η“i+²£9(­ΩΦό*πχφžu•?e²`ΛΤo—ͺσίO?έμkΪk‰·ρ…Ό?₯­•ΫΞΆƒΛΕ,η8$6œœ’sƒΞ;VN§ρVΚιšl²e8{‡ ΅ωώΞGNγΈγ­xιΧΕTζQvιsνπuπYmNU}mΏ+μzeαχίΥsΐž+Φ|M­yw oΌfIL0Άž qΤ·§ήΌ~½ΟαntΟ G4ͺ’{ΦσΙΪ2#7ΆγΕF2… =γ^†™V7ŽΕ%9ϋ«Wm>GaEWˆ}€QEQEQEW‚όN‘γRΆ_ϊ)+ή«η߈7Iyγ-RXƒYDGpη(‘α•?…zyRύλ~_ͺ>w‰Zϊ΄WχΏF{'€ξΕοƒτ©D~^ΨD8ݜμ%3ψνΞ;g½oWπ~βYΌ&ρΘΫ– —Ž1€6±ω³Ζ»ŠβΔΗ’¬—™λeυ=¦œŸdQEbvQ@Q@Q@]ρ‹BQ­[Ηι ΞΥΎ\ΰΐI'ϋ€W–ΧΣ—Φvχφ’ΪήΒ“[Κ6ΌmЏιυŠωγΔϊ,Ϊ³5„νζlΓ$‘J‰Œ‚3ω£ ŒœW½–βyγμ₯ΊόŠβ ₯Wλ^μ·υƒώfUQ^‘σEPEPEPEPEPEPEPEPEPEPEPEPτOνο[ΪΘ3l™šχ·Py$/Œη΅} \§ΓŸ‡ Η$¨λ}v«$ϋ‰γΥΑ‘Χ$σŒc«―šΗβ=΅M6Gθ.κ˜{Λβ–―τ_ΧVQEqΐQEQEQEWΝ:Υ_k7χqXξ.$•Cu˜‘Ÿ~kθnιμtkϋΈB™ ·’U 2 U$gۊω¦½œ¦?½“βzŸΓ§κ/ψ'£ό»ΩͺjV{3ζΒ³oΟMŒcίΜύ+Χ+ηΏ]?ι2όΒσˆBηλLώ³ψWЕϙÖ·7twpνn|/'ς·ψλώaEWœ{ΑEPEPEP\§Δ §ˆ4Ζ–Ϊ%ώΤ€~εχmή3ΚάuΖzΰ]]tκJ””γΊ1ΔP†"›₯QhΟ—ζŠH&x¦FŽTbŽ0TŽ#±¦W©|TπŸήΦ΄»VΌD?ω/η»π8ϋΖΌΆΎ§^5ΰ§σŒvx:Ξ”ώOΊ (’Ά9Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ½αg…Ύίr5‹τ•mνά5°θ%p~φsœ)؞όpΌαIόKzΔ±†Β<ιGSŸαQܟ^ƒΏ`}βΦνma·JΓ ,h€“…Q€2yθyY†3‘{(=zωI‘εn¬Φ"²χVήoό‘-Q^φEPEPEPEP!ρRτZx:α3 {™)۝Η>ΫU‡γ^^™ρͺuΦ›§«H6#NλŸ‘·ͺ~£k~~ζΌΞΎ-§ΙA>ϊŸŸΧφΈ·‘I~Ώ¨W>Τ†―‘Xί‚₯¦ˆΪΗ <ΰ0"Ύn―Yψ5«‰,ξ΄™YŒ‘1ž,±#aΐ`08=yήxλQ™η₯ΞΊpξ'Ωb'΄—βΆύOJ’Š+ηΟΈ (’€ (’€ (’€ (’€ αeψa‘Όλ5όjΜHE‘p£ΠeIΗԚ)֝/Ψη―„£‰·΅Šv8/ψUΊ'όύj_χρ?ψŠ?αVθŸσυ©ίΔβ+½’΅ϊεζg?φNώ}£‚…[’ΟΦ₯ˆ£ώn‰?Z—ύόOώ"»Ϊ(ϊεζaύ“ƒŸhΰΏαVθŸσυ©ίΔβ(…[’ΟΦ₯ˆφŠ>Ή_ω˜dΰηΪ8/ψUΊ'όύj_χρ?ψŠ?αVθŸσυ©ίΔβ+½’WώfΩ8?ωφŽ ώn‰?Z—ύόOώ"ψUΊ'όύj_χρ?ψŠοh£λ•™‡φNώ}£‚…[’ΟΦ₯ˆ£ώn‰?Z—ύόOώ"»Ϊ(ϊεζaύ“ƒŸhΰΏαVθŸσυ©ίΔβ(…[’ΟΦ₯ˆφŠ>Ή_ω˜dΰηΪ8/ψUΊ'όύj_χρ?ψŠ?αVθŸσυ©ίΔβ+½’WώfΩ8?ωφŽ ώn‰?Z—ύόOώ"ψUΊ'όύj_χρ?ψŠοh£λ•™‡φNώ}£‚…[’ΟΦ₯ˆ£ώn‰?Z—ύόOώ"»Ϊ(ϊεζaύ“ƒŸhΰΏαVθŸσυ©ίΔβ(…[’ΟΦ₯ˆφŠ>Ή_ω˜dΰηΪ(hzM¦‰§GeaΘ—’O,νݘχ'¬0~Š+žRrw{Π„a«$QE"‚Š( Š( Š( Š+ Ζϊ±ΡΌ3{uœ―—Μοn€rΨdΥBrQ[³:΅cJ€φJη‹xβω5/jw1lςΜΎZ²8u`€ `GΉό{ΦWΧB*Q]ΛκΤujJ€·mΏΌ+oΑšΏφ'ˆμοΚΑ»dΨ'ƒ:γοcΤ Δ’‰ΑN./fjʍHΤ†ιάϊŽŠδΎjΛ©xVή&“u͟ξ$S΄£ξΫp2q’§3]m|•ZnœάCτμ=xβ)F¬vjαETQ@Q@Q@qZ‡ΔΖώζ[kσ$΄LV4Α*H8ωϊq]­|αβ―ω5ϊό›C5ί€ΓΒΌšŸCΕΞ±ΥppŒ©ug©ΒΡ?ηΧRΏiΕΡ KDŸ]Kώύ§^3EzΩ”<ώσηΦguχΝ KDŸ]Kώύ§Gό--ώ}u/ϋφŸό]xΝfPσϋΓύaΖw_qμίπ΄΄OωυΤΏοΪρtΒΡ?ηΧRΏiΕ׌ΡGφe?Ό?ΦguχΝ KDŸ]Kώύ§Gό--ώ}u/ϋφŸό]xΝfPσϋΓύaΖw_qμίπ΄΄OωυΤΏοΪρtΒΡ?ηΧRΏiΕ׌ΡGφe?Ό?ΦguχΝ KDŸ]Kώύ§Gό--ώ}u/ϋφŸό]xΝfPσϋΓύaΖw_qμίπ΄΄OωυΤΏοΪρtΒΡ?ηΧRΏiΕ׌ΡGφe?Ό?ΦguχΝ KDŸ]Kώύ§Gό--ώ}u/ϋφŸό]xΝfPσϋΓύaΖw_qμίπ΄΄OωυΤΏοΪρtΒΡ?ηΧRΏiΕ׌ΡGφe?Ό?ΦguχΝ KDŸ]Kώύ§Gό--ώ}u/ϋφŸό]xΝfPσϋΓύaΖw_qμίπ΄΄OωυΤΏοΪρtΒΡ?ηΧRΏiΕ׌ΡGφe?Ό?ΦguχMιχI}amwaρ,ͺ`€ΐŸ~jΕexSώE}ώΌαΠjΧΟΝZM#ξ)IΜdϊ€QEI QEQEQEWόcΥΕΖ§m₯ΒΝΆΥ|ΙFβvŽ™ ΞyϋδzΧͺj·πišuΕνΣm†.ά€O ξOz‘_8κ·σꚍΕνΫ–žw,ά’ $ΰ ;+ΣΚθσTuΛσ>sˆ±~Ί‘εΏ’ƒϊ•(’Šχϊ (’€:ox‹ώνm^v?aœysŽNx|€}±Φ½φΎ\―lψYβ%Υ4uΣ¦βςΕδ‘ϋΘϊ)cξŒ)όy―4Γέ{hόΟͺαά}›ΒΟ«υ_―ήvτQEx§ΧQ@Q@Q@|αβ―ω5ϊό›C5τ}|αβ―ω5ϊό›C5λe?½˜βoαSυ‘—EWΈ|pQEQEQEQEQEQEQEQEQEQEτw…?δWΡλΞύV­exSώE}ώΌαΠjΧΘTψί©ϊ–ψQτ_QEΑEPEPE›β^ίCgΎΊeΒ)‘l λΙϊqΙθ)Ζ.MEnLηqs“²Gρ‹]Q’ΫIι5ΞΣ|!ΑGχMymO{u=υάΧWrg•‹»žδž•}VŠ‘MAšγρo^U^έ=:Q[œaEPZ^Υξ4=Z λV`Q†τ "g”=x?N8=EfΡJQRV{ ʜ”ΰμΡτΞ—§§[ήΪΆθg@λΘΘυδυ­WŠ|2ρOφ=πΣο^4Σ_q‘ψς€ΖgΠΰž#>Χ_/ŠΓΌ<ωzt?EΛqΡΖΡS[­Χ˜QEΜzEPEP^)―ψ#Δ7zφ₯qo§ο†k™$FσγRΔƒ‚ή•νtWF<;nNv_O«v†g‚ΒβoϊδxΏψͺ?αρ7ύς<_όU{ΥΧύ«[²όΜσ?Υ¬/σKο_δx/ό & oώG‹Š£ώΠ7#ΕΕW½QGφ­nΛρ0V°ΏΝ/½‘ΰΏπ€x›ώΏω/ώ*ψ@ς+«9Zˆ›r:υϊnυξΎ ρeΏ‰,φ°κ1.f€t#¦υυ_Τb| ¬ιχ·:uμ7vS476δuνώ#±‚8LV8ˆφ}ΟO,Μ§Ÿx½ΧκΌΟ¦¨+αŒΣ]‰l΅TΥx=ΰτoQψŽ2k_9V”©IΒ{Ÿ}†ΔΣΔΣUi;¦QEfnQEQEΙcI’x¦E’7R¬Œ2 ŽβŸEΥΟ›5ν2]X»Ση;žΪΉz«`Œ‚;f³λΪ>(xZMbΡ5 >&’ώέv²)ζHΉ8»r:g'©ΐ――©Βbzj]zŸ›ζx`«Έ}—·§ό’Š+€σŠ( Š( Š( Š( Ύ…πN‡ύαθ-$ΉoήάsŸήdpHΰΉg½y·Β K¨κPκΧ*ΖΦMɜζYLc°89ιΖ9ηΟ^gˆζj”^۟aΓΈMFAΑΑ8―ŸΔΰη‡wzηάeω­j²v—oςξjQEΘzEPEP^mρΐ¦ν5mYXοšΥTγ€σq’K{π}&ŠΦ…yPŸ<\fž2›§Qΐ>\’½χΕ ό@Ο<ΚφχΕp."<œεθΓ§‘ΐ"Ό»^π΅₯Νϋ‹wΏ› %²–n§AΘ8γ3_ACJΆΩωŸΙq8WtΉ£έ~«‘ΙΡEΪyEPE³ ψkUΧ$Achζ<Ξγlj2;»γ=O^*e8Α^Nȝ)Υ—-4Ϋς1«°πO‚.|BΏkΈΫiΚΐoΗΟ/<„νΖ1ΈχμpqΪxo᭍„«>­*ίΘH‹aXΡϊž8Ο8g#ž;σΙΙλ^N+3Vε£χŸM—pϋΏ΄ΕνόΏζΡ^ΒΞίO³ŠΦΞ%†ή%ڈ½ώ§Ύ{Պ(―ΆέΩυ©(«-‚Š( aEPE εΤVΟqw4pΐƒ,ς6όhJϊ nΪ²jδ|gγkOo΅…~Σ©ΚΖ>δdτήsžœΰrqΫ Χ!γˆΣ]΅πϋIo,―rFAΣεώθӦ9σšυπΉk~ύo»όΟ—Μ³υ Βκ›§ΛϊϋΛZ–‘w©έ5ΝύΔ—7ρ9ΞIΐ‡'ΐͺ΄Q^I+#δ%''y;°’Š)ˆ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*{+Ήμn£Ή³™αž3•t8" ’“I«1ΖN-J.Ν«αo‰‹#₯Ώˆ‘"Oϊ\jpHΙΑδq’8šτ›K˜o-£Έ΅•&‚A”‘C γƒυ~σ hiΞ££ΜdΣ.ε·-‚ΑNUπ”πq“ŒŽ3^f#,ŒύκZ>έ?ΰEβ”—&!s.ύΰZŸIΡ^c όRY&ςυΫD‰YΈšΤ¨ T’p99žœW‘iΊ₯ާ™§έΑr‘U˜Fΰ• 27ͺ}ŽΌzΈj”~4}N0ΓβΧξ₯―nΏqrŠ(¬Nΐ’Š(’Š(†££ιΊ–γcmpμ†=ςF …η€έGSΠρ\έχΓάμςcΉ΄Ϋœω3»λΏwOluΊΦκSψdΡΝ[B·ρ ŸΛυ8/ψUΊ'όύj?χρ?ψŠ–Χα–… λ${pƒ9ŽI@VγΎΥς5άQZ’κΨvGςγpΨ9<ƒ΅ζΎ!ρn――nKˍ–Ηώ]αω#νΤun@<“ƒΣέC/«WW’σ#ΖΕηΈl=Τ4ΌΆϋΚη¦x«βŸ¦!‹Jhυ ³‘•oέΗΖA,8nHΰΗ$W”xƒ^Τ5λ‘>₯6ύ™ςγQ„ŒœωrrNIΕeΡ^Φ N‡Β΅ξ|–74Δc¦νΛoψ!EWQηQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Mis=ΒΟi<°NΉ $NU†Fη‘#ρ¨h€jΜi΄ξŽΟFψ‹­ΨlK—Žϊ΄beΓ…pΓΉΫwσΟm€|LΡξΣ‚Ma(RNε2!9ΐ¨ΞqΟ*Ϋ>-ErUΐQ©ή‡©‡Ξ±t4Rζ^zΑόO₯4έgMΤφ>ϊΪαΚy›@\/•κ:Ž’―ΧΛ•―aβ]jΑ’6ΊΪ¬CjF@1Œm9\cΪΈg”Ώ±/Όφ(ρ2Ϊ­?ΉώόΟ£(―²ψ•―ΫΔRcitΕ³Ύh°@τω Œ~λf/‹"A6Ž­ s-ΞΠOrӁν“\Λk­•ώg£O?ΑOy5κŸιsΥ(ͺϊeΟΫ΄Λ+Ν›>ΣslΞvξPΨΟ|f¬W N.Μφc%$š (’ΒŠP+ΝυO‰ί`Το,²<Ο³ΜρoϋN7mb3œt­hΠ©Y΅M\εΕchαu₯kω7ωExΝίΕ f_9mνμ Fάμft§$ΰ‘τΗ·jΓ½ρ§ˆo"ΝͺNͺva ΟΥ8η₯vΗ+¬χiUN#ΒΗαMόΏΜχ«ΫΫ[„··0[F[hy€ τΙοΑό«™ΤΎ!x~ΛpK‰.δWΨVή2}yάΨR8κ λ^,4―,HμYŽKΤ“άΣ+žUρʁεΦβZ”υΧό@Υώ(jw*SMΆ‚ΙJœŸ5ΑΟ$γ`©οψqšž©}ͺKζj7s\0%‡˜δ…Ο]£’aΕR’»ιαιψ#cΔΔc±ŸβΝΏΛξΨ(’ŠΨε (’€ (’€ (’€ (’€ (’€ (’€ (’€?Ω endstream endobj 15 0 obj << /Subtype /Image /Width 400 /Height 397 /ColorSpace /DeviceGray /BitsPerComponent 8 /Length 17 0 R /Filter /FlateDecode >> stream xœνw`eϊΗw7…Π€’‚€ ‚pœ’ˆ`‡“Σ‹"Q~bl§±—OEξ”œν@EΔ*-€…`EŠ@(‚˜@Κό²3[¦ΌSχ)»Ι~ώ~gžοϋΌΙΞΜϋ>ΕηK’$IΒίϊ”~CœŸ_PXXTτί™΅ΌZT4©πΡόό19ηŸΪ6•[_=‘νοž0eφ’]Υ’5ϋΎ[ώΞξΦ―} ·δ:IJΧ?=πό‚oΛmVAΐΡM‹§=<ΌG:χ κ ώμœ‚y+έ/„Žσ s³“,1ΡtΠCοοˆy%Tμ[ςψ­Ήg•ψ³σ¦o„\Š(;ζεχKώ|Ή‘ΓΝ3Άβ¬E˜=sο:•{–‰Α19E?αEdMfζ΅γžmœΣ+Ώ8φ'· ͺWJ~ͺ˜pςCλ)Χ"ΜΦ§ϊϊΉ§τœΌ‰c1φυK.‰Š%|‹‘°urrI\j·ωAΓΧγ[qϋ‚ ™φ@°¨^˜S―Ÿξ­ςΏα^=; ;q{…‹>/βφΎˆΚ·/ p»†ž΄ά5܎7gS~snΠ’ ”ΫηΦ”M>ΫGtt˜—?TZŽΞμΓν'²_ͺΰφ΅3jζυηφ>=r»Ω +‡pϋ —σjΈ]μ’εΉ}†G·™ρρ!ξŽβά~Γαψ玠ω¬lΖ]―’έΌζνΣΉ}O“‰xϋ"nhδk΄νφ’T==‹Ϋ°ψ‡γΉλΐΝΑ=§|΄ϋΛΊ§·ι½ΟS_ΘϋMχβYPψαά^„’νKˆρΚίν0< ><…Ω‘ €O8ˆθ£ηB["ڈpτ©ΔίΦκ»ΣCE‘3½vU˜V’μΈŠΧ›±’9υϋovxcόL+ήοΐκΠΨΈt3ͺoΦ7 zՎ†ύy‰zΞ~ό<\Ο”1υ%-«{2:Υ;7μFφΛθ¨-τ·] εχ¦ρΉΥ#­ήΖφΚό¨±κ}±/ΊρyΦCχ`»dΏ*φΆ5Ά1εω‰tƞ1[ύ•½Nθ֌Ό“8y$η¨―W§:΅Ε·gdΟP6»"₯€"D}°Ϊdƒ¦7ας± ڐΘ.ΧΨ 0s­οΞδdη\€ύ–«p±Φκ&£FΚGρxΩ1ω4ι4«uf? ±*’(ž33^ ςα)Dv|ΏοY'|A䃽:Λ7±΅7‹³νŠyΠ‘αI½ιS¨,‹¨ΜηπΆ-wAΤbˆχπBf[Δsρ—5’BψΎΞh~uο75Jb₯eθCFϋ·šρCzŸ[pꩬAxZwji<=Υ³qΟulIψ’Rˆ²K¨½nΚΐύ€3Y€α!R "*σ¨ύnΒπ£΄.эVƒ‰qq²>†z3οx‘ŒO‰Uˆx6©&P?I·‹uŒqy›ί0΄Mγ.@ηcZ–Ό+VΒ]\Ιƒ8βϊ_‡Κ¬,™h’eΆ››¬Ξ\€£ŽuAΟβLΚ’LΔ uq5™'`=υ>ζ;4L™†4'KΞ5Q“ξ|kΣ±Ύ{Πτ­ΰ Ίΰ₯ˆYΡΡLΟΏœήαΰ©>ί'x??†p’ψ‹π¦dA΅il`o‡w¨ΉΒηkˆ™Ώ€ε:„ω'βŒ,(3Wδ°"Jπ…ΰBT0β>Œ:#sv™KΊΥΡ V§β«ŸM~ ςWά ™σ“Ή¦&N(+䬳YΘ*©δVΆύν U/:ΈώoςHτzSIχ²†σZψBV_ϋΛΏ‘σ?ΣπJ„y‚h)‚\BZ΄XΛr+a_Ω^”μ‘ΐΎ‹d)‚τEΩ‹sΘGVΚlŸθs•q}„ΦΟ8‰&$Τ“νD…¦eΦWŸ¦Œ»”BιQš@ΗΨ(xc­£υ·,ΕύΧΩΕ4ωΈ»O²Τ C*Z¬μeιCμbΌj©Ÿε΅Uαxt’xΖο2ρΧγy4υΣkο>ΨΆΞs–κόίZ];#<Œ*°œϋπΔ ~C΅όΨfΤΓΦϊξΆΊ6R‘’,ήχ δϐ‘˜ί}ƒΨ|:ίf-°­Ε«ψŠΘ(ΊψkAμ έPC¦ο•m€Μ΅τ'‰‘£ΧFε+7§ϊ2Δεhφ=ͺφ·+Λ­™G…ΉΜτΚMΡ`ƒΛΑ΅›R†W₯Ι?\ιί…μdY%―Ϋe⧚Ύάτ{υf¬A;Q¬Ό*\ο*‹AΆ§‘7Ή°Z·ΥCΎӐ–£?ϊΥ‰aSΣM‡TΨΎ°t5yεX€ΣibΖ ,Ηq;Ρ…>l+sŸΩν…._9Z=.*ŽόήLj €!Φ€ sEΔΪ8³!οΫ+!Ό°BσCgωΚΞ6„œΟΗt_±–fΦ8gнΖΒξ ³4cˆ#•ށ^ ίΉفͺκ“!·;Π*|ϊhΏ[,?γΈv5|ΝH2nr£& N>―.\W‘ „:#‡O†]WΑ±žΙQY4©¨λd ;π³ρΊωΪ!-¨ΟK@ΏBˆκwͺ»m€ ;GmTQδΰu·–³ŒκΫA‘ΗΊV_΅Ύ”eDšΫ«­f‰>?-Ok£NAΦκGό™`:ZΆ΅„Y b,Έ–£Ϊμ"Ρ3λgŠΡ_χ˜~D‚ωθxd1|ΎTM7iνŠ6a―KΤsšώ:γ…ΰ™ L3ͺY¦δ"­αTA‹ΣΎ(ΊNκεΖsS†T’±―†Ο—G¦wΊΞςK†ΑΤZtρˌ#MJΝΏc\Š νmBšω?ι‹ #ζ % Π₯£ έΠΝ+B @DΝ— ŒΎύbša—χQΗ²΅Σƒ#ή$›W” 1w=²:¦ΚP΄θ-ύ?:Φ­Ωώ<ΪX0βt3‹bcKsΫx(8Φ¬]νŜ£Ύμ3ш4τ’ζŽd{_‹ Οj5Φ‰ι¨a‘‹£'Uύ[χ/α–"˜Ε1dNWƒO’n5ΪN;βyΥq?ΉΒNσ?aΉV¨Ε!vΑ‚ Ά€u)ΌΧG˜r·υƒ˜y‘²%†δ[7%bf³@ΐH͈7ǞͺΘ“²;ˆ±―<θa! ·Ό±Jkw™¬RՌβ£)uš iΝ’WTήΡυB„ =Τ΅’σkΉKΙΫΉΞ¬£όOx¬3&ΜΙΖ`qTXeBΣμ"Wς£τ«Ν†tεIK=ΟεB„ΐΛτ!ΞΣToœ}Υ™31r‘ω;{€S σ™§wή3hxΔE·―VXθN䌹ΒόŒw ι# s7λ°pā έU#ί'VœΎΞp6¨b5ν$Cόθ‘_^oΪ §₯EλπT·1##<W,]I:Ι7Ή›JΚΰ΅άg"cmdΔ·3ΨΊp‚Υ ΪΐΡ0Ϋ]GœM¬Π¬Σ‘N"5¬ ]8Ψju`\—Ώ½>_1­>γήnˆΘ[R…λπŒΧCWZ—ΊηiuTκrΧ€?±Ύ3!‘-χ9ξ&PΛ?” mBθϊπT*rωίn’CFW3!‘3Ϋ+έMΐ©όƒΝ0ŽsBIΪακ Bύ«ϊΉ©’πΦNχ%πBρBοΩ λŒ_{I„>Xΐ’ΕΔβξ0U τUκόδ}SΨο`ΣδLjQ6Q(F»KΑGλ‘jΕ: A ΙsδϋΕκrK»ΜFZD=ύ f‘€>†”μmΈ ά{Ί €/ΒTΛ_ΝυΜ Φ2)V[Σ\’s3ώ˜ΓΤ¨ε[S9¨έ Dœ³Λ­9`Όk€eΛτλOΤJvΰώ\Σ;ά冑τωcZFώsε&Ώί³₯žΖ§r„bm0Ӑ43ˆ»όΣQ}Xζ…ό9M¬…ΌBΧ!τnW‘ŽuwΑΥφͺαy@¬…²vŒŒ— Cw \&"5ΑμSoΖJ±–φWΒ".σIf₯Ϋ+¨JΫͺ©ΦUμf!,5mbwΈVΉ΅B •b)žaw#2ΰ(R-FœEϋ¨θOν… ϊBž2δ‰tŒέέΆ˜–Κ0#ƒγR*uoDUυ8Β₯·ΑeΞΊ/š•KΚ™Fδo»1ζBδij?Όρώ›ZΓbrW;‚¨΅†A1ΛΖΘΰvvυΜΙΤ~Ri(uۊ<  V3)δΟΡ †‚Ν€₯ƒT7γπΆΦP{"H^ΕγΤ Ύgp΅#^£φDCΨω>Twp„}’°9¨ΛI’ rUŸ€’λ©=!£ϋ‘.―$Iη³8Ϋτ’Kr!Οα¬6ΌαΕ YԐΡεvΞ’ΆΏ™ΕΧNpμ`ι[”RΫ„ΗΩNΨBν M’d{rσ/py۞Οɝδj τ#ξηςΆ=σɝD³₯x/ΉyWqƒ΄ΌLξŒ SK &υV‘„ςœ$MΦzϋρΐœ{εArg©R₯₯Ά^S%\Θ T‘”τΉΧΫωάm Kց¦VΓrγVYAά\Kξ Uq™IδƝΦFγΰ roΘ¨Άάί'7nW—žκ}RiTΑδΖέW¦ƒ₯PC-‘Φ}…ζ79nSΣιΤ°€γθm;+ΘCzwΘD*Cc?šΈ=­υρ­GδHŠΌb’$ΝζtΈ »C&RG’α³κU¬0½_EK{Π6”YΔιp˜z|I«Β>’·ύ5§ΓmΈ‰ή2{Γ~€·½Σα6Ηv„ ElϊΔ”ΗρώξD{ω8„>@šs؎γσ—8όd€b$Ϋgρϊά †Η©BŽbŸ₯vΉϋvidgΒ„ΉE±‡m‡eΥόΖᏠ‘˜›\Ϋρ»Υ‰Γ2O)XΞ‹γχ„εηB&”†ώ‡ν#.ΪοΡς―˜ΚbβŠ6ULΐQϊ§’7™Σ™ΩωςΈ|!ΣEΦΐp\«p7³σ|Θε εΐ–ΌςU˜uqχI˜Ιφ·)£€H‘'«E@mζεϊ[ή~p°ΊτdοΎ2π‘rΛ|ΐ[~ͺ›f»?>ΎΜξΧλ`{*§›“΅ίvj5?ΞΌη’Vϊ ΗΒψM&””?π–’`G*­χΨΧ6Y]ΙΟ³-'U΅αΥρΔύ _N­ά΄Υ„Y“¦ύςη™ ίhrΧ™ΞηpρδάμTΣ A·XVξy.δ=w¦™Ο:ν¬±―ύ$Ίhs6a α–jΕE7χΆiιϊHίέά³;δ=mю½’p‰‘νϋ‚›«PρڞW¬˜rc‹Ώ¬0©; ]wƒrΣ6χ '1XO£Χm―hknύ=&‡Ζˆ6!iל η8mt [Z#t\š ΊQPε4j€υΰ‡ήω9|U c~gΚ°Šς•“‡uqs)la½pΞ1θ?τ΄› ΅Ήδή7ε>Ζe§ΈΉ ’,ωαQωΥΛcΞrπ ₯‘;μ–WΫΠma·tλ‘τμάΙΕίdΊ½ ††k~™W“νιφ"¨γ~ ίx£ωO~i*l:O»ΣΜίfmh›©ώ7ΠΫJY_–ΉΦo‘7!Πt‰’Ο|\± Φm‘ΰθuί֏θ:YΒ7ξ |ci§›¨H‡ξktUψΞiΠAφ›Σ9Ex(|―Θ­ΆμŽzπ’^U/Ί—ΏϊΦ›2zІ[‘}v0zοg‘ο-=Βη(šνvيθΝΑΧZ*?‘ΟU$³Υ25zσ~ΰ7ΧΆ «{΄ƒOP…4E‹»\Pfΐ;μ<Υν7Αί~ƒΫΝDβ|xIκύ;ΐ »w²y BΙM…hψ§“$ύΪ‰Λ]θ`t`Σδξ]`@Zΰς2ΗDπ–ζΔϊ’4†ΛaΘ`όΊKΧ«-€"> 8p—ΗPΑι‡wͺΖN•xΛg‘%Jώλ^mT9Ζ]ŠλڞΑ)·―ϋΣ½ňt¨Ο1-‰ϋ΄VŽAͺ3΄ͺ„t8€γ¨ώ:;XeΝβ«”π£ …#ϊ ¬²šΥƒXό†ΕHnϊ\o­αξ,ΡΌ”σ*ν'μ ΓΟ^—…Εu'Ϊ€Z-qcψ2^ΩςΈ¬[ι…ΐ{h>jg0φ*š­κΊr˜Ϊ¬c½ΡΨp4cRiέΨ7Ή―φ¨ΰ-΄baζ5u!ά€b_© φ>Γ3?E1ΌΣ6KFC™θ«ΉΟž$έLξ?`―FτΞ‘EΧ<άPޓځ° )ŸŠ»1MξHθΟBtLίHβ1,*–'ςΞβ3¨Ω 6:Υ¨4…Φ… ·ΐ{JlυXδΪώqXέ£+Η 4±‹άh­f_‚‚ά2g—YB)FXQ[L‹Bg²<­—œgΆΎΈ₯ΥGΆ™‡ ŽβΦV±¨@ܜ·IύδσυπΝηWΨbU^u$·ΊϊΗ“ΛαkYΑ-―ήqΆΥzψ^α–WίXkΉΎσΈυΥ7n·^ίnυ‹Γv ‚ξβVXΏxΥf9|™Ι':%ϊ0j#¨“I΄˜œD©Δ­±>1Α~=ό?Ψί& †v ξΓ²>+/Ay Λ#o9X_‹CHΦγͺΧ  λKFθνΘ_?δJ—υηαμφ ΅Γ«OΜυzκ!"υSξι$:₯­—Γηλ\Ζ=‘Δ¦Ί' F@o=ΒeΈ’u4bΰ«ΰλΡ₯nύ ’ψrψ|}“•Ό2 a9|Ύ1άΣJT¦’,V§ι:O1Τ>‰žŒUάSKDv»ΛLsC‡=ά“K<* -‡Οwar#Λ-Έ»ΪrO/ј Ήme$e.²ώa9΄όŒ;/™7nΘXŽ;X’)½€»[π»όe~‡:ƒnθΠ‚U Of6Α :£φμC0i˜s©€i4ή―q’L!B&βT€›ˆ&‘‹ΨοF’9„8o&’¦ζHάƒ7 ψƒKΠLΗ}ΣUγm‹Θ&!σ$ΪD–zK’υ†?XΣ8@χWdΦ<–Ζ–ηα–΄w°&‘rώ_f±.“r΅€ΝCš‰°7;}‘&Q{^[‘šy‚Δ€;εο8sψ³άH£₯(s9нγ£§;ΣfΌ+šαO]C7ƒn((νB7 mΧaLgέΒΠΏΗ{ύ…Xi†±Ω[s •όΖ{δt"•|ь"Μ¨ˆJύ-βΏ?J½sΰ§TAt@89ψΪmέPh2ΎC‘‘>^ω:ξεπωR^ŸΥ’”F[Α…/oF!ά„ω…nψMκ₯ρ°΅Œ«†žΩEψ’;VfQ˜–Ž―Ϊ#O !>_Οΐ’₯BڝiKϊBŸ©c… G€~Χ=’‹­Ψ‘λο{­Αιΐ1ϋ1£B½ΠxwρPWL΅MΏ‡U»©;¦ZO4Ž\ό’1žV?PΕ‰0kΗΣκ>l°υ"Όgϊ³ B₯ηρί>©γ/” @" šΒͺ LTχΫ(Xu(΄ <ω4!σ]Hm_Q€ϋ+ΰ€ΛΗΑ »ς·ͺ ξ«ΒœΌpή+@_†)H?ΗΫ‰ Ÿ…|‰)9BS׏%IοQ'ΦΕΘΐ퐳Ÿσ†D“ɐݗ~―έ\'΄tΨ3*%&5ƒn ~q“HΉl €ΆŒΛπ*$ϋ€’ƒyqtςδ†F… ;Œ;σ=}¦δΒ†QΞjν':BΥWΨVΰϊ9l,l#ή½#τŸC!-ΆŠYυΒΥ‹όƒf‚nίH5E”Ρχ(τZ κ‘Ϊ’’!ŽrΑRϋ?ώ °ιc{‹0πšΏ½ϋ—ή–&ξ#gμƒΆzπξ8=wrKγ‡CϋF’*>}fxoA–^ΣΣ―*ό‘Zpυσ φhEϋH%™υdαω·ζεεείS8ιυΟ°Šy,>“Ϋ‡°τ\‚δ(Φβφ8λ C΄ΘΨy§ηOΡxΖ?d ·g½°=/nβr‘ δ$άȎΊ»A9ΐ‘Έμ‡•4»™ΫΛNΩϋhKnoQRΜνi'lΘ­ΣΏTzMχBΎΕC°’#γ“Ξ“Ασ“ΰ¨šŽΡ "Ξ9ajaLο~Ή·ox š y¨ BΝœ:ωρηvωΉW@ΝξΒ“Ή=ΒMϊΜΘ3΅udC=F²Ζ.ϘvΝΧ­χ*Zζ΃ΙvAMρ8ή20ρΧ’$Γ”γFΏu€v1ΚάI]Α?±τΚ_Hτ\³ͺ°_Β„¨s’uΣ›θŸŠeά‘όΗpA֐Βb€χΰš’’άNάσKDZ )\\Χ’jυ”λxͺ±Φ²†δO/Ψ )™Y0€SςyBσsΗL]²Ελͺ”˜vΧ…ό•τκι' ϊσΔ+w:]‡}«g=qΫεέ)?ΤKRZŸ|φγ{nζΒ…Ε«VmάΈm_-;7n\³jεΒ…³_(œ0jθΉΩmυxοΕ’Α– endstream endobj 16 0 obj 15970 endobj 17 0 obj 7670 endobj 7 0 obj << /Font << /Font2 12 0 R /Font3 13 0 R >> /Pattern << >> /XObject << /Image4 14 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 18 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 19 0 R /Resources 20 0 R /Annots 22 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 19 0 obj << /Filter /FlateDecode /Length 21 0 R >> stream xœ­”Νn1ΗΧABκόίΘΡ‘Οά LήΔε’CrΩΛφKŽQ^ΑΑγ·—πf‚< Κ³ω›Ν\Ιιΰ‘œ^[ωžC·P=Ζc]U7ͺSό.&=xε8*w™ίYΤΑ˜@K»θφ |#ΩΦ0[w‹2•x_¨E(,’H4γ5ˆ1ΨΚU―k<ήšJ,Ϊ:ΚΉ™SΧER.LI…%R6j‚σθu˜ΥΊn}«am"Ώ‹UΏ8UΒΗΦΟβ“°+»―ξ±6NNΤmnNUΙΓ?z`M=:Pmqήjσΐ™Uβ/8–•e#ͺw.xΙ¦%,Ϋ"±V³. „¬cζ‡ζ¨ήυUΡύΤw‹ ;Š w_ͺ> 7j{š˜­&τΈϊΜ;@|ςŽ? γ΅„ΟsHΏμιͺθ‚τ+Λ“*13ΌR΅[ί™ή‘κpŸΩ˜¬`ξ°Αώ‡ }Ά φXν«=―€W{’δνϋLΪcΒΥDώϋ(ε |Π endstream endobj 21 0 obj 594 endobj 22 0 obj [ ] endobj 20 0 obj << /Font << /Font2 12 0 R /Font3 13 0 R >> /Pattern << >> /XObject << >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 23 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 24 0 R /Resources 25 0 R /Annots 27 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 24 0 obj << /Filter /FlateDecode /Length 26 0 R >> stream xœ½VΛj1ΉˆΎ!•M\ά‰4z]΅.Z(]4 ˜–$'­ΣBvY•ζSE)ύƒ.ςή%+/όιΉ3™Η3ΝΓ8±πŒtηJG:η^IC.cΑ©<Ι+ZΌ?μρ!±2΅ήyΜΆαD―=¬qVdέU#Ζiͺ ψLƒž»ό-ίȐ―?|Ων Ύσ ύΧJ#V"υB₯ŠμΜ΅Λ·σ7(Γ)$™!eΓJη ­άXγ}œ¦ΐHR-…šΆ *›tRX=ŒEίi[ I ΚμV΅ŒΪ’Aomco”HΈΤ>6‰3ͺς)ώ˜θσpΐΧ_|ή¦x’aΫWεK‰ ƒ2όxΘυ ω;ΎmEΆΉΙ^³εθœ…Φίθ,:e!štΉ€nkΡΈ5bmΦcΆLŽ=rE#j­΄Fp^νr%2Χ ΎΑες3 hD§v₯uεοyxΙ7Β<σ7ZΖ^[­W±ΦεαŒΡN@›δ?Υ;ΠeπΠΝ šKg ͺ“I€EΝ#t―a˜f ™Δ&Ε –§³HΡq…•ΊΔ蔐ςραϋDήm—£h=³($ύt Ήψ}Φ†zL°\Bu/Š0 έ3΅_‘¬R°L9"nθS'‹•ΐŽrε'›Pι^¦Φ =Η6ϋΥ&n ¦]£θήĐΚ=„5˜†LαΩΥSιUζδω΄FρyzvΉΞύOYD}ζ@ΞzλU/χ'3"Α, Iπƒυ³MμθrϋyέGΗ΄Y²₯θŒυP«¨η>Sδ/dζΪŒ£}Iχ¦G"ΥCθQƒ!=ž–Ϋς!ސ μ°ΜŠ Ό7βOθ΄MCΏ-œA²M4$Ν{`Σb‘ϊ†·ΐ̘hͺmυcdAΜ·i?Κv£’}xτiΛ‘#£΄"δ‘ͺ£S)εdᙐjάΐΌUυe•<έpέΊωϊ'S‡Ϋ—QΤ χ?+$ͺIiT&­•ΙMUΟΚ6οεN±T©Έ|ί‰½„‘οξΎωšƒπ ‰?Θ:Ϋ‘:ΛΩ9τ½ΪΨ k;?¦[Έ5„ΦοΉ•½nnΖΚΨokΌ½ΈTώ¬ƒ} endstream endobj 26 0 obj 828 endobj 27 0 obj [ ] endobj 25 0 obj << /Font << /Font3 13 0 R /Font5 28 0 R /Font2 12 0 R >> /Pattern << >> /XObject << >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 29 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 30 0 R /Resources 31 0 R /Annots 33 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 30 0 obj << /Filter /FlateDecode /Length 32 0 R >> stream xœ­‘ΝJΔ0ΗΫ‹ΰ2ΙoςO΅Bq:8-Ϋ‡5τ€ ±Ž.X4Ήb?ζ"1k g½ΓΌ½›Φq:Ψ dnα6 ιa~Φ½΄ „Υ+΄ό>ͺ™‘c@ŠΫ՟P-,Oΰ†GΏCͺ3)>Vk$§UˆP“±rw†X‚VSͺ›R†΄RΣΞ)χ $…QΫΙΛŽXλƒ"Ύ$_:ΊQϋθ΅5‘ǚ£^τš¬ŽF?O|BΪΒόςyσ¦Αr‘|ςη›F‘hε €αΑ#άAU”ευ ²PUρ^•ΗeΣ3Φο+Υ4εb§†—ξ!]ΑEϊΟβg¬ύ―«€'‘ΠsXώR[‡\ endstream endobj 32 0 obj 305 endobj 33 0 obj [ ] endobj 31 0 obj << /Font << /Font2 12 0 R >> /Pattern << >> /XObject << >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 34 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 35 0 R /Resources 36 0 R /Annots 38 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 35 0 obj << /Filter /FlateDecode /Length 37 0 R >> stream xœε˜]7†!!α›ώ D75φ9ώΌlΛj‹J³d7΄€¨¬ͺvΜ5Ώ‚ΧžΜG6I•ΩΙφ¦MfόΖ{όψ=Άs%2ίΧ7V;\x'―€VZ›δ£ΣΆδΈžF¦|y'Ω»ΰu)^u .Ψ|SΙk‰ό})ς=*Ή’~¨ώΉ|­εۏ¨ς’eƒ:λ5'–ήή¨ͺKωζ;9Γ±QΪΕH·ΞGO!ίqύ±Ή:πžxˆMΡ•«v.EίSͺVρ)FS”¦T§τšΐ±ιλξtt“ΘWλΑΙIΓZΗ»LΝ‰φύ8GωωθψοχŸ9*_>rώf©±*„)HfEN<5ΉωŸςHό&NΔqG</Δ‹©œ%ŸΜo\Yt δόŽΊš§Οώ½CΖΰ Ζ8^ΓΥ(dh°)Υ)#pαΩΐΕ°Ÿ!M’h­ϋ‚ΕCqg,'² Γ+—Φn«ζƒβ\όšΏΗVœJžΓŽšnqHΐ\ΖΏwΞ—!a}²©/U„¦S4šr2tP£w 1#“EΏ –h†ΣΪ%³ΓΒΏˆεΘζβΉx:WR.qϊΟ άφzˆ‰Χi5RV Ι…5ZrsZΣ†χVσȈ‹˜ΰ Ϋ]χXœΒ\gβ%"ξΕθˆ‹*8Ο–γ5ΘLAVŽUd­“KTΐx"χ”ͺUΰͺ•―šRb[‘τ­ L##«ΙλΛQ’WΙ€”b―«^L˜Jc²ε0žƒ‰XdBΏΛωιFθ%~ΨVρ!ωD‘6©0ΒΊ)™ΎT΅ιV3βͺ\ON ―m"Ί φΑ{z"½_΄Λ£b££κ©‰ΧύςPΜέ ς‘ξ©ψ,Δ3xh†•Λ=œΛ#ρ v:CΖgΝO{Zk[CΘP‰~³9‡°%Ν:0brδΦ‰΅Z^†P[Ά§ ‡ΖœT΄ΞΈ[ƒφžγ8AΈkP}P©3 |\μUΓ㏑Ύ(όfβt ;K*¦hν­°#ΗXΝ(CT‰qΨ•Ψ˜§¨ΎXυČ*―λ2ΆxOΞΟ{§‚±T›Ξν7eν‹/C ·εE –…H‘χ-Έ]ˆŸ°a8+!ς)R…α‘ΎΞϋ…ωω ΐΉ•"Εƒ8pΰ6‚’.―αA—·ˆlΎ§T­bŒΟ; W›²λICW!˜Ύ£Λ»4X^‘fkώŸΫΎCψlkμŠmi0ƒΑHuRΥI–ΑΆ6\[²Σ†ϋΝ…¨8bŽγς¦Ι7€@Ξ¦<΄ FHˆ!K‰ΒτF’tΊξΒΈΥ† ον5N&?O₯­%Ÿ'w'χ&0δ—©€FZ.'―{yΎt;`λ1Λ»`ΒFχ§›―Ϊs endstream endobj 37 0 obj 1030 endobj 38 0 obj [ ] endobj 36 0 obj << /Font << /Font5 28 0 R /Font2 12 0 R >> /Pattern << >> /XObject << >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 39 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 40 0 R /Resources 41 0 R /Annots 43 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 40 0 obj << /Filter /FlateDecode /Length 42 0 R >> stream xœνZmo·^Α@0‚ό‡ΌXFJs†δμ·ΆγͺΞ‹¬³₯ΔΚCil§€N τοφs~EŸαήΎœξNΎσJ‡'νΝ-9Γ™‡3ΟpυƐuF_j/‚‹ψ{qiήg£"9ΊPοΈϊ7ιŸKγ%&quψ|ψΐ.¦ ssεƒώ~mNΝΟPςΖάΛό―_:σκŸΠΐϊN9x‚λ]ΙΞo~}υNͺ^›ο™cΌVτdΉΒUŒ’…³^Q’H•GΖDΜE¬ͺfΞήΙX6Ιbf—«l;ΘF†ψάy|Έͺξξ>θ_ΟΩ¦D’ ¬΄XάΡίΤ½aηη3 ˜ύjξ?ϊεηE ƒxφγrLCΆE8±7‘mIT’™΅‘›ύ`ξ6ΎyΦΒΖύ¬Ή35N,ΰ•XLλΤ<(ž5ίκο©ͺRDςiƒ¦[„v ―ψδϊ ‰ %”±h>ˆ`:·Υ£7Hv{x—Ψ{άΰ—ν²ψ5ѝ‹…6lαošσs„lΦ|έ|19\ΕF$ς½oΰήλ)Ώ­N4ŠVN%¦₯h ’wV ΞOΜΈΘ B>lΚΈš£Z|ϐq·,ΊΧd\¨πJ›¦¬ ՐΥ,I™ƒξ$Oμ` Μΐtΐ¦"W§/\>Šy«ΰߘδȐωΙ(#ϊΌψή™ϊRy―½zϊPb΄π  E{›Γ΅'KjԐΫEΟυ7θκKΙΕ€]ŒZ‘s‚)( •bΔyD[B„-@©² h„ Βώͺ`όόή΅ξ]]ΥeοςL”έmΈw­’Ru2™‹6yξ͎‘ά²@i(lIκκ…HcŸI’©o '°ήqλwπl–P‡gtϋrmΞ’@‹±ΉPT8νΕ·9%±žu±Ρ£± κ€"Ι†*Μ(͊lM’QχX˜€9S±KQπχζaη9YΙP%xT–ύ ΧΑ™‚ͺ΅H½ha«@ΡΡΒ%)«)Υ/Ω„R)#; ΒNu0X=ο ΒΘƒ !¬4‰ΗR$μ'ϋFŠ6΄FM²Θ1ΫΤtέ†:Ψ Ύ/Υ@ΐ½5πνF&oY7ζ― • gΜ{ ΅ έ¨AsŽέžj(a›NkHOi‚Ο†Ε*([#π¬#ͺαΉ‹Vο(ˆvώ ί›ΩΡ’i;|±NρΖΨΛ,qΗφͺνψΨE§ψ€§υ¨Ζ{'cΡ|eM‚mτΊƒhηsμ`Ξy4ΟΒλSΓ—`Gς˜…u:Tύ%'6²hǞ€;>F―ώ)žγϊiΫ’ώOnΡnϊXΠ¦­΅`Λιu3¬Μ\,­/& &Βn^ζϋXa‰`a€ψa]qΕηc,σmwc¬ΘύθΠψT―ώΌρ œpŒ»ΞΠόΤ;·Δσ:S‰ΝOρ peΕTενgPtZΝ>¬―?Nπ eFmπ‰Χ*»βŽύΣrœΡaf/φΓŽΥ™"·³έ4[–’kmˆΊ{φBγQ*ϊDpΙNιؐJeBR JνλήZE˜|qdθΰΑlδznŒβ™–„σ‘0†”²ΥΎa=ΘF ι6&?½Wα ^zLƒΑ ΫY3H»ΧΛ—―ώΜƒ_zLnr‡€¬W€£—κκ’]‘±hή‹Ψ₯΄ΘΒ‹q#Ιξe;‰ΠΒk?!θ.Ά;{Y·CΥP@ή/wοŸΥtsŠuVΟqύο'5έiήΓϋόnσΝύSάψ€ϋjJ E^s Y5η&ςvI¦ε€±W,-G¬—ι“–ΤΥΕΨ‘lχ y @υn-hZ%ΎΖλ1’x*­RΣω3π¨V ^ϋdδQ­=ΏγζhJ켝LŒέ¦Σ4`ΰύΚyΈ -‡Η–n©νͺl>–eΖφSVν6=Zqς‚.YΏλ³x'Ή0@4l£Ϋ2f•₯ΉΙBγΕH©,jΠHŒ§ΗςΪn€·’“\ŒνoλWΤΟ5H/:nά+†_‘ Ϊy.Έ΄ {Γ;Ι’αύm½™ύ\+»X}²yΕπίγΎMάwh–ƒο …ž’nιΆ£φuKrώgΑrr£ΛόZoΦΙνΏηφ©ϊ=lŊ·*y~‘εΧ=ζu%¦˜΄ ‰>sβ₯ ˜Pλ>m>ή²’mT£η-lzƒšΫ|Β δΧg΅βΕ¨OxAσd$™χ"Ρ‡Ύ±e(uΨH΄s·οmŽϊ]ΓΨω@ŸOδ74?πˆ(ΗΡ³Ϊ¦_biΡ|ω© #Ωξδ1b³z$)}rŽ•ιώ‹©Tf€Π" $ε€Ι”ΉζΉ²‰ua^K)y W.Ύ:4‘=RϋΟΑή;8?o~;4ά‰ΞΟ^Žξωm8œΈAλΌOVb’΄bγφΡΥΧ8χ1Ψ endstream endobj 42 0 obj 1999 endobj 43 0 obj [ ] endobj 41 0 obj << /Font << /Font5 28 0 R /Font2 12 0 R >> /Pattern << >> /XObject << /Image4 14 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 44 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 45 0 R /Resources 46 0 R /Annots 48 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 45 0 obj << /Filter /FlateDecode /Length 47 0 R >> stream xœν[mo·^Α@l ύnmΉ.M_†Μ·ςKœ΄‰,ΩRkεC 46‚UR§ϊwϋ9Ώ’ΟpίΈw{ςξNλpήhΙΞ gž΅Όώά^8νρχςͺ~Wk₯΅I!zνς‹Ÿq“όΉͺmπtތH{vrΡΤ δχΫϊ¬ώLήՏώόλν7Ί~σop ystΦ€‡²:Em“­zs#VoλοΤΗx-ρ‰ΦSrWή‡(Κ•αΰΨ3CžacˆRPš(ZJZSΠ|$3m; Alμ5>^euχδ―₯¨˜MΰR*,κnκߐσΣS 8ύ©~τδΗώγ1 δΣο¦6uQ₯@LΆφ€›ΔυikΉΣoλϋ•­^V/ͺ―ͺgΥYυ9~ŸW―λΣολΗ§7aFd”K<ζ˜m1±±^‰Ά}τꉏ―WςŒ#Φ>Fςbq–+ΫώΈμ ‡5¦h8;‚χ)†‚ ”bfΧ £FΚ¦.ΰ‚Β6y,]+φp‰u\ΐDςΟ²αHœ"qm­"―Y‡‰#όΖ\έ©Žͺ“κd=K­f½Β+xέ‚ΉΨo'ζκ)£Ή’‘Ξ€ύ¨‘²…Ή0χΜΧ†4aKΝYλ.6ξΓκΞΆv"§ΰ^L‘vnŽΝ+8ΕΛκος{[Vμ‡,―ΰ΄G—ΐ΄Ωb}v ’K%©IΪμя)›:Yhא΅ΈΙA/λEρk¬…%jν“Y±…Ώͺ..`²ΣκΛκιΦζJΚ#ίϊ΄Ξ1Ω©΅zRa­ΘΙσΔZ#εζΦrΐ!8m·ŒΈˆ ΑX·*β>©žηδ{Žˆ»f½&β‚…Ψ΄½Αz“™l²ό‚$ΙΙ^AπΔÌHhΚSVz§ςΒζ-ƒb’η΅©Ώ―ύ΅~ύ΅Ώ…ιSΖa4{υβ)ΌΠy― Α€mUt+؞LΨh°1z>Χί «O)&ε v1rEŒ Q6ΔUR΄…΅ƒσ^*(Θׁ ˆ ό*ΞψιƒkΥ»Όͺ«Aεј¨χ‘ήY¦‰B5Χ‘’ρ6Τ5!ΈΕ¦.‘2!―>#Ά&h #ΊMΔ4ψz­o Ω\n(’ΪΈ-ΥΖ°ۘ’ρβN·’ΫΘ”%Y¬·(,LV@ ¬\&F€fρl ’> ξАαsδΆυ]γώ­iX[b"Ψϊΰ,2Λνx―†2²Ψ"τ’„Ν DE X€€(’Dd?VŒT*!: Γn«` zΊ5FΒJ9X,%ΈΫ‰Ύήx Έz ‘‹>*ηDpΥ†(Ψό?eαξ­€οW0"y‹Ί1^hp’pFJ3PΰYhμG”slV8Xΰ|@gΫt»²ΑH—ΖΩXSPΙ$€­ΌκΰΓΪdσάG©χD*ΐ―λΣηΫ ۜπ9Ζ[ ΖΎ-3ΑŽνU[ρ‘φZόίι>δV΅:”€f$E ‚­υϊ#iγ> v0E‹8˜§ υmΝǐƒ-f!™Y’Δ*tεΨΐŽΟP«ίΓΥ+\ΏhK4ΐ­ B”›Φ'”i³¬9½l†₯™“’$ω₯v†l°›§Žω[,Η`‰ca  ψq^qφΟgXζΗRξzŸ=χξam9_}ψ#”pŒ»ΞQόδ;Χτη9Q!?ΙΒ₯%Q·ŸƒΡYn›ύ>Ώ~·…^L$δΛ4Λlΐϋ§Ε8E3s Αχέ†ΩΩxjgs²iΦL%ΧΚΰeχά ŒGͺp¨%{¦₯Φ!€Œ„@4ή ΄₯+²Θ$B9;°’Ϊ !ΙΛeΫΌΞl)Y“ε[΄1%­)hcοx{σ~r@¦ΆΨΦn³~2bgW˜/:­ €ς Θ6$+Η“-ς;χ¨ϊ ογκh½Ν±š™τ~#!―Ο3Ϋvzΰ…„Œ‚9„vz·™>9¬s΅pΏk‘ΖκαΊρεΊU‘ ΨJ<ΛvλUI?“’wςσ‹ϊSΕxΩaiEp•ήβθœς€c³μ"°;cΔ§rF`LIΫ9,žek5’ζ”νήƒYΑΤδm«¬T™ˆb₯(₯xr ‘kιUαμ=gcδmΘΉwΔ[ˆ›)•€f$ΰjxsΌ‚GωŠši#Έ•ΣΥ±τe΄7y£ψΕ(BΠΗR|Ža'―ΩŸε'ΗhŠfξb7 g‘…[&nΫ$7Hσkn†Y(ΗXΉ::8žtpnc3$T֜ϋV‹nKDδΥΘN$<;ˆ’˜”Φ,ˆ, ”Χ) ^§†CΆΧ¬<彆5σ„ΨD’–ΰ8z€ΎΏΙΟδσu»„Α 1”ΣΜxΧ£ΟΎyσOWύ8ψα*uXŠ&Κ0Φ‚IΌΙ€vw%­iΡ89QR?t$•a`Η_―†₯!›iΆiQ-ϋ`•Ο> ywBl "‘H½'γKjι{b0ՊζN/dP•ΘάΈA5aΥ„D9ίD1ε¨4œLIjiζ.#tγ Κζ-D<„W£m-½ddF½ήΉΫ\u&‚"žΫιΙΝΓ\jž!AœηG'Žq}„χΉ½S}„χΕύκuuΒ+»mS>£&•3©°,Ξ.jDΔΡh¦#+Αfj±&OΩpίGιƴ͍fΕ͜7~oF“Α—9―?L%ƒKω—]ŽoΧ>σ$χΔ~ΗΥσml°εΨl/Άλp Κχ,ΚaiIl ’˜Jž0aΩ”ΈΉύZh†„Ÿνη‰Φ;<]Χ|R±8μΆΆΛΥZ$[ομφͺϊuΩ‹άΟ|ŠOΩ†E9ΣcΉυ»œ³V€Έ“Έκ<hΈ Qkα‰–ΰ‚k»πHY-ΒZ¦5%- ό2ŒΠε0ΝXΰ |ή5τazΚ%~!›―Έ ~Ba2ΧHι8^4oR/  vlδrz,―=O€θ)—₯°ΓmʆΉFJΗρ²wΥ•‘mIπ«Z)Έ“³£©ΰŽR rΑ{ΚDπαΆAΜa%ƒ].?›Έ ψ»―cχ J™χτι€Mω‹u–“.σƒk½Η΅N68ΐ³Τ>7T[ι EΣbεχf>ΫEωΉ5uςμYP§Ζh‚cˆε^υ‡5ρΘJ6rbκ σ 67Mi β } @ήto—|ς©IžSjˆυΡδ§½!-Oοβ 9-°w’štžF¦m¦(Sj/ηωrf៳& _ѝ±ΉdGUδΡΟ‘ΪTΒ6lέ΄ gαs9 2―H r§<ΆIvι@\ΰIV'Fž“ΟΕ ay,‘’Gσ—‹NΖΩcgQœ΄Y΄<φX8ΦAώιέkXΥΪ~;.mnφ›#±_α)NφΉΩσ›;“ΧnOsό½sšχsš#kZuŽ3]Υ~Nuπ/«ϋ9Υ‘Υ­:Π™¬¨~Ξ»£κ£± ±υ*= ΖDΡ|8Ϋωşν¬o’L›·ΩΨ>±FεTf€6%f5ΉλŒ0:£δ,³KQy;› 1%w-ϋα#qͺ”=Lί«$ v~p•φΣΜ A'qͺ“ Ώ‚„Β.™(θ(g W΅7Ϊ†‚ c‚|+Ι·mT­§€G³*zω†—ΔΦ™_ηWΖVBηˆ•˜š³#ΰ›w°₯IΝHBaΗ]‹t96οzΤ’`RΎΪ…•¦ΠΝ6εƟΈ)*VΖ₯Ž”ρθ’ σωqΦ`œE°ό288ψΫaνΪg>w𛃏..ͺŸkκIίχό<"„Jg±ƒgΓK2o]yύy endstream endobj 47 0 obj 2922 endobj 48 0 obj [ ] endobj 49 0 obj << /Subtype /Image /Interpolate true /Width 256 /Height 279 /ColorSpace /DeviceRGB /BitsPerComponent 8 /SMask 52 0 R /Filter /DCTDecode /Length 53 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐ"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωRŠ( Š( Š( Š( Š( Š( Š( Š+Υ>ψ>O:=wT…D@n΄ŠAΙ=₯Ηa鞹ΟαˆΔG9x,LeUJ7ΩxαΓά7۟§έ\Ζ_ΛίLΚŽ c¨λλJRQWnΕB›ε‚»ς3θ³ώηŠ?θ“ρUGXπŽΉ£Y½FΑ’· Έ‘)=3΄œsΗOZΙb)IΩM_ΥΑb`œ₯NI/&`ΡE±ΚQEQEQSZΫOw:Αi ³ΜωΫHYŽNη €έ΅cI·dCEvzWΓίΕζI jUY~Σ& gΩA Žΰγ­u–?νRo΅Yζ‹o B"In:ρΖΉ*cπττrϋ΅=*9>2Ά±…—žŸž§Q^λeπΏΓΦς—˜^]©\lšl}~@§?Ž9«rό:πΓΔθΊ{FΜ€YδΚ’:Œ±yW;Νθ'³ώΎgdxoΥۊωΏς>’½ͺo„ϊ1‰Δ7Ί‚JTνfd`bFΡ‘ν‘υoTψQ©ΑΉ΄λΫk΄Tέ΅Α‰ΩΉω@δzrHλΫ­m Λ=9­κsΥΘρ΄Υω/θξyΝ>(ήiR(Q€‘Ψ*’Œ–' ΉΟDψo­ί_Ό7ρgΑCΜϋ_œ€~n£œγƒΞF+Χ|3α3ΓΆώ^Ÿe9έq(VŽ 8ΰp08Ο\šœNeJŠ΄}ηεώeΰr{ύΗ”h? uB8¦Ύx΄ψ_ͺΘ Jάƒ°qΤγ‚0xυτMα燴ΧmZς@Δ†»mΰ1 #κ ΙϊW]Ex•±υκξ켏«ΒδΨL6ͺ<Ο»ΧώΘbŽ’(Qc‰*’  °§ΡEq¦ΑEPEPEP=GK°ΤΥWP³·Ή _60ΕsΧτθ:zW¬ό,nΘm2y΄φΘΚLsœAΟOβΗ+Π¨­©b*Ρψ%c›ƒ‘‰V«?ΏsˆπίÍJΫ-κi\β™G–:τNGB>φyފ*j֝WΝQέ•‡ΓRΓG’ŒlΏ―Ό*Ž·§¦«€^XK°-ΔMf@αI6ppGΈ«ΤTEΈ»£YEN.2ٟ+\Α%΅Δ°N…&‰Κ:žͺΐΰΞ’›βU΄VΎ8Υcv£:ΘFIω˜ώ%‰fΎ”ωΰ§έ\ό»KΨ՝>Ν―Ή…QVbQEν_cAα«ΩB(•Κ³Ι€O ΙόΝx­{oΑ/ωnλυτ\uηfΏξοΥηΎ/Fz Q_0}θQEQEQEQEQE2ic†'–gXβE,ξΗ@δ’{ »’Ή=Wβ‡t5~Ϋφ©cΗξν”Ύμγ£}ΓΧϋݏ~+™»ψΉΞΒΣH–XxΪςΏεB°ϋšκ§‚―SXΕώ_™ηΦΝpt]§Q|΅όz•β³|XΦLa²Σ2Ηj²»;w Ÿ| £ρ7ΔW;<™m¬φη>L ξϊοέΣΫk’9V!οeσ8₯ΔX8­.ώ_ζ{ΕαV?όCmIΫΞω‘ΑΣδ*1ψgšΤ°ψ·|‚Oν 2Ϊrq³Θ‘’ΫΧ9Ξμφτιί²–WˆŽΙ?Ÿω•!ΑΚΧmz―ςΉμ4Wžι_4{Ÿ)oνξl€lοl #NΈδ|Η<SψΧ_£λΪV² ι—ΠNΕKya°ΰ‚J˜ ϊŽγΦΉjaͺψβΡθPΗaρšo·_»sNŠ(¬°’Š(ηߊς>jŸφΛE%ruθΌ7y­6Ήσl6 Ža`‘FοcƒκqιŸ8――ΑΞ3‘WΡ#σ\Ξ”ιβκ)«]·ςo@’Š+€ΰ (’€ φ?Χjϊ>₯f‡†q1nΔ:ΰό†:ρΚτO‚wˆ―- Θ‘Oo»c Ί°Ζ3Ι 3œΩ=«‡1‡6^G­’UφxΨ_ŸόΪ¨’ŠωSτ0’Š(’Š(’Š(¨`΄¦»ž(!\n’W£'$π95‘βΟYψkM77g|Ο‘ p·τΉνξHΑ|Mβ-CΔw«q¨ΊαlqFHΗ|O'Ή<ώcΏ €ž'ήΪ=Ο#2Νι`}ΕοO·oSΏρ?ΕOυ–ώƒΥ~Υ8ϊŒͺί$ϊ―9Φ΅­G[Έj—r\8ϋ‘°xεQ€3œ{Φuτ0”¨| ^ύOŠΕζ8Œ[ύμ΄νΣξ (’ΊN ’Š(’Š(§Ε#Γ*K ΄r#WS‚€t φ4Κ(άΆ¨νΌ9ρXΆΗzίΪVΓψglH:ž“ԏ½ž+Υό9γ Δ%ΙK“ŸτyΐI^ƒ$7Ÿ”œΈ―œ©Θν«£u9 >’ΌόF[JΆ«GεώG΅Ο1kFoš>{όŸωθ}YExο‚Ύ%Kiώ‰β7–β”Gr ωϋ°Η9εΊυΟΏ‰4I,.²DκNCΘ χσψŒ5L<Ήf}– GjOΥuA4QΝ Ε2,‘:•taΐπAΕ|ύρΒ³xoTfCiΧ ΝnλŸ”uΨsΞG―qΟ¨BVgˆτ{mwHžΖνP‡Sε».LOƒ΅Η#‘Ÿ^y ­0X·†ώΛάΗ4Λγ₯o΄Ά/F|ΙE[Υ¬'΅+›΅Ϋ<QΈ t# ‚pET―«M5t~u(Έ·n‚Š(¦ ­? jm£kφ:€, A}€PπΰΖJ’?Μ’¦QRN/fT&ιΙN;­O«ΊQ\WΒ]sϋ[Γki)Νψ[ޱθ@WΉωrzΧoŠψΪΤέΊrέ¨a±čXl―ΐmμQŠΚζΧE;b‹…ΖΦ'‹D0)ΓJίΠη·Ή {Ι⳴žζαΆA 4’6 ’p9θ+η/ψ†λRέJH·RRήρuΟ†/vΆι΄Ω[3@ }}τ#ƒΨŽZŠŠ”γV.WLΦ…yК©MΩ£κm>φΫQ²†ξΚešήU܎½ώ‡±A«ΰΌVώΥV+©˜i3·οΣnν‡8Lγ¨μHοΠΊM K €‘:†GSΐς=Ε|3 πΣ·G³?BΛsc©sm%ΊώΊcρ—ΓΙ%šk–±ͺΝξH.§XσΤ/BpòאWΥWv±^ZMmp›ΰ™9$eHΑτ5σ·§Ι€κχ–n-o+GΉ“nΰ B0G±―[)ΔsΑ{―ΘωΎ"ΑͺUV"K_ψ?ζQ’Š+Χ>p(’ŠήπVΎώΧαΎΌyS’€KFHΞ3άιΣ3_HΫΛΝΌSΐαα•C£ŽŒ€dψWΛΊ%ƒjšΕ•‚1Ss2EΈ.ν œΗ| ϊžRR(Qc‰*" €μ+ηs₯8΅ρ3μ8ju)Εό)ιλΧτb€Ε―η܏b€ΕCyq€χW/²Q€‘°NΥQ’p9θ(Nϊ rI]žSρ«Δ%DZ «˜ n±ƒί(xιΈ‚?ΊkΙ*ζ―¨Oͺκw7χmΊ{‡.ά’z’Nΐ°©ΧΪa0λIC―_Sσ|Γ,eyU{tς_ΧβQEtœAEPZš©λςΛ“hΧ †sΉT('– dϊuΰϊνώ|:ώΧ·MK]Εfψh S΅¦Ξζ=BΐΖ ΞAϋ5₯¬vι€Aglq U98Ž€Χ‘ŒΝcEΈRΥώΏ—δSΔ%R³ε‹ϋίωW£|"@‘΅­E‹9ŠΡp烽ΘΗm£“ΧŽ{Kxnŝ‘-˜°Ασσ0ό“ΒΊlQŠπκγ«Υψ€#κ(eΨ\?Α~οWψ˜ΏπŒθ_τΣ?π?π£ώ ώ€ΊgώΗώ΅Š1X{y3:}/ε_r9KΏψfκαζ“J‰]±‘ΌkΣ*ΰ+”Υ~Ϋ2€κSFαNεC†nί2γhό zΆ(ΕoO^ŸΓ7ωώg5\· YZTΧΛOΘωŸΔΦτi/μ›μΑˆϋDDο8δ{πI―[ œΖ^νuo4|ώ3‡eε†wς{όŸό1αUύkHΏΡ/ž©lΦχCν$AθA}PGQT+܌”—4]ΡσRŒ άd¬ΠW­|ρ8Ηό#χ―Ο-g„yI˜Θώχ=y->d‚d–hεF އHδ{Γ‡Ž"›¦¦tΰqrΑΦUcσ]Ρυ†+Ζ~8ιk«a©FϋLf)6¦>dΖ nδ†ΗΡ?/Pπ~΄ž!πυ¦ …»fEΗΙ α†2p;€yΑ½a|b³Žηΐχ2Θ\5¬±Μ€t$ΆΞ}°ηρΕ|Ξr‘ŠŒeήΟς>Χ3Œ1XJ:«s/–Ώ‘σύQ_\~~QEzΑ=;ν~.k·IΆY@Ξ£εί qέK8?/±―yΕy‡ΐ;š>«}ζgΝ`Ω·ξμ\η>ώgOo~=OρΩ΅^|L—m?―™χy%?gƒ‹οwύ|ˆρF*LQŠσzχ#Εp?u&±πˆΆŠHΦKΩ–&RΨs˜¨Ο¨PzŒ6;Šτ,W„|rΤΎΣβ‹{—|vp Ι·$s“Ξ9Κω~£ρΝwεtύ&+’Χξ‚y™Ζ#Ψα$ΦοOΏώΟ8’Š+μΟ€ (’€ υO„ώ7o»« ϋ2ΦΠ0Μ=7·’ŽΓ©#=>χΰψ–ήΙ²-‘γ#¨κH^:g=«ιˆaŽR(Q#Š5 ˆ€P8ΒΌLίι/c ήώ‡ΡdYz«/¬ΤΪ/OUΧεω‰Š1Rb«ί]ΫΨZIu{ΝΫΆξbΨΟΖzΧΠd½IΛ²όᏝβ)ώξξ/ψr•Q_P|˜QEοŸ΄•³π€šƒσoε$2±'ΛBT:»y㱇£b«hΦ?ΩΊ=™ζύ–ΰί·nνͺ8νœt«˜―ΟρUύ½iTξαΡ°”VŒiv__Δ§©^Ϊι–3^ί̐[B»žFθυ=€“ΐ―> ψηΕwΑP<\'χδςOχίՏδΉ=‡ΗoKφ˜4 i„"Οs²L–bNΤ`:`Ψ=r§°ΟΧΡdΨΖ 5«ΫΙ5ζœή›χVώl(’Šχž (’€ πφ΅{αύR+ύ6]“'O+"χVΑ0@5›EL’¦œd™Q”‘%(»4}1ΰ?ΪxΆΞVŽ#m{ύν»6μΡ•°2θz¬WΚΦοΌ?ͺE¦Kε̜2žVEξ¬;ƒδFΎ’Πu[msHΆΤ¬ {…Κο]¬$G¨ N8Θ―Ν0TŸ4>ψy‘φΩVeυΈrOγ[ωω™wbŸŠ1^MΟZη—|lπ»κ:rkvœΟcɐbρnΞF8IbxθI'€+Βλμ)’Žx^)£I"‘JΊ:†V‚=G΅|‘β]"m]½Σ.η·“hnυ<«`Œ©γ8―ͺΘρn€=c·§όΤω, ‘QWŠ[ϊΑύ Κχƒή)Σaπ§Ψ5=BΚ[IXF³H#-ΐεŽ ά\qΠžΌψ}κc0‘ΕΣφrvκyX,d°u}€Uϊu?<''‹uΏ³xl‘_2βe\ΉΐPq€Ηœg°'œ`αθΊmΖ±ͺΪιφKΊβζAπHκǜ’N8šϊ§Βϊ ―‡tKm:ΝΤy’*ΰΛ&η9$δ‘κp0Wm˜}R°ψžή^gNU€ϊΥNiό+?"Ξ›§Ϊι–ΩX@ZΒ»R5θυ=Ι<“Ι«;}ͺLQŠψ§6έΩφͺΙYνφ£o΅IŠ1JγΉίj6ϋT˜£\.G·ΪΎ7―³1_(xξ ρΊ“Fρ±½™ΒΊJ³–SΟb χWpμύϊ‘οoΒζ|ηΖρ§.ΧόmώFQ_R|ΈV‡‡¬£Τ΅ύ6ΖrλΝΜPΉBgγ=ω¬ϊ»’ίfk6ώ_›φ[ˆηΩ»nν¬ηΗZŠ—δ|»—NάΛ›cλ½ΎΤmφ©1F+σ[Ÿ€\ωΔΪ—φΏˆu-@4¬—$~iΛ'εSΙθΈνŠΜ’Šύ.1PŠŠΩ›JNrr{°’Š*‰ (’€ (’€ υΏ€ZαŠώχC™E2›˜w0Μ  c,Jΰυΰ!γ“^I[ΎΏm3Ζ:=Н UΊE’GΐUŽΧΙ<΄·=«“AWΓΞZz£―]ΠΔBkΏΰΟͺφϋQ·Ϊ€Ε―Οn~r=ΎΥα΄o#U°Υ⏠s‚R±`^T³w%N<β>ύ½Σΐόo°[ΏάN˜Ν”ρNͺw˜Ky{IΘΗž~ξ1ΞG£•Wt±P}τϋΰžvkMUΒΝvΧξ>q’Š+ο…=Λΰ/…γO“Δ7£O3ν†J ΘvπXεy€§³W―b«h–φφΊ6Ÿoc7Ÿi ΌqΓ.ΰΫΡT9€9UΜWζψάT±5εR_πΘϋμαθƜ¦3bŸŠ1\·:n3bŸŠ1EΒγ1F)ψ£\.3σ―Η]&k5ϋ Ύ‘Ί9Œ… А7F cιΌ{τn+Μ~>hnπ΄:ͺΎΧΣdεIα’Bͺp1Λn ά nλΕzΉ.#Ωbγ}₯§ί·γcΜΝι{\3Άλ_λδ|υEWޟQE}qΰνDk―ώΠ.$šΩ ²Ϋ™@Δƒ0ΰcŽ20kcⳉ-νήλΓΧ$¬Χ2ύ’Τ„$3lύβ³gŽHγ6O@}ΏωΦa‡x\D©τιιύh}ή±#>»?SδoiΨΎ,Υtρ“7 εG»v"'rs“ό%zσλΝbΧΡ<.½§Ηͺιp<Ί₯’μxՎe„dαW»r1Œ‚G'h―λνrΜdqt–λGλωΓ π՜z=WυδQEzQEQEQEhψvΚ=OΔe„μλ ΥΤP9Bg HΟ~je%Ή>ƒŒ\šK©υώΪ1OΕ―Λξ~q˜KβΕ€Χ5˜ν“{¬k)εGWcΟ’©?…vsβ5ά6ΧfΉlkG„yj έ Ψ½Hγs žΓ<•Ρ„“Uΰγ½Χζaг£5-¬#δϊ(’ΏJ??=sαwΕμΈSIρ<=„hΪμ‚νΔlI\―N˜ΫοIΔΝ‰,2(ttmΚΚFAuw―ŠλΎψuρ"Β~]•Βύ―F2nhϊȁΞLg8œν<?„’kζ³\‘U½l6’κΊ?O3έΛ³gI*UΎ·όι­΄m¬ύ ^|AΝ’j^Ζ‡ ε’y F—;N2kOρςRƒε’³σ>’3ŒΧ4]ΠΝ΄m§βŒTσq›hΫOΕ£˜.3mA}g υ•Ε₯y–χ΄R&Hά¬0FG#ƒΪ­bŒSSiέ³ΡŸψ£F›Γή ΎNηΆ“h|½O*Ψγ*AΖxΞ+*ΎψΩΰΙόC€Α¨iVζmNΛ ’c|°žJŽ2Μ g»c$_7ΧθΉf9ch)ύ₯Ώ―όβ1ΨW†ͺγΣ§υδQEz'$IoΖΠBΎxyςTAEWQ€U½7RΎηi΄ΫΛ›9™v3ΫΚΡ±\ƒ‚Ad=ͺ₯₯%f4ΪwGceρ/Εφv©o·3"ghγ•ω9εK½Ν>Š>1š "}i‚Θ₯ Kx‘€#0PAχ\]Μπ8fομγDmυͺφ·;ϋΩoQΤo΅9ΦmJςζςe]‚K‰ZF ’q’O'z©E’’¬Œ[mέ…V·†4 CΔΊΔ:n•™;ςΜxHΤuv=”gω’@₯9Ɯ\€μF.MF;› |"ώ-ρ,pΚΈΣ­vΝvΔ6sώ―#fδu#8Ε}U[Α0F‘C„HΡBͺ¨ΠΪ³<αΛo xvΧJ΅a'” ’o-Q¦rrY±ΧΠg$(Q“ŠΫΕ~s›fOZλα[ŸΜϋ Ώ°΄μώ'Ώων£mIŠ1^_1ίr=΄m©1F(ζ ‘ν―hlΌOgͺF&£ W‰c$xxkF=ΏFbΌŸφŽΡΌ%be–Ω/Rμ4*γχ›HuLΖJœ9Ϊ­‘Χtρ°·]?―ž§ŸšAO +τΤωŠ(―я (’€ (’€;†>3“Αzσ\΄Mqcp‚+˜Cvδκ2uηγ Ìδ}g±άAΦς$°Θ‘D`ΚκFApAλαΚυ‚ ЈΠuΙ<½>i7[ά»Άξz«g€„σ‘€ $πI1ΔS―¬Ρ^ςέw_ζΏΨΚρΎΙϋ*G·‘τF(Ε?bΎ˜ϊKŒΕ§βŒQΜŠσ?ˆ_ ΄ί<·ΪS&«;4’6 Šαˆώ%ΟΚrά£»šτόQŠθΓc*αgν(ΚΟϊάΚ΅*u£ΛQ]x³ΑΪη…gΩ¬Y#ψ7αWΜ’Κ9΄»–ήΫ­›1—n„£dmψWoL}nŠiΙrβcgέmχoωž|žKZ.ώLωzŠφ kΰN΅m½΄JΚϊ5ŒΆΩCA#??*™yγ°δσŒfΉ;ο…ώ2²΅’βmf1‘ ±Μό8DbΗ―aοΠW»K5ΑΦ^εUσvό™ζΟ^ηω]½w‰Ώθ\Φπ_ώ&­ιŸΌY©NΠΫθ‚:ςn#ς†“h'ž™Ο_C]2ΕPŠ»š·ͺ2Tj=_άrΤWͺxΰˆοέ[V’ΧJ‡yV βiqŒ† ‡iγ–ƒνŸQπ―Β hn“έDϊ­ΠP Ό’ ‚¬xΖz6μ``δfΌΌVƒΓέ)s?-ŽΚ9ez»«/?ςάπί|;ΦΌ_ ’ώΗ¦ŒΌ# ΫHϋμ0ά 0HΘ―₯ό%α='Β–-m£[y^fΣ,Ϋ€”Œ±?‰ΐΐœšθ1F+γ³ζΆ=Ωϋ±μΏ^罄ΐΣΓj΅—λa˜£όQŠςyŽλŒΕ§βΉΟˆ>&‡Β>ΉΤε₯?ΉΆ_,²Όμ¬P6ΐωI<Žγœ₯(J΄Υ8jή„Ξ€iΕΚODt¬έo\΄(<έcPΆ³R¬κ%p£'jυcΘΰy΅ς&«β­VKˆυ-gPΈ†α·I ΞήSΫΎζv€001±kλhπ«ή­OΉ~―όyίςCοΧζ}βφV» π΅―Ϋ₯Ÿ«•dˆ}ΣΒpΝόCΈ Exf³«κέσήjΧ“]άΆ~y[;FIΪ£’Iΐ< ‘E} -Γΰ•©G^ολΠς±ΚΈ‡ο½;t (’»ΞP’Š(’Š(«š=„Ί­e§Ϋ²,Χs₯Ί4„… μ€N2}*vΏ,ΰΎψ‘Eu™Θσ’>tŒͺk U_cFu•7χ#JPηœcέ£λ+ 84ϋ k;Dςν­γXbL“΅O'€:Τψ©1F+ς6έΩφ‹M(ΕIŠ1K˜.GŠ1RbŒQΜ#Ε©1F(ζ ‘βŒT˜£sΘρF*LQŠ9‚δx£&(ΕΑr]Όy[kUl€ {V8nψμSβ‡Δ ΟjAP=ΆnΔΫΫΙ=<Ημ\ΑGΉ<5~…‘dίRΆ­ρΏό—ώ»Χζσ w·|ψWβQE}ζQ@Q@Q@Q@wίδͺθφίDI\ vo ±ψ‘ Λu'—Jπƒ‚rςFΘƒVe5Ε™&πu’ώY~LΫ νZ χ_™υφ(ΕIΆ΅ψ1υΧ#Ε©6ΡΆŽ`Ή(ΕIΆ¨kšΖ‘X=ξ±{²ηη•±Έΰͺ:³`(Ι8ΰUEJmF*νƒ’J췊1T4{IΧνΜΪ.£kzUάC fŒ0Κο^ͺN ΰϊVžΪ&₯ rΝY‘))+’ΕSΥ5=?I·Yυ[λK(Ά,—3,j[ΰ gρμkδ­cβ׍5DΈ‰υ—Ά‚fέεΪF‘Ζμ…Wx§ήΙIζΈ»ϋΫ­FξK­Bζ{«©1Ύiδ.ν€ΛOΒ»pόY»Χ¨—¦ΏΏS*™¬WΑΌϊ7Ε΄k8ζ‡Γv“j7#„že1AΚηvΞΨ8H\σƒΠŸρwŠ΅oj’^λ7O!.Ν ΗΚ€|±©'hΐΤγ$“ΝaQ_W€ΙπΈ hΗήξυΧ‘ζWΕΥ―€ή‚ΊΝ3β/Œ4Ϋ†šίΔZ‹»)B.eϋBγ π²nρΧλκk“’»κΠ§YZ¬T—šΉ„g(kcΤτΏŽ~/³·hξN¨9bΒ[›}¬Κ<²ƒg¦y<τ­KΪ_KΈΫPtΉνFwΗ’'<a‹0γψOαΦΌbŠση’`'{ZφΣς7XΚλi3ίΏα’κWΚ‡j―g🈴ίhκš<ήeΌœ2·Ž¨γ³ ώ Œ‚ ψjΊ‡ή4ΤΌ­‹έ<ωΆςanm°“ μ}dα»gΈ$#2αl<θίΉfΌΫOΛVνεψωuaσ*‘—ο]Ρφ(Εax3ΕΪ7Œtχ»ΠξΌί/hšR²BΜ2)όFFTpN t8―Ο*ΒtfιΤVk£=ΘΝI^.θb€ΕRΦ5+-LΈΤ5Kˆν¬­Χ|’ΉΰζI8I MLo&£vΖδ’»<‡φ™ρYxjΣA‚`.oεΜƒiύʍΩεrϋH s±†zƒσMt;ρE׌φ> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐ"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωRŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š|QΌ€P£I#°UE,O@s_Q|ψ Š.±γΛhn˜·Σ[ζŽ!ΑΜ½™»mε@λ’~V•Ι””V§ˆxαŠΌmΆ]O1ΨΧGΚƒψ‡~Tƒ°6\W΄ψwφb΄XΥόIβ εvAΊ+„aΎχn㫤IΒFΏ@qώ*ψ—α HΠκΪά vΌ[@n%PΌΔŠΣ•-Μ]IKc•gΟYΐ#Ή³½Τώz\]Ί·ώCΪ?J½ +αΧύ ηn?ψεb^~Ρ~ˆ‘k₯λwC±ςγˆΝͺ‹~Z7πxgU?[˜…ˆ­3©…πλώ…σ·όrψQ_Ώθ_?ψqΗ+“†“ΏθVΤΏπ.?π£ώOJ‘[RΐΈΒ‹Δ9fuŸπ’ΎΠΎπ6γŽQ +αΧύ ηn?ψεrπzWύ Ϊ—ώΗώΓIι_τ+j_ψψQx‡,Ξ³ώWΓ―ϊΟώάρΚ?αE|:‘|ΰmΗOώOJ‘[RΐΈΒψi=+ώ…mKγ /ε™ΦŠψuBωΐۏώ9Gό(―‡_τ/Ÿό Έγ•ΙΓIι_τ+j_ψψQ '₯Π­©ΰ\αEβ³:ΟψQ_Ώθ_?ψqΗ(…πλώ…σ·όrΉ?ψi=+ώ…mKγ ?α€τ―ϊ΅/ό ό(ΌC–gY +αΧύ ηn?ψεπ’ΎΠΎπ6γŽW' '₯Π­©ΰ\αGό4ž•BΆ₯q…ˆrΜλ?αE|:‘|ΰmΗ£ώWΓ―ϊΟώάρΚδα€τ―ϊ΅/ό ό(†“ΏθVΤΏπ.?π’ρYgό(―‡_τ/Ÿό Έγ”ŠψuBωΐۏώ9\Ÿό4ž•BΆ₯q…πzWύ Ϊ—ώΗώ^!Λ3¬…πλώ…σ·όrψQ_Ώθ_?ψqΗ+“†“ΏθVΤΏπ.?π£ώOJ‘[RΐΈΒ‹Δ9fuŸπ’ΎΠΎπ6γŽQ +αΧύ ηn?ψεrπzWύ Ϊ—ώΗώΓIι_τ+j_ψψQx‡,Ξ³ώWΓ―ϊΟώάρΚ?αE|:‘|ΰmΗOώOJ‘[RΐΈΒψi=+ώ…mKγ /ε™ΦŠψuBωΐۏώ9Gό(―‡_τ/Ÿό Έγ•ΙΓIι_τ+j_ψψQ '₯Π­©ΰ\αEβ³:ΟψQ_Ώθ_?ψqΗ(…πλώ…σ·όrΉ?ψi=+ώ…mKγ ?α€τ―ϊ΅/ό ό(ΌC–gY +αΧύ ηn?ψεπ’ΎΠΎπ6γŽW' '₯Π­©ΰ\αGό4ž•BΆ₯q…ˆrΜλ?αE|:‘|ΰmΗ£ώWΓ―ϊΟώάρΚδα€τ―ϊ΅/ό ό(†“ΏθVΤΏπ.?π’ρYgό(―‡_τ/Ÿό Έγ”ŠψuBωΐۏώ9\Ÿό4ž•BΆ₯q…πzWύ Ϊ—ώΗώ^!Λ3¬…πλώ…σ·όrψQ_Ώθ_?ψqΗ+“†“ΏθVΤΏπ.?π£ώOJ‘[RΐΈΒ‹Δ9fuŸπ’ΎΠΎπ6γŽQ +αΧύ ηn?ψεrπzWύ Ϊ—ώΗώΓIι_τ+j_ψψQx‡,Ξ³ώWΓ―ϊΟώάρΚ?αE|:‘|ΰmΗOώOJ‘[RΐΈΒψi=+ώ…mKγ /ε™ΦŠψuBωΐۏώ9Gό(―‡_τ/Ÿό Έγ•ΙΓIι_τ+j_ψψQ '₯Π­©ΰ\αEβ³:ΟψQ_Ώθ_?ψqΗ(…πλώ…σ·όrΉ?ψi=+ώ…mKγ ?α€τ―ϊ΅/ό ό(ΌC–gY +αΧύ ηn?ψεπ’ΎΠΎπ6γŽW' '₯Π­©ΰ\αGό4ž•BΆ₯q…ˆrΜλ?αE|:‘|ΰmΗ£ώWΓ―ϊΟώάρΚδα€τ―ϊ΅/ό ό(†“ΏθVΤΏπ.?π’ρYgό(―‡_τ/Ÿό Έγ”ŠψuBωΐۏώ9\Ÿό4ž•BΆ₯q…πzWύ Ϊ—ώΗώ^!Λ3¬…πλώ…σ·όrψQ_Ώθ_?ψqΗ+“†“ΏθVΤΏπ.?π£ώOJ‘[RΐΈΒ‹Δ9fuŸπ’ΎΠΎπ6γŽQ +αΧύ ηn?ψεrπzWύ Ϊ—ώΗώΓIι_τ+j_ψψQx‡,Ξ³ώWΓ―ϊΟώάρΚ?αE|:‘|ΰmΗOώOJ‘[RΐΈΒψi=+ώ…mKγ /ε™ΦŠψuBωΐۏώ9Gό(―‡_τ/Ÿό Έγ•ΙΓIι_τ+j_ψψQ '₯Π­©ΰ\αEβ³:ΟψQ_Ώθ_?ψqΗ(…πλώ…σ·όrΉ?ψi=+ώ…mKγ ?α€τ―ϊ΅/ό ό(ΌC–gY +αΧύ ηn?ψεπ’ΎΠΎπ6γŽW' '₯Π­©ΰ\αGό4ž•BΆ₯q…ˆrΜλ?αE|:‘|ΰmΗ£ώWΓ―ϊΟώάρΚδα€τ―ϊ΅/ό ό(†“ΏθVΤΏπ.?π’ρYgό(―‡_τ/Ÿό Έγ”ŠψuBωΐۏώ9\Ÿό4ž•BΆ₯q…πzWύ Ϊ—ώΗώ^!Λ3¬…πλώ…σ·όrψQ_Ώθ_?ψqΗ+“†“ΏθVΤΏπ.?π£ώOJ‘[RΐΈΒ‹Δ9fuŸπ’ΎΠΎπ6γŽQ +αΧύ ηn?ψεrπzWύ Ϊ—ώΗώΓIι_τ+j_ψψQx‡,Ξ³ώWΓ―ϊΟώάρΚ?αE|:‘|ΰmΗOώOJ‘[RΐΈΒψi=+ώ…mKγ /ε™ΦŠψuBωΐۏώ9Gό(―‡_τ/Ÿό Έγ•ΙΓIι_τ+j_ψψQ '₯Π­©ΰ\αEβ³:ΟψQ_Ώθ_?ψqΗ(…πλώ…σ·όrΉ?ψi=+ώ…mKγ ?α€τ―ϊ΅/ό ό(ΌC–gY +αΧύ ηn?ψεπ’ΎΠΎπ6γŽW' '₯Π­©ΰ\αGό4ž•BΆ₯q…ˆrΜλ?αE|:‘|ΰmΗ£ώWΓ―ϊΟώάρΚδα€τ―ϊ΅/ό ό(†“ΏθVΤΏπ.?π’ρYgό(―‡_τ/Ÿό Έγ”ŠψuBωΐۏώ9\Ÿό4ž•BΆ₯q…πzWύ Ϊ—ώΗώ^!Λ3¬…πλώ…σ·όrψQ_Ώθ_?ψqΗ+“†“ΏθVΤΏπ.?π£ώOJ‘[RΐΈΒ‹Δ9fuŸπ’ΎΠΎπ6γŽQ +αΧύ ηn?ψεrπzWύ Ϊ—ώΗώΓIι_τ+j_ψψQx‡,Ξ³ώWΓ―ϊΟώάρΚ?αE|:‘|ΰmΗOώOJ‘[RΐΈΒψi=+ώ…mKγ /ε™ΦŠψuBωΐۏώ9Gό(―‡_τ/Ÿό Έγ•ΙΓIι_τ+j_ψψQ '₯Π­©ΰ\αEβ³:ΟψQ_Ώθ_?ψqΗ(…πλώ…σ·όrΉ?ψi=+ώ…mKγ ?α€τ―ϊ΅/ό ό(ΌC–gY +αΧύ ηn?ψεπ’ΎΠΎπ6γŽW' '₯Π­©ΰ\αGό4ž•BΆ₯q…ˆrΜλ?αE|:‘|ΰmΗ£ώWΓ―ϊΟώάρΚδα€τ―ϊ΅/ό ό(†“ΏθVΤΏπ.?π’ρYgό(―‡_τ/Ÿό Έγ”ŠψuBωΐۏώ9\Ÿό4ž•BΆ₯q…πzWύ Ϊ—ώΗώ^!Λ3¬…πλώ…σ·όrψQ_Ώθ_?ψqΗ+“†“ΏθVΤΏπ.?π£ώOJ‘[RΐΈΒ‹Δ9fuŸπ’ΎΠΎπ6γŽQ +αΧύ ηn?ψεrπzWύ Ϊ—ώΗώΓIι_τ+j_ψψQx‡-C¬…πλώ…σ·όr¨κŸ³η€― 1ΫYήιοŸυ–χnΝ‘7±φ’ΡΏΓ:¨ϊ\ΔjυŸναIX ­/[΅Ο— ~MEβš9~ΜV?†όAιHj7֚fŸs©\Ηkcl†I§αQGθRx€Σl­τέ>ΦΖΖ!­΄K Q―EEςσ/ν1γi5oΒ-a1f–ΐέΤΎ?Ιρύ•ρέ}‡ρψΕ ρύ΅ρέ9ξM-…’Š* BŠ( Š( Š)(h’’€Š( Š( Š( Š( Š( Š( Š)(h’Š(’Š(’Š(’Š(€₯ Š( ŠJZ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(€₯ Š( Š( ŠJZ(’Š(’Š(’Š(’’€Š( Š( Š( Š( Š( Š( ŠJZ(’’€Š( Š( Š( Š( Š( ΎΔψ$ΓίIΏτkΧΗuφΐƒΓIΏτkUΓs:»_ϋbυπύ½νωΊΎύ±:ψGώήφ|ίJ[ŽŸΒ‚Š(©,(’Š(’Š(’Š(’Š(’Š+θΨσ―‹νΣkWΞτμ{ΧΕΏφι΅ͺ£Ή>Τ~>Ÿψ΄ ϊC£VΎ<―°Ύ>Ι!ρύ΅ρν9ξ*[QPhQEQEQEQEQEV΅Ÿ†΅Λν ]jΗIΌΊ’”Γ-Μ™7G 9Ζ9¬…eaς~”΄QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEφΐ#ƒΓIΏτkWΗ•φΐ#‡ΓIΏτkUΓs:»_ϋaυπ—ύ½νωΒΎύ°ΊψKώήφ|αJ[ŽŸΒQEIaEPEPEPEPEP_G~Ηέ|[nŸϋZΎq―£cώΎ-·Oύ­UΘ©πž£ρσώIˆ>θΥ―kμŸςH|Aτ‡F­|}N{Š–ΒQEA QEQEQEQE΄”Q@^ώΖίςN΅ϋ Ι’£ΖΏ |γςκΊVόv׈x‹ΓϊΟ†nΎΝβ.σM˜τ•VuΎλ~ΏI*Ύ‘ai©Z=£kέ³ύ觌:7Τ(σ>Šϋ/Ζ³„u­σhMq ]žqn|Θ χΊΐH―ρŸΐŸψgΜ–Φ¬—Ÿ;N%Ÿρ›ςΝym%,ŠΡΜπΚ­ΘpρΊ•e>„E%QEQEQEQE΄”PEPEPKIEQEQEQEQEQE-%PEPEPEPKIE-%PKIEQEQEQEQEQE΄”PEPEPEPKIEQEQE-%PEPEPEPEPEPKIEQEQEQE΄”PEP_a|’Cα€ίϊ5«γΪϋΰό’ύ&Ρ­W Μκμy‡νƒΧΒ_φχ΄kηϊ7φΐλα/ϋ{Ϊ5σ•)n:QE%…Q@Q@Q@Q@Q@}ϋ uρgύΊνjωΚΎŒύzψ³ώέ?φ΅Tw"§Βz‡ΗΏω$^ ϊC£VΎ?――Ύ=Ι"ρύ΅ς 9ξ*[QPhQEQEQEQEQE}{ϋΙ:Υμ+'ώŠŽ½ξΎaύ”/Ρ#ΊN†λNmSτa^γΰί‹> ρqHτ­nέ.Ϋώ].Ώq6}Ά7ΐs_R2« 0λ@§TWηΧ„>(ψΟΒ[HΧnΥxϋ-ΩσβΗ  ΚΐH―pπ‡νEm!H|a‘ΙlΔΰέiΝζ'ΤΖί0ό P΄W3αψ_Ερ†πφ·gy!0‡Ϋ*ύcl0ό«¦ Š( ²ΌEαΝΔΆFΣ_Σ-5 sΡn" ·ά ϋŠΥ’€>yρ§μΗ’ήω“ψGSŸI˜ς-3<@OΞ£ρo₯x?>xΣΒI5-[›$δήXώώ,zœ|ΛΎώ’€?1U•†Tƒτ₯―Ώ|kπ“Αž0/.©£Ελψό³ύΔΩυ%xoψ5ΰΎ3ύ˜υ«σxGT‡T„r-―1 ΓΨ8ω[ρΫ@>QZž"πφ³α«Αkβ .σNœœ(ΈŒ¨χ[ξ·ΰMeΠEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP__|’Eα€ίϊ5«δϊχΰ7ό’?ύ&Ρ­W Μκly—ν{ΧΒφχ΄kηJϊ+φΌλα?ϋ{Ϊ5σ­)n8|!ET–QEQEQEQEQEτWμ‰Χşφι΅«ηZϊ'φEλβΏϋtΪΥQά‰ό'§|x?ρhυ€?ϊ5kδ:ϊλγΗό’MιώZωœχ=‚Š)* ’’ŠZ(€ ’’ŠZ)( ’’–€ ))h’’ŠZ)( RRE‘ $Šr§ §ΨŽEzOƒώ6ψλΓ#V:₯’ΰ}ŸRw°|‡™―5’€>Ίπν7αλύψ§NΊΡζ8xΏ ϊ’α|Ÿ­{W‡|I’ψ–Π\θ₯ž‘so(rΏP9ΨΧζέMcuq§έ₯֟s=₯r³[Θcqύ4’Ύ$π‡ν γ}dZŒΦϊν’ρΆρvΚ΄‹Ι?ο^ηΰΪ+Β^#Έ†Κών#R…X€ˆΞŒO`ρƒω(Ϊ( r( Š( γœqΙπ‡ΕždhϋtωYw(8`ΌžγΦΏ?—ξ₯~όo’CβοϋΝ ΧηΪύΡτ QIE-”΄QIE-”PΡE%-”PΡIE-”PΡIK@”΄QIK@RPΡE%-”΄QE%-RPΡIK@”΄QEQIE-”PΡIE-RPΡIK@”΄QIE-”PΡIK@RPΡE%-”PΡE%-”΄QIK@”PΡIK@”PΡIE-RPΧןΟόZ=ι7ώjωΎΊψ$“@ϊM£Z™ΤΨσOΪο―„νοhΧΞ΅τOνuΧŸφχ΄kηjRάpψBŠ(©,(’Š(’Š(’Š(’Š(’Š+θΩ―ŠνΣkWΞυτ?μΧΕφι΅ͺ£ΉψOMψρ$—_ϊC£VΎE―~;Ι%ΧώθΥ―‘¨žβ§°QE&EPEPEPEPEPEPEPEŒΑFX€=M-ΦxCαΟ‹Ό^Q΄ ξ[v?ρυ0ςaΎΫώ―oπ컟.oλ„τ-i¦ΠΚΓ?’­|Η‘Έ/Vn“τθ~ψ7γl{Mμ-ιZ‰0&=B‘½‡ΠWΩ~ψqα/ͺD΄‚pn]|ɏό ²ί‘Εu΄σΏƒfΣdή,ΥuIG&ήΫχύ εΫσZφί ψSAπ΅·‘αν"ΟO&€fyΊ·βMmΡ@Q@Q@GΖω$>.°lίϊ ~}―έJϋgγηΔ? YψΔ λ6ΣkΆrA­Ήσ\;νΉ?ή"Ύ&(h’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š+λ―€ςIt€ίϊ5«δZϊηΰA‹K }&Ρ­W Μκly§νsΧŸφχ΄kηzϊφΈλαOϋ{Ϊ5σΕ)n8|!ET–QEQEQEQEQEτ?μ‘ΧΕφι΅«ηŠϊφIλβ―ϋtΪΥQά‰ό'¦|v’K―ύ!Ρ«_#WΦΏδ“kHτjΧΙOqSΨZJ(©4’Š(’Š(’Š(₯€’€ŠJ(i*ξ‘€κZΥβΪhΪ}ή‘tε•΄-#}Nλ^ΕΰΩ·ΕΪΖΙ΅ιν4+fΑ*Ηϟξ©Ϊ?ό(Δ N­― xW_ρTώW‡4{έDηαχkώσœ(όM}ΰοΩΐώ1Νue&΅xΌωΊ‹oP}£OΜυ{kxm`H-bŽPa#Bͺ@€>NπμΓ­^l›Εš½Ύ›δΫُ:_‘s…†κχ|π?… Ke£GwxΌ‹«σηɟQ»ε_ψθ”P0Q@Q@Ι₯ŽžYδHβA–w €šςό~πO†ΜΪή>·|§Nœ¨>ς~ύ(Φ«#Ğ&Ρ<1fnΌAͺΩιπγ Ο(Rί}€5ς?hΏλΎd:(·Π,ہδ~φr=δaQυ―Ώ»ΊΤoοQΊžςνΞZ{‰ ŽΗκy ͺΌiϋOiždηΤε «¬Α}Bύφ‚ΧƒψΟ⿍<_Ύ=WZš7ΰΩΩ~β,z|Ν&Έj(UF=©Τ”PKIEQEQE-%PQE-%PΡIE-%PEPEPKIE-”PKIEQE-%PQE-%PKIEQE΄”PΡIE-%PΡIE-”PQE-”PKIEQE-”PKIE΄”PEPQE-”PKIEQE-”PEPEPΧΧδ’θIΏτkWΘΥυΏΐ―ω$ΪoύΥPάΞ¦Η›~Φύ|)oϋFΎx―‘ΏknΎ·Ώύ£_<–εCα (’‘AEPEPEPEPEP_BώΙ]|UnΏϋZΎz―‘?dΎΎ*·_ύ­N;“?„τΏŽΏςI΅ο€?ϊ5kδšϊΧγ―ό’}{ιώZω&œ·&žΒQEI RQ@ E%΄”Q@-%QEυμfό+­\ΰgϋVNqΙύΤuο΅ΰ_±Ÿό“_ώΒθ¨λίh’Š(’Ч«κΊ~dχš΅ν΅•ͺ}ιn%¨όM\’Ό'Ɵ΄―…΄Ÿ2[άkΧK$OάΫƒώϋ ŸΑOΦΌƟ&Υ€ΫηH?ξ£ϋ«χ›π§ρŸνC§Ϋο‡ΑΊ<·tWΩ†/¨Aσ0ϊν €kΞ|kρŸΑ>2Ew«%νςpm,Ÿ&}>UόH―Žόgρ;Ζ1ޚ޷qφF—KSδCB«χΏΰDΧͺa@Ϊ€=χƟ΄Οˆ΅?2 X[θΦη<؞|z€~EόšΌO^Φ΅Oή›½wQ»ΤnOGΉ”Ύ=€<μ¬ϊ(’ŠJZ))h’Š(’Š(’Š(’ŠJZ(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (€ ’Š(’Š(’Š(’ŠJZ(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ ))h’Š(’Š(’’–€ (’€ (’€ (’€ ))h’ŠJZ(’€ ))h’Š(’’–€ ))h―­~Ÿψ΄ϊoύΥςU}gπ/ώIFƒτ›F΅Tw"¦Ηœ~Φ}|+o_ϋFΎ{― k.Ύ·―ύ£_>R–γ†ΑER((’Š(’Š(’Š(’Š(’Š+θ/Ω?―ŠνΧkWΟ΅τμ‘ΧΕ?φλ΅©Ηrg±ι?δ”kίHτjΧΙ•υΗ#£^ϊC£VΎN§-ΕO`’Š*K (’€ (’€ (’€ (’€ (’€hέ»>΄΄Q@Q@Q@Q@Q@Q@Q@Q@£α½γΔ> Σ΄k'Š;«ωΦή&”ŠΝΠΆ8ϊ φ?ψfΠSΓίχφoώ7@E{§ό3Ώθ)αοϋϋ7£ώƒΖίτπχύύ›Π…Ρ^ι Αγoϊ x{ώώΝΖθ†`ρ·ύ<=fγtαtWΊΓ0xΫώ‚žΏ³ρΊ?α˜Jπτ`Κt#4΄QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEυŸΐΟω%oύΥςe}cπ4Ε¨Π~’θΦͺŽδTΨσŸΪΓ―…ΏνλhΧΟ΅τν_ΧΒίφυ΄kηκRάpΨ(’ŠEQ@Q@Q@Q@Q@}ϋ(υρOύΊνjωώ½φRλβϋuΪΤγΉ3ΨτŽ?ςJuί€?ϊ5kδϊϊΏγό’­wιώZω>œ·=‚Š(©,(’ŠZJ( Š( €’ŠZ)( ’’Š)i( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( Γΰοό•ΨNη_‘ΥωαπwώJΗƒμ'σ―Πϊ(’Š(’Š(’Š(’Š(’Š(’Š(’Š‘βωj_υν/ώ€kσ6υ)τ―Σ/ΘR―iτ_™°©O  Q@-%΄RQ@Q@Q@ E%RQ@ IE΄RQ@Q@Q@-%΄RQ@ E%RQ@ E%΄RQ@ E%΄RQ@ E%RQ@ IERQ@ IE΄”Q@ E%΄RQ@-%΄RQ@ IE΄”Q@ _X|’S‘}&Ρ­_'WΦδ”θ_IτkUGr*lyΟν]ΧΒίφυ΄kηϊχΪ·―…νλhΧ€R–γ†ΑER((’Š(’Š(’Š(’Š(’Š+ίΏeNΎ(·_ύ­^^ϋϋ*υρGύΊνjqά™μz?Η«]ϊE£VΎQ―«~7Ι*Χ~‘θΥ―”iΛqSΨZ)(©,Z))h’’–€ )( ’’ŠZ)( ’’ŠZ(’€ )( ’’ŠZ))h’’ŠZ)( ’’Šιώ_Ϊιό3¨Ξ–φvΧρK4Ξp¨ ςM}΅ αού Ίgύό?α_ŸΤPθό.?‡Ώτ6ιŸχπ…πΈώΠΫ¦ίΓώωύE~€Βγψ{Cn™ψQ αού Ίgύό?α_ŸΤPθό.?‡Ώτ6ιŸχπ…πΈώΠΫ¦ίΓώωύE~€Βγψ{Cn™ψQ αού Ίgύό?α_ŸΤPθό.?‡Ώτ6ιŸχπ…πΈώΠΫ¦ίΓώωύE~€Βγψ{Cn™ψQ αού Ίgύό?α_ŸΤPθό.?‡Ώτ6ιŸχπ…πΈώΠΫ¦ίΓώωύE}λ¬ό^πϊ=τ1x―Li$‚DQΌςJ;WΑ±(<)ΤPΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIK@”PΡIE-”PΡE%-RPΡIE-”PΡIK@”PΡE%-”PΡIE-”PΡIE-”PΡIE-”PΡIE-}]π<ΕͺΠΎ’θΦ―”+κο‚ςJ΄/€Ώϊ5ͺ£ΉΨσ―Ϊ――…νλhΧ€ΧΎώΥ]|/o_ϋFΌ ”·6 (’‘AEPEPEPEPEP^ωϋ+uρ?ύΊνZπ:χΟΩ_―‰νΧjΣ[“=Eψί$―]ϊE£VΎS―ͺώ7ψ΅šο/ύ΅ς9n(l-”T–-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡE%-”PΡIE-”PΡIE-RPΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡE%-”΄QIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”΄QIE-”PΡIE-”PΡIE-”PΡIE-”PΧ՟?δ•θ_IτkWΚUυgΑ³BϊK£Zͺ;‘=;ύͺzψcώήΏφ•x{ηνQΧΓφυ΄«ΐι=Η ‚Š(€PQEQEQEQEQEW½ώΛ|OnΏϋVΌ½λφYλβϋuΪ΄ΦδΟcΡ~7ψ΅šη/ύ΅ς₯}Sρ΄Ε¬Χ>‘θΥ―•©ΛqC`’Š*K (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ ϊ―ΰ‰‹Y‘ύ%Ρ­_*WΥ?όZΝι/ώj¨‘==ύ©ϊψcώήΏφ•x%{ΧνMΧΓφυ΄«Αi=Η ‚Š(€PQEQEQEQEQEWΌώΛ}|MnΏϋVΌ½γφ\λβoϋvΪ΄ΦδΛcΡ>6ψ΅Ίη/ύ΅ς΅}Oρ―ώIvΉτ‹F­|±N[ŠQRXQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEWΥ?ΟόZέι/ώjωZΎ§ψ)$»CϊK£Zͺ;‘=>ύ©:ψgώήΏφ•x5{ΗνGΧΓ?φσ΄«Αι=Η‚Š(€PQEQEQEQEQEW»ώΛ½|MnίϋVΌ"½Ϋφ^λβ_ϋvΪ΄ΦδΛcΠώ5Ι.Χ>‘θΕ―–+κ_Gώ-~·τ‹F-|΅N[Š E%%‹E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄”Q@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΄RQ@ E%΅υ7ΑOω%Ϊ_ύΥςΕ}KπTΕ―Ρ>’θΖͺŽδOcΟj.Ύ·Ÿύ₯^^νϋPυπΧύΌν*πšOqΗ`’Š)QEQEQEQEQEξΏ³_Ϋ·ώΥ― ―tύ˜zψ—ώέΏφ­5Ή2Ψτ/'ώ-~·τ‹F-|·_Q|i?ρl5Ώ€_ϊ1kεΚr6ŠJ*KŠJ(h’’€ŠJ(h’’€ŠJZ(€’€ŠJ(h€’€ŠJ(h€₯ Š)(h€₯ ŠJ(h€’€ŠJ(h€’€ŠJZ(’Š(’’€ŠJ(h€’€ŠJZ(’Š(’’€Š)(h€’€ŠJ(h€₯ ŠJ(h€’€ŠJ(h€’€ŠJZ(€’€ŠJ(h’’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h’’€ŠJ(h€’€ŠJZ(’’€Š)(h€₯ ŠJZ(’’€ŠJZ+κO‚Ηώ-~‰τ—F5|·_Q|?ρl4O€Ώϊ1ͺ’Dφ8Ϊ―†ΏνηiW…WΊ~Σέ|5o?ϋJΌ.“άqΨ(’ŠEQ@Q@Q@Q@Q@{§μΕΧΔΏφν΅kΒλάΏfNΎ$·oύ«MnLΆ=γGό“ oιώŒZωvΎ ψΟ$Η[ϊE£Ύ_’B†ΑE%-"ŠJ(h€’€ŠJZ(€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h’Š(€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h’’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€Š)(h€’€ŠJ(h€’€Š)(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€Ύ’ψ.βΨhŸIτcWΛ΅υΑω&:'_ύΤβLφ8/Ϊw―†ΏνηiW…ΧΉ~Σ}|7o?ϋJΌ6‡ΈG`’Š)QEQEQEQEQEξ_³/_Ϋ·ώΥ― ―qύ™Ίψ“ώέΏφ­5Ή2Ψοώ3ψΆ:ί/ύ΅ςύ}=ρ”Ε²ΦΎ‘θΕ―˜ha ‚Š(€PQEQEQEQEQEQIK@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@}AπdΕ±Ρ>’θΖ―—λιοƒGώ-–‹τ—F54Lφ8?Ϊk―†νηiW†ΧΈώΣ=|7o?ϋJΌ:‡ΈG`’Š)QEQEQEQEQEξ³?_Ϋ·ώΥ――oύš:ψώέΏφ­5Έ₯±ί|e?ρl΅―€_ϊ1kζϊsγ!‹g­}"Ρ‹_1ΠΕ‚Š(€PQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEWΣߏό[-ι/ώŒjω†Ύœψ6βΩθΏIτcSDΛc„ύ¦:ψsώήφ•x}{ν/Χßφσ΄«Δ({Ž;QHaEPEPEPEPEP^έϋ4υρύ»νZρφίΩ«―ˆνΫjΣ[Š[οΖCΣZϊE£Ύd―¦Ύ1Ι4ΦΎ‘θΕ―™(bŽΒΡIE"…’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( –’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( –’ŠZ)( –’ŠZϊoΰΩ‹i’ύ%э_1ΧΣ?δšhΏIτcSDΛc„ύ₯Ίψsώήφ•x{oν+Χßφσ΄«Δ¨{Ž;QHaEPEPEPEPEP^Ωϋ6uρύ»νZρ:φΏΩ·―ˆΏνίjΣ[Š[ηΖ#ΧYϊE£Ύf―¦>0Ι5Φ~‘θΕ―™¨bŽΒΡIE"…’’–€ ))h’’–€ )( ’’ŠZ)( ’ŠJZ)( ’ŠJZ)( ’’–€ (€ ’’–€ )( ’’ŠZ(€ ’’ŠZ(€ ’’ŠZ)( ’Š(’ŠJZ)( ’ŠJZ)( ’ŠJZ(€ ’’ŠZ)( ’’ŠZ))h’’ŠZ)( ’’ŠZ(€ ’’ŠZ)( ’ŠJZ(’€ )( ’’ŠZ(€ ’ŠJZ(’€ )( ’’ŠZ))h’’ŠZ(€ ’’ŠZ))h’’–€ )( ―¦~Ι5ΡΎ’θΖ―™kιŸƒίςMto€Ώϊ1©’e±Βώ}|;o?ϋJΌN½―φ’λαίϋxΪUβ”=Η‚Š(€0’Š(’Š(’Š(’Š(’Š(―jύ›Ίψ‹ώέφ­x­{WμαΧΔ?φο΅i‘=Žλγ‹m¬ύ"Ρ‹_4Wίό[mgιώŒZω¦†(μRQH‘h€’€ŠJ(h€’€ŠJ(h€₯ ŠJ(h€’€ŠJ(h€’€ŠJ(h’’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€Š)(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€₯ ŠJ(h€’€ŠJ(h’’€ŠJ(h€₯ Ύ—ψ?$ΫFϊK£Ύg―₯ώŸψΆΪ7_ύΤΡ28oΪG―‡νγiWŠΧ΅~Ρύ|=oϋJΌV†5°QE†QEQEQEQEQEν³_ΫΏώΥ――hύœΊψ‡ώέφ­4'±άό_’o¬}"Ρ‹_5WŸό[cιώŒZω†(μQE"‚Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Ύ•ψA$ίGϊK£Ύj―₯>Ÿψ·?_ύΤΡ28Ϊ;―‡ΏνγiW‹Χ΄~Ρ½|=oϋJΌ^†5°QE†QEQEQEQEQE쳟_ΫΏώΥ――fύzψƒώέφ₯4'±ά|]?ρn5€_ϊ1kζΚϊKβι‹s¬}"Ρ‹_6ΠΕ’Š)QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEτŸΒ#γGϊK£Ύl―€Ύψ·:?_ύΤΡ28ŸΪ3―‡νγiWŒW³~Ρ]|?oϋNΌf†5°QE†QEQEQEQEQEμΏ³·_ΫΏώΤ――dύϊψƒώέφ₯4'±ά|\?ρnu€_ϊ1kζκϊ?βΩ‹u«Ϋ/ύ΅σ} QŠJ)-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PKIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE΄”PΡIE-”PΡIE-”PΡIE-”PΧ?Οό[ι/ώŒjωΆΎψHβέiφΧF54LŽ+φ‰λαϋxΪuγU쟴G_ΫΗώΣ―‘lQE!…Q@Q@Q@Q@Q@{μρΧ_·ύ©^9^Εϋ<υΧνίjSB{ΏΕ£οWΆ_ϊ1kη ϊ;βΡ‹w«Ϋ/ύ΅σ "RRQEQEQEQEQEQEQEQEQEQEQE%-Q@Q@Q@Q@Q@”΄QEQEQEQEQEQEQEQEQEQEQEQIK@Q@Q@Q@Q@”΄QEQEQEQE%-Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@}π”Ε»?ν―ώŒjωΒΎŽψK$οHΆΏϊ1©‘3Šύ‘ϊθφρ΄λΗ+ΨΏhnΊύΌν:ρΪ-‚Š(€0’Š(’Š(’Š(’Š(’Š(―bύžΊλφο΅+ΗkΨgΎΊύ»νJφ;_‹'ώ-ζ―lτbΧΞUτgΕ“σWΆϊ1kη:lQE†QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQI@ EPEPEPEPEPEPEPEPEPEPEPEPEPEPE”΄QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEτoΒcσHΆΏϊ1«η*ϊ3α1‹y€ΫOύΤΠ™Ζ~Π½tϋxΪuγ΅μ?΄']ώή?φxυ [Q@Š( Š( Š( Š( Š( ½ƒφ|λ―ΫΏώΤ――_ύŸΊλίφΓjP&vΏ?δžκίφΟF-|η_E|W’{«Ϋ?ύ΅σ­‚Š( aEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP_F|'’{€ΫOύΥσ}π£ώIξ“m?τcP&qΏ΄]ώή?φxύzνΧAΆϋNΌ‚€AEP0’Š(’Š(’Š(’Š(’Š(―^ύŸϊλίφΓjWΧ―|λ―Ϋύ©@™ΩόV’}«Ϋ?ύ΅σ΅}ρXΕΎΥΏνŸώŒZωΪ†Z)( bΡIE-”PΡIE-”PΡIE-”PΡIE΄”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-”PΡIE-}π€ΕΎν§ώŒjωΦΎ‰ψRβίi?φΣF5LγhΊύ·Ϊuδ5λίϊθ?φίiאΠ(’ŠQEQEQEQEQEλΏzλΏφΓjW‘W|λΫύ©@™Ω|U’ͺΫ?ύ΅σΕ} ρSώIώ«lτbΧΟ4 (’…Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@}π«ώIώ•m?τcWΟτ7ΒΏω'ϊWύ΄Ρ@™Ηό~λ‘Ϋύ§^E^Ήρχ…mφy‚Š( aEPEPEPEPEP^·π»l?φ₯y%zΧΐNΊηύ°Ϊ” —ΕC«lτbΧΟ5τ/Ε3«lτbΧΟT0AEP0’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(i(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ ϊαYŠJΆŸϊ1«ηšϊαaŠJΆŸϊ1¨8t/ϋo΄λΙ+ΦΎ=υΠνΏώΣ―% QE (’Š(’Š(’Š(’Š(’Š+ΦΎυΧ?ν‡ώΤ―%―Yψ Χ\ΆϋR3±ψ€βΥνŸώŒZωξΎƒψ€βΥνŸώŒZωξ€BΡIEŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€₯ ŠJZ(€’€ŠJ(h€’€Š( ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€ŠJ(h’’€ŠJ(h€’€ŠJ(h’’€ŠJ(h€’€ŠJ(h€’€ŠJ(h’’€ŠJ(h€’€ŠJ(h€’€ŠJ(h€’€Š)(h€’€Š( ŠJ(h€’€ŠJ(h’’€Š)(h€’€ŠJ(kθO…§ώ(+ώΪθΖ―ž«θO…§ώ(+ώΪθΖ‘ œ‡ΗΊύ·Ϊuδ΅λ?zθφίiΧ“P(’ŠQEQEQEQEQEλϊλŸφΓjW“Χ«ό λΫύ©@‡Εω΅Oϋg£Ύ}― ~(Θ…ͺΫ?ύ΅σνBΡIK@Š( ŠJZ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’’€Š( Š( Š( Š( Š( Š)(h’’€Š( Š( Š( Š)(h’Š(’Š(’’€ŠJ(h€’€Š)(h’Š(’Š(’’€Š( Š)(h’Š(€’€Š( Š( Š( Š)(h’Š(’Š(’Š(€’€ŠJZ(€₯ ŠJZ(’Š(’’€Š( Š( Š( Š( Š( Š( Ύ‚ψ]"—m?τcWΟ΅τΒω΄Ώϋi£€g#ργ‡mφy=zΏΗnΊύ·ΪuεQEQEQEQEQEQEW«ό ˜ίύ°Ϊ•εκίΊλφΓjP_ρCώD=SώΩθΕ―Ÿ«θ‰ς!κŸφΟF-|@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@}πΏώD=/ώΪθΖ―Ÿ«θ†ς!ιφΣF5r_Ώζ mφyEz·Η^Ί'ύ·Ϊuε4QEQEQEQEQEQEWͺό ˜ίύ°Ϊ•εUκΏ:λφΓjP]ρ?ώDMSώΩθΕ――~ψ"&©lτbΧ€PΡEQEQE%-Q@”΄QEQIK@Q@RPΡE%-Q@”PΡE%-”PΡIK@”΄QIK@RPΡE%-RPΡEQIE-”PΡIE-”PΡEQEQIK@RPΡEQIE-”΄QE%-”΄QE%-”΄QE%-”΄QIE-”PΡIE-”PΡIK@RPΡIK@Q@Q@Q@”΄QIE-Q@Q@”PΡE%-{Γω4Ώϋi£Ύ―ψc"&—m?τcP%ρΣώ`ŸφίiΧ•Wͺόsλ’Ϋύ§^U@Q@Q@Q@Q@Q@Q@z§ΐΞΊίύ°Ϊ•εuκŸzλ_φΓjP[ρ8Ε ©Ϋ?ύ΅ΰ5οΏOόPΊŸύ³Ρ‹^@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@{χΓ&—m?τcW€ΧΎό2?ρBιŸφΣF5rϊθŸφίiΧ•Χͺ|rλ’Ϋύ§^W@Q@Q@Q@Q@Q@Q@zŸΐοωΫύ©^Y^§π?ώc_φΓjPYρ4Ε ©Ϋ?ύ΅ΰuο?δFΤνŸώŒZπJ(’Š(’Š(’’€ŠJZ(’’€ŠJZ(€’€Š( Š( Š)(h€’€Š)(h’Š(’Š(€’€Š)(h€₯ Š)(h’Š(€’€Š)(h€₯ Š( Š( Š( Š)(h’Š(’’€ŠJ(h’’€Š)(h’Š(€’€ŠJ(h€’€Š)(h’Š(’’€ŠJZ(€₯ ŠJZ(’Š(€₯ Š( ŠJ(h€₯ Š)(h’Š(’Š(’Š(€’€Š)(h’Š(’Š+ί>ψ‘tΟϋi£Ό½οαŸόˆΪgύ΄Ρ@§Ηω‚Ϋύ§^Y^§ρΓώ`ΏφίiΧ–PEPEPEPEPEPEP^₯πCώc_φΗjW–Χ¨ό˜Χύ±Ϊ”ΦόL‘SΆϊ1kΐλήώ%ȍ©Ϋ?ύ kΑ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(―|ψg"6™m?τcWΧ½ό4‘LΆŸϊ1¨”ψί0_ϋm΄λΛkΤ~7ΜώΫν:ςκ(’Š(’Š(’Š(’Š(’Š(’Š+Τ~ΜkώΨνJςκυ‚]uŸϋc³ΠYρ/ώD}OώΩθk^ ^υρ gΑ§Ρώ>΅ΰ΄QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW½|4‘LΆŸϊW‚Χ½|7πF—τs΅rŸΏζ mΏφyuz‡ΖήΊ7ύΆΩ+Λ蒊(’Š(’Š(’Š(’Š(’Š(―Nψ(ΐK¬/r"?ϊψטΧoπŠμAↁ܁q"―bΐ†ώA¨Σ3ΓΈόFGγTθ ¦-."»΅†βέ·E*FυdW”|YπϋZj_ΫΘ~Λv}ΒKί>ΝΧ뚡π―Δι-τU˜›V=2y)ŸsΘχ$zW¦άΑ έ΄ΆχQ,Άς׍Ί0€ΝWiγ^iIs¦€—zw\¨Μ‘F·Έύ+‹¦EPEPEPE%-QEQEQEQEQEQI@ EPEPEPEPEPEPEPEPEPEPE%-QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQI@ EPEPEPEPEPEPEPEPEPE”΄QEQEQEQEQ]§ƒό y«IΞ€i§uΛ I(τP{{ŸΦ€.|&πϋ]κ_Ϋ1’ΪέdpςφΗ²υϊβ½^ξβ+KY.lQ!wo@MΠCim½¬KΌK΅#^Š+ΜΎ*x&E±2«fι‡LŽBgΨς}ΐ΄€ΰ5‹ω5MRκφl‡žBψΞvŽΓπ…S’Š`QEQEQEQEQEQEQE($A ŽAκ> ρϊ:%–Ώ GXξFφCώΧO_Sε΄PΣ‘Έ!^6C)λXΪΏ…΄]]‹ήΨF%'&XvΗλŽβ+Εt?κΊ!Ζι„9Ι…ώd?ιψb»];⏠ΊŽΞ9x©t!š³ό1ѝ‰Šκϊ!ι•aόͺΉψY§vΥ.ΗΦ%Ήmρ#C”~π]@Ϋ‹?ϊ 5hxΓ§ώ_Ϋ Η…YcA[ŸϋςΏγI ²Λώ‚·χδlΒ}αίωύoϋπαK χ‡ηωΏοΓ…bΒ¬² ­ΗύωγK ²Λώ‚·χδlΒ}αίωώoϋπαGό'ήŸζΏώ‹ ²Λώ‚·χδ/ό*Λ/ϊ άί‘ώ5³ χ‡ηωΏοΓ…πŸxwώ›ώό?ψP/ό*Λ/ϊ άί‘ώ4Β¬² ­Ηύωγ[_πŸxwώ›ώό?ψQ χ‡ηωΏοΓ…bΒ¬² ­ΗύωγGό*Λ/ϊ άί‘ώ5΅ χ‡ηωΏοΓ…πŸxwώ›ώό?ψP/ό*Λ/ϊ άί‘ώ4Β¬² ­Ηύωγ[_πŸxwώ›ώό?ψQ χ‡ηωΏοΓ…bΒ¬² ­ΗύωγGό*Λ/ϊ άί‘ώ5΅ χ‡ηωΏοΓ…πŸxwώ›ώό?ψP/ό*Λ/ϊ άί‘ώ4Β¬² ­Ηύωγ[_πŸxwώ›ώό?ψQ χ‡ηωΏοΓ…cΒ¬² ­ΗύωγI ²Λώ‚·χδmΒ}αίωώoϋπαGό'ήŸζΏώ ²Λώ‚·χδπ«,Ώθ+q~GψΦΟό'ήŸζΏώΒ}αίωώoϋπα@ίπ«,Ώθ+q~GψΒ¬² ­Ηύωγ[_πŸxwώ›ώό?ψQ χ‡ηωΏοΓ…bΒ¬² ­ΗύωγK ²Λώ‚·χδlΒ}αίωώoϋπαGό'ήŸζΏώ ²Λώ‚·χδ'ό*Λ/ϊ άί‘ώ5΅ χ‡ηωΏοΓ…πŸxwώ›ώό?ψP/ό*Λ/ϊ άί‘ώ4Β¬² ­Ηύωγ[_πŸxwώ›ώό?ψQ χ‡ηωΏοΓ…bΒ¬² ­ΗύωγGό*Λ/ϊ άί‘ώ5΅ χ‡ηωΏοΓ…πŸxwώ›ώό?ψP/ό*Λ/ϊ άί‘ώ4Β¬² ­Ηύωγ[_πŸxwώ›ώό?ψQ χ‡ηωΏοΓ…cΒ¬² ­ΗύωγGό*Λ/ϊ άί‘ώ5³ χ‡ηωΏοΓ…πŸxwώ›ώό?ψP7ό*Λ/ϊ άί‘ώ4Β¬² ­Ηύωγ[?πŸxwώ›ώό?ψQ χ‡ηωΏοΓ…cΒ¬² ­ΗύωγI ²Λώ‚·χδmΒ}αίωώoϋπαGό'ήŸζΏώ‹ ²Λώ‚·χδ/ό*Λ/ϊ άί‘ώ5³ χ‡ηωΏοΓ…πŸxwώ›ώό?ψP7ό*Λ/ϊ άί‘ώ4Ÿπ«,Ώθ+q~GψΦΧό'ήŸζΏώΒ}αίωώoϋπα@ίπ«,Ώθ+q~GψΡ ²Λώ‚·χδlΒ}αίωώoϋπαGό'ήŸζΏώ‹ ²Λώ‚·χδπ«,Ώθ+q~GψΦΧό'ήŸζΏώΒ}αίωώoϋπα@Ώπ«,Ώθ+q~GψΒ¬² ­Ηύωγ[?πŸxwώ›ώό?ψQ χ‡ηωΏοΓ…bΒ¬² ­ΗύωγK ²Λώ‚·χδlΒ}αίωώoϋπαGό'ήŸζΏώ ²Λώ‚·χδ'ό*Λ/ϊ άί‘ώ5΅ χ‡ηωΏοΓ…πŸxwώ›ώό?ψP7ό*Λ/ϊ άί‘ώ4Β¬² ­Ηύωγ[?πŸxwώ›ώό?ψQ χ‡ηωΏοΓ…bΒ¬² ­ΗύωγK ²Λώ‚·χδlΒ}αίωώoϋπαGό'ήŸζΏώ ²Λώ‚·χδπ«,Ώθ+q~GψΦΟό'ήŸζΏώΒ}αίωώoϋπα@ίπ«,Ώθ+q~GψΒ¬² ­Ηύωγ[_πŸxwώ›ώό?ψQ χ‡ηωΏοΓ…bΒ¬² ­ΗύωγK ²Λώ‚·χδlΒ}αίωώoϋπαGό'ήŸζΏώ ²Λώ‚·χδ'ό*Λ/ϊ άί‘ώ5΅ χ‡ηωΏοΓ…πŸxwώ›ώό?ψP7ό*Λ/ϊ άί‘ώ4Ÿπ«,Ώθ+q~GψΦΧό'ήŸζΏώΒ}αίωώoϋπα@Ώπ«,Ώθ+q~GψΒ¬² ­Ηύωγ[?πŸxwώ›ώό?ψQ χ‡ηωΏοΓ…cΒ¬² ­ΗύωγI ²Λώ‚·χδmΒ}αίωώoϋπαGό'ήŸζΏώ‹ ²Λώ‚·χδπ«,Ώθ+q~GψΦΧό'ήŸζΏώΒ}αίωώoϋπα@Ώπ«,Ώθ+q~GψΡ ²Λώ‚·χδmΒ}αίωώoϋπαGό'ήŸζΏώ ²Λώ‚·χδ'ό*Λ/ϊ άί‘ώ5΅ χ‡ηωΏοΓ…πŸxwώ›ώό?ψP/ό*Λ/ϊ άί‘ώ4Ώπ«,Ώθ+q~GψΦΟό'ήŸζΏώΒ}αίωώoϋπα@ίπ«,Ώθ+q~GψΡ ²Λώ‚·χδlΒ}αίωώoϋπαGό'ήŸζΏώ ²Λώ‚·χδ'ό*Λ/ϊ άί‘ώ5΅ χ‡ηωΏοΓ…πŸxwώ›ώό?ψP/ό*Λ/ϊ άί‘ώ4Ώπ«,Ώθ+q~GψΦΟό'ήŸζΏώΒ}αίωώoϋπα@Ώπ«,Ώθ+q~GψΡ ²Λώ‚·χδmΒ}αίωώoϋπαGό'ήŸζΏώ‹ ²Λώ‚·χδ/ό*Λ/ϊ άί‘ώ5³ χ‡ηωΏοΓ…πŸxwώ›ώό?ψP/ό*Λ/ϊ άί‘ώ4Ώπ«,Ώθ+q~GψΦΟό'ήŸζΏώΒ}αίωώoϋπα@Ώπ«,Ώθ+q~GψΡ ²Λώ‚·χδmΒ}αίωώoϋπαGό'ήŸζΏώ‹ ²Λώ‚·χδπ«,Ώθ+q~GψΦΧό'ήŸζΏώΒ}αίωώoϋπα@Ώπ«,Ώθ+q~GψΡ ²Λώ‚·χδmΒ}αίωώoϋπαGό'ήŸζΏώ ²Λώ‚·χδ'ό*Λ/ϊ άί‘ώ5΅ χ‡ηωΏοΓ…πŸxwώ›ώό?ψP/ό*Λ/ϊ άί‘ώ4Ώπ«,θ+s~WόkgώοΟσί‡ OψOΌ;?­~ό($|,ΣΏ‹T»?H—όjΔ td`eΊΎ”zeT#Wό:?ερΟύ±πͺ·?48‡ξΕΤηύˆ±‘@šG…΄]!ƒΩXFe"YΏxΓιžΰ+fG3ΘΐΙf=+ΜuŠ<2ιΪw8αη~‡ύΡώ5Εkž%Υu²EυΣs‘ |¨?ΧρΝw>6ρϊ"=– w9Y.‡EφOSώΧOOQεΔ’I$’y$QLAEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPΩ endstream endobj 52 0 obj << /Subtype /Image /Width 256 /Height 279 /ColorSpace /DeviceGray /BitsPerComponent 8 /Length 56 0 R /Filter /FlateDecode >> stream xœέy`EΪΖη —ΰr@"DΔEΔED#ςΒ~b8pQ1 μ.*β‚€h@ΐˆ€P?\E.Eb9„ύ’pˆ@\D„E–`€p‰$™ιΝδœξγ}««»ΐߟ0Υυ<“™žκͺχpΉ­Ho£ZƒB9­iΕ³λ©–‘ˆί|¦•s€‡j%Jh½O«Δ?χ7ͺΕ8OŸσZ ϋ§ZŽΣLτkΑ\ψ£jAŽβ£πOυ¨ε«ŒφΛH U-Λ)Β7μkΪ†Ϊͺ…9Cθj’}MΫ\G΅4'π ΨΧ΄τΥβΰ=ͺ}M[ρλΏ ŽbΨΧ΄9ͺεΩMOΣΏ6\΅@{‰>ΓΆ―wR-ΡNΒΆsμkΪαHΥ"md*ΧΎ¦­T->βJώ΅GUΛ΄‹πύϋΪιFͺ…ΪD"ΘΎ¦-T-Τb ώ}ΏW-Υ>ΪΧ΄ ΥRν 5θζWΑƒͺΕΪ@*άΎφ΅j±ςiΓYψκι¨ZtR0φ΅%ͺεΚ¦α/(WnP-X2cQφ5ν/ͺΛŝƒτΏY΅bΉtDΪΧόC;^―Z΄DήΔϊΌW'υ» pqw‹γ’gξΙΙΩ—έΟv/"μπ_Α‘₯#nc\8δι/Ώώ`˜c¦ΰ4@¬ύϊ°?ρ<μΟK/˜^ό’ΣζxάςΒϊ"Kφ”nIμθΦ_·υ,βfΪα56Ι΄LάeΩ{‡f½w,£-()΄«'ό‰,?E€ 'D—_9:…~αmŠ]WΡjζYΉζΛρ₯=βΛάJh₯Ϊyž?eJώΣאχ/φΏ‘ΪΌ+μٟμ2 ΧΝWh'uΖW辌v*έ‡Uμ^ι $α jχšΆΪgήϊ7·Ž-£1댺‡Κο}5jIτέθαο€l>Tσ‹γ?΅'kI•ζx˜• Ms‡$λ½§€ΣlKφ~8(:θΥa όΆσ„uο=gξΜ”»παΚ •Έ½ΆΫ3Υͺωή‹.‚'+ό2‘Ά+bͺ΅G<ΉXΪ>υφI½Œœοβ"μώ–½lwίδ΅ΓͺΥ[η'aϋΓpϋΤW)G„ύΟU-] g…ύγŽiVN ϋ_«ZΊ ϋΟT-] {…ύ§ZΊ„ύ ZΊ>φΟΩZΊF/μŸ y- žQχ Ή%‡6-Nή―K›¨ϊU9 nλ™0ς­ε»…Φcβ„e{csκλδ!]šy‚<1ϋό‚}ό+SzŸ°―μρI d{ς£1PY‘½¦d v.Ζ‰ϊΗDi‰γΫ‘Τ}ΌΡsΞ!θηE¨L‰yς)^?΄± :W»qΩ°Iςο›`²½ή΅5 υEΝWΠfϊ1ΘDg~+tυmuŸ3ΟΑΓŸψU8(τ!{ά>σώ ½€₯w5I:ǝo‡H:a'»άΟ—{,[ηξAˁc€&φΈΏςψ§ŒwΰΏ9³ΞΔ_Τ}ΙχώΤ[€»ΰΐΩv8€lϊ#ΩAΎυJΒFœdΝ\€―«°\ΆϋόaΆ&΅Φ™^̘|Ί²Ζk’ν/ΏΡΧΑ΄έ̘ώ l,D/©ξσΖrfd•Ž@^μ&™φ3›ΪbΨDδ2ͺ„BVτ( ζ …?Iζ9<›§¨η•;ρ_Θ²Ύ§=VΙΔRοq!Ι~Γ•½Ό‰”€Π’»PΧi'ΗώvΫοϋ&zPβ-χ’*Λxx)ϊ 2U”΄ŠήA3uG€kΤT2 ŸOTSˆzψπΌ\Y ϊ8bΤ-ͺ¦@ƒ«φW+,ε”@Tϊ)Κ°h”>€}βŒ€ΏZ³Ώ]q«.ζœά2ΈΑ+φΕφέdrηi³ͺӘί#+aœωbϋRΉπΌŽίOάΎ/ή6WΪη›„ >–! v"β'ΟR‰3oγΝF ]Τώ*Ε©ΥΔ›v… ‡ΒM—G―žβMOšB“£ Ωχu·Νž1Fuη'ν„’·¦ΫηF€χςF"SΐώΎ««|cH†AίaΔvT;TΉ’r|βQφΠΰ€Aa_ΔΰΟΠώgΩfD”Ϋ τ Χ!ΖΖbΑΗλΪζC˜Gυ}˜}€YHrnδcgŸ‚ΪΠΌ†d±YΚΗέ΄Λ3o,ή°-»œoΣS’Η>Ω]ψαΊ=:‘ΗX‘fF†bμϋο•Δυέ'€‘χρΟo;’=F|mτ»έCέYK΄ι‰΅•“Bu~͘θO™~;CΜΠίΒΛVߊΥ₯η¦1”­[#‡’χ1πθ":Ο 6&G‚ύ„d$n λ ΫΘΙΩ¨Sύ–Ίd6Td°š R‹3Œg >ζzΣ pψΊ6ά ΊΎg9˜ξbg^‡zƒgΘCέ@€Α >αoνλ…άΈ0Ήp’{‚Χς˜Ϊu€!Η«D¬—>ΥQΓΕ)ΐΏΰUΠX„Ύ@!ΉwΕρβΧΈδ=ϊ8GKf!?ώ»„ά‡L—‘1½τy]3ΰψϊρ*bΏΙ& ξΛ(8Ϊ  œ‡?₯ ¦ΰ’ΘQw'ρ-f#?Κ%'ΤΌ| XγG°ωη Ψ‚Yππψe7ΒΠSΦ .ŽβΞƒM/Π±`¬δΪPιάr©ͺ_{*“ƒ~$qO—λ> ‚lδ©©ΞΡ(X²]mΛύ‘tϋek^±ΑΥ/…>| ›Ή-Φ[6Ψ/[ƒΎΒž5¬ϊΫ \…ΒŠ€όˆ΅¨D’Μώ"VΟϋ Lη½°Y±Ηm+‹§Νcξ \_Υpp L(πλΞώΦKYʌ;J|Υ1˜RΨ Πq\p}{«£­amο΄©|‘tLε!EјΑeΪ»Ώ„\³ψdNvvφΞcψ#(νΦ=`[ε‹ZC€Ά‚M8εŸέό«ŒάΟ^θSυ5Υ΄σσ vγή…·³«| (nh:_CŒύ–Μ*ίζΏ· Šμχ8ν·Œ—ιΣΧ­όE{’u&hΆaμ»3W:;ƒž#ζŽ›yκί]ΐ’Š—°>#Υΐ €.Uγ@εδKΧ±Η†>­Μp™Ύ λZρ ΘΐSΐž₯’ώϋυ©)«E―BB&;₯Γή€ύΤƒXwEi³΅€Ιbasa™§Ρ.’Ωx…Ξί‚D­€ώΜ.oSΕƒf:  )εζW2 ώιy”œ@έβΈΏόΏχf‚­—•»\“/‘‡Ϋ>ˆ\ uεvΚθZεoίIΐ<ω.Όy«ϋ{tA€§w¦lZ€Οόΐ^Μ«Φ .›όΤ›&°wΨPh”φŒΫ?πŸ—“ΐΆ'αq ΅‰ΉIiˆcΌκς%‹(YυŸΒBώa §Τ|ΈζΏΖgq~τixY=„+ΨHΊ%πζπgh ±―m‡K&ρξ'6υΑo$J‰u τ`|Ÿω ¬χΒθ ΨΜ\£&{Ι·ΐΦ>@ά­ΐƒ―I`Ήγ £ΐέx›'ξYςΈΎkήγ‚7zz8ρ X-‘ͺpކ›’}Tμζβ ―ό &Ή™ OόΛ_A(οq”ΘU[` €–Y&ž1΅^‘ρQΆΊ<|’w4ͺ„;xσγΣΠo%„KvεDO<޽`«’†?xοΣ|’Ψ«Δl}¨Ν™2:#Ο€/@/άΤ4t+R™°ΩQq)ξΏcƒqΐUΆ2 •Tβnφζ(&ν9π>ϊzΩ82WVI ωLΕπέΩΪλΠφαί/Σνo‚Y7±)A;½ΓoΕόo1Ž΄.j€} „ΆBk&ΤΆμίxθυƒ Y7°λ΅Α’‘oλΪφo\T$ Ϋ53›)τ„Ιω±κΏžq `Ό$‘ζΜ_­y’5Ώ‘ώ£ γ|RkΓ¬aIτσ«π„γ\Μ@ήά- γΠ!#L΅U‘ΐ/”ThΈ¬¦‘­‚HΞ,=dmtiόCoeύ­Έr„Αξ…dŽ1l.YCϊ0lΣn“ΈΊŽ­ΠbqΫCG2P€ΫΏOCηbά_Υγ3ί’‘ν™œ€VΊWRZ,oΘή-0ωχ‡‡ρΰσšΙς?‰©ο8aΔ»ύ³6ΨtΤ5€qύ «` »c ινf‘€ϋ|t3UΗ­Zƒ½–έDJΔ„]»\oF~-Eΐ„[Ή8Q„ΌF―EQP₯γYν@ι.O±ε#-ΓWI{h;LfκS7 f=r!OΉκe­Oeω/€›šφ­΅ΪΡΓO }—ψ&{ώOΦΈn6εςN’GB‡NXο€,&KͺΕP bχ›†ηO"ί[Ν+τoΰVTŸQHɊ~ ξLg!άΏ+’Θ[Ότaγ.…·ozω_‡ΐΘΣ4?e•v°Ζ¦Ϋr±ΑRΑΪΡT­[ Y|ΌςίOqΦ¦π%Η6j,άγάpZϋβΣί€§¦ί\z‚W\nPαNJͺ]X²”›ΐ0ŒWΠ‡6€ŸS³<Ό‘I-O/£γαYDw‰€μρ°;Ο9^Ιvx³RκwτFρ"œ5|ς_φ;π)`f ·i "ny;υ;κŠ«υMΠσ»TNμΥΞϋΉΧθŒQψWϊun΄ήτξΎ΅{tγ«·½?ΰžŠΪΘ<Νͺ2Ρ“ΣJšO†@}ςZ=ζ7/σ?ΥSGύω9 @BGRΪG‚ΑTΧ―ΑΫaԊœΰί βμiχ7Υ2pσΨρυgΠ~—aψPΕ΅uΤiΤKc¦Lό\Ϋΰi{=± y•Z£ή±ΤώύŒάcaθS¬ά[JΓ)VΎ{νς ^ σ β±Šδε¬ιΡ HŒΐgυSΠ•ο~_8:βΗ y2δ]Άh ι½Pπ-xΣ^Χ5NΪ“Ρ·^.κ#$HΎ‡YŽοτ`yΕ3$1ΛΑ C—₯бvPϊΌ£ξΝYΜj)@τ`“₯‘ŸώƒnΏn™Υͺ=‘"΅”8 f΅=G)αΌ{— Χ$ΗFr%žμ! ΅²S,˜]:’퀃ɺ–ˆx†d Υ7%sΥάΰν₯Βο>κΈœkiπ:†γ+Ώ Έ'’ΉΘlΫ`Tv·•AͺW’©ΖΎλnΥΖ+™¦Θ H?Ο²eΗ¬»".\`Βηυ\ΖCWKЍα²έqT˜§ œ¨ͺyR–€jC¬UeŸί{Ί"]θkΘ=#—K*<θm(P‰[H5>u{qξφΛφ―ΐ{[Κ¦,όΰ#Œθ†w>aEεη2ٝ#―jΕ%~yXΛr2Μυκγ Υ[tό­dgΜ endstream endobj 53 0 obj 12037 endobj 54 0 obj << /Subtype /Image /Width 1024 /Height 1024 /ColorSpace /DeviceGray /BitsPerComponent 8 /Length 57 0 R /Filter /FlateDecode >> stream xœνέ]h]ι}ορaŒ1Ζ!$„P…ͺΚ¨B Υ•+\«FΨw„±cΖ3υ`γΑΣ’‹ΆW…Άττζœ$₯½JsQ8„hZN_rΣ‘‡N ι )i&Ι΄yi“Ξ0™7Ÿg­΅₯½eOf’zkiόϋ|˜Ό\ΞΪπύ―ηyΦΪ[=ΐΓτ8πΎuέλΓΡυ§t]7ό#κϊcƒGGΧ5pήλjžφx4f€ΪααψΐΝαΓΓφAο3ύCΐΌΟ!Πuητξρο^ίαZwŸ/d{ϋψΰŒ€Ζί^SοΊ*G€h'–¦Α1p0'ΐβ/ε7α—Kκϊ3…š:œf Μ€ƒ7φΦ_·?p·?z΄ϊgΧ1`ώBJ1»“ ύ3ΰ` €=υ·ϋ˜φž?Xϋπ'B»hΟάΈ―ώφ{ε75Z΄3:μ1ΪίHί(h‡@;Φ¨Ώwλο΅ίλ~l ψqΰ¦ΑXoμΜ€EΐA}υίίώθΘXιώΗζζo|μS/|φs/~ώ ϋ—ώώKΐύύ—^ϊΫ/|ώΕΟ}φ…O}μ7žύ™/s`ldτώΠ7ΊΏwσoόJύεΆ_ύ«Ψ‡>υβW^{η?‚w^ϋΚ‹π‘«We΄j„%ΐž₯αψGJόΏπΗ/+ώΫήyω‘Œ€‘pxΟ& γό Τ_βΏτ'―uύ©Α£γ΅?ΉΤŒ€Ύ p¨ΣΠΏυoWώυ­tlό·_ιϊγ‚GΝ+Ώ=^oFŽ΅»€NώΚΏP{οŸψŸΩυ'’ό_νΰH& ‹ΠΏφίΉωWυΚwΊώ”ΰQυ_o&ΐΡώ ° /ζ™_}δ?>ώΧυ'²Ώϋ‰ρρΡή轴ߠρίΛΏΌΨσλotύρΐ£ν_/― υ@'[€½'eη?6>1ωg]6πθϋ³Ι‰ρ±φ`ΰpΏσ―GΤ;*―vύΑ@‚—Λ({€*Ύύί δΈ¬ύ«ΔΔO½ΪυΗ^ύ©‰‰r pμθξw‚φmμφ_ǎ«oώ§lύaŸΌρ³υΰXΩ΄[€ύκΏ—σΰοhσΜς§ίμϊ#oώτdσ.ΐѝǀϋ3ψΔΤροwύ@’οŸjφy ,ώ«όGΖΖ'§¦ΏέυΗYΎ==5YΤ`w °ω·ύ·ύ«όgώ¦λόΝL3ŽΥ+€ύ9Ψ]ύχε?ύρ? Θσριώ°/;€έΝyν§μύ«όλύ\=FGΚ‹@»GCΞρ'##£γ“Σ³6ЁoΟNONŒΧ/΅GC^μΩόŽMLMΟ|’λ2}bfzjbltΟΐπσ?ΤΌφWέύ§f~―|A'ήωΙ™©zP^<4τΠψwμXsτ?χΉ?HυΉΉήC€ώ#ΐαζί[ύ—χ~¦ηΦΊώ ΧΪ\΅ݏΐΐνΏ=ϋ›‹?Θυσνΰπƒ«Ρ±²ωŸ[΄ϋ‡ΞΌ³Xvε«@Γ;ύ7«±ΙΙ™ΉγΏΧυΙ~οψάΜδδΨXύ `Ώϊoo³σ ήυυC²_˜ŸέY ³Ύε{ψWέώΎλΛ‡l?_-ΚWwŸgμΌϊΧ»ύOΟΝ/|¦λ«‡lŸY˜Ÿ›ή=V}κέ}ϋ_όfΧWΩΎΉX/ΖΪΐ°φŸώ΄·ΕχΊΎzΘvοΔb»ζ ΰξςhέΤΜόρΕίκϊβ!έo-ŸŸ©Ώpτθπ6ύ§££υ«? Kήύ…Ž}ni‘~ ¨~ pηπαηΏσπ―^ώΟTΛε―u}νξkΛΥ`¦ή ο`ίςΏ~υwzvnaiευ―½Ύ²΄07;½σ5ΐaυΏsϊ_~υ§Zώ/.Ÿrό»wͺZT€ςχϊž<μόNΛΓΏ₯•t}ιΐGV–šG€Γ{0Έύ―–3σ K«ΏΫυ•Ώ»Ί΄0?3έ~ p¨ύ·οώ6ΛΥΣυ•ŸYνm†vΠί»ό_\9ρΊΎrΰΕ+ν;€£Cμgϋ?26Y^ώYZ]RΧW|i}u©Ό496πpσίέώΥΫΕ₯΅υ—»Ύrΰ_ͺώλ€±!μΩώOΝΜ_\^[χνθάΏ­―-/Ÿ™ΪΐΆK+'N~·λ+Ύ{ςΔΞΐ‘φΈν²ήώŸΨx΅λ+^έ8QLΆύF½ίύ.Ηειςκϊ)―Bη^?΅ΎΊ\ήh?τΐUΫSov}εΐ›§Κΐύ€½jύίόςίμόβΚΪϊι·ΊΎrΰ­Σλk+‹Ηg›_άύK CθΏ|ωobj¦ξδι·»ΎrΰνΣ'λώg¦&ΚW~ƒΗυγΏ₯•§ύνθά;§7Κ€α=άΣδτ\}όΏ©θά;›υ€Ή™ώ――ςψoaiu}γŒώ‘sοœΩX―Ώ89€—·K§Ξψωθά½3§šώ§&‡σ@―=υέ«ϋx`ˆύΆύ―ι‚ZΫθπϊoόkηυŸΣ[ϊ‡ΞέΫ:½σΠΞO€=δώϋ_›ͺΏύwRpTύŸ¬Ώ85€Њώα@¨ϋ_ΩΏώ§ΫΧτέkϋŸŸΦϋ―ςηΚ ύΓAPϊ?±RΠαχ?Ϊόεί•΅MύCχξmmn¬5ύOŒ±ΓM폞ά<«θά½³›'{?\χ°ΏΤυίϊλυ―逦₯ήώ€οϋϊ―ώα ΨΣΓπΐίώΨωϊ―ώ‘{χΞξ|xbΰoλyϋΪίΟθΊΧΧΰ€ ·Οΰ(Οτ™φ»ιΉ¦λθ^―ΉiύCš{gυ©τΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉτΉ:띯xG««ώ·ήξϊʁ··φ·™YύΓAΡλvfŸϋ«λ+ήκ¦Σgίμϊʁ7Ϟ޿ώG'vϋ~ΧW|·‰Ρύλσμk]_9πΪΩΝύιp'7Ο~―λ+Ύwvσd‡‡Φ‘ΑώΏέυ•ίμΘΠϊ?φ?w|±ξλ]_9πr΅ώ_[Y<>Χφ?¬υ‘¦ΙιΉωΕ•΅Ν­μϊʁάͺϋŸŸ›žlϊ?4ΔώΗΖ›ώOœ<½υ…―ψόΦιjύ_χ_ž »‰ιΩr―ϊΏ]_9πΩͺrŸžΨ—ώ§f7ύAΧW|²ιψμΤώυΏ\ϊ΅―ψ΅ςpϋΌιθΘh΅ώŸ™―ϊ_?½uΩ€@Ηξmo^―ϊŸŸ©Φ£#G›ώθύ?qΈξl²κ‘κΤ™s―w}νξυsgNUύ/TύOŽΥύ~bxύ΄ύ―–ώ_ιϊΪ!έ+₯ΥΆ‘aφ_ΎPέ§ͺώ—κώͺλk‡tUχΏTυ?UέΛλCκPΣΔdΣΖ™sοϊΪ!έΗϝΩhϊŸœhϊ?4ΤώΛ @Η—VΛ€8„nέ»\~ώcuιψάΜδψΎτΏϋ|:υν οφσ­ϋΏάΎxώΟ»ΎzΘφηη{― λλΏƒ__*ύ―Wύίνϊκ!ΫέσερίλΓλη Ν @§Ξœ»ψέ/’}χbσψΏyύg(―υΐΰ g/ώο―’}ϊβΩϋ£ΎΚΐφΐ…m:σΞφ…φψχρίΓ~όί ε€κ_Ϋ:ισ]λσ—Ξo5Ώώ57΄Ηƒύ· >Ψ:wρι?ΘυτΕs[υφψlσλCνΏp©>Ό°νG€ #_ΨΎP-=ΰψο!φίχ >œͺΦ76ϞςCή„NάϋΠ“ηΟn–·ΧoτΎύϋpx°Xήά:ις§»ώ Σ§/WΫςφ_σγΏΓΪώίw0Y~pyυdyΰΙ+ή€|χΚ“ειΙΥεςγΓΫώο9h~h‘Ω\ΈtωΓ]θΓ—/]h– ν iϋίίω  '€§ΟœΏΈ}ε…?ΘσΒ•ν‹ηϜnŸώ•εφ‘φίφ}Έή”W/στ΅ΛΫϟέ<΅ΎΆR§z·aζ?pX-Ζ&'Λ`iuύdspυ©j<ϋΙW»ώ„ΰQυκ'Ÿ­ςκj³ω?ΉΎΊTn““cυνŸϊί9hw'NnΦ«pγ™[·Θƒ‚Χθφ­gnTω׏ώ6OžhW»»aφ?8Κ#€ςPy `ύT9|²ן~ζΩ[w>σ]Rπ¨ωΟάΉυμ3O_―ΟώΝ9}ͺώΥϊ՟ζ›CΞΏ`ύΰψdσ  ZlœήͺVΫ—―•=ΐ­Ϋ·η₯7ΊώΈΰΡρΖKΏsϋφ­²φ―φώΥέλτFΉύΧg“Ν³Ώa>όν`€έ”ο­oln=ρΙ+W―=]–·ο<χ‰—Ύγ—ΑΰΏνήw^ϊΔswn—›ΣΧ^yςβω’zωήO»ϊُΫί`η% ήX;yjsλά…KΥΰΪυλ7nή|φφ;w?ϊ±Ώό§o½a ΐδήίϊ§ΏόΨGοήΉsϋΩ›7o\Ώ~­Zϋ—»ζΖΙ΅ό{―ώ ϋφΏwP `Ί>lΐΩσePŸά|φΩΫ·Ÿ»sχξσΟςoώώ ϊβ_ρΎόΟ_yωkίxε•―λ7 h}σ_Ώ^Ίxε_{ω+όεψβ_Ώψ§/όώoώςσΟί½{ηΉΫ·Ÿ-Ηώeη_­ύ«»fyνΏ>ϋ›_όί—ΥΫο/–@sΨ€Ν3ΝΰΚ΅jά¨Fΐ­[wΚ2ΰΉj<όh|xWm&₯˜*œκΖηΦ­*ώUύΧ”›Ή­3υέΏδߞύΥ«W†Ψξ ΐ‘#ΝŒON•Ÿ©Οκ=ΐω‹ΥΰΚΥfT«€[·oWΧπܝ瞻{·όηξέz{Υy4₯TΙTαT›ώjα_ΧυJuσΏxώ\ΉωΧ{ς£SεWJώG }χίληπh9¬ΐ|9(Κ šΥΰjY΄3 ZTc •濁ϋυ©Β―nϋmϋεΦ΅άϋKύεζb΅μύη›όGΪΥ~άώwΐύ`¦=\[ί8΅yζμΉ Υ(‹€jP-nάxζ™j ”9PM‚ζΏ«‹»΄κ$v©r©’©yϊzuη/·ώͺώ ηΞΩ<΅±ΎΦύΝτηΔΎδίΨό5πvPΐςκZy`sλl½ΨήΎR­=U†@εFν™ž›Ο­έšNJ1UϊO]«ξόWΆ·λ{Ω­ΝςΤmuΉδί»ϋΧρ{?vϋoš0ZΎ 8=3;Ώ°°\M€υ“§š P-.mo_.Λ€kΧΚ(ƒ`ΧΣΐŽώ6J+₯™rγΏΌ½}©Ίυ7υW;ͺώε……ωΩrς_φώ#ΝβVο2κΚ«ΐKΛ+k'κ p¦e#πd—―T6]k­ύ?ΏŠ’ΤrΉ€dYφΧρŸ©λ?±Ά²ΌT^ϊ­_ϋι"#€ϊ›@εοL΄‡e°ZM€S§Ο”PΝ€z!PjTυ•]v΄Y₯”*όϊΆ_΅_β?sϊΤFUjYϊ·[rχ?vμΨΐβ?ςολΏΝ‹€£γΥ`znώx½¨'ΐF½ Ψ*Cΰάωj)pαbOua—€₯‹ž*—σUωUϊ[υ£ΏΎχŸŸ›Φώγ£Νk‡ϋ^όΫ—ώΐ‘£υ‹@Ν`vnΎΩ¬΅# šΥB`λlε\«Ί°σΐηκδk₯—ͺό3UϋmόkMύσσs³νΝΏΌφSϊίοόϋ@³¨φε1ΐΔδdyΈL€Ε₯•j¬­――oTC L2Κ((Γx°:‘ΚιR~•ώFΡZΚb]ΜτΤdΙΏͺΏΌφΣ.ώχ5P›ΖΖΛ“ΐf,,.-­,―VΛ€λλ'+υ (Nο’i€ΤRͺY_?QέψW—W––šϊΛSΏρ±φ±οK?ϋœή-@3FGΗΛ&`z¦Ω”°\νͺ!PMe'Χ› jσX/ΩWͺΫώj΅κ_ξΕ?;SnώγeηίζίΑβΎP―š 0ΦΫ”E@Υ ¨†ΐςΚJ™υ(~¦”*™ε’~΅μ/ρW·ώήΚ¬WοΑ_ωnš p¬™Se03WVǏ/TS ŒfμZZi4΅TΩ,,TUν—ψ§§¦ͺ΄šϊυΧίIώνθ?¬—Υ. ZLΤϋ€²˜­eTƒ ϊ§ ƒΖBc‚νΝ`‘Ξ€τ2_ίφgΛͺΏ^χO”CͺώήΝΏδoσο‡Ϊ%ΐΡ£ν l&¦κΣΐbΆΊŠ²(³ v|Χ<{@ ₯”RΜlO9ρ›š¨ώΝ½h{πΧ·φο"ΐ eLΦC ”IΠ\PY{υς˜©s™žͺӟ,ν·ρχΧD·wέΠ›‡Ϋ]@³(# Z”σΐ²˜š,η‚­©žiˆw_u,eΕ_Ξϋκ½πoγ―_ωλ―Ώ«ό<8ΤN€£eΤ«€‘±f ŒW[—r&P›ήΕN#₯™¦ό±‘ζΞ_Υ΄­PΗ[½`w°wT j)Π¬γΐ»Ψν€Ξ¦>οΫΫώAΉωχ€v΄ί j7e4S ™£νŒχιo€©¦θh»μίύΟnύ]η  Π7Κh¦@ί(ήέn/GΫτ{νΐϊ‹= > θiΗ@= ZΗ€ϋτ%r€ HοΐoχΘ ΥΨξΨ™ν (Cΰp=Ύ€JN}Ϋοo·ώƒ“c} oΤ[C‡Ϋ1pψπΐŠxXšvΪߍ@Υ_<ώΐ°3ΪcvάoO!{BzόΰΦ_{χπΐq ψΩτψkψWΌOƒUuέψ{xό>]|πΑtK]Χύώάοm ΐ{xlΊϊ‡σΌo]Χό#κϊcƒΊ~8ΊώჀλ^Ψ_Ϋ΄ά endstream endobj 55 0 obj 33253 endobj 56 0 obj 5272 endobj 57 0 obj 8054 endobj 46 0 obj << /Font << /Font5 28 0 R /Font7 50 0 R /Font2 12 0 R >> /Pattern << >> /XObject << /Image4 14 0 R /Image6 49 0 R /Image8 51 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 58 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 59 0 R /Resources 60 0 R /Annots 62 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 59 0 obj << /Filter /FlateDecode /Length 61 0 R >> stream xœνZΫrΗ]FOή—όD¬Θ*e4έ==—ΗΈ$ΩQœΨ‘K"ϊAEΗRΉ@;rR•ΏΚOδoς9={0A²RrqΈ³=Σ§§ητ >Άδ|k―ίtΑ+ώž·[οΌ§³ϊPοΈψ7ٟσV’¦θkσετ½¦`ΛφΒϋύ‘}έώ#ΫΗΏ]ώυΓ;ίΎ,°½SB°αΔ—μ₯Hϋσϋ+™ϊΠ~°=ΖkΝNεWͺ1GΞvE)†DfŒ gΙxωPΌ83ΝEsζ9Άœaκ3iΕ¦Ά6λˆδΑγΣUuχπΑώͺŽ½i9©Ρ’¦›†7ϊωω ?·Ÿύτγί΅λΚβϋUNCv%rbi•]I„G-:ζί΅i^6/šoš/›ΧΝορϋMσκ³vρCϋtqcΜδBΨΨd쀓¨c8VΫβ·?ψψr'o„˜ΌQ¨ΖΏB²+ι~‚u.kΰhndΌj ‹FžAΛ ŠrΠΠnBφ ΖΓ™Δ‘]ή%(»XΦ}\J%sjE«O>„ΒŸAΣζ^σ€9iNvγj»±ŒΈ₯·ΨΊΒ’tΙaFΨΝΓTν9ΪMΘ„Εt„!ζ=±gGΏG±^ lΐζ”e―1¬R6AW§,`Ic-9˜|£Λ‘$lKΎΟšηu%~ƒδ»γ |Iς… 1 u8imTi«/HA3[ώTJ9£ξ€ΣR½ήϋ|F|gαxΚσ–ΪZkπ‡φν·Ύύό—ͺΚxγΥ‹/`5yΐ€ΊΓ»'+v<μίΗΠε7Τρ'ΕT=ήt9'λJˆžc[ ‹‹A-BC %9\kΐΜw ‚Φςσ‡—»xm\η“Ϋ“€œnΔΕ­&Α$€δJͺσω–\œŠMXυ₯8н‡1pD@ μ±ΘRηΰ’u+!GŠϋ*ξU)%TΜ…[σ―šHΔ]f7Εhauֈ*Θ\³ˆ,‡ΪΗ:0Ή\`CŠ›€YΆ΄›ν–” p88†)*z‹AlU©Jm­Ή₯(Žpgδz•ΰΈ>Qg`.X‘²Τ0Ξ¦C’ΨUF’ΐ’{°±ΚΚν2²’δ˜m&ΕpK>φ˜­™Μ¬²­ŠY‚ Αœ€π5κ—5 $YЦXͺΈS [q`ω–3•~¬‚’Μ ε!ΐzA9΄›QˆμYVΐΙΘy¨ƒ>¬ͺ ΫΘ ’[Τ;˜‚₯δ™:x -’>ƒ¬2Ž | ab›%ίΆ‹η‡Θ’ΒŽΣγFΓΧ!KΐV ‡>Vβΰ”λΖ "UVΐε Δβ†ZΥκ©υ„ΝtγM<όυΓΊ F„rtτfβ;— m0ώΗΏ;χώ/‘}ςΣθ©mξHAλFt0—Ψ…mΤΣ[ND―τςΠtνΉ–ή±œ@ο 5†w«{¬[k±γj₯*«ͺωQsŒ:η5‚τMέΓ:ΖυΌΏ‚’>nξ5Ÿΰ}ϊ y Qύ7~5όkG½©# c€€^λΞuλ’LOp&˜žV9›°‚4ά—BcΫ ΫŸ4%,R\ρΖH»ΎΖλK=UΏQŸ^€Κ'5γtδuΫ“ΟπωUεοΈy~w].kΒaάm«d%±Ϊζπ…R–…™κZ)ϊυc[Ξ1ŸmνBΗ’’SΏ„/kEθζ䈜΅¬δQ@«M·‘Bρ|αiΦ[=›a!¨v‚l†E¦έ73`΅OYιΗ€œΝ»;ή6Žj|Φ„τΟ†@ݚΩΧ:~Ύ›w\‚©©•Ž ΚYιψ€¬t|Όm’cxΦigλG :~Ηύάο!NƒŒBZ׎‰lϊQw^TUγnΐœ\λ0οΒk‡π:Ω}ω‹ΎΤ?iΑ*r{"έiω“>γo:uρE“&[’ Š ₯υ|5LXχ~έ|ΊγͺΆΥLΐθ₯΄ΕΜMΈxTΆxDΞβDλ>mŽΔ3h9Aδ³Β64œA{oΣ9f!γέ₯R˜ώ?ΘΆˆΙΘ#όΔR “r^Α–3,ˆ8W19Ά°ύΕd@YS’_Kl‰Γw J•J_„Ω–r²οd oΝ‹άͺ87jLe«γηD==Ί΄8:==ϊγΡ»£O›γγιiσ/C>9zttπξ5v5†ΘΧ»s\r§ιΑ‡r="·-ς=G=ΆœaZβPŒm'l.Eΐ₯jH6™]’B#™‹!;›me¼˝?uƒ9nέ"°Im'Nw~ρΟ‰²λ3Η¨³/”6½Vήf#G³ιK™}ΎΐΫ„ΔΫκ±τo—ςFœ’ωΎHς]ξ$‘bEχ„-gΩΧ}ϊsδ±ρ ΌsT3ŠU«κJΉά·qΌ­27‚+Τ©zZ£n Nbvˆ–;βώ;qT’}γΕΎ>Γ€ύ~eΏ§>—s0Εθϋο`MΝ'π*ΔΗQ1ΞΐΠ>Κu=uφϊζ - endstream endobj 61 0 obj 1968 endobj 62 0 obj [ ] endobj 60 0 obj << /Font << /Font5 28 0 R /Font2 12 0 R >> /Pattern << >> /XObject << /Image4 14 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 63 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 64 0 R /Resources 65 0 R /Annots 67 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 64 0 obj << /Filter /FlateDecode /Length 66 0 R >> stream xœνZέ²Η^Α•η&›˜`Š,3έ=—qv Ž'§Š:Ž‘\ΒNͺς€ΉJž ϐ§ΘΧ³»Ϊ‘΄"‘ŽΚU•tV;Σ3ύυο¬ήΧZ£―_ub=ώ^Ύ3οm­u9$o₯ά±ώ7ιŸw†ƒΑ–α‹ρ YE/fν‹~Ύ5/Νχςήάϋυβ/o_[σ毐@ϊŽIΨAFΛ6'˙͏o$κ­ωφŽ9ΓkCNbOYΌ)P+ƒD§Β\¦Δ s8+Ωr«’)ϋ”¨ΖζmrΎ`γΨ«ΒiΠψxUΤ=|ΡΏή†Φ1Vc(ϊ–Ωη8ή4Ό±ΞΟη0Ρά{ψΓχσ†u)σoW9•Τζ@‘Ψxjst˜jή17ΖάnΈyήP-F(€T a܈μk„ΙΙyηœkF—v1—ΪPώmκPΪs’h˜[ς6Ϊ°b ύš›ΝύζΌ9ߍ«νΒμΦIΨ"λ„ξ‚CEΨU„ΑU{‡q#ra!ƒ0ΨΌud 3Oρυ 8οέζζ‘LaՎm€`D¦ΔΌ€Y»-žό΄ΉΈoσζIσΕΑœεΦ#’Ÿά—z{]£lΐjΚ’υAV)‘«S&Hiδs ίΠ¦ΰXΆί‡Ν£’‰ΏBπέ1 ψBk u8imΠV^Z ‰O€ρΣ“ψΠ‘³¬{PΐυZοu^ίIψ;fydœωΞθ€ί™W_[σ ψΟ₯*£Ι«g_@j΄ŒΥ…pφm’-rΟWδXΘqvAΎ‘μ?zΈ²$¬Δ"‘€u)xjΑͺΪ ^-T‚δΨβΪKQΠͺA~~ηΓ*χεs§γAν‘cŠΧ’βI©‘α(Ή’χβΣ‰T³: €Ϊœ[z cγ°€(d‘d]§ΰ$Q—£‡Šϋ*κυœ³L“ΒΙτλ΅HΔ]*7† fu ϋ€.HU±°¬½.Fΰ\­’‚ζFΰe ½Yo @‰ΑΙΑ6μ$»μOhΔΪ΅‘ Υ]yΝ5'²βu*WŠλSnL1+q1γ€uHd½JΔ-’ξΑ:F–εΣ2’’60δΤ“‚œHΗޚœŠυwϋPA,­ˆ*ζ«Τ/ŠpΤνBta'CΦζ@γ-%—ϋ½2Zˆ\A‹‚υε0nD–…Θžm”Œ˜‡~€±ιΓΊ §9Βɠ߁ ζœͺκΰj‘ψΚ*εθ6zΑη(LτpEΙΧfώ萲$SλΣΓ€ΰc”%ΰY£Ε™XZOεΰ–Κ+ΰ’‘άΠ«j’GXU7^Ηδ/ο”S0ηΈTQ¦ΰQ°ο”'Ζ`χ~σξυ›?‹ΉΓRSk₯΅πK˜#yΙΈrέYZη0λ'UΔ¨5h<˜8ηΨ·°fΜΞ6GΪσTΓvF7{!ΔQ‡ O‹Ylο#§]fg{όΩ‘[Ξ ElLŽ–ΰIσΎwοΣ«‡ŠΈrLžwχ‹βΛΑ(ϊ.Κ}W[—΅«Ϊr2Β«]Ϊ]ρtޏѹ57›OπΎΈέΌBχ 7>ώkGζ¦σŸθ26—sŒF.£Bˆ«œ1ƒu«œXFΪο[οεΨ۟4·%ψαΪH»žΰυ%Z[ψGξwε~f¨*©Pi)ελš ]ΚOΧ`ΏΊΝζ΅ƒyοžώ‚Νε ™ XElΞο”ώΈψSOωlφΡGMI(ΠJ6ŒΘ{Ώl>έ1«m#Ψ½Έ·ˆ9FiΒ6θ)ς¦xBΑ˜Έτυœτ)ς߈.*Τ# 2ΘM]NQΓUΟrBϊζ.‘5lα=EuΙΖ υ¦GΉ½«.{Ήρθ<'žŠΠήνυ τc{χΣoο*“…|΄kλΎ2’΅―D 1·Ι―ΊJ…N»γ‘EμκŒΛA;ωβώ5‚•X~U:)_b¦ΰ¨‚#δlΩ‘bΓΐ Ϊϋ&쏈&©6ζLξσχ#[¬9гr¬ΥSΙάθ|½€΄‚-*LXUεrμˆνίωκ“Στ·]\6›ΓπΓ»<„υΰPΔυΗw‰JΰίΠ"ί‡„4Ω{C³[³ωμβbφϋΩλΩ§Νπυβ’ω‡"ŸΜξΞn Ϊ=βB„ΆH6—s .+ Dϊ8Φv'š1³EΖ‘ΕU)o9r"ηνξi1|΄>βΪ(Σ©€°υ𼓃\΅vn~γŸΝŸ@ή­Ωk|ώόΖΏnόϋΚόm—ŽXΫΖ”τA n7jKsKΡΧ)ζ&Ί endstream endobj 66 0 obj 2051 endobj 67 0 obj [ ] endobj 65 0 obj << /Font << /Font5 28 0 R /Font2 12 0 R >> /Pattern << >> /XObject << /Image4 14 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 68 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 69 0 R /Resources 70 0 R /Annots 72 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 69 0 obj << /Filter /FlateDecode /Length 71 0 R >> stream xœνZݎΗξ+χM€Ό@n DŠͺ:§ώ.cΖ–'¬#‘u ²zνΰDΚϊ*y‚ΊXΘ†ΰƒ:ΡΏB'j±0[/b΄ψdC0–œ·Ԍ·c†ϊq#²­XLnƒβŒ1Š`tq#0QωόoU†¬BHΡ†šHY§ƒφ ¦πg¨Qu³zXWΗ›ιj=±»5μΧΠ:€Β<΅Α‘PX ƒ«v:μǍΘ σa ƒΝkc΅ΕΜSϊϊΞ{ΏΊΉ«¦ΐ΅!¬―™§Θœΐ,^U’ί»’B0K’„iJWhΑSL9Œ$γΫxn ;λJ¬)0—¬ †ŽΠΦ†‘5’’Ηj‘²°p Ζ;†Ε:΅vΙ¬ρδΥι)τ6―žWŸξ¬³€"ϊΑύx»ΧXλ’Κz¬TYΤΞσ’ΚFθς*c€4λRτ;_―’7Δλ‚ογκiΞΔ_!ψn˜/Ύ ARCν΄^m&«-€@b­ΔOgΩωV9Cέƒ“z'σBρ-…b–§΅©Ώ«eΐυ›―uύ τŸrUf'Ÿ^~ ͺA TLΙ©Θkθ/ΠΡ cτ6„.~!―?8Έ2Gp’‘Hb Β {=ϋ±€+εΩ‰…²ηž ­δ'χ.qΉ.—ZχbbΈOR '@Ιœ3 $βΔi@U§€Œο$Œ…Γ[$kZGΒV@Œξ+ξˈΧQJœ1I “―“"o έམΥ!μ<Ί !ΘΒ²za†α\Š­ Œζ†αeΌ,―x – Λ;Ϋ°αd’; KΧ†‚TVε$ΧȊ=Διm~ \(Θ&%`LˆY‘²G©CΙS΄€tw–1²,ΐ₯Ι€!ϋ(žδω@2ΦπΦh„¬“ΈΫ… K¬˜E0_Q}“Ν€‚„hγ£π²4om4©[+‘…HԌ ¬+(ϋq#2"[Ά2bϊΒ’wλ*Œlδ0Εύ\0₯XToP‹„»(«DGwΠ ΎBa"›(JΎηOw)K’U1έOήGY] k(π@ΘΔ¬œΝ7°TZ›DrC―*‰z=bEέx“ΏΎ—wΑŒ‘\E΅’‚GΑΎcšƒυ?ψμόν»Ώrύπ‡ARK₯5Σΰ%DΑ:Nx2ν^Zλ0Λ;EΔ(65zhά˜ΨηΨΆ°&ΜN:»ε†n*¬φBˆ£:<ž4²ΨΦ[N›ΜNz³C m™)ber΄Ο«gπ½#xŸ<=Ϊ•Γνc$Ή=Έ_`—7FΡwΩΤuށ“kF Mu2ύΠΪ>RJ9ςυ5ό%ΗΜΝϊlak%V©Ό3B‹]Ϊ}(γκx…>νE§š‡ψy†Ξν¨ΊY}„ŸΣ;Υ4q/ρβ³ώΏ6Τά#0?θ]Ζ*;ϋhδ*„°¨3BzΠfQg#–φ»Φ{;bΫ+ΝΑm- |eJ» <Ηη <ͺWΥo (o/‘Κ‡9Γ΅Κk·ΓγϋIΦίQυtέ1ZΓQƒμ¦»u;'mtΧ΄΄ubΙZ“k3DΫ^YŚΣQj%F)xΗm$‘θς*ΈυΙ9«­3Ϊη|| ±ΆK³XGυ¬ΐ˜k€σΦ$τι΅Σ=rV²;Ό6¬j˜kD:Šg½‘­$V?ŸΐJΖ‰₯z_`œΠ.Σγ=²ΐψπΪ¨Ž~₯­i-1~­ϋMuΏE3T”T(‹€”reM….ε—k0Η{]ζ΅ym`^Η›§?―Sήh¦ZElΖm”ώ¨‹ψS§|:Ήΰ‚€$”†νB6 Θ{Ώ―nm˜ΥΦ’a¬žMkΘμ£4!νey“EΑ)χυεωoD›uH‚εƌS”pΡ³\%‘Ή‹h Ό'‹.κΰεPozԞۻβtθεΖ#Π<'NEwhοΆ:½nο~ων]a² vmΩWF΄τ•ΐ>$έ’«θ΄;ξ™Δ¦Ξ8 ΪΘώ6‚ζoDNΚεCΜθ- f„ŒΞ+¬X@[ŸaΒώ¬%#IJ…”¬ΉΎ?²Aτ$ڍmc¨Ÿr0΄€5>ϋ:Œ±­#¨œΔψ€YΆ•EΉsA"hΰΔrτd`cxcηIn”pSΒΦΪ1ΐ sθB ½:"?EWν'Š&©#–\R\Ν/Ήδ€ξ7 ½ΌG’½@„°ΧvΉΆvF+œI¨τ‘tδξ•“7žε¨›y§ρ€ϊ|γ«^k Ϋ ’7όSš"ό[{Rέͺ¨:½»+-UΝάiRϋp&Λ^w`ςmˆ.ΉŠΊ₯um;Ρ­Ο={»Γcή]“T!η±Θ.Ÿ|nFχψbζC mzχά7ž£δ°¦ΐ˜δ.p6σaμˆmΏο*χv’—›Ε”Smςύ΅οΤ§EoИ†δκw+^1[».œΖΙνXg刡4²G³Ϋ³ωμτtφεμνμVυ_|==­~δ£ΩύΩνή4φΘ#)‚’_eg†ˆΐ-X+—t{žLΨ5#T4\ΓΘ‰Žkσψ$‘Φm̍ lCΌ€*­_{tΫAž_:΅½ρ―κ/PήνΩ[όώݍίψΟ₯υ·ž:*}bŒΣ,\AYn ΅=ŸO›ΌY„B<9ΝνiKDΠb=ԌBMτ-6-ΐKœΆ8…Ϊ’Ψη¬Ζž]8˜­ΌkΉ[η«™wͺΌ.Ώ5™ώjΑ>ΩpŠƒρφΧa4ςω—ΑΠκ endstream endobj 71 0 obj 2351 endobj 72 0 obj [ ] endobj 70 0 obj << /Font << /Font5 28 0 R /Font2 12 0 R >> /Pattern << >> /XObject << /Image4 14 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 73 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 74 0 R /Resources 75 0 R /Annots 77 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 74 0 obj << /Filter /FlateDecode /Length 76 0 R >> stream xœν[[Ηξ'χK€όΌ ˆu9u{Œ˜–ΐ λHhƒ¬ΖN€<εΧε)ωω ώωNυ₯jfz–ž«l΄;Ϊٞo»κœs―:σ‘VBΦόϊ]{AβοωϋϊC-…”*Ί`%₯;–?γ&ώσΎ6Ξz'Σπ&Πz⋦^ϊΐοοκWυχ ς‘ΎσϋζoοήΘϊνίAAσ―dh#c&šϊΗ·[‘zW{«>Αk…N0VGRΈ²Φ§_)οΘ+&¦’&`%)J#˜΄Ž6]bMY”MX›±‚ϊΟWiΉϋόΧJ'”7΅φVc£Ο7υΏΰσ‹9Μ¬οάαϋΨΪ0+σoeJAD§½6΅Υ"z…©ζ­δζίΤ7*S½¨žWΟͺΥ«κήΏͺ^ή¬ηίΥχζΫΣZ Š4ƈν0±2Vh,¬­£\?ρΙΕ‹<’ΞK‘eω³"xΎ2ν1sΑ’vΌŒ―€Jλt5ršBHP?.#›*ΖδZYN)% ”.LQ„K?«kHΒϋ΄―ΪJ/έ‚*όβΏW]­ξV§Υι4Y­' ·ŠάZG˜3­s(ΦC…ΐ`ͺ ϋqΩA`ΞοC`Πy©΄Τ˜yL^Ώ…ρήξ*)p­ŒτΪΥDcd^B-^Tβχ]IΑ™EΒ8₯*…w&ΔδF’r­?WЬΆ%Φ˜Zϋ„ C3΄±bH ―θπ΄YxpvΖ;)†ΖsJi£ZcΙΟͺ³3Θm^=­ΎάYfQXxτ£Ϋρ°ξNβY—DΦc₯Θ‚΄ŽE–‘νEFiΪΖΰvtΎN§ ­sΎχ«‡)η;1_ΰ|AΒp΅»Πz±©$Άτβ‰lΠμ?­&λZα yΈnΥ»5/ίRψ'fyX«ϊ»šό±~ύ΅¬ΏόcΚΚτθΥσ/AΥKƒΩ™hE 5tOθHΠQrBߐžί[˜2p"HBπΜ 99»ˆeWΒ‘e %GΡ \[ς@=ZVΘ/n]ΌΔεsΩΨqΏμήψΰ²Δ£T½ εςΦ*GZbΩh@UΖ(”λV π€%‚¬j8gΆ<|tŸqo³ΌΦΔH γ p΄υ΅œ$β.¦λc΅:Ζ[‡*ˆ—d‘Y΅3C0.AšQBqC°²†oζ[Pm M;λ°’¨’=’sΥ†„”ŸΚr¬9’;,§ΣιΚcα:Gat †ŸLRγΐyˆ7|΄Ί;―1’¬9ž"Γ+r‘Ev-ΙΡ‘ΦXΒZƒb²–ύnη*΄!AΔ‹υeΡ7I Œg­\$Tn’"sqΐώV»g5(!b5‚‚u e?.#C"²aYE†ΟC=`πΠ»UŠ7rΘ„υL0ΖPd―‘‹ψ›H«XF7P Ύ@bΒ›HJΎηwIK’ >ݍήGZY jπ`‰IX6n ©fl Α ΅*κ<:cEήxˆΙ_έJ»`J™”E΅+‹‚~‡82ΟηοίΌύ+ΥwVj)΅&3X‰1^[ŠΈRν^Zk0Λ;…Η(65z(oaŒμslšXΜndτzΓ] Ω*•_­…ΰGtX4,ΝKD±·œ¦ΜnδώgΗ €₯j„ˆ•ΙQ<­ΓφN`}|uoWr³CŒ‰£δφ`~žlΪEέ₯cW8 NJ¬ΙŠ,ΣmΘτC hsOΙιδΧ°—δ3§ΥΩΜ֊―igΔ,Vi·!Œ—Η ΤiΟ:ΡάΕοcTn'ΥΥκ3όžέ¨^£ˆ{Žχš(Ή1F ~'ͺŒUvφQΘEd~QfαAͺE™e,"μw₯χ06c› ΝΒl5|w0‘]‡žβυΥ‹κW”Γ§ηεέαZα΅Ϋαχρωe’ίIυpΩJЃμ&»u;'­w—fiλD­UΚΝΰm»|ekJLΞ•5ήYβjK!ˆ›ž‚Z›σZ[%]ͺΐσm¨ˆ₯^š-cΥσ#²Ά- ΜiQgΈΦŽ |τΘyΙξpΫπTΓ\ι(žχŠΊ6“XaόύV2nˆ³χΖ Κe³ΐx,0>ά–ΕΡΟ΅"΄σΥ#­%Ζ/e?UφCEJ…΄ˆS)[ζT¨R~Ύ sΊΧΗΌT― κu:=ό9ΣF³©!Uψv―μ€πg:?vΚ'£υΦsHB¨H/DCΈχyumbT[K†πτ€Ό_Cf©‰‘ŽwA7Ιj$ŒΑ€Ίή>ΕCόΛhS AΠ@Έ!‘Γ%\Τ,‡$w₯‘€υ€₯ ;>Τ΅ης8jΉ|ΪCωΐsδTt‡ςn£3ΠΛςξη_ή* ϊ(Χ–m%£₯­xr>Š`M₯@ΗΝqΟ$¦γ0h’-Zξˆ’ά=D”ς”Š+6K;˜b*‰‹ƒg6Ό¬)°|ʜΗnςœΜ‘'Ϊπδω“4ǘώ!טγƒjsœήκ°ήƒπ6ΈƒΪ"%Eδ•u‡‘l|^] M‰Z)ƒξΡcύΐΪΈΛšΦFq'|ŒZ]vXN¨/ŒςνΡ―R¦/0Έubk |φ%Ζ06cϋPξUpQ΄  ]ΦŸNα)²£αΖ> Bΐm}Y†›ΦH‘‡`˜£@άθαˆ|čڏ\i/™$›š[2ΙΛζ7 έή"5ExεΪΜ"Χξ.! σVEeα™Sw²\όΦBί“ό8Υ\Mgq/«G“›‘ΧF’ΰίΔ1ΒΏ±Υ΅ΚTg7w₯向πqη8©}“&'; P©_° ,nήάmsݍ;ƒz½Γe:βPΑKˆ6υM£{ϊζϋl»ολ€}‰„ϋi„§²ί·`•³μΠ–5ύ‹ „}O°! Ÿ-ΨvŒ₯°¦ΐΘπw•’“Ζflσsaξ+ŽŽΏωdR’]΅΄Ψ'%Žk=<5­]Z1@]Ϋ.˜…Ργb«Ή¬4ρ{³λ³ωμμlφdφfv­ϊ ΟΞͺ3ςΩμφμzo˜{d„‘*Τn•}Έ„HAknV–mΏp8ΐ¨ΙP±!<ŒΩž8ΞY:•ƒπ€}ΨR”Ϊ­m-kι ΛZκ*»ςŸκ/ήυΩΌζΚ―όokω­§ŽRKψΒ8  ȏλωΐoΟύs*f‘ ŠVRΫ …%«E5‚£ΕςΠά’Δ dφ†\Κ)Θ‘υGΣ•Χ¬-7λτΥ‘Υ Φ“ΏέͺLίϊΈO6¬ ―œώ₯+MH±@λΆ9Ώέγζoΰ$_2`M‘\οΎ@›Ηfl›Y\Ol@ΚΑQWeͺΟo¦Ύ1ϋΧμBΔ?͞Lu”%*€Σγ_‚ξπλ§Βκπ endstream endobj 76 0 obj 2637 endobj 77 0 obj [ ] endobj 75 0 obj << /Font << /Font5 28 0 R /Font2 12 0 R >> /Pattern << >> /XObject << /Image4 14 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 78 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 79 0 R /Resources 80 0 R /Annots 82 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 79 0 obj << /Filter /FlateDecode /Length 81 0 R >> stream xœν[ˎGξί^Ρ$^€ I<–iΧ场ˆ‘νΫΔ—ΫO¬ ±΅XΑ[πD¬@<@–¬Xπ|§ϊRυίΖύΟ!±fF3Σ7]uNΧΉW~[λFΥςύσξ‚γοΩ›ϊm­₯tt₯;?γ&ω󦢎½Six›?Ş䒭>ΘοΧυσϊky[ίόeϋ‡Χ/Uύꏠ`δΗ²4«bP6ΪϊΫW"υΊώςzύίKt‚eIγŠΩg‚\iοΘk!¦£ 6`­(*Ϋi9Sbm± š–Ηf¬`Δ†aΕσUZξαƒόeεmΑMm<7Φrτω¦α|~|‚'ίΦ7ο|συŸΈΆΒΚΙ—σ2₯ΠDgΌ±5›&z©N:ɝ|Q_«lυ΄zR=ͺξVΟ«ϋψύYυμ¨>ωͺΎ}rbΖθ†’UΔΆ˜X[n –λ¨ΦOόψόE^‘Ξ+!‹όEΌ\Ωξ‹„Ήΐdœ,£ΑwRm,;S@m†œ‘4ŒΛΘ¦J`0ΉΡ Αi­ ₯ S”@‡Ζ₯―ε5€ΖϋŒ―­m +―ܜ*όβΏ]]­nUΗΥρ4Y­' ·šάZ˜³s(6@…ΐ`ͺ½ ‡qΩB`ΞοB`Πy₯2˜y•Ό~γ½Q]έVRΰZ[卫‰V‘y΅xZύF~oK Ξ,ŠVSΪ£RxgCLn$jΧωs­‰ —X[`ρ ‡fhcΕP ^Ραi²πΰ⌷R ƒηTŠ£^cɏͺΣSΘν€zX}²΅ΜbΓπθ·γqݝ³.ˆlΐJ‘ŎζE–‘‹‹Œ ΗΰΆtΎ N[Zη|οTχR$ώ Ξwb>Ηω‚„•j{‘ bΣIlι[$β`Δ²!vpΖΌ \Ώκύš‚ο(ό³ά«uύU-~]Ώψ\Υ_@ώ1eefεΥ“O@Υ+‹ΩΩΘM 5tηθ(ΠΡjBηߐžί3L™8Q$!xa…œ†œ]Δ²€«Ζ‹†’£θ\3y  ­(δΗΧΟ_βςΉ8vk<,»·>ψ½,ρJͺސryf ςα@Kμ£ ¨ͺνϊΖƒC<… «»δ…-=dάY^Ά1RΒ$(l}Y’Dά%t½s’V‡X`v¨‚d AšΥ φfΖՐ”Pά¬¬•›εΤXHΐΠΦ:¬)κΘTb©ΪΚS±Δši±Γr:“<wΦΔFΐ᳂Mj$ρV‚± ‚ξΦkŒ(k§ΘπŠRd@‘]Krt 5V°Φ …,‹ίν]…±ΤΙ"@}EτmRλΕEk Υ€›€ΘRˆΏ5AΗώY-JˆX@m† `}B9ŒΛȘˆlXV`‘ασPX<τvU…–²‘F½Œ1ΩΑ δ"ώi•ΘθjΑ§HLdsIΙηυΙ½m’h ŸξVήEZY j4ΰΑ"SΓ&mά@SνΨ ‚jU ΤytƊΌq“?ΏžvΑ΄Ά)‹κV ύqΕ<Ν_½yωκχTίϊf\©…Τšμh%ΦzΓq₯»½΄Ξ`w0 Qlj PήΒX±Ο±ibm1»UΡ› w5T§T~Ή‚ΥHΠaΡ°4―Ε6ήrš2»U»Ÿ+@–"–&GIπ°zΫ{ λ“«ΫΫ’#˜bL\Inζη‰ΣΖ(κ.ϋͺΐ18)±6c(²lΏ!3 - Ν=₯€H__Γ^’ΟœVg [KΎͺI;#vΎJ»a<ƒ8ž’N{Τ‹ζ~ r{\]­~„ŸΣkΥ qOpγƒα_%·Š¨δ‰*c™]r‚Ÿ—™ExPz^f‹ϋ}ι=ŽΝΨζBc˜­A‚οφ&΄!‡ψΎ ‹DυcΚαΣˆςVŠpπΊνπ;ψό,ΙοquoΩJЃl'»u;'wWvaλΔXctΚΝΰmϋ|ekKLΙ•4΅ή1I΅₯D§§ Ξ&Gδ¬6¬•KxΎ ±2 ³e¬§zV`DΜ]P`Ξθˆ:£ ΅vœγc@ΞJvΗΫΖ§ηΚHOρlPΤ΅™ΔγoV`%γ–${Ÿcά’\ΆsŒΘγγmYΓ\KB;[>Z`όRφSeΏA1T€TH‹$•β2§B•ςύU˜γ>ζ₯zMP―γιαΟ©˜6šm ©Β·{Ν“ΒŸν=ώͺS>Ω³—„4P“™‹†qο£κƒ‰Qm-ΒΣ“φ~ ™]€&V9ΩAά$6HƒMu½ rЇψ—ΡΆ@AΠBΈ!‘γ%\Τ,ϋ$w₯aλIK”wr¨·zԎ˻βt¬εςθεΟ§’[”w^–wίςPYΠGΉΆh+-mΕ“σ± ΘЌ±ZΚΈΖΗhτe‡ε„ϊΒjίύjm‡CZ'ζ°ΆΐΐηPbŒc3Ά±•^ΙA[c‚₯Λγύ©1±ΎΨ—Ψ^ΈŸFx*ϋC V9ΛmYΣΩ?Ÿπ;Ψχ+h”•³ξΑ2…0‡΅FVήUJNf›±ΝΟ…₯―8:yσΙ¦D'Ία΅΄8$%Nj=ΌΌšΦ­- ©Ήfaεq1i›οϊΫ‘”ψη΅Ωκ?Υίg½ς―ΩΙ•οͺ_ΰσΏg/g'Ήj‡μXD B2k–˜Ϊ‰3@π,Œ‘–eΥuύψ·l„Ϊ ΫΒγΘϋΒΣc„D;φ¨φP?4žŒ¨qkΜ::Θ΅zΛό£ϊδψαμ%~τΚ?―|7¬θ©£ΰj|a5 { (λεΨoΗ]t:i‘Ь¨λ 1Y„‘6CpχΑuXZ€θ αω½%—2 rΔώ`ΊςB΄ε¨N/\«f°φΣΣٍNe.lτη°Α yνΜ]iBŠΖt-ϊέN·Ό‡“|Ɉ΅†’½6ΝΨEϊddŒxb RŽκ°*S}t” <ΏΜξΟnΜ>…βT}Ί7ΥΡL jI’ΨΊΓ]χω]£S_νԎu.’₯: “ΔΧ€ ₯Χ6¬²PΆ#r–ZνΙΛvΥ€₯N{λ½”aγHΖΘτvRx5ƒ\\³φ€eQΰΖ`AΞdSCG”†ΰ#Τ`FΔ ΛhΔβρœw4ς–A€Χ±­’Η‚ρ’<:mx³4z#Ϊ:Ί‚σ# ΘYρ¨Φζυ ~Εςά=02°y+Μ Q$š—Rϋ?JνΈ··~ϋŒ[ endstream endobj 81 0 obj 2817 endobj 82 0 obj [ ] endobj 80 0 obj << /Font << /Font5 28 0 R /Font2 12 0 R >> /Pattern << >> /XObject << /Image4 14 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 83 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 84 0 R /Resources 85 0 R /Annots 87 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 84 0 obj << /Filter /FlateDecode /Length 86 0 R >> stream xœνXMŽ5v‰…ο€²fFΰρσΟ³½$ !1™&‘duȌ’ž„ HμΈ'°εœ€ENΑχ\]Uξιnθω‰Δ"]ͺnΧWφϋμχηη>Σd¬–λΣlΔομTŸik¬₯Β9ΪP{œF'ω9՞cb[‡ΟΗgc ˜λsς}’τKœιύΟζ?œ<΅ϊψG08ΉSžΐaΌ-ΩϊβυλγKQθη{ϊΧYΓD•©^K)G2!$M!zΡHBI$ΰ€Ν,;l;b₯ϊάkwlUΥφςΨδ¨Dt2δ ΩΤλΏ$CAƒ‘w›rdη£+A&k ΣΧz‹W/r:’£|²ž>_ΆkΑα §Ρ¦Οτ#½£~έΥEW;“OΤίκΙ/7ώœLoό₯>˜Ό§›“›»ΪΧχκΝ䣉Rovυ=½«?Ÿ^ητBf“|Κ+sάΩΥΣBφ=Xυ$N6ζμ"š‘3»$-ί}κμ˜b]z†κΉΪl Ω5Π|„Θ:\λ6Pγh[ٜ˜ Η¨E‹σΨ§ΏΟ+0jʝyEΔ†aΰ΅χΖE›,·ZTΏ©οΤ=u[©κ‘:TΏχz½,aΑgXΟwy«εκ<$F«VΛ’Δ!‘ΜΟΓΛΔ0δ}I £yŸ«‹ΨΌΑRΙ9wά‘‹Z-c~ΦΑΞΑ#na5/ξ³κρ¦ΐ'—Gf)iΙ^^}«ξ«oΤXμΎͺΫYl-™sΘRΪYKvΑδ£q6ΣΕnΌ•lΘΞT‚‹žΘ‘r2ΡU‹Γ”΄ΞΞ3σfτˆ56φκFΠ š"— ž\֌ΑϊχΏ:}zό}Π·_ šΪœΚ|MΉΦŸΛeΙs—Wbr5.V ωΕRl2A§ΘΦb ΘEΘή6Χ. `¦s±δ B}ΐJ]με @Ο5‘δΕ•~„γHτδΔ\Kί³fŽ=6,£—3 YoζM~΅2αΣU¨™0{ηyiΒb>n'άν„{l4ΕBΊmfm‘²nΒο Όήΐm€tiεghμ&ύBKΟ―υ£'V?CΌ„nk‘ eT–PΤ•˜Nίςθ‡ΧΉΌw>΄βC‡(ΩrK^γp‚lŽDΎUΝζ‰zuσ Ζ–˜bͺΥ3·T$Εκcυα–•ΪFšPPͺPJha“ΖώOU³}=|ZMΜRMv±pmW Χ]O’§ςΔEκ1. ΅Jv³Τs*Νp28…ˆDN&w,Ψ°‰d%8£™ εjK4Eι”(.vώ[{€^#Άκ ŽιΉΕζ ζΨr‘ΓΠΊψ)Σ‰ώi‡Ϊ7‹CΨΥ8Q&Ž.iΗ¦P)%/9ο%뱏«χpϊΈ–3A ΈγΞλ(7cςNJ5½εhΊ?29fΝGHώ³D­‡±-Ϊ–›oAx_n›‘€,eΑ…DBMΩ«γ†’³,—œ›T‚qβ}‰\M›§C0ާδ­c»ƒ‰‚,pmH‘‹ )€„B¦ΠΎZœγd Š€σ\)X@faAL°Ι$9yƒmD";u1xŸ P#…1Τεϊ’°©~ endstream endobj 86 0 obj 1211 endobj 87 0 obj [ ] endobj 88 0 obj << /Subtype /Image /Interpolate true /Width 868 /Height 420 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 89 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐ€d"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ω²Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¬YY\ίKεΪBς·}£υ=«CÚ3κΧ'$₯΄}ΗςυθφVY[¬6Ρ¬q―aίάϊΠkΰΛ·Pn."‹=€,Gς«_π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•π„ΤC φUΩΡ@gό!υΘ?ύ•ΩΡ@7΄ϊQ΄ϊV―Ω=¨ϋ'΅em>•ΡψΑΊ―uθτέ&/φ¦‡Ιwf?Θw­x2Εϊό:^šͺ†ω$o»`€\ώcκH―}ρ?„%—QOš6Œ’ΟV8?)δuDRHžΐƒ΅}²έΰ>(όΤ|£[j–Ά₯h‘zU0a~μχ=ϊŽυδ›O₯zχΓo‰Z§…΅KΏνc.«₯_»=δΆζ.έ]Kw=ΑΰŽ½ˆΣψ―π²;ρ_„TΙαϋΈα Α n ώGΊηΣ ‡m>”m>•«φOj>Ιν@[O₯*Fξꈹf8ΤΦ§Ω=«CA² ¬Zξέω Jμτ‹Σ΄ψm£ΖT|ΗϋΝάΥΚ( »ΐ/&§βψ΄«ΑώϋxΞp=ΊŸj£πΗJVρuͺN₯‘·α—ΈΖ}·όͺ―Žuλw_Ή’Wam˜α‹vUTqŸ©κO½t‰α^•‡Oρ,ΙpNΠfib8ΐ*½ύλ˜ρg…΅ ά’^…’?ΥΟJ··=·σ§x–τ­¬t«λ)ή Ο5Β0K–ΪŸ4ybΞO}α]g._ΔήΥ|7z|Ζ†6ΥΨ’WΠ6?EyQ@ΎπΕkΦr[€:\>|ΒV!™pΗ €r~CΧ« ½?α7ό‰Ÿμ΄ζ¬―ψ6ΛTouο^=–…jv–‡‘ψΰpxδ™$ΰP Ez›x3Βώ(―eπ-νΩΤνy΄Ί8σΫ#©υΙΐ8ΞkŸψyΰΨόGφΛύVε¬τK-q:ΰ18Ξ Ι8=Έζ€8Κ+Υν|ΰΟΗuoαRς-VΛ€wCδό¨<δq\Ο‚Ό? ]Ωί_ψ«Y[-›bΪΔκ.%n2BœœrΧ‘Šγ«vΫΓ·ΊρIn,m¦:>ac·1Œ|γΏ­uΊŸ„Ό5«ψ[RΦ|yzdΣπσΪέpž£ŒŽ9ΙθG.$\°Š8hΎπΕν—…4K%Ή²½Ε+0Xr1Œ|‡‘=« ½ΆΪΓG½ψ/αηρτΆz}ΌςHL $mς€‹Αηœτ<υψό#αλ―ΟβO^]Ό6²ξ-ξFJδ¨γŽ£p=HΑ<Œb€<βŠτ/x7Jo ?‰šΗ…uv,$Ϋ.Ÿy"‰€=Υx'zπIΟȝ:τiβψΩά‹ΫΑ‰Ό²ή›±ŒΥZχΙ£πό*Ke’mWϋν?+Ύ~ύΝ׌c9―+πί‡΄ύvγW?Ϊ‹coj Α灹ԓ‚άŽ€ γΦ€0tΝ>οT½ŽΣO§ΈΊ‹όΙ<ξk€Τ~x†ΖΠά5ͺLͺ2Λ †eό:ŸΓ5½π―|^ρ-Ɯ»΅T‹aw0ωX~sΗ| Ηψo¨κςxΞΩbžβa3rΛ˜ε›>œsλή€8ΨΡ€‘R5gv!UTd’z+―O†ώ$kA7Ωb F|“2‡ΦΊ­'L³²ψΝwΕUςΪxύΆPN?73]Υ5ερΛξΣQK‚‘F„ρσ|ͺ«άŽ1ΟΎhœΊ·šβH.bx¦Œα‘Ζ ŸqZv>»Όπύφ²’A£}μC3p φ‡R:ΧeρΆΖ8oτ»Π‘n.ct—oBSnώ=ΐSnΔWΓ]Ζρš$ΤξΔχ;>ρ‹9${γΛ 7’»Β)cγ«]Υ₯kk£Fb „nžΰ†νΠQγί &‡XΪi†iaΌP#2°$Ι»d꿝sώ.5έZ>ΡβI₯άU₯$(Β’s€OoJ©}lφW·²•2A#DΕz§•zf‘£Xh?4λ 6Y€TšS+C˜άγ€;m?2χFπtΎ%Ή°ΎΤo_RΉΉmΟqΘΜHLΰσΘ―>”ζWEα‘eγΡ.o‘‚ γύ*bBݸ䁜qŒυβΊX4/\jI€Ϋκwοvν±n©Ÿ PvΰŒϊθΞΰ†[‰’xήY\αQ³1τu₯Ή‚kYή˜€†d8d‘J²ύAλΑϊUŽγφΣυi. νΌκΆ­ςrΩδ šoΕ(τ‡ΧE“^6²Σ¨™V6|ύίΦ€8:+Ρυ xSΓ²[Xψ‚χP{ω£ο8Α$g¦{ί§AY1xcMΪij+{§\e„Φς)ec΄‘‘Έό½3@u‘β+(τνwP²€ΉŠήw œ’ΐΝtή(𭆕γ}'HΆ’α­nόŸ1qΎB§ t”ΔΡ^›«ψcΑΎΤ Ύ‘|ο&8““Ո^yόZζόuαˆτ ­n,. Ξ—x›ΰ”OAΑ#ƒΤΒ€9j(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€9_°ϋQφjκ~ΓνGΨ}¨Γχ—ώΥ Τt©š ¨NAwR3Θ>•μϊ₯ή‘ρ@ώΥ𞯩iΪν’w¦C{"$ƒΥ`>‡ΏCΝy‡Ψ}ͺφ‹qy’κPίi˜"<ЎΰŒς₯d?ˆΌU²Iβm]NZϊPAτ?5Aw­ψ†ςΪK{ΝsUΈ·mx₯Ό‘Υ‡‘°k¬ρ† ž#ΦN’,b³wVE³½ΗW=9?ΠuλXaφ [μ>Τ}‡ΪΊŸ°ϋQφjεΎΓνGΨ}«©ϋ΅aφ j&·“Μ·‘β~›‘ŠŸΜ³φGώοϋn}‡Ϊ°ϋPMΛUΤ§#νχqΫ§2Jfl(όϊΤΎ"Τ ΔBΒΕδ6¨6΄ŒΔ΄ΏRNq[άHϊlVPΖ°Δ£ηΪyϊšΝϋ΅rίaφ£μ>ΥΤύ‡Ϊ°ϋP-φj>Γν]OΨ}¨ϋ΅iόΏAρν¬“]FΦεΒ…έ‚ ΙΗήUόλ#β„gπηŠ/m€‡m΄’4–Ξ ρ“‘ŽάgvΕIφjτΖγϋ&=/ΕlZ½œ`,nψσ;υ wΰϋΠŠύ‡Ϊ»{i_\Υξ%ΆΤξ%Qkf@‘ΛwΞ2/Zξ·ό§Ÿ?Hπ‘{‘σ)Ί`U[Χ›§^ί‡ZγΌQ«j>%Τ>ΧͺKΈ„21θ£<:σο°ϋQφjκ~ΓνGΨ}¨–ϋ΅aφ§μ>Τ}‡Ϊ€2|?¨j~½{½ιν.&…$‘ΖG9τ؁^…ϋGΫyή8±ltӐδYk“ϋ΅zΆ±βψ†hnυύPšυ"…p1 Ο$σŒΠ€}‡Ϊ½§βV­ͺiŸ|c§]4ΧΪW“tŠωŠ"„c'‘Υ‡¦§ϋOΓ_ϊ5?ϋϊίόz²ώ!λ– ‡H΄m'·²Σbh£»(ο$ζ€<μ>Τ}‡ΪΊŸ°ϋQφjεΎΓνVtλo&φ'ΗCΜbΊ°ϋR‹,(₯e*pzPcπ›QOρŒ 1 —Q΅ΆγΨ’ ώe@όkŚDΪ½ue2mPΕ£=™ ωOεϊƒY(̎ŒU”δpA―B³ρ–•­iΡXxΞΕ¦x— {ω„tηΟq@~ _Z]xkΒZέA4°Zm•#1Œμˆa€θx=} _ψahΪ6΅βK # 0ΒΔr͐xυΆ―š©πζΙΎ³_ίσ r­Θ㐠ώ'Φ°όeγό@±ΪΫ@,΄ΈΎεΊ  ΐπθ(•’Š(ΣώΘ™ρώΑίϋNj»₯[ΛβrXi!¦½±Ί/5Ό|»εΊu<6GyΆ“―jZE–‘i§άω6ϊ„~UΚyjήbα†2A#†n˜λG‡υύOΓΧ†λG»{i™v±0aθAτŸΊMφ—¬κZΞ§o-–›£Λ:˜Α;•»υ!Ο§΄x3―ό-ρ^¦5ΈϋJΐ%?v@_-—ρΕx‹Η~"ρ ™΄Τ―ΛZ Ejˆιœ Ÿ\+EΥ―τMA/t«—ΆΉ@@uΑΘ=A‚=mψsΐzφ»s`ΡοZ€!ž&Utcλ‚ΈΑ cΡξfΎψuβΛΉ<7e‘A%œ‹ΫΓε4؍ς[20~΅Ηhς@uΟϋ―σ†Ή›ίˆ'½KΨξuGx―"ςfΚM₯0FΫςύγΘΑ=Ο²aΧ΅(t τHξvι“Θ%’Šw7ξΖοα^ύ¨Όρ1‹αaΫνόζ§ψώHŒήΙk€ΉΧ΅+­ ΧFžηv›jζHaΨ£kδξ'ο7Sή–Γ_Τμ4{Ν.ηΛ°ΌζxΌ΅;2:v4ιZΥ₯LjΎ h-£Dχ/a6ۈ!™qΉIΪ9Ο ύ=)ί ¬΄ ψ§XΦ –ΦΙ­‚ ™vy€θ_Όυ-Šσ xŸWπΤI£^5Ώš‘v†WΗL‚όzՏxΟ]ρ,I―|e·Fή±"*.}p?Žh«π6₯β­Βowo€Γͺψjy™ αΘ9ΪάΈœ‚;χΝ_ρf“’kn TϊWα―kžYGΏx"‘·θηΧΏŽΌUο ψΓ]πά2C£ί΄ΘΫΪ2Šκ[ΞOJƒOρ.―§\_OexΡKzKNΑη$“žœOLu  _‡vΊΣήέ^xzβέnmcάφς±ΜκsςŒGr0Hζ»/x“ΔΊφ»šιΠiρ,Šχ“, ­΅NJ’Η‚zzσ^W₯κ7zUβ]iσΌ Ρ—ΣЎ„{θuˆ>"Ύ²6^,hΓk΄Q…f^ί†(φΆΣψƒβ„γEΌŠ  H&v*»£@©Vφ5Ήsβ―Ηͺ ,鍩ξ1-Βΐη#¦πsŒwΟOjςΈ€xeI"vI†VS‚€t Χ]Δ₯―“φΘΩ±+B₯ΗιΜPΟΕ‰οSΠ΄T—ν°DGξΞϋ@Ο‘;sψŠ₯ρzxΣY±νΘς4ϋUŒ/χIμBVOεŠλΖΦwzΕάj‹!žI% –‘Ιο»ŸβέCϋSΔΪ•ΰ`ι$ν±‡t/θzƐΠήιš/‹.>c§iΣ,€Ÿ™@Qό€?ˆͺ~ ώEΊ»o2ηIΏ‘€w<• Έ?χΡOϋζΌΒ {RƒE›I†ι—O™·<[W“Η|dtόΝF½©θπέE¦έ#ΉeTξΤƒŽ§¦(π~£ύ­ρl_n,³K9BΉε°_Π η― „ώsž΄ΫFΦV“©]ι7ρήιςω71ηkν Œ‚Кο'{φ½i3rωΕπ>ώsœtλ@§―hφΊηΕ΄΄Ώ?θgYΑ“ χsϊύ©τ›±'‹#Σμ<gmΰέK̈§οξΫΑΐΘδσŽ΅ζWzώ©w«¦©5Ϋύ½1ΆdP„c§Z·>?ρ%Δq£κ%v0|€H€r3Θφθ{ΠφͺΑ~6!bϋL#!­cόI°Ί„βτ˜]βTHγj6Uz1γΤkΎΥ/o΅FΤngf½fWσT9P#*ξ΅βc[²ŠΧS»σαΓ¨1ͺΐœ€Bh»ΊΧu{Y-΄οψb-Lr*sž2Θ-μ1MΈΡτο όSΡΗ1A:ος™‹lf  dφ'Ο9φRΟΗΎ$΄΅X#ΤY‘FΥ2FŽΓρ#'ρΝ`ήκwΧΝ{wq$·Lی…ΉΆ=1Ϋ(₯ρg‡υ;Ÿ_ΫΓg;΅ΝΙxΨ!ΪUŽwg¦y=°k§ρό•o}mΏτ{W#/ΌI-›[6€ΫXm.#@ψx ώ=j+=vοUρ†}­]+΄7©••c ‚Lσ€IΝmόTΠ΅&ρ|χPΪO<A meΖB…+Η|ŽžυgΗρΆ™ΰ? ι7Ÿρό€ΚΚNJ ?ρΰ?ΰ4ΟxγTΣόU©.‰©G-ƒ)²¦|΅ΞΣΟ|τγ9VΤο5{Χ»ΤgiξY°0`{ §EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPΕQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@άB%_F g:26`Φ½5Ρ\aΐ"€2h«Νf‡ξ±­7μ_τΣ  tUΟ±ΣOόv±ΣOόv€)ΡW>ΕM?ρΪ>ΕM?ρΪ§E\ϋύ4Ηhϋύ4Ηhsμ_τΣ£μ_τΣ  tUΟ±ΣOόv±ΣOόv€)ΡW>ΕM?ρΪ>ΕM?ρΪ§E\ϋύ4Ηhϋύ4Ηhsμ_τΣ£μ_τΣ  tUΟ±ΣOόv±ΣOόv€)ΡW>ΕM?ρΪ>ΕM?ρΪ§E\ϋύ4Ηhϋύ4Ηhsμ_τΣ£μ_τΣ  tUΟ±ΣOόv±ΣOόv€)ΡW>ΕM?ρΪ>ΕM?ρΪ§E\ϋύ4Ηhϋύ4Ηhsμ_τΣ£μ_τΣ  tUΟ±ΣOόv±ΣOόv€)ΡW>ΕM?ρΪ>ΕM?ρΪ§E\ϋύ4Ηhϋύ4Ηhsμ_τΣ£μ_τΣ  tUΟ±ΣOόv±ΣOόv€)ΡW>ΕM?ρΪ>ΕM?ρΪ§E\ϋύ4Ηhϋύ4Ηhsμ_τΣ£μ_τΣ  tUΟ±ΣOόv±ΣOόv€)ΡW>ΕM?ρΪ>ΕM?ρΪ§E\ϋύ4Ηhϋύ4Ηhsμ_τΣ£μ_τΣ  tUΟ±ΣOόv±ΣOόv€)ΡW>ΕM?ρΪ>ΕM?ρΪ§E\ϋύ4Ηhϋύ4Ηhsμ_τΣ£μ_τΣ  tUΟ±ΣOόv±ΣOόv€)ΡW>ΕM?ρΪ>ΕM?ρΪ§E\ϋύ4Ηhϋύ4Ηhsμ_τΣ’€+ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αGό$ή ΏώKIώδP―ΒMαΟϊ 䴟αEyQEQEQEQNŠ7–EŽ$g‘ŽTd“μ)χ6σZΜΠάΕ$3/ήI«¨4Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@^ƒ …ύ§ο-’σγαψλθj}VΫN°³yM¬EΊ υ5ΜιW­ax’Œ”θγΤUjnΌ!`εOS@„δ’qΟ Ε%P₯όA©­_ωjd΄°vΨd#ώώ΅ΐλ₯注K}©NΣέKΞ@^­πσW‹]π6΅αθ­—OΈ·²gϋMΆΜ9εΈλΠyτ― Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( «αί‰βπΎ±4ΧvΝsgs ·™αΆ’GεϊΦ7ˆ_K“Wτaӎ<΄Έ Έγž„χΟsTŸΙςbςόΟ7Ÿ3v6ϋb£ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  ΙΊΞΩ<ύϋ7~οf<ΌŸ^ωͺυby7YΫ'ŸΏfοέμΗ—“λί5^€ )ρHΡH‡ §"»½9ν―mtŠ1žmβ€8+¦ρMΤQ(΄]Ήr a\ΝΡ?ƒu„ΌΈ΅hbσ ²ώΠqζ>ΉυφvΊΉžυίk_|?wΰνcWπΗό$ΦWzJ$Σ[k–Θž|LΨ-P:u9Ου $’½α—ƒ|;β½_›VΥo΄Λέ./΅Ό’%{qΐ'άΟά vζ§Τό!α-WΐΪΆ»ΰ}GX{’7ΆΊ€q‚θν΄<{: σ‚OαΖ@<ʊο|ΰ½6Γ·Ύ(ρv§.›αΫi…ͺ}ž0σέLF|ΈΑΰ`rIγς$oΓΰΏkώρ«αmwYŠηJ²{“§κQΔ$r1† Όμ@η$tξδtWαOiGΒψ³ΖWχVz/Ÿφ[[{$VΈ» »ŽGr}γfϋΑήΧ<'ͺkΎΎΤΩ΄―}§κŠžhˆœyˆι…`9ΘΖL€y½θ^π~7nό[βiui,#½ΪιH†Rϋ—vl„\:g5‹4'ƒaΥΌ)«κO©5κΑ&›¨ybX£ΨΔΆ|Γ!FαΗ8#4Ιιz5ζ§i¨\Ϊ"4V1yΣp0Ύή΄k5ζ,ς"‹ΛuΊ‡k†ΜmМt©t]jM.ΗVΆŽ0λ¨[ύ‰llωΟΏB?5ύjMdi‚XΔa²ŽΙpΩά8>έh&Šθ| αΤρGˆ#ΣdΌ[5dgήWq8ώ?ΰj—Š4₯Πυϋέ5nRθ[Ύί9pNpyΑχ—EP€OAšN•κ?¦{kOάΐvΝ Žτl΄€δuχΌλVΤυ}FkνFc5ΤШ\ΰ8€P:(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€,O&λ;dσχμέϋ½˜ςς}{ζ«Υ‰δέglž~ύ›Ώw³^O―|Υz+ODΤΝ$›hOΛώΠ…fQ@žWžg–C—s’i”Q@Q@˜uZήΑo,¬ŒΔ>φa )€OΜηΣR+ΩuΟΫ^ό2πΦƒŒΌφν6ζκi‰Φ#ΨVB ν=IγΌ*ŠτpΫYόTΣξυ WJ±΄Σ]δ–k«₯‰$)„cΓN~œΦΏΒ;Mγrέjώƒ–›$²½Σ_ †`ρ°'<1ˌύ yιΏ ΄K[oκφΧ>/΄Ρl,εšΟV΄ΌO!¦Κ7žJ³dN zn™β-jΌ?<[αMsΒίf‘ZήmζšαŠΎPCg8δτύGΜ΄Pχ€΅X4?θ:₯ζαkg{ •!Αb~3^βO‡Ϊf‘βM[Y“ΗžƒD»Ί–ζ9VθΛ>ΧbΑ|7ς3^CEzχΑk»Ψišε†“β[˜γJΥ/qyaϘˆ;—oΏ§Jλτ–?ψ«@ρGΔΝ7RΥ΅;KxgΥ[XαΛL(sŸΊΌΰωʊυΟ„ϊe¨πΏŽ`»ρ‡μ₯½΅:| w¨$Eέ][pͺΡ‡SMψQ§ΪΛΰ/Es―h6κPGkoνϊBε‘Γ“΄σ΄ŽMy-κž»|UπΚ_j:΅¦ͺZ_BΒβυφ[Ν”*Ρ»γ zO¨™«ψJπξ‡{u―x³J›RΩ‹=?I”]4λ# _σμ|ϊŠχO‡>1»Ίψekα½ ΕžΧτλ™$Œή²Η δ.KσHW Nλό“ΕΊ―‰νΌ)©E⏊\ο< ‹₯ιΕ.€œž ;">Ή5α”P²ό*ŠςΗΐςj^ρέ–ƒβ /^),/ξ’HgQJ°W ’y#§«ί΅Ή.ΎIkγ[BΦ|ZχˆφRi¦'–€ωόnjσξ8γΓ( Š( ‡ΐšv“ͺψ†+m~ϋμVEΌΝα2Γ’ξ<ώ΅RρE₯…†Ώ{m€]»ίLH;†qΑΑΘΘλŠΛ’€ (’€=7ΰίό‚Όc`σ ½y•uρkx\κ lc½†φ!ˆξSŽ{©¬=^ζήσQšβΞΙ,m܍ΆθεΒpSΟ'ŸΖ€)ΡEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEby7YΫ'ŸΏfοέμΗ—“λί5^¬O&λ;dσχμέϋ½˜ςς}{ζ«ΠEPEPV5/$XDb1Œίzτz―V5ψό“ύGoυs ι@蒊(’Š(’i/©κVφqΊ£ΜΫC7AI΅v&We:+VηE’ *{σ4l‘]›B£9,sτ¬ͺQš–ΒŒ”Ά («ΊV—yͺΜΡΨΐ”œδQκIΰS””UΫΠm¨«²•₯ͺθ—ΪZG%ΤKδΘp’ΖαПLŽυ›J2RW‹ΈFJJι…QT0’ŠΠt{έWΜ6qC2HμκO2’ŠΌ₯%vgΡWυm&σJ‘φ-‚AΉX2Έφ#ƒK€θχΊ«Iφ8ƒ$c/#°U_©ŠšκΦβAΤΒεw‘J’=pkf?λOρi†+ΌDdQ!»sšR««Ι€LͺF:Ά`QJAV!pA­Άπ°ΆΎq΅ώ3ΚήΎfί]™Ν©|NΓ”γ‰ΨΓ’•AfA$πο[WΥνν^y-FwΌk"—Eυ*h•HΒΚNΧ N1ݘ”SαŠIεH‘F’G;UTd“θlάψWW··’Y-ΤωKΊHUgAκTΡ*ƒ΄‚SŒ]›0蒊²‚Š( Š( Š( Š( Š( Š– y<Ο"'“ΛC#νΪ£©>Υ …’ΪEΐΡF¨Άί°…SΟQΫ₯gTΖJ[ I=‚Š(ͺQEQEQEQZϊg‡u-JΤ\[B’v£I" sθΉ<ΦmΥΌΦ—AsE4g Œ0A¨U#&➨•8·dυ"’΅΄ΏjZ·Ÿi1Ϊ¬ς*ooEΙ¬Ια’ήgŠthεBU•†4Τγ&➨βέ“Τe΅cαVφΡ. ·_.OυaδTi?έδΦ<±ΌR4r£$ˆJ²°ΑЍHΙ΅{œdμ˜Ϊ+fΗΓZ­υšάΫΫδΖΥZLuΪ Ι¬vVF*ΰ«‚Αœg6’ο`SŒ“Šθ-<1=ΝΖ“ άΒQ€BsςΰώU€Γkœΰγ"”jFnΡΧτ‚3Œ΄LJ(’¬ ’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(Δςn³ΆO?~Ν߻ُ/'ΧΎj½XžMΦvΙηοΩ»χ{1εδϊχΝW Š( Š( ¬jρω'ϊŽίκ>ηA«ΥCώ?$QΫύGάθ:Pz(’€ (’€ ±§έΙa}ά|Ψ\:ξ΅^ŠM&¬ΔΥΥ™v]JβM=μά©…ξ>xη~1ωbΆ|3‘Gw¦]jwVχ7qBβ(ν­Αέ+ΰ’ΐŽΙζk¦πξ―nšEΞ“{u=’<’x’μl`†’« κQ‡ξϋΓ™UMGά/ƒ©ewεh—ΊEΤ™c2ohεͺ’Γƒι\Œ7wΫΟo Ο·ΜE<>:gσ’w°·΅—ν$ΏΎ‘”…†ά:‚qΖζn1κ*/Λ£ΪΛ=Φ©t°έGΕ°xZDSύςR=8¬‘'JM6Ί+?ΧS8ΙΖ-»Ώ“ύu&ΏVΡόΊuαL½˜\XP§Πœt€Π΄ކu[«+­@Ό†8mmΓsެΔ@ͺϊδZL]]v]KQ‘”¨ϋ;F:σœϋtΖ*}V·ŸAM*ξώ}:H$2Cqb€ͺΑyλίό™|ώΞρΎ―]ϋΊφ%σr^=^Ί5žσBŠσFΌΌƒJΌnmΜhεήc•;ΰ°Θ"Ή»M'QΌ‡Ν΄±Ίž,γ|q3 ύ@­­Aμ!ΣζGρφ£pλ…Ž Λ?νκ>•“c­κvlοg† I؍š—΄ε|½ϊίυΤΊ|όߍαΖάθڝ¬ 5ΟwKχβe·$ŠήπύΈΥ<'ya$«e7"γνRρ»v1υοή±nυνVςέΰΊΏΈ–ΖδgΘ<ζ΄4«›ί>‘{t,₯K΄E+!d—iVΗ#λEUQΓήήλml:Šn>φχθXρeνΒΖ³Όρ°θO|]σAΡαΎΤ&Škt‘Z8‘άFη'$œΚ©λ”ZLzNŽe{q'4ςΣ+γ°Ϋ]/HΈΆ†C%Ό₯A–)mΫ*{ΰŽ 5£wt―ueE(έέk₯‘_^[HΉ‡Λg·™ΠNƒΧιΨΧ_ε]j:_†”λ?d2©W ;¬’eρςΰr~΅Μψ“P΄½’ΒΞΕίμ6QˆVi—Ιω›žΥ­¨σNν—Δ Y#&²JwΩΘ㊚œŒ9―}z_£€)σJ1ζίύΜ]wS–{h΄ΩΩεk9εΔς9fpH―¦?ZήΦ4λ[iš;ΖΦπZ€2*§ΩΩz““ΗΧΫιXΊρβl-΄λ΄Ό$‘ε˜BΡ’0ξ½ u–n°έjZ’L 6FΕΨt’υm.U(¦šΏGωy”εRŽ_§θ\ψ“iβ%hΨ3Io»βlŸΘ ΠΦτλzM3Q%‹μ‘ΫG9•S쬽s“‘ŽΏδW)jRjΪ€χ“ ¦Cς θͺ8π£§Yθφf+½GQK H- ‰sύΦbΦ—³•:pώd»\\ŽuεsoΔz}½χĈ-Ž s˜Ϊ\qŸ—'συ¬/k7³λ—9ε†8$hαŽ6*#U8ͺάkwSx„κωγΝ(κ遊ΩΤ!πώ³tχιͺ9ζ;ζ·–}¬z•#ƒŸOUƒ₯ΛνVο¨F.Ÿ/:½•»κdxZ“\ΉΆΈž=²ΗΒη9ήA$·Άs΄Όn—:Όw³_¨»…χGn[N@αC9ιΦ²5!₯­ό)`ΧMh  d|nsžJŽάtΆ¬μ|?k{ κλ¬πBβAΩΨJH9 žŸ]NXδŠjλ΅ώENʟ,S_#"kƒ‰žζϊ~l°γξόω+]ŸφMδώ9‡Y‚β&Σ₯™$K‘*αl9ΟπγΓλ£UΦnΘ,ςδnώΫ8φ­8ι>›νίmMJϊ1ϋˆaF«c†f`3AQZεMokZΧ†υ&¬_*Άφ΅­rδ΅ΣΌ{$Œ΅‚ψ±p ?§·τ›LΡ―SΗ_Ϊm4Ma4Ξι8•H•X(δυύ+Οw5έζιζUi€ΛΚωΐ$ςΗΧGa6™αΟ2ξήυu OiHDq•ŽF7’Γ“μ(―J\Ά‹Υ«mψ`«MΪΛ{[oκΖ-ά­§λ—`ζ3 οε2φŽ+{Α^e•ΕLj/]–u%70ϋƒΧžM`i g6«Υ¦x­³,€8λ۞OuΊ»ψTΉ„Kβ+OƒεŠ)"ϋy>€UWz{6ž«Wfτν§_Θužœ–z­]›8Λ[[‹ιΜvvςM& l‰ >ƒ΅\„X UχύψoπͺΆ—·}ΣM§Ο$/Κ‡S‚V―ΒO­ΠNλώϋ­§νoξZήw5—΄Ώ»k|¦ΨίήήXκ°H’,NβRεL%zε{υͺk(Ό3¨έ&Ÿ7ΦςJή\Wo l±ΰn^€ιλMπ$Α΅ΛΩξΓL €Ο('—γ'Ÿz]9|7§ήG¨hέ\˜I‘·*ϋ‡ 3goΉͺ7Ο%w²΅―ΏυίC ·Ο-φ[wώ»θQ­m­|BtνZΠά“0·ω%)΅·cw‘Z7ΡψoFΥ.mgΆΈΤe`Ϋe(± œ(ξΜ;ηŒΥ-.ζϋΔjz­ςΩ0Έ[€ΎSIΏζΙQŽ˜ΐλNρ$:LχΧφzΚΟ,΄«Ω€Sσ6qΈρΖJ©]ΤJWΫ[^ΧυώΌΚwsJWΫ₯νq4}6Β[[ύVΞu»„ŽožF'…'錚΅¦Ϋθή!™¬m,€Σo™IΔζTr;[#ŽQTτ FΜi—šNͺΟ­Γ,‰:.γŽδw{K“GπνΑΤ#ΤF£xŠEΌQΒΘ‘ˆ#s۞”ͺs'-οΣ{–ϋάSζΌ·ΏMνώ^·₯ΫθιαΉ――τΩfΈ΅œDΐ\žΌ| {zV±<<Ϊ΅ž›œϋυ<ψε3τ}ΚJ€;τ=}kΦ}9Ό!yo>€ϊy~Ρε\ςΉΒηηΧ΅^WΣ^πφ‘φΜ₯½²CpžSf"¨FzsΙνιYMMΉ5ΝΧΏm?9©Άν~½ϋiψ”Ό; Η6•s©ήZάή$ry1ZΫƒΊFξI£=ΙΈϊ :–›{$:5ξ‘um™D›Ϊ9TuaΓzT:~©d–z<š”Φπ‰ΜφχΠ£œ`†QΞ GtφYΜ&ρυόΜ„,PUΞ8ά[¨υ©ΊŽmέ­tΡνωzά¦ζδχςίoΛο,ψιeΥ<Υ½ϋOφ|ώ~»<Ύ3·ŒξΖ:ρΦ°5C’˜ϋ)u6ο›ν,…vϋmzTήΏΆ±ΎΉ[βλmum%«ΊŒ” ›ϊT—v:­€¬šΌ··O”Ϋ”φ,[·°­RδͺΫΎΆοcKrΤmίSCΓΖΝ|©Ύ’²Ι\Ζή\m΄ΉΑΐΟaοUu{M2οΓ©ͺιVΟfΙ?Ω恀2W!<Σ¬eΣWΑΧv’κ*—“H&ω.pW .@Η>½¨Ά—M žΞMEVυζϋ@‡ΙsΘΞ1Ο­Eš›’ΏΕηk]HΥIΙ_=Ώ₯;AŠΫCΆΤ.tΫ½R{’Lvπnˆ?‰ŠŒδϊS5 'ΠeΥ-΄ϋ½2H,ΦΣξ*A8 …†zŸσέΦz­Ύ‘’YΩ\j“ιwv`’H‘Œr‘<·ETΦ$°Nx“[ΎΤ˜Œa^yΞξOΆ)GΪsκέοηk_ξΨKŸŸVο=Ώ-ˆυk;!α­.ώΦέ‘šWx₯Μ…·Ÿo₯?[ΆΣŸΓφ:ŽŸhφ­,Ο£LdΞη&₯ΣηΣ5 Η¦κΖΖ{išXάΔ]]Xr8θsOΥηΡ›ΒΆφV7ξσΪΚΟΆHYLΕ±’;(ϊœρT₯%%toΎΪΐτ)6šZξϋμOc£[Ε XήG£Ο¬KsΈΘc‘‚ΓƒΈ^sυ¬ΏE¦Δ,Ɵgse9V7άnʜρΧ¨λZgL].ΜΨk³iwε?y»]²y%z‡Εz¬zveγκ3Ϋ2]ΊΞO 3ΙΗ©₯MΟΪ­χ}Χ—ά(9{N»ΎπΕ_iϊ^‘},zΝηΩbXχ!ήqϊž? ΙΏŽ―#΅ΛHΛ‡ψ” kxA΄EΎ—ώΖ/χ{½φσ²oώΞo>ΔZωεnλ·½σU蒊(’Š(«‡ό~Iώ£·ϊΉΠtͺυcPΙ?ΤvQχ:”^Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  m[“F3΄6–“΄«°™Π’Έ#ƒήͺκ—Λ:ΚΆ–Ά€.έ–θUOΉžj œTΉν©‘RζκQEYaEPEPEPEPEPEPEPEPEPEPEPEPEPEPνGVΎΤm¬­οnXl£ς BΎœuϊžxFŠ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(Δςn³ΆO?~Ν߻ُ/'ΧΎj½XžMΦvΙηοΩ»χ{1εδϊχΝW Š( Š( ¬jρω'ϊŽίκ>ηA«ΥCώ?$QΫύGάθ:Pz(’€ (’€ Ώ‘X₯«ΪΩΙ!f}…ΐΙB₯΅Έ–ζ+‹w)4lv"¦iΈ΅Ε$ΪvάΥ»ΡβƒDΈΏ[†fŽω­mΰ€ΉέX΅aο.Υ­ΪRai|βΎ―ŒgςŸΒ:*Ν£]j†;ιO&%p©»–l‘žOς1•GF.Uυ2sφQΌΩΘV–£ΟͺωοΑo 4σ>Τ@zgΏ85םMBΒρu}/OΣδŽ#$6Š7αe r­pPω²"μd ykŸ˜φγ½­νSQvkζ«νεΡ―™©ͺθRΩY%μ6χ–Lώ_$+z0#"±λͺΥφθ~+Έ{ϋ™χ*D ύξ™υUΏθ›|:ΊœVj³ΘR(ξV8ΤpX‚Fγ‘P±ζžΊΩtΉ ·,9₯ίO3Š’»½CHk­ φ}KN²Σ―-—ΜŠKg@²ŽκUXσο\φ•α[U΄66’HI*ΜUδuΰšΈbiΚ.MΪή©q―›nΖ-jι,Ί…ΌΧO<–q­<큻ϋ£“νV5 k:u”—w– ›ΝCŒœt=Mhh1Αuα;Έ5yMœ—"HWζo;n6νώ.9₯RΊpζ¦ο­΄ΧϊbTγΝΔΖΦ4i΄Ψα›Ξ†ζ|ωsΐΫ”‘Τ{j]#E—Q‚k–ž [8HWžv!wŠ1ΤΦ·‰’+oi–ϊdŸiΣ !Ή<—‘RΏΓPκ_'€τuO»%ΔΞψξÁϊTΖ¬ε­ΫσιίBUI8νΨΙΦ4Ήτ«„Šs‰" #–&ά’)θA­|!­MRΗh«ΉŸΜ?οͺ›Wωό »ύτ–tSίnμkŸς&ψgώήΏτ`£ΪΤj)5vΪΫ΅όΧ`φ“i%½Ϊϋ―ώF.£§έι·Mυ»Α.3†G¨=λVΟΓάiΦχ’κZe€wŒks9F 1νVD―}ΰ)Ϋ{;₯XŽH 9P};.«’Λ’ι–Ϊ…΅μΣΪ«©ςά"ΞN{’zQ*•²έ;;zyόΞmYnŒKϋi}φTΈΆΊcŒIo&δ$φΟ¬|€ ΄ŒΠύ’>ρκ­βM*>KY¬eylnβσa.0ΓΥOΈ…ν4λ½+ΒΙ©ή΅Έ*T ˆΰΙΞ[#oΦ”λΙF2‹ίΙΏΑ? V£Ώ‘Λκϊ%ώ±5ό5—!‘\c= υ«Άž–[Ky―¬¬šδfξ†qΨπ8ή©κ—n`]=›;iε0°œ‘ίΏAωΦώ§Ÿˆ­τΫ€Τν,Ϊ u·ž+‡*Λ·Ί |ΩΟANU*(Η™ΪχΥ/»MBSšJϊyΫξ9KλIμ/%΅ΊCρ¬§΅m[x^i-νžζφΚk₯ 3Ή ΰτ<3Ϊ­|Jςα!ΚΟό{GΈ·RyλοŒUZ+/τΥ--p$WΜδ:λ±qσ{b₯Φ”‘ m}τΈ½¬œ#-rW–ΣYέKor†9£m¬§±­kO j·0Η(†8–Q˜Δͺ3ύ9^··Όψk ͺ 1‹ΜVξBηπΐSΔχS]λχςά32„@…T+NͺŠŽ«ŽeRΙi₯Θ5m.οIΈX5Ό©Y…ά‘Ϋθk^ Ν+ˆ₯¦ύΉ†VΨM–~ξ>]˜ιžύ1QZ΄’“NΚΧο―bjΥ”Rk·§2K:Γ3JΜ ’N1]ήΉO6(―,¦Ώ‰wΙi„ΘR$zS/―"Σόw=ΨMΡC|ΞTwΓσΦΊ=O΄G©Α«ZΝ Σ<±DŽLΔ°'qΐ9'°₯ZΌ’”–ŠΧΫ―aU­(e¦—€p6V³^έΕml›ζ•‚ͺη5Ίή™„ΡΪίΨέ^B₯žΪ%π:γŒ=+'Sq³vφΜP ά‘S‚γŒV…’ώΓ€ψ†ψ”UVKHw#tg­iZsQζ‹τ]Ωue%hΏ—vrtUν/MΌΦ/ „³ν.Wp^;υΗ­lΒ βωρχω?Ζ΄zpv”’~₯Κ¬ ν)$sΦΠIssΚαg$ΰQu–·2ΫΜ»e‰Κ8ΞpAΑ­Ο 46#‚ΪώΐOp.£‰XΚWΙpψ'ŽŸεV|M¨i_Ϊz¬?Ψ‰φŸ:UϋGΪdΞνΔnΫΣ―8ιPλKΪr¨έ[ΛόΙu_?*W_/σ9Z+_ΒσΗ±oΦ–ΧQάH‘:Ϊ ‘ΟZΩΤυ'FΦ.ν¬τ{k ³8‘ξFqΙωPtP:fœκΈΛ‘Fγ•F₯Κ•Ξ>ŠέπΤy«O,dQ*³˜ε}±D ΰ’{C]υ„Ϊ₯$φϊ*Oj‚X€Σ\dsΘ`₯MLJ„ΉZνψ“:κεgEtš­‰w­jβοΛ”[Α)r2K{zU«MwGΌ‚ν5M"ΚΪo%ΔΫDTnΑΐ#Χ¦ 9WiΎXΆέWwΛΨδGZΠΧlνlu‚Ζρo •G‘Θ¨τ»Υ°ΈiZΦμΫ²α (χΐ#šρ½Όή!–;XRŒqΆΔ”ΰUΉ?j£δBœŸ΄Qς‘ƒEuΎ’ΔxWQΈ½Σm$³xόΆ †rΔπΗ<ιΕ2ύν5 Ν~ΆΦw–³¬mφd؎Œ;\Τ{y§/k“ν½λ[­ŽVŠιtψ¬΄―Γͺ]Ω₯νΝΤ­1ΚO–нI©ΟjΊΧ:eΗ„―ο­τ‹Xo<Υ…ς *ξζLŸ”…g€[W΅ΑΦ³Ρi{m©α£¦.― ΦΓ,ΨΞ3Ž3Žqτ¨υσ§^ΰθα…ŽG–>ƒ=yΖsΦ΅ηχω,φί‘|ώχ-Ύ} t=}aρΕ€xŒε K€§ςͺ7Φνg{qlδ3Γ#FHθH8ώ•wΒίς2ι_υυώ„*?ΘΑ©ΧΤΏϊ¨R—΅qoK›φœ―kiΆRκ7ΠΪΑςdτQܟ`2j]oM“HΥ&±™Ρδ‹dΞTΧΨΦݎŸweα¦Έ΅΅ΈšοQ5h£-εΒΝΠpXρτ߈ΆσGβ‹™€‰Φ)BvRb4Ξ|Vq­Ν[•=5ϋՈ^jœ«m μΌ=$Φ^^^ΪXΫΜHˆΞηt˜ΰ™ξ}…WΤ­a΄ΈΑyΪνΙxƒ§ Wc¨Γ₯Zψ[A‹Ršιa’30ŠΠ.ζvδ»γ€p+™ρ”ΊUάB ΌϋKˆ–x$#‘υ΅4«{IjϋΫNήdΣ«Ο-|νς,ΪxfYm-ζΊΎ²²k‘˜#ΈrΗcΐΰzΗΎ΄žΒς[[€1ΟΪΚ{WW©Ηgβ+}6ι5;K6‚έmηŠαΚ²νξƒ6sΠTΌΏψHcς³Ρξ-Ԟzϋγ4«IΝF]oΣkN¬œΤeΦ"­– Ε¦‹+\²Ά‘pΠ2…ϋ˜8Θυκ+Q·[MBκέΊΓ+FŒdFiΡjQ-ͺΗ3΅Λΐωsϊ ―,,―$‡sΉ,Δχ&·„f€άžŸπΘΪ1’woϊΈΪ(’΅4 (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€,O&λ;dσχμέϋ½˜ςς}{ζ«Υ‰δέglž~ύ›Ώw³^O―|Υz(’Š(’Š*Ζ‘’¨νώ£ξt*½XΤ?γςOυΏΤ}Ξƒ₯W’Š(’Š(’Š(­ΝV΅‹NΈυXe–Βg†„€ρ8ά3ΑγŠΓ’’pSVdΚ*JΜθ%“ΓVΦς}ž Bφα”…3°φ?/''ƒυm/I72ίEvnΨm†h ˆΙŽχΑnЇAJ.-½|Θt“‹‹oSTŸΓΟeplU–ώVKvΙ…η,~SΙ>ω£LΥldΡΖ•­E;[€†Xf·ΖψΙκ0x Φ{ΛΚΫd­fΝΫΙ|=œ‘ΨΫί]\ΊΰKpΑ¨UλψΦ4sΝνŽY}ˆ¨θ«ŒU―Rγ .δ―q4ŠUζ‘”φ,H­­+R°“E}'W¬"o>) ²60A¨Ε`QDι©+ PRV7uJΘι6ϊV”³X₯3Ό³ΰ4ŽF:€ ]+R±“G}+X‹q/ Π€Z6Ζ υ°h¨φ1εεωωά^ΙrΨΨρ©βYΪXG$vhR!&71',ΗdšΣ—QπυΞ‹¦Xάkf˜Φ1ΈΉΉ'¦zq\₯:²I½ι+%ΨΪΦux'±‡NνΪΫO‰Œ„;ny_άΗϊSνWΓr[BnŸS‚αTy‘:±ο·‘aQOΨ€­ΠύšJΙΨΩΧυX5+›H …ΰΣνPE—ΫžIχ5«}¨ψjςΖΒΦOν…K4dB©['<σ\.„l’mXNŒl’θnλ—ϊlΊUŽ”·{-ήGfΉ ݎ›O΅..…b°άΛφΛΫ΅„"θΗ$‘ŸΞ°h§μW/-έ‡μ—/-ΛZτΪ•όχ—-™emΗ ΐqZΪtϊ›ε]w}x€:Δθ±Δύ£’Hσ~Š©SN<»/!Έ&ΉvEΙ΅+©ufԚB.ΜΎnρΩ³‘jίΌΤ<;«Ξo5oν/™–Ϋk#ŸQžA5ΚQJTc+5₯» T“΅΄·cGRΊΣζΏ…¬¬L6q€¦3!- ’Ob}ΊVΕ½Η…mξ£½Š=PΌlm›fΓ‘σuΗλ\΅JŠi+ΏΌ$Υώςζ£zΪ–©5έΟΘg“smΪ§lΪj:FˆZ}(\έκ;JΗ5ΒH²0X($“υjŠ%J2J=;©©.^„‘l’αM̎¨ΝσΈ˜ ςqžOγ] ¦—’Ε3h’ζ{ωΖ.gP‚ z”PO>ζΉͺ)ʞnΓ”·Ψ»£Kg§šœRMh­™Ώs‘^Ιyufu1y<†@²¬b0Kdτ9ξkŸ’‡Essέ‡³\άΧfχ‡5K+k=COΥ#œΪ^ΛΐFτ*r:υ‘a«xzΒ Ϋ8mυ‚κ#—,PΙΧ€8―|Χ#ELπρ“m·©2£6ϋ›Ί6―kmmy§_Α,ϊ]ΓωFΓ£ΩΖ8©&Έπν₯¬ΒΖήςςζE*―u…X³άκ~΅ΟQMэοwχW½Ν-(i$ώΦkπω>Μ¨F=χΨρ£αύVy—ϋU.LaQJG³*Έη8γšεh’TT₯Οv7I9s]™¨ιPxjϊΒδ_}¦θ«‘@T’½N{σΕ-†£₯Cα{½>q}φ©ΨHJ*l ΉΫΙ9Η―ΞΡC‘}^βt“Ώ­ΝΝ'Z‚9΄νVΛν–[όΔΪϋ&ξAτφ­›λ‹y<pm,~ΕjnΡb ŚC‚I$υλW-₯jwzUΙΈ°˜Γ1R₯Ά†Θ=°A©ϊ―ͺΊΆ‘rσϋ ΰτŠΞt/4ΦΧΎοςΨ‰QΌξΆίwωlKα«Ϋ=?W†γRΆϋM²ƒ”ΐnqΑΑΰΤzύΥ­ξ―qq§ΫύšΩΘΩΗ<O5ŸEoμΧ??]y7?SoΓW:M•ΜWzΫΔ,‘¬ …H<δƒΦ™β;*ξκK3νήt΄’ …@£'?. υοXτTϋ%ΟΟwq{5ΝΟscHΦn-δŠGS†ΕAme LqΦ¬xΟXΆΦ΅Ή΄’τ¦άξ1΅ω@'ΖO½sτQμcΟναμ£ΟΟΤμ,5/¦›*j°;όΧ/l#ύιτ$œνφβ°΅Ή4–6λ’ΕtˆͺDrFη9γ‘ΗO₯fQJ%Μ›i(»¦ΞŽίRΣu &Λ[ϋTrYδC46δ<ν`};©βmZ=RκkEgk Α ·ήΪ;ŸsXτSΖ\ΛϊΎγT’₯̍ν:] ΕaΉ—ν—·j *DюI#?eκwΣjWσή\Άe•·t€{ΕU’œi₯.mΨΤ|έBŠ(­ =/C[α-ζ§wim>‘©NΠZ4±+•mΘΘγsυΕy₯M%ΥΔΆΠΫΛ<―o &8ΩΙTΟ]£ Ο΅C@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@'“u²yϋφnύήΜyy>½σUκΔςn³ΆO?~Ν߻ُ/'ΧΎj½QEQEcPΙ?ΤvQχ:•^¬jρω'ϊŽίκ>ηA€+ΡEQEQEixrύrΚΦλw“4iΑζ¦RQNO €ωSlΝ’·οtΫ(Ό=sy“ΟME­“-Η—·#Z‹JΣ-/t]Jα₯nνΜl+:υΟZmsy؏k_δbΡE© QEQE^ΣtΩoγΌx™Zΐg}έΐ `{σJRQWbm%vQ’Š)Œ(’Š(­ΝKL±ΓφΪ•„Χ^o!Φe 'νXuššΊ&2RWAEU”Q[zφ™ei¦ι—ΊtΧEyζq2…+°Ϋκj%5’ϊ’δ“Iυ1(’в‚Š( Š( Š+BΩtγ£]΄ο(Τƒ― |₯sσgπΟιS)XMΨΟ’Š*†QWu6]*ω­gdg ­”ισ(?Φ—2½ΊŠκφ)QEΖQEQEQEU½-lZδNKˆΰΪp`PΝ»ρ=:Υίi–ϊeΥͺΩΛ,°\[%Β™ gƒ₯C¨”Ή:‘Ξ”ΉLz(’¬°’΅΄ ϋOνSO8Ά²΅O2iŠξ €δΤΊ¦Zjκ:]Ω»³σ<©7G±βn£#ΠϊΦN΄Ή:™Ί‘Rε1(­GKϋk»Λ˟²ΨZζI³sx sF―£Εmc‘§έ}ΒW1ο)±£qΞΦJ=΄9Ή:‡΄7)ElxnΒΪύ΅/΅οΔRΞ›N>eΖ?έ…΅¦›£ΝoΏΜΉ€Ι.㑐Ψγς4{Xσςuώ˜{EΝΚcΡE© QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEby7YΫ'ŸΏfοέμΗ—“λί5^¬O&λ;dσχμέϋ½˜ςς}{ζ«ΠEPEPV5ψό“ύGoυs ιUκΖ‘’¨νώ£ξt(½Q@Q@:9)H™‘ΤεYN> Σh ™d1˜ΛΉŒΆβΉγ>ΈυŸΑWΦΓ^’Žm– „eIέΖGqšεkwAΦ­4Ϋ Λ{4έ5ΠΨξ. / `χοXb"εT―·ζeZ.P²W5SŸ_πΎ51²Ωˆε‚A©LΆΰ1P錚7„΅`Š9/ξ. Ι"†¨ΘŒš£’kVz~™yi>šΧ&λ ξ. |£1ƒΠΤz>Ά,¬ζ±Ό΅Kέ>fήΠ³*ίήV `ιI)F1ιΫMU΅όL]6’ϋwFΦ‹/‰φΓXΞλnσCq±UβeχqPψFβτ«Έ­οm΄ύUε..`ǎT1iΝS—^ΆΆ±ΈΆΡ4±›…Ω,ο)’BΏέ n“­ΩΫh’i·ϊ`Όη3σvω@γƒιJT€β“kM?αΎBtί+΄l΄ΣOψo‘³βfΥΓ,.εΣυVuf½΄1^°―_ρ¨όͺΣ5X…•‹}žΙδήΠr8sόCž•‘{­Z&m;I±kXgeižILŒϋN@θͺšͺΪMΤ²Rβ’hf…Ž‘κ3Ϋ§Zjƒtœ\zέ[ Qn›‹]EΥuvΤbH͎Ÿm΅·nΆ€FO±#΅f€I “ΨVεξ­¦9`Σ΄H y Κ²»œcλUΌ7«bjΡ^ˆ}€ŒqΤcƒΨΧD[Œ,mεύ\Ϊ7Q|±ωgƒΝv:απŞ›k¦ΑΈΈΆK™ξ$Œ;1lό£=ΕsΪώ€u}ZβψΒ°ω€ŠsŒ:χΩ, #Žt˜ΖεG@ήΏZ~ΖV\ΡΌnτΣεείοfτΊΊΧOΛΘgˆ΅θu:Α>Ȑ]ΔΞfhΠ*Ή8δcΏΧI£XAy xnY¦_:άάΌΫ‚΅Γ‡ΘPOqΟΦΈύkTŽόA΅”V°gdqςΗ8Ιf<“ΕM¬kQ^ZiΆφ6eŽς˜˜Ή%ˆ$ηŠr£'Β Ϊ·ι£>ƒ•&γΕ[WςίόΕΥυ;έwSŠ α—ΛXΦ0žY$ΞΊύ[ΞξώΕ’κΪF›m c‘ΏxνŽKε5Κx‹\΄ΥΚΝ˜m―†έΧrΕ°;ŒžœϋTψƒOΤ M­iiΌU ΣE9ΝΗpΗ_qS*R’»dΊh[ TδΤ}Ϋ%ΣOψa|h,Yμnm&³{Ιύ©mcή1†wΙό«Rο[aα}3P»·‚λP2Κ‘;Ζ‘δ¨Σs:ž₯my=Ώ“¦ΫΪΫBΥΔNηάη“Σ―jΦ—Δ:<ΆYΎ€ζήgEϋsp[―;iΚ“ε‚qnή›k¦ΰιΎX§νιώfF΅­ήk"·™‘+$aIqτ¬Π €p:š’ιβ’ζG·ˆΓ 1+mΫG¦{Φώ‰βƒ₯θΊ`²Ž_΄nύαlcrγ‘Žk₯ޜ§–ΗCΌ"Ή#ς9ΊλΣRΉΤΌͺύ±‘ώΞπ,dFͺT}τRDž6š?25`Y7mά3ΘΟjι‘ρ …Εœz {‚­"ύΉΉ+ӝ΅ˆ·kFν4ϊwσdVMΪΡ½šνάΒΡn%΅Υ­f€ J†ΰπx>Ζ»MKΔW~2’Βήd°7 °ˆWχΉ#qcŒηšδ…φžšΔ7Qi¬–‰‚mΎΠI$wߌυΑιΪ­ήλvw^$MU΄;ή΄ΗFݎ;qŽΥi{Iσ8t}·ϋΙ©OžWqιδ3Q‘4_j omm4qΚθ±\G½ΟJίρ–ΊΦšΫΒ4έ.aεFwΝlΉ@zΧ-β BWS–ς SkζόΞfόΆy9ΐό«QόC§έ¬2κΊ*έ^GΝ Šΰp (₯IΎIΚ7v³ΫΛΜ—MΎYJ7Σ_Γ̏ΐφϊžΎ~Ϊ¨`†7‘ޱ޷?₯tPί^5Ϊ‹½kΓςιΕ°φ›†ΝžƒδτF nk]sϋJΚ {vy1#ی#ίΏ½]ώΧΠƒ™—ΓΐΜyΨΧLcΧινSZ”η.f­ε§ίω‘U§)Jν_O->ς½Υhώ$Ή} th‘ν6œqστΟ΅t+Χ›Fρ%δZE΄JL³4aΩΞΡΐΟAOzζ Τ,ΫSšκMŽhδϋ°A!PρΣΦ†·―iš¬—7’²^L?Χ}­ˆSŒ·nJ©RΌγΝ«YνεΎΊυ*Tο%Νιή^eΟj2άψ²V™"ςξΦGš5Œm8VUΊΰž€“ΛzΞ₯*š^ΧMνm?ΠΞtœ§¦ΧMφΣρ.xP²ώΚΏuI.JΘ— ›ό·_QάΦΤΒΣαμ‘YLχ %θΔΞ›7ΆήJ©η }s\Ζ—6›˜uIξ[‹ήZϋη‚iϊή―&¦abŽΪΞά‚ή?Ί€υηΉ=Ν’εSK₯{½­ώ J“sΣkίΛόΜθδxχynΙΉJΆΣŒƒΤjW‘έQ]Ω•£9ΐτδšeΧc¦ΑEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP‰δέglž~ύ›Ώw³^O―|Υz±<›¬ν“Οί³wξφcΛΙυ@Q@Q@XΤ?γςOυΏΤ}Ξƒ₯W’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€,O&λ;dσχμέϋ½˜ςς}{ζ«Υ‰δέglž~ύ›Ώw³^O―|Υz(’Š(’Š^k·ΦΌamΰφρ“Bέf•6$ΰυlρ‘ΪΈŠτθδ‚Oa‘-yQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@'“u²yϋφnύήΜyy>½σUκΔςn³ΆO?~Ν߻ُ/'ΧΎj½QEQE“^΅«ιΣhεΣυnΪυd“+δ=±―%’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ +ό9i£x“α€Εk©hΦΒayΣ3|ίχΑ9λΖ+Ν(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(Τ>Σx….Δ_ΨΝgώš\B᱌{oΝp~%]%5«αχΈ}7#ΛiΖ§?†sŒσ]Χ†&Ό7πο]š}bβϋY΅Ηg Μ‘:όΓ¨ϋω9qί5ζ4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEΩ endstream endobj 89 0 obj 29646 endobj 85 0 obj << /Font << /Font2 12 0 R /Font5 28 0 R >> /Pattern << >> /XObject << /Image4 14 0 R /Image9 88 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 90 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 91 0 R /Resources 92 0 R /Annots 94 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 91 0 obj << /Filter /FlateDecode /Length 93 0 R >> stream xœνYΝnGξY$$ϊqΒΑΘ4ύsŒ Α x(˜ƒe­!&‘ΰΔ )·όŠK^ Κ%Š”Ό§DyŽœ|πK$_υμμΜξΞΒΪ;‘r`G»ΣσΝLUχWΥΥU½{\ Ιι8[5¬t8ομς=.…”*ωθ€ΝOL_γ!:νrγ]π2Ώ>l.΄tΑRcΘ§.θχΏΞ@Ι?χώπ‹{Ϋ’ίύ4}C΄FA‡02Ei’αξIΥ=~η Ώ‚c―₯IeMω€X’SΒΪΐ•u†8€›‚"pŒ [˜΅ΖUXσnƒU’Rkv›V¦ΆΎ ³υ":«’ΓCB™€d¨ωOA;›Ππΰ]†ΘQ§“₯Ξ―—Q>βη>xψΰ+Ν€OδεI»&|ής²2Zy›ίδ§ΩσUquΊXcϋμEρtπwQ^²w‹γΈ:Yœ\ε&ίgΕJΑΨΑ*ΏΕΛKόBΩgχlτ"˜gϊxz•—χIΩ½2λI>H£vh:½Τ2Υ'χΞ+—‡A½ΟvWΩ¨[Π°”Τ82VΏΨ‚ZŽΆΝ•W‚γZ9‹ϋζ™ϊ;M γ*Vϊ•Φ°†#΄“Aϊ6‹μwφΫ`ηΩuvέ`›μšΧ£*LΈƒΙi»υέj1;"£e«Ej©ΰmPΤ?/#Γ(cR͘˜]tŒ [XH1ΖjΧ―6Πa­Ρ?i&*&»·qp«rŸY >© Ή<"K φ2μSv•}Β.Βbψ½Α-f±NeZ#J%°Σ©l ΑΚ8‘5lΖ“œ/x!/˜U²Ϊ x’w*αtΆ8L©&ΐa „³ΈˆΖ°υvƒ΅lώ_Ώ~&―j Μψ1SJΠSΗ;Ήv·ο~nωω‡c¦ζ‡2“C4S±,Hε}W\Πy^Μ@Γr)Ι ,ΞK-”‚XD“Ρ[ΖόΘΨα1Ie¦ϊKΦV°–3j];  fqVί@˜γτ-ΙΑ{«Ϋκk`§ΥΗ£–Σ#];΅™ηωΥL‡wg‘V‡½ΡΖOt˜Μηہv‡k¬1ΕHΌmvΪ‰JW‡ίΈΫΐWΪ3₯ +ΑΨ%ψ}NO~Μoή’ό6ζ‹­–Κ0‘ΦQfIJU)¦ζW?όzΕfŸΓ{λC3>΄yˆ”-Z(ΠΑp'ˆζδ εlf¨gO+drΑ…œ½y―¬žΘσμ=vjΑLm›ͺ¨ζ¨ιa‘Ζϊ―2³u>Ό›MdΕDNvΈιΪ-\·[’T Κ(Ÿ(ƒ’Ν ‘B•œ/uŠηQUIτAΔJ l₯h$¨Ρ„₯tΉ%šDΊ ʍVώυ3―'©fD¦dl‚cίΖ†-L{ι«9~΅_ejβO+‘ϋ:+Q„-Wp ’ ήιΐ΅I₯”β„σ–HY/"‰έΪbΗP}τRs(°€―›£³t΅^Θ΅2‚†­½€6JV?Ϊ ¨_l Γ›ΘΔ$TD†GΫBiΞ7ΙσŠ4j…Ÿ*ϊCmjUώ>ΞM_¬[OWΉΥύγΦώΰ—¦ϊ?jŸ4ni‹S[¨ y`ž½ΆŽϋ$œ#ΉΆψΑ7ƒŸ—Uα~Ί€«hί€ΨΪ"r/ς³)Sω$o₯ΰFYlƒΏπ]žKƒ…(Pή9β₯ …pη$Š;šx$>MϊmO„vI'BΧ[ξψ€‹+ΕSΈν:{ŽγZ―ͺMͺLύ pŒ‘½ΒφΙ«uͺ=X₯‘χΐΊCȏтΪΕK΄{‹μ‚’ς·ι(7ψ/Ϊ;€wΠΞώΟπΰLρ,Σf6VΤs‘8ΥιΘ`DΔόξ&eYB̈œ4RΆ(&φίχEχ”δ:SdνΉΎσώΈ‰ΎΕe iΔ?£ΠB`‘b Σ’ΜwJ˜ζλ±·τB|@\₯u~†š₯] ‡lΔYδ&rr-όΠλΣ’'X9ΙsfoΦΕΪΑOδΈrαzΗ Ϊο…RZ•U³γξ!vDIΫqXΡ’r"ΥόΨ«;#v±Ν^ΗsμFΉ—)~{‡ώ``ΟΨO5ΥΩ{ˆΜΉs”`αcΪC‡ ΛΖ€K’lV[}·ͺ…ΣP:ώκtMY endstream endobj 93 0 obj 1600 endobj 94 0 obj [ ] endobj 92 0 obj << /Font << /Font2 12 0 R /Font5 28 0 R /Font3 13 0 R >> /Pattern << >> /XObject << /Image4 14 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 95 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 96 0 R /Resources 97 0 R /Annots 99 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 96 0 obj << /Filter /FlateDecode /Length 98 0 R >> stream xœνZ͎EΞj$€ΙgXΔae―Η2ιŒόΟγZΆ1ΜwΝ4-ζ` Ζκ5 ™“OHάφWΎπ ­VΪ}N‹x9ωΰ—€/²ΊΊ²»«qΟtYΪ]κιμθͺˆΜ/~2"rξKRZςυJ;pΪγσθXή—ZiM9$―]Ήcυ;nβciƒA—Ηgύ£}t<˜Ι•/όχžΌ)?„ϋςβogΎw[Λ»Ÿ@‚αwLΞd(«s6[ωρέS‰Ί'ί?/oΰΊ_I’"©\`K1yRΞEIΞ[ΖB\ŽΔΔmVќ³Ύ₯υΟφ΄…HjS‡n?*Πv_ψΣ•Ό£μq“"›IǍwƒάuL‘uŒυ&;žό₯)xL?–―~τα§FzάΘ―$§ο/λ5γν NN[₯Mί“οΘsβΡΎ$ΟXk.ˆ'βΫζαδϋf:y,^j^Δ·—›—χ₯-Ώ‹§ΝΩFˆ§ϋς]9}]^™Ž9=—‚Š6¦΅9žΫ—ΣXΨ3½±nI!jŸ’ρϊ‚‰<²ν«Μ./KO€>½“φ.™Š4λI€ Bλ¬H•‘m₯s €ΐΨ{iΘ+h<τχtοU½€ΤΦ€ ΄α¬΄V―£5Šβ?βOβ@\7Ε[βmq(ώΫαzZΏΐ9έ°ΌΣk-γ!VZΡZβΕΰ"ρό,¬ŒCΦζ8Wš΅©˜θ‚6«h1§”ZξνI'ΥZΒό΄%8*œ=8‹8Έ…Φ,›ΟΊΕ« ›4–M‘%Η%}Yρ¦xCόQ\ƒΖπχmρΦvf ’T:ƒΒv`LΦ+c 3™υfΖ[YΑ†θLΩ―`‰ΑSŠΚ›’q¨’–ˆ³Šcρ ƒYυtO«tώ<˜ί<_v52a™xRxλΏψΪρν»wœΌόΡ©Ν‘Μ–«νJ,‹šBh㊏¦ψΕiΦ“|Ξ:*'£Ϊ(   ±S zλTn™Ždʚ¬‚«/hΩΉ6v|„NΦQOŠ^\Δχ$ψ8}Ε9†ΰL-Ύ#Usμh‹et|zΒ\ΦQ§ζMv΅6αγuR5α` Kfυ…zΒ‘žpGλU1糦›£:Qšπ/ VπΪSΪ°ςˆ½.I~ ωΞίΛwήΥς=ψ‹k·Ξ0‘ΦqfΙEmŠiδ―ώZΕα˜ΛϋΕ†Φlθπ)[r`’•(NΝΘ·ΚΩμ.*rj)';™»Φ«…ι‹@j,…Μω„.1Υ`Jz3ΧHŒ‡ͺζ’J­lΨDΌΤhΚq:€άC"ωωΞιόΟƒΤ!’sΆ¬€`˜6Τ΄YE3A‡Φ#φ€“W™†ρ3$ r_ο4Š°έ Ž¨΄N!JT¦œsZ²]‡ŒυrΨ[·Δ (>F)9HE¨qŒ:FΊ‰Z/–ZAΓͺͺΠ“f= %k˜wΊ{ΙUdSV”αqΫA‘Aΰ|Ά’,ƒ±©Hc¦N…•’ί¨νQΝ£Κ‚ΟƒΎΖo.,Fχ₯™Χύ‹Ρ“ΙΧ}υΪ9όd~X™ΨVeΘΟ1†EΒkσ2daΩΧμ'™|΅«£δΞ¨^αΎIsλƒ;y<ωίΎ|%(?+­ό0mn7“οpώkw,-6’ΘEψΰŠwΜ½Χ(ξα‡Ωη%@: CάΠK•9~ΠΞΕ³ΝC˜ν%ρΧηύΠ6© τ{ΐ φYρ„­ΪδΞ‚)Ο-xΤ=B~JŽ7Τ!\F€=8dΏ­FΉΙίΖ‚}€ϋμβΗ… .―#mΧcEη Ν™1@G£ό{”]ΙP#rΔΩ’Zκ?Nώ>ά+œ»@Μ‘‘νΉ2^ŽχZ«α:€›0 ?h.ΐώ§]πm―ωbaΦOGAΨƒ™‰ά_ag“ΦΚ#οπΨΈ1\Šϊ“Œ„ο*η%|7ϊύ¬Ή^ΰ»ΐ;`gΚ{EΧ˜ΟβΪγVχ(˜ςfGŽΦΧ=B”HšoΨπ0z)©Ÿόs,TΈΖζζΆψ‘y±Dix<ΐ½Ξ‘ϊ…_ρQ‚ψ\|ΩA],}„\&Η©^Ά^:T8νΈ#Θ.b_Eš;,κτ]ξͺV·Ά;DY”κάηΞ&/ŸM¬žV Ctνr2‘-ROkΓΙN&ζG;q=ίΛπ€’ΚrΙu€“χž·αΞΖ86χrή‡Κ:sqUόAόUΞ q³Œμ*Ξ‘ͺΑ—ōPέΈΐηΦ‰μ%g• δcιCI¬¨³ŠšMΒ~ΈΘνTΔΚΐž—€yS=*cψG,iξ+ΐ…žΩΤTί‹Ci§J―"͝ΝkgVόh§φΕ ­½ ¦dΧ&πΙού ―Qώ(˜+8Ϊd”)b,' Ž—βΒcο²εWgψNςNiΏU#λ8«Zήη k¬'υ݊ϊV…μ½Mcu0ψ@ΛΊΘΑ}°…ΰΰoŠΛβP\Ϋω°”ΑLΝsλ[ΐ€JG4h—-Έί.Nnΐ|±ρ1w9X,6IŸ:bΥ[Άήζ »!O<ƒ©2ΐ Y†1lž> /Pattern << >> /XObject << /Image4 14 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 100 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 101 0 R /Resources 102 0 R /Annots 104 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 101 0 obj << /Filter /FlateDecode /Length 103 0 R >> stream xœνYΛnG­žHHΤ?D,"‘’ޏe‚σ20 f ‘6Δ$Rvω Ύ!Š”]"~e—`—¬²ΰ+rnυtwΝLO˜ρŒ₯,`°§ϋΈ«nΥ}ΥΉ·Ή’ΣηγζΒJ‡οΓ#~Μ₯R%΄ω‰Ω{¬{³Νορρ ~uΌΙεΩθE0!Ξ­qk›Ÿ°·htwή“|.Fνpι|τ:Π•iώεΥyεςΦ#Tο³έ•t6κͺ{HIOΖځT8ΪR6W^ LμΧΚ XάχΟ΄?³ t\ΕF~NΚ kXÍΪΙ }©Eφϋ†ν°+lŸέfwΨϋ½ΥλI&όΑi‡εάj1;"£e«EΊRΑΫ h}^F†QΖ€01š11»h‡ΥRŒ± ΰvh­j΅ˆυI£¨vo ςΰV3δ>σ/|Rryd–¦μeΨ-v“}ΝΓb;ψ}‡έ^ΞbƒΒ΄F–JΠΞ °5&VΖ ­a3žδβ‰—ς‚ΩY%«€'z§bNg‹Γ”j ¬ Ξβ".κbt6?Ιχ/δSMA3ΎΣ”κ‰i` φι³£ϋZ~εY§©Ε©Μδ”+ΝL. RyίδtŽ‹9¨ξ!—’ ΒςΰΌΤBy ΘEΘή2ζG&ΐ!I*#κ–¬m`;O΄²{(DqίCˆq$ϊbζΰ½Υ₯ψ8,ΦΨbέ6Ϊyz`"λ°5σ"Ώš[πΡKΐ™κ>ϋkτ3Τ±:x§ϊr›ΫIC¦:ƒΠCψ‚­F/Xi ΙVκm4­ID+mΜωΤκt@‰«hφ-ΰiiΉ; λ΍––νeE˜Ϊu¦6ηQ9Ύ4sΫΗΊΛφσΥΥuΕYxtQ·£ΣzjŠ£y΄Θ"ΒΘGάY Ύ,ΠΊ@“ŽΑ‰H ͺŸ  ;-“ŽMT ]ˆ¬°(‰΄"„Ζ,κΨ,P‹ohˆpœ›“VΟΔΡZάxP„”NxMa΅§Χ λ’cκiά3š¨…Ξb x°΄΄ΒHχ6κζƒ(γIε@\έR9Ι\•όΨΉδε4= ·γΦ"ΗFψδœ‰›’ΗΤ-56DΏ€{ψ-v΄ψϊڝx…zίΓCO‹ÁrΉν₯ Σά«;0}Θyη&·Ιl6ς€+`ΧKΦu“ ΫKZxΒ€BCg`"Z“{Ϊ5ςΊ7XΌ…•\vN€”βdΊ0.ε°¨Pϋ΅―ώŽ` K€ξ―# !Ν 8³" M2¨ηQ‘«κS©^lSλ€ˆεCφΑvΓΖpΊ”΄}YΈš@ACΨ­΅ k‚΅ :xhΒΙΗAMΘf2;E―+:¬.0T™M΅]ƒ °|p “·οπ7Kο &瑁ϋFJ΄Ξ:…d₯ϋQέy€d Ρη_¨‡‘ endstream endobj 103 0 obj 1881 endobj 104 0 obj [ << /Type /Annot /Subtype /Link /Rect [ 298.6378 245.00552 657.1224 263.00552 ] /Border [ 0 0 0 ] /A << /Type /Action /S /URI /URI (https://github.com/prometheus/client_golang) >> >> ] endobj 105 0 obj << /Subtype /Image /Interpolate true /Width 792 /Height 42 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 106 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐ*"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ω’·uοjzζ•₯iΧ'Ω4ΨD0".ά€½NλΦv~π,ή.Ρu{› Εφ!JYμΙ—=χdc‘μj1₯M*΅zuν} ¦§'Ι§,+ο•Ωίnc“ΐΐύ)•Ω|FπŸ„M²M@έj{Ψ†6ΒxΪΧζλθ=k«£V § ™3ƒ„œeΉ³ΰύU΄OYj)y§΄ X\YΖ²H‡Fe ΐ 1šχ φ„‘-5ψH΅ Bi-^ ( Σα‚0μ>ό‡Ν'<€kΕ|α]GΖ~$΅ΡttSs6Iw8XΠ}ηoa^­ υ=ޝΖ:& l…ΪǝΠΘv₯±ΠυΗN•R·Q+τ<Οΐ>;Χ| ¨Λwαϋ•ŒΜ‘&†Uί tάΎ£Χ―'Φ΄> όQρ7Žν ΅Φ ŽΖή–Ά±ωqξΖ’I8Ιγ&³<α˜ατ―ρχ…lό-yk ˆτy'Œ»I§ΚFAΖΰχ‘I7`±κ~ψοu¦_ιΦڎ»«ίhvΫKηKn₯ Ρ ωΨΖ@Ί‘υ―4ρu‰Ί‡‹t).,&’λΟΆl"Œΰ‘Πr9‘Νq΅BouέbΣKα3ήέH"Š1ΖIχμ;“ΨQΚ–‘sΤ.ΏhoΟdπ,Ϊl2Ίνk˜ν˜xχ%Jς½+Q»u+mCMνο-€Ε*Q‡C^Ιuπ[»iςxίΓλβ5φc>8Ξ3œγ΅Θ|ρž΅α_ΪZθΧΕ«wmot%}Ιζc‚G;tυ€­m^’ψΣβο‹ΌΠŽ–—ώNhayoQId$nl+0ηhοԚ»ν γΘ’XΦηOΪ_ψσNk˜ψπηVπO‰ν4‹ω ™ov›[ΈΙςεŸQ‚yΞ½Ώg;‹}QtνGΖ:-­ύΐ&Κά‚dΉrHRAΐ9g₯νƒSΙ|qβύWΖΊΚκšλΒχK ΐ QΖΠIv<ΧUcρ·Ζφ~]jMh°eiνΡδ ΈάG8dζΉϋ/kמ>Αl­¬G3C ς ^K–ώξ9ΟΣΉΕz§πεl΅Π|S£λZΜ…ξ΄Λs‰S@δσμ@ηŠ.Α©ζΪŒuΓzΞ…§ΟiΪ°Qr±8τ'‘Ε:ίΖzΜΉπ”sEύ‹q8ΉxΜCvπTπέq•ΞAΑΰUYτ_όaρ_‚τ64™νd± ^$Ή‡Μ0’rJœŽόΰδf²aΥ}¨mX59/ |[’?ˆŸπ˜xΒΗϋ[Q‚ΜΫΪ,!T~ˆΗ‘nzσ^o­κw:Φ±{©ίΘdΊ»™¦•vc“ψV―<9kβ}bK+έwMΠβHZQs¨H6 ¨Ψ #ζ;³τ½ίγŸΒίi[\iϊη†<5διΰύ‰ΚΒΧ, αF3žpzQt˜jΟ>ψMρJψ/ΔvP%ΨΦ―dŽ[9R$x¨ώ<°8>ΐΦΔŠΎ'ρΥ”ZΔπEc oΦ‘ωhΝύζδ’GΧΧ¦~ΟZ3ψƒα/Δ *aξΪ(όιŽ1΄ε˜ϊ“\/Δ?„ΣxWΒφΎ#υέ?_Ρ₯“Ι{‹Φώ'΄»ΛΘ+++ŽeΉ(Ό2;pJωΔΊ%χ†υΫέ#VˆE{i!ŽE#=AΈ ‚=(ٍέE‡ΕOΨΙαΗ·Ί·@‰ΰ²έNΤu Cqσpͺ>ψ…β? xŽσZΡοDwwΟrŒ€Ε1f,w'N€γŒρ\•uί Ό«|@ΦίO<¨σn.f8ŽΞ2}IμΏ‘§d…©³γŒž+ρއ&©=Œt¬­,6Άα<Β€0Ι$ž ι\Χ‚ kϊΏmοΛΠΦ§Š~jώρζα«ιΰa«OV—±δΔαά&μuΰ·#όkΌ“φs–(δ–_h‰ ¬Ζι8Ά8AΛ}γΉ8;~πλEβƒSΙ5k—Ύ35α‡[iV_> † `1‚;χλ]νΧν γΉμž›M†W]­s σδ―ι\?ΔoήxΕ—ZόΡΞρtš0BȌ2Oqλ]ΕO„ϊ‡Γ½7K½ΎΤm/ω™Β¬  χκ9§ jaό=ρφ»ΰF{ΏΝύ‘M ΙΎ9ι‘ΑΘΙδΦ΅όcρƒΕΎ.Ρnτ^ζΤιχ2$Vκ»v@SΤ ¨=i ΎκtΝNϊΛR±±†ΒDI>Σ»rY² 3ονΦ§ψπšγΓ‡ΔzF·§ψƒCi<©.¬ΟΆp3‚Aγ υϊχnŒπWΖψC@·Ρ΄Σ§Ν§Ϋ–0₯ΝΎσf,pA«ΞkWρηŠΌgg­ψΡ€Τ’ŽHΔ°G„JΆLh1€?™­Ο†? uOˆ:-ώ£¦ίΩ[-œι %ΖαpY² sοŠOˆ? βπΎ—g€ψŸJρ sέ 6KR ›?tŽάγŠ4Έjg|]ρԟjώ3Τ΅(Rk}:ΗL$^ήܜG γάπO ’8€œz₯gγ'Œ΅Ÿ MαύNώ‹’XdwL ƒΛzπ9λGƒΎ1ψ·Β: Ύ£Of–P1‰-•˜nbǞ§’jǏ~\xsΓ)β=\ΣόE‘yžT·VGύSg 1ž:υ#ŽkΡΎ ό5πυί‚”7§’ψσ⏉|s§[ΨλσZΌMη †έc;πFr9θMoθŸ|q₯iPXύ’Κπ@"šξίΜ•@ισddϋœšΐΧΌ+gαohPYxIΧ£ždv“O8Œ‰ΪΨ'­{ηΖo„Λγ_ˆiizUέΥΊEge?Ν5Α@wΉΈ‘‘Έ†§ΟV_ΌIiγΉΌ`—qΎΉ6CΚπ©R lΖάc@…Aα_kήΦ5-SIΈ‰/5ή;†xUƒmΔ€FΝ:ΛΐZυ珟Απ[+kΜΠΘ|ˆ’εΏ»Žsτξq^©όΉ[-EtθϊΦ³§!{­2άβTΗP9<ϋ9β›q O΅½'RΆΤ4ΩήήςΪA,R‘εt5ΫxΣβο‹^xΨ^[­΅Π΅6δ7˜Δ•Ξ1ΥΗεF©7‘πΧώ‚^0Α}·¬νv?Η`_Γ·ή"“P ₯VφγΖyω’V ϊq]Oώ>Ώα$ρ.Ήβ=3ΓΊ<΄6ςή™X2@†sςž1\―Δ/ λqX¦«c«A=ΊάΓudϋ‘‘‹τ9SΖOj4Έ­α―ŽχZeώm¨λΊ½φ‡m΄ΎtΈκP½ΏŒd[©Zσoψζκχβ…‹τ '±™ξΌλbpT 0Ž@δr9"Ί?ΩΧΒ–ΪηŒ&Υυ”C‘θP›Ϋ“*ε€;ƒΑΗϋ5Ιλrέ|@ψrΪ5Š,ϊ₯ήΫ[hT"ͺτQΗ OΤI\5:όuρ§ˆ49τ»‹‹;h.Η;ΪΑεΙ*‘‚ dγ#ƒŒq^\¬ΘΑ•`r8 Χ·]|ξΪ|ž7πϊψcίύ˜Ο†Ξ3Œη?ψνrόg­xWΕΆ–Ί5ΔqCͺέΫ[έ‰_ry˜ΰ‘Ηέ=hM[@υ%Φ~2xΛYπ€ήΤοαΈ±š%†GxΚκ<·―ž΅?„~6xΓΒϊZ=ŒφsΪ@1oφ¨<Ζ„v r8³œUοڐρ“TΗόπ·ΡkW?g_ ά]ψ†ΗΔ^» ΓͺΪΟ,pι—ΞΖYG”A`ͺAΖΊtΡ₯άβΆΧυίιž²½}–_m#3“Σ©Ο8κxΞ+β―ΓMCαΔϊd:ν­ΣίF³ξΒ rzŠže°Xΰθ― όαkύα?Œ―΄]{Γz”:ŽŽ%Ύ·WwšΥ|©ί”πΨf0κΎΥγώπε―‰υ‰,―uέ7C‰!iEΞ‘ HΨ‚£`$˜ξΟΠ ετΧΗ?…ΎώΆΈΣυΟ xkΙΣΑϋ•…X;Œg< ΰτ―™hNΰΥ‚Š(ͺ―xψgo§ό;π€>&Χεqq«΄qΓ» wcΏ1τλΑλGSΦ΅RΦΖΪώξIಏɷFιzΘ~CΈ±Έib’©^Ρo^νvϋΝθUT›•΅θt?ν¬ΰρή£&Ÿ~—°ά‘qΉ\ΎΒγ;wwλΗ=ΖΡEtQ¦ιSŒ½•e9sΙΚΦΉν²UΤ.bšEŽ[­2h`'»ο°=π­]ΏμσΰŸψcUρ€ώ °Έ΄‡μn$”`O&Iά§ψ†ω‡5|Ϋ ήΕ¦κφ·“₯Σ€-Ώ·g”6²mm€‡₯z¦ƒρΟSΣm΅Q{©«\έ[=­Ό—ΊeΆ >φΑάΩΫΞGNΤδŸA&y†ƒ jϊδ² KΎΤ ;L’Φ—`=3΄gς―nύ¬+ΧΌ,Χ ανRλO7DΎCc~άγ?LŸΞ΅u/‰Ύ4Τ¬.,―όI¨Oip†)bi8u#b*šwΈt='φe†Kί|J°΅S-εΞ–« Kχœν˜`~,γ^1θΏ‡ηŽsLΌΣε‘w"άΒΡ–ΖFG4έ [Τό?¨-φ‰qcvͺẂʢΣΤuΥcΔΎ'ΦόO<3xƒSΉΤ%…JFΣΆvr@’ΞαΠΖ―Qύš―­,>0hΟ|κ‹*Λ lέŒ„/ζxόkΛ©T•`TG ŽΤΪΊ°TρΧΓo]|NΦ£‡FΤ.{Ωn#ΌXΫΚdg,­ζ}ΡΖ;ρŒW ΰ©£Άρ–ƒ<Μ(―ΰwcΠ"’kuώ+ψιτ³§7‰΅jSa†ύΈΖ7γwλ\E$ŸP=Χφ‘πΆ»'Δ-O]‹J»“Fπx‘–‰p‘NXtηΦ΅~'hΊŸŠΎ|5ΈπΝ•Ζ£₯°‚β;Ȟ²lDΙUηο# γΏ½xέϏ{7«ΪΌΰέͺwΟLψ%α}~ΓαΟΔϋ{νR·žχK mΆΞ;ys #ζ<ލ―Φ4GE»ϋ.±auarT8Šζ&Šž‡ ΗŸjκ“βϏB―Šu<ϋΟώ΅s~"ρ­βKρ{ίΟvD%™²B‚HL“ωΥ$ο¨3ήj kzζ»’jΊ6•{§&’›-’2*α™ŽHιΑ΄Ύ^ΩΨό;ψM©ίΊ.—a«^Ew#’d3™ϋ OLŠπ«ˆ^.°K³ρ£ž±˜–1Ϊ¨F6Aτ­_†&πŽŸ¨θϊŽ™Ήαέ@~NžBƒwχ•°vžnΓ‘<Φ κ{ρπχ‹4m+βΥχ‰΅uΊυ6ρμc7>fυΩ!VUώ‚ΰzA\oΔΟλ3ψEπΒγΒΆsκPZY kˆ­†β’μr@μ 8'·γ^WβxKP°š-7ΒZ†ŸrSd6Έσ€<q£δvΖE'…Ό{yα";="λ\³vrΧΫQTŠ\ž Ζb;ΙΞ(Q{Žη¦~ΥφΣY[ψΦμζβ 9β”η9eƒΟ~EXψ%α}~ΓαΟΔϋ{νR·žχK mΆΞ;ys #ζ<ލ―3ψ³ρ Όs€Σ›OΆΣm~Νosη³z±m«ΞνΪ‘O‹>™'σ­kˆ^.°K³ρ£ž±˜–1Ϊ¨F6Aτ¦ΣάLψ<̟Ύ'•$-G…4ν#ŸΩ[Οm]q}Γ^7§λϊΆ₯_ι–:…Δΰ ˜ΘI@ι‘Kˆ5xΌ?.…‘rΊ<²‰žΠ?ξΩΖ9#π•.PΉξ>/ΠυO~Ο‡‡μn5'·™’T΅C#!%א9ΖF νΕZύ‘-&°Ÿα=μΈ··X€\η ¦Gζ+Ζ<1γxZΒ[-[»²΄”–h‚ ž€Σξ1T5ΟλΊλΩ>±«^^=ΫnΘI‹§CλΐηΨP’ξ>ŒψΛΰjŸ΄†57O»Έ±&Τ‹¨Π˜ΰΚYχ7EΐωΉΖsΖMywν9ymyρ‡Vϋ+«ω1Γ „}Pd~? Δ‡βߏa[…Oj8Ÿ—,α@>RFW€:bΈ‰dy₯y%vy–fc’Δυ$χ4$ΦΰΩκώMπΦΓMΊ—XQ’<{VάΕ°¨?xη­uŸ³’Ά©ΰˆΊ™"¦Ήyg›uέ΅œluΐ?RΆκρψΓΔ>(Šή?jχz„pΡ,ϐ€γ'ΌVn‘ͺ_hڌ7ϊUάΦwœ€ΠΉV_ΔS³jΜ/©³yΰιΊN‘¨κ&‘cci΅'–ζ&ˆeœ(v7rGLΧ²|NΡu?|ψkqα›+F KaΔv‘™dΨ‰’«ΟήFΗzςόEρoŠ4ρcλ·wv`†0¨¬GMΑ@ݏ|Τ^ροŠ<%°x{YΉ²‚FάΡ. zν`@<i4Ψh{ΗΔeΣΌAπGΤkYIl.PΆYs%²Œώ(γπ5₯βRα ψ½‚δa‹B‚Ύd½ρ±}―Η^j73jΡΘ’₯ΣΎ]YH*Aν‚*yό_βνu+i΅‹ΧƒQ˜\]‘”βi3{π?!ιK”.zgνk%U=τθ›Τό)γθΪώ-ρ7φΥ΄Μλ{άω-΅IϋÞ;ϋW—λϊξ©βΆλ—Σί]μω³6ζΪ:ΤΥΏψΏΔ%‚Ϊ{W»ΏŠΫ&$™ς?^RMX.{Gΐ=6χWψ1ρOΡ€½Έ@‘F½\ωgε^Ÿ/‡΄Λο ώΜ>0_ΪO`ΧχŠ-`ΉŒ£±Μc;O#•?‚η₯yη€>&έx/Αϊώ§ΪIφ½IH―£ΉςΪΩ—‘ ΄ξόΕsή,ρ·ˆό]δκχ7ΛLhψURzͺΟΎ3JΞαsΥώJρ~Ξ_&*ΕΒ’b¨όA"Ό‹ΐ·PΩxΧΓχ7ŒΦFήYIθdRIό3Uμ΅ύZΗF½lυ ˜tΫ Ε²9 )2?YtάW>žψ‹ΰο괏ͺιφrιOgp—±‘1G{wεΗξ·G­Z³Ή†λφ‰ψ₯%³«’ψzhΙ^Μ‘Ϋ+¨e#π― Σώ)xΫNΡΣK²ρτVH‚4@A(£€ˆάΠΧ;₯kΊ¦‘qw>›qm=ά/o<‘Ή $nAe'―$Κ§•Žη֞'νΖN?³.Ώτ™+/α•λΒρ6ΟIμυ­Z vβΰι— Ήgˆ²6χϋκ|ίmγoΫ>”Πkwѝ);,Hp¬0BϋΗͺi%Φtmiυ}/SΊΆΤ€,^β7!ŸqΛnυΙδζŽAάφΏxΓΕό4ΧνOΓ‹?θs*%Τλlφΰκ …;wΰg_φe†Kί|J°΅S-εΞ–« Kχœν˜`~,γ^cβˆž-ρE—ΨυνvξξАL„F#‘•PΑηšΔΠ΅½OΓϊ‚ίh—χ7j₯|Ψ«m=AΗQνO—K ϊšQθΏ‡όM€Ci—š|²\FΘ·0΄e†π229―uψœμk ‚Δ…{0=†γώ&Ό Δ>+Χ|Gwouj·w·ΓΙ+σ9ω}9€ΏρNΉ―Γ^j—sjπ”hξ™ώt+χp{b›M…Ο₯Ό!ymiϋ\ψ;‡D’ζΜΓγl°=φ«U}7Ε>7Σ!ψOρJΦΚ.₯vΛmε‰V8UλΨ€*ΔΊ§ ώΙz¬Ν”φWj):Γ:p†X€%O#αήρ>΅α]A―|=¨ΟarΛ±š"0Λθΐδυ{^ρχŠ΅ϋ+›=c]Ύ»΄Ήq$°Θ#0Ζ>QΐΖŽ)ς»Šη«|7Χ΅ˆ~iz?ˆ~\x«Β’M$ΆSΫΔ]γ;ά60!·σςžO8kφ‹πfΰiΓ@Š[K}BΠ\΅”­Ή­Ϋ$c©88ι“Θ<Χ+α―‰/πΜΆ½ukd™ΩΪθΉ$œ$ž=k9|K{sβ»m{\fΦ.b&‘nά‘(RRGAΗAEξ=ΖGώ§ΐ/Γ)ϋ½{Δ§ν—ήHx;ώ:ΏƒΧ)ϋ5_ZX|`ўωΥU–ΩΊ _ΜρψΧ+ρΖWώ;ρLϊή¦‘Ε#’Η1’V$QŒϋδύIeIVIrνM-ϊž©γ―†ή6Ίψ­G¨\<χ²άGx±·”ΘΞY[Μϋ£ŒwγΑSGmγ-y˜$Q_ΐξΗ E$ΦλόWρΣιgNojΤ¦Β7 ϋqŒoΖοΦΈŠ}D{―νCαmvOˆZž»•w&Œ-ΰ&ρ#-αBœ°ιΟ­eώΝ:°~'ψ{XUρAœΡy#χ2/ίΖ:ρΧ―Β\ψσΕWZ ΡnuνB],Ζ"6ο)*Pc λŽ&…ρ ΕΊ™£λχΦv1Rί Ή$œrIόiYΪΓΊΉΥkΊV‘αΛ­kΪeν–Ž|LfW2Dθ.wδ1?('ι^έρO]ρ•γ°tΟ†šwˆ"•b’ΧT[6™Ϋ :Ίƒ΄©r8Α―˜Υυgφ‘ϋG‰tΨtΝQlZ9mbmې δδδΰεUΏg†i>*|B.KΆΊ,OsηŠπ»_kΦΎ"}z Zρu—$΅ηšL‘ƒ’zŒq§₯3Fρ6΅’ί]^iZ₯έ₯Υ2O,r99=ςy£”.uί³Ό‰Ζo ΄ŒL².O©…ΐ™Ώό-―iώ9ρ.©{€_C¦M¨ΚΡέ΄-ε0f%pέ9ηM%Όρ͏Ѱttb¬¬At ΧE―xχΕ^ Σ³υ­vώφΘ°sd:λNΞχ‡3[ώΊ‚ΛΗ~»»`ΆΠjVΚΗ E•I?5΅ύ»ΰ/ϊu?όφŠΝΧυO έιΝ‹α›ν:σp+<Ί―Ϊΰ§”ΉΟ֘‘5x–ηφ’±Χmμ%њX.Vυy‰"H•YKt ŒwΟ½/ƒ.­νΏkGpκ’\[° Ώtςs°ΎΐWβΟ]λώ7Ύρ4A¬nξ.~ΡŠBZ1· Η Ο―©W=ίφ|π―ˆ<-ρΕ:§‰,¬4Λ[9{‹„+§ΜVΚ“Γ +Œώ΅ΰ š;oh3ΜΑ"Šώv=)&΅΅ο‰~2Χτ¦Σu^\Ψ°β%T8h¨ΏΧT“κ+žλϋPψ[]“β§Ε₯]Ι£ x ΌHΛDΈP§,:sλ]=Ž‹iΰ†ΎΏπηΓϋjzΔ 5ΝΤπ}£ΘvUm˜νb@6œδΧ„άψσΕWZ ΡnuνB],Ζ"6ο)*Pc λŽ?‡~#x»ΓzYΣ΄]zςΦΘδˆT† ž»w·πΕ.WkΟnύ¦#–-OαŠ\[Γm:©Y €b8˜4Ud΅3βs±ύ¬<. μΐφψšπoΕ:ξΊlޱ«^^5"Ω¦”±‹§CΧ<}…ώ)Χ/υψuΛΝRξm^Σ?Ξ…~ξlP’>–πΤ΅·‹β–EŽK«&†{Ι²γί ΥGφyπO‰|1ͺψX\ZCφF·J0'“$ξSόCόϚΎy‡Δ77)Ms\žώφθΏ™$±]y3³Β²Ι΅Ά‘…μzb½#Aψη©ιΆΪ¨½TΥn­žΦήKέH2Ϋ{`ˆnlνη#§jN/ ΣGπίΒ―γoiήŽνlΪσΜΔνπ›#gϋΉΞάuοSόQπdžρtΪ·«|c‰$σ–?/;†qŒŸηX&­‘jj:EΤΆ—Πη˚#†\©S¨$~4ύ{ZΤΌA©I¨kW³^ήΈ ΜΩbΐzά“ήΎ&xwXρŸΒ/†³ŸR‚Θ[\El7—dk’`QΑ=Ώ­ϋWΫMeoΰ;[³›ˆ4ηŠSœε”F=ωζ~ρνη†tˆμτ‹­rΝΩΛ\mER)rx+ˆμl`g'8«~!·ξt‚šsiφΪm―Ω£ξ|φoV-΅yΐ»T$ξ;ž™πKΒϊύ‡ΓŸ‰φχΪ.₯o=ξ–Ϊ9mvςζ@GΜyQ^¬i:Ž‹wφ]bΒκΒδ¨qΜM=Ž>ΥΥ'ş"…_κxχŸύjζόEβ [Δ—βχ]Ώžώμ ˆK3d…>™'σͺIίPgΌώΤΦυΝwDΥtm*φNM%7\[DdUΓ3‘Σ‚ |ε]U‡Δ/Xi ₯Ωψ‡Q‹OXΜK˜νT#G ϊW+DSJΐŠ(ͺQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEΩ endstream endobj 106 0 obj 11407 endobj 102 0 obj << /Font << /Font2 12 0 R /Font5 28 0 R /Font3 13 0 R >> /Pattern << >> /XObject << /Image4 14 0 R /Image10 105 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 107 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 108 0 R /Resources 109 0 R /Annots 111 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 108 0 obj << /Filter /FlateDecode /Length 110 0 R >> stream xœ­‘ΝJA €w½™'i§™ŸΜdŽ zP„VA”ΆΘΆΊΥ³oα»yτμS˜l­]υ ˆfς3Ω|3I Φ ¨μŒ€$ϊz- A΄92aθ2Ύϋ’€j>RŠΨύήl‡”‚ |stŸΑ,Βh―ΉŸ]!L„ΰt%ή Γx̌>{XN„šΑdNEΪΙv€N€¬΅>ΩlΘFΰ”΅ZŒc"k ωM°ι­M‰?’½ύπ'ZαžΧ]ήX]‹ΧŽj—Ω„CηΡpŒ.¬η“£ΕˆLœtμ<ΉτϋEj”%ŒοHυc(“―σΝ²Θ™ ¬†WnΰΥeυVΗυI½]½n½TΟCy‹ΆpP?ΥΗrV†pεΚήΖ2„Μ?4BΉUΨ/ \Ώ ˆ endstream endobj 110 0 obj 313 endobj 111 0 obj [ ] endobj 109 0 obj << /Font << /Font2 12 0 R >> /Pattern << >> /XObject << >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 112 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 113 0 R /Resources 114 0 R /Annots 116 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 113 0 obj << /Filter /FlateDecode /Length 115 0 R >> stream xœ΅VKnAžE€τ@YΕΨΘ4ύHlˆDŠ„4 (%r+8°α ˆ X‚mΔ²ΜŠE.―f<žρGγφxΊΛ]U]οUwυ+!9΅UΗJ‡χ“c>δRH©’NΪrΖμ“θu̍wΑΛR}Π ΄tΑRgΐgτ{Δοσηp2δ7o^νK~ψ4=!Z£ΰC™’4ΙπW‡KΉ:βΧω=΄aΛ“*=• fU@<Βi¬3€ΐΒ‰ŠΙ[=%΄„ΦW kν–lβ”άšXγΫτJpλ½­Ρ©ΰ& e’FπcRΠΞ&t<—!b!jγt²΄ό­6ŠWόζΟίhŽΕxϊD^L3›π8-ΌεEE[ρ”?ΰέμQvΞφφΨ.[ΟΞςΣμs+EΰuΩ{ΆƒŠΘ‹»|»ψχΥh24»cp2ΖΉΥt{ΌxF~ώ‚έίΨ€©+2’LγCJ-Ρ Ό*E΅^#Y’E#Λ€J»”š9υ3‹‘αΪWŒω9 TΚ{m Ύ Tώ!Rƒ΅¬uJ.¦ S>\νq“JώϋlŸuH‚έ& –ŽΖ' ˆŸ‹ζ²‘(%‚s8 6%7Φǁ΅Θ:!v«F,;bYvžŸζίΠί`λcK‘ίΙO ΔρΌsΆ35*π˜ΌΝ:Ω―^΅sΊ₯ϊμŽΜΏ_ž ηνe³±βm΄;AZAζΣ!ŸVDΘ"λDΘ[τ8Τϊ,kα|Β6Kf² ΘδXV UGXΚ~βύ=(―³·@~LΡ*@·8:LRΞ.†ε²ΠJκž‚έΈrΓΑ‰ΩΚqψvρEώ¨]«1eοzάΦ™½‰Lo£½Ϋ'Λ.H;ΪρήΪΉe­$VέΆπ€Z\rJ­…QΫθ%4λΨ’ jž48­ +υfΗ- Τ—¬RΑ;ͺΊ’ξ½XΥ_χοΑ‘6E)Q₯¦Θdk”ςψξ”tŽςQϋˆΡ›Υ5a /bό ΆG?e?Y?;Γx„_dΞ::Ϋ0’Z§ΊZό ξψJ‘š$˜7L ΡωTΓ;ηΕ!ώ£μΏB=ρ²ξI>]ΐaEYΞΰŽ|"kE„]— ›$ΣάΈΡ‘ˆWžZt5ΒΗ,u§£φΏάtl endstream endobj 115 0 obj 862 endobj 116 0 obj [ << /Type /Annot /Subtype /Link /Rect [ 41.889763 107.0055 583.63574 131.0055 ] /Border [ 0 0 0 ] /A << /Type /Action /S /URI /URI (https://prometheus.io/docs/concepts/metric_types/) >> >> ] endobj 114 0 obj << /Font << /Font2 12 0 R /Font3 13 0 R >> /Pattern << >> /XObject << >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 117 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 118 0 R /Resources 119 0 R /Annots 121 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 118 0 obj << /Filter /FlateDecode /Length 120 0 R >> stream xœ΅T½nAΎ»‰y” δ‹Βzgwφ―Δ$(NJA(, ΆΠ9Α‚ŠŠWΰ5x‰Tπ)©Rδ)˜ΉΛωΞ?"J<:ομη™ωfΏίPi{ά:€―ο°­΄Ζδ£ΣΤDlξ9H–Xο‚ΧMzέoŒvΔ©ac#ίs8„&YΒψIύi>Υ0ϋΜ FžΙ"s(«SΤ6Y8›ύΥŽχα5Ϋrΐ„ Sc\Ct¨ˆ 9+0 ₯€°z€YΧb}n­(…ΤΖNέήk€ν6²’WΡ&ΗA mB:ύS0Ž;žuΧ!Ήƒh¬3‰€ωIΕ5ͺ3??=ωbΐq |"TΗλχšψqFy‚ͺ½΄κ=ΌQφ „FͺQ~OσGωΡQv•Ώ*α-T/αYu›-γ•F4n«‘Q ΥGa“°ξΩ,mσ›~ηιΈ²ςλ§+~e“ό ۞πkq‘?ΜΞω”ίŠ‹l’ύ`ϋΞήΖφΨ*ώύ>+ΐΛ= Λ.σ½ŒeW%`λ]?‹ίw’E£"³u–•@7ΜΥΏζ\Ζ׊Vθ(*νeΜ9™ϋοΑz’ 8Ε9†»τ5pπχΊ›ς‡ϋΝ;ΒΔH&JR£•e‘I₯δw₯± γ‹ιμ"<=])v“,hΡjv 7Ž= Αz5ŽΆ=ΐvˆr›Ε―%I1ΙΝγυτX~mΘm₯τr˜^±ΏdΉ)ρ endstream endobj 120 0 obj 531 endobj 121 0 obj [ ] endobj 122 0 obj << /Subtype /Image /Interpolate true /Width 1020 /Height 128 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 124 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐ€ό"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊŠ(ͺQEQE=οό}?αόͺ žχώ>ŸπώUQEQEQESζŠH$)4oŽͺκAό2€ (’€ (’€ *o²άn|‰wJ2ƒaˏQλK=ΥΊΈΆš%'Ίτζ€ ’Š(’Šx†S ˜Fζ v—ΪvƒιŸZeQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@¨Œμ³€ “Nς€ΨΝεΎΥ8cƒ€}θ”Sž7Œ"2’27 dzΤχ}έ΅¬3ΫMΌκ€d!_θhΈ¨’Š(§4n¨ΘΑξ±₯6€ +SΓΪ₯βί²ι­< eŽ@T¬O©_[=•υΕ¬₯H$h˜‘Κ’§ӊ‚Š( Š( Š+oΔ^Υ|>°Ι¨Ϋbήp SΖΑ£|ŒπGc@”QES)Y’7e^X>΄‚71—ΫΑlqŸ­6Š( Š( Š–[iαEya•Ύλ2’ Š( Š( Š( Š( Š( ŠΤπφ©x†χμΊE«O(c«ΐͺWΦΟe}qk)F’ &(r€©ΑΑτβ€ ’Š(’Š(’Š(’Š(’Š(’œΡH±€ŒŒσ΅ˆΰγΠΣh’Š(’Š(’Š(’Š•-§xZd‚V‰zΈBT~4Q@Q@Q@Q@Q@T[ΝpΕmα’RHE-Κ€#’†X†Α΅QEQEQVtΛ ­Rώ +Zk©›lh;ŸΖ΄|Qα»ο έΕm©<ι~">ήqƒθhŠ( Š( ­ιv-¨έ}ž9cŽB€ sηϋ£άΥJ• © ŽA¨σE$ΌS#$ˆpΚΓΉy¦MgaΕΛ"4Ηδ„ύύΏή#°­Xu»)βKNΧΟΤ­Ζ#oα—Σ°―ζΎΊ{‹—/+žIνμ=©€^ΗΣώΚ ©ογιεPR’Š(’Š(©m?γξχΧωΤU-§ό}Γώϊ:φΏxg@Φ~ I₯Ikͺ^¬kopUωBΝΣ$ƒΗ½kΛ#πδƒΕΟ έέΫΪΊNΠ½ΔΜ5 œΆO°ΰ{Šνόw%ΗώΎμΏφJ–ΚΣLΎψεͺC¬$2DdΕίqεΐΪ―~=©–ώ Π5=I|3―Λ{¨ιρ4E$;RU^»υη·k3Α²ρ¬jϊ‹XE§ωlΟεοNwu'€:šυ/Gβ8›Y!Σ΄:°Μ"ŽΩ#YρΘΪIΨ―¨―<πgό“ύ-Ώτ3@όQα-6ΧΓ0kώΤδΏΣΪo³Κ%cΖψώ_β:ΤΊGƒτˆό)k­ψŸX—OKΧd΅Ž(L„ΰY€νΗ·ny©tω":Ÿύ…Χ@J֟A»ρŸΓ a¦ΈΣ °άBdU)Ή‡''ΡAϊβ„ΧΈπsιΧ@Οg¦’ΕpŠ0ΨάυΟλϊηΑν>σUΈ7'V)Ό¨ί€Cρ’ΨYCαKQ"Κ Σ/1NCmΐΘφβ§Πt›|(M+F1K¨Ϊjfw€Ε ‘ŸχΏC@/…΄IόE―Ziv¬©$μrμ2@$“ψ]uΗ‚t;λMM<3Λ{©i±΄³A,ŠΏx‘υώΉ£ΐKΰί‰Άvή T΄£FΔΘ₯Wz€qΙΐόkΌ„ΏKΆΥnu ιš|1:­Π·LΞEP§9>ύθΞΌ α[}v JUΎ6:Vœη•Sss€αοΫΦΊ­bΓO°ψ9yύ¨ϋ΅5•$hΜlΏ*©VΈ+ϊŠ£πήΫϋsΑΎ)πυ΄¨ΊΘ†hΨ3cdωψΥν[AΊπχΑ««MCbέΎ¦²ΙΈo+* ) ‘œςš(’>›’hΧ> ΎΤξuΈΰΥar"²8ˎ;u9Ιδp1Y˜5mE-ϊΚΔ2–σ―%ςγ υ­m7ΑΧ—ώ½ρW6«mjεZ&sΌγνΤ`Ώ–rΌ?q¦ΫjI&΅e%ν˜Rε1’qΑΘ Žo€PΌŸπ–xYφ©m«’qΨqΦΈΊνηΦ| ΠΘ±xZρ$*B±ΎcƒŽZβ(ξΛΒ4~΅ΝkY– ΒκcH7±`ΔΈν€I'ΫΦΈJυKήψ‹αŸ…"Δr]Dgo%€T,¦B ‘ӏα­.[km@γΌoα±αΛϋe·Ίv7p‹‹yφνά§Τzu7žπφ«[iΪ—ˆfŠκνΐ‹oœΰ=NF?ΥŠΒ;OψGτ9%ΉΣ¬)φ…~8ύ?QIρ™Π²”2γεvμ»Ξ? ΫΈπVyk©/‡5Χ½Τ4ψΪYa’Υ~φΣλύsTώλBˆ6wΊΕΫ±˜4oq<…ŽJ»˜ώΊo x^οΑ2뚹$Y-œ°@ώb“;66ΰžqΣή•IΚ.Νλeσ`rώπΎ™©hͺκڌφ‘-κΪmŽ ωά §'ςgĞ ²Σ4}Z{=NK›Ν*dŽκ6‹jνs…ΑΟ^F›ΓίςLd°δ?ϊ Φη‰γΗβoύ|Yθb“œΉχλϊ―σŽΠt τhυk’ΤLε#ΆΆ_6QŒΜ*8τώu_Εή­i 7bξΚς4žήpΈάŒ{Zξτ› ΄πf‰?ƒt­.φiUΎί5ΒFς#δpw‘ΧςŽWΖxξ<2σU±Rζ ɝΈώτ§Τ΅ϋΟλΎ‹Lρμ^K™$‰ζ‚/8¨ ›rqνΊ™6‰€iώ.Τt½cRžήΞΨ²€ιφf`=‰ό«Πυ έkŸtιςΑ&†νΣάωͺΒδœηεό;τ―/ρ­μ:‹uk»V·Q‡Fΐ?:ss²ΏM}@τ?‰:w†RΆkύ^βΦδXΗεΗ±`λΞΦ$t&Έψf-r=BσP½:]‚žm…Ο9ΐπ?§­uή?πΦ₯βCa­h±Εu§ydJ‚H ‘λY!]gž%πό3G‘v!–έ‚ω›$Θ~u0—--oή%𡍁ΉαύI΅ 5₯ς$σ#ΨρΎ3Θ=G­rιή›/…~Ι₯jΟzυπmΥΓ2 P2p}ΏQ\η€ό'7‹υ9μໆΤΕ ”΄ƒ9δ ψυν[Q“’zά ^ Ÿμή+dνφ˜Τύ wχΦb xΙ—ηΉ»ΉΉύΨή"?τ*σ%έ§κƒ,¬ΦΣuCJ·cψW³λIρΞ™¦δl»΄Ή-m9Ω*+i$­ !±ΒψνlδρYκoioPΌˆ›Κβ<Œό‘Lρ•ͺΓα[M^ζNv‘`IcΨoΎ£š«βK;ΏxTΆΣ£\4ξ‘wΘAƒΙ8ν]>―ΰύnγΑZŸ˜k»W™₯O5ΠΞHη8£όG\Υ­ΒBxRΫ[ρ6±-„W²4v©BpH,ΨνΑkcΗ²ψŽΧΑλˆ›J±73‚Άρ(•Ά*H­L†ΫOρwΓΝΝu?OΤ4—•eKΙ|°Q›;‡―Q@ηΔ ΑαitΔ·½7‚ξΨNdΫ…€ϋVίΓ[†Φ<;β_ή±–Ωl^ςέ_Ÿ*DΗ+ιΙ_σš_Œ‘A^Š_:Ϊ=-)?Ύ£€ίˆζ‡²hήρ7ˆοPΓnΦ/glΞ1ζ»γ§¨Θ^~Ύ†€<ފ+©ρWƒgπφ‡€jRήΫΚ‚ TΚ†λάs֐Βy`‹EΧΰήY Ατ”Ω«>ςΖM3αώ³e7ίƒW“λ…?ˆζͺxp•ψ}β’€‚Τ‚;~ςΊoάΕ¨ό5MNƒ5‘α„±ρ&›`χžmŽ‘ε΄7HΈΚ9ΐ8=λ­ΡηΤuι αΨ,ξ­ ‘\A:#2ε²€nθ1ώxoΖχz…Ύ±§¦‘sg-՚+yv©΅a9ΞΓΫRŠ~œΞ‘NROΠn)4S<»ΊώΣ·ΧνΆ7Q²€ *ωMό$v¬― x~=a/n―nޝd¦›fγΞpό+eό.žš•ήΏ:ΫXΐŒ`‘$Rfα{ώtΟΔ5_ ψƒD†XϊδE$ μ™±²@ό‡ηWx¨·!Y·ο5Z[h±k& otφ—Ι}ρμxίδžΥOVΡRΗΓΊ6€³3½›ΉΐMŒΊ-^ΒO|=}7ShΣP»Ό, አP2qτύjE!πτzφ£¨ΫK;Β-m%Ή ͺβ„ ~΄ψnwϋFζώπΩιΪ|>tς*ons€ΰ*ν΄ ]ψ1όGͺλo VfΞk{vσ™ΩΘ+€{t>΅Ν|1‡Z{«ω|9mμq‚m&ΗϊRσγΓ―Z·Q΅'¦€Pρ Α₯%ώ­ύ―χž[ΪΞ\£ύ ;ΒΉŠυ_ΨΕ—Ύ"τύ3Δδ$Kk΄cΗ%€'ίΏaΣ5ΗψΒsxΏSžΞ ΈmLP™KH3ž@ΐ^Υ₯sDvM€ΜζkΣ|WβΫίx½4λ©€Ω,hmU₯A#8Θ88―6t6wμŒUΜ2ΰ•9iμ τΟxNγΔή)M^Ξh›E»XήK‘"-B€άψγ]0½΄0«ΛΜΉφΤβmlWΔώ-6ϊTBΦ+ΉYΥ[‘ΰ±ιιΟ΅?„t›»}Ateο¬Q€–„¨u^»O™ΰˍ;GψŠ‚+­ΪzΌ₯Δ„r€OLόλkΓώΊπŒšΞ₯¬<1Z I!…ΌΐLΕ±Œ{βœUɜΪz>Φσ8έ+DŽχΓZΞ¦Σ2=‹jΓοlrh‡DŽO\kFfEv-ΔXΰ‚ η?mψ !©ψΔZ,RF—·iΐΨσ 1$Σσ©΅«<9πμiš“"j7w’qpΕ(8ϊ~΄”tΉNo›–ύ­§…τ˜ό;¦jϊΎ­-¬7eΤƐοmΑˆΗlI5ŸβOA‘λVPΙxeΣn•&K•N|Ά<œzΟεZ'’}α/ϋxΠι> Θ3Ÿφ ω Vϋ…+­wΉΠ^iώ>°I5[…±lRΰ[μΨ9R=:Χc’Η«x4½ΰΛ ―ˆη‘ ό d’?]6›₯άψ‹αΕ₯–’#šςΪυžHŒX)“ξ+;ΐ­ ‡U+!x$,ΐ„b€ ‘Η\~tή­h(·+=u%›ΒšMέ΅ϊθ:ΓέίXΖɐ”*ύβ§ΧYώπμνΆ©5Υ鳎Κ5”ΎΝΓo9$uΰ‚»K₯ρ6m¨Οz4}>Ξ8™Eΐ…30=vσ“ο\Ο‚?δWρύz'σjWZœΉ^½ˆuŸ ιλαΦΦ4Iο-‘E:ΛΖBq‚=ΉkM«]ψgΐZќ[Ο|ςΛ<‘³mlΘ>£ς .#Ά’Ϊ9ε[yH/Ή δt$t5ލ"γΕ^Π£ΡΌΉ΄χ–9α2*²=°ηνI;ί”©«[έ_τ(όH w6…¨”TΈΏ±ŽIŠŒo_Χτ«χ~ΠμυΕn΅ΩRς}’gτάzrsΗΣΦ¨|Dh ΊΠτΔ™%›O³ŽŠ€ύΗιϊΧWβ? _j?‘Τ­ŒMeΌξdΕ°) ŒηZ«]½ ωΉb•νΏόΞΰl¬υϋΝ?Δ’ZGnY<Ψ£/ΉγЌšν<aαΧΏ―uIνœ~\inX0ηi'Άk‰ρ₯ά7Ύ+Υ.-œŸπώUO{Oψ*‚€ (’€ (’€ (§Ό{bσωγΣΚ(’€ξς6ι™ΊeŽi΄Q@*»(`¬@aƒƒΤRQ@Q@9€vUVv*ΏtΐϊSh V*Α”ΓAδRI$’IκMPEP†`₯A;O$gƒIEQEVφ§β&½πΦ‹€­Ήˆι¦R&dΎφΟLq©¬)8§k€uλES₯,H’@θ ιIEQE(fPΑX€έ@=i(’€;*ν<‘ž %PEP³$±$ž€Π¬TεI¦A€’€ (’€ (’€ (’€ (’€5<=―κ^½ϋV‘tφς‘†=<₯u%νυΕάΑD³ΘΎΡ–98œΤP@ΰδQE:Gi΄ŒΜΗ©c“]†uMΆ•5¦­+>δ‘š-ƒwϊΧ;Et4ρ4Ύ'Τ ˜ΫGimm ΑooȍlχυT^#ρN­β…5;’Π@ŠQ8Ηu>η&±( ”± I€ ιIEQE*³)Κ’¨4”Q@Q@ Yˆ’@θ ιIEX’I$χ4ͺΜ§*H> Q@Q@Q@+1f%‰$χ&’Š(’ŠΤπφΏ©xzχνZEΣΫΚF Έτ πjο‡jη¨₯$€¬ΐ’iZWbI X°\π3QΡE0 Ub§*H> Q@Q@)ve X•^€ž””PEPEP‡`₯C§¨ƒIE¬μΑC1!xž”€AwQ@ ξΞŝ‹1ξNM ΕNTzdJ(₯ ΑJ†;OQž %R–$I tφ€’€ΑΘλJΜY‰bI=I€’€ (’€ (’€³± tτ€’Š)U™UŠŸPqIE*­θsZώ+Χ_Φξ5 Άσ•TΖw@\ ττ¬z)ί ¬―p’Š)  δJμΞΩv,}IΝ%gLΏΊοα½°™ Ί…·$‹ΤΠρG‰5]CqͺLΡ¦ΐΡΖ#9ΙΗSXΤPEPEPEPEPχΏρτ‡ς¨*{ίψϊΓωTQEQETσΗ­Ώό ωΤ<ίρλoώtQ@Q@Q@œMK-΄ρJ±K ©+cΘA9ιN°λϊθΏΞ½λβMœwώ&Π΅uύφ›ͺΫΩ\γϋc‘ΣζΗΤΣΐ$β‘’Tduΰ« ψSk·ρ~œ5oŠΪ•‹]Ah³]0iη`¨€ ’Iϊ~&―?‚t FΟR_ λςήκ:|M4‘IΤ•WΓύyνλš@yΥΫψ?Βz^«αΧΥ΅}Fβ5Ύ[=±Fvε\}9oΘU―ψΓJΡu‰μ΅In―t™γŽκ6‹jναp}yόhΟ¨ίEπž”žΆΦόS«Kamy#Gm™φœ>ƒ#―ΝdψΫΓGΓZŒΗr·–WP­Ε΅Βέθ}Gcώ"€9κ+§ΣtMηΑ·ΪΞ·¬.DVGqΗn§9<Ž+˜ œˆς"³3€3M“ΐwφϊv§y%Τ«=œ±©nμqϊR“²Ή2vW9ΦGUVe`­Π‘ΑϊSk€ρό^πεΌ2«Mn“ PuL°ΖWτοΕ{«Z[ ΗX.4τ½!vώf§%v.t•ΩΖRΊ4lUΥ•‡b0k^λIz6}$η]M"yDp ΟΦ»θšV£γbΌΥZήϊθ †$„°S΄Έϊ’:’LN’Lςϊ+M4w m*ββ wIZ'šFΪ‹Œδδύ+uΌ3€ή[_ W{«Λ8ΪWαΪ²*υ*ύtάšGEuν΄Ιu‹I.δKεŸ@"ά1έ»wόͺΏ‹-4H/€²Τf–χν ˜ͺ>c‘»Ϊ—?½Κώχ)ΜQ]>— iΨ1jΊέόΆΠO!І-ε±ΤŸN‡ς¬έsN³²Ύ…4ύB;λi”2ΊŒ2η³ƚ’nΓRMΨΚ’Ί _@ŽΗΖ ’¬μρ΄±Gζ•ΑωφσlΤΆ^ŽηΖ―‘‡XΥέ<Π£?*“Σπ£ZβηVΉΝQ]ˆπ›sk™«›JΙI"0•F Τ)=yγ5ΗSŒ”Άd₯°QEuw‡tρ Cͺkz“Ω₯Λ²@‘Δ\œ}Έ?δΠδ£ΈJJ;œ½Πx§Γρθ—|q]}‘n‘Yw…ΐδφφ£WΠ#±ρ‚h«;¦°,τ+‹ŠΜ±άyΖ&n c9#Χ€O½ i‰M3&Šλ/t-Rς+Mq…ν°o–β-‰!^ͺ­rtΤ“Ψq’–ΑJQ‚+`­Π‘Α€―AšΟNΉπ7†δΥ―šΜΐlŒ»9/ΫΠ iJ\Ά K–ΗŸQ[^*Ρ‰} Ep.mn"Yα” nSκ+bΧΓ:#Moc>Ό§Rœ ’όΘ•E,'ς£ZβηVΉΖΡ[ϊ7‡ZσΕΏΨ—r˜™^DgAžTΗΧ£Ά›si~šf¬nuΪIb0•F Χiύ3Cš@ζ‘ΗΣΆ>Νϋ[fq»f·|/‘CͺΗ{wwφM>ΝCK ]ΜIΞ…nκV––Ώ'ώΞΌ7vj κμ…~@ ‘λΕ'4Ν'cˆ6Σ…άa”(ΞÌTUίx[\Τ΅-ΔΧΧM4ι’R mΐΗaι\œM8ΆΫL#&ΫL(Χώ2ήξ 2Xh΅‰‚β5€΄hΝΡIυ5‡§x~ζοΔΓE,±Ξ%hέϊ… œŸ~)Ε‚œYˆξHEf dΰg›^•α­3I΄ΉΦ[IΥν’°š)Qβ*{|Κ{ŒŒWšΡσ6Ÿ3aEθ~ ³Ρ‡«7Ϋεg{!φ`SΗ%}phœΉUΒrεW<ςŠΣΦ­΄Θe…t{Ωoή^"„ΐzΧK~™άeώ΄bΦ&Qˆ–Θ¬z)49₯Έ9₯ΉΓΡZφϊm₯Ά΅ucέ=’ΑΉ Ε™– cЌœΧaγ›―`k­JkyŚl-Λΰ“Ϋ4œišM#Ξ(­i–šƒάI¨jXΪΐ»˜·.ώΚ½Οw\Π,ΰΡ£Υ΄kζ»²2ω.$c£c?ηπ§Μ“°ω’v0 ΄αwe s°γwήΧ5-KGρ΅υΣM:d…¨p1ΨzWD[m¦(ΙΆΣ$ΚJ’Γ+…<j޽#IΧ¬!Υ<1$—Q*[iν€ŸΈΫxςζζˆΙ½ΠFMξ‚Š(ͺ,(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Šžχώ>ŸπώUO{Oψ*‚€ (’€ (’€ žoψυ·:‚§›ώ=mΰ_Ξ€ ’Š(’Š(’Š({ψώ·‹όλή!ΎˆόeΧ΄[²<‹δ·–0{MhκCω π (Φl­4ΛοŽZ€:ΒC$FI QΝχ\  ϊχγΪΊΏGβ8›Y!Σ΄:°Μ"ŽΩ#YρΘΪIΨ―¨―žιΞο#n‘™›¦Xζ˜αω%²Ψzύ+wΕςψ£__ϊ―’Ω έκڟý |)o§_^Y!ΊΆΉDfL·ΚΓqηρφ/β¬ϊ‰Τ¬,υ{» ξ­ ΓEeΥƒ<μ=‰γ΅q1»ΖΫ£fVυSƒM ›Mπuεƒο|EΝͺΫZΉV‰œο8Ζ{`u―εžf”3* Ϊy#<J(’Š+ν/–ΧΐΊ^¦[#ΗhO²OΏω-y₯35ˆœ9¬vΡ-5]?Oˆƒ(ςŒv2JΝό±Rψ«ώJ½Ώύ|Ϋμ•ΑΡR‘k S²άο­mμnΎ)_E©,o–B‰/έwμ ohρλ1j bΛN²μrˆEv86’vjς:VbΗ,I>τ;υ%ΏScΑ“Εmβ2YέR%˜e˜ΰ ρΝ^ρ†υ; «έBβRά1IVE;·GΟι\Εn.χFŽ/šθο|'ˆ@GΡZΛQ΅y’Ζm§Κ9κCΧ―½PψƒmieͺX˜ ‚ήν‘W»‚”I3Πzϊ«’Ve9RAυ’’‡½rT-+ž₯©hW·Œμυϋ9!}%š+†ŸΜP g9ωk+Γ7Q^όWk‹vέ “NQ½FΖΑq FNQZ~ΥΏ°υ¨5'Οςƒ/vάεHλƒλSμΪMyXŸfΤZς±ΩxDΈΠ%Υυ[χ…l>Λ*C(8Ά6ΰίη4ι»1η“ŒτΝjθή"Τ4{w†ΕβXέ·ρ+œγHφͺQk]ΩJ-]ξ̊οJΈρ'‚4EΌΉg±icž2αJξl‚r}όλRρV©©YIiu$&1Έ,§‚δ υ„ Α#<oΘm9y§Δ8…‘πτAΦA „kΉO ŽγΪ·΅- γVρžΏg$/€³EpΣωŠ Œη?-pzξ±ύ«™‘ε}ŠΩm³Ώvόwθ1τ¬­Δ)8=EJƒ²!AΩΆ‹«Ϊ/ΔιošU[I§•VRp0Aύ ΗηZΧ+β=>ΫPžμi66‰(œB€ΜE]ΌδϋΧ™R–$I t”έ;±ΊwgYΰωόU^ΙόΝrιs:[Ιn“J°HAxЬGLކ’’­FΝ²ΤlΫ;Ο†ήΤΧ[Σuv·ΩψωΎbτ(ΛΣ9λνXφ…©hwIs¨Ϋγ’RSχŠΫ°s؜V<―šχ‹ζ½Ο_Υ?Άoυt½Ρ#εΣ& "έΙdΗ€3ΈŸ›#ΐΒχ7ώ4/₯Wo9+x>XΛ„{cρ|1€NQIJ4ωI>SΥε³ΏΉ²ΤΏα2Σττ·Š1ί&Υ‘œtΑœύτ―(₯,ΔX:zVΆβ-CG·xl^%ΫyΉΞ1ԏjq‹ŽΓŒ\V†Euž"‘Βίφρ‘Υ KΕZ¦₯e%₯Ԑ˜dΖΰ°"ž#3ΤV;7fΗfμΩΩxΈDΡxIn¬&Β!—Œώ•Φ=¦‘kβUΣtύ& IK‘’ΛΖ~brXœψ}kΘiK$ΰtΥK§ukž‡£ΙaŸώ»M 5eό?Ά³`ωšΧE?f?g‘Ωx.νOkϊ<‚φq£0φΆHόκΦ£₯\h ζ·ΌΨ. ρ«Ω”GΐΟγ\$AΑO48;ήΰΰο{oΓΝ“K¬Xωˆ“ήXI ;Ξ1νYZΆƒ©ψ~Kiu;a»ό˜‘[v0OBkŠW{•ήη―κŸΫ7ϊΊ^θ‘ιrι“‘nδŽ2cΐάOΝ‘ŠεͺΛckky­ΖWɊΰ;λϊ~:^$ΛπώeΥ#΄†θ^b·Uή7γ?ΣζκJTGqE'Nξχ%ΣΌ―s­ψy²iu‹1{Λ !‡yΐf=«\πφ§‘¬M©ΫˆVRB"ΆqΧ‘>΅•EW+Nες΄ξQO…•&δA"+ΘN7 τͺ(θό]α7πΝ–“%ΝβIs}œmΥ1 §<ςHό s5·γ\x£\“QΉaΚ,iœˆΤƒρΙόk€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€'½§ό?•ASήΗΣώΚ  Š( Š( žςnŠ4Ζ6gŸ\Σ(Q’οΕWGβkΆ†ηPŠ'΄•Ά¬πH7zdtιY:.™>±ͺ[ιφf?΄NJ§˜ΫA8'ό(•wY―΄[η³Υ-€ΆΉQ’άz‚8#άU*(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Šžχώ>ŸπώUO{Oψ*‚€ (’€ (’€ (’€='I΄ΊΥΎ Kc€E%εάz―™,Ξ‰³‚3ΦΌφςΦζΒινο!–ήζ27G"•e=y₯z™ww₯ό–λJžk+‡ΥvΛ4LQέvt 9ΖqΣΠםάά\ί]4ΧSMss!žF.μz “Ι @Φη:Β+ JρΌέCM½6^s}ζŒ@'ΏUό«ΞkΡυλgπχΒ=;MΌSώ₯|o -χ–0ΈΙΊ'υηQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE=οό}?αόͺ žχώ>ŸπώUQEQE‚₯PCβλ$‚5)£ϋ4'rCa7Lΰwζ²τMNγFΥ-υ -‚ζY ΰΞ?₯E]Φukνjύο5K™.nX`»φ€φJŠ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(Ω endstream endobj 123 0 obj << /Subtype /Image /Interpolate true /Width 340 /Height 46 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 125 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐ.T"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊŠ(ͺTχΏρτ‡ς¨*{ίψϊΓωPQEQEQEO7όzΫΐΏASΝΆπ/ηPPEPEPEψSΜ™8άΐgλ@ ’ΊxR]ΔWš}ˆΉΌ‚Ωšo(ρΉAη΅ΛΠEXžΖξή–βΦx’ΊοP~„Τq[Ν*;Εމ€ΜͺH階ŠšκΦβΡΒ]A,,F@‘ ’=y’ήζεdk{y₯XΖ\Ζ…‚|t hΏVπΝ€Λα§ΎΏš;MNΡ.§GΈΓΈg΅?Š|-£XψNί\Π΅[‹θe»ϋ/οaςπv±'ž„~tΔΡEO=ΥΌi%Ε΄ΡFu †ϊΦ€ ’€‚ n%X­βyenˆŠXŸΐWDžΐΧzδKΝ½π΄6μ˜Ϊ§'<ƒΝs4QEWwoαO£Ο©»uφXRVϋ)αŽ01Τυ2β7ΣE`Οqv6ΒΤ;qΝLf₯°άZ+ΡR΅ΌΙ•α‘bc€εHR~΄ΘΡ€p‘«;ž¨Ι5BEI<ΫΎΙβxŸΧR§υ—ΐ‡^ΏΉ›R˜Α€iρ}’ςAΧhΞ{œΘΠ-Elx¦MΤ5%}N}Œqˆ’2ϋ™πOΞΗΤηί₯u7:Vβ― ^κΊŸφv«¦ {Λ@ε£–ΙlΏκHθTγ Ο―\γΎκ3iρυ¦Ρq€ΖΜ νbXΑ㠜ώVΓǚ.ŽΧΏΨ~KawΓ#΅γ3ή„ƒ…ψτoEρφg…υΝμΎoφŸ—ϋο3o—°ηξγœύEuϊΎ«uβo„_k../¬΅! s•Š•ύ―ΠT·ϊν„ΎψQt ~Λ-ωšyζTRX« ½ω-qvώ#ς|uαο²ηΟ»_hσ>ξFέΈgk_Fρ­”~ƒEρ‡«£™-XΞb(IΞ#$ώPΖK¦Ύ‡Β—n‹Ο¦$¬Š0ΆηU―Ώδˆiφoύυ‘γΏΒW.œζΕ,ώΙ“΅$ά­ΟP00=Ή©ό5γ };ΓςθšΞ­§4ίhDiŒMγ0ό“@ό±·Ώρυ‚]"ΙAζΓ ²©Ζ~‡πϋfήκΫ[·ρ'‹tJΖξ VΚΈ0Ιό%NήίΟΌΎE¦ψΆ kΓϊjiΡÍΆ¦f•~ξ8<‚~•³}γ][_Ύα{{-Jω Kq$Ζ`™κQHΐ'ΫsαΥΫθžρfΉb j0ω0Ε)PLa›Œύsψ Ή©λ—ΊΑ‹›MΔ·1κk—h@Nδg…ržρ`πκίΪήX&‘¦_ K‹v}™ΖpAηΤΥέ{ΖΦ—ήιΊiφbq4en χ²2I=σ@MΣxΔΠx_TžξηL‹PYa1v©$‚AτΑβΉΫ©DΧ2Κ±¬jξX"τ\œΰ{ @uΪGό’ύ{ώΎαώkQ|)‘ζΓύΩ?τ[UΈρ$ΤnbΤ 7MόFήξ!ΧiθΓάdώf΄‚²ΪΔΘε«Π~>%-γGŸΜΟLεqŸΓurώ+±μ5@š’u #$Œ›Y2OΘΓΤcΠuͺσVΡ<-αKέ#ΓΧM¨κš’»ΌΩ΅#Lr‹λԏΔσΠUˆσΚ(’Q@Q@O{Oψ*‚§½§ό?•AEPEPEPσΗ­Ώό ωΤQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Ω endstream endobj 124 0 obj 13275 endobj 125 0 obj 2517 endobj 119 0 obj << /Font << /Font2 12 0 R /Font3 13 0 R >> /Pattern << >> /XObject << /Image11 122 0 R /Image12 123 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 126 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 127 0 R /Resources 128 0 R /Annots 130 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 127 0 obj << /Filter /FlateDecode /Length 129 0 R >> stream xœ½•½n1ΗΧ[ 1ο€R „l6¬ν’ˆ R$€•RpDh“p" ©x^ƒ—Έ Δ€€JqO@3φννζξψP”p֞νzfRλ;iKTjz›pQu‹‡e %αΚΖ`j]δŸσ― «ΞΩxUzTjnβΧCΓΈyψ”‚ΰlΕ:%zS₯œΏΕτκSƒ6NΓG„hœmew ΦO"ξ.ΪTΜenCΪ Υ²λ ·1F‰σi덄ϊpχ ΛJeηMΑε¨ικαEσ 5Ύ”ί> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐ„"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊŠ(ͺQEQETσΗ­Ώό ωΤ<ίρλoώtͺ₯˜*‚Iθ>X%‡tOznR3@ΡEQEQEQEQEQEQSGkq*Ž ]OB¨H4Ι‘–ΡΌdτά€f˜†QE†QEQER’4޳€ “RKm<*XdIΖYHμ+‘QE†QETΡΪάJγ‚WSΠͺ 6he„4OznR3NΜWDtQE!…·₯ψ_UΤ΄‹½V }Ίuͺ3Ός0U;FH_Sτ¬J(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(₯G ³1ΰ&<2ΐϋ'γ~»]H?­2Š( Š( Š( Š( Š( Š»’ι“λ₯ΎŸfcϋDδͺy΄‚qŸΒgJΎΡožΟTΆ’ΪεFJ?qκΰq@¨’Š(’Š(’Š(’Š(’Š(’Š(§EΚα"Fw=FI¦τλ@Q@Q@Q@S’7pΫ›hάΨΐυ4Ϊ(’€ (§IΔε$FFC mQ@,V·¦θ •ΧΥP‘Q²•b¬`pAκ((’Š(’Š(Fπf±«h³κΠG v>l„ί·¨QΤτr€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ žoψυ·:‚§›ώ=mΰ_Ξ€=α֌–ήjqjšaΊ6,Ρ~χ-jΔgsŒpΖΉο½τσΨ.£ΩjΩ,ΪΊ·•’ΉΞλΗεSxώ<ξRΈŒ·,RU‘NC1#Œητ¬“ζΓιΩωφάΡ«VΦ[―ι6˜ή _‡Ίό#^o™Ύ7Λ xσ{ρ;Ε7Ԛ…Ό^(iΌΤ\…ePΑ ηγ΅uVϊN±ͺό<ΠCŽIΜ›&π\γ©G^Πυ« Ϋhuh€k›– e3sŒ άΥβ9ω#dνeι²"/;Υ^οΧsiΌ σλιχ&m&ξ/<^ΐD{w‘ΧλX–z4z―‰Ζ—€Nd…δ*“ȸʁ’ΨCΒ½ΚKΚή\ΈΈ½‰ΌωΥώX%|mAνώ>ζΉ©πΧΔ­΅b°”/ ;(ʝ§>‡ΞœθΣRŠΆλεεύ~ ³jNϋ-<όΕ›ΒΊUέ΅ϊθZ»έ^ΨΖI•*υ*ύu[Γ~ΣοτVΤu+ι­£[΅΅ΔqξΞ@Ηκ!]eΘρ.Ÿo¨Οz4‹ 8γeΜΐτUΫΞO½sϊό“η°Δ_ϊ Σ•()λMΏ[‰T“Ž’κΏ­ˆυοΪiϊ^§5‘%ΕΦ›*%ΒφΧ8\^F-<1₯'‡tέ_VΥe΅†θΊ”H·±!ˆcΆ$šάρόyόAφΏϊͺσθWzηΓ Η§’ζ31ς™Β–Rη$gӏΜ¨Η™ςΖϊm―σ[ς«.UΝ+kΏΚη;β 2o λwmη›‘‹‹[€ cώy­SΌΥΎΪ\κ3™ηώΫΌ€8Ά:U_‰!-±4Ο5$Έ±²XζΪr½?OεV΄}:oό;];K1Ι}o~fxYΒ’₯ΘΟΧτ5 59†ΦΫΟB›N©.ϋœv‘d5J FΈ†Ωdlf`ͺƒ$“τ₯ό+£ήΪߍY{«Ϋ(ΪWβΪ²*υ*ύtίhqΩxΪ=;ΔpD²,e’)23‘•ι]–‰·Υ΅c¦ΨΕφ9Di"»:m$νώΤπΨu(ϋρκΧ]?Θ+Φiϋ―ώωž{αA[j“]^Hμ£Y μά6σ’G^νV5iλαζΦ4-Eο-αE:ΛΖRq‚=ΉMΰ―ω<[^©όΪΉDΊΈŽΪKtžU·‚ρ!\ބކ°|‘§ΗVžΏ7cUΟ)»=šόHΆŸ_ƒΐ„l\&7Ɍ?aΖr½qή&ΉΧn―-’ρœL£χbhΒ€ΰ‘€=?JέΥoξμ~x`Ω]On]d)ŸœυΕrή]^έΓ%εΜΧ€(i\Ή=2kLEM.φ¦ΘŠ0ΥΚΛwλΉά]x'D΄ΦΖ“sJ·³cΘA@Θγqι’sΗΣΦΈ}JΒ]?TΈ±›Xe1:3]·‹Ώδ[ΧΝ―ώΙ\―ŒυVEΑ"–&J\ͺΦ•‡BRms;έ\ιΎ3\΅–­gαΫ2bΣ4λd π ‘’ΗΤτύ}kΑ‹^Q½Τ―ΎΑ€ιθβ`››œΰ(όιΗ5»ρ–ΞKέJΛΔ–ˆeΣ5hΨL 6ŸCŒ~Ύ”Ÿ ΰ]oΒ'πδG£v!šέ‚ω›$Θ~uΖuž'π¦™oαδΧ|7ͺ΅ώŸηy¬±μ’6ώ£§nγ­uΏ΄  λΜΊ­ΓΙ.œ>άά£pwγζΑΟOJδ|Gΰ‡πΧ†£ΌΦ– ZiΆEb₯\μΗ,H?_΄~ ½΅ρF•‘­νφžc·Gm»Ϋž3ψŠζΌEiαλK»A’jwWφΝώ½ž-“‘χs׌ΧNί žγ_Σ#ξΝΖ‡}ΪEωP<΄ί»°##σφ5ΛkΎΦt;ϋK-FΣeΥΦ<˜ΡΥΛδΰ”žυλ:tΊf§Ϋ|>ΏΌ]j?ΪnO–ήi1΅±το‘ύγ@/­CgoͺέC₯Ο%ŜnV9\\ψ‰Ξ=ͺ•_Χt«­WΉΣ―“eΔ΄ϊ0μG±5B7ƒ<3Ή‘y¨^‹.ΑΟ6ΝνΞpόιλVΟΔwΪo‰/€³ŽΨΊy°Δdάα€z“]oδ·ZΧݟώΙ\―Δω΅―ϊωj)9;&χWΊψ“§xaυ+fΏΥξ-nEŒ~\qΫΌνbGBk†π†βΦγΤ/5 Ρc₯Ψ {‰Άns…Qܜμ<α­KΔ†ΓZΡcŠλO]:0ς,Θ •A#Φͺό(»‘τOivΤκ³₯ΆŠδ+$»IάΈ¨Λ½’Ά „ZB>>£ϋΥ\ςδΊwwΣΜSΔϊ λv:dΊƒΛ φωX ΖBχ$ ŸΚ»‹έ7Β§α֝šΕΚιΒυΜwBΤοwΓeJυΗ^}«‹ψ‹‘/ZϋeΌ­s¦κYΊΆΈ'vπܐO¨Οκ+ τ‹―ό-³°ΡDSήΪ_Ό’ΒdT`€HυOXΖN@yώ­œ:Œρι·sf­ϋΉ]6ξ;UJ³©Ψάi—σΩ^§—s‘wƒυWAβ―ΟανHΤ₯½·5 >©• ΧΈη­t­€ΏΰYΞ•αkΚΏn·X’†FP|½ν‚F~£ς¬νcΕrk~K=Z3q¨Ε6ψπͺBc• σΕhx%Υ<;β)cKλ₯ŠHΫfΖΙτόκ–ΉαQ ψy'Υ¦ς΅ifΫ’ΊΆ#Η,qώzVΊςι±ΟξσΎmοϊ|3§.ƒo«x‡S{(.œ₯ΊGvl}η5CΕ>:₯o \-Ν₯Τk4¨Ζδ>ή΅"γΕ~ΠSF1Νu§™bž V]Μ<φΐRψ‚ΡAs ι‰2M>ŸhΜPδγ#τύhiX#6εkχΠΏuΰ}Σ\MΞ»*^Ϗ!‘ΖγΣ$珧­rΆϊU½y§λχ’ZGnY<Ψ£/ΉΑqθFMu/’Ώm_6Ώϋ%s^=‘ΛW―†’I-SrvMξŽΛΗφ{ψχTžΪΰYΗεΖ–εƒv’{fΈο hκι}u{v,τλ$<» z=x§ΖήΤ5σe«ιΗsbΆ†u•F ’&«ό4Ίw5Ν:ΘΫJQΆράV]€δ`ρŸρΟj¦―-Q1“=Ώ‘‹―ψzΞίE‹XΡ/ΪχOi|‡G±γ|gΧΥI†΄<7₯£K%Υΐ”Asm΄n‰Β‘κ ώ~ΖΆόbϊε·†– lι֞|ΐ‹(#Q!Ηρ’Όc­Sψ:xό’.·¨οi΅XΰΆVΖb§O¨υ₯ΚW<Ήnέώσšρ‰a’λz|—Ο#€ŸmuLˆIΖBϊ2*μ/4 ŸΨ$š­ΒΨ‹Ά)p-Žφl©k’ρގtν[νPJn4ϋόά[ΞNwΙϊŒώ’Άτέ.ηΔ_-,΄‘Χ–Χ¬ςDd ΑH8<ŸqBέ« ZΖ2ΉΔκIm όΙ§ΞσΫ+~ξV]₯‡;Wy­Ξu„V•γyΊ†›zlΌζϋΝ\€O~«ωW}cqc-Μ{nb}Œ€†ΓzqΦ»νzΩό=πNΣoΕ©_Γ }εŒ.2Gn‰Η½ft-8’Š) ξμΌ!£Gα}+\Φ΅™m Ό.¦4ƒ{ @ ŽΨ’}½kΖώΏΆ[{‘wcwΈ·ŸnέΚ}G―ψΧcqαΫί|3π€ZXŽK¨Œν䴊…”ΘAa’:qωΦGΕa§ό#ϊGœ’άιΦ ϋBΏ~Ÿ¨ZsnvΏW ο<αν;VΆΣ΅/ΝΥΪ!ί8-ΐ,z œŒ~9b/ήΙγvπΠ‘>Π²”2γεvμ»Ξ? ΧψΖ̞1…ΡŠ²ΪBA―πΟZόA³½Φ.݌Α£{‰δ,rP…άΗπβημωο}Ήqΰ­ςΧR_k―{¨iρ΄²Γ$ͺύν§Χϊζ¨ψSΒϊf₯ >««j3ΪD·«iΆ8ƒηr‚>œŸΘWQα― έψ&]sUΧ$‚+%³–ΜRgfΖάsΞ:{Φ7‡Ώδ˜ΙaΘτ©ηm;JλM@‡Δž ²Σ4}Z{=NK›Ν*dŽκ6‹jνs…ΑΟ^F­£ψ[KO[k>%Υd±·»vKhα„Θο΄ΰ±τ<ΧWβψρψ›_ϊ©t;SSψ’§…ντϋΫ»#$WVχ ²e²¬7‘ηνKΪO—WΧτΈŽ Ğ‹AΧ,`žχΞ―9㻍L,ymΎ dγιλ]Υξ›αSπλNŽMbεtαzζ;‘jw»α²₯zγ―>ΥΙ|N›P:••¦­uc5Ν΄μΣjΑžvΩΥ³₯ι^'ψ[ga’ˆ§½΄Ώy%„Θ¨ΑH8<‘κ)Ι·ΚLe_†YΓρNΦ=6αξlΤKεΚι°°ς›¨νK/ƒ4BΧV6ΆχZΆž4И £…ϋΑ λƒΖ{ρλLψ[cq¦|Q΅²½O.ζ9$]ΐΰωmάqGΒΟω|A`˟ύ h›jNQ{%ϊ‰ΰ Ε­Η¨^j’ΗK°@χl.άη £Ή85cбΆΠaΧ4 EοτΦ›μς "Ω$OŒ€}GψZήψQw#θž μ ©ΥfKmΘVIv“ΉpxΟψη΅9“ΔžX5σ₯Ω}¦pVΒή%6ίγ%xΗZ©Ξ^Χ•Φττο θZͺNξϊˆ—te@ ±€ΰχλGŠtτ[-xηyN‘f·L°žΒΊΥΡΌaπλΓπθ~Tχšl’Η<EVPνά‘Ζόύ«7β«Α Ξ‡€Η:M.›aΌμ‡ 8κ?O֜*7%υwύ³qΰΟιRΪXkή šΧTž%‘‚Α˜£έΣ-ιο‘ψW ©Ϋ-ž‘qmΔW)•Y’9Yb>΅νZUŠZM>ώ #ΔZ*ƒ{(C²#אr±―#ρt66ώ&Τ‘YZΕ&aΣ‘@{Œζ•Ή6›ΈΩ|=Ψ*_εUΌUΰΩό=‘ι”·Άσ¦ ‚GΥ2‘Ίχυ« m₯ΌΔvΦλΎi΄Ω#EΘcΐ>υΩ Μκό αλ¦Ρ΄]τ”ΏΧ5‘l%r‘ΫΐΎdƒΔΓ°ό)šŸ‚uύ2ΖkΛΫ%Žή!—o9qΠχΏL±ΊO ixSMΣ―%‘[ν²Ξ¨ΞΗqΰuύ?»κ‰Eouœo‰΄ κ–‰ ΘΊ΄ΉEž ‚γrάzΧsγGΤόk,WΪΓΫ_݈ΦRΐ|  ΝΣ$ƒΗψΦ?Ε iπηšΠ΄Ÿd]ΖlΞyΫŽή•Ώβ/ _j‘Τ­ΜFΚ)!’w2(1l H#9δ]FNwQ“vўuiα»»Ÿ2-ΐ•£g?tΙ-ω ΦΜήnν―ΧAΦξϊΖ6–H€„ ‘Wο?ώΊ»€k6Iρn{Φ™€³I”Ÿ—•*} ΗηZχKβm:ΫQžτhϊ}œq2‹ f`z*νη'ή’Š±Rœ΅Άˆζ>kϊ₯Ά΅¦iέ²ΨΙpE΅pryη¬/ΘΣ¬Χδίϊ§ψ>β+Oιsά8H’α 1θ£=MnxΣΒZΌϊΆ¬`τζη,ͺ~V|Ž3žγ΅N%ϋ±©ΪδG‡4ίψG’Φ5νF[X.%1BΕ½›Ι>εY>$Σ¬΄λΈΖ™¨Εk,bEuee‡c]ƒ‘ρxr947±Τν$‰,& |£ž§qzπ{ΦgΔΫ;+MJΘ[Αoky%Έ{»{s”ŽOAŽJm{·&3|φlγjΝ§ήjw?gΣ­fΊŸΌΈP»`u8Z¬X_]ισωφSΪΝ‚ΎdlΩΦgAίxή το†>Σ΅$k{τ–w6οΓ.Ψ$vκ?:σšτoΝ>‘πΏΒwϊƒ½ΝσΛ:‰ζ*€»τ}+Ξh’Š(€π₯‘–ΗSž;(―.#ςΦ(εMΓ$œώ•KΔp$޽2ΪΑΧ,<˜Κξ\œŠ4[ ‹ϋ[€²Ί+:ΰύ›vί4zη8βλ‰-§‡l¬υωfgT-Ή£ΤσO Œm6ΖMBi#‰‘JF’ήŠ3E₯„—6w—(ΘΩU˜§'Vƒ™?΅Ϊ)SΟ†H•›¦β8­ }&ηKπώΆ/B$Ž‘pΗϊœtX Λ]i­ –K«KvΈSΞC?ιQYθ—›“,°[EnΫ$’gΐ θ1Φ·τ«kΛ« ,­5+0% ΅ΰεKpF*;-.Π&’ϊu΄zΔ7>ZG#π±γο`»ž)ΨS§°–fŽdœnŠHNεqνZ)α{–™-ώΧd/3oζ|κ―‡8­-zSiάΧQA…Ωž8ΘΈu$OOηšuΎ‘1ρZj+qYIqζ€ΒPwdδ(sΞ(°ύ‹<σ]+K0Ϊ±Ig•Ά 9ΖsœS5"{6·ΓΕqΗK nW9Ζ>΅ΩΙηΫjΦvφΦΧWk~σyτΘδr?­QΧ άVΪ}­ΔVΛζ,qΊ3Σsrp;ώ¬+ŸΟsbκΞKˆW|°$™uϋsŠΔκξΖK¨ο\²ΆŒ$E—P…φοaΠγ?6~•ΒΠΖQ@λΝ ;‡^υˆ/$ΤšXΨ*Δя½ΑΟͺΉ]rΪ =bςήO2€*œδ}k±°Ÿΐφ‘EΜc #‡ώ°ΌR<:ΡΗ&€Σ¬»°ρ0m»qΤΟZbκVπ•΄wzΏ“,K(1>†FvρEƁ4vΣK Υ₯Λ@34pΙ–Aάτδ ›ΐψώέ\ΆΑεIσz|½jή“¦\θ¦ϊσQ Έ·xΠοLXpGzΘmΰ^ΨΫ+FζρHΨŒ7―»Σ†‡qύ₯wdΟ½ͺ4’9'nΠ3žžβ·t[ˆΟ‡>άμƘ²Η―οΪ2hΤ#ώΠVIΎŠ;VυΚΈώ v"?JmmξgΌ³·†t +‘“ιΣόζ§΄¦ΆΥξνu£r–²HΏΔ§ŽUΝOI»Τ΄¬”LΙnFΉ<ίαV‘‘ud΅YI-t¦†FS‘Έ‘ŸlΡ`9λ=Yν"ΈΈΊ΅΄Ž\ˆΌχΑp1Σή­hšo L’lδΗΈƒ Α#iO§\λvZ\ϊb‰’+d·‘ceΞr οV㹁—g%¦΄R-.ΪΙC„œΆι$8ΪIοΤρΣ5ηš’Š) (’Š(’Š(’Š(’Š*yΏγΦίώόκ žoψυ·:‚Š(  ΑJ‚vž£wξlτΗϊšΖ’ͺ2qM.€Έ§fϊQRPR³3±$ϊ“IEQEQEQEmι~(Υ΄Ν"σKΆΉ'OΊFI ‘C(ά0Jϊ₯bAEν#–‘™˜υ,rM%PEPEPGZWfv,μYRNM%ͺΕNT}A€’Š(’Š(’ŠWfv,μYrri(’€ (’€ RΔ€ $'₯%E+1f,Δ’z’i( V*r€ƒνIEQEQE¬ΜμKΔχ'4”Q@Q@tMNγFΥ-υ -‚ζY ΰΞ?5ZϋZΏ{ΝRζK›–.ύ‡ €=…R’€ (’€7΅?5]%mΜGM2‘0“%χΆzcŒ}M`υλE”Tv’Š)€₯‰H=)(’€ TvF܌TϊƒŠJ(’Š(’Š(₯vgbΞŘχ'&’ŠTvC”b§¦AΕ%P„Ž vz¨<mP–$I p=)(’€ P̐PZJ(₯ @ ΰΰυ€’€ RΜTāΠ’Š(’ŠTvC”b§ΤRQEQEtz7Œυ'F›J·ž7Σε <™£vrTυkœ’Š(’Š(<žh’€ ΟZ(  @ κ) δ΅P©Ϊΐΰΰτ5ΠC­i°ά-δ:B₯βςΈ”ˆΥ½BγτzŠ`>Y^YžW9vbΔϋša$œ““E€RΔ€ 8%PEPEPA$€ 8(’€ (’€/κ:‰»‚Κ5CΆ‡ΚΞμξη―΅P’Š#8$g­Q@Z(’€Ip:QEQEQEQEQEQETσΗ­Ώό ωΤ<ίρλoώtQ@Q@Q@X°±ΊΤ.6ςάLA;#RΗ½Wγαυ•Εέ¨΄Φ™ƒ―—9?xρΠf’€Ή#rιÞV8†VF*ΰ«‚ΑRJΫbGvτQš‘3j¦'Ug›cM)ΐlcιάΧ¨ι:lΊ'ƒvιzώ‘mq5ηΟ{ζƒ.ίΈŽΌgZU*r%ζU:\νφG“H”‘YXu 0E6΄όLΣΎΉtΧwΠίΞJξΉ„‚ςŽ„ΠqψVeZwW3jΞΑEu>πΔφ•Φ£zlτέ::βDMοƒœ?λΣޟβ]ΓΠi ¨xw^ϋ_ο<·΅ΈO.aώΠΗαLG'Ez ƒt8ό)€kΊξ΅5œ…Υ£Hw±`ΔΈν€I'ϊΦ'<.ΎΤ-–Ϊθ^X^B.-§ΖΚ}GεωΠ3EzE—‚|2Χš]׊kWJ6‹hĐ«·E,8'ρ­bψwΑζΗ­α½Bv…£yQεŒgξ) Œφ8ύh‘§EΝ"Η3»pFIό+с4[Ϋ V-^{½cM₯š€ͺ8_ΌžΌρŸ§­/Γkƒ£x7Śυ’§φ²C 2ƒεοl3υπη·6ΣΪΛεάΓ$2c;dR§CQWeψΪOψM4ύnsͺΓ?™ ξp˜εH{ώž•Χ|:Σό4|/―2κ·$ΊpϋpksώΑάW›==(Ηθ­οZxzξΠhšΥύ³―g‡Λdδ}άυγ5Σ·ΓgΈΧτΘτ»³q‘ίCφ‘~T-7ξμΘόύyΥwZ†ΞίUΊ‡KžK‹8ά¬rΈΈπ;œ{U*(«š5΅½ζ­im{r--₯•RIΘȍIδΥιšv“Λi£κ)¨Ϊ*©YΤ‚2G##ƒQ@”WY€ψ55: ³β_Ϊ™Ww“sy²Dη£ pk/ĚθsAκΊf£ζ©mΦω‘1ΩΈΰΠ=V§‡mτ«›ηMrϊ[+Q+$Q lŒ }3ωRnΚΰeΡ^»ρ'NπΓκVΝ«άZά‹όΈγΆ,yΪτΧΰŸ Ϋx†ΣWžξόΩGaΚlά6œξ$uΰ/AΦ³dγΜτ•’»=wΒΊbψa΅Οj’_ZΑ(†α&‹Λd'#Ϋ‘ωυ¨4B}=GΔθ΅9Hν­—Ν”c#sʎ=??k\NŠθΌgαΏψG΅h­ξEε₯ά+=΄ΚΈ.Σ#ΧόEtΝΰMΚςΫHΥό@πk· Έ‰ -3}Υ-ίσ:±I>ΰy½[ΉΣ/­lνξξm'ŠΦγ&]Wϊ»ύ•oaβy4ΝvθΫΫΓ+G4ρ.ό`;δγσ›Ηv‹„΄¬u»½GK‘δKxζŒ g―\Žhu5Iu’ΊίxZΣ]5{λνDΨΕ§ωlΟεοNwIΐΰ¦Ÿβ_ iφήƒ]πώ₯%υƒMφyD±μxίόΏΔu£ΪΗ›”>ŠνtŸ ιKα{}gΔz΄–ή;Gl‘Bd'i ±φΰ5KΗ^‡Γ2ι©α»VΒs&ά/'·΅ ¬\ΉP½WQπΞΟΨGp‹$kΎM¬2 Hύp Ή>TΨ»±ΞKm<(―,2’7έfBϊTUήEγ Vώ-J=bΞkύ6κ7XΡbDΩΰ†·τ¬ θ1κι{u{v,τλ$4» z=x©Si^C·cŠιuοYΫθΡk-ϋ^iν/βHφ¬υ'Ή“RΤ’°΄·MξΝΛΎz^犽―ψvΚ -cDΏ{Λ/‘ ’=γ<žβ›šNΒ³΅ΞbŠμ­<1€Ηαέ7WΥυYmaΊ.¦4‡{Œvΐ$“Y^.ΠFƒ pά ›Kˆ–x&”ϊŠJi»‹Jεoh—ˆo~Λ€Z΄ς–9Pz±< ₯}lφWΧ²”i ‘’b‡*JœN+ΏΌ΄/ƒΪRΨ&}fβFΉ‘8gDbηΣ…ύ}MqώΠηρ½k₯Ϊ²£ΞN]†B(“ω ±4W£Οΰ}ϊ J ψ‚K½SO€’‘Ψ²ᢟ―ΧυΝEπ~ΣD›Δ^ίΝͺ·Aj!,’.Ξ₯»ε@{Ew>>Σό1 Φ«6¬\Νͺ}©χZ΅ΉTR\ξ±Ϋš­ƒΖ©α+][@šk»‘0·»΄*7DΜ@R1ΥI#σφ4ΗΦ߈Ό/ͺψ}a“QΆΕΌΰ§ƒFωΰŽώΖ¬ψη@³πή‘λ]ή€AπH܁ς©οΧΡό5ΈmcΓΎ%πνλm–Εο-Υως€LrΎœ•9¦œQEu>)Π΄]3D΄½n;ϋ»”xŒΔpAΘηŒiΛQEQ]Ζ…α=#ώh5οj³ΩΫ]LΠΫΗoφbΉΙ'œrήυβNΣu;hτZJΞαΦDαγΙϋ;ΐ’½ZχαΧ†μψdθ-­Ζ’σMq8Efm­ΐδP? ςΧVGeu*ΚpA W[βΟΨx―Y k)6G‘:wς7H{g ξLπ‘ψk¦E.΅tš`½sΠ΅%έπΩRΈΘyφ ’ΊM3LΠ―<`4ζΤη]*WςαΌςΒΔ n Ο³Γη°ώέΈρ%Δ–z~™ς,¨ ›‡8*PGζ=θ‚’Š(H šαŠΑ’°!Ά?*V*ΐ‚=«Π&ΥΌ5ΰ=θΞ-ηΎyežPŠYΆΆδQωW;β½j?]Ϊέ-―“yδ¬w 1‰\ότ¨Œ›{hSI4W{V•owo₯κα‡ZF"X "³tRίώͺΔΠό4ΧΎ0ώΒ½”Βκς#Ί ς ž=Ž(U"υVs΄Wk–—ug¨&•¬5Ξ§aI,F¨Α~φ}ψΟψΣ~[iRλVr]ήJš‚Οˆ­Δ[–A·»vοωPκ+6Ί+½Ž2Šκόcg Εq%ާ<·hmΦνUqά7{Ri~ΣΧC·ΥuύIμΰΊvKx∻6 Aš9Υ.]lr΄V牴%ΠυxΝΗΪl#Yαž5ΑxΟ±θϊΥ²ήyυ>=>δΝ€έΕη‹ΒΈƒοnτ#ϊύhφ‘JαΚΞ*ŠΪΆ΄Ρ[Ή‚ηQž-5\w3@ϋ£ <ŸΚ»OXxyονΪσTžΪΰYΗεΖ–εƒŽv’{f‡Q&•†£usΜkoSπΎ«₯h–ϊ¦£oφk{‡ Θΐ;eIΞή `wφ­…št§t›k΄Y ή27C±€?ˆŸγMbη\ρ-ύέΤ¬ΰΚΛ“Β 8Pn*ΙπΎ«/‡W\‚ΫΞΣ²Αή6 bΪpw/P=λΊο…ΊΌΪgŒ΄ψUΙ΅½•mgˆς²+£#κEdψΚΒ=/Εz΅•ΈΔ0άΊΖ=<Κ€1ιQG ³1θdšJ±§_\ι·±έΩJbΈ%q‘ŽώΖ†5Κ©f·˜($‘ΐ¨+1tΌπ3Η†3ΦΊˆ–'ώdΎρ&•§i~"7!"[B Λrΐοάτ3Šς5%H*H#E:IF-#3±ξΗ&€=fηΓwή$ψ[α(t‘—qΫΙi )‚Γ$8όκ‡Δ΄³ΆΤ|#’^\#gΪΕ λFxL• >ΈώUΚjΎ%kο hzB[˜[L28—&M힘ΗΤΧR{Χ¬ιιšŸmπϊώςAu¨@iΈI>[y€ΖΤΗΣΎGχxU]΄M^ηNΎM—>ΣθΓ±Δ`Υ (  š6Ÿ&«ͺΪX@ρ€·2¬J6qΙ«ή/πυΗ†5ΉtΫΉ‘šDU}ρAduθ}«•™‹1,Η’IΙ4Χi―ƒΰΣ`SπνΥΥβ%™/œυ++Δχš%άΠ7‡τΙ΄ψΥH‘dœΛΌηƒΟJΕ’€ (’€=SΗώΤΌHl5­8΄υΣ£"Μ€©PI=kΐς(xΫώΌγώm\%Š€ωyxο.c΄–Φ;‰’ΪR «ŽGBW‘ΕzΖ“avž Ρ'πn•₯ήΝ*·ΫζΈHήD|Žς0:ώCρς PΜ‘‚±Ί€zΥT§Ο°—ρrW†οΒΞayΙώρ ŒνΗτ­x*οΕ~.Ν<’_,r=Ψ‘qͺ*ΆA9'?ΟδT‘Ψ!PΔ)κ3Α¨T\Rεz―Τ €Π$Τ|M>“αη†Χq„ͺ z·'­z&΅ΰ\ψΓΊd6JΧΆrNΣGη ΪΙ^sƒΑν^AETα)ZΟo/ψ wލ‘ψwγˆδt6κΓ=ŠŽΗώHΞ£aeΡk\-{=o~·!·°ρ_€t[5Υτϋ ύ)εYς_,fΞαλΐ­Cρr(aO Ek/nšdkŸίQΠώ#šη<9«hΪuΌ©«x}5IYχ$tΡlι€iΎ0ρž$Ώ†fΆŽήή‚ xΞDh: χυTFœ”ό΅ό@Ή¦x6{_ψ/m+G*`oΌΨΖyμyΰw¦|6½‚ΓΖ62έH±ΔwF]Ž,€ ώ8h1 T΄ςFx4•Ό—2hiΩάυ½ΟYπ½–§ύ·v‘θA*Ϋ¦υ"Wc‘΄yΙλλX ]τoN³6ΗR˜G%Όw“i9ιύΫdlζ§πζƒqαΩυ­cQ’ΣΎΛ*A*Θ§ΞάA\{γΏzβ<+¬`k–ϊ‘φ(0ςχνΞTŽΈ>Ύ•™,†FbI±lg¦j6έΊY™ΟΓλ4ŸDΥ¦Σν-/5ΨΩ<˜@`ΉPxΟ_Θ~:ž'[υψs:κΡYΑt/S1[*€ƒo‚ρ»ϊbΌΑX©Iw”έ;Κχm,v>&’α?ϋxΠθρόƒ<+`Ȑ:Š₯ [ζ'#.meΧώim§©žγFΉ•n#A–Tr[v;ŽWυτ5•πƒQΆΣ”Ϊνώ!x7Zου=^κή1§Mvμ“,ͺΫƒ±+ΖsϊWEΰ)αψ}αΥρ­ζ5ΖͺΙ½’Ά „ZB>>£ϋΥδΤP_ρ/A:VΉφλišλLΤσumpNνΑΉ ŸQŸΘŠΩψqk&α―xŽυ 6νbφvΜγkΎ:zŒ…ηλθkΝλoΔ~)ΥΌB°¦§tZ@€*'ΰ§άδΠ%tή,π£ψoM..oKB7ΩΒb\ΙΟ©Ηΰk›‰•dFuή ‚W8Θτ­―xŽkM¨\D°Ε(r#P:Η'ρ  :(’€=cΐPx/ Γ/‡$Σ΅{)$a.›p˜=Nβ:υλί8¬Ώ‹}޽€}–ΪΦΟP–{λkb qɞΨιίςη±Θρ6蝑ΊeN(φJ―Τ‚֘νβΏκ:―ΕK]ZΡ‘kd‚K‰ Š %6’ η<€ϊΧ5£^ψΣ¨Iz`Έ³‘δ6βSϋΉdPηΤ=x/ΖΎ$x‚ηSX   BMό(“žž•@Bxr?ΔΪΘρ€iΠύ†avΙΘηŽFNΐ=}Eyηƒ?δ˜xίιm‘šΰήFέ#37L±Ν6€;ύ?ώHާauΠ΅Ώ±.ΌkπΫΓ‘h&)―4Η–+‹s"«(fαΉφώ>ΥεTθδxΫtnΘέ2§/$Ί²ρώ‘θ“Jך)Z‡“wΫQWksœΰϋS^%E^ΡtηΥu›=9$HdΈ™a'I8ζ―xΟΓ²x_^—Lšβ;–EW Ηg‘ΨΦ+1v,Δ³I'$Π  &γΕ>ΠγΡΜs]iο,sB\+(fΘ<φΐŸ΅sώ'­<=©Y[ΓrnncdΊ‚Lς£η₯sκΜ§*H> TF =τ)΄ΟXΥ|9s«ψήΫΔ62Α&#ΓpΧb€δœηεΝπΝδ7$ΉΆ`πΙ$Ϋt`#aŸΌλ'dΰφ€©T¬ίKŸ[―ßω kφΈώkXήΈŠΧΕΊ\Χ±Δ³ ³ž9όλŠMόΙΎΗUγO jΊuέφ₯s nX€«"Α˜‘ΖsϊWS£Ο¨κ Γ°Y]έZ"Έ‚tFeΛeHέΠcόρ^YJ¬Κr€ƒκ 'M΄“{ JΜλ6Ρ.΄/_ZέΔΘ¦VhœŽ Θ χΰŠΒ­½OΕΆ©’[ιZΙΈ΅·pρP]p€cwR0{ՈΥψU’άjž1ΣηHΫμ–R­ΜσΓ'Ԑ8¬o_Ηͺx§V½„ƒ χ24dw]ΗςΕHž)Υ£πβθp]tμ±xγ7Νԏn•‰@N™ΰΩοόβ4½·H­©Ύσcη±ηή°4½>ηTΏŠΞΖ?2βRB.ΰΉΐ'©γ 5X1 T΄ςFx4”0=3Ζ~՟ΒϊΫP³­$7?Ό_“>ΌπLΦΓΨ΅gΉΌ“A½‚+ČfΦ\€/98ό:Χ%@$Ž f ωy[+™^η£ψΪΟK½sN±Σ΅Γp5Άΐ2GŽKOΏδ:f²τ _]ιVZŸ…o^KήVζ%˜DπœρŽGλfgl±,}IΝ Μ‡*ΕO¨8‘A₯dΑΙ6wŸš 5M Nh€ΏŽMFHˆ=ΗR;ΊΊΉ,υ+OZ—¦θπx}dˆ₯ΞΘΙeγ8brXœψ}kΕιK‘I;GAš—KD>}nz]ό”/םΟώΛVΌ/!oםΗςjςš(t―Χϊ°)η€¬›Pπ—Šm#tI%*8·6}ΞγNΥtιΌ9πκK P€wΧ—’T€8bΙΗΣυΜιzίΨ4_Mϋ?™φρσ7γΛΨIιŽsŸQY ŎX’zsO‘Ή7αΜ¬v? ΆO.·aζΗΕξŸ$0ο8 ηΆk#Wπφ©αΙ-fΥm„Jο”ΔŠΫΆΰž„Φ%|­JδίKΣ«sPΦc½Πc₯§ "ήKdΕ€3ΈŸ›#ηΗψSTEψ›φ«ϋΈdσd’3pƒj3 žΔγσ3* zŒυ€¬Υ+&ŠsΦη¨ψSΒ·ϊήΉ.‘ε’› £‡ ”pw@ΰuυgαf‘™γέ"βεΒBdh™A½JΤŠεY‹cq'sIW΄Ϋl–ο’7|m’]h^$Ύ΅»‰‘L¬Ρ9:AοΑ§π«EΈΥ8€—>Tnψλ΄ŠY –%έ$R ι–R(:*E‚fzΕ!Oο8όκ:(©2’ Dδ°ΚαO#Ϊ£ Š( Š( Š( Š( Š( ŠšΦβνŠΪΫΝ;’#BΔΒ’udvWR¬§‚ %Q@Q@TA5Γ‚)%`2B)l~T0*ΕXAΑ΅QEQEQEQEQEQ[zŸ…υ]+D·Υ5³[ά8H–FΫ*NvυΏ΅ α}V_Ή·§eƒΌlΕ΄ΰξ^ {Π%Q@ψ’’fΫ;Ά3…5/ΨΏηΪϋφhΈ蒊(’Š(’Š(’Ÿ2ΜO“Ɏ»TœP(©e·žέ,2"ηe PΆΣ΄~bΓ!ΰ§*(­Oh—ˆo~Λ€Z΄ς–9Pz±< Λ’΅,τ;«ΟbΐΠ›Ο9ΰΎ²η‘χΗ³₯_h·Οgͺ[Imr£%ΈυpGΈ  TV…Ό'©ψnΏ²DφϋwG$‘³œmΟ^†±nνζ΄Ί–ήζ6Šx˜££UΑ€"’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(©ζ[ψσ¨*yΏγΦίώόθ (’€ (’€ (’€'‡ώ=n?ΰ?Ξ ©α[ψσ¨(’Š(’Š(’Š(ΣΌ5¦ Yλ:©%¬3HΡ”H·’A Η°'&¨x³Γι£Kg%ΟΪμocσ`—nGλΘόλKW’c‘ΧΤίΝ«—³±΅Ν,±[œΗ9!A!AιΣ΅cfο~¬ή|©rΫ’;ψC΄«{Λ}+P֚ju\FΊ)=Ιό+ž΅Σ,ν΅»«]Ιf°nC$Q™2ΰŒz“šτνTλz†³ξ…•.•:€‹y,q“Ξβ~lŒœW”x†αξ΅»Ω₯ž+‰C™b\+φΘ•₯)ξΛ­ΓTΏΰώ'{γΫ=ό y©Οop,Σˍ-Λΰ“Ϋ5Ζιz*^ψsXΤΪfW±ςΆ >φΗ&ΊΏhϊρ²Υ΄˜γΉ±[ λ*₯A$Mgx!©h!Ρb‘φι"xΫΚ1$Σσ₯ rΣΊ}ΎZ•8σU³[ήήz°θ©'„'ΦLΜ$Žθ[ˆρΑAΞΣΣΌ5¦ Yλ:©%¬3HΡ”H·’A Η°'&λ62xwαπΣ5&DΤ.―|ρpΕP(8ϊ~΅WW’c‘ΧΤίΝͺΉάΆ{²9w[/ΔΟρO‡£Ρη±{K―΅X_F$‚m»IdψΞΊ―θ–šΨnuΙRφly ΘŽ7™'<}=k†W›h¦žY"„β4w$ '£·α]Ώ‹Ώδ[ΧΝ―ώΙN\ΚΚύC‘ήVκŽ'T²“MΤl§Α’ 6#‘Ακ*­nψοώG [ώ»΅aVΡwŠfV“Hλ|αkM{IΦ/―ucž#f/xΪsΈΰrN€:š“ΔžΣνό7»αύJKλ;μσ cΨρΎ3ωˆλZί μSπO‹μ£‘#’an¨]Ά‚Ϋ›=²p?~³₯Οαo…²ιΪΉŽ-FϊωfKpᘠQΙΑ>Ÿ¨g7ν-~«O‘&n—α-!Ό'a―kZΌΆpO+ΔȐοbA Η°$“YΎ4πΚhSXKawφν?P‹ΝΆ—fΦ#Žυδ~u«­Ι"πηύ~OόΪΈτΤ.YμΕΔσΝ«o!*ƒ  π3ŽΥpζmΚύXχό :-­νΆ©ψ…‘ΧξH… -3}Υ-ΧΚ°ό?αΆψ›T5;“jΦΛ#Θ‹Έe=9ΝwzΟ…n΅Ώˆ6ž&Σζ·“D•ΰΉ{Ÿ5@Œ \‚3œόΏγYZ τΔOέΪ8x$°ΊΨ㣴d{VQ©'Σιχ0 ƒΐ5δ–qΩkW/&₯lΣX«@J‚X?2υβ=k¬ψaαΣα­q†§;Ι&ž>Ϊ ΉGΰδ―χ°sωUΙβ O ¬ωμΎΣ8+ao‰oρ’Όc­TΎ ΌΆρ.—‘­ενƒG;ήάρŸΔS“r€Ϋ}@ηυ»]ΦφΜh:ŒχΡ±ύα–Σ‘Œg­z_Ž|9‘κώ>– C[’ΧR½XΦRΚΏ(QΉΊdxϊzטλ^Τό;¨Zëۈ$—€H―‘œ 5ΩψίώKu§ύ}Ωμ”ε«\²θυϋ€δl|-ywγαΥd[•™’iv€Ή%Ύ˜­ιό£^ΪκKαΝrKέCO₯–`($UϋΕ―ϊΦ­†£o¦όr»šςEŠΈ–##,€ ώ8jήi–Ί₯ΕψΠτΫ’e[‘fpx Nr}ιJ€ξ΅Άˆ8Ρτοό)jν;€šq‹laA½±ΙνEΎΎΉΧŒξ%†πZˆ°0APsŸΖΊ‡ [Γ^'Πa–4ΏΌŽ)-ΡΨ0£@ΟαωϋTϊφ/…ώ'UhγΤοoΕΐ·W ȁ@ΙΑ>Ÿ­[¨ΤΉo­Χά^‰α}+ώ˜uΟκsYΫ\ΜΠΐC½›Ι'· ρνοXή*μ4»Ψ—IΥ"Τ­&ŒH£ ™ώvήƒΕ)αh₯πσιϊ΅”’0—NΈ ΖΟSΈŒg―Ύk'β͍…–©§‹[kkKι-ƒήΫ[Ηžƒ;ώB”&ύ§+}ΐαkwΐΏς8iυςŸΞiž žΑWώ#KΫtŠΡʘο61ž{xꟁδp?λε?uΗtLώWρgό:Ού~Ν‘š—ΓZMž€χ2jz”V–ι½ΩΉwΟ@‹άρ]ˆ<β+Ν{RΉ·±V†k™dFσγR䃂ކΰ }X{;;Ν~U†¬g’ œg―δ?ε|Ϊ™:‹“Fdkώ±ƒC‹YΠυΌ±2ω #ΨρΎ3Οωξ+‘žΗMΊπ†$Φu³ΆŒΜ—wv/ΠΐI5gΕP_‡ «ΕgίΫS1[*€ƒhΖνΌnώ˜ͺΧ: ζ»πΓ1ι‘$ΉŒΜ|¦p₯”Ώ$dφγσͺ΅›²θgΝtϊώ‡)βοa_ΐ\}ͺκ%šήPΈ,§ΫΧόk{ώΝ&ήςίJΤuΆ‡ZW€£FnŠOr βΗasαύ?ΜIgΣ­'Ψr qϊ~΅ΩκΗ\Τ5˜οtτ™t©Υ$[ΙcŒ˜°wσdcϊv‘E]Τ—*Τςθ/΅o j·Άφ—&ήεΓ)@6Σξ:VίΕY^}[I–Vέ$šd,ΗΤ’δšζόEpχzεμΣOč!Μ±.ρΖ@τηΔώΤ|Q¨hIΥΊιρBψ•T«.rHυύ*UΪiڌ£)―„΄΅Ÿ·\^έ[ ΌΩ€TήάηΐώTνwJΡaΣRχDΦ>Σσμ{y“d£ύ ;нπώίX—ηBΌ·Šφ$­e#ύ dδ ρΖ?ZΩρ½ž<"—zξc§k†ΰ,km€dLrX}!Σ4%ξ‰Νͺ–ΈΟ„.­oγ /U’Ββ-5RGk©#+Γ ξΚα|-₯Mα?O»’@ίl–eFuCΈπ:ώŸIΈ«6\›Š³g!β}ϋφαœ][\Δ³A(\nSӏZή>­n Σu-i‘Υζ ϋ΅„²#7E'ΥNψνΞ€ς˜™ΦΡ y8ΨH<νΗτ«ώ$π½ΟˆΌIύ©c,-€έͺ;\‡\F‘@9η<ϊͺyέ•έ‰ηvWv8ϋOέ\ψ—ϋYΐ•£/Υ@%Ύ˜­i|3¦][ί V{«Λ(ΪY"’‚E^₯M7ΑσΩi<ˆ ₯’Ν]α[†AΘ ‘5Πά―ˆτϋmB{±€ΨΪ$l’q 0=vσ“οNRwά%&žηαmZϋLΤ’K†…n%eΈnιΘχ5―ρ+VΎŸ_½Σ₯Έf²†Uxβΐƒœγ=ΟηY~Ρ―υmJ7°„JΆFςκ»F}Ο=JΧψ—£_[λ—š€Π…²žUHδή§'g¦sό'΅7Λν |ΎΣΜ·u­κ7ό4ΪmΙ€ΙηοΒƒ»ΗQξk3ΗρΗ$ΊN’‘$RίΩ€Σ* ύΟγύ+V} PΦό αΑ§B²|σ#4Š‘A~'Ψτ¬Ο›KΣΰš9ΪΒΝ –HΞWxκιS siΎ€ΒάΪo©Ώ€λΦκž’K¨•-΄φŠROάmΌω σsE¬`’i(μtώ'Ρ4m7En΄½n;ϋ«”βΖb8 δsΖ5ΜWMβo^xFυ+››YbΤ2,NK.@nxηƒΤW3TXWq‘xOH„Z {ΔΪ¬φvΧS46ρΫΓ½˜rIηƒΗ·½pυλƒΕqxN|9&«ΩI# tΫ€€ΐΩκwΧ―^ωΕpή(Ρ΄ν7SΆHΥ‘Τ¬ξ]dN<ŸΊγ±ήχαΧ†μΐΗΪΉx~ΗΓwΆv·†κτ@π Η!ώλν@ƒ¦xHό5Σ"—ZΊM0^ΉŠθZ’ξψl©\dΌϋWιšf…yγ§6§:ιRΏ— η–ξ cp=x·JΡξόUπšΗOΡ<©ο¬υ’XLŠŒ†Αδ΄+’Ρ.ώΐ‘79ϋKd0…76G―ζElΕπωμ?·nη9Αχ¦ΌƒEӟUΦlτδ‘!’βe„<œ$㚣^6­uα―θFqo=σΛ,ς„RΝ΅° ϊΚΉΏψvO λι“\GrΘͺβDΰŒς;ιF“qβŸhqθζ9΄χ–9‘.”3d{`ΟΪ²©m/±QΎΆ9ΟλQψ‚ξΦιm|›Ο%cΈaŒJγψ€η₯oΒ₯[έΫιz†ΈaΦ§Qˆ–Θ¬έ·ͺ°όO₯Zx{R²·†δάάΗΙt$™εF?ΟJνυ_\κώ7Άρ Œ°I£Θπά5ǘ  @Ήg9ωΖ’RI+;"’»Τβt? 5οŒ?°―e0ΊΌˆξƒ<¨'cŠΣ„KKΊ³ΤJΦηS°€–# T`Ώ{i>όgόkGΓ7ίό`’ζΩƒΓ$“laΡ€†JΞψs!­oώΑΧΝh”₯½ϊ I ψim₯K­YΙwy*j >"·nYήνΫΏεUόcg Εq%ާ<·hmΦνUqά7{UάEkβέ.k‡XβY†YŽΟώu{ƞΥtλ»νJζ2ά±IVE;ƒ1#Œητ¦τ©«ΩΨ4Ώiλ‘ΫκΊώ€φp];%ΌqD]› ΝQρ6„Ί£oΈϋM•Δk<3ΖΈ/φ=Z»}}GPπNž‚ΚξκΠΙΔ’3.[*FξƒηŠζ|vuυ[ι­./#cΩ¦E Ηύ)FMΚΝχJΕ†π3Ο¬iριχ&m&ξ/<^ΐD{w‘ΧλX–Φš#kw0\κ3Ε¦ "+ζrtt“ωW ΩIc£ΩCΰ«Λ—±7Ϊ'Wω`•ρ΅·―ΧάΧ—κϊuΖ•©Oex›f…ΆŸCθG±Σ§'+¦β’Hτ?XxyονΪσTžΪΰYΗεΖ–εƒŽv’{fΉΟ…št§t›k΄Y ή27C±€?ˆΉγM^ϋ­€Η͊ΨFΦUJ‚H šΓψY¨E¦xχHΈΉp™&cΠoR£υ"‡pžζ5‹sΔ·χwR³ƒ+,jO€α@Έ­?…ΊΌΪgŒ΄ψUΙ΅½•mgˆς²+£#κEgxΫDΊΠΌI}kw"™Y’r8t' ƒί‚+OαV‹qͺxΗO#o²YJ·3ΜxTw ŸR@β΅ Ηρ•„z_Šυk+qˆaΉuŒz.x•cΦΏŒ/γΥ)ώΒVAp%hΩϊ¨ ’[遚ν|Oα+―xŸϋVΒh[HΌXέξ„‹ˆ”( œηU`ψ.{βj.ΦK%y![–ωAʐПηDfω[NξΐγΓ¦π•wm~Ί°χwΆ1΄²E$%ŠΏx©υΦG„u‹ύ/U†; †….e%ΈnιΘχ5έ]/‰΄λmF{Ρ£ΨYΗ(Έ¦f’ήr}λ‡πv‰¨jϊ€Riπ RΦXήS½WhέξyθzQ^/™θ Y«u‹ϋ_i“\3XΓ*Όq`aNΑΞqŸβ?_»Χu-ΐ^}.δΐdσχαCnΓρΤSTώ)hš…Ά½{ͺΝ[ εTŽMκrvzg?Β{Uλκ:χ€Ό0Ίl+ ‡Ο23H¨ΰς}JŸw–7Ϋώυ»2>"Η²θϊ’D‘K¨Y$σ* ύΟ㟡ο'm ΰφ”ΆɟYΈ‘dNΡ€Ήτα_SXίη€M€ιΆσΗ;iΦI²Fr₯ΗP?!ωΦέΝ¬ΊΑν-΄υ3άhΧ2­Δh2ʎKnΗqΚώΎ†Ά§π’%Ήζΰr85θΪάη_ψEa©^7›¨i·¦ΛΞoΌΡ•ΘχκΏ•y‚ΜA$œ;Χ£kΦΟαο„zv›x¦+ύJψή[ο,aq’;tN=κΙ9_ΝΏ4In%ς’KΈΛ98ζO§―΅k|JΡ5x|O­j7:uΚX½Σ2άygΛ*[ε;ΊsΕex8ζρΆ‡±ω¨o#Κγ9ω‡_nυ§ρ/YΥ¦ρ^·as©]Ιf·N«nfo,(l¨ΫœqΕqΤQEQEQEQEQEQEQEQEQE<ίρλoώuO7όzΫΐΏAEPEPEPπΗ­ΗόωΤτ“lR&3Ώϊb™@Q@Q@Q@Q@ ‚• Bž£=i(’€ Š( f,Δ±$ž€QEQEQEnθώ ώΝπζ΅₯}›Μώ7ΜΗ—±‰ιŽsŸQXlΜΗ,I8Η&’ŠJ)6ΧP (’˜ …* ΪzŒQEQE+³;v,ΗΉ94”Q@Q@)ve X•^€ž””PG•™‹9,Η©'&’Šr;Ζs2ŸPqM’ŠPΔ)PNΣΙΰQEͺΕX$ЊJ(₯RT‚€‚:IE‘˜)PΔ)κ3Α€’€ (’€H9R»3Ά]‹RsIEYΣ/ξ΄»ψol&h.‘mΙ"υ΄ QEQEQEmκ~(Υ΅MίJΤnMΕ­»‡ˆΊ‚λ…#Ί‘ƒή„ρN­‡C‚θΓ§e‹ΗΙΈδξn€{t¬J(₯ B•ν<‘ž %QEQE‘ˆ@=FzQE(f T1ΪzŒπi(’€³$Πg₯%PEPZžΧυ/^ύ«HΊ{yHΓW„ eΡ@–zν埈Ž·”/|ηœe2‘›9γρ¨5ZϋZΏ{ΝRζK›–.ύ‡ €=…R’€7Ό1β½SΓ)t4‡†7Έ Gˆ;.3ΉιΤΦ-ΜςάάK=Γ΄“JΕέΫ«19$ΤtPEPEPEPEPEPEPEPEPEPSΝΆπ/ηPTσΗ­Ώό ωΠQEQEQEAΰ½bηΓ_ΫΆ±E=VwΘ ˆͺH$―^Ηπn½ ΰλn»ρ Ό, εΖ•2[ΒN―ΖΉλΠžΡW΅]Q5Υ,nmLμΖSv:γ=zΥ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*yΏγΦίώόκ žoψυ·:‚Š( Š( Š( ½ΰΨdΊρπ·pιS43cύ[qƒυ^y]^2Φ πΟφ ΌΡΓ`U‘ΒFΊ±$‚έ{ŸΒ€2u-WPΥRΎΊΌdΞΓ<Ν&άυΖONŠ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(©ζ[ψσ¨*yΏγΦίώόθ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (©¬ν./gΪC$NΘΧ'6–¬oDCE;cω›6Άόγn9Ο–HeŒfHέL²‘EΠXeQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@O7όzΫΐΏASΝΆπ/η@QEQEQEW]§xkL>³Φu]RKXf‘£(‘o$‚@ `NMr5ΨκςLt/ϊϊ›ω΅gQ½}Mi%«jφFo‹<>š4ΆrYάύΖφ?6 vν$qΑΌΞΆα­ο-τ­CZhu©Υq@Z4fθ€χ'π8^ΞΖΤO4²Εnslδ„…§NΥλΪ©Φυ f;έ =*]*uIςXγ&,ΔόΩ8¬ͺJQ²oΉ­(ΒwivΠσ]2ΞΫ[Ί°ρά–kδ2E“.Η‘9ΣΗΆ{ψσSžήΰY§—[– 9Α'Άk‚ρ Γέkw³K©e&›©\ΩOƒ$4lGCƒΤWmβοω+–ίυσk²W9γΏω5oϊξΤ©JNΧwΊΉU£{+YΨΒ­hPjΊ~£usyφXμφm›†sΗ\ρΐ¬ κΓ‡>fυ3žΎΥΝRv£5)m{m›αz±εŽφ僚œ’άΟg©ˆ%aq„‰:œη­u:Ξ‘u©ό?Άžϊc4ίΪw°όA‘κLžmό$™Ϋaή­žύ½mιV3k~ϋ²KΘ/|ֈΈS΄‘ϊώ•ue‘SMΧώ ”Σ•=vΨγh«ZžŸs¦^=­μ~\κ+Έ6229UZλMI]­4μŠ(¦ ’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(©ζ[ψσ¨*yΏγΦίώόθ (’€ (’€ (’€ (’€ PΜ¨bυλIEQEƒΕ+1f%‰$υ&’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*yΏγΦίώόκ žoψυ·:έƒΑzΕΟ†Ώ·mbŠ{ ¬ξ#TI^½α\έzΑΦέwβxXˍ*d·„œ _ŒsΧ/UΡυ!£]RΖζΡ€ΞΑψτ―«ΊΥΤ—ΪΕνΤΧ&ξI¦w3”ΩζδŸ›olυΗj₯^ž‚ΓΣTΧτΞZ³u$δŠ(­Θ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€&ς?Ϊύ(ς?Ϊύ*j)‘ώΧιG‘ώΧιSQ@ων~”yν~•5‘ώΧιRΙmαι»·½-Hκcόh―‘ώΧιG‘ώΧι^νϋLΜ·o?ϋJΌ>€!ς?Ϊύ+΄…•γ/±}—ϋv_+g—ώ’-ΨΖ>ώέΩχΞk‘’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(ς?Ϊύ*j(#ύ―#ύ―¦’€!ς?Ϊύ(©¨ Š( Š( Š( €υ1ώ4Q@ΩϋLΜ·o?ϋJΌ>Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(Ω endstream endobj 132 0 obj << /Subtype /Image /Interpolate true /Width 778 /Height 92 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 134 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐ\ "Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊŠ(ͺQEQE=—ό}'γόͺ žΛώ>“ρώUQEQEQEO{Oψ*‚§½§ό?•A@Q@Q@SαŠI€ΓΘη’ $ŸΒ€E`ΰπh Š( Š)QYέQ³1ΐd“ι@ EOΤ’ΌqΫL'ήUŒ’ΏQΪ™<[ΈKˆ€‰ΘΘWR§ΌΠtQEQO–beΠ8ά₯”ΓΤzŠeQ@·₯ψ_UΤ΄‹½V }Ίuͺ3Ός0U;FH_Sτ¬J(’Š(’Š(’Š(’Š(’Š(§KΉIQ‘ΗUaƒM Š( Š( Š( Šthς8H՝@£$ΤΖΚθ ›iΐf˜W’Š) (’Š(’Š(’₯ŠΦβTέΊϊͺ(*)YJ±V08 υ”QEQE=β’5VxέUΉRT€~”Κ(§άΖdήX8ݎ3ιšmSž7@₯Ρ”0Κδc#ΤPh’Š(’Ά<=α½KΔ)wύ“ Ο%²‡x·€μ ώzτ  z)ΖρJρʌ’!*ΚΓHκ¦ΠEPEPEPEPEPEPEPEPEPEPEPφ_ρτŸς¨*{/ψϊOΗωTQEQEQE=οό}?αόͺ žχώ>ŸπώUQEQEέ|’‹§Ή/ώ‹jαkΊψ'%Or_ύΤ~ohΪ•Ά°4Mu=^iΰh ΖΑOΜžΈ„sU΅‚ΦηνΆ—¬φΣΑun€_ρΪižΡt?θ–WZσ€πά ˜Ž6Νέ‰ΰ“ψsY_εXx fˆτΘ\ν΄ΧY­xNοVψ§ψšΞkwΡ'–Ϊγν>jΰœ’JŒcΦ€8x‡UπχΔ/I£έ΅³Λ9W!U·Σ¨5?ΖΉ^}{Fšfέ$šLΝκK9&°ώ&ΘϋΧΛWoγ? jž2‹AΥ|8ήZ2(*”u,H ‘ύμ~€8Ÿψb-v=FχQ½ϋ•§ {‰‚ns…QλΑύ8ζ¬ψŸΒΆΎ‡^πξ€χϊ[Mφy±l’'Ζyυβ:ζΊO„·3.βMΟμŸΫ.c’ސ¬’•'rΰπz~ΉνMρμΎ#΅πzΑβ&¬MΜΰ­…ΌJ%mΏΖJ’λP>‘ΰύ"? Zλ~'Φ%ΣυΩ-cŠ!8$`;qν۞jχΖ;ae…-VU™aΣ1*Œpϊυ«³θ7~3ψqαŸμ#Χa–ˆLŠ₯70δδϊ(?CTΎ2[ (|)j$YDbEζ)ΘmΈάP›ͺ–`£©8£Lπlχώ Ώρ^Ϋ€VŽTΐίy±ŒσΨσΐο\Ί’¬u"‰ρšε¬΅k?Ω“™§[ XW€\Œ–>§§λλXώ 𡦽€λΧΊ‰±‹O³?—Όm9άp9' ΐMm|e³’χR²ρ%’tΝFΪ6($+§Πγ―₯ μSπO‹μ£‘#’an¨]Ά‚Ϋ›=²p?Ξ΄œctν·ζO‰<-§ΫψnwΓϊ”—ΦwΩζΗ±γ|gςΦ§ό%€7„μ5νkW–Ξ εx™μH$Έφ’kKYηπ·ΒΩtν\Η£}|³%ΈpΜ(δΰŸOΤU oώI‡?λςζՊ”šI>ΆΏ^4πΚhSXKawφν?P‹ΝΆ—fΦ#Žυδ~uΡΒ’ΪήΫhϊŸˆZ~αTˆRΡ£7έRίύqό«MBεžΜ\O<ΠZ°1Fς¨2 8ν^»¬ψVλ[ψƒiβm>ky4I^ —ΉσTΒΘ#9ΟΛώ4κJP²”­ΎΏ'‡ό!φίjšF§rmZΒdyw ‘§§9­ψ<£^Ig–΅rςjVΝ5Š΄d¨%ƒσΗOηψΟ ίA¨όDρ}έ£‡‚K ­Ž:0FG±ΕjxGώC??λΖηω5g:“ήφΣτl<π†βΦγΤ/5 Ρc₯ιθβm…ΫœαTw'¬x“Γ6Ϊ :恨½ώšΣ}žA$[$‰ρ¨λ[ nδ}Δ]΅:¬Β9m’Ή Ι.w.φ€ρ̞ ΄πšΑ―.Λν3‚Άρ(‘Ά+Ζ?ϊΥ£œ½₯ο‡φ>ΧjsΌ’iγν ΫŸτ~J{?•pšέ‹k{f4F{θΨώπΛ iΘΖ3ΦΊ…ˆ/-ΌK₯Η$ky{`ΡΐŽΑw·– C[’ΧR½XΦRΚΏ(QΉΊdxϊzΧ›XψZςοΖ'ΓͺΘ·+3DνrK}03]wδ·ZΧݟώΙRΨj6ϊoΗ+Ή―$X‘{‰b21ΐRΚ@ΟγψΦtε(ΓGvΰeOΰέφΧR_k’^κ|m,°ΛA"―ή(ύΦ°΄}; kš»Nι&œbΫPCοlr{W£ήi–Ί₯ΕψΠτΫ’e[‘fpx Nr}λ˜ψqΥΌ5β}cKϋΘβ’έ€σ 1$ ώŸ΅8Τ—+wΎίπ@ηντεπ5ΞΌgq,7‚ΤE‚ ƒœώ5§’x_J„fsΔzœΦvΧ340$οfΖrIνΘ<{{Φ¦½§Kα†#IΥZ8υ;Ϋρp-ΥΓ2 P2pO§λV| ŠSΒΡKαηΣυk)$a.pŒ-ž§qΟ^|Σ•FβΪ}@β|U₯Ψiw±.“ͺE©ZM‘]F3ό.;Ελβ͍…–©§‹[kkKι-ƒήΫ[Ηžƒ;ώB³΄ΟΟΰ«₯νΊEhεL χ›Ο=<υ½)sA0αwόz_ΦOύυ»«έψώο%˜έ%’,Ε#ΐN}½+ αwόz_ΦOύΥ‘©ψCΖ ΧNρΞΦδ³nΤ‚Όφέι]Ώ.‡4νν5Άέ~f/…τuψ/‘†ε“TŠ?2Hf¨Ο―ψύiڏ‡“KπΝ­ώ‘;Η¨]Ά`΄Ϋ,Ηρ7§\{Υί‡ΊzΗu/ˆ/€xtν3η,§I; ϊδgκz»γ•$νόScΈ¨ήξΫΌ†φ9ύG©€’εΏRœί=―§υ‘₯xsN] ίUρ€φp];%ΌqD]› ΝA«xcϋ?Δ:mˆΊΩߘš ”\nGlgΏύjμtyυCΑBxv »«C$WNˆΜΉl‚7cηŠΗΧfΎ>3πύΆ§sg5ΕΌ°ƒͺmXrΰμ=³τ¦β¬Jœœž½Ηέx7DΆ[©%ΦnvW"ήηχεΎξή3υ¬Λ«xωό;5Λ±2¨Ξ<½γ¦+wΔ?ςρ‡ύ…bώf―§ό—gwm…7‘*rIλΡώŸζs£Β]έ‘“¬΅Φ©cI,F¨Αz…'―β+Oιsά8H’α 1θ£=M-š{½υ%ΈΟΘΣ¬Χδίϊ­-EџIKύsYΒW)Ό ζH1όL;ΒψΣΒZΌϊΆ¬`τζη,ͺ~V|Ž3žγ΅oι–7Iα-"o iΊuδ²+}ΆYΥΡψΰξ<Ώ§β”uwQr+3‰ρn‚4Ψ‘uisž ‚γrQλ]-ί‚τ+ NήΒ]–+›₯C 3άΗ§'"™ρc~νΝhZO°ΖlΞyΫŽή•Wβ«2xͺ&BU…¬DpAΕ6’ΈFR’޽ΞQΡ.,|Fϊ;•{2Β¬:6μm?ŽEz'Δ1†οm­TΔ†ζ(†?癍WB?ψνrίMOΖ°ή_Ν$ίfFΊ–IX³‹€I>‡oε]‡u»έλ:dJYO©ΫΘΝ(™œΙ ΙŽδΡ[Ԛσ'Ψδ<%αθux―ο5³g§X i€ Ή‰9ΐπώUΠκvvVŸ .?³/Mε€ΊŠΊ»FQ—ε«QΦͺxΨκΎρ‰ ’ίΞ"’(άγ~ΖΙύηVυ=γEψ]=΅ξΕΉmAdxΥΓyyP$qœ ώ4% ε+ΞΝυZ:o†tΤπνΎ«―κ’Y%Ϋ2[€p™ ΑΑcνΗωΝ[ψn-“Γ–ι"Μ#ΣΡΠpψΰυ«rθχ>(π.ύεΝ=–)β2*•άΐδδϊƒβDbΒO Feφ1δ<6ΣΤN(jΡ+Ν]λ‚Β€Ϋή[ιZŽΆΠλSͺβ4€΄hΝΡIξOαX:G‡žηΕι‘^Θa5βwAœδg·ιΊ±Χ5 f;έ=&]*uIςXγ&,ΔόΩώ«‹π½ΓέόT·šiβΈ‘2ΔΈGΒ0Θ”άUΠ‘98·~„‘ψ7J»{λ 7Ziυ‹Uv1J£m8*׌ώ•Ζiχ·:uμ7vS<7°tu8 Š΅uqg―_Ki<°KηΘ7Δε[[M°ΊΤο‘³°…ηΈ•‚ͺ ΙλzΝ΅Πή ­έΞΧγ PKͺι:½ΌkΥtψ€ 1—=OεΚΈοΎ1K :Ζ•€@κΩZ|V²s‡‘ωm¬oψNoκsΩΑw ©Š)isΘρλΪ‘g5EIu ·Ή–efΚ§ ΰγ ϊTt€(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’ŠžΛώ>“ρώUOeIψ*‚€ (’€ (’€ (’€'½§ό?•ASήΗΣώΚ  Š( Š( Š)σΗεJɜγ½2•£`ΘΕXt ΰŠJ('''­Q@.φΨqΨvηŒQ@Q@ΰδS€v‘‹HΜΜz–94Ϊ(UΩCb ’’Š(C₯A;O$gƒIE·₯ψ£VΣ4‹Ν.Ϊδ>ι$‚E £pΑ+θ~”νΔΩΎΦ΄―³yŸΪB!ζω˜ςφ1=1Ξsκ+ ŠM)hΐVfc–$œc“IEΐ)C₯A;OQšJ(’Š(₯vgbΞŘχ'&’Š(’Š(’ŠRμΚ±*½=)ΑΘΰΡE+3;rYRNM*;Ζs2ŸPqM’€ PΔ)PNΣΙΰQ@Q@Q@ ¬Θr¬TϊƒŠJ( ΅Ό)¬`kΆϊ‘φ(0ςχνΞTŽΈ>Ύ•“E4ν¨šMY–F‘Ψ’@,[nx¦QE!…(f€H¨­%QEQET‚ t"‚rry4Q@ pHΘΑΗzJ(  ΑJ†!OQž %P[>ρ.§αΤ»Dβέξ•Qδ θON΅E:YYI]žG%™˜δ±=I4ŠΕNTzdJ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š({/ψϊOΗωT=—ό}'γόͺ (’Š(’Š(’Šžχώ>ŸπώUO{Oψ*‚€ (’€ (’€ žχώ>ŸπώUO{Oψ*‚Š( Š( Š( žρHЬρΊ«r€‚ϊS¬νήξξ xΉ’gXΧκNzΔ!‡/m­TĊζ(†?癍WBγώQ)ς΄ŠQΊΉε4ο-ΜfMεƒΨγ>™ƒΒ~‡WŠϊσP»6zu’š@»˜“œ?ε]§geiπΖγϋ2τήZΛ¨««΄e~@ °υύh•DGKž{Oςeά‹ε>\eFΣσoZκ΄ί i©αλ}W^ΥΙ.Ω’έ#„ΘN n?Ξk£Χ1¦ψ£ΐ責©Eζ/F‚δ~4E{ Qξy—•&Ζo-φ©ΓοHρΌd ”‘‘Έc#Φ½VϊΜCα―Ω2όχ7w71»ΔGώ…\ŽΦΞO%ž‘pφφ–πE Θ‰Ό#ΘΐοΙ£W™μ7 ΖŸwmkΜφΣGo?ϊ©Wϊ­]§Œ­V θ²Ϊjχ7ϊs΄‹Kΐ›xΰuυ|4Ά₯Φ¬δ»Ό•5Ÿ[ˆ·,ƒovνίς§Οξσ —[e9£uEvFίuˆΰύ+©ρžƒΕό–:œςίύ‘·[΄TΗpέν[³Ωi·>π̚ΝϋΩΫΖfQεΖ]ά—νθ&‡SDνΈržoV>Εu>Σί³ZΎ.ΠFƒ Cp.m."Yΰ›ά§ΤW£xΚOΉ ΠEΗΨ6&݊„gυη­)TΪέAGΉγu*Γ¨#RVν€cVρKCβ+Ή ši rΝ΄edθ2:c#€ž {?ν‰΅ΙšΦΟOωE\™άς‘sκόΗ½[š[‹•½ŽBŠήπΎƒ—·W·bΟN²@σK°±η ׊Ÿ^πυΎ±’ί΅ζžω$cΖψΞ―ͺŽu{+΅ΞjŠο,Ό§ά[Ψ«κ’Ε{yeφΈΠΓ•\ œœτXž%Πνtϋ}.σNΊ’ζΚύX£H›X2Ζ’©μ†βΦ§=OŠf$EΘG]ͺN+Π.Ό’Yλk₯]k²₯δϋD Ξ ιΈτΙ9γιλ\Ί^jΎΥο­¬ξL£€d†ρΤ~4)©| γmΜyb’Ϋ*:63†4Κν>*JσκΊL²Άι$Σ!f>€—$Φ'†τ«=IξdΤ΅(¬--Σ{³rΉβ…;Η™‰­lcQ]>ΏαΫ(4H΅ύο,LΎD‚Hφ³ΦumRKXf‘£(‘obA Η°'&h­qς³­Oh—ˆo~Λ€Z΄ς–9Pz±< ·βν=K9m.ΎΧa{›»v’8Θ#ρtχ“Ά…π{J[δΟ¬άHΧ2' θŒ@\ϊpΏ―©ͺ‹RWD΅c€ΎΆ{+λ‹YJ4HΡ1C•%N§FκŠΜŒΊ85oEΉ΅³ΤbΈΎ΅p 'Ι'›n}³Šκό_©M«x3FΌΉ${‰FΤ\*€H`+EΣw1GΖ6Ρυ8z(’ Ψ(’€ ’h’»ηπV•og₯^km±6ΡIAŸαέλŒγ―X?πΙ?Œ€ΠlεάΛ3F%qΡTXμ B©S‹G?EvsxWJ»ΆΏ]X{»ΫΪY"’‚E_ΌTϊθψim₯K­YΙwy*j >"·nYήνΫΏεC¨¬ΪW{eM­Δˆ8%u= ‘"Ί_Ωθ1\_Ιc©Ο-Ϊu»@UAάw ήΥΣi­βψ{ Β3ζω›ησ|°§1±χΏN¦‰ QΦΗ˜Λ °&γ'¦ε#4ΚίρMΖ΅.‘oŠo5*¬ͺ!<γv­fπ3Ο¬iριχ&m&ξ/<^ΐD{w‘ΧλO%¨rίcŠ’Ά¬΄dΥ|NΊ^‘9’ͺO"γ*K`} …lΝα]*ξΪύtaξοlcidŠHJ ~ρSλ¦ζ–βQlγ(«Γ~ΣοτFΤ΅+ι­£[΅΅Ϋ{³ύOδ*Ζ½αM?KΤζ΅ΤβλM•ε [Wkœ.zς3ψφ‘½‡Κνs₯Dg`¨₯˜τdšμ-<1₯'‡tέ_VΥ€΅†θΊ˜μHb1Ϋ’MRρ™7„υ‹;6σ͎HΦζΦδ. ؞hUvAΚΦ¦ΆσB‘₯†DRq–RE]ξΏͺ^j ­.uΜσiνή@ΫŠγt‹!¨κPZ5Δ6Λ#`Ν3DΙ$Ÿ₯8ΚιΆ&΅Π©Ev―α]φΦόh:ΛέήΩFΌoΥ‘W©Sλώ΅›αΑ[j“\ήύŽ;(ΦRϋ7 Όδ‘Χ€: ^6Έω^Η9SGkq"Ž ]OB¨H—XπޞΎmcBΤ^ςΪS¬±ld'?NGη]½Ηˆ π‡α[’ΔΟηy1γΜ8ΞAΗzN¦šsΝ%†XHFρη¦ε#4Κέρ5Ξ»uym‰ ΐ™GξΔΡ„!IδŒά~•Σ]x#D΄ΦΖ“sΚ·³cΘA@$qΈτΙ9γιλMΤIj·ΨσΚΫό/ͺκZEή«Ύέ:Υήy*£$/©ϊV~₯a.Ÿͺ\XΝƒ,2˜‰ λγ5ΛYjΦ~³&-3NΆ@°―Ή,}OOΧΦ­jIηTWUΰ E―G¨ήκWί`tτq0MΝΞp~τ㚳β i–ώMwΓz«_ιώw‘*ΛΙ#oκ:vξ:ΠE{Γ­?ΓGΒϊσ.«pςK§··?θάΕxω°sΣΌχΔVž΄»΄&§ulίλΩαςΩ9w=xΝ`ΥέLŸXΥ-τϋ3Ϊ'%SΜm œŒώά7ΓgΈΧτΘτ»³q‘ίCφ‘~T-7ξμΘόύpϊΜVvΪ΅ΜZ\ς\YΖϋb™ΐΐώ.;g8φ Y―΄[η³Υ-€ΆΉQ’άz‚8#άUΏxoRρ ]dΒ³Ιl‘ή-ΰ;„½+Φη:Β+ JρΌέCM½6^s}ζŒ@'ΏUό«ΣοntλΨnμ¦xn!`θκpA ±ΌRΌr£$ˆJ²°ΑR:‚)΅ί|aŠ u]'W·c:ŸԁF2η©ό±ωW@Q@Q@Q@Q@ΩΗ~?Κ ©μΏγι?εPPEPEPEPχΏρτ‡ς¨*{ίψϊΓωTQEQETχΏρτ‡ς¨*{ίψϊΓωPQEQEQEu_ νηΕΆςˏ&ΡεΙμp2+¦πξ·cβK½gL‡IK)υ;y₯3™$# ρܚςϊ+9Sζw)JΗqΰ{sͺψgΔZ$.‹8ŠH£sϋ$ ύηV΅-"γEψa=΅ξΕΉmE]γW εε‘Ζp3ψמ‚Aξ('''­›½οζΪ…&‘sβh?Ψώ\ΣΨbž#"©]Μ''ΠψΤ_‡φmΗ…ΒΘ²}šΚ,:†ΪzΚΈ0ΔgŒπqή’…M§ΎŸζΪγ¬y'Η:f›‘²ξδ·ύ΄ηd―8ρ%ίˆ<ͺ[iΡ‰wP»‚δ ΑδœvVŠP₯Ι³ΟQΥό­άx+AΣβ³ wjσ4©ζ ΪΙηJγ<*XxΗMk·X–9φ»1αO#“υ¬)Ζ &›άNZέW<1ͺιΧwΪ•Μ,eΉb’¬ŠwbGΟιSψ›ώI„νγC:Š|―K½‚ϋΨμ| Ο Ψ2?δ+§ρΧ‡|K¨ψ†[!f6+r¨2ž ςz*}›V³Ψ9ν;ΓZ…χ‰Ξ‘:˜ξU³pΕƒyk՘‘ΑλωšνυΛ›Oi—zN“$­s€φΑŸwΪΡWksΧάzšςͺ)ΚM;μ VΠοώ\ΘΪNΉ§Y›ν)Dr[ΕpY “‘ƒΖΗΪ“Ζ[xi`ΦΝiηΜ³‚5ΫΖ+₯f,Δ±$žδΡμύξ`ζΗ«ΩΘKΓ_φύΧ-βωΌo_ϊ1k₯S΅τ9€©ΩήΦΏζW=wΔ~½Τ>"C©[šΞ9!yάΘ‹`RAΟ >΅η^3ΊŠχΕZΕ³‡…ζ;Xt`8Θό©ξ€ΈιιXτSƒVo°ε$φ=#ΔώΤ+Y9ÁΘόΆΧN–G–G’Wg‘Ιff9,ORM6€ (’€ (’€ (’€ (’€'²€ό•ASΩΗ~?Κ  Š( Š( Š(  ογιεPTχΏρτ‡ς¨(’Š(’Š(§Ο'›+>1žΤΚ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(Ω endstream endobj 133 0 obj 28789 endobj 134 0 obj 9973 endobj 128 0 obj << /Font << /Font2 12 0 R /Font3 13 0 R >> /Pattern << >> /XObject << /Image11 122 0 R /Image13 131 0 R /Image14 132 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 135 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 136 0 R /Resources 137 0 R /Annots 139 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 136 0 obj << /Filter /FlateDecode /Length 138 0 R >> stream xœ΅TΝn1^η€Τy n(©ΐυό$. @$$$K=PΠDhΣ’Β™+oƒxNE<GΞy fv»ΩMhA%ΦΖφggόΝ|^‚Υ€έihˆϋW X‚ΡΖΨlvlΟy“t πb0yέOœ‘ˆ2¨ak"s8„v²„ƒ{υ»ωΤΐμ={pςΕ„ή²νMNΖgg³r5‡γ}xΞm9πdOMγcmLd5b‹δ…v‚9ZΧX=ΐ=΅XoΫck—βΤ§Žέ~ΤPΫM€Η ‘ΝΔ›΄υٚΨρŸ£#Μ<Μ»‰)J’σδ2Jπχ ŸQΞΰΰΡιΙΔε— oζ5σGN„&­Ό†0ξN ‘j\}USUU« Ό„ς–λτn“ΡΡ!Ÿ΅Γxε­x»„±?e­wr‡θrδ{FI ’™{°€Μp΄\ζΡΞzˆ Κζ~ΈίTΎΛ$ΕΕ& Q£'sΨaΕ <^Lgo,ΑƒΣ5Y—1bMbωhc‡ν²·‰ΦΤ9ΎΞΊ>`ξ`εΊtΜ`Fκ+Θg'Δδ]V=3α*ΜΨl‰#γβς&5Zw–K{Υ=DΙXΧ*ύΒGώ^η$/›ρό¨£ ‰Ÿ΅υžξΫV•ZU…šφ¨Γ¦€GηΥuƒε|t4ϊΚθΤGυTνU?½Ιΐ³ ψ܈~₯ ―άV·T©VΌRԞϊ4αΫΆ«£Ο£oƒ‘#q#Bbu.B”ΌΙ²ζΥU/ν·]I’ endstream endobj 138 0 obj 573 endobj 139 0 obj [ ] endobj 140 0 obj << /Subtype /Image /Interpolate true /Width 1072 /Height 126 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 142 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐ~0"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊŠ(ͺQETπΗ­ΗόωΤ§>ύ)EZ]6ω™ΥlξK άΐDί(υ™§CΣ0Ε$Xͺ“΄{ΠtSž7Œ)te 2ΉΘυυ·‘i– K՝£ρ ¨’½Y΄xv+mJΟνή$Τ-‹όΟ„³VSŽνΧρ§p>’žΛ"3Η²&72© g¦iΧΣΫ0[˜d‰ˆΘ)RG―4\¨©’΄Έ—Λς •όΓ„Ϊ„ξ>ƒΦ£–7ŠFŽTduΰ« ψQpEL–—N–σ4+Φ@„¨όzS"ŠIIFξ@άBŒΰzΡpEXk΅2n΅œyjσωG©τ hς8H՝ΟTdš.h©. šήCΔRE κ₯Oδk{ΓώΊΦ4ύRθ!VhU0“ηuαO“’Š»’§{Y’–8ξ"’"ηz‘όλwΖ^“BρζŸiηέΓl¨Ν/—ΣrƒΞ:u£™^ΐstQSMkqhσA,hu τ'­0!’ž±HρΌ‹΄iΜΏSځ†(Μ@ν/΄ΰLΠ(©­­..‹ X%˜―$F…±ωTr#Δμ’+#©ΑV"€E£αν&moXΆΣν™VI˜ΝΡ@“ωMj&μΜκ+ΈŸΒMΤρθ:Σ]κ(I ΒT8^»O―ϊΧ4Ž5fsΡTdšn- 3RΨJ*Iΰšέφ\E$OΧk©SϊΣZ)ΩQώλ€~•% ’œρΙS"2†RΓ’ž-n%”A)ŽΥp‡ϊλ@QJθΡΉWR¬8 ŒRKm<(―,2"?έfRϊPTWAα?G¬­νΝνΨ³Σ¬<σmάy΁«!π坋±’j {§ΌΎKοcΖψΟ#όφͺεvΉ7ε9z*hνn$ΩεΑ+ω™Ω΅ ݏOZŒΕ —Κ(ΒLνَsιŠ’ΖΡ[Σψfκ/ Ϋj HΝ4ζn";—όΩό=+ Dhά€ŠΚΓ¨a‚)΅a)'°”TσYάΓ’ky£ŒτgBόj°ΰg“ιHbQ^‰ρJ @‘<;¦hρ$±$rΆ ΞL’dώΌξ€ (’€ (’€ (’€ (’€ (’€ žψυΈ€:‚§‡ώ=n?ΰ?Ξ€ ’Š(’Š(’Š(—α§όΊύ|­sUoGΤ&u[Kϋ\yφ¬©»‘ ηΪ€/xΧώG-{ώΏξ?τcW‘x`λZW‚4πšΖαΛk—i£šA™ξ†z° Œ Γ1β_θzά7’ Emͺ\όΖρ/\αΙΙm›@9ησ©mΌi¦\ψOΣΌEαυΤ€Σ”₯΄«rΠόΌ|¬δp?*`h|lŽ7½Π―ƒΓ4χv ΣOΒLGρ,We΅>΄ϊkψ'Δϊ}šΕ Dš=Λ/Uυ9ΰqιΑ―,ρ·‹?α'}1’Β;c…R7ά€˜άΦτ~<ΠdΊΆΤ―|#nϊ½Ύ²ΓpbŒ²τm€c―Φ€9λΝg\πχ‹΅;˜ŠiΊ£;Η:ΐ‹΄d‚@#€kΊψ­γ {JΦm-l5†ήm>)$@Šw3nς;βΌΏ_Υ'Φυ›½Jθ(šζBμ«ΠzτΦίψγLΥμ ]sΓήj0Ϋ uΌ[Άˆΰ P9δη­ 4Ύκo£xΔڌYέmsg&ρ(ΘόFGγ[ž?Σ#Σ| ―΅Ά ₯ξ«μt)")ό·nό«Μτ―}ƒΒšΦ‹φ_3ϋI’>w™/cnϋΈη?QZšŽ₯Ώπ―†§³Λ[•ΕΧ›ΥT£fήΐΧ΅0/ψΣώI‚l\θb΅ΌCΖ§πΏ?σνi‘%sΪŒμ πμ:'ˆtTΥl­δ2۟8ΔΡ’I# r2OηήͺkΎ2ŸWρ^«ΙiPX4^E€mΒ’6ν»±Τϊγπ Lρˆυ[{K Σ,–Z¬1[ΆΡϋ΅$ωόΟ­g,iνΆ5  z›LŸΤšβuOύΊΧ]‡μ_φ₯δwyσ³εm?wξσŸ^>•#xη?G‹?³ΏνΧΟ¦>_ίΫψτφ  όE¨x-Ώ΄£ΆΡuΤ ‘RVΉΚ‰2~b3Σ=«'α§όΊύ|­iέx§Β—s šLΪrpΗΎ6ϊΧ%£κi:­₯ύ<ϋiVTέАsƒνH ή5‘Λ^―ϋύΥκZFν#αΗ‡Ζ™―Yh3^'šyΣ-9 ΐθzε\G‰|W‘λpήH<)Ά©sσΔ½s‡'%ΆmηŸΞ“Dρ…Œ~ƒDρŠΊ­•³΄–쳴ONHΘκ2O₯0:]ιΊ‡ό%wayiwxς[₯μΆΓ ς,‹σ~9ό€“Δ#Υmμ΅εϊ―ŠΦχΔΊn₯›oii§ΌFHpΤ`p[“ŽΈ«:§~έkΓφ/ϋRς;ΌωΩςΆŸ»χyΟ―JίρMޟ£|t–σQ60Ν²»°L*wcΎ†ό+£Υ.|A¨Ωλ3θ~"|E§K΄–2 Gžs8δώ―:Τ.λI›ΜRa'Σ=85Ύ=Ρτθο¦πο†#°Τ―"hžvΊiuΪΈΗεŠσΊ(’ήρV‘α;ι΄ΕžXό¦Y°ΖAμAΟ΅”²Λs© Ά$“Λ.ύ€ ¬ΔητΝmxΔ~Τ¦ΉΏ Υ#’IqςQG·NžΔ’K™%Ž5‰YΛ*/DΙΞ€=μώ2’{αόŽW–x‘n—_½…•½…Πή[[¨Xγ8(€?«ύ£}?—?χυΏΖ«Θο+—‘™άυf9&€^πίP›JπOŒ/mvύ’·1–PΫ[,`ρ‘œώηθί οSOπO‹ξe·Žζ4ααΰH₯˜νΑ<Φ5υ‡Ν~`?RΥ.ΌIπž{ΝaΕΕε– ±Ε9PiQp?ΪώU2λ·ϊΒ] ]*o³άKu2B‚Αw1 ddγςwĞ-ΆΏΠ Ρt])4½9%σ€O8Κ>1Ι#όΰV}χˆ>Υα 7Cϋ6ί±Μςωώfwξ'Έγ―­B€ΪI­/{₯βο[xM ή)SHΔ³UœŒƒώχaΦ»}{ΕZ–ρ.ΟAΣΚC£Γ%½·ΩV5ΪκαsΫ?Εϊ}kΖA ‚ο^ŠΏlεΈΆΤ΅[άλΆθ/<φPHθΕ1Œ‘Š*R΅’WZ§αΨ#Ύ&ψ΅,TDΩ\Όj χ[zV‡΅‹λνGΑ°]άbΤlgϋX`?}΄67zγ©υ―-ΡόY=–·«j—p ©υ&…ΐ}L„r8< tύjφ‘γμλίάgωŸΩKί;nπyϋΏ.3οQ:2}/§θP,ό3T·΅Υυ >]6ΖE‰υάζ{'ΉΘκ=+{Ζe΅†_hΎΥmu›»[ΰ‰wγj•εΧ?•qΎρDV—₯jšjκ:]γ+Ό^i•‡B}εV5Ϊ]xZM NΡ#ΣνLλ:²Ξ\π9έ‘–'Χ>ƒR„KΫ―—ό8όa$ΫΑGΪηC'Δ ε΄²πEΕ»˜η‡L†D`9V ώuGBρ}œ‡FΧτdΥ,­δ2ΫώψΔΡ’rF@δdŸΟ½eψΓΔsx—SK™ Kha‰a‚9 θ3ί―Z¨Β\Ι5’Ώβyγ z?†Zf¦šŒ‚ϊ[η‰εΨΉ*`cμ+α‘o|I΅ΉΥΘΊ•·ΜΕΤ|Μ¨pHιΗπͺZ‹mm)McF΅[TŽBΡΫ3™TŒ,y<Ν%I₯(₯kίP;ίψŸQρ}ΞΏ¦k·RΩM2DΘ£Ιe# gŒώ•δυήέψςΚ+=@h>‡MΎΤΗqsη™8n‘F3ώEqϊ%ςiΊΕμ–ρέ%Ό«!†OΊψ9Α«₯6νd*φ9ώΟ‘iΈ?0³΄΄έμ.#ςS^wγmvψ‚mFήΕ,cuUς”η8IΐδΤσxͺGπu¦„ΆϋMΌΎgΪ<ΜۏVυνUVV±Qv6~%Γφ ?H°l–ξR=wLqϊTΪNΉ©k> ρHΤξšΰA^εnXη φΟψΛΔίπ’κ–Χoh ŽΔ~W™»wΜI9ΐΖsϊV­§Œ4KK+»K ·» &O·Ήή’9+‘Ττ¨ε|‰5―όυ9M#U½ΡξšγMΈh&d(Y@9RAΗ?A]οΔ?k•΅½₯σΗ ΆQ»¨U9-œžEpZΕΝ₯έσK§Ψ‹r‰L˜=ΞγΝt7ž+°Τ¬a][AŽκϊ( t·-pJΟ­T£v₯a'dΥΛήΎ—MπŠ.νΆ‰’$΅‹qœώΊž£qό47z›‰ξνoΔI16 ΰγλϊ ζ΄½oμ:­¦}ŸΜϋ—ϋΝψςφτΗ9ϊŠ"ΦόΏ O’ύŸ>mΠΉσ·τ·n=Ίζ“‡½{um,u>Οό+ΏΏΦy6ωΗ]»Ÿ?¦kΟ«©ψ}βHΨͺί ―΅Ψ5‹‹_[[^˜OŸks.D_\‘Θά3L‹VΦ―υί‚σ]j­ζ\.€±ωΕB™(Α88Ξ? β<ζΒo ω9ίφΨsξοΏLΧ£|CšξΛαΈ°Χ!Σ¬oζΎ ocdXβ θ οž}ΕrώΌπ†l“Δ· {­€βΧOEΐΊv<†€1Ύ#>;Χvck~žΉηυr¦½Ή–φς{«†έ4ς4ή¬Η$ώfΊ]/ΕVφ^Τ4`šk—ή·eΉ^±ΤcŽG_Ν…ςώ£qm»qκsœΤ>2ρρ.«ηΩΎΚ©ŒFrIΞRjcNJZνύXnJΗWβ›2β.£§}qi3΅Ί[ωQξάΕr{sΞ±¬΄{»_ˆc§¬WΣ[HX5ζvο>=3ωβ­/ެεšήPΠaΉΦmΤ*]yΕA#£Ζ3ώx¬M#Εv&—Y‘yf-ηFxW Τ{vό©Ζ3Jή@ΪΉθz}ΕΖ§·m©λΪ~«–’ΏΩΰ\ωl:8θ>Ύ•ΗxkώIχ‹>Άϊ>ΣΕϊ^šn²|<–i…βvk¦f½ ιߊΘπ·ˆN†ΧqMh—–7ˆ#žm»€Ξ='σ€ zv$jZΙ(½°šθ Z3κ·ΎψαφΡ€ϋ;έΙ+Ο2¨%Š·δ΅ƒβΓ₯A₯izriϊlRy¦1!‘ρŒ’~΅³ΰ‰όCw‘Ιi§ιΊ~₯c ΉQxωNyΰ=sNKKΎΰžΆB|Iv½ŸΓO2ž{ΛͺŒm,yΐόkΥoŽ•βHmβΧτϋ2Τ"6žΙΙLAωzx3βΟ›¨ipI4rή[Ω’\Κ²dδqώyγ=>ξX/u_ΓwͺΒ‘DώyUr:L`Τς9Eiά|ΦlηΌB,‡‰/NžΘΦ&rΡ”ϋ»IΞ΅u_·ΒΐΈέžD[>›{~9φεο/&Ή”"Ό\„]ͺ3ΨΒ»έcVΡή¦ŸΰŸάΛoΜh-ΓΓ!ΐ‘K0#Ϋ‚y¬oxΆΪ@ƒEΡt€τδ—Ξ‘<γ+HψΗ$σ\œ­Τv]VΏ$DΊνώƒπ—B—J›μχέL†P °]ΜH8ό«Ÿρwˆ-ΌW&„€b ي*‰NFΑ{°λY·ή ϋW„4έμΫ~Η3Ληω™ίΈž6㎾΅„ pGzΦ’|Νkv³kή*Τ΄‰vzžR-νΎΚ±ΧW žΩώ/ΣλT|;zWΔί₯Šˆ’+—@α~λ`JΜ_ˆΆrά[jZ‡-ξuΫt —ž{($tb˜ΖΘΕsϊ?‹'²ΦυmRξu>‘ΠΈ°)ŽGŽŸ­cRεjΦή z—‡΅‹λνGΑ°]άbΤlgϋX`?}΄67zγ©υOαTImαjqέ[ΨήΔ"†+ΙΧ+brzΌ~•€xγϋ:χΓ·ΩώgφDΓ·ΞΗ›Ό~οˌϋΦw„|Lt·Aqeώ|.-ŠnΖpC„dΣφ2I€»~oτ¬ρ­ύ₯χ‚C]±Υυ›{ΠΝ αό’0Tπ;σψ ›αη‰υ‡π׈‘οœ¦§fΤm_έγžƒ­r>"ρ…ζ—™’h°ι–k'šμ_Ν–Fχr2΅Cΰά]ω–qίYήB`žέΨυ>όγΏηUμ―NΦό€―ͺkϊ¦½yjϊ½Ϋ\ΌGjUA#=―UρG‹u[Šφz]¬Α,h"–‹‰<Ν ’qœΰψ ς­{RΣ//-ε4q₯Ηωγ-6σœη,8«ΪߊΏ΅~xΟΆίϊ%ό‘GώΒΛ -dx;ΔηΓΝ{ φqίiχшξ-Άξ8 φ#'σ«'ρ\Žo£hϊbišT2yΖ1)‘€|c%ΤΥΈKšΦιΣx/YΆ> ‡KΣuθ4 Y.Y€YΑισž…s—Z΅‘ρΩΙ1·+«Qςά&xb{ŸΐTz7‰΄˜τHtΝwΓΠκ Šxε0ΙΙ΁–λλTόcβSβ+‹AœvVVpˆ-νΡ‹lQκ{φό¨Œ©{wμ=]Β_ωμά“@5—β«{/j ι0M5Λο[²ά―NΨκ1Η#―燑j“θΊ΅Ά‘k΄Λ dθΐŒ~ šκ‹³L‰h΄Ž—ΒΊ—«ΫΚTΌƒUHe–HR<(U?ήχ:>¦£Ά©}c&Ÿg’ΖχχyΜ9μžη#¨τ§\ψΚ+{γ’θqX^ί!I<βψсŒΦg†ΌG›¦ήiš‚ίιΧL£σ l¬;‚>ƒςͺΌSFMM§tu^,-}πσΟΌΤ­΅[›{Π‰u γ W•<_εXΎ)‘Β?Kύ U]WΕ6·>“F°#±Ά3‰”¬ΕϝΩ$ϊηπ₯ΡΌSk‰“­ι)©ZA!’ޘ٠9##¨Ι?Ÿzm¦(ΒQIΫf[ρ²πŠ1ΐ:l@ŸN•Τk:φ£§όF°ΡlΐM-–ΨF6²œeΊgύ–ΌοΕZτΎ ΤRβHRή£Γ ˆΠtοΦ½Γ“ψ›PMνε†—φuΨ[R“oδδgœδ3ښwnΔΞ<±\ήf6™i ηΖK€ΉE’4Έ–M¬2 Hύp ΣώΥ†βίV‡^ρ.is ˆΰU Η'π•ω{…qz–ΊΦ>>ΌΥτΗI6];!<«©Θ?«7ž*ώΟxΪg‡ ΅Ύ»R²Nς™BgΥ#RHn›v~H“ΓςNΌWο[θt–_ςIυϋ /ώ€΅—α_ ήC=’^Ψ^ IΰvΫ»Α·SVxhι’ωΚΣ”(,9;y ΗεTώ!]HΣxoYŒ―糎wueΖlžΥz]JΚΗΐMOMMBΪC91™ l¬²GΤρήΉ/xόA}ΏgK[x"Α„Qοޜž–ΏbiΖς½Ί³²½ρV΅ΓΝ;PKχ’ή!„+nJΪJ|Ε F6’zυλIΚφw*0΅ΥDΤn5«λ]Vm'\Σ΅»#v{GP8ΟpΎ {ώ#αP :jΝ/˜62›6χݞzϊVρ†™eδš'‡Κϊκ6¦7 αuΪΈΗς(HΘτ₯7q‹ξΏ―‘άόhϋGό'·_hςφyQω:y{xΟΎs\5zΕ+Δ/ˆt½ai8›OxΚȘŸOσšσΚƒ`’Š(’Š(’Š(’Š(’Š(©α[ψσ¨*xγΦγώόθ (’€ (’€ (’€ *{/ψϊOΗωTQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQETπΗ­ΗόωΤ•ͺZίΪmσν€&ρ‘{Š@Wžmεh#x₯_ΌŽ₯HϊƒL­ψ‚σΔΪ»κ:ŠΒ³²ͺm…v¨§ROλYWeaΰθn―tX λ¨Τ-MΓƒδ gžk­«κχFΡﲄΑSψH#Ÿ^΅3R R Ž¨ΝΈ’³$‚—Ι—δύΫόwε?7ΣΦΊO6ϋQ³?ςχa4@{γ#ωWo 1™τ=Κ1’ζ9ύ»+ηώϊ¦U9]‰•NWcΞ΄Ν^hZ½ϋJΘφ>^# χ·69τ¬™‘– 4oH8ΧΑΪ„φ~ρMτD}‘L,¬@8bΝσ`χηπ€ΤoηΦώ­IΌλ«kο)% ΪTqυύΝ7Ψ9Ϊo΅Ξ2%ŠΑ’0δ„ROιLΨΫφmmωΖάsŸJο΄FΥ4 ZlΤtέ έ€I:~zž«όEs§£jK]ΙkΝ±{k©Λ₯λVΝ”‘»=«¨gΈ^Δσšη<;"'Š~Άϊ ¦—©us”ςάΖ_cl±Ζ}3NKy€)²έΒ“»ιλ]M·ό’ϋΏϋ /ώ€΅₯u­^θώπιΣ€ςe”Μ@ ž9 ΗεC›ιάno§sudb₯XpA"’»ˆn.—CΤnnμ•ζ*1Ή½Zγκβω•Κ‹ζW4΄K}2βY­{%œarŒ‘7N*Ο‹thtKλhmβ)νΦα]“iΓŽ? Δ³β7ό~θφ ‡ω΅KΊ’Ί’9DVv ŠY@I§M °>Ι£xίΧRλ]_SP† JφΙμ-"T½νήsžΙξxνιZή'fΌπžοP·Τξ Ό—1.RΌ©ΰœRs΄¬'R±ηπA4δˆ"’B:„RqωSLn$ςΚ0“8ێsιŠοlτγσ‘Τi'a:$μyThς8X՝@£&œΠJ± Z'€εN ϊΧgΰΕΈ_‰ˆ/!Hn|ΙΌΘγUmœ{Uο λ—Ίνή΅§j,²Y5€¬μE·vΰv Ϊθ›];Dg`¨₯˜τdšt±I μ•6τaƒ]ƒ'm3Γ> Υ­•~έŠ8€*ΐΝ‚F~Ώ₯K¨ίOό>{ΝL‰―-/Di1P©QΑΗΧωSηwς›½­‘Ζ₯Όςα‘·ύέͺNο§­FκΘΕ\aΑ`Šοnυ«έΐ^:tΎL²™·Hΐ~œŽ„‘ωUˆ._EΏtUΈ»°ŽIJŒnoZJm½M·k²ZάI• •£\!#σ¨kΥγΤζԚż/ΩΪ¬q,k¦ά.Μ°ώŸ6zqωΧ7αK6ΉψŒ#Υm’IRY$’_8π=3Ν%SFΨ•Mg!$DŠςE"+}Κ@?J޽?ϋR;‹}R-oΔ6Φ·Ώ— ©Μr _”t―0ͺ„œ·*rά)πΓ,μVήF$"“L―JΣΛιή ΡώΓ«Zι2ά΄’Λ,«σJC`‡ ΗιNrε Λ”σΫΰ{Ψ£Ύ• ·-‰$ Έ¨ϊVφΉ ιΦΎ‡Uυ nβ{³αβΩƒ΄“ό…IρβΚςϊΚβΦζ ‹–· u$# βθ:JuΗό’ϋ_ϋ ŸύΥ7n̞fμΞN€’ ’Ey"‘Ύιe ₯t?ma»ρu’\"ΌkΊM¬2 Hύp κΏ΅#Έ·Υ"ΦόCa}kq ωpͺœΗ'π•ωGJ%;;$9T³²GšEγʊGΙΐΪ€σιHΠΚ±‰7“€ΕN τΝvώΎΉΣό$Φr˜€:€jXz§β{™n΄ΟA;n†{sγ2Οƒ―υ4:Žφ°½£½¬y¬0Λ;†7‘€Ι€Σ ΰ‚₯zVž_Nπ^φZΧI–ε€–Ye_šRt=?JΑρεΕ•ζ₯§άZάΑqrΠ*έIΒ΄€ύξƒ―τ‘NξΦj]ΪΗ3φ[Ÿχόƒ-ς”{ϊTqE$­Ά$glg 2kΤυκmτϋyBY™aŽH‚ŒIΏnI8Ξp@ό+Φ/.4κ­€Jmˆ•Πl…'8Ανΐ’3rθ(ΝΛ‘[ΔΈΡξ’‹ηœ<+6υŒ€ΉΟ†+4i$jΜΗ Q’kΠ|}β=ZΛPΆ·΅½xα–Ξ7u Ό–ΞOJΘψ©Ziσj qr,n!ςνξΚoσ‘οΗεDe.[°Œ₯ΙvrσA, Άxž6τu ώ΅³§θqέxrmM.’ίΛΫΖ9ΟγϊVί‹Ζ²ή‰ο¬um8M•»„†tl}{~ΏΚΉX5K˜tΉ4ψΚ‹w•f#ξ9¦›’ΠiΉ- όS₯&‰άιρΚfXvόδ`œ¨nŸeU½_QŸUΤf½»*g—ΆŒ>‚ͺUFφΤΈήΪ…QLaEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPSΓ·πηPTπΗ­ΗόωΠQEQEQEOeIψ*‚§²€ό•A@Q@Q@Q@ΪWˆΎΑαMkEϋ/™ύ€Ρ;ΜΗ—±·}άsŸ¨­MGΗRίψΧΓSΩε­ΚβλΝκͺNΡ³o`@λΪΈΪ(ΉΆρ¦™sαύ?Nρ‡ΧR“NR–­ΛCςρς°‘ΐόͺxάjϊΗ‡ο—LŽΥt‘Η/ΚαX6ΛςŽ1ήΈΚ(°ΥρB ΐΞ@=»Χ%Ew—ή5ΡΕ΅ϋθώ·²Τ―€·Lf ž₯Œ}±\~w†«iw=¬wqC*»A'ݐΠ“Tθ  Ώλ6Ϊφ»5υ– ¨LxΖ@ϋΗ Ÿ₯bQEQEhψ{S:6³m~±yΎI$¦ν»œZΪOΘ«―ƒhφ‘;yώ£ ―§<;tRŠ—υdΈ'«5΄έcμZ«§yώέεώσ~6l9ιŽsυE¬lπΌΪ?‘Ÿ2δ\yΫϊ| cn=Ίζ²h§Κƒ•D>%²›H³²Φ4…Ύ{0V νΚ{{~UKΔϊπΧZΘ‹D΅ЈB£eHƒnkŠJ ;‚‚NηG€xŠήΫFώΛΥ4ΈυE—ΞŒŒLŒF V}§žΊ/νlb+’Ά²Ÿ1B‘€ž½zΦer εZxρ^gΫθΪYή\ΖΡ΄Ζᜠn»WώU•α­xθΖκ)­RξΚνO6έΐgΗ“ωΦ-r+X\ŠΦ:{Δ1^ιιše‚Xiρ?šcg|c$šί—P³²π7‡QΣώΪC1(d1²όGΤρ^E'Mh„ι­Ή―λ?πκ–ΖDKHΥ`,"Lυ>Ώύj΅ύƒ’ΠΡo€²W3E>[h‡Λm±gR‚ kΩ!΅Ί[ΈWfU*€Ož…t_π”Ψ]ΩΪE­hQίOm…&-*:RŠSάn)ξtˆ!°²½Σο¬σNΊ`ζ/0£#„0ό?*“Sρ%½Η‡ίH²ΞάΜ&R³< s‘Ιχύ+›’ŽE{‹‘^ηE₯λΊtzTV:Ά‹κΔΕ£•$1?'8$j·‰΅Γ­OmεΫ%­­΄BaVέ΅G©οXΤP “ΈΤw:=#ΔVφΪ7φ^©₯Η¨Ϊ,Ύt`Μbdb0y¨[C§κZ΄ϋηM&Ρ²θ4‘y\υ?_jΛ’ŽTΆTΆ:oμώ†‹ό’³τ}cϋ;MΥm<3νΡ,{χγf ηη―΅dΡG/wpεθέΒΊM3ΔVΙ£Ε¦k:bκ°ΉxH”ΔΡη’2:ŒΧ7E7χŠ{šzφͺΊ₯βK €6pF‚8‘ˆp zœr}λz?i-<—>΅v‘$S˜Π°θΫΗσ:ŠN «ΰš±Ωψώ]Kβ4·D“΄@θ?vά dΎ,Ά··Ώ]?GŠΫP»VŠk‘) ƒΤͺž™>ŠNšnβtΣw6ό5―νPΝkε•Ϊšm»±œ{MMψŠ+έ.-3LΣΣOΣO4Ζ$23Ά1’MsΤSδWΉ\Šχ5΅cνš—¦ω>Γζ~σ~wοlτΗϊš5ΝgϋR 2?#Κϋ²Ϋη~νψοΠcιΝdΡME εHμcρV’ΣΑysαΘQ‡iE9 ° :Ε‹Δqψ”λk³νFS!\|Έ#~˜8¬Š)($%£©»ρ&›δ];A‚ΪςιJΌΟ)”.zνR0 fθΪnŸ{nο}¬Ec lήrΓr+"Š9l΄-–†ξ₯€ιvΆRMk―Cw2γl+©n@<ž8ώ>™β+dΡβΣ51u X\Ό$JbhσΙFk›’Ž[«0εΊ³4υύQu[Ε’HlΰqΓα@υ=Ο½^ΡΟ»7kuζoΗAΈΗ·\Υ»ύ-}>Ι³ϋUβ|ωΉςΆ6qΣζΟα\εr-Γ‘ntšgˆ­“G‹LΦtΕΤ-arπ‘)‰£Ο$du¬ύwU]Nϊ9a΄†”$pΔ8zœr}λ.ŠRwΝνWΔ?oρdzΧΩ|½’E'“ζg;1ΖμwΗ₯gkwښ΅έο—εyςΩ»vάφΟͺTSQK`QKcͺ»ρ=Ž‘eκš$w7±@ [•Έhψ‚T}k7ΓΪΌgΪb½Σ‘Ώ΅ΈPŽv²γΊΆ2:Φ=Ή¬ŠΦ:=cΔVΣθίΩZNšΆm/&e23Ά=OOώ΅s”QM$ΆŠ[z-νΥΆ‰π‚ΖΚ! jΌο4„`²FοΫ;Sσ5ηTSQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQETπΗ­ΗόωΤ%³_ήZύZ!Ν¦ Žq#uλώ αh©―­e±½Έ΄Ή]³Α#DλθΚpQPΠEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPSΓ·πηPTπΗ­ΗόωΠQEQEQE·ΰr|a£}„ Ήϋ\{ Œ―ήΟΆ3X•Χ|6‡KZTΥυˆτδΣεŽeŒ‘fŸœ }zυ  ?‰ναOν}`iιͺmύ₯ΌΖ;>ΟΏwϏβυόkœπ™ ΎƒδηΫaΞ?»Όnύ3UΌY¨C«x›SΏΆBά\<ˆ\ΤύzΧOΰ{ΟψfΙ> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐ.8"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊŠ(ͺQE=οό}?αόͺ žχώ>ŸπώUQEQE<ίρλoώuO7όzΫΐΏAEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE¨¬μfc€Ι&€Št‘ΌR4r«$ˆJ²°ΑuSh’Š(’Š(’Š(’Š(’Š(’ŠTVv €³1ΐd“@ E:Hή)9U’D%YX`‚:‚)΄QEQEQJŠΞΑPf8 ’idβ‘£•Y$BU•†#¨"€EPEPEPEPEPEPEPEPEPEPEPEPE=β‘#I7XδΞΖ*@luΑοL Š|ΡI¦9γxδ^ͺκA’€žA1Ό’ŠŠI?€ QEQEQEQEQE=οό}?αόͺ žχώ>ŸπώUQEQE<ίρλoώuO7όzΫΐΏAEPEPEP½"κ -JήβξΡ/`²φξΫDƒΠšξό[¨|7³ΦτΝίLΈ“Qϋ;œΎT#ž§άΚΌζ½ xdŸΰ}Ÿ’'—«–}£;G–Γ'σpΊ}•Ζ£{ ₯”/5ΜΝ΅#QΛκu‡!΄Ω―§‚ b€n™a˜;D;–αšoΒνm[ΖΒ——6 o3KnvΛ΄ §ΤηLΧyΰτ+«ŸΓWŽCc7Ϊ'½”:Ώ³όDδώtΐςΏ ψsRρ-λΫiP‡hΣ|Žμ}I5wΔή Φ<;iέτpΙi#lΑ ‘ztιZu+:Ο\σ4y΅=βŽΙb­όΨ9VτϊΥοι\ώmkΓ7Z­Ύœ·"9l.ίδ.qσ.8=G<ώ€Ώό6—PΠ5 ΝB+y$žΘK§²άck°Θ,γ¨λ\†Ήαkκ0κ’άύ‘²’)C‚η:ΧCπ½OxΪ8Τ»Ά˜pͺ2O ΪΈ[4dΎΆή₯x½F;Π­όDπv•aβŸK¦ΪG„Χ±Ω]BΉΫΈ²°ΟΥXώUΗkž“Qψ©hš FD"ŒΆΥUUΙδΧͺ΄©©όEρƒ;Λ5ž§mμρ,[‡β ΞΉΥ?h;°Δ Μ£άωf˜g‘h7ΪέέΥ΅‚ΖΫBσΙΉΆͺ@8όΕ_πΧ‚υoX΅ήœ-ΕΊΝδ3Λ(L6ουκkͺψ_cse―ψͺ[Έ^(ν΄λˆεg ِ&‘πΉ#αl˜$Δϊύ(žΦό ­θΊLš…ό1,1IεJ«(gŒ“€X€φϊŠι­_BΠΎθο‡m΅;«Ω'Gy$(~Y™ν[,$ι9βΛCZ«ˆ―ό=π£ΒςiΠΫΚΛp¬&‡Μ §₯qzˆ4{^ΒκίΓVΆΦΦωσ­VbV|τΙΗ­Η£κ μυ½3E·Σ.$Τ~ΞΒ'/•η©χς?ΔΪΥ潨-ή‘1J# ^Zΰzzσ]dπΙ?ΐϋ?%O/W,ϋFv-†Oζ?:@p–w…δ6–PΌΧ30DKιυ―‡~!4Ωon-α’FgLΡφ€ώ™«ΏB'ΔK8όΉ|°ΓψΆιšθτMSK²ΎΧ—IπξΉ-λΫΛθ–euPz–_λLΓ^ ΥΌEbΧzp·λ7Ο,‘0ΨΏΤ©§λ~Φτ]&MBώ–€ς₯U”3ΖIΐ,@{}Et>$|-“ψŸC ₯nψ°“§όPδ ‹/ύ hπΧ‚5ŸΨ½ν”pEf―°Mq(Y½­fψ“Γϊ‡/Ε¦«•+.τ*Α•ΧΤ]–ͺΪΗΰ[ ?ΕΪτΪ0™δ³½΅}§q'#ς[ΏαYΏtUfdΆΏ½»°»΅Ϋ%α&HW— Α…qU΅ΰ½.gΔΦ67LV X—ΑΑ!TΆ?b«ΫθzΞ>«”―§ΐΫdœ•Oβ)|7a}¨κρC€ΈKΥΜ‘Άύ„ηƒλS-˜ΦηQyyα{¦Τ΄λ½$hς@-˜ΈΰwχλΧ+‘θ·ϊεΣA¦Αζ:ηbBͺRO»φo­φ›βM>35½»:ίΌΉ"eΔ§:zRπ Άρ?Ϊ!šeΔ&Xΰm²2dτ>sνšΕIΕ>ϊy—k³šΧΌ9©hk—Ρ/‘/Ν‡F>™Σxcΐ²ήθχ·7‘ΒΝ-¨’Μ‰ρ΅ΘΘάγ·Z―ͺκ―ΰW΅Σ4«ψ¬ Π‘n.2‡ΖŸΦ£π ³θώ*Dœιη “Φ‰JNJ潑^θRΒ—ώVιAeςδΣι]ƒ,~ ψ}ˆm’ŽMkT™‘Ά–E -γRA δ―κ?7 Ž ­z‰~xRβ0J[\O ˜ηigb3ω~΅Ί½΅!œJΗ}¬_ΜρΗ-Υά¬Ι±rΔ“’p=Νv·Z^κλOψ?δ:΄‘~ΞΟ_ψζnψΑsΓ2>›+ΐ­ yΖwσ»5Ξx{K}cV†ΡΤ'tύΔMl|BFώΤ±m§i²‹΅?„ζ–ΓΒΪέφž‘―•‘ ΫΈ€g©ΗηωTΒ₯HΠζ½Ϋ΅ΎzjT‘MΧε΅’ίδ`x†[)uiΏ³ XlΠμŒ όΐΟ­\π–• νΔךe’ω“Ÿοz χ?η­jή]O¬xβχVPχ\*[ΞP+8=WŽ£―ω(]:λΒv|:Ε­[rŽ g“Άqιώ”έV©ςm­―ΏΟϊκ%M9σo₯ν·Λϊθq·²Η=άΓ Γ1+τQΨW‘θ2ΗΰΟ‡Πψ†Ϊ(δΦ΅IšidPΒή5$ξJώ£ρηΎ!AΎ§a; Ύd ΛsψΦΧ‰~xRβ0J[\O ˜ηigb3ω~΅ΣFjpRG=X8MŜ•Ž© _]]j–I¨ΙpK·˜ε>br[Z½γ›KK]BΔΨΫ­ΌsYΗ1E$€X·―α\εu^>F3θς%NˆΗ―ψŠΞjΥ’ϋάΈ»’νcH―5{ƒ „&FQΉ‰ *RMK¬θWϊBΖχ‘―“' ,lρΏΰΣπψ|ψ₯•q‘!mS'‘τλšƒQ½·o5΅†{™Ή³Ξα”>0@8τώ΅΄ύ«ŠZ'oΓΧτ-Q‡³ζoV―ψϊ~₯ ?ΒΪ₯ύ₯½ΤGφy+#Θ sŸzΟΥ΄Ϋ­&ρ­o’ςε8ΞA ϊVφΌμ< α΄μfˆυ!ψώf“Ζμ^ΣΓΞη.Ϊ|y'©’YΉ«ΪΝ΅χιAEΫt“ϋΞƒA–?|>‡Δ6ΡG&΅ͺLΠΫK"†ρ© rWυ¦Xίx›_[h Λ{#>η!C7,I?uώ$FΉψ=αKˆΑ)mq<2c₯ˆΟεϊΦgΒ/ω(Ί7ϋο’Ϊ»QχŸ |Ii¦O{%¬L°)y"ICH«λ΄{sŽΎΥ‡αΏκ~$½km&ίΝt]ς30TAκIΰV΄~'ΏπBΟΚ–ifž)pYYYΞr‚ΊO…ζΠxΕβζή{…Δ&h­˜,­OCιχ³νš@qή'πŽ­α΄†]F6ΣG<.6>™Φ¬xkΑψl^φΚ8"³WΨ&Έ”F¬ήƒΦΊoS±“α€Άz6‹©Α¦5βΘ—7R+’Ιά)ϊz{hϊ­¬~°Σό]‘_M£ žK;ΫWΪwr1%»ώΐγόCαέKΓΪ’Ψꐦp`ΚκN2|)ρG›,fήΨ:”Τyœςϊυλ›ρE]&D’ΪώφξΒξ–Ω/ 2BΉ.A‚; κΌu’ί΄†…& Ιna`8Ψίψ}μύhΘ.`–Φζ[{ˆΪ9’bŽŒ0UΑ££βSγύof1φƒΣΧ?k'RΠυ=2ΞξώΚX-Χt28αΖ3όz@jxϋMΆΥΫTΡ ΤΕά±D†Y ω9l09ΞGε[?₯Ρμ΅[­KΠ­μ₯΅™έΗ!,κS;vžœ°οΪΉ/ «7ˆtΒͺHQg§Ξ+βς°ψ‡¬±S΄Ί`γυk@ ΡώλΪΎŸg}iΈ΄Ί VY&  ·ŸBOAXž"Π΅κMcͺΓεNaƒΚz{Ž+±ρ„>x. ΔFΝ;2ϊΗυ?'ΕG{7Α’ΘKΝ&“f=XΰuόιJΗᏈο, ΈXm’3§™2Ξ«#ΘγόkGπΆ§ͺλW:L1Η υΊ³J“ΈM»HdχΙθχWzoˆ₯estχrΓ)S;’Yϋ‚sί€}γO…Χ1]Ε&ƒ΄V‹j­*ΙsσwΈτι\†Ό9©ψ’ρν΄˜<ΦEέ#³D€ž•Φ|i†Cβ 2A˜ΫL‡ ΑΑnυ€τΫtπŽ½¬κwzΣbd‚[;ΨgΞ>ϋ#wσ  /x;WπΤPΟ¨Εv€πΘ τΟcΕ\ΡώλΪΎŸg}iΈ΄Ί VY&  ·ŸBOA]^²ΪtΏ'm"ΞφΦΛϋELkvαΙ8e?έώΉ¬―JγαG‚β DlΣ³/© pSωΣŽρ…¨xwRkV*p †SΠƒάq]—Γ]ιρέ%¬(dMρΑ$Αdqμ½ΏVŸΔy°ψ{Ά ΏM„Κνά|ΉΟλV~%Ϋλ’|\΄Α7Ϊ[Ι6£€ŒœτΐmΩΟ΄ηι—³κƒMŠΪVΏ2y^@6όΰŠθυ―‡~!4Ωon-α’FgLΡφ€ώ™‡αΰΌOŒ›uχυ@f0Ϋƒ'–zmγ8Ν_Ρ5M.Κϋ^]'ΓΊδ·―o,w’Y•ΥAκX}­yΗ†|9©x–υν΄¨C΄iΎGv ˆΎ€š»βok΄Žξϊ8d΄‘Ά ΰH½:t­?‡:•Ɲgyš<ڞ‹q Ηδ±V~l«z}jχˆτ.6΅α›­VίN[‘Άoς8ω—£ž R†ΊοΪ§‡ΒšΜqάθ·ΜΡ"²ΠΘέ[sόλΧτζ5Λύ=ΫqΆβέύΰόEiό;΄’σΗ:p‚Ynγ”ΰg Œώ€Σ~ Ξ—7Χ$ˆε ܊?₯uϊUγxϋΒ:­–¨ϊΎ“nn­.•B»’ŽQ±ΤtόΗ₯yΦ•¨]iZ„Φ˜‘mΘψθxγαfρN₯&E½Ύ“4lqέ°@ϊό†Όφ˜‰γhνόEΰΝ?ΕΡA½ω›μwΛΒ»€H|v=?1ι^w^„Ρ›/ληdν[̈c¨ ‚~Ÿ!―=€EPEPEPEPχΏρτ‡ς¨*{ίψϊΓωTQEQETσΗ­Ώό ωΤ<ίρλoώtQ@Q@Q@nxwΕšί‡#–=ύν£”ξtΨ€ϊၬ:(nokSxu·Ώqͺ(N¨«ΐΖΖ1νZ—_ρ&³§5ώ’Νlγ*Fˆdx¨ύ:VEΉ¨ΪιgM‚γe‘Έ[£Ε?ΌΓdŒφg›ElέψŸW»TK‹½λ©²=Ψςy₯W γΨ«Ϊ/|I’i±Xiš—‘ivGδDΨΙ$ςΚORk˜’€6/ΧLHŸoo“m‹ΈγΤγ&±ο.fΌΊ–ζεχΝ+nvΐ?APΡJ4α b’ͺNzIάΪƒΕΜbŽωΎΝ³ΛΨΘ­ςγΙιTt½NσJΈ3ισ΄2‚F#ά S’…J 4’Τ=€έή†Ž―­κ:ΉOν –•Sξ¨T~VuUF**ΡVDΚNNςwe­BώηPxžς_1’ŒD‡hQΠp=λ πw‹›BΆΊΣ―μ’Τ΄k² Φ’|ά|Κ{δ:W+E $¬ΆέΩ=ϋΑ%υΓΩΖΡZ΄ŒbŽJ¦~PO¨­KkV©ok|Λ *²+`zA¬J)Nš΄•ΗΚρv.iΊ₯ξ›vnlnŽA Τ M¬kšŽ±εBΰΘ±ύΤ GΰfΡG³75΅yrςίBΥΕύΝΕ•΅€ξ·Άέε&Π6ξ9<γ'ρ’φώζυ-’κ]λoŠ!΄ ͺ:?U’šŒWAs7ΤκΌβζΠ­΄λϋ(΅-μƒ5€‡72žΗω•‘oͺΙ₯λν©hE­ r»[nΜjr;² ΪqΞk2Šb$ΉšK›‰g™·K+vΖ2IΙϋ+-ίgb›ŽO dώ$Ρͺkϊ€PίΟζΗe‚±Wbƒ€3υ95ŸEv6ΏόWmfΆΡκ„ͺ.Υw…ΤΌFOγ\ΥΔΧw2ά\ΘΟ+wc’Δυ&’’€:‹_ψžΧKt:«ύŒGεx£rΖβ€τχͺ>ρF―αΉ%m"μΒ²ΰH…C«γΤkŠθ5ŸkϊՌ–zž ΣΪΘβCtΖ@φV}ζ³{₯ΨιΧ3ο²²έφxφ(ΩΈδςOβMgΡ@¦±ͺAe όώlvPˆ v θ8?S“[Φ_ΌSe§-”£y(»š4gUτ Fk‘’€,C}u ϊήΕq*ή,žh˜1έ»9Ξ}k’Υώ x—VΣ^ΒϋQ-o Ϋ H‘ ƒΠVŠΦπ_]<ϊ=Ϋ[»€6†Wΰ‚ Zρ'ŒuΟΓ:΅ι’έrĈ¨ ϊΰŸΖΉϊ(°πχŒ πζ‚ρhϊj&Ή0t“Q‘²QIΰ"φγυμkbX’Δ’y$χ’ŠμuΓ6€Ί‡΄δΣ4Ά!§ω·IpΓ±ϊŽœτJη4)μm΅ki΅[V»²F̐+m/ΑΐΟΧFŠθΌe⫏ΟlΏgŠΟO΄O.Ϊ»γΏsΐό«’Š(’Š(’ŠΩ endstream endobj 142 0 obj 15008 endobj 143 0 obj 7263 endobj 137 0 obj << /Font << /Font2 12 0 R /Font3 13 0 R /Font5 28 0 R >> /Pattern << >> /XObject << /Image15 140 0 R /Image16 141 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 144 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 145 0 R /Resources 146 0 R /Annots 148 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 145 0 obj << /Filter /FlateDecode /Length 147 0 R >> stream xœ΅TΝnΤ0Žs@ΪyΥnUΌΆgό'qQ$8TBŠΤCΫΓ θPΆe o…ΈΒ•}‚>C_f’f“.ε―‚ŒΫ_Ζώ¬o>g VΈίΘxξ_¬` FcsHήP“±=η$ιV€ΑΗ`šεu?qΖG’A [y/αN™d ³‡υ›εάΐβ-38i1ZζΠhr2˜Ξw’ZΒΙ<ηX˜lΓΤokcςVE°δQ4`ΚΡ ΈΑκF„ΎΕϊ΅=Ά‘RLΊύ¨‘Ά›HOA'O6{N³5±Σ?Gη)σ °ξ&¦(5H½Λ$‡TρΥ9̞œΎsΰ9QžΥΙΝΊfnήι@P΅E«^Β!LŠSh€š_Τ\ΕUyY~*φΤΈψ6e!ε‹Ϊ-?Oαͺg°WύΛ3‘#Ι₯6™BυZΘ~#γ―ΚJ™λ₯‹Ε#μY.¬ Α:mΒ­¨M!’kκΨo0~ϊ_;Ν΅pžέΖ7―υrˆQRnYΕJ̞ζ‹W6Β㳍h?5|Ά^8&“±±»3²Χͺ{ΘΗ(|bφλu=ςχVχrΉ½Ο³ΞΙμSΊΆν Z…[]€ΓMS—_‹κϊθ¨ΌTο;Wj_Uj€v՘ρQϋy€*~ο³ωΗ#nEω‘Όθ Χ³ρ_K[²žΆOψηξ–ψuΕη endstream endobj 147 0 obj 519 endobj 148 0 obj [ ] endobj 149 0 obj << /Subtype /Image /Interpolate true /Width 942 /Height 452 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 150 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐΔ"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊŠ(ͺ=οό}?αόͺ žχώ>ŸπώUQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEO{Oψ*‚§½§ό?•A@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ήΗΣώΚ ©ογιεPPEPEPEͺ 0QԜPQ]Έψaβo6XΝ΅Έt(3¨2pΛλΧ―JζtέχPΦΣI‚-·Μν—!Ϋ†Pr§CPͺAμΐΞ’ΊλΏ‡~"΅ΣfΌ’Φ2°©y"YU€Uλ’£Ϋœuφ¬oxRργ[iVώk’ξv,Pz’hU"ΥΣ*Šήρ/„υo$2jP'‘1ΔsDαя¦Gz½iπϋ_»°Šξή&€\D‚eήθ}ΤqωΡν!kάNŠΨρ‡/ό=%Ίκ [„σ"’)«όJΨ²ψqβ;»(ξΪ2'™2L«#―¨SύqC©Ψ}©£θ7ϊΆ΄4›X€ΎΛ‡n ‚H9ϊMD½Φnn`±Ti-αyδ ΨΒ.3όκœ’κeΩό:π|Ύ!Ώ·Ή"“KIΜS©›cŸ—<½ΗJΕώΏΠώΫzVέtτœ¬ag αKar:τΕG΅7%υ’ΊOx/Zρ£]ΨAΪ†Ψ%š@ŠΝθ3Φ²΅ΝϋCΤΛT€Αp£8$AθAT§ωSΤ Q]/ƒl-u ]z;ˆVIβΣδžs•eξ?1NO•\i\ζ¨―N‹ΓsΛΰεΘLΰ‹ΑΟΞήRΙƒΟ‘5Ιι:%Ζ―­^I₯ClΠΫOΏΚš@ͺWqΒσΤ`b‘TLn-νΠψυgOΜ·VΦ„LΓnA^r;Φο†< -ξ{sy,Ϊ‰,ȟ\Œΐ;u¦κ%f­»#’΅υσDΉ·‹PfnWː?η₯uή*πμώ »ώΔ΄†+0«εFe \…Ά‚ry?JH«j¬σͺ|PΙ1anεT»mRp£©>Β‰’’žQ’TbŒ€rΰŠτΏޟιψKFT₯Ά¨άνζgκΉμ1ϊψΩ'˜Ρ[~πΆ©βU»ώΘ…fk`₯ΤΈSσ3τ5kΔή ΦΌ9eεό15€·Ν‚@κ­θqΣΏ΅sTWKα―k^!³kΛbŽΠ6Α5Δ‚5fτλYZφ κ/cͺΫ΄ Α †‘pEgΣαŠIδΓΙ!言“ψ μ ψcβi¬νξΦ3ΰ¬-2‰’>bΎœσάzVhψSΔlA₯c)— »υΰυ  š+ќUΜ—P³1(ΏΒ:]„VZή«¬Ϋύͺ-4*-Έ|+»1‘Ϋ ~u½>©θ){am›©Η6Η΅G,²&>πτυΤσλk—Kœ­»‘xSUΦ­šζ(Ψ6Ρ,V>ƒ=jŽ―€^遲Τ!1OΑ †‘u\Ι»\V{”(­;νφΛ]]"tAzΞ‘… Λγώ"™&zšΣi"χΒO+ΛCœ·ΦŽdf}Υάψ]·³C $Q΄ŽΛ2Έ ϋβ±t=\Ίh4Ψ<ΗUάμHUAκIΰRS‹WΈr³:ŠΨΧΌ9©hk—Ρ/‘/Ν‡F>™#hϊ?ƒ4;Ϋ­ ϋ‹Γ0wyΚδžίΚ“š²k[‚sƒ’΅΅Λϋ-Nkq§iQiΫr¬±Θ_y8Ζs™}‘ήΩk«€Nˆ/Y0‘|cŸΔU'ά,fQZφώΏΈρhΡ’εfR₯Ζ2£'Ÿ «·Ύ ΦμτΙ/¦·O.!ΊTY™ισ+Ϊϊ…bΣε†H‚ct»Σr‘Ή}G¨ΰΧoπΏN²?Ϋώ§Έ·Ρ , χd‘³·?χΟηŠζΌE_ψ—Uϋn₯"ΌδΠ*…TPNNM1TWn>x›Ν–3mnΚ κ œςϊυ빝7E½Τ5΄`‹mσ;GεΘvᔃιΠΤ*{03¨Ίοα߈­tΩ―$΅Œ¬*^H–Uizδ¨φη}«ÞΤΌExΦΪUΏšθ»‹T€šH΅tΐΚ’·ΌKα=[Γ‰ š” δLqΡ8tcι‘ή―Z|>Χξμ"»·‚I  ™wΊEυ~t{HZχ“’ΆxŽκΖ;”΄L‰ζG“*ΚλκŸηŠH₯vΐδ(­mΓχϊΦ§5…’F—Q+3¬ξ#Ϋ‚χΙι]nj~άCuš$VρΪ­ͺ΄’K‘“';ˆΙι”ͺΒ/•°<Ɗξ| αΤΧΌ)β?&Νn58Μ lΔΰ¦ζ;ΉΞ’kΔΎΥΌ;κFm¦8I‘:ι‘ήš©' `Q]‡|¬k֍we ih­°M<‚5fτλYΊΖ£κgOΤ­Ϊ ‘Œ) ‚BΰzjqnΙκ}―¨xzώΓΔI’\€bύή8Β‡rψΫΟβ*)τKψ΅ζΡΌŸ3Pω>Zrή™ιψΣζO¨΄Wa©|:ρ…”χ/ΌΛn»εHgWt©#ό+₯Ζ_ ’Šξ¬αΡό?α-7RΤ4΄Τοur«$…V4SŽ0:τόύ«DL₯Κp΄VŒ#ΡΎΧmq >Ψ.!Io’Lέrjέ§€΅λ›D-βC"oH€•VFΚ­φBφ‰+½VŠΡ΄[έOWe΄`^eIά ώF“H.υk‹ˆlΥYΰ‰¦}͏•qŸηJΜdgΡZžΠoυϋ§ƒMˆ9EάμΝ΅P{š΅¬xKV,ςφ(Φέd‡Y$dŽ’‹;\NqNΧΤΑ’·t/ jΊΥ«\ΪE[ΫζΝ EfτλTuM"χKԍό&ŒŒr=#‚(³ά9’έP’½>ξ i>"΅πΜΪ2ά—ςβšρ₯`ϋά ?Πχφ>γΓwxΎλCΣ±$©+¬eΨ.UA<Ÿ\ §ˆTόŒ +₯½πFΉg¦I}5²yq "Θ Ζ:δ―jŸΐ~“]½‚βd‰τδ›Λ™L»Xρž^β—+½Šu"—5ΞNŠκ’Ύ"Ύo κύ›2¦a€1Χ#‘\ŸͺήιϊͺjV— ·ΘΕΔ̝Η9'p υ=k’)8k¦–n/_h1Υ΅ O*Y₯–hδΚΑœη θ+cΑ+4Ÿ|eˆ&μˆ2οχί¦κΰ&{‰δšfέ$Œ]Ž1’NM^Π΅½GAΌ7ZMΣΫLFTzrγ[Jγ¦ϊ~uρ$ΡόΉϋXeFΤΤΫξ6Œνφϋί­uZi#Tπž ‘uτ^]β/λ"h΅οZu”@‘}πχ₯ΕΔrΪH—˜{Kci ς“εˆŒιΟΟ5›£&Ύπ:=~έ―<ΰ e`­3]DΊ Μ’ΊG‹GΣώ!Ψiχ ―κzάBΏk–qŽΗ8ΖvyφΟΦΌ²λV½Ί°°²žrΦΦ;ώ΁@ςχ[2ykyΎ"x Α_ڍϋΌaό€ή@9Ά2―|Ρ*S΅—Ÿβΐλ4Hώ=έBξžp=ɍfό5²Έ³ΦΌO%ΤMvΪuΔr³ lƒΘ\=Ζ­}>Ϊ€—.5“Ν3 wϊŒ` ΨΦΏ―λ\‡Ό_xzƒJΏh`cΈΖΘΉυΗαYšΆ§{«ί=ζ₯pχ/ΥίΣΠ€{ ˆΣ’–»+ώ Mo‘κw:<ϊ¬RΎŸm’p>U<ˆ­Ώ†‰^Ϋώ~­f‡Ή\JΛ³ρ6―g \θΆχe4Ϋ†έ$[Tη=pqώ΅CLΏΉο’Ό±—ΚΉ‹%hldx9 ­fΉ’vw=“Nu:–°κF4›γΨ SσZρ ¬έ?JΥ‹ΔZ¬GR1ݐu,‹―‘yœη·xτΗZ]Δz„“&•uδ,€Z6Hιχυ¨„.T€™·ρeOό&w'\|ΐEV}ΕH€³<ΰ’zΦ~£γOj6RΪ^_ω–ςžLc#κ5•€j·Ϊ=ίΪtΫ†‚lm, B… rr°ΊζΉZ DΡδσΏZτ/Ο(ψ½g‡a²{d_`vδ~§σ3ZΧu-nβ)υ;Ÿ>X†ΤmŠΈΟπLΌΦoο5…Υ.gί|¬Ž%Ψ£q΄ΰ qΪ›‹nμI€_ρΉψΣU`8,qψΧCρΖ&7k †κΪ)clpF1ύ+†Ώ»žώςk«·σ.%mΞΨ'θ8ͺ?ΕyαC’λϊr_5ΌL–aΆΙnqςƒκΌΐw«Š²HOVhό5‘βπ‡Žš6*ίaA‘οΌε­|G{mαkέ±Ί•fbΐ—F”η;Fx5[NΦoτΫ;λK)ό»{δά&Ε;Τg$du=1YτΔzυδΊ, <*ϊ½υݘ2τI“qΞμχ?6?ΐψ•©-εί‡Zm.φΖ-•ν„– FxΟ_ZΑπ猡ίΐπiWΖ;v;ŒNŠλŸP~™­jχΪέϋήκ—/qrΰ큀:{ `{‰4]nογ.—©ΩΕ3ιΫ ‘.‘sDή tηζγΎκσ?‰ς>λŸυςΥΥxOTΡlm4©u/je-™'m-`—`e „ΟB2>•ΙήλZ~‘㛝_Q²’}:k—•­ƒmf^v‚GNΩόh}£6_ΧΞΘ7Ϊ·™ΗPύ>C\₯΄Χ—Q[ZΖΟ+DQ’ΜxVUqβYν—μρYιφ‰εΫZCχbwξx•bιχ—uτ–R˜`pρΈηi:M_K½ΡοžΟS·{{””~Έ=½z.—~–_ΕΖ ­]ZΜBŽκ9φΞα^―λWϊώ€χΪ¬ώuΛ»Ά…€ΕEs©έέXΩΩΟ6λ{=ήBmfγ“Θ<Žυ‡5Š‹±ΩόK³]:ηΓΆsΙoj±1=ΒΆ3ω ΫρUΦ›mγΘ€“MΤξ5 bkv‚PπŒtλŸΖΌΫZΦυ nX€Υ. ομBQWπ5₯gγoZY-¬ƒ‘v‘dVeˆΝgμεdW2ΉΉ‘\߈š΄/nφΝ¨ΕqBύT•Ιί+]\D¬η|:Μϋ+φ@?τ%5γφ:…ΥŽ’—ΦΣ2έ£δυ'9Ο^υm|Cͺ(Τ€»8Τγλδ_ήuφγ©ιŠ%I· )€oψV7Ίπ‹!„&ύΔ›G$€δ“ωVuhτλοΟͺG’ΫιΣ}©a‰’\pIό*δ4m^ϋF»ϋN™pΠJF@0τ πjΖ»β-S]1iέ4©(B¨χΐŸz§Νqs+,Άzv™α]υΉ5KΥ» ,6πJ~™ώ#»ωΣΎ&YΌ6β9bQdŸ,Η.£=ϊŠΐό]­ιv"ΞΚτ₯Ίœ’²+μϊ*†―¬_λ jW ;BžZ3(r?SIB\Χ`δ­cΉρMΔΏlΪ8™–Y­εBWnOαƒF4#γ<μΜΈ7"“ύνŒ1ύ+š΅ρ·ˆ-lΞEΔ*»”RΚ=šΒ·mΧ‘΄³4y›’ΛΟ-κOz7k>Φe{£ΡΌ€jϊ}ο‰eΤ‘š(šΞef‘HΏPG―δzΥ›aαύ’¦\BeŽΫ#&OCιΧ>Ω«iιze­όίπ‘ίkwrΪ½΄1KŠ©»όίA\.«_hΧ_hΣn^ HΪHΑzx5*.Iό‡t¬u‘jώ{]3JΏŠΐέ βαΓ(|`€qιύkBMjMαχ†š;;£)œu˜œŒu?]ρ©ωcSΊ2€|’  ϊΰΝUΉΤξξtλK ¦έijXΒ›@ΫΈδςO>΅~Ξι_ΈΉ‹:Ά°ΪΆ‘ΔΆΆvΎX ΆΦ/-H9#'žk³ρMΔΏlΪ8™–Y­εBWnOαƒ^o]―ΌAk`Άpκ.!UΨ€’–QθŒΣ”Ω}ΟBeH#ΜqμŒ+;αμK­xƒΜrήm…Γ>ˆδr3ωΧ%¦j—šf’·ΦS˜ξΧ8¨cΘ υ¦—MΥ/4Ω§–Κo*I£h€;CnVκ9ԝ7fΌωާΒK,žρZY‚nH‡!~ρMΗ?¦κΖkKΰφrJθfΰ|­·™1ΥsΟεΗZ££jχϊ-ΧΪ4Λ–‚R6’!‡‘ƒV5ίκΊο–5;¦•#9D Aυΐš|―›ΘWV:Ώ‡¨Χ^ρΕ€@΄Ζή‚ŽI Xž? ΰ _ϋΓωΦ―…ψΚ;MΩd'ή1ξ;ΏMΥΑ\LχΙ4ΝΊI»c$œš½‘kzŽƒxn΄›§Ά˜€¨0τ δΖΆ•;ΗMτόλβI£ψ+sφ°Κ©©ΆάmΫνχΏZκ΄F©α<"λθΌ»Δ^'Φ1»­~#A$ΊN―uͺ©‰νšή`ΐW3ς½VςσN±±Έ›}­–ρn›Tlήr܁“’;ζ·,|βk+³ƒSq .Δ-3 τ Fh•tσόX7!ξ;ζΊ?Œ1ΉΧtΙ1FΣaΓcƒχ»Χ #Ό²4’3;±,ΜΗ$“Τšθν|uβKm,iΠκoφ1ˆ#DŒBcΙRz{֎ 8ΈτgΑr<_I„νΕεπsŒτŒβ“¦ΫoΝ0=ξ]?†>mVΚφκΠ‡ϊ,‘IΌηvGSΞ?Γψ‡¨ύο@/¦ήXGolˆ†μ‚ςFΚxόkΓή.Φό? Γ₯ޘΰsΈΔΘΉυΗαYΪΖ«{¬ί½ζ§pχ..Ψ€ΐΒ”)5+Ώ?ΔHρ……Μί,(]’YνfF‚‹³qΟ Ϊk"φςςΫγ ε֏lo’Ό¬ όx0ό·VUŸόMg¦­Œ£ˆv!(¬κΎˆΝsφwΧVwρήΪΟ$whΫΦP~mήΉ₯ RJΟ΅€τ»KΔΣλ-’.±‘λQΓ$σ£HLMΟ̌zς}qτν^aim5εΤVΦ±΄³ΚΑd³κ_|K¨ΨΙis¨Ÿ&UΫ&Θ‘ B@Ήέ>ςγNΎ‚ςΚSΜ7ν#§ZΊP”oΜšΎ—{£ί=ž§nφχ((ύpzzν―δX|ΰϋι,VώΦq‘6v–c€=Α?…qΪώ΅―κO}ͺΟη\° »hPθU­ Ε:Ζ… Γ¦ήαcΈΖΚΉυƒΒ·‹Ks:‘r΅οivΏjπτvvPιΣίB­,KŸ‘˜€3τζΆή-.ΗΗVV3oPΥα–%ϋT“ v9Ζ3°Ογ^m©κwš₯λ^_ά<Χ-œρŒtΖ8…mŸψŒΓΪMςcε¦γŽ@'?Χ½W2½Μέ9Y+6ŠΚŸ nš`>» gό?΄žΧVράDΡ₯½„ι#0ΐVΘγτ5ΗΟ©ήMͺ6’σ·ΫZO4ΚΈS»Τc₯jjΎ2Χ΅[g{~Νnά:ͺ*oϊhRCtε²μ‘΅ΰXfΌπЬμkι"¨ΏyԐ=xΘόjkΛν?α3E¨Η$.Ϊ€xγa•Jχ§9?rΎ’(΅@σκΣi*βζflw Ο5ΡxŸZΣ‡†?²¬u;­Zβk―΄Νu:2㠌 άφ­4Υ…(Ύ};άΡΊ“JO‡žmJξβΨGϊ4Ύγχ²:υΗγY8ΏϋMή†^ΒκΙ ·DCrAwŒσ¬}ΕΎ‡ C§]˜αcΈΖΚΉυΑ…PΥu+½Zυξυ Ϊ{†ΰ³zz8ιIΚθ¨ΣjW~g{β«+™>.Ϊ΄p»,³ΫΘ„ ¨LŸΓ€ΡY_γ\εH#Θ~Q°^ΧΗ!΅°[8uͺμRQK(τ Fi<ͺ[iž.΅ΏΤζ) ω†I,rQ‡l“Ι§Μ›ωιΙEί΅ŽƒΐqήGβ/΅‘Um'Η²>ύZηΎxΣIΟόφώ†“PρŽ·ya&Ÿ-ϋ΅›eHΪ‘™{ΨΙƒo4–σΗ4ΡΛGS‚€t"₯ΙibΤNύMFρψ‡TŒ§νRυώ#]&™¨Ϋ§„lμΌK€^K₯‰YνnνΫiάIΘηƒΞkWρf·¬XύR½3Ϋξ ΄Δ‹ΘιΘθž,Φt[cm§ή·Ξο-Ρ\νqBi1ΈΙΕ'Ή£γMέ©6›ΠΈ&£fr΄U­RKIu‡Σ‘x,ΩɊ7mΜ«ΨήͺΤ”QEQEQEQEQEQEQEQEO{Oψ*‚§½§ό?•A@Q@Q@)F ¬GΚέ)*yΏγΦίώόθ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€'½§ό?•ASήΗΣώΚ  Š( Š( §›ώ=mΰ_Ξ ©ζ[ψσ (’Š(’Š(’Š–ΝCέΐ¬2¬κυ―^ψ‰ΰν*ΓΕ>—M΄Ž; ―c²Ί…s·qeaŸͺ±ό«Θμ?γϊίώΊ/σ― TΤώ"ψ‡A€ešΟSΆφx–-ΓρPηLρ~ŒOυ 'E΄$ύ€Εn‚­k)κύ΄0t»Ϋ†ΜGΌ Ό± γρλ@V>Υo|3u―[Δ‡O·b—Ž1’ Ν`Φ΅₯ΎΈΪΤΆ‹ύŒyζ2ήNξ>πΣτ¬š@ΡψΚϋS»Žώ–4³’EžcωΧ9NŠY"$Δμ„Œ§”€¬L•Υ‘Πψ†ΚίΓ>Έ·…R{„˜ΜΰœΉVgυ­!αgΤό-‘O₯ΫF·ωΖβg}£‡Βδ“ω\cK#’#»2&v©9 žΈτΗ^IΫαΧ†ΜaŒζߎ›·ΉΗ«9&¬―Τ‰&¬―ΧόΞkVo4›σg—? δ0=>”ϋΝςΟZ]*tQxΈ0#-ŒsψŠθΌyΎ8Ό4.².Ζ?3wQυύj‰m'“β΅£$LΛ$Φς)‚ͺ'πΑ‘Mισ7eσ8εΡΫ[:V#Κ\Θ<τν[~-²ΌΣτM*ήσN²· ΉVβ γqYΎ3!όYͺ”;‡ΪqμkO\S ϋΓC>eΗώ†iΆύΦ ΏuŒπeΞ™5ݞ›}£Cs$σl7 +φ•‡―ΓΎ»¨Α „Š;™vˆ­ψ0γŚVxHOηQψͺ'ΔΊΆτeJ”ς;$kIi2}ΒΪ¦―dΧv ·jΌ’}jߍ΄Έ΄¨τXάA;Ω#N;™;“οVΌD²Ώ€Ό0a mΑ˜>ή›χqŸ½KρL±ψ|\ηΟ|bMέwwΝJ“r_2T›’ωœmYΣlfΤo’΄ΆΩηHH]μp κ~•Z€ < Φ¦ΗYβΫ+Ν?D­ο4λ+p›•n `Ν.:瑒膡ο§B%7~cΗ_‘­qOό+ο ω—ϊ§x]Ϊ?x¨‘*vΐΉ…ˆ?‘¬“j:wύLSj:wύLsڎ‹3^Ζ† xYcpκO¦GzΩπ_†€Ή{‹έOLΉžΦ+Vžφ²‹†ώλŸjd ΟπΊδ1ΘMHmΟo‰«>Τo›OΧΠή\”ƒMΔ¦VΔd σΖ=©IΙΕ„₯.Vcψ±v›_ψ6χΈbΗΝιύαΫϊΤΦήΧn,α-Po]ιHͺμ>†±₯ΏΉ½Έ€κSά*7t…φ‚FzΧoβX―[β­«F²e€Δ@γ` »πΞμΣmΖΙ ·$qZT uΛ;{ΈΞί΄$rΖάqΈ uΊΖ•¦ΓaβΧ†ΥK;ˆR ύΨ,Ÿ­`xΡ€ρv¨ΡbαΉ^ΗΏλXνq3 K!_,~cολUg+1ΩΚ̎Š–ΞΪkΛΈm­c2O3ˆγA՘œSκϊeζ|φz” €΄lA###§΅Y‘NŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  ογιεPTχΏρτ‡ς¨(’Š(’Š(©ζ[ψσ¨*yΏγΦίώόθ (’€ (’€ (’€7hέ]H ϋΦΡρV²|Gύ½φ5oωξ#Aό;>ξ6ύή:V%ͺž"ΥS_mj;ΗMMœ»Nͺ£$ŒΖ=±ŠΪΊψ‘β›’ϋυ=ͺθΡ²$…!‡9zϋυτBŠ΅Χ5],ι°\l²7 tcΨ§χƒl‘žΓŒβ§»ρ>―w¨—{ΧSd{±ε σJ―AΖ=±XΤPCαΟkΎΰ―ŒvμwΧ> 08ό+3ZΥο΅»χ½Υ.^βεΐΫtφFŠΩ³ρ>―gαϋή즛pI’-ͺsž dώsXΤQ@Q@mιή*Φtθ-ΰ΄½) ‚'–€NNr9ηΦ±(€{‰€χ-ꚍީxΧWσ4Σ°ΑcΗ €+RΫΖ:υ΅ŠΪC¨8…Wb岏@Δf°(‘Ε=,'τhΉ¦κwšeψ½²˜Ηt3ϋΒ‘=zƒ[πžx“ώ‚_ω/ώ&ΉŠ(q‹έŒ^θ ŸΞD»·‡ΩΞEm_x»\Ώ°’ΞξψΛm ”Ζ™ υ=½k ŠSάn)#ΔΪΎlφϊ}γE μ*¬υ ξ±u©έZI«ΘΧiTΑΒ’€δŒΧ―'šΝ’ŽU{Ψ\ͺχ±Σiψcώ…ϋό oπ¬ΥՍ†΄ΧΪ 5ˆ«)\,9Ο?eΡIEŠ:ψOΥ±­ό9ρ¦Λ}sm Β30†Pνυaώ >ŠήπΧ„΅o[έK€B“ fEp\)Λ1žάΤΎ(πn±α«x.5’6Σ©42MέqŸZη(ŸΓ^Φ|CbχΆQΑšΎΑ5Δ’5fτ΅SVπ«€λΆΪMό ΥΛ"ΒΕΑGάpn˜Οε@tW¬\ό+Ί„BΟȊΤkho:Cuςπp8ΟJδ|9‘yμ4m^(₯εc™·+3ŒŽ΄ΚΡZΎ,·ŠΣΕ:Ν΅²ΰ†φhγAΡT9~Bα―j~$Ό{m&5‘wHμΑQ©'₯dQ]Š<«ψj(gΤb­¦;Rxd„ϊg±βΊΟψA€Φόው»”LΧW>ΐ@|.Iό€ζ4VŸˆ΄-CΓΊ“Xκ°ωS€`δ2ž„γƒ]ŸΓOέιρέ%€HdO28$™VW_P§ϊβ€8Κ+wΓڍ–‡ytΊΞ‡€ίκό©άΖb`yνΧ΅m|ZΣμ,5½3ϋ.Ξ;8n4θ(Ι 33η―°π "ŠΧπΟ‡5/ή½Ά•v7ΘξΑQΤ“W|Mΰ­cΓΆ‘έίG –’6Α< 7‘ΗN”ΝΡ[~πΖ₯β‹Ιm΄˜γi"Μs#…gq ΫΟ$3.Ω#bŒΎ„@ ’ŠΠΡ4{ΝjκK}=εHΜ€3ωF3Χκ(m%v4›vF}ΤΏ5΅»‹ΝR³)σ}žΈZΗΠτ[νrι Σ‘σs±!U©&₯T‹WΉNœΣ³Fu΅―ψkRΠγŠ[ΨΠΑ)ΒM‡B}2;Ս3ΑΊΖ₯emwm_fΈ VG”(;yΟΏJ=€m{θΞwεΆ§;W-΄»ϋ¨„ΆΦ7SDzg}Jφδφ–Πηθ­­7Γ:ž£iΥ΄QύžBG˜ ƒƒœϋΥ=cJΌΡξώΟ—!”ƒΓΤ΅V\©κK§5f΄(Ρ]‡φ>‘₯xkQιφ3FαXάyŠΟΰqŠζ΄­>γTΎŽΝCO&v‚p8<ώ0­'+芝)E₯mYRŠέ»π¦­ka%ά°/—έ"«‚θ=HνT΄]χYΈhl"Pnvc…Qξiͺ°iΙ5d'Ji¨΅«3κΥ¦{y{K;™Π₯’‰˜ι*φ§αΝKL³k«Έ‘`#1# ŒuΡ|$Χ5+Oiše΅ά‘Ψ\\ξ–Œ9Ϋίς•T'«Εά™BPv’±ΓH²H₯]I ¬0Aτ4•―γωuΏϊώŸF5[Άπv―qo«(e]ρΖςͺ»₯)Ԍ>'aœ§π«œν£a£^^κΨƊ—1]ep˜ΑŽ~΅xΑsΓ2>›+ΐ­ yΖwσ»5ΔS„”[άΈΠ©(Ή%±ΕQZ:F‹}«‰Ώ³β˜B–€<œ΅6±αέGIΆŽβκ409Ϊ$Γ€}*έX)r_R=”άy­‘‘EužΡυ$Z½••μN¬«ς(φΞΉyΑk™ΕB\ό«ΠsΠ{RU)8ƒ•7©>€tWKF·½ΠΑuθ ͺ ρŸ—Χ­aCes5ςΩΕ ΅Ρ,GŽwzQПΒΣ Rœ~%b½Ρ\x7X€HZŠΖ†Ge•H\ }λžRFFy΄αRψ]Ε:r‡Δ¬Jmn°Ή0J-Ιΐ”‘ΪO¦zT5ιίu[Ψ΅Α’E7—€EO²¨ §yYEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPχΏρτ‡ς¨*{ίψϊΓωTQEQETσΗ­Ώό ωΤ<ίρλoώtQ@Q@Q@XΊΗ{nξp«"’}kΡ>*θwϊŸΕ)-ν fkα’Ψ;HΨͺI>€ƒšσZλlΎ#x¦ΛM[5G’„BΡ£:― b3@ 4ζΡΎ,E§ί4-sš<£ewμ9Αϊf¬ό-ƒQ‡_ρKκi*Ζ,g Β™2>xύ+Ν ½Ί‚ύoaΈ•.ΥόΑ0c»vsœϊΧC¬ψϋĺƜΦ7ϊ›=³Œ:€h…ΗΉP ϊSoΐΌ? όpΡ±V+δz Θšmœ'ΐλε‘‹,Z²„ψAE<~$ώuΖΩk7φZ]φm>Λ;έΏhbϋNG$d~Q±‡.Ž“γN–a;Γ±y|œγ=γ8€o£κΆ±ψΓOρv…}6Œ&y,οm_iάIΘΖ@<–οψVoΔέt™΄™-―οnμ.νDΆΙxI’γεΑθ0GaYήρΎΏαλO²i—Ϋ-rXE$jκ ξ28ό+3^Χ5~ϋνz½ΣάΟ·h$z0¦e¨ΖςόΡΜhΞS“vќpύk α°+γν AKΑͺώρ†½αΫy Ρυ·…Ϋs!DuΟ¨ ? ¨uέHλΫFηώ&~gηl_Ώλ·J@Zρ¬RkΔFδϋα?σΡ«£π›nžΧ΅NοRlLKgbϋ ωΗίdnώJ© KΖ?τΙXψŠΖπŠυζβm.πΔnfVEesΟU#ΟJοu–Σ₯ψ1;iwΆΆ_Ϊ*c[·IΐΛ)ώουΝPρ\WR| πy…]­Δ’ω›FFβΝ·?ψυrΊΟŒ΅ύjΖK=OPiνdq!ŒΖ€:c {*}Η~#-mm¬5΅²²Η‰ €Η'•½cρΕ:zΩAͺ7’‹± ƌθ=šΟρΥΑ»ρ~«pφ²YΌ“–h$ΖδnΰγΎs]7Ζ%}CΓσ$nΠΆ‘«H,HΟβ?:σιdyey%fy–fc’IκMtϊWΔi6YΨκ–Ρ ¨o΄zΚN){αΞ₯q¦Ϊk‚]mOFžŽόBΕZ5ω°r>­ιυ«ή#4ΉόΪΧ†n΅[}9nDrΨ]ΏΘ\γζ\pzŽyό1\–…βm_AΎšοJΌh&›ύoΚ_œς€cΦ¬x“Ζ:ηˆαŽZτΙnΉbDTP}pΟγ@<9³=돭ρΊ’ίc,g|•νΣτ¬Ήa `ΰΫΊηή΅|7β-SΓwr\θχ>D²'–"°#θAk2i^y€–V/$ŒY˜υ$œ“@ »α·ό„u_ϋO²Χ#VτέJοL’Y,₯ςžXš;Ce¨δ{TΞ<ΡiNJ2Mž—α‚΅Ό 2qφ;δΥΜψJΖαΝcSΏΉΏ1”ŠKk7ΪeΟχ½†οηX–Ύ!Υ-f±– ­bΉςΤμVΞG#ž§i4={RΠήFΣ.LBA‡R‘•Ύ ŒV>ΚZΫϊΥ³okkZ%ϊ†¦ΦR|.•΄λk¨-Ύή₯EΛ†$νδ©ΗOλš₯❾ψdΖ`MΏΫΫnρκΑΥ# ΛΓ+s‘r4υσ}αΣ―λVυ―ω"ή°„Ώϋ=qzΆ§y«^5Φ£;O; n8€ΗGρW‡α²Πυύ*ςμ[Lσ+C6Α–'ρθkjq卙…I)Ι΄rΎžκΫ\΄šΒάά\#±Λ Λ5ΣAk¦krjM¦.£¦jIΛ*—ΜgϋΚO^Ύ΅ΕΫ\Kkr“ΪΘΡJΉO"Ά/|[­^Ϊ½Όχ§Κmp±ͺ–δ Φ©NRζ‡ηϊlΝ¨Υ„ci_>ƒ|#V›]Gς5O^FMoP₯OΪ$κ?Ϊ5J^RX’D!•”ΰ‚;Φ§βM[T΄ΧχfX ΄Ζ£‘ξkG *œλkXΝJ.Ÿ#ήχ4υ'aπσH@NΦΉ‘κA8ώf±u-ZγQ³±ΆΈν³Cl ξ#ŽΌφΕC-ύΜΊ|62K›XXΊ&ΡΑ=yΖj²1F §ƒE:\Ί½ξίή:•yΆΪΙ}ΗQα αρ?ξA‘53αΘnj,³ι'ώ€ΤΟψMόCAόƒTΏ©\j†ηύ8 ’_-zc1ŽžΥ“₯VJi₯οyω[±ͺ©N. 7ξωyίΉ΅ΰ‰d“SΦόΖ-ζYNϟβ9ŸΜΡα₯ΊπLjνlΑk·HŠ’ύζPN@υγ#ρnΓPΊ°–i-%ςήXΪ';Aʞ£‘νV<>ρ¦’mJ]5BŸίΔ¬Η>˜^y§R‹χŸ§ΰ*uWΊ½‘Ί΄»²ψncΎβc|#q‚ͺWΣ·9ͺΏ Ώδ hŸυίϊˆ5[αμλKϋJyn~Ρ-Δ¨Λό8ΗΝΟ₯Iΰ-{AπόΙy©ι—wZ”3yΛ»UW`―~sωΥa”Ή[—VN!d£Ρή0ηΕΪίύO£Ίi,υmVΞί]°Τ,5‚$šοό-ƒΣŸJγυ»ΕΤu«ϋΤR‰sq$ΑOP‰ΑόλJλ°[¬)|v¨Ϊ₯£V`>€fŠτε;8ολaP©]KoK™ϊυ¬–ZΝε΄Σή9 ™ςήηήΆώ!#jXΆΣ΄ΩEƒŽZεζ•ζ•ε•ΩδrY™ŽI'½lAβf ±G|ίfΩεμdVωqŒdŒτ§(Nρ’³kδœ-(½4<"μš‰ŠΩ”dzA¬X5kˆt[-DfΪwYΰw)ιΟ°¨m/ξm-ξ`·—dW*UΪΰ>£ΒͺΣT½ι9uiύΘ—W݊DΧήtΑ„ΓO88ύηώ‹jÜ|ωςΠ:Υ°ρ^΅ai­₯ο—c ΎRsž€f«κϊώ₯«¬K¨άωΒ"Y?v«‚~€T¨ΤφM+=7υςσ)ʟ³QMέk·§Ÿ‘Σx–iΔϋl9ω&·UφnGκ:v–ΡΗρZmδ(3Κ>₯MrZ­νΦ¨ΊŒσnΌ $Ϊ£•Ζ8‡jŽK©/5΄έΞVYd $‘y<Άτ¬ΦςrΏε±£Δ.~eόΧ;_ iš•ΞΏ%ό2Η΄•Yœ$~Ή½ωχ¬O x©ό<Ž‹€ι7ΑδΎξί{;+gŠΧ]_NΣν―e:υζ―s-³ΫΕ‘Ί…έŽ~cμ+…‚8#‘U†ζr”€»t·ζ,G*Œcί­#ΉψΡn ρυγy’9š8ε!ΞJΏt{q\5v~5ρ^™β›DΊ—I{}{’\€ΔΖκ?Ωνώy2ΊŽP’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š({ίψϊΓωT=οό}?αόͺ (’Š(’Š*yΏγΦίώόκ žoψυ·:‚Š( Š( Š( (ΑUˆω[₯%O7όzΫΐΏA@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ήΗΣώΚ ©ογιεPPEPEPSΝΆπ/ηPTσΗ­Ώό ωΠQEQEQEO7όzΫΐΏASΝΆπ/ηPPEPEPEP£ιZ6“.§α˜₯΄FK›–`Iωά/SΟ±Hξ΅{§·±UiU ›Kc uΗ©ͺΛs:²2Ν(dP‡?(τ•{Γ:‰uλ+ܐ±H7ΊxoК…ΜΤeυ"Ρτ»­^σμΆH­.ηs€“NΡ΄{έfι ΣασYFζl€ͺ=I)¦\BdHk”Ιθ}:ηΪ§Ϊ6›DϋFΣhηuΏκ*Δχ±/“/ ,nϊdTϊ_…5]NΚ»X£ϋ4₯€‘δ 9χ­=NϊΩόΦΊv™}‘Ί,σΈeŒ=?­&¨μ>h¨ ΪΧR’=H-ζhζ•Ύcζ•—©­θχΊ-ηΩ΅ΌΉ ξRCPkVΧΑΥΝ΄S,P‘•wΗ“*»άVf§¬\κvZ}­ΒΗΆΙ Q²ƒΈƒΌsΫ»)ξ,u^ΚΫΔv₯§kd$I4 Ζ…°zsιNR’H%)$Ž"ΧKΊΈΥFš¨οs!I.ΞA'ι[ώ-²ΌΣτM*ήσN²· ΉVβ γqXž!³–Η\½΅–fΈ’) ™O%ύΟ½nkŠα_xh`ηΜΈΠΝ κ˜ΫΦ,ΒΡ4kνjθΑ§Cζ:ΜITz’j}wΓΊŽˆ±=τ*!—„–6 €ϊdVΧ…–WπOŠΤpD9 Τ¦γŸΣu¬‰πΆo΄―Α‡w”g―λC›Έœί1¦ψGVΤ,νξνβ‹μΣ†+#Θ sŸzΜΦ4»½υ­5ΌΉ€ Œδz{ŠθΌC#xb0Ηc4μG©Ησ4ž=f’ΟΓr9άν¦Η–=M“o_0Œ›zω›:V€Λ©ψf)m’ζΑ₯˜~w ΤσμkΞZ•ngVFY₯ ƒjηεƒ’ͺŒZέ•΅»7΅ κΊ™a¨Δ‰oz ΖUΓ‘μqX5­«Ϋλ‘iΦ «-ψ²dDϋAm›qόΰ c§lVMQaEP^₯hΪLΊŸ†b–Ρ.lY'ηp½O>ΖΌβ₯[™Υ‘–iC Ϊ„9ωG τ©œ\ΆdN.[2Ξ‘₯έjχOobͺͺ6–Ζ@λSF₯έjχŸe²Eiv—;˜(u$š—Γ:‰uλ+ܐ±H7ΊxoКνυKπ½Ÿ‰―“ o\[ZύΧ›Ηό¦RiΨR›NΗ9αέ>ΧXΠ΅;4…΅­ΗΪ`™}δ­!°΅ΣΌ//!WΏΤ$ΫkΈœΗύηΗΏOΔVo…οeΣόAaqΓ‰•HυΰΘšΥψ•tσxͺ{|*Ah« H£Wh=>¦‡~ktάNόΦιΉj-'B𾝨_i«¨έκψY$*¨ŠqΖ;τόύ«?ΖΪm•ΝΞ˜₯υ²ά,Ls°ž£?•]ρ O7<1,J^8ΜθΔ α‹ŒΠxύOA(Ϋ4zrCΥ~Ώ‘©‹Υ?QEϋΙϊ”όoamas₯­œ+Λ§Ε+Ÿ™ΙlŸ«x7J‹Yρ₯•Α"%ŸiΑ!Tœ~8ΕiόERnτlβWσjgΓΖ–AΈ%d>» ;Ώgqέϋ;šv«‘xŽ=RΞΟI[­ yνηI ,³λ‘XΎ²΄ΎΤξγΏ…e,δ‘A'†Αώu£ΰ+Yν΅=q"hΦ ’BΓO~†ΈΨ₯’"LNΘHΑ*q‘ιB[Ε1%ΌS:ΩZ[ψgΓ·πͺOp“œ—*ΐ ώ΅ΞSšYΩ‘3΅IΘ\υΗ₯^Πτ]G]Ί{m&ΥξgD22© η܊*ΘΦ*ΘΟ’•Τ£²·ήSƒΞi)Œ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Šžχώ>ŸπώUO{Oψ*‚€ (’€ (’€ žoψυ·:‚§›ώ=mΰ_Ξ€ ’Š(’Š(’Š(yΏγΦίώόκ žoψυ·:‚€ (’€ (’€ (’€ (’€4u-oQΤ¬ν­oL°[ D₯Tmγ@Ιΰw¨τRχHΊϋFpΠKŒ0A„ R’••¬++XΤΦ΅ύKZςΖ£reHωD Gΰͺκ7Rι°XI.m bρΗ΄|€υ9Ζj₯(€ )tvώ6ρΛz*£j–€ϊ‘šη(‘Ε=ΑΕ=ΡzΗVΎ±ΤŽ‘mpΛxK+Δ–λœƒλ[?πžx“ώ‚_ω/ώ&ΉŠ(q‹έ Β/t_Σ5‹ύ2υμnZί;˜CgΤ I­kڞΆΘu+¦˜'έ\QψγY”QΚ―qς«ήΕ»FκζΒΦΞiw[ZξςShwž@ΙηΦ‹νFκώ;d»—Μ[h„1  mAΠp9όj₯μ‚Θ(’Šlλ>'Υυ­:ΚΗR»3[YŒD₯TcŒH'sXΤQ@Q@Q@hκZή£©YΫZί\™`Ά‰J¨ΫΖ:“ΐοYΤQd+&:RHΞ2ŸB:TڍνΖ£{-έδžeΔ§.ϋ@Οθ8νUθ’Αn¦Ζ‹β][E‰βΣΪ8˜ξ(UXgΤ*†£u©]½ΥτΝ4οΥ›ω{ ­E.TΓ•'s€ƒΖώ!‚α‹PΫjG“ΐψk*χWΏΌΤΖ£qrΖτ"U#¦0P’…­”bΆFξ§βέoS²6·—ΜΠ7 ͺŠ»Ύ€šΒ’ŠKa€–Α]—‚ΌGiαΟψ…‘άk‘-½° Β―;›wnΉόq΄SQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE=οό}?αόͺ žχώ>ŸπώUQEQE<ίρλoώuO7όzΫΐΏAEPEPEPσΗ­Ώό ωΤ<ίρλoώuQEQEQEW£ιZ6“.§α˜₯΄FK›–`Iωά/SΟ±+EΏ³±šVΎΣcΏFUy m>ΌT)ίdBφFmΣψώΞΞΣR°:}²ΫE=”s˜Τ’1o_Β²4]χYΉh4ψ|ΖQΉΨͺ£Τ“š’jγRMsτVΎΉαέGEŽ)o#C§ ,nIτΘ«:o„umBΞήξή(ΎΝ8b²<@ΑΗ9χ£ž6½Γž6½Ξ~Š»¬iwz=λZjysΘ τ χ±‚5Ιm ™myΨ+‘Cΰχ#ӚnIkprK[œΥ©o‘_\k€DˆoU™J—ʌž ‡Kξ΅9§ŠΡUžšgΛc ΈΟσ£™™h­ G½ΦnZ >1”nv$*¨υ$τ©υΟκ:,qKy%8IcpκO¦EΚφ2½dQ[š7…΅M^Ιν!AnΠςH3z ΥMgF½Ρ€5„O4~bΰHώ†Že{\9•νs:Šι-Ό­άZ$ιlŠd]ιΚ«#/¨Rk'JN·gowΪn9cn7A£™=ƒ™=Š4Ww¬iZl6-xmQd³Έ… Ÿέ‚ΐ9ϊΧ₯Ψ\jš΅šΈΈq)8ŸzQ—0F\ΕZ+SΔΊχ‡5WΣυ4EΈU ς6ε τ Φ]QAEθϊV€Λ©ψf)m’ζΑ₯˜~w Τσμje>R%5Ο8’ΆΌ₯E­xŽΚrDYŸiΑ qψγ΄χžΥ"Ώ΅:tzcG5­Θ‘˜»†;Πηgk¬qtV†‰£_kWF :1ΤnbH £Τ“SλΎΤtE‰ο‘Q Ό$±°e'Σ"Ÿ2½‡Μ―k™QJ£,8υτ¦P”W~4·‡΅¨΄θšξβΖc|δμN>Qθ1ώzΧSssWAα―μ{{;λν]Vζx‚­½™bΎa=IΗaώ4Ϋ²ΈΫ²ΉΟΡ]~Ήk¦κ>[°²|Ιsφi"W%Œδgόυ§E— ψsLΌ»ΣSPΌΤ7Ώο\…γη"§ŸΘŽ}68κ+£ρ–gjϊ}ξ™Ckn&³nςΫΈΊM+FeΤό3ΆˆΙs`Μ ?;…κyφ4:‰+ƒ¨’ΉηPzΡVhQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEO{Oψ*‚§½§ό?•A@Q@Q@O7όzΫΐΏASΝΆπ/η@QEQEQE<ίρλoώuO7όzΫΐΏA@Q@Q@Q@­ΜκΘΛ4‘mBό£ΠzTTQ@ΔXάάθ²ci€ΐpOΝώ"™α[(G‡΅mJϊβψYFR)-­i”ŸοvΐΟσͺ:w‹υέ:Ρ-­5HaU£Gΐτ8ͺš>½©iK&Ÿrc3¬R‘•Ύ ŒV|²ε±—,ΉyN―R6oπFΣνξ`Άϋx*.1'o$tώΉͺ!‘‡€<1c±šv#Τ‡γωšΗΤΌG«jv―m}xΐΞ$(Q@ `p=‡NηQΊΉ°΅³š]ΦΦ»Ό”ΪέΗ'2yυ€ ΦύΑA­ϋ/Ž_|–cΈ>"Δυ5Πkzf§qρ.ΖϊΪ)^ΘΌ.“¨Κ,` ΓwO_ΞΌκϋQΊΏŽΩ.εσΪ! ChPtλ» iψJΪζ;ϋ GE„Ie―-Ϋ“Έ0'ŽJαmζ’ήtšhεŒ†WS‚ξ+oRρv·©Y5­έσ4 0Κ¨«»κ@œΰΫΠΚpmθiψYdψ‘-7C½Jn9ύ7Qȟ fϋ@!όwwωFqϊώ΅Νι:­ξ‘sφ:α ”€ŒG‘ƒSkZφ§­²Jι¦ χWT~ψΠΰξώFeP€«:ŽEhjuήSNJΈ?ροovD‚5ΣΒyβOϊ δΏψšΒΤοξu;ι//€σn$ΖηΪ8 RMΆDT“mŽΌΣ/l­­ξ.퀊…έ°α…[πΦ‡6ΉzcF[D7Ο;}Ψ“Ή>ώΥ₯­κ•­­νΑ– eΫ•c’<τύ_ΤτA0ξ|67ών[8Ξ>π>¦›ζ·˜>n_2‹5xn£·Σ4¨Ϊ-"ψς9•»»}yόύλnσQ—Kπη†/νν ΉAo< η&δ°ύx?­sΊ―Šυ­VΙν/ο|Ϋv •ς‘sƒ‘ΘΤZ?‰5]‡O»1ΒΗqFEuΤ*9‘<ŽΘΦρΊ΄:W† ”™,²ΘFΙγ?‘]ngVFY₯ ƒjη僀Τoξ΅+·ΉΎ™ζΊ³/j­WΩY—ΩY…ijZ₯¦YYέίΪΌχ‹Ύb?x0@ΞzωΥB4Ρ¬¬R2ΐ3œ ςq]gΔοΑβ-rμΩvp¬Α†ή1ΙΗnxϊTQΘQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE=οό}?αόͺ žχώ>ŸπώUQEQE<ίρλoώuO7όzΫΐΏAEPEPEPσΗ­Ώό ωΤ<ίρλoώuQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEO{Oψ*‚§½§ό?•A@Q@Q@O7όzΫΐΏASΝΆπ/η@QEQEQE<ίρλoώuO7όzΫΐΏA@Q@Q@Q@₯hΪLΊŸ†b–Ρ.lY'ηp½O>ΖΌφΦήkΛ¨ννci&‘Ά’/Rh[™Υ‘–iC Ϊ„9ωG τ—αQγ;-ΨΞΩ6ηΧaλΦvpM™YΑ6WΤό¬ιΦR]OnC2yr)υ³`.η²·»‰‘žΰZ‘ά3ζpEuŽξ=O^kΕ‘PYL.KŽ7qΧί­Yψt‹w€Νœ­τWΗΨlŸόv“›IάNm'~‡)sανBΪ}F)£E{WŸη±ŒzυkMπŽ­¨YΫέΫΕΩ§ VG(8η>υΣxŠbήŸSsϋΝR+H™½Y7nΠEdx†FπΔaŽΖi؏Rζi)Ι^@§'oλ‘Ξλ]ޏz֚„^\ΐΖr==ΕkΫx+[Έ΄IΩΘ»'•VF_P€Υί8xΌ/$ηvν>"μ{zθ|Os§Ϋψβ7};RΈΤ he_`(ΗNΉόhs••ΞVV<ηOΣnoυ4°‚<];ηnΞAΟN†΅ξ<­ΫΨΛu%²mˆnxΦ@]WΤ―ω5§‘Μn~)Η3[΅»=Γ³DύTνlƒοšΗ‹\»ΡόK¨^ΫωrK$’£‰A*ΐ·9Α\oAΉI½ | ei}©έΗ ΛYΙ"‚O 1ƒόθρ •₯Ώ†|;qo €χ 1™Α9r¬Ολ\τRΙ&'d$`•8Θτ‘₯‘Ρέ™;Tœ…Ο\zUrΎkάWΝ{›>πΖ₯β‹Ιm΄˜γi"Μs#…gq ΫΟ$3.Ω#bŒΎ„Z^ƒYžυΗ‡VψέΙo±– ³ΎJφιϊV\ƒ°0pNνέsοTX”QEQEQEθϊV€Λ©ψf)m’ζΑ₯˜~w ΤσμkΞ*UΉYf”2 ¨CŸ”zJ™ΕΛfDβε³5Ό%₯Ϋκš”Ώnf[+Xζ}J/aωŠθ4x΄ίN-‡M•€Ϋ’ΨKŸ-°qΉ Σ™ΰψχρύ‚ζώ•ΩhΛ©΅η„Ÿηe‹1ηωdω{°wnνœγ―zΚ£Υ™T–¬ΰtΟ κZ”rΙj°ωqΜmٞ@ 7γψ~tšŸ…υM2ΑξξαEŽ9<·@Μ‡Ά@θoΒ·γ$xRϋρ<_εW΅γ›Oηώ{ZθtωελΘ|ςΏυδr:7†u=^Ω-bE· ·Ν•Β)oAž΅CUΣnτ«Η΅Ώ…‘yΑη#ΤΑΪάΙ¦§€Ό>Ϊ…­ΤφΰΚ?Ρδχ½‘Χ?ΖρΝα»m,›EŠΥcO΄ZDtӌΫ~EFmΏ# ΄m&]OΓ1KhŒ—6 ,ΐ“σΈ^§Ÿc^pzΤ«s:²2Ν(dP‡?(τ•\bΦμ¨Ε­ΨQZZ–‡©i–Vwwφ―½βοΨή 3ž„~u›TXQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE=οό}?αόͺ žχώ>ŸπώUQEQE<ίρλoώuO7όzΫΐΏAEPEPEPσΗ­Ώό ωΤ,ަT™sŸΞ’ Š( Š( Š( €·š[yh$hεB]N>’£’€7u/λz•™΅ΌΎgΈeTUέυ k?MΥotΨξRΚsάΗεΚ6ƒΉ}9u=*•ΉRV±*)+X»>«{>—o§K9k+v-{GΚN{γ'©κi·:ΥΝ…­œξΆ΅έδ¦Π6ξ9<“Ο­T’‹!Ωο΅«ψν’ξ_1m’Δ6΅Aΐηρ­[OλΆΆkk ϋ‘vδVeˆΝsτP➍ Ε=-XκV:‚^ΫLV鰐€Η'©η9κjΌ²4Ό’»±f>€Σh§aΨ(’ŠkxoΔZ§†ξδΉΡξ|‰dO-ώE`GΠ‚:ΦdΌσI,¬^I³1κI9&™EQEQEQEQEkψ_VM#S2ΟšΦhΪ γ£nΈχ«:«XΪZ!ΠυΛΙPɟ²ΌmŒrw€τι\ύ<Ίά—n\TΌŽΕ¬b-ΪapT¨9qΖsŒΤΣλzŒι~²άn[φVΉo*r½ΈΑτΕfΡNΘvFΎβMWF‰’ΣξΜq1άceΉυΑKSΤ.΅;·ΊΏ™¦Έ,ޞ€ͺ΄QΚ―pεWΈSαΣF²±HΛΜp3ΙΕ2Šc:‰ή%ƒΔZδ?Ω₯²μαX-ƒ Όc“ŽάρτΉ ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  ογιεPTχΏρτ‡ς¨(’Š(’Š(©ζ[ψσ¨*yΏγΦίώόθ (’€ (’€ (’€½*k«[‹I]A,FvΘ…OδjH Ž’½?^ΥnυΟƒ°ίkR «ΔΥ<¨¦**μ'υύ(Μ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Šžχώ>ŸπώUO{Oψ*‚€ (’€ (’€ žoψυ·:‚§›ώ=mΰ_Ξ€ ’Š(’Š(’Š(―PπΎ€|;π–ηQŽΦΫPkLBΠ]©’π™έ·=xλξ=+ΛΖ23Σ½v~&ρfsαΈ΄ιo§ιβ΄Je—Μyό;wμ(˜Φ/Ξ§©OxΦΦΦ¦R“mΘΧ•{t©΅-RΣ,¬ξον^ {Εί±Ό g=όκ„!hΦV)`€Ξy8³βw‰`ρΉφiμ»8V `Γoδγ·<} BŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  ογιεPTχΏρτ‡ς¨(’Š(’Š(©du0B ό˜ώuzPEMukqi K¨%ΘΞΩ©όC@Q@Q@Q@Q@Q@Sε†H‚ct»Σr‘Ή}G¨ΰΠ(§ΝJcž7ŽEκ€ψeQEQEQEQEQEQEQEQETΖΦΰ[ “’ܜ J€ϊg₯C@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ήΗΣώΚ ©ογιεPPEPEP@$GQEιϊφ«w|†ϋZ]^&©εE1PWa8$―ι^a^‘α}Hψwα-Ξ£­Ά Χ:˜… »S$1α3»nzρΧάzWληSΤ§ΌkkkS)ΙΆdk€Κ½ΊP:+KRΠυ-2ΚΞξώΥΰ·Ό]π;ϋΑ€rsЏγhΧΐώ’ιξo΅M.ζ{H­Zx"ΪΚ.ψ@#kŠοΐ:•σiΎ!F½Ή)o¦HΠ©•±‚ΌρjΚ³j:PQsχŒΖL–j<<Ϊ)mΐ,|ޞ tώ΅Ÿ{‘ήΩk‹€Ξˆ/Y0‘|cŸΔTκ7w³ΐΧχ—6Κ™€gΫΘΞ2}«»ρEΔΏμΪ8™–Y­εBWnOαƒK™ΒΛɏ•TΌΌΡΗ[ψ~ώ}}΄hΡ ς³)RγQ“ΟΠUλίkvzl—³[§—έ",€ΌcHν].†Κ G8γΩVwΓι€—Zρ˜εΌΫ †|Θδώgσ©u%Ίμ™J”6}[G3‘h—ϊνΣ[ι°ωŒ£s±!UG©&¬kώΤτ(β–ϊ$0Jp“DαПLŽυ·α%–Ox©,Α7$C½Jn9ύ7V8‹Z_³’WD7εmΌΙŽ£<ώ\u«η““ΧB9"’ΪΉ»πΏN²?Ϋώ§Έ·Ρ , χd‘³·?χΟηŠζ|I―_xS7ڜŠσm‘*’Œα@†MuίQΌ γ‹HiΌ3’±<~η΅©‰ιϊUγxϋΒ:­–¨ϊΎ“nn­.•B»’ŽQ±ΤtόΗ₯y…zΒ8Μ βJL‹{}&hΨγ»`υω yν0 Χπζ‹q«_ΫͺΫΜΦ†eIeD$(γ9=Έ¬Šήπ]εΜ> ΣΰŠβd‚K…ίΉ ίQΠΦUœ”Žζ”T\–ΖŸŠ­’΅·Ό†ίΓRZΓ›υ™Ο±žxηλޝ€6•«iz’ '΅²yVa#1,\}y¬j7²λ΄——/n.d&•Šΰ9ΐΖqΕ^π:—·ρ ,ν§HަΉhσ7_—™¦₯ZΙi―EζrΥΠΫψ7ZžΥ'KeΧzF(vJΒ„š?0aw ηΣ5άψŠ;Ζψ›lΡ¬„a1Σ` »πΞμΦυͺJ-F--ΧΘʍ8Ι7-uKO3ˆ†y―Φ(]Klγή•³α-ZΖΞK™a’!™DrhΗΈ­‰Τ~#ίGΜΆΑ$’C$Η/ΉΞ?:»αy4ɀ֝m¨+9|Ι.$ κϋΗόk˜™$œ{&ώf΄πρm©wi|ŒψzMbξ₯XΪΕeΩ(2cΖx{Šgˆ|5w₯››†XE’ΚU1(fΑΒΦΓΓS꺜+,·9ŠΚ&Θ统aώzΧ5^™$:v©β>Xu‹&Ά·)aέ½2ΒΈ/(]{RU(Ή:˜ΣΓΥη“Ύο_O!b)rE[e§―™B•H δzWGαO?‡‘Ρt&ψ<χέΫοuΗelρ]g)ΥόmΥobΧ‰ή^‘‚Rkf^Ρυ{νλνmΓA)IΓΠƒΑ«Mw˝ѕ#9D Aυΐk&Š9c~kj>y[–ϊρη†uˆυ <©p IŒ¬ˆz©ό©|W¨ιΊ¦¨.τ4i±Όć_r‰2rWΠc`V5Ι;Ζ0Ν .…αν94Ν-ˆiώm\0Η,~£§=Έκ( ₯³Ή–Ξκ+‹gΩ4LΰcQQCWΡ‚vΥ\Ν%ΝΔ³ΞΫ₯•Λ»c$δž*]:ώλMΊ[‹š€Ζεττ#½V’“ŠjΝh5&Φ枱κ:ΒΔΊ•Οœ"$§Θ«Œυθ₯Y·ρf·ofΆ±_Έ‰WjεT°ˆΝaΡQμi΅ΛΚ­θ_΅š|άΞώ₯‹;Ϋ›;Ε»Ά™γΈRXHNO\ϊΦ¬ώ.ΦζίΎτνu(Κ#@=xΗ_~΅…E9R„δ“jN*Ρm†W†T–'d‘ee8 Žυ«©ψ“VΥ-΅ύΩ–Cm1¨δ{šΘ’›„dΣkT%9E4žŒΥ|Cͺi14VMLrP¨aŸ\qT΅ λBι/fi¦n¬ί犯E œTΉ’ΤδΧ+zYάΝguΝ³μš& €p~†›q4—7Ο3n–V.νŒd“’j:)Ω^β»΅‚€H ƒ‚9QLGgγ_ιž)΄K©t—·Χ°‰%ΚLLn£ύžίηšγ(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€'½§ό?•ASήΗΣώΚ  Š( Š( §›ώ=mΰ_Ξ ©ζ[ψσ (’Š(’Š(’Š(’ΊΘώkξΕ|ˆγ+ΊeψΞΦ¦SŒ~&Ta)ό*η'EZuαΤΏ³ΕΌ†χΜςΌœ|Ϋ½+gTπ^΅¦ΨΙu<ΌQ Κ"•]’x β΄l$ξ9Κ+ͺπ/…δΧ/`ždτε›Λ™L»Xρž^β™β ^θkΊ"b³Œ,Α˜)l/}){XσrίR½”ωyν‘ΜQW―4««M6ΖώeQoy»Κ!²NΣƒ‘ڍOJΊΣa³’ιT%ά"x°Ωʞ™τͺζLŽVΊh²?‡Ϊϋ±_"8Κξ™Fώ3…υ¬[ ώϋZώʊ·ΐ²˜δ;pTyό*UH½™NœΦθΝ’ΊKίkvzl—³[§—έ",€ΌcHν\έTd₯³£(όH(’»YhΝaoz}z[1δͺ[¨Ο\u'oλωάcΜμaVͺ₯fqTχθ±ί\" *Θΐ@ AHΡ;«…QHaEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPχΏρτ‡ς¨*{ίψϊΓωTQEQETσΗ­Ώό ωΤ<ίρλoώtQ@Q@Q@wξζΆρ…œρ9ίoo ǞΔd:ακζ«©έκΧBγP›Ν˜ MΫBπ: *o$ˌν½Ώΐϊ£k‘Ώ½HRyݱ‚pŒŽ2OaV΄­BΒΦηXv‹«IrΠIΠ’PΚ υ,1λύkΟ­η–Ϊxζ·‘£–6 §Hξ+sRρŽ»©X΅₯έρhaΒΖͺ\{¬ηI·¦Ζ°¬’Χ}Γαωnjτ¬Οoθj‰cxόC©‡FSφ©:ŒͺM%ΌΡΝ΄rΖΑ•Τΰ©­_ΕzΦ―eφMFτΝoΈ6Σ/#§ Z8Ύ~df₯NVlψŠ'›αο…₯‰KΗO3†/ΐύ 'ΔTh-Ό5o(Ϋ4ZlaΠυSοωΕΠόO«θpΌZmَ;ŒlͺλŸP8ͺ–‘u©ή=Υόο<οΥΫω{jˆΣ’–»+ώ%Κ€\tέΫπ:ο‰ws[xΒΞxœο··…γΟb2?ΐڜΪΗΔΘ/ξR4š`ε–0BρdŸJδ5]NοVΊ„ήlΑnځΠ`I₯j7ZMτwš|ΎUΚd+ν ŒŒ#‘£Ω~ο—­¬Χχœέ/s­ψ}4’λ^ σ·›apϟβ9ŸΜώuΓΥέ;TΌΣfž[)ΌΉ&’ν •n£‘νTͺγI³9NρK΅ΒΊ?‡€Βc¦œnnΰ \εnιή-ΦτΫ(­,―|»xς<€8ΙΟRΉκkh4ΩΟZ2”cΤΛՍΦA½ζj΅iλZφ₯­ω?Ϊw>“Ÿ"3ŒύΠ=fT»_B‘~UΝΈQE‹ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€'½§ό?•ASήΗΣώΚ  Š( Š( ₯‘ΤΑ ƒσ.sωΤTuι@5Υ­Ε€. –#;dB§ς4Θb’ypΖςHz*)$ώ€EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPχΏρτ‡ς¨*{ίψϊΓωTQEQEP ΤQEz~½ͺέλŸaΎΦ€W‰ͺyQLTUΨN λϊWiZ…Φ•¨A}a)Šκ܏€p~‡Šτo κGΓΏ nuνm΅ΉΤΔ-Ϊ™! Ϋs׎ΎγΌοXΏ:ž₯=γ[[Z™H>M΄{#\>Uν˜Ǎ£·ρƒ4Evχζo±ί,C ξ!ρΨτόΗ₯yέzFlΎ―o΅o2!Ž & ϊ|†ΌφQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ήΗΣώΚ ©ογιεPPEPEP@ΖFzw’ŠμόMβΝ:ηΓqh>ίOΣΔh”Λ/˜ς>1ψvοΨW5‘Ocm«[MͺΪ΅έ’6d[i~~Έͺ4PEγ/\x–{eϋ> /Pattern << >> /XObject << /Image17 149 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 151 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 152 0 R /Resources 153 0 R /Annots 155 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 152 0 obj << /Filter /FlateDecode /Length 154 0 R >> stream xœ΅TΝn1ήΝ‘σœŠ²Uqƞρί‘ ΰ€„΄R”C4Ϊ΄€pΰ©x Nπ}‚ϊ0φfγmT@TνZŽΗίΞxfΏoβh…Ζγή`΄²Ύ[Β P!κθ‚EΞΫ{qJΛΘYο0‡wecΠzNF[›τ»€C8•$+˜=ι>-ŽζŸ%ƒIΣ&-9a H‘ΰ|~«T 8ΩƒΧ2V£L:gΚCŽΥ>X­˜=hΆ”8$½NΰλF3Ω+±Ϋ€LI) μ+S;lΚNΛ:ZqRš’F?π½±ΕpΒ;ϊΰ“Α5‘Sρ­œΡžΓμωΩιVΣ =Ήk”ir m/Zϋήΐ΄:¨Τm}tTοΧUύͺΜΫ΄ϊ^ο6πΪ—π¬½Λ2L*©b»–iνΗ”μΜύUΙ¨-©@²ŽFK΅c¨+ ¨M―β: ―‘M]‹$ ƒ¨,[iٍΟ0·‰"0'Κέ¨±rΧεšόΑφ ¬RύurQύj€ίך%!'’h^vyT]Φκͺ‘oΝΦ₯ΌΡwͺ«zwςmς³ˆ}Ϋ‚)°ςΜhΆΛΎ eω€ύΌSΡΩτEc€5Gh7B5“w&Yέ&~Œ†ϋ9ώp/ίoΖQˆ6™« w†ud‰f/–Ησ:ΐΣ³ ]βΔpπ­dεη"χWͺOLWΐn :±Ώ¦Fαqr?ΗœxO”^―ϋΗ†cΈ)¬Π -iόύbL³ endstream endobj 154 0 obj 568 endobj 155 0 obj [ ] endobj 156 0 obj << /Subtype /Image /Interpolate true /Width 968 /Height 300 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 158 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐ,Θ"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊŠ(ͺQEQETπΗ­ΗόωΤU3¨2pΛλΧΨP E]΅o΅uΰΆvΏi ^OBuΣ5ι^ψqw¦ήjoβ;;k‹UΣ¦dd”8Ža΄ŒγqšςŠ+½ψo}’άίiΪ.₯αΫkΙ'ΨoRΣεΗo­rή+·ŠΣΕΕ½²ΰ†ςhγAΡT9~T—EtΎπF΅β6Ό±†(νl\H#VoAž΅•―hΧϊ’φ:­»Ap `zGP}θ^ψk}·H»Ώ²‰¬δΈ‰ε·iG™ε‰_L{Υ½AηψΣs€ΛgiΛ,ΐ@s΄„Φ€<ʊτλKoψΖfΚΗCN«em%ΔC;2Hς¬9Ÿ΅pΆνφ‹¨κ–κ†ΓgœK`Η½eΡZqhw²ψvmm>Αβݎο›yττδVΎ‡ΰ-sZΣm΅  ϋε€–IB„Ϊpwg§4ΚΡZή&πξ₯α­@YκΠyr2οFSΉ]}A­ϋ/†^%»±Žε-‘€O28%™VWΛΫρΕqTVΦ…α­GZΥηΣ-R8ο ViwνΪΑHηΎOJοΓβέ›w;Θ§ΠŠξ<#πξ[ύώξϊ(ζ³ΨqFA`GZ™ΥŒΫΝ¨­xrΓ²Α£δn™K/•(~+fΣαΏ‰.¬κ;8ΧΜO1!yUdeφSύiΊJνΗQOš'‚gŠdd‘«+ #‚ 2¬ŠνtMΟPπ֏2Ϋ©Έ}am'~rΘFp}±ZZΎ‡₯Ϋάψ¦βTϋ,6PΛj2p†@#ŸPk?j―bΉηWmΰ- S2ΓͺΫXX_Βκθ°άJ£œγ8=ψ5Ιω]κΏg#ŽY¦ςΥΒ©-Œg°ͺSM΅ΨVΠ«Ez$nαΆ1Gn5_=ΌΧ7iηιY Πγ>;‡JΥαŽe]βD •$!#‘ψTϋX΄Ϊθ>FrTWM¨ψ+Y΄°žωνΣΙ‹ζ‘@^5λ–^άUoh©βιΪd¬Λξ|Β½vͺ–8ό«RRΨM5Ή‹δΙδΌ·ςCl/΄ν݌γ>Έ¦WcρΔςj—―€ΩG‡a)KkxΠ•Κο'Ή<ώA‘ψ \Φ΄ΫmBΖ(>Η9`%’P‘6œΩιΝ1­­βoκ^Τž­—#.τe;•ΧΤέ³ψiβ[½>;€΄‰ ‰ζG“*Κλκ\PE\³Σ/o5DΣmνδkηΔ!Ζpκzc9ι]eΧΒΫ YαΆdŠ&–GIΑ ΄d©οœβ’)'‘#vŽaδ;U)Ε꘬ΜΪ+fλΓz΄ϊ”3FŠϊz,“όγ61^’―kΊ}­Ώ‚ό9y *—7&6AœΎΧΐΝλK™ΜQ]?Œτϋ[?=€+\iρΝ)ω܎I­Q‘jz/„΅Qs¦ι³Ε W7>j΄‘Ζ?ΟZ^ΡY1ςœ5¬Χ·Q[ZΖdžVˆ:’k’Ώπ.·gi5ΓΕ«ξ•"™Yw$U9%£bI³—’ΊΏxZMrφ ζHŸNYΌΉ”Λ΅ΰuξ*?xFχGϋ]ΩXŠΜV0³`₯Ύ^:τΕO΄7(r»\ζ(­νΒzΆ·jΧ6P · ·Μ•Β>ƒ=k;Xο4{η΄Τa0Ξ£8' ŽΔΤU)&νp³ά₯Eu0ψ_–Φ –Ϊ1η`¬m*‡ ˆN Κ‹B½—_:2"}Έ9nαŒ€Iηπ€§³VeΡ]=ρ΅Ϋ{ €ΆB°F²)‘WΤ―ω5“‘h—ϊεΣA§Cζ2.ηbBͺROJβΥξ¬Ξ’Ά΅ κZqK}yNhœ:ι‘ή­Ϋx'ZΉ²Šζbt–ΟχΌ³ύ3Yί  Τγ֟§\'ˆuMv aQy,γo89Η]€ŸΖΌYX«RCGjλΫβOŠΝΌQj°ςρ‡ς“yΑΘΆδηί4ΐ«ρ4γνpτ’•nόi†Cβ 2A˜ΫL‡ ΑΑnυΒκwχ:¦‘=ντžmΤνΎGΪqϊoΪψΔφΊXΣ‘Υ_μb?(#Ő˜Ζ7'§½ 9•GΈ¬ίAšοώ8£\°V* ‹œqχk›πη‹uΏ Ε4z-οΩ’f ς‘ςGOΌ¦κŸΌQͺισΨίκ~m¬λΆDϋΨΚ0OR(Τόq―ίiι²κNφ-•#b†dμ c$cίλ\Υ!)I₯³Kυ[α䏄όlΡ±Vϋ CΌη\Ν―ˆ/-ό5y‘ͺΒΦWR¬ΜXκΐΊs£§8όλΞ.|Cͺ]G}χ[’φeΈΈZξ:AN“Δš»λη[75BA3ͺͺη  ΖΕ%FKgΣόΏΘJπ,ϊ%Μώ!:=–¬Žl&σζΌ”:ΏϋΐΌNOη\η‚’{―‡~3·KΝΆήMƒΠΔ“ωY—_ΌOr_ΜԈWF‘aŒ) 0r6υχλXΊ·¨θ7Ώjnžήb6’!‡‘ƒB₯+?—ΰ[ Omπ^ε§R‚γUV‹wΖΑΘΎOεMψl&…γ$K;i§ Iλ\爼O«ψ‰£:½γL±}Δ Wπ ϋΥmYΤ4;ί΅ιWOm>έ₯”‘θAΘ?W³“‹Ovξ[P©wž1υέΈqŒσ^£βψu&ψΩbπ€₯LΦν(γΛwώߟ­yοˆ|Cͺx†x¦Φ.ΎΡ$K±–©œ©iρΔφšrΩAͺΘ UΨΉDfQθŒώ΄η ΚΝZϊ !ψŽPψηZςρ·ν-ΣΧΏλšΞΤ΄=OL³΄»Ώ²– k΅έ Ž8qŒ#ή³€v‘ΩδbΞΔ–f9$ϊšΨΦ|M«λ:u•Ž₯vfΆ³]°©Uγ2N8Ι­bΉR@vΏ ΚΛ‘ί†Ζ,’πη·ΘίόMΣcαŠήg&ς [b}Lnα\—¬ίιp]ΓapbŽν<Ή†Ε;—c‘ΗS‰΅›ω΄h4©n X@ώdqm_•Ήη8ΙϋΗΏzΙ|Χσ/ZΖίΒε?πœι‡½ητΙλœΤ‹ΫŒ‚?xίΞΆtίkϊm”VvWώUΌCžLmœυ+žυW\ρ&­Ηz­ίž‘Θ<΄\ΧξT”Ή+«Xά½F…ZiE,P}Δ γ†λQ|*ρΝ€=vΛ’Ϊ²tOjϊO—zΠDηqMŠγ>Έ`qQAκPkM«Es·PbΜeΨ§’0xΖ:JN³qέ]3¦ψ{4’λ^ σ·›apϟβ9ŸΜώuΑΙ–ˆΪIs€ήbξc`?Zζ4έRσMšyl¦ς€š6ŠC΄6εn£‘νU­n%΅ΉŠβέΜsDαΡΧͺ°91³l–ξ‹Zυ΄–zέύΌΚVH§t`F:1Σ\‘Χΰ―‡# B5τΕ‡ γωΦOŒΘήΣ€_i€B’CΣψν`x3[Σ΄ ©―o΄₯ΤnΠ)΄>7–#ΏlqωVf»«]뚭ƣ¨Ιζ\ΞΩb°Š@.‰’κ:εΛΫι6’]LˆdeNΚ;συͺ‘#GvˆκUΥΐ Œs΄|9β-OΓ—r\θχ& dC‘BλY²M$— <ŽZVbμΗ©bsšφioόs­θς‘ΈKkožΟΗΈrΌ~u£.|ΜgΞ›f}vώ½q'Δ:‘ΧΆ>Τ΄Ώη°EΓ·ξγ8ιUfΤ―&ΤΫQyΫν¬ώa•p§w¨ΗJΑQkO#G4wzN‘§Ϊ\λNΡ5i.š #ΊJ¬ͺRάzZ_†h—Ί<πΙΚΨ_Γ~}€VηcRρ–»©X΅έρhaΒΖͺ\{¬ν/XΎγΊŽΒs ]GεL©άΌρΘγ©δSφmΕχesΎρ4ΕΌqͺΉύζ­ œLή¬›‹θ5 ΪνΞ‰ΰ 5¬6²™|π|ψƒγzzuγWΎΈm΄Ι§-cnΕβ‹hωIΟ|dυ=M2ηS»ΉΣν,g›u­¦ο%6·qΙδ ž}hTΊ>βη:Ώ‰· vžΈ‘Q^m:9 Β‚yΰv„U‡‚ό^ œ˜νϋ΄ΥΝήκ··ΏcϋLΫώΗΕΚ£b―Aΐηρ­ΟψX^' ŸώKΕΔΣδ’ŠŠώ΅e{³7ΒSήΩψŽΚ}:ΥnγbΛΈΪr?,Χ_mg€ψ‚]U΄•Υ4}Y"’i‘Ÿ17?2“Χ“λ₯qwzφ§u«¦©5ΫτΖΩ•BŽZ:‡όAg%­Εωςd\$h…‡‘ f‰FMέi ψ}njτœΟoθj‡‰cxόCͺFSφ©zŒͺM%ΌρΝ΄rΖΑ•Τΰ©­_ΕzΦ±eφMFτΝoΈ6Σ/#§ TΣζΊ&κΦ6όH“IπσΒΖΩY­˜I΄doέΖ}ώυ/Δ-ΡΗαqzΪΒ?87ήόZΑΠόQ¬hpΌ:mγE Ε «}@ γπ¬ύOP»Υ/κώwžwκνό€θ°©Œ~Zώ%9+ιZ­ΟΕ BΦ)^Δ΄.— 3Ζά7tηζγή²tω,ο_rθ-QxrϋK΄ΆΣ₯Ώρ]ώΘ&m=a¨e9 ž˜ΘϊW7{Ξ|Ss¬ιΜmζižX‰PΕAΘδކ’1nλΚΓmnY‹_ΌΡ|S©_[yrK$’ΖβPJ°fη8#―xFΖα½cTΏΉΏ1”ŠKk7ΪeΟχΏΩΏrSJσLςΚwHμYŽ1’y5£‘kϊ–†ς6™rb :• ­υZΚiΉ)λ©Ψjme'ΒΩ[MΆΊ‚ΫνκP\ΈbNήJœtώΉ­[F₯αœ 'Π yώ©β}cT΄{kϋ֚έάHP’€ΐΰ{)‰β-Q$Ά‘n°φΠh–Ώ,dcoN~§šΟΩ;Μkψ›ŸxCύΫ―ύ΅«βDkŸƒήΈŒ–ΧΓ&9ΪY،ώ_­qZΥՍœςξΆ΄ίδ¦Π6n9n@ΙΙλΑή.m ΪλNΏ²‹RΡΘ3ZHqσqσ)μxιZΑYX†ξr΄Tχο—ΧgEj1Š69*™ωA> b ͺQEQEQEQEQEQEQEQEQEQEQETπΗ­ΗόωΤ“ρώUOeIψ*‚€ (’€ (’€ (’€6ό;αmWΔPέI€ΐ³ rŠΰΈSσ_‘Ο₯Kβ_κή·‚γPŠ3m1Ϊ’Γ uέΧλ’π \IπΖΛfΜb‡…κW-»Ν6έfO‚·Ÿi #mIL»£8φλϊΧ;©%+tΊ@chΎΦυ:ήϊΚ~Ι1`%yB…Ϊpwg§5›β=Qπνψ΄Υ`ς€+½H!•ΧΤ]F΅#ƒήŒ1Χ³=H/ζkŸΎρ Ξ―‰i¨,FœHαNζBWοNplUBSnύ.ΐΤ΄ψoβK«ΊŽΞ5σΜH^UY}”ZΔΡ<=¨λ:•Ε…”#νp#<‘ΘΑ @#žω5θ>/‡Ro–/ JTΝnΠ2Ž<°αωϊΣτ‡β DcμW]=~\ώΉ¬ΥiZώW–“αLjHDVΞ/9 \)σW;=HZΒπφ¨ψ†ρ­΄«5Ρw»Pz’xκž'ϋgαΰΙΗΨn“VΓcj<βί΄Α=Ββ,VμF'‘=ΊηΫ4{i€οεωΨOĞΥ|<Ι¨B†ήcˆη‰ΓΖΗΣ#ΏΦΊΟό;–CΏ»ΎŠy¬ΔΆ\ck‘XΗQΦ«λ:•”Ÿδ³4}J5―‹ss tY1‚ϊZ‹α²4šŒ’5,ν¦œ('­9JnΩά]πέχ‡ξνbΤΔŸ•ς₯08ιΦ»_|7ΏΈρ-οό#φVπXͺ―“LΘB ΫA9<ž½+ΜΰR·1n|Γ¨χ―Nρ­ΜΛρΊΓlŒ<»‹D_e;r?ργωΣ›š’³θ@<Ϊ:ςmHiρ[ΘΧ¦O+Ιζݜ]±ΰJΣεΌΈ·ŠH‘˜C*»EώπΧθ>Rόy»4ϋ3ύν‡―Qhڞ™gw.• kRέ½Ό±ή fWU©a_λJU₯ueΡ0<φΛEΌ½5 NCkc³Ξ%°Fぁޒ=ςM]eU>Γβέ›w;Θ§ΠŠλ|έ|;ρΌ ^mΆςlv†$ŸΘ!‰νΎ ά΄κP\jͺΡnγxΨ9χΙόͺέF›^i‰αίjϊυ‹ήYΗ vŠϋ<Ωε«7 ΟZΟρ…¨xzψZjyR•€0euυu·IΥ-SΑ66+Ρ/₯Ξφ—–Ο΄ξ$δsΑδ·Β³ώ#hΛ₯M₯Ιm}yuawj%·[²|ΘWϋΈμ9”£R\φ`qυ|:°ΆΤΌ]ek} ΝnβMΘέˆύEfΫθzΞ>«”―§ΐΫdœ•Oβ+sαOόZϋ²θΆ˜όHŠΠvΰ:TΦc»eHlg–0sς²•Αύk?ΒΪ%ξ―tYGm ΆdwIδ ¬3Ӟ£ƒ]Η…|Mw¬]λv—φQΖ–ΈhaΔ‚'ӚςΠ¬ίtτNΙ""δΫ[lt>>YΣΔ“-Υ…΅„‘0ېW§\Žυ…α=SZ³k»T‰-UΆy³HτλZΏ”ΒirpqεGΞ?Ω&™¨Ϋ§„lμΌK€^K₯‰YνnνΫiάIΘηƒΞh²ζw“φiΔη΅j:n―›y Ηq9Q, Άγ€CtΖk°ΈψwsΝ©Š;q«yνζΉΈ x8œg₯axχJ]6]5νο.lmĐ-Ι;β_ξγ°ιιVο‘ŸαN˜QKΤvqΓu‘$›M ΚME¦sSi‘λ'KX„·‘Δa"!²}kκΎΧ4Λ.ξ-γh’—ʐ9Œz*׍«γ‹!&l.}v隿πφ+Ψ΅΅ςΘ¨,¦%Ης>ύhŒSη(ΏC”πώƒ―έ<lAΚ.ηfmͺƒάΥ­cΒZΆ‘`χ—±FΆλ Œ:Θ1# ŒuΉΰXfΌπЬμkι"¨ΏyԐ=xΘόjkΛν?α3E¨Η$.Ϊ€xγa•Jχ§9? *ΧQσ[Μΐ|«κΆ0^ZE΅”°<‘Bΰΰη>υC^Ρ/΄+Ρk©CεΘWrr¬=AVv τ$ B5ά€\Ησ5‰uͺέλι£i·J‹l[Γ €7φΐτ€EFRnύ54-<―\Ϊ$ιozE$ͺ²0φSύk'IΠoυ]B{XGΪ FwΫiNηΎMzΕ₯ΨψκΚΖq­κΌ2ΔΏj’aŽΗ8Ζvyόj·β‹qΗϊ%ΙγώUȌΥYkιs›kŠ$"+v š₯gSζŒdμυΗψzΣό§ιίٚơ«Ϋ›¨tτ@–ϋЇv$ ‘ψ~uΦx\ŸνoŒœ}Žγω5s~‰ξ|βΘ RςώαφΈ ’ hεIθςi§εωΨ5λ]+Uπ‚λΊe‚ιΣΓsφi‘G,ŒΘ#?QϊΦv—ΰ½cR²΅ΌΆŠ/²ά+#Κ 6ήsο΄a‰ΰψKrΣ)A>’¦=άnG#ς?•KβΈ†>1«˜“oΐγvφ۟όz“Iκϋ I­λcšΤ4 CNΦbο"]JΚ©–ΐ9ιŒΧcqπξηώ›SvγVσΫΝsp6πp8ΟJ‘ρ HΆ>[œ‹‘§―˜οZeς3ό)Σ )`ΊƒξΐΞ8n΄μ“h₯%™ΝM€^G¬(F$½ή# ‘ι[WώΦμ­&Έx •`]€StɝαοlόIe>›jnβbΛκγiΘό³]΅ž“β΅fUΡυtŠI¦F|ΖάόΚO^ΎΈϊRŠL©ΞQ~G›©##<ZτߍΊ­μZΰΡ"›Λ"‚'ŠΩTSΞΉO x©ό<Ž‹€ι7ΑδΎξί{;+gŠΦψΡn ρυγy’9š8ε!ΞJΏt{qPlpΤQE (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ žψυΈ€:‚§‡ώ=n?ΰ?Ξ€ ’Š(’Š(’Š({/ψϊOΗωT=—ό}'γόͺ (’Š(’Š(’•‚¨ΛμΌβ8t? xŠ(ξΪίSœΐΦ›P’J±'œ`p{υ¬x«YρBš΅αš8ΉD¨ γ“X”T*qRrκιυ{ιτ‹m.YχXΫ»I[mcœœγ'©κjU€–ΐu6ŸZΆr9υ=sUτ=oQΠ― Φ“tφΣ΄•†„ gQO–=€ΪρŠ5yCV»2ΗΚF¨¨ͺ}pηήͺθšΞ‘‘ήύ―JΊ{iφν, BAόk>Šb—-΄[^ρ«―άΓq«]}’hWlmε’`g= eφ½©_ki«έ\ωšŠ::Λ±F1΄ν`v¬Κ(QŠΩzγVΎŸWmRK—ϋ{Iζ™“ wzŒ` ΨΥΌwβ=WN{έD΅ΌƒΈτ$Ms4Rp‹΅ΦΐhθZή£ ήύ«IΊ{yˆΪH†„ Xρ‰υ4gWΌi–/ΈB*ώŸzΖ’ŽXߚځΠθ3Χt Ck¦ίΆΙaΖ ϊΐγπ¬νsYΤ5Ϋί΅κ·/q>6†`ΠΐJΟ’…§Μ– lΩψ›W³Π.t[{²šmΓn’-ͺsžΈ8ΘŒZ£€κWzMόwš|ΎMΜy ϋCc ƒΑt&ͺQV&―£.ιΪ­ξ›5ΔΆSyr\DΠΘv©άŒŽGJ΅‘x“VΠ’dό…”‚γΛFΙ>π>΅‘EhN)ξŽ‹Qρ―ˆ5)m/u2ήQ΅ΣɌd}Bζ’Ρ­6’‘.aFfΟχpΌσ]‰υ­8xcϋ*ΗSΊΥ&ΊϋLΧS£.0ΈΐέΟaϊΧE5++ Α7v\›TΌ›K·Σ€›uœ^8φ•Sœdυυͺ`A‚9QE"’±ΣψŒΓΪMςcε¦γŽ@'?Χ½fG―jQκ7wΙs‹«΄hζ}‹σ«uΖNΥ™EΟΈ”"ΆF΅―ˆ΅KY¬%·ΊΨφ(Ρ۟-Εlδr9κzζ Ρ΅‹ύμάι—-€m$CB¨QEΨrΖΆ½β-S^hΞ©tΣ,q…Uόλο]ρ|Ίg…΄ }τΗ{oη ˆόΌŒ3εsΈ`ώ+ˆ’š“άNœZJΫ5mNσW½k½Fvžvn ΨΐsDρ6±‘Βρiw­NwΨ3놏E+½Ζ⚳ZŸVΎm\κŸheΏ/ζ”;½p8­mCΗ Ώ³’ΦβόωR.ΧΩ!qθHnŠ.ΑΒ/tAr+³ρ―ŠτΟΪ%ΤΊKΫλΨD’ε&&7QώΟoσΝq”R((’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*xγΦγώόκ žψυΈ€:‚Š( Š( Š(  μΏγι?εPTφ_ρτŸς¨(’Š(’Š(©μΏγι?εPTφ_ρτŸς (’Š(’Š(’Š(’½Gα‡4EΧF«oJ8a™³˜™ΓGΎq@]Evλ’[Ϋό3Υξn­Pj–Ί¨΅2Ό *ε<Φ†Ό­x†Ν―,‘Š;@ΫΧΥ›ΠzΠ1Elκ^Υ4ίC£_[ˆ―ftHΑ`Uχ)Σ5Ύί όF¬‘£³Θbv7+ˆΟmή™γQλ@=§s κVώ m­™υ%“ΚςSζΙνƒιŽsι[zΧΓΏιl··πΙ #3ˆ&Wh‡ϋ@LΠ#EZμ.5MFΪΖΝά\8œO½Zρ.…}αΝUτύMnC|ΉH=4—EPEPEPEΤiV6Rx2βξxVώ8„„œ„ d:MΨ™;½Σx³IŒxή}3J…"VxγŠ=ΨŠ/sξk5τ+τ°ΎΌh”Ae7‘1ά2―1Žό‘II4˜)&“2θ³ΒΊ_ΩiΪΔ "I‘£έ‘ƒaœ~VΑϊ½­ŒΧ―nžL3’Θ ΖΎ¬½Έ£ž7°Ήγ{ν‘’θχΊΝΛA§Γζ2ΞΔ…U€ž•>ΉαέGEŽ)o#C§ ,nIτΘ§Μ―aσ+ΪζEάxoΑrήi7—7QΔΝ%°’Π‰ΐΓ‘ΈΗγ\Ξ·’έθ²D—’-ΛεΘ§’œ[²œ[²3h–ΧΑΥΝ΄S,P‘•wΗ“*»άV]†{}«fCΫΠYLnvΰ¨$ƒωQΝγη‹κgQW΄½.λSšx­Yቦ|Ά0«Œ:ŸEΠ5 j+‡Σ‘ˆ ‡€?18λτ4ά’άnIneQ[η†υf½<‰NHά:ηΣ#½cКz M=PQEt±x#\’Ϊ –ٝ‚±™>9#ΣŸΒ‡$·$·9ͺ+RίAΎΈΧHή«2•.1•<ώ—₯έjsO’«<14Ο–ΖqŸηG2dQ’―θΊ=ξ³rΠiπ™Fζ$…U€žO­ψPΡV'½‰|™xIcpθΗΣ"Že{2½Œš+wK𦫩ΩCwkf”°<Bΰΰη>υK[Ροt[Ο³jyrά€† Π€›΅Δ€›΅Μϊ+ΆώΕΤ΄ jbγNΣη‰Β±Έσ€ˆp8ΕqΦΆσ]άΗomK4΅FI4”“Ι2*+ ΤΌ¬iφr\Νm_λDR+˜ή³τMχZΊh4ψƒ².χf`ͺ£Τ“O™5{‡2jχ3譝oΓZŽoΕΤq΅³ΆΡ,R\ϊqXΤ&ž¨i§ͺ (»HπVͺntλ‹»D6KIoςχ ’ΉΞ0~΄JJ;ŠRQάδh‡RΡοΖWΊ^“)8Ž2Ψ ž§ΨVf—₯έjsO’«<14Ο–ΖqŸηB’΅ΑIZε+OEΠ―υ‘?φt"SRΛΈΙΐλSλ~ΤτkXξo"Cnηh’' ϊQΜ―k‡2½bΡ[z/†5=bΩ-bE· ·Ν•Β)>ƒ=j­ξ‹}c«G¦έΓε]HΚͺ†ΣΈΰτΗ½ΚφΈs+ΪζuίOΰ;ψG-Ϊ8ΰŸžDŒn˜8Η8ΟJδ—F»mkϋ(ΎΧΈ―ϊΑ· gοtιJ3ŒΆglgQ]g‹l―4ύJ·ΌΣ¬­ΒnUΈƒ4ΈλœV‰£_kWF :1ΤnbH £Τ“B’jγRM\Ο’΅υίκ:"ΔχΠ¨†^XΨ2“ι‘VtίκΪ…½έΌQ}špΕdyƒŽsοGΪ?τ²Xls·A$ύ Ιυ(Ύ₯+‘Όπ~³i§I{5Ίyq "Θ Ζ=H*†…’_k—/Ÿrƒs³0UQξhζV½Γš6½ΜΪ+±Τ|:t―O5ύ²-π½UI•·Œ θAΑΝdθΎΤ΅{FΊΆH’Ω[g™4oAšJi«‰M5sŠΏ­iš5ίΩ΅ΌΉ ξR!‡¨"»+FeΤό3ΆˆΙs`Μ ?;…κyφ4₯4•ΒSI\σŠ(=h«,(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*xγΦγώόκ žψυΈ€:‚Š( Š( Š(  μΏγι?εPTφ_ρτŸς¨(’Š(’Š(©μΏγι?εPTφ_ρτŸς (’Š(’Š(’Š+Ρ<s-—Γoέ[ΆΩ žΞT>Œ²‚?Q^wWν5‹λM*χM·Ÿe•ιC<{οΪrΌ‘‘ƒθE{ΔX­δψo}ͺYcμϊ΅άΐu™0ϊεIόk›–ΓIΡόαφρšΞ’—Α¦‚Ϊή`°Aίβ;ΏŸγΔΙβMZ_G‘Ιv[K·¬ƒ’~φ7u'½_Ρ|wβ-MKUϋŠρ£ω|ηε,)ήxλiρ_ΓΖH¦ˆν°“œΘ£Μ\>£Ώ½'f_ްOό†`οξ+Νυk:•ν…ευλMsc³ΘΘΉLŒρσr;ζ›uβ]Zκ+θη»ή—Σ-ΕΐςΠo‘zA@―ˆ~Ρ—nέΖ1εηϋίf_ιšΞΡ5M.Κϋ^]'ΓΊδ·―o,w’Y•ΥAκX}­y₯φ½©ίk‡XΉ»s©VσΠ ¨8΅υˆ%Υ΄Χ°ΎΤK[Θ6Θ$C τ$h›²K‡ΌlD­t\„YίΏ'T˜ΨœΙ=k’ΪrVτ­NσIΊϋNpΠM»—#ΠƒΑ©5fZš9u9όω#]ͺv*ΰg=€«I©6RMI³΄žβΗXΥμ­ΌA§jZvΆBD“@άgψ[§>•WΒvΟ§|O·y#ySΝcΛό‚}λ"ίΖή ‚Ω`P%TmRΡ£0R3XBξΰ^}¬M Ίίζy»ΎmΩΞsλP μΡ ›³G_ΰ[Y­΅}§£X,gI lŽ?CMπzΜώ ρZΫ2βαzνΛnύ3Y:Ÿ‹u½NΜΪή_3@ίyUw}H5kΓάzO‡υΈε Ώ˜ΒΦϋT’J±'œ`qλCŒ¬ΫςY·δZ…d_…·>x!ύL;»ό£8ύZγ«WZρ§­,K©]R>UB…ϊΰΝ[³Τ<=¬Iu’O,κ <‚μ¨cάγU+ΗtRΌV¨Α‡oœ›ρ·pΞ}+ΡυqšΥΞ—qδeiςYνέζoœΙΏ¦:τΗ?khώ1Υb›OΆ»ΤiρM™ςήXaHˆΐ₯$ή¨RMꍭ‚ό`ŸqΖg˜Ζͺ>΅šΫQΧΪxΪ5‚Ζt°ΐVΘγτ5ƒβ Afρ=εώ3iΜ±JΉSΧ‚;Š›Sρn·©Ω›[Λζhο*’ο©f§‘΅ς#kNΘΫπ9·ρ'ŸΣ.!2$ ΅Κdτ>sνUυ;λgπ[ZιΪeτVFθH³Ξα”>0@8τώ΅Ξi:₯ξ‘uφ:α —$`‚=<ŸZΧυ-kˍɕ#ε(U€«‘σ\|šζή¨μ>h¨ ΪΧR’=H-ζk TΦnu;->ΪεcΫeŽ6Pw8λΟl{Tκ7Rι°XI.m bρΗ΄|€υ9Ζjͺ1GVS†Sj£nTcmΞ³ΒΚGƒόYΑWώ„ΤΟ†[WΖv^fΫ&άϊμ?ύzgό'ž$ —ώ@‹‰¬{νbώϋS…ΝΛ5ΰΑ¨F:cTςΙέ>€ςΙέ>§a₯ίΨΪΟ« ?GΥdΉh$ŽδI(` υ-Η―υ¬o_KeoͺoΣ₯ΎΣ%ˆ%،Psƒ‘ψΥmGΕΊή£dΦ—w₯‘q‡ Š₯ΗΉ&¨θΪΕώpΣi· °Γ`{ƒΑ€ μΑAΩάθ5:Β_ OCžώ+5ΈΙirί.μ}εΗ·­r­­xTΦ£Hυ £$Hw,j‘T\3V¬υGk]h“Λ:¨ »*χ8ΗQΌVΊŽ7ŠΧSίhΈ‹~6ξΟ¦kΠ|Cαψ΅hΘ²e€ΖGO,έψ}κγu«.γΙώΚΣδ³Ϋ»Μί9“LuιŽ:»Œuθ­"ΆMAΔqcnQK`t‘’8οJIΛTNZ££Ρ˜/Ζ χfy€ϊμj£ΰ[Y­΅}§£X,gI lŽ?C\€Ϊ…ΤΊ‹_ΌΜ/όΣ*αNοQŽ•§©ψ·[ΤμΝ­εσ4 χ•QWwΤ€3IΑμKƒΩ^ vΓž*d$²¨Θτ%¬+}fζ λIQZάH²1`w+ tη‡j‚ΟQΊ³ΆΊ·Ά—d7JeΪΰ;r8ό*₯ZŽ­²Τum¬Άš~α!υ™5;ΕΊ ,0C(X’ηί<σόθψ–ώ$Ec’1φΒΚrκ;>΅‹¦x§YΣl…₯αHεU‘[gАqT΅]ZϋUh[PΈiΪΨ…€¨ύMBƒζ»%B\ΧgAxŒί ΄βͺH[ηΙ§Ήγ5­£x‹UΡ’xτΫΖ†7;ŠνVυΓŠŽ sQƒX}R+·ξIiv)Ι#ŒcτͺI«•ΥΝ½qOό+ο ω—ϊ©<,²Ώ‚|P– ›‚!Θ^₯7ώ›ͺ―ό'ž$ —ώ@‹‰¬}3XΏΣ/ZξΖ呝σΉ€6}AΰΤςΚΦdςΚΦΦ§Eȟ fϋ@!όwwωFqϊώ΄ίΘΓΐŒ1ΨΝ;κCρόΝaλZφ§­²Jι¦ χWT~ψΥ{FκζΒΦΞiw[ZξςShwž@Ιη֚ƒέχ»ξt~=f’ΟΓr9άν¦Η–=Mr5~mNkΙ,F’ΖβήΡV%ŒŸ»ξδNύk_ϋOΓτ/άΰk…5x«XjρV±αYξνuϋ9τλsssX@εΖGεšκνν4½zMQ΄΅Τ΄Q"yeF|ΖίήRzυυΕqΣίG­φ½9,Qh—Μ,Θp3σwΙΟηZ7ώ2Χo­Ϊβψ˜€\$j₯‡‘ f”’ΫΊ’ΫΊ6<mΗ…|IηΕ4ˈL‰mr™=§\ϋU}NϊΩόΦΊv™}‘Ί,σΈeŒ=?­sšN©{€]}£NΈh%Ζ  B§Φ΅ύKZςΖ£reHωD G࣑σ\95Νί¬―ΰ ˜e3 6τ»ŒϋύκΛΧSUŠM(kΝ•ςPΒnDYΰsωσQhΎ%Υ΄Xš->μΗΕC.}@ γπͺ:ž‘w©έ΅Νόν4νΑfττ J#˜γ™άψ–+Φψ«jΡ¬„`18Ψξό3»4Ί9Sρ†/σ¦ιλ±³ϊζΉ«oλΦΦKi’β]«•Rΐz#?­eιڕޝ¨-νœΕ.—$H@cΘ υΞzšŸfνo+©»[ΚΗQΰ9€—VΧΌΗ-ζΨNϟβ9ŸΜΣ|.²?όPΆ ™±BυΩΈητέ\֟©]ιΝ-œΎ[ΝDηh9Vκ9ΤύWΎΡLϊmΓC![€CB©Αλo!Έ=mδtaf_…OηubΟχvφφΞi4νBπ΅₯Ÿˆt«Ή4Ρ+=΅Τ ΄δ“‘ΟœΦ.©βM[TΆ{{ϋΓ,.βB…|ΐ`cμ8§θώ'Υτ{soavRsε²+€}²)r;|Γ‘ΫζZρ˜ΊtΊ{Αwsqiqn$nΟwωVάΞ¬Œ³JΤ!ΟΚ=₯O«jwš΅ΡΉΤgiζΖܐ TκβšVeΕ4¬Β΄΅-RΣ,¬ξον^ {Εί±Ό g=όκ„!hΦV)`€Ξy8³βw‰`ρΉφiμ»8V `Γoδγ·<}ͺ(δ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*xγΦγώόκ žψυΈ€:‚Š( Š( Š(  μΏγι?εPTφ_ρτŸς¨(’Š(’Š(©μΏγι?εPTφ_ρτŸς (’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*xγΦγώόκ žψυΈ€:‚Š( Š( Š(  μΏγι?εPTφ_ρτŸς¨(’Š(’Š(©μΏγι?εPTφ_ρτŸς (’Š(’Š(’Š+΄π¦—ewΰήάΫ€—V‚"CΦ=ΜAΗΦΈΊτί†:ŒΊOΌc}nΙ,?geY“r™‡#ΏZΔ΄Σ,Ÿα5ξ¦ΦθoΣT¬ίΔbΏ™5KΓ^ΦΌCfΧ–0Ε m‚k‰jΝθ3Φ»g_ΉρΑλΛ»Θma‘5Eˆ-Ό~Zΰ"œ‘λΙ«’θ±ό,π«κφ7Χv`Κ?Ρ$MΗ;³άόΨόiη³Ψ\xSΔ‘Γβ 0La!ήΪGΒΚ§8Γ ρξ=+ͺρlz>‘πήΟ[Σ4[}2βMGμμ"rωPŽzŸp?*©ρOP7푃₯ήΨ,6b8ΝαεψOZžxdŸΰ}Ÿ’'—«–}£;G–Γ'σqώΡόA«E§iʍs(b‘Ϋhΰyϊ έΤ>ψŠΓH—QžΦ/*ί,i(i#\g,ΏN}jίΑe+ρN ;%ΰϊfΥΉπΦψΌ[βΖΎIV5΄ΈEΗχ3οχΣ4ζz]…Ζ©¨ΫXΩ {‹‡’“€Iχ«^%Π―Ό9ͺΎŸ©’-Β¨o‘·)‘¨Ω%Γή@Ά"VΊ.B,οߞ6γœζ­kΡjκr¦Ί.…ψΖ΅.xγ$ςx€}Q@Q@Q@uU”ž Έ»žk•ΏŽ!!'!ΞΉzx–AŒ;ˆΙάT υΕ)+“%s ρ½ž—γKˆ­νSμpc(άμHUQκIιSλžΤtXβ–ς40Jp’ΖαԟLŠΥπ­”#ΓΪΆ₯}q|,£)–φ΄ΚOχ»`gωΦ–€lίဍ§ΫάΑmφπT\8bNήH8ιύsIΝσXNošέsD𾧬[5Ν€HΆκvω²ΈE'Πg­QΥ΄»½"ψΪj˜¦8ΞA Ž’ΊO¬―ΰ ˜e3 6τ»ŒϋύκΙρzΌcMΣ|…ϋ8m»„}Η?Ÿ4γ&Ψγ&Ω{ƚ:Eγ94έ"Ϋh-c‰3Τ¨υ¬[&ξcϋ0"ΙyΌG²6 σΩιώκχ²XjPΩ«Eβ΅ΔJAvΑ€£±Ηυ―3πτΊ…Š ’ήΪKB0œξcƒΈ|f¦m|ˆ§6ΧΘ΅{ΰ­fΦiή(dXWt«ͺΜƒΎEsuθφš^½&¨ΪZκZN¨‘<²£>coο)=zϊβΌώorα&χ ξ<7ΰΉo4›Λ›¨βf’ΨIhDΰaˆΘάγρΊο©}'Δκ€³€9'­/m₯ν‘‹¬h—z5Δί³/#ː?φ«ΔώΌ—^Ί5€QZΎRB—;Fν œžk„Œ*dΘχΕ3H>+ΪaΘΩ=²―°;r?SωΤΛ™5gάRζMYτg•Μ·ΒΞ8]‹ω~P6μ㱩x?XΣμ乚Ϊ8ΏΦˆ€W1Όtš7–Ώξ7`:mΏ]§―Qiwφ6³κΓOΡυY.Z #ΉJ(=Kqλύi9Ύ‚u%Πΰ(’ŠΨΨξtW5#WA’Ao=₯ƒΜ³,¬Δ°^Έϊσ\5uήV’ΫΔq ,ν¦JGS\½΅»Οu δi\ -ΠqQFqΡ΄oΪψ'[Ή΅I’ή52.τ‰εUv λYz^‹y©jΩ@ˆ—]e`˜ΑŽ{δΧrρiΆ^5³²˜kϊ¬RΔ>Σ$ΓΰηΞџη\@,Υq? SΉ;Ή;‰ό <3Ζϊ\p₯ΊΫ«HqόξΖMrZ.{¬ά΄|&FQΉ‰!UG©'[‘Ώ΅¬iΪl"ΑΗ­Zπ9·ρ'ŸΣ.!2$ ΅Κdτ>sνIJJ)(\ηuΏκ*Δχ±/“/ ,nϊdU­7Β:Ά‘gowo_fœ1Y@ `γœϋΦ†§}lώ k];LΎŠΘέ yά2‡ΖŸΦ“Δ20π†# v3NΔzό3OšZ!σJΙyœξ±₯έθχ­i¨EεΜlg ƒΠƒάVΝ―‚5Λ‹D-γ_1w€o*«°φϊΥΏ8xΌ/$ηqm>"μ{z³γ˜΅7ψˆ ˆ“ν b6Œ:p£§lnΞhηnΒηnΗ#e¦άέκkaΊ,Sl‡nΞAΟN†ΊΩ^iϊ&•oy§Y[„ά«qiqΧ8¬mo―vΊ‰ z$>q9nύ8­ύqOό+ο ω—ϊ¦ή©”ΫΌYƒ’θχΊΝΛA§Βde˜’Tz’x>·αύCEXžφ%ςeα%Γ£LŠθΌmΗ…|IηΕ4ˈL‘ΒΫ\¦OCιΧ>Υ_SΎΆ΅¦_Edn„‹<ξCγOλKσX\οšέ ­Γ–―hΧVΙ[+lσ& -θ3Tυ­"σF»ϋ6‘—!]ΚA0υWE§j/…­,όC₯]Ι¦‰Yν m§$œŽx<ζ©xΧL]:]=ΰ»ΉΈ΄Έ·@·η»ό©©>k0R|Φg7V,l―ζ1Y[Λq(ŠF₯Ž=p*½Miwqg)’βh$#nψœ©Η¦Ehό‘θWz,:=₯ŒxVmNgΆYgΈ,γs•ΐcΓθš5φ΅t`Σ‘σFζ$€ͺ=I5ΤψϋUΤmξτ₯·Ώ»‰_N…Ψ$Μ‘˜–Ι8<š―αe‘όβ„΄άBυ)ΈητέXΕ΅χ1‹j71uίκ:"ΔχΠ¨†^XΨ2“ι‘Si~Υu;(nνbμ–G(\ηή΅#Yαlίh#_ƒξ(Ξ?_Φ›ͺ;†š*v΅Τ€R cωš|Οo2Ή₯·Œ oG½Ρo>Ν¨EεΘWrrzƒYυ₯ͺk7:•–Ÿmr#ΩeŽ6Pw8ϋάφΗ΅f֊φΤ7Ά€Ά–Σ]άΗomI4΅z“[Ϊ—ƒ5>ΚK™ γˆfQš1κ@©ώ3²έŒν“n}vώ½VΡ Χ…φ©φ ι:Δl/΄ Ήω³»Œώ΅“½‘“½‘’θχΊΝΛA§Γζ2ΞΔ…U€ž•>ΉαέGEŽ)o#C§ ,nIτΘ­_ ΩB<=«jWΧΒΚ2‘IohϋL€{ΆijFΝώHΪ}½ΜίoEΓ†$νδƒŽŸΧ4œί5„ζω­Π‹E}#X5t$σΪX<Λ2ΚΜK돯5ΖΨM½δRά[­ΜHΩh˜zdWOΰi-ΌGΞΪd‘Tu5Ι+ΤυͺŠΥ‘ΕjΡΨkΙ¦έψ.ίT±Σ"±™―|‚ΛeB1οψ~UΙΪ[Myu½΄fI₯`¨ƒΉ5Τȍ'Βθ )mš™-œ ‡―ζ+ΒΣήZx‚Ξ}>Ωn£bΛΈΑΘό³J:&vL½{ΰ­fΦiή(dXWt«ͺΜƒΎEsuθφš^½&¨ΪZκZN¨‘<²£>coο)=zϊβΈ(!’βxαId`ͺͺ2Xž‚œ$ήα 7ΈΚκ4«)<qw< Χ+BBNB2?sϊ…•ΝtφΧ°Ό32ΧšˆK ŒΖΔdξ*ϊβ©«­ k™hmψξΞΪΓΕWΦΦQ­γΨA”RRk,,…εvw=YŽIόkBΫCΤtkZWm:έΆI>@U 08ό+ž’€/kZ½φ·~χΊ₯Λά\Έ»``€ΐΒ―xwΕšί‡#–=ύν£”ξtΨ€ϊၬ:(Ίπ_‹‰ψ‹kψ¦χ!QIό―ϊfU~T_§j‘«xχΔ7ϊtΪdš“½ƒε1±C:v±’1ωχRб§ήάiΧΠ^YJbΉΓΖഏ­YΧυ«ύR{νV:ε€]ΫB€@⳨ Š( Š( Š( Š( ­Ε¨έE¦ΟaΈ΄ƒΙΡσΠηͺ”QkŠΧ,iΧ·uμWvryw£νc‘γ½C,4―$‡.μY©4Ϊ(·P·SKEΧ5δm:ΰΔ$u*[κΕK©xVΤν^Ϊϊρ₯œHP’€ΐΰ{+"Š\ͺχ°ΉUοccEρ.­’ΔΡiχf8˜ξ(Κsκ…QΤ΅½Nρ―ηi§n¬ήž€tΪͺΡG*½ΗΚ―rύή±wͺJβΰ΅θ*ΒP‘H+Σ€1Ϊ‰υ{ι΅_ν'Έ"ϋpo5!ΘΞ¨QEYŒ΅ΫλGΆΈΎ&)Χ ©aθH~Š(QK`QK`«šV§y€έ}§NΈh&ΖέΛƒ‘θAΰΥ:)΅}Α«ξhλΦ‘¬Οڕǝ$k΅Ε\ η°Ϋ½^ϊοV]Nβ}χͺΚβMŠ9\mΰ vͺ…¬ƒ•"ΤΪ…άΪ“_ΌΝφΖ0ΚΈS»Τc₯iκ>-Φυ&΄»½- Œ8TU.=Θ5…E«°ΉSθQE2‹Zf£w₯έ­Ν„νΰcrϊzx"­λ>!Υ5₯„jW^p„’Ÿ»UΪN3χ@τ•E++ά\ͺχ:#γO£ϋAΎLaΌ΅άqΠŒŸλή°οn¦Ύ»–ζιχΟ+vΐ?AΕCE )l„’–Θά·ρnΉŸφοΫμ» {Ύ\c#==ꆓͺ^ι_hΣ q‚F#ΠƒΑͺTQΚ»*μjkZώ₯­ycQΉ2€|’ £πUkFκζΒΦΞiw[ZξςShwž@ΙηΦͺQBŠCQKbέφ£u²]Λζ-΄B†Π6 θ8ώ5«kγ-zΦΙmaΤD«΅rŠΜ£Π1~ŠSΡ‘8§£Eέ;T½Σ΅}g9KΎx@bsΧ¨>΅΅ η‰?θ%"βk˜’‡½Π8Eξ‹Ϊn―¦^΅έΛC;gslϊƒΑ©΅­RΦΌ±¨ά™R>Q…Qψ+.Š9Uοaς«ήΖ֏β}_G·6φe '>["ΈΫ β¨κڝζ­tnuΪy±·$θΰU:(εIήΑΚ“½‚Š(¦2ή£¨έjO ήΛζ΄1,(v„ΐΰ{šv“ͺήι?hΣ HΪHΑzx5JŠ,­aYZƞ΅―jzΫ!Ԛ`ŸupGΰW—QΊ—M‚ΒIsiŽ=£ε'©Ξ3U(₯dE ’Š)Œ’ήim§Žh$hεŒ†WS‚¨­­GΕϊζ£dΦ·wΜΠ0Γ…ERΓά€ `ΡIΕ=XœS՚Z.Ή¨θ―#iΧ! Γ©PΚίPF*]KΔzΆ§jφΧ׍, βB…@ΐΖΨqYQΚ―{ •^φ-išή—v·6΄ΛιθAΰŠ·­xƒSΦΦ%Τξ|υˆ’ƒΛUΖzύΠ=+*Š,―qς«άΤΡΌAͺh«"ι—mΉΛ.Υ`O#5Ξ΅¨\κΓS–εΎά"UHΐΐΰ:V}r«ήΑΚ―{Œ΅ΫλGΆΈΎ&)Χ ©aθH¬KK™lξ’ΈΆsΡ0ta؎•(₯’@’–‰5mJοV½{»ω|ΩΨ[p: *SJΐ•Ά μ΅oΪ/Ý'ΓΪkΉ”ΚΧΔΡ»$ͺϋυχΘ6ŠQEQEQEQEQEQEQEQEQEQEQEQEΓuφ}»όί%Άνλœγχ€Υu½ZώKέFvΈΊ“δldΰ:{^ΰsRΤ|!β»ΫΉ&΄΄`±„Hγπε΄Tφvw7²˜¬ΰ–yέΆ5,qλΕwWZΓ±΅Θc·Φ΅aP‘Gq""Žΐ1UF₯ζΰΥ‰tν4ΚTVƏα½KV·iν"Q;|Ι('Πg­QΥ4ϋ­.ν­―’1LΌΰσ‘κqMTƒ—*z‰Σ’3Zh†ΫΑΪΝΕ²LF₯ΧzFς*»`­fιΊEή‘}%€ «<`–YX&0@#žω4•jnφ’Πn”Υ·(Q]―ˆό<3#ι±Β°, œg;±“\燴·Φ5hmνBwHάAΤΤΓNpsODTθNδkVfΡZ^!–Κ]ZoμΘ4;#?0ΔsλW<%₯C{q5ζ£Ζ™dΎdηϋވ=ΟωλTκ(ÞH•MΚ|ˆΑ§Α ³Κ±ΑΛ#tTRΔώŸ{,sέΝ,0¬13±―E…zΒλ©tο ψΛP±Ϋ‘moŠr ”Ά@Ο‡εZ-LΩηRΕ$2΄s#G"œ2°ΑЊmt>Άoψ±΅fy Ε¦ϊ3ΰdώu­§bψ“νΦVϊBXK5΄ΡΘIω{0=sW]T νm·ς8Š(’ ά(ίΑVZ³X[ή£__ή–Μy*–κ3ΧIΫϊώ|}ϊ,wΧƒ ²0ΠTγes(UR›…Ά ’Š*MBŠ+¦π½•Ši:¦±©Ϋ›¨μφ$pn*Ψγ$ŽΓЍgb*MA]œΝΥκΆϊv©αwΥμl–Ββήq ±ΖΔ£‚8#= r”J6:œλkX(’½BmφΖηPΏπυ΅›n0ΣyΕί²¨ξiΖ<Ϊ\šΥ}’½yέ-ΫΗ-ΤA•;2GœνRx…EPj‚Š( aEuρG¦h^Σo.τδΤ//χΏο\…γη"©xΗO³΅}>σM‘΅Ώ€L!fέεžΰJ· +˜FΊ”Ήmί_C’ŠtQΌ€q)y…UI=AΈΪ+€ρu–“ž—hΧΡ&ϋΉΑ'.yΨ;`gωW7U%gb)ΝN<Θ(’Š’ΒŠU` ΐ'­w‚ΓΓΝαύf=:&ΊΈ±…XήΉ#{”z ž΅q1•Zͺ·8*(’ Τ(’Š(ΓΑŸeΤ<θ6χRZ[©&e ΉΞHƒzΘρlΪdΊΜƒD€Cg„Ξ‚rΓ?犷Gšζ1«zŽŒj(’ Ψ(’΄ό7€Ύ΅«Αf‡jΊWώβ§όχΕ4쉔”S“Ω”VŸ‰&±›WŸϋ*‚ΙΘΐΟΜρϊυό«2†¬μ|Ι;QH ’Άό₯C«λqΑtΜ-‘Yvυ*£ ϊρ[šZθž%šηN·„Β&{iRΗ+Ξjγ £ •ΤVΫ#ˆ’Š* Š)Ρ(yY‚† =½6Šο`—Γ?Ϋ6Ϊ-Ά–·–ς”ˆή‰[{;φΦV•αλyόq.“4ŒΦΛ&ζ–UΙΗΧ 5§³}Ξ± ΝΙ5e‘ΛΤΠZ\\G$A,©.Θ…‚ύHι»?ϋğn²·ΒXΰy­¦ŽBOΛΩλš‹αV³¨ιή-Σν,.|«{ۘβ2.zsμN*\l]:œν¦¬ΡΖΡ[Ύ“ρώUOeIψ*‚€ (’€ (’€ žΛώ>“ρώUOeIψ*‚Š( Š( Š( ½3α–£6•ΰ_^Ϊ€O4?f*²¦υ9fŽύkΜλoΓ~*ΦΌ6· ’ή}˜NTΙϋ€}ΨΞ>π8κzPwβ{ΫΟ|-:΅lm.lnΥ-φŽ9‘°8Bq‘žΎΗή³ΌY·? Ό=Ί4‘ΔΣΔεFv±~θk•ρŠ΅Ώ,k¬κ\€gr¦ΥEΧ Ο½MαΏλΎΰoŒvξwΤP₯0:‰Q‹Qΰ‹[ΠH4ΨDθίΒ2Οδ*³ρ.ί\“βδm¦ ΎήI°udη¦nΞxυ―:Φ5KέfώKέNεξn_«Ώ§ €=…t6_ΌSe§-”£y(»š4gUτ Fh{αϊκ ρ’%֝_R0—n yMŸ»ΗεZΪ›Yήό9ΦγπTrΫ΄Weυ8₯9™γηGπρΣΠ7Ύ|·JΦ΅ +W]RΖε’ύK7œΚε NΰAΞOZ“Eρ©’ίMy¦]g™JHv+䂬?•wŸ Ν π/‹ΕΝΌχ ˆLΡ[0YZ<ž‡ΣοgΫ5_[Τμdψi-ž’κpix²%ΝԊθ²w ~žžυΕhzφ§‘_5ζ“tΦΣ°ΓQ΅‡‘R1Β­x—ΕšΟ‰K«ήcˆε#TTE>Έsξh₯ψ^'‡Όmj]ΫL8U'†ν^~cpΑJO@F*ώ…­κ:οΪτ‹§ΆœΚzAρ©ΌGβ=WΔsΓ6΅uφ™"Rˆ|΄Lsό RΣ.τίxƒM΄ρ^‘¬i%eŽm_Œηεlv' 8υ―4ρŽŸ6—β}JΚζιξε†R¦w$³χηΎ1[6ΏόWmfΆΡκ„ͺ.Υw…ΤΌFOγ\ΥΔΧw2ά\ΘΟ+wc’Δυ&€4u{}r-:Α΅eΏLŸθŸh-³n?ƒ<ŒtνŠΙ­gΔϊΎ΅§YXκWfkk1ˆ”ͺŒq€I$γŽk€ τ†ίς*xηώΑγg―?»ΐ~%Στ}bΫV³žξΫQ…ae‰ΒsΟγLF½αό€©4š5΄ΆΆ'o—―½—œŸMuΪGŠΌ?€ψcP²²―QΎ±6³ΞfŠγp ΙΝ 8{[«‹I<ΛYε‚B1Ί7*qι‘]wŽ5;ψ.΄Ε‚φκ5}>'`’°άΗvIΑδΧV΅ ϋAαkΙ|Ɗ1  aAΐχ¬gIJq—kšΒ«Œ{—|"@ρ>—ŸωψOηQψš7OjΥ—ύ&CΘμXβ³cvΥγb€`pAυ­›ίλ7ΆOiuzd·p)2@9λŒφ’P’¨§ΦegΙ/SK]Y_ΐώ000}£ϋΈΟΏή©!#jXΆΣ΄ΩEƒŽZŸΒsKaαmnϋOPΧΚΘ„νάR3Τγσό«"k0X}Š;ζϋ6Ο/c"·ΛŒc$g₯Qυ;Ν*ΰΟ§ΞΠΘF  px4{Ί^ΝΫK|ύt0φΠU}’ΎΏ‡§τŽžςκ}cΐΧΊ²‡Έ‚αRήrYΑκΌuΘ©BιΧ^°ΣαΦ-l‡ϊΫ”pK<³OπτcWΦυ\§φ…ΛJ©χTͺ?+:ˆαέ΅vΦϊl‚X…}τΆ§[γ•ŽΓ[Ϊ†EŠϋŸ$˜fδŽΰβΊ»uΌQποΕqIaa¦ 4†`tθΌ•—,~W9ϋΏ­yŽ‘s¨έ«z0p‚‹άΖ¬Τζδ„ψhGό%pFηŠE_s΄Φ―ƒο..Ϊ‹H L°ž7uŒ«vϋη׏η\}εΤ1λέhΛ-€ &ψΎ^1۟Z½©x―ZΤmΪξυšϋꨩΏκ@˜M$pV‘)Ι΅ΧπίόΜh!’βhα…ε‘‚ͺ¨Ι$τ-ύ•ΞŸtφΧ°Ό32Φ™iq-₯ΜWΞcš&Œ;¦Υu+­Vυξ―εσg`lΐθ08¬τ·™Σοsy„ΗM88άάΐ±u@F£uGο_ωšΤΣΌ[­ιΆQZY^ωvρδ"yHq“ž₯sΤΥ]k^Τ΅Ώ'ϋNηΟςs³δUΖqŸΊ «n<Ά1Œj{W&•ΆίΧΘKmRΉΡ5hm]΄λvΩ$ωTρΗ'?Δ?:ΝΛVρ’ό9|=¦»™L­q|Jν²J―ΏQ|Šγk3 +°πΣ8πVΊΠ –Hf·˜‘Ο#Σƒšγκξ“ͺήι&}:ᑐ€€#ΠƒΑͺƒ³ΤΚ΄γeεψUεμ—ήΥ― ŽίνwΡμXΧj’g—ηšδ΄έ:σS‘°·’yUK•AΠυcYΧud§φΙ•cϋˆ*―ΰΝWΎΡ}:s Ž»ν ‘τ"ͺRRjδS§:p|Ά»ϋŠi4ΛΒ±mΏ7>υΫψ~M{Aρ…/Οlς$;C##csG‘ύ+†wiΙfc’Os[ΡxΓ^ŠΘZΗ¨H" ΄ͺXMΨΟλD$’ξιΚ’²Iϊώe/Γ ·ˆ5m@G;ͺΠz~(Τ΄=KL²³»Ώ΅x-ο|Δ~π`œτ#σͺm’tσάͺ3 3Ιχ³βw‰`ρΉφiμ»8V `Γoδγ·<}¨z³h«$ŽBŠ(€Qή]κ2ιžπΝόΠ\ ‚xΞMΘ aϊπZΞρ²΄Z_†ΰ”™,²ΘFΙγ?‘¬½Δz Catc…ŽβŒͺκ¨UFϊηQΊ{›ιžiΫ«7ωβ΅”ΣV9)Π”f›Ω_ρΏωŽ‹L½›O–ϊ+i&ΪςΒŸςGη[Ώ ’ŽOBdPοo$H‰ΒρύOαXφϊΦ‘o€Ν¦CpVΚcΉγΪ9ιίS·ž[iγšήFŽT;•ΤΰƒRšM3YΒs„’ϊμwώΥ΅~χR±ΧTKcδΘς†ˆ/ΩΨt#Œƒ\ ΄Χ—pΫZΖdžgΖƒ«18΅υλZ›Zέί3@Γ ͺŠ»Ύ€MXψy¨iϊO‹l΅ ]έm­·H&βΝ΄…™ΟαNrζ±4i86ΪJύ«ι—š=σΩκP.Ρ±ŒŒŽžΥN―kڜΪΞ³y¨άŸήάΚύΠzΐ`~F³:ΊΟ ©„gΕ<ψχ·ΉMIRκ9›ώΏΠG GΔΥΑ€ξΜ+Ζs,- ύ̐Aζ΄΅-RΣ,¬ξον^ {Εί±Ό g=όκΛΩ΅]Lέjs–’VQ,‘ΐ ΰ ptΌKˆ΅Θ³KeΩΒ°[xΗ'ΉγθI²½΅9 (’Ξ‚Νu―YΪjvμŠψ­œΊΐŽΉ«Ώγ_ν :αβXo.l[”Qœη$ϋ…ehώ%Υ΄x>ρ£„œμ*¬υŸ{q¨]=ΝμΟ4οχhδΉlŽh—΄η•ΊϊΏRΥΆ‡©\θΧ΄6Ϊu»l’|€ͺxγ“ŸβfΧe«xŽΡ~ι>Σ]Μ¦VΈΎ%vΩ%Wί¨ΎEq΅™Ϊx>y΄ λ·ϊr†ΏVŽ2vξ)κqωώ^ΥΕΥέ+T½n ϊuΓΑ!$`‚=<ΈK•άΚ΅7R¨κ―n5―\_k ζήεRΪΰ Vp~ςρΤ/jζ4=QΧnžΫI΅{™Ρ Œͺ@Β‚yχ"Ÿ¬λΊ–²SϋFε₯TεPͺ?­xŽΣÞρ #ΈΦ/"[{`…^w6ξέsψ '.f*4άOΎΛ‘Η:”vVϋΚpyΝ%T΄MNγGΤ‘½΄+ζFz0Θ`x Χnu+M7Β·΄\}φ£Ί1bWψœgξ@=«Ξͺζ₯©ήj^GΫ&σˆ’P‘B(μV‘Ÿ*9κΠU$ŸίώDvΣ^]Γmk’yœG¬Δΰ ŸWΣ/4{η³Τ 0] £b =«cαζ‘§ι>-²Τ5wuΆΆέ ›‹6~g?…dλڜΪΞ³y¨άŸήάΚύΠzΐ`~™ΠQ’Š ‚:Šνtλtπ†žš•μaυ©Πύ’έ†|•?ςΡ‡―·_ώJσxΕZg-4Ι.Kuf*OψΤπψώ‚?ω?ώ&±n5;ˍLκ2Nίm,ΝPδtΌ:ζόn·~0Ρ iZ χq θpΓζcοNΤΌW­j6mwzΝ }υTTίυ Υ―λZFƒxχڞ—-ύδ,’Zm—bΖΓ<Ÿ^vφ=)JIΩ#Z4ά[“ύΟŠ){ΝcXN‘₯Β±άώΤ H;©|χΗ§C\n‡’κ:νΣΫi6―s:!‘•HP@Ο>δS5½F]_WΌΤ.‰neiX/A“Π}+₯πWˆν<9αί²;bς%·ΆxUηsnνΧ?€¬ΝΞ9Τ£²·ήSƒΞi(’€ (’€ (’€ (’€ (’€ (’€ žψυΈ€:‚§‡ώ=n?ΰ?Ξ€ ’Š(’Š(’Š({/ψϊOΗωT=—ό}'γόͺ (’Š(’Š*[WTYŽgωTTPEM₯ΕΔrIΚ‘ςμˆX/Ԏ*(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*xγΦγώόκ žψυΈ€:‚Š( Š( Š(  μΏγι?εPTφ_ρτŸς¨(’Š(’Š(’Š(²ψU¬κ:w‹tϋK Ÿ*ήφζ4ΈŒ€D‹žœϋŠΚρβE5ΈνγΔ·r(@0τ”Οۭߌ4hVˆ=άCz0ω‡CΨϋΧQρCΕ/y¬kI4ΈV;ƒΪ„ιcu/žψτθhΟh­ EΤuΫ§Άm^ζtC#*0 ž}Θͺ₯•Ύςœs@ EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPSΓ·πηPTπΗ­ΗόωΠQEQEQEOeIψ*‚₯΅uI՘αF•E@Q@Q@Q@7υ­#AΌ{νOK–ώςI-6Λ±cažO―;{•­κ2κϊ½ζ‘pKs+JΑz žƒιT¨ ΛΑ^#΄πη‡|BΘξ5‹Θ–ήΨαWΝ»·\ώΈΪ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( §‡ώ=n?ΰ?Ξ ©α[ψσ (’Š(’Š(’Š)ιΘ‘»G7°RBη¦OjenψCΔχΎΏi­rA6βήE ³ ?tη§SΝaQ]ΕΣHΧα›K]š~£n·§dݜ¨φοψΧ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@OόzάΐASΓ·πη@QEQEQEP$2Oj+’πf·§hS^ίiK¨έ Sh$|$n,G~Ψγς  ‹ΙφFπƝ'ϊϋM"z˜ΗkΟͺώ»«]뚭ƣ¨Ιζ\ΞΩb°Š‘@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@OόzάΐASΓ·πη@QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQETπΗ­ΗόωΤ> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐ6œ"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊŠ(ͺQEQETχΏρτ‡ς¨*{ίψϊΓωPQEQEQEO7όzΫΐΏASΝΆπ/ηPPEPEPEPEPEPEPEPEPEPEP«`ΚJ°9jφ•«ίιZ’κ67 κ–"VΞXIά9ΙͺPΥτ`+±wfc–c’i(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€  ‚:Š(  zΆ₯w«_=ζ‘/rΰ}‘sΐtRŠ)‰+h‚Š(€0’Š(’Š(’Š(’Š(’Š(§Γ,Θ$…ή7Nόi”PEPEPEPEPEPEPEPEPEPEPEPΛ]NξΦΒξΚ Ά[]νσ“h;φœŽHΘό*Q` (’€ (’€ (’€ζΙ䘼Ης‹nٟ—=3ZePWouKΫΫ;;[«‡’ήΡJΑΖ#?!T¨ Š( Š( Š( Š( §½§ό?•ASήΗΣώΚ€ ’Š(’Š(’Š(yΏγΦίώόκ žoψυ·:‚€ (’€ (’€ TRξͺΌ³ J–Σώ>α}]ρ‹yαύV];RT[˜Β–Ϋ‡##Ÿ‘¬Ϊχo_ψwώbi–ƒμ·Ζ¦»’CΊ2ΐ*…pη<ŸJσI΄[ ?β4ΪMάW—:|7LžU²ο™Χ’ͺsΠƘ₯νΏπΩkz~―oqΰΙ4%··y¬ο7Δ―@ώη9οιšε>ΨθΟα/jzޞ·’ΗΙxΧqRI'εΘθ ΐ>Τη΄W’ψ’ΫEΦώ'ˆ΄­.=*ξΪπZΝLJ8#9ϊςΏ­KoƒαohΧϊŽ‹­¨jζF"Y γS”€py_|Ÿj@rα=Qnτ{vXDš¬K=Άd##'΅OβokΣ£½Τά[Ι(…LR‡ωˆ'·²šθΎ1›c… ‚²Ω1 *Η$'A?LUkοω"ύ†[E½08 +₯ψu Γβ?Yiχe…«n’]§ͺ©8SψΧ£ΛαkMnΟV΅“Αςhgε²½~r½σλοοH­8τ;Ω<;.ΆͺŸ`ŠqlΝ»ζί€zz`Šκ~iΪLZ½β-nΝo’Σ–4ŠΩ˜…gsŽ£ΏS[ZΕ|ΌΉtρ§+κkη[«—U“jς€φ#iΗΦ€9αζΏ«ι6ϊ”Vνop ˆ4κ¬Ψ$t>βΉΝ_L½Ροδ²Τνήήζ?ΌόΑξ+΅ρ#αw‚8 άΰχκo‰_ιpψ"ζγχ“άi°‰]Ή/Σ―ζ:σŠ+ΠΌ]£iφŸν΄»kHγΣΪκΥ χHm›‡γ“RYθΊsόkm%­":wΪdO³dωΠœΡ^―k/‚υ-OVπύΖ“k₯E•mυ).pΖE8–ΐλŒγΆ+—ψuiaquzχš-φ΅s`ΫΪΐ§Λ,š:ž½θ«Ϊv‘}©[ήΟeneŠΞ?6v ΔυδσΠτ―Dρη‡­_Α)θŒ7" -Α;dB8`>€~F΄>kšcψ[_Uπύ²5–š Γ OϊfΘn8Ξ―ZρΪή|5.₯α½OXKΛH£± 42>$~όǏSLρF―§κΫΆ›’Α₯,jC¬Rσ θN@ι]­¬ΊˆΌβk« Ϊiχ:t1–9 ’X‘žƒwυ /’Ίo‡#ρu–ŸxXZJΰ•U'χ8ΨιΛαocLΣττΙνm€Έ΄ΊŠBK„γζr:ητ (’½ αݎŒώρ6§­ιλz,|—w$’~\Ž€œνOρ%Ά‹­ό>OiZ\zUݡ࡚(˜”pFsυεZσͺ(©-”5ΜJΓ Έ~4Ϊψ_Ή±K˜νP]ιΘͺμ=@?Φ±t­"σSΥWN΅ύ,–νΑPI?C]―Šξf_‹ΦΫdaεά["{) ‘Ξ¬hͺγMΐQηLςV €­wΪζœͺφ<Ρ”«=AΑ€―DΣcΠ’u’1ζΞj™2rΫηšκΎ9ΆπŽn’βa1¬XηϊWe,p^A4Π¬ρG"»ΔΗ@J“ο΄$žM*φ-&Mΰ"ΖY I.F δc9μj•{ χˆ4„ψo¦ή?†­^KΧE³36Τ`ζΟ­yͺj–+β?ν€Blwϋ˜vcn1»―^k*u%+έ&­αιtέ LΥξTΎ¬QΎ]?ήη±+ΌρΌ:\ώ πώ―¦ιPι^I2Θ‘1nΆŽOΣ?MΰΛm*>§¨iP_Ξ5DΆ_0‘…e\τλΤώ4•[G™χΟh―Sρn’‰β¨l4ΈνfΡn ςηW, φ8ϊ Oψv/iڜ~m~ώύ™YŽΘ#ά₯/nΉooλp<ΆŠμΎ'hΪ&£a5΄–_[,ζΦF$ΐΔΉ<ρΗλ\mk )dΆ–Σ^\ΕokK<¬G$ΧC©ψ\Σ¬d»žή6Ž!™DR†hΗ©©x;U‹Dρ%–‘p…α‰ˆp£œ+‘τΞk¨›KΌ΅]KXπ†±ό#˜ΐUΉ;•³Ÿ―¦riΨ¨€ΡΑ[DgΈŠΚ†FΞdγ$ϊUοi’joe-Δ ͺ|-•η·Φ€Π5+-9§7ϊT:ˆp6‰$+³Ξ1럴~$XZιΎ*žΪΒ‚Eθ Qš|Ϛ¢—9Š+ΎDΡό‘j7Z•ΚUνvβK½jώβbZIgwbNy,k|‘ΪΕͺΩxzjrά2O’γΘAœa}πLόήΥb<’―K€_E£ΓͺΙnFŸ4†(ζά0Ξ3‘Œη±ν[Ύ-ŸJƒΔ–“Zh7:x‹cέιΧYUf$/p€qύ+ΏΏρΓ=2ωό1hφr_α .φϋJMJσR2ήHT")ΗθyŸ΅7βq€§‡Mš²Ϋ9 AŽH^ΐώ•KΙ$ΆGEz΅ζ“c₯AdΆΎώΧΣ^yocr6zO^Γι^gz-ŸR”Y$±Ϊ΄„F²ύυ\τ>βœ'Ο°J6:Xό#—…Ά|A¨ 'Ή‰ΪΒΜ&dœς“θΉΗΰ{UhΪn»u5•φ¨4λ·Ϊ-Σtr9<«έ°tecγ—·Cmmq―`1Ÿλ^~GZ²KΪζ“w’j·~‘—q m#±ˆυr+ π„­όE‘I&‘¨«k+Ι&"`Θ€πQ»œvυτ­O‹Οφ―ψEοδιZD/!υ=©{αεΤ–ž9Π€ˆΝyGžΞΑOθM09φR¬U =©+‘ψ… Aγr8†Τϋ\„LœZη©QEQEQEQETχΏρτ‡ς¨*{ίψϊΓωPQEQEQEO7όzΫΐΏASΝΆπ/ηPPEPEPR[0Kˆ™ŽXŽŠοόYβ 2β½³isζi©qlν7–Γ ›w€gŒΥoIρn“cρkPΦ₯‘ŸMΈ2"\,g)Έ >3Ϋ3Νy­λΪ±ανγT’ηΕχš΄·V’Εψ%Ψ₯°Fsœ±υθ9Νr>Φl,Ό β:ζ}——ΎGΩγΨΗ~Φ$ςβEqτP_g¬ΨGπ²ϋGyρ¨Λ¨¬ιΖε6¨Ξμc¨(k:>­ύ…ƒ;KogdΆδ:2”Η@r98τΘ©ό=©ψRππξΏ¨Λ¦I ηΪ‘`i•²€`…ηΉύ+€’€;?jΊ_ƒό{kya|ϊž™Ϊσ LC.ΉΰŸΗ±¨Να›;]Bκ?ꚑ•ZX§›F=7±καΗ­y₯άό>Υτ„Ρ΅ΝΔ7ii©*2\ͺΊœŒΟ\Β―kz†μ~Ο hΪ›ήέύ΅ggkwŒKΐ†F“ž+Ξ( K~ΦΌαέ;UΧίOΈΣΌΣ$Ig$₯·6pcΧ­`ψϋΔ6šΆ₯§E£,‹§ivΙmle3νώ#ϊ~UΙQ@Αu«x3Yρ-—‹o5y­naΙ6ŸφvfiSpÌp?!ΉmΔ֍ρUΧ4Θ|/¬θwΪ€Ί5Εδ‰$WΡ£7L|§o qνχyυιZώ΅‘ΕπξηD²Χ.uKφΌYŒ“Ε"οΫ»8QŽ„η9¬‡Φ—§ jΓ[šKkMNΠΫύ‘Ώ–yηžζΈΚ(o_Στ[;Ϋhτ}i΅w½”ΪΌ^_>Ιγšο4#ΰ½'@ΧtΑβζ”j‰0ςφ=1Ξw{W”Q@§‡5M+Αή=΄Ό°Ύ}SLE+$ΒΚAΒ·<|WAeΰ &―¨θš΄Ϊεε»ΑmmφvA|}βx8 ~₯y]ΨxgY°²π'Štλ™φ^^ωgcϋX“Θ‰–zΝ„ /΄wŸŒΊŠΞ‘lnSjŒξΖ:ƒΖs\…Σx ΝͺNΎ.šX­$ΔSv δuΪ ιœW?1Ž;Ι «1‰d&6aΙPx'ή‘’€=.ηPπΆ©―[xŽλSšΪβ?.IlΌ†b Γ1ΐλV/‡ΌCh>"Ά΅~ζήΦI%rJ–*HQ€ ξ+Ž’³T•­ς+ž§ίxoB‹TΤ΄ύB[›»ΈmSξ~fθqΗ5ΞxYtiα5‹»›° ΅Τ@°ΉΞ@δφύk ŠjΎ‘Μw~%ΦlΒG‹X›ZΊk/Ÿ$l’% -ΙόϋšnͺiΊ§…τύ6ϋWŸH»±g *ΖΞ²£ΰν=GΏ§½pΤRφjΦcgΕ3iς_G“=ΥΜF§ΈbLά€zjΉρS΄Υ΅εΉΣζσaρ¦ν₯y‘‚sTU(₯o!\|ΌΗ4LVHΨ:°μAΘ5ίψίΔϊUφ„ρι~Χ¨Λχ«±†Ν¨ܐδ™θ}kΟh’PRiΎ€€±Υψ/X²΅°Υ4½NβkH/• άΔ€˜NAΐηαοQψ΄˜4Έν¬΅k½Vυ€άςΆδ‰Π+u>υΜQK‘^αΝ₯Žλαv‘b± κ³‹kmf ΞέAΉΎδ+›ρ>}α½PΨjJ‚]’Dd`Κθs†π=k&Ÿ$²JI#ΈEΪ»ŽvAθ*Δw:6‘ κž‡BΦ΅9tΉ­nΪα%ν2Έ ρ…ϊšζν¬4‰*x‚Γ\½γΣ$½ϋ°†KΩcNήΈ8>‰«:.£ανWΐ0hζ©.•=­Ϋ\G(·i•ΑŒ/ϋΖΌϊŠνό«ιργΞχOu¦xRρa*@ aφG§―5ΣθzΗ‡΄RKŸήjέZK{ΰ—b–ΑΞrΗΧ η5δ4Paΰ½fΓMπΧ‹-/gςξ/­R;uΨΗ{ Ω¨λŠγθ’€;?‡Φ—§ jΓ[šKkMNΠΫύ‘Ώ–yηžζ±> /Pattern << >> /XObject << /Image18 156 0 R /Image19 157 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 160 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 161 0 R /Resources 162 0 R /Annots 164 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 161 0 obj << /Filter /FlateDecode /Length 163 0 R >> stream xœ΅VKnΤ@u{‰ΊΔ,PΒ8 ώ–D FB²”aI„œ„ ,²αΙQΈΔ¬@`–Ye1'`Uvlw&ˆ|άςtχsUWυ{]φŒArΤ7#,φo` ‚ !£ V˜Ϊb~ŽFΤ€vΦ;Q»WύD λ *˜›Πο>lΑ!Γϊ“κγώŽ€½OAΡνƒΡcp-b:j8ή»Q¨}Ψ]…WΨΖI$YGͺ.+}°’γA«‰ b’—vX•`ΖhΫ`½ou!)¨-»ύ¨¦ΆPoΦΘhшK₯π-Ρ+k"ς.|π€APΪͺh(ωΧ(aύΩΡαg ι Pξ^Υ5βmwΚF΄ςΌ†aΆΑ°’mo³5–±Q5oΓlΒ–σiώ3Ÿf PδΊFφKΏωΡ-s‘ρ„ ά’±xΖ;›φžgJƒr Sn‘ΐΪpwUίό*ΌΦ ΕNPΠ_(h+)ŸOρΤέ"+ΩE"μ¬ΐ½Φ£ |ާd‰΄ΟΏζί{΅oš°†{c„šO»Sφ6TΈΘ}ΔΛΞσQ@hvΔΨχΏ†ϋ:©wŽό`e³M,έXM²σl–mfSζ°XF8Ÿ-(I[Ν“l†vηˆΨ ep°}q;‘°ΧtA¦G½ΛJ>½=εN Γ‰˜˜2žŸε§ω)¦^6Ϊގ‰―IiνΒ`wPΈ&FA¦AzoytTΉR{,Ζθ{°J@ι΄u’FUηbΙ‡β>ίZ­ΏuΚι-5YΈX χΗuάϊ󃝽χ2ΐΣ£Žͺ?ρ‘\Š ‰Œ;/ˆτ:ιΰ½iς»« ^»ΐ£B4ρOΠ„“ϋ ΠςV/JhgπΏ†ZθΧq£DΟ ΅ίFž»Β endstream endobj 163 0 obj 725 endobj 164 0 obj [ ] endobj 165 0 obj << /Subtype /Image /Interpolate true /Width 1204 /Height 84 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 166 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐT΄"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊŠ(ͺQE=—ό}'γόͺ žΛώ>“ρώUQEQEQEO{Oψ*‚§½§ό?•A@Q@Q@W_π£M³ΥΌqeg©@—Ξ’ϊ!#υ BŠμ΅‡zύŽs©=¬_g‡/$I(i"NΉeνΗγXžπζ§βKΗΆ`σYtŽΜz’zPEΡx£ΑΪΏ†’†}F(ΪΪc΅'†@θO¦{*ζπχ^Υτϋ;λH­Ε₯Πb²Ι0PΈmΌϊz δh­?hZ‡‡u&±Υaς§0ΑΘe==ΗΧψαΉφέ"ξώΚ&³’β'–έ₯g”\n%}0yο@{Ew:΅Φα―kΦσθ6ϊ…’ΛεΓ ΘPEN 7β֟aa­ιŸΩvqΩΓq§EpΡFI™Ÿ=}€…qV·†ό;©ψ’υ­΄›5ΡwΘΜΑQ©'V|Oα[Γi ΊŒ(m¦8Žx\!θ6Ϊ0π¬ fΆΧ3XΖnΤui8 Ÿ|ζ€8:+ΩΌC„m|ržΉπΤqΕ3EήA;+£HίLŸZσηπμή5»πξžR[ˆ₯‘Q€`‘•rA'Χΐζ¨­] AΎΦξξ­¬6–ΪžMΝ΄mRΗζ*o x[Tρ*έdB³5°Rκ\)ω‰ϊ@bQ]/‰Ό­xrΚ+ΛψbkIo›Υ[Πγ§jw†Ό­x†Ν―,‘Š;@ΫΧΥ›ΠzΠ1Elκ^Υ4Ν~ϊ μΞ‰ζΐ`έ1žυίάό+Ί„BΟȊΤkho:Cuςπp8ΟJςz+i<5~ώ'ώΑGΫχZ6d.ο½Σ₯ttνCJπΆ‡g¨i:e¨ˆ²-έ³‡yˆξΐόO^hΟ¨­ ψsSρ-λ[i6ώk’ξvf ¨=I5kΕ>Φ<2Ι©ΐŸg˜β9’pθΗΣ#½sΤW]£ό=Χ΅}>Ξϊ+qit¬²L.o>„ž‚±6ζΎ€sV―ˆτ GΓ·βΣUƒΚυ †W_PEnZ|7ρ%Υ‚]Ggω‰ζ$/*¬ŒΎΚ­€R»`qΤVΆ‰ανGYΤ,,‘kδŽF@RχΙ­Ή>x„Elαbσ₯Ÿ5q“³Τπυ‘Ԍ]›Ž’΅<= j>!Όkm*ίΝt]ξΔ…T€žYρ'…u_$2j‘·˜β9βpρ±τΘου§ΟςίP0¨―IπΓΉoτ;ϋ»θ wšΜK`EΖ6Ή€2ψoqβ[ίψGμ­ΰ±U_&&˜)„Ά‚ry=zWœC§^M© >+yτΙεy |Ϋ³‚(…XΝ]0*Ρ]V±ΰJΣεΌΈ·ŠH‘˜C*»Eώπe’ή^醧‘΅±ΩηΨ#qΐΐοT§˜΄VŒz-δšΊΚͺ}†)Ε»6ξwO‘₯αίjϊυ‹ήYΗ vŠϋ<Ωε«7 ΟZβ•Ϋœ’΄όC‘jΎš€T₯C© ]}Ak2ši«  +‘ψ}em¨ψΏO΅½‰f·Ύδn‡±¨‘{β $žπ₯¨*Yύ‘Ένž•j:\‡;>TqΤV–’^j:uν嚀‘Ϊ Σ(aΌ/ήγ―εGφ-ΰΠΏ΅έ,ŒžR³0Ϋύ‘ίΏδiY™΄Vξ…αMWZ΅k›H£K`Ϋ|Ω€¬ήƒ=j₯懨Yk1ιwp―$uEV# Έΰzcή‹=Þ7΅ΜΪ+¬okͺΚ;`<Γ±qν»Σ=Ύ£Φ² πξ£7ˆ[EX”_©e(Μΰg―Ÿ+©³2(–χΑεž™%τΦΙεΔ7H‹ /λ’½ͺ߁΄©ο,t«ύ ©g›aΉiX τ”r»Ω‰ΤVΊΤγθ­A·ˆ58 @Εu*"ŽŠ‘Θ―h^Υu»VΉ΄Š4Ά ΄K4 ΟZVw²+™%v`ΡW΅­&χEΎkMFΐn †ˆ#¨‚?‡ž w+δ@§ι”oγ8_Zj-‰Ξ)]³‘’Ί/ hQρ|N€Wo=:0Ϊ #ρΖ?θνΓή'MZΖΗG[ ν`yνBK…ώπχΘυ‘Fβ•EyΥΨψ;BMgΓ:•j'Τ#0-ΉΞ ’Η=ρΣΦ²|Aα}OA†―’CΗ ,Nsι‘ήŽWkT‹|½LJ+{B𞩭Y΅έͺD–ͺΫ<Ω€ z υͺZξ}‘ή mJ.B»Τ‚Y}A¬νq©Ε»_S:Šκ-| ―\Ω₯Β[F¦EސΌͺ²2ϊ…?Φ±tέ.οQΥcΣ`nΕHvΰ€I=:9X)ΕμΚ4WQsΰ]zήΒkΉ-¬#t‘¬€Θ«κWιψΦ<:EάΪ-Ζ««ZA ŠC»ζRqŽ=9ΡΚΠ)ΕμΜϊ+BΫH»ΈΡξ΅H՝³*;3`ξ8ΐΏQWt/ jΊΥ«\ΪE[ΫζΝ EfτλE›$΅lΒ’λ]ζ|φšŒ- κ3ƒΘ τ ކ?‡ž w+δ@§ι”oγ8_Zj-‰Ξ)]³”†)'G o$‡’’’Oΰ)•‘kqανif„΅‘i!ΖTŒ8<+΄ρ΄vώ"πfŸβ蠎ήόΝφ;εˆa]ΐ$>;Ÿ˜τ€YηtQE (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€'²€ό•ASΩΗ~?Κ  Š( Š( Š(  ογιεPTχΏρτ‡ς¨(’Š(’Š(λΰŸό”]?ύΙτ[W W΄M^ϋCΤcΏης.γ+μVΖF θh½ψYq,ή&ρH•Λ τ뗐βmΓ“ωŸΞ©ψM·OλΪΞ§w© 6&H%³°}†|γο²7:δtoP..4ϋ&kˆš[bΆδb AΗA¬ψkΕΏ†δ•΄‹³ ˁ"―PA Ym:_ƒΆ‘g{keύ’¦5»pδœ ²Ÿξ\ΦWŒ%qπ£Αq"6iΩ—Τ†8?©όλ›Φ|e―λV2YκzƒOk#‰ f4ΣΨqYχšΝύξ—c§\ΟΎΚΛwΩγΨ£fγ“Θ?‰4άόFK'Ί`ΕτΨLŽέΗ˜ώ΅±βΈ56ψρ§ΌK)S5»Bΐqδ€Ύgαχσυ―.Υ5‹ύR (oησc²„AΨ«±Aΐϊœšέ‡β/Ša°‚=UΔPνΨLh[ ,FHγΏ^τΐƒβgόΊηύ|΅nόa‚WΤΈ θ4―ˆ(l"³±Υ]-’Q(ίhτ”œR§ψ^mΌ^.­ηΈP!σ’Άm²΄y= νχ³νš―­κv2|4–ΟFΡu84ΖΌYζκEtY;…?OOzγ4_jš&’χΪ]γΫάɝμ!²sΚ‘ƒωUψ³Yρ ‰u{Γ,q€jŠˆ§Χ}Ν0:―Gq/ΒΟ›Eg΄a(A‘ζΒηίοΤίΦαΑ«{»νCNˆK»ώ3ŸΖΉOψΧ_πύŒ–zUϋElΔΆΖEp€χ]ΐβ©k^!ΥuΉmeΥnΪβKdΩ2( g<ΰ ύNhΡ|cgqyρΦΥmayJ\ZHΫFvͺ„$Ÿ@5'‡na“φ€»dpU¦ž0}XFA‘FηβW‹ah€ΦdΓd1‘όΥAΚΪέOiwΥ΄ΟΔl$S† λšτ…φ76ZŠ₯»…βŽΫNΈŽVq€­qωjŸΓY/xι£b­φϋΑ¬mkΗή$Φtζ±ΏΤY­œbEHΡ ŸοŸ§JΖΣ΅›ύ6ΞϊΚ.ήωw ±NυΐΙOLRΝ―ˆοmΌ-{ "ΒΦ7R¬ΜXθΐƒςœΰghΟ»Il4Α>oΙ¬κ)|h-­ζ πώ#»ωώ>e]6‹γΏhΪh°°Τ Z―άWΛη?)`q@7Ζ­₯|.ΙΡ§.s™q€ΗΤwχͺڌo/Α=ƌα597mΗΦΉ wΔ¦ΌΦν«έ΅Λ[§—2¨!}Θ?SΝZπχŒ5οΫɏ¨=Ό.Ϋ™ #}@`qψS#Ϊ·zcšτΖηαƒΤ#nέdcŸυ\½·‰υ‹oI­Αy·T±iΌ€9ΘΑωHΫϊVηό-/Πc%aβ)£ΰTžO†ž5‹Oޟ#r ωŒ{Žοόw},)<_n…κ²£κjmƒρ‘’Ύί{υ;Fρ«£jRί闏ΤΉσCδδεHΑηΪ₯ρ/Š΅Ÿ΄Ϋ­:Fr‘…Š}pχ4ΐκ|a+… ˆ1³NΜΎ€1ΑύOηMψ­#M₯ψ6iXΌ―€ΖYRp:ώuΖήk7χΊ]Žs>ϋ+-ίgb›ŽO dώ$Ρͺkϊ€PίΟζΗe‚±Wbƒ€3υ94€uΎ‡©άθσκ°YJϊ| ΆIΐωTρώ"³γm’+uΑ΅μόM«Ωθ:-½ΩM6α·IΥ9Ο\dΖ­cP |q‰‡ΪδaΊΆŠXΫŒJw€RβO‡ώ6[0ΖcQΰ―ύ¦ ξ™b·`²4y= νΧ>ΩͺϊΞ₯e'ΓΉ,τR‡MkΑ"άάΘL`€~ŸΦΈύ[Τt+Γu€έ=΄Δm%@!‡‘ƒV|Eβ_Δ^PΥΜ±Δr‘ͺ**Ÿ\9χ«tŸ=ϊnEπΩM ΖI–vΣN “ΦΈˆ­Μ[0κ=κή‰¬κοΪτ«§ΆŸnΚΘτ δΖ¦ΧΌGͺλχ0άjΧ_hšΫyh˜ΟE­FJMτ`wΎ5Ή™~7Xm‘‡—qh‹μ§nGώ<:›Aς—γΝΨp ™§ΩŸοl?ύzσ›ν{RΎΦΣWΊΉσ5tu—bŒ2ciΪ8ΐνQ\jΧΣκνͺIroi<Σ2aNοQŒYͺ/–ήVΡ΄mOL³»ΧJΠ5©nήήXο³+ͺƒΤ°Η―υ¬ŸDχ_όgo—›mΌ›]‘‰'ς±υoψUӞΖχQ-o ācD.= YZ·¨θ7Ώjnžήb6’!‡‘ƒB₯.WίOΐΆžΫΰ½ΛN₯Ζͺ­ξ7ƒ‘|ŸΚ€κ–©ΰ›θ—ιg{KΛgΪwr9ΰς[Ώα\LjΌO«ψ‰£:½γL±}Δ Wπ ϋՍΖzξhmtΫβ–Ω,"xΥΤQΈ~έ98ωήΰ_ψ£.•6—%΅υεΥ…έ¨–έnΙσ!_ξγ°δzV Ύ‡©άθσκ°YJϊ| ΆIΐωTρώ"›k:†»{φ½Vεξ'ΖΠΜz8ιVlόM«Ωθ:-½ΩM6α·IΥ9Ο\dΖ­kM5₯Έ? Ώδ{ώ²θ·©u―j·+{g%½˜…χΖYm€lr:ϊϋΧ5₯κZUόWΆωW1gcν Œ‚Πšί“Ηώ&’6GΤςŒ ‘δEΘ?πΥKKΚ ΛšΧ%ψ`—Ÿπ“€Φ±ΪČ׎sΙξΧ·ηΪ―|Oέ4ZMΜΘ|N?SωԚ‡Œu»Λ 4ωoέ¬Ϋ*FΥ ΛΨΖH¬€x₯I"fI†VS‚θEK’ΖŠ[υ5Ό_ ‘ψ§Xσ#eΝά­ΘΗΙΊIlτέ3š+λ’j·ΛxXmΰ”,0ύ3όGwσ¬=CΖzώ‘§Ιey¨m€]LH ΟPΉνλMΌ_­ιvΞΚτ₯ΊςŠΘ―³ύAΕWŒΪK±½ρP.<½©θρM™tΦλ3+>ΥRIS‘Ι&½βMW^X—T»2€\ͺ  ϊΰΝΚΐα.o+άθ4ΝFέ<#geβ]"ς],JΟkwnΫNβNG<sUΌi₯E¦_i%εΝΟs ΛέΎ$ΘωHτΖ+;Dρf³’Ϋm>π₯ΎwynŠΰlƒŠ‘¬jΧΪΝίΪ΅+†žlm€€'%`P’•ϊβ«­6ΫΗ°Ι&™ͺ\j@ΔΦν #ΰ ιΧ?sϊ ζηβμs5»Ϋ4—23ByΖΘ>ω¬k?ψ†Εm ΤXD‹΅ "³(τ FkΓR»°ΤRώΦb—hΕ„„99Ιη υ5Ni»“M&Ό¬lG―ήhž+Το­ΌΉ%’I£q0%Xη8#―ό5•.n΅ဇTΆhΧ=€PJŸηϊW!<―Κκ{Θn­$1Ο G8#λP₯fi(^6[‹‘΄?hΊ —3fφι{‚xP ψ i]I₯'ΓΟ6₯iwql £ύ@_qϋΩzγρXΥ/u‹Φ»Τ§3άΆΠΌƒWt?jϊ-vc…Žγ*ΊηΧ~\Κδ:o•wάΣψƒzoIOΊ³X­Dqύ€‚ς ϋ¦όNΌšΫΖ6SΔη}½Ό/{IώuΘjΊ•ή­zχz„ν=ΓpY½=τ₯Υ΅KΝZθ\κyΣh_”tRrά¨Σ΅Ό‡kš€ΪΞ«q¨]$I4ΔX ΐŒ“ι]£FlΎ―o΅o2!Ž & ϊ|†Έ½ {mZΪmVΥμ‘³$ ΫKπp3υΕjxΛΕW%žΩ~ΟžŸhž]΅€?v!Η~ηωTš%edaZ[Myu΅¬m,ς°DE,Η€O«ιwΊ=σΩκvοor€Χ‘χ¨τϋˍ:ϊ Λ)LW08xάs΄ŽjΞΏ­_λϊ“ίj³ωΧ,ξΪ:†gQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE=—ό}'γόͺ žΛώ>“ρώUQEQEQEO{Oψ*‚§½§ό?•A@Q@Q@+£#a†•=οό}?αό¨ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ )QYΨ*ΜΗ’M,‘ΌR4r«$ˆJ²°ΑuPh’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(§Λ ‘2Ζθw¦ε#rϊQΑ¦PEPEPEPEψb’ypΖςHz*)$ώ€EPEPEPEPEPEPEPEPE?Ι“Θ3yoδ†Ψ_iΫ»Ζ}qCΕ"F’Xdˆ!–7@λ½7)—ΤzŽ 2€ (’€ (’€ )ο‰HρΊΗ&v1RczeSζŠH%1ΟΗ"υWRό 2€ (’€ (’€ (’€ (’€ (’€'²€ό•ASΩΗ~?Κ  Š( Š( Š(  ογιεPTχΏρτ‡ς¨(’Š(’Š(©ογιεPTχΏρτ‡ς (’Š(’Š(’ŠάπN‘Ήβk;’Β,m8$*“ΗžΡ\…w©2²ϊ‚+¦Σut𕝗‰4‹Ι4±+=΅έ»m9$δsΑη5WΖzTzmξ“"^\άιχ0¬±-Ρ;βL”LSS|Φ`±―uλ›4ΈKhΤΘ»'•VG_P€:ΕΣt»­CUN‚<]»ηn η§C^›β«­6ΫΗ‘I&›©άj@ΔΦν +ΰ ιΧ?`h3›Ÿ‹qΜΦοl\ΘΝ ύδ; ϋζ¦5$Σo΅Ζβ―c.ηΐΪν½„ΧR[!XFι#YΘ«κWόšΘ‡H»›EΈΥ#UkH$Θw|ΚN1Η§#š‹_ΌΡ|S©_[yrK$’ΖβPJ°fη8#―ό6•.n΅ဇSΆhΧ=€PJŸηϊU9I+±Y7dsΦΪEέƏu©’¨³ΆeGf`γŒ;υwCπ«­Z΅Ν€Q₯°mžlVoAž΅³βΥmΒ:6„ΓeΜΩ½Ί^ΰžΓ#ώZ7RiiπχÍ©Z]ά[(F Wά~φG^Έόi:ŽΧ]Xr«œΦ•£I§ψΟOΣuΫLγsΓ8Τ}+ ΈπνŒ~ρ<†έEε½δ«nάεcΠ{aͺŸŠυBϊ·‡g6VKk{ Ι݁Sšξu›e>"Jγύ>ήυΚϊ—*GώQ)½ώ¬RKSΟόU‘F|Ym€i0ΕŸgŒ0-΄ΩΈ’O΅;ΖV7Ίvƒ€[^ιΆβ2Κ·6ξ₯#μœΥˆsŸκ¬9Δ‘8eBJΏ―+Β·πΈΪsζ\v¦†­^ΡΉ=Θ< αi5ΛΨ'™"}9fςζS.Φ$ŸΘ δυ½&σEΏkMF/*`r„βΊ_ΘΓαΧ…c v3NΔzό3ω|Cv’ΗΓHwHΪde˜υ50“ΎΎc’F§‹τλRX/†mgŠΫΜΜΉΘΟJγΰ³okΟ•o «LIŠάΙ…={šξόβGJρ$ΆΆ°Ϊ"ΩYYκšyΣ­RΦ)μcœΖ„‹zώ•SριSγ-[f1瞞½ZΥψ™΅Φ‰*£ΫK„‚rέUz/ΈΊ4sš‰]4t>c"ξv$* υ$τ«:†u- 8₯Ύ‰ Ό§ 4N τΘοZή°…|7¬j—χ7βΖ2‘ImfϋLΉώϋ#wσ­MM¬€ψ[+iΆΧP[}½J — IΫΙSŽŸΧ49Ύk-EXζτŸjϊ₯Œ–‘EφYK#Κ.sӚ‘―h·ΪθΆΤ‘ςδ+ΉH9V Šθ΅gaπ·C@Δ#]ΚHυ Ά?™¬ [[ΊΥ,tλ[₯‹e„f(™AάTγοσŒJqroΘM$vΊ ±ψ3ατ>!ΆŠ95­Rf†ΪY0·I€{’Ώ¨όxνJΤΧξμ"»·‚I  ™wΊEυ~uγJ·ό'wGiΗ“8dW_¦’5O ΰŸω_@5Q§ί [β?_ψzKuΤ"· ζE$RVω•―iπλΔwV1ά₯€jdO28$™VW_P€žjζ»έιVΏ ’]'WΊΥTΔφΝo0ΰ€«Ž™Θ?¬μ’ί_ΑβΖπΚρJŒ’#ea‚€uSkkΖ—οΕz€οjφ$μΝγrΰγΎjΎ₯‘κze₯έύ”°[]θdqÌgωυΣt˜žΣ,n,υOP΅kΥΣβWKUb7–Ο'†*zοΓϊ–ˆ—66«¦κΙ.ΦΆŒ³$‰Ό0?ϊΗΪ‘π²kvvχzΞ†δ-‘U™Tδ°>«ά…mk†ΑRk·:|VZŒ ™ ”K…8ηΌυφό+'€ξZΨ‡ΐZ¦e‡UΆ°°Ώ…ΥΡaΈ•G9Ζp{πkΉ―%62±~κœτΥό.S ΘpqϋήqLžΉϋ•#T“ ίύ ©_‰μŽώηˆ<ΙΫΒ~κ™”8ευλ\Τ67SjΖ(Λω~V>mΩΖ+½ρlς‹Φxv'ΆEφnGκ:›CΨΏξ·`,Ϋ~»^‘T•ϋ\§{#™Τό­ιΦ2έMOC2ˆ₯ яR++CΡoυΛ¦ƒMƒΜu]ΞΔ…T€žjh–ώ"†­ύŸΎ;…ŠOΆ—ΪάόΩέΖ^΅±ΰl<#β΄C4ˈL±ΐΫddΙθ}:ηΫ5NrŠ}D’lζ΅οjZΕ%τKδKΔsDαя¦Et_ τλ#ύ±―κp‹‹}2ΐίvI;s|ώx¨υ]BΥό φΊf•Ί-ΕΓ†PψΑγΣϊΥΟ‡¨Χ^ρΕ€@΄Ζή‚ŽI Xž? Έ6Φ€Ι%±Θψ“^Ύρ¦o΅9ζΪB(UEΒ€; šθ¬~ψŽςΚ …†Ϊ#:y‘Γ,κ²0<Ž?ΖΈ•ˆ©β½ŽκοMρˆ4ΫOιΖ‘βVXαŠζΥψΞ~VΗa’zZ‘q£ψ[SΥu«&γ†ϊέY₯Iά&έ€2{δŠξΌiπΊζ+Έ€ΠbΆŠΡmU₯Y.~c Ξβ7+ρŽŸ6—β}JΚζιξε†R¦w$³χηΎ1]_Ƙd> Σ$Ή΄Θpΐο@Ÿ†Ό9©ψ’ρν΄˜<ΦEέ#³D€ž•oΕΥό53κ1FΦΣ©<2B}3Ψρ[ΎΣmΣΒ:φ³©έκCM‰’ lμaŸ8ϋμίΞΆ΅–Σ₯ψ1;iwΆΆ_Ϊ*c[·IΐΛ)ώουΝr€΅ΝkMΆΤ,bƒμs–Y% iΑݞœΥ=_šΆ‘Ϋi7π,W7,« oqΐ!½3ωWIHλπWΓ‘†!ϊbΓΧρόλ–Χ|G{­iΊM•βΓ³MˆΓ  !™N>ρ$ηGLPsπλώ ?"+Q­ύ‘Όι ΧΘcΑΐγ=+Ο€„όFDr€Z“πρΰvμx5Φj1ΌΏτs3„Τδέ΄g?ZσΒ œA0=ΖΡΫψ‹Αš‹’‚;{σ7Ψο–!…wψμz~cΌξ½ £6_ΧΞΘ7Ϊ·™ΗPύ>C\₯΄Χ—Q[ZΖΟ+DQ’ΜxR*ξ΄ϋm+Dπeޱw₯ RβφWCζ9T„)#w88GWοt{η³Τνήήε%Cο]&•}―ψ_H΅Ί‰bΈ―²D2/™ ΰδ ώ…EMRH¨™~,ώΕ’ξή–H¦ˆ4Άδ7ξdξ ‘Θϊf­Ϊψ^Ή³K„ΆL‹½"yUduυ Oσ«~9Σμ­΄kψmΏ„M=―hΞFp;žžΥΤxͺλMΆρδRI¦κw15»A( ψF:uΟγYσ΄’‰\ͺξη–ΫΩ\ά_-”0HΧLώX‹6οLv­νOΐϊޝc-ΤΠDρΔ3(ŠPΝυ"·Ό)p·?δš[v΅’G˜ω2}δm‡ ϋυ¬ ίΔCPΥΏ³χΗp±Iφϋ@۟›;ΈΟλΦ©Νί°¬ŒΝ DΏΧnšίMƒΜuœ’Tz’j}ΓZž‚±=ό*!—„–7„ϊdw­ί¬²xΕif Ή"…ϋΕ7ώ›¨eO„³ύ€2£j `έάmΗ·ήύhs|ί;*±™¦x3XΤ¬­ν’‹μΧŠΘς…ηί₯eλzMζ‹~ΦzŒ^Tΐδ0==ΕtΎ%‘ΗΓ― Ζμfˆυ!ψώgσ§ψεόΘό%,ηqm>"μέϊu’3•υσ•ˆτoκΖλLΈΌ΄Ck$Ρ΄™+pΙ+œγλY>"Σ3γέ7K·λrb†$ϊπ9ΏΔq_Œ6mΘAš,ίψ}όΦEεΕε§Ε+«6Ψέ]Gt찎0r?,ΤΖRnώCilRΏπ.·gi5ΓΕ«ξ•"™Yw$UOh©βιΪd¬Λξ|Β½vͺ–8όͺΪΟIρΊ«i+ͺhϊ²E$Σ#>bn~e'―'ΧJΜψ92ΓρI.pΜ@}ΜlλWNMθΙ’ΆΓ>"xžMRυτ›(β΅Πμ%)mo2Ή]δχ'ŸΟρ«ί uί΅O…5˜γΉΡo™’Ee‘‘Ί2·\ηωΧ―[Ig­ίΫΜ₯dŠwFc£Τψwi%ηŽt8α²έΗ)ΐΞ1ύ­ 35ύ9΄rOvάm§x·x€T+ ψƒ:\xί\’#”7r(>Έ8ώ•FΫCΤtkZWm:έΆI>@Uψq΅+K»‹`eθ ϋήΘλ׍/hωS]C•\β―4Kϋ-b=.ξ䎨ͺΔ`ξ8˜χ­–𸬑£ΆΜ1»ΧžΫ½3Ϋκ=kOZ½7ž%π :}՚ΕδGΪH/"M[ρμrδ)σ4Ih>Tq°x{Q›Δ ’¬J/Υ™J38λτvσΑ:ݞ™%τΦΙεΔ7H‹ /λ’£₯v‰%ΡέΫaYŽς?ψŒέ¬Vqp\q»=ύϊώ΄{IZώI‡*ΨΜπ=Φ•=ε–—’Au$σl7-+>ƒ°|Evή ΤΰCΤ¨Š:*‡ Ήΰb‹τŒœ€§σ¨Ό]‘ψ§Xσ—7r·#$΅€Ιϋ$Ϊ…5]jΩm"-ƒmΝ Ecθ3Φ¨k:Mζ|֚Œ&)€άA ;GQ]lΆzv™α]υΉ5KΥ» ,6πJ~™ώ#»ω|R ωXεŒΒΚrκ;>΅*mΚέβ¬RαφΎξWȁN2»¦QΏŒα}j/ι1Ογ{m7WΆά Θ²Βόr¨Ηœ{ŠΡψ™w5·Œ,η‰Ξϋ{x^<φ#ŸηKΰ}Nmgβ}­ύΚD“MζXΑ Δ,8Ι>”Ή€ΰΫμ;.kξΦcŽηEΎf‰”n†FθΚέsŸη\~Ώ§6‘_ιξۍ΄οοοpβ+Oαέ€—ž9Πγ„Λw§8T`Ητ›ρtΈρΎΉ$G(nδP}pqύ)ΧιWγοκΆZΊ£κϊMΉΊ΄ΊU ξŠ9FΗQΣσ•ζθ_γ0'Šu)2-ντ™£cŽν‚Χδ5η΄ΐ(’Š@QEQEQEQEOeIψ*‚§²€ό•A@Q@Q@Q@ήΗΣώΚ ©n^ve9SεQPEPEPSήΗΣώΚ ©n^ve9Sε@QEQEQE%΄ςΫ\G=ΌΡ°du8*Gq[š§Œ΅νRΔΪ^_³@ΓͺŠ›ώ€šηθ€βž­νzF½©hρM›tΦλ3+>ΥRIS‘Ι&»β=W]X—SΊ2€\ͺUP}pζ²(£•^φ ½ΝΕzΞ‹lmτϋΒ–ωέεΊ+€}²? ‘¬j·ΪΕίΪu+†žlm€€R’ŽTμ{ŸΌAidΆ°j "EΪ…‘Y”z#5a¨έΨj)k1K΄bΒBœδσœυ5RŠRθcζ•ζ™ε”ξ‘Ψ³c$ςiφWSXέΓuk!ŽxX:8ΑZ†Šb.κϊ₯ζ±zΧzŒζk‚–ځΠ`*ζ‡β}_D‰’ΣΜp±άceW\ϊΰƒΒ±¨₯ʚ΅‡wΉoTΤnυ[Η»Τ'iηn 7§ €>•~_λ3jΦڜ—€ήΫ!Ž)<΄ωT‚Ζ0~ρκ+Š9W`»4m5½FΣX“T·ΈΩ~μΞμS’ΩέΑοι[?π°ΌOA?ό—‹‰VŠN{ ζh•.fK±r’2\σ―6s‘ψΦΎ―β½kX²ϋ&£zf·άi‰‘Ӑ¬:)Έ§«B».]jwwZ}₯Œσn΅΄έδ¦Π6ξ9<“Ο­†§w¨EkδήbZΔ!„mjƒΟγTθ’Θ.uCβ‰ΐΐΤς^/ώ&²‘ρ©³.«Θ„ †›ΚBy8`tμ+*ŠJ[!σ>憙¬κ]ΜΧW,’Ξ₯%,‘ΓƒΧ!›€jχΪ=ΩΉΣn ˆΑ*zx5FŠ|¨WfΆ»β-S]ςΖ§teHωD AυΐšΔZ’Im"έaν 6Ρ-~XΘΖޜύO5“EͺΦ°ξΛ³jWW–6—ξ΅³-δ¦Π6n · dδŽυΨψ§Η·Λή7‡΅&ώΟ”.b nŠΰh€αυ@€Πιdydy$bξδ³3’ORkMρŸˆ4Ϋ8νlυH#EhΡφ@XŠη¨¦βžθI΅±«£x‡SΡ¦š]:θΔfX₯C+ύAοRjž'Φ5KGΆΏ½i­έΔ… (Œ°β±¨£–7½‡w±rmNξm.ίN’mΦp9xγΪ>Rzœγ'―­S’Šv°Ž«Αή.m ΪλNΏ²‹RΡΘ3ZHqσqσ)μxι\εϋΑ%υΓΩΖΡZ΄ŒbŽJ¦~PO¨¨( –ΧΗ^$ΆΖ¦c˜‚4HΔ&1Œ•'§½UπχŠ΅ŸΗ2hχŸfIˆi”’:}ΰ}kŠŸg¬Q©ψϋΔΊ₯„ΦWΪ—›m2ν‘<ˆ—#κ£Š5ˆε΄‘/0φ–Ζε'Λ+Ӟ;žkŠ8-νή«yy§XΨάMΎΦΛx·Mͺ6o9n@ΙΙσ[–>?ρ5•‚ΩΑ©Έ…bz#5ΛQC„^ιε‘€‘™έ‰ff9$ž€ΦΎ³βm_YΣ¬¬u+³5΅šν…J¨Η䁒qΖMcQT†‹¬κ-ɟLΉx$a†ΐ0χƒSλΎ$ΥuΠ‹©έ΄±‘ΚΖ*ƒλ€5‘E.U{ΫQέμt:o5ύ6Κ+;+*ή!„O&6ΐΞz•Οz­­ψ—VΦΥ.όυ…‹ ςΡpΰ V=Ή"μ{šΝύζ°Ί₯Μϋο•‘Δ»`6œŽ0;Tsjw“j¨Όμ/ZO4ΚΈS»Τc₯S’t:ŸŒυνJΕ­.οΩ q‡ Š…ΗΉΜΡυkνλνmΛΑ)I B¨ΡBŒR²C»5΅ίjšο–5;£*GΚ PͺΣΌ)β Ο λκyRΰ’7YυSωV=KD&ξlψ―QΣuMP]ιhΣcxΗ›Ύεdδ― Ζ8ΐ­‹_‰~+Ά³[hυBUj»ΒŒκ?ή#'ρ:Š–κβk»™n.dig•‹»±Ιbz“]―όOk₯:UώΖ#ς‚n{ΦΈš*w••ΔϊΎ‰E§]˜αcΈΖΚΉυΑ…QΥ5½Vρξυ ΪyΫ‚Νιθΰ₯T’«•'{ήΖΖ‰βm_C‰βοZœξ)±\gΧ *΅½B-lκράcP,_ΝΨ½H ρŒt'΅gQG*μgQ'ΌK$l©e#Θ‹ΰ5k«ίZι—:}Όώ]₯ΙeT\Ύ;ΖqνœuυͺRPŠΩΩ~=^ϊ="M-gΝ„ζ™°ή ‘‘Σ±kCρ>―’DΡiΧf8Xξ1²«}pAΗαXΤSqOF‚μΏw¬_ήj©©\ά΄—¨Κλ#ΑS‘Œ`zcϋsQΈŽρ&Έά·r‰§oqΠτγπ¬Ϊ(ε]…vužρ> /Pattern << >> /XObject << /Image18 156 0 R /Image20 165 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 167 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 168 0 R /Resources 169 0 R /Annots 171 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 168 0 obj << /Filter /FlateDecode /Length 170 0 R >> stream xœ­SΫJAή7λ‚―;²ινKU_ΐ—A|ˆ ‹‰»Θ¬fM~*δ£ΟώDRΥ{›(NΣΣU‡:}¦Nχ,ΐj2ή/4ΔλΥ`΄16‡DkΕσœ‹d™ƒƒ©τn›8C%θΰY"οœΑ-‹,`ό‘ϋ>›˜ώ`'3&τ–5΄79Ÿ=άOKjΧ{pΚcΡS²U©ήΦΖDV#F°H^<`ΜΡ ΈΑΊ†θi‰mΉ[l#)’>­έέFΥΪu"+m&.ΦgkβΪaζ °ο&¦(gœ'—Q>ώcα=Κ=Œξn: .”'AΉώϋ\3Or: ”ε‘•―π†ΝΎ:i‘š5T#5QΗƒ5j~šΛζIŸ«΅Σ<ͺ2ψΕΠ»|^•ξͺ]Ξ*±yjΩσ= eΔ€Β”ΟpXή²‹ˆYΗθE+ΓʍˆύΓψΧ.BΒ૆χ΄ΌΑξ0₯ Φυ0+=%ν‰Ρ΅υnή[o|ΆWOžBFυ‡¬εZ.yΑαΎΗŸζ“ι7gαΰne‘Œ?SκΔ- endstream endobj 170 0 obj 415 endobj 171 0 obj [ ] endobj 172 0 obj << /Subtype /Image /Interpolate true /Width 1700 /Height 246 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 173 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐφ€"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊŠ(ͺQETχΏρτ‡ς¨*{ίψϊΓωPQEQEQEQWtM=΅MVήΝ ca˜vQΙ?•R’¬j1CύΔVΞd†7*z°f―hšR_[ίάάΘΡ[ΪEΌ²ŽYEόy  š(’€ +[Iπώ‘ͺ@ΣZΔ’vο‘‚‚}zΥ-JΒηMΊk{ȌrŽpyΘυΈ  ΤQEQEQV-¬ξ.£žH#.&ω#ε_Z―EPEPEPEPEPEh^ιoi¦Ϊ^4π:ά‚B#e—κ+>€ («ΦwQΟ$—H|„ς―­W’Š(’Š(’Š(’­iš}Ξ§t-μ£σ% Ά2w$ΤΪΆ‘u₯…ΰŒy™Ϋ±ΓtΖz}h>Š( Š( Š+jΓΓ:•υœWP$^TΉΨZURpqΠύ(Š·©ιΧzeΗ‘} E&2Αz‚85R€ (’€ (’€ (’€ *ΓΩά%’^4d[;”WΘε‡j]6Ζ}Jρ-m4ϜqΠgϊPj(#ƒΤqEQEQEQEQEQEU‡³ΈK$ΌhΘΆw(―‘ΛΥ^€ (§Γ–dŒ2©v –8>΄Κ*ξ±§Ά—|ΦΟ4S2€wDΩΥ*(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*{ίψϊΓωT=οό}?αό¨ (’€ (’€ (’€ ιό3έTΥΫ‰6ύšά΄έHϊqϊΧ0$2OjιΌZE…Ž™£!ζόι±ήF:`s5Σκρ+π…β{ζϋLΎ»„#ψΗΠl§«ΪΪvΘ>;(δώ€Υ_C]Έ’ζ䎁³λ\ο†aΆ–iΜφ:„ͺ™ŠΪO«ΘzθιAs*kwŒκD0(tΪOχ‰κ3ΓZ…€zEώŸsvφ2NΚΙpŠ[§πœsλ4gΔZdGΓι¨fΆ›t“yONHΞ@?η­YπΆ‘ftL 2 `΄ύιή}ŽΉτΝQΤ―΄τπΌš}½ό·wΰHZHΩw vΟAυζ©xZϊΫνφΪ„pΌΥ]Ϋ(ž§uo4"ΞΒ;<|₯QΛn$ϋΧfϊ%­­τ:pΠdΉΆ;V[͜ž¬1ΨfΈ½N ;IβώΝΎϋbγq$Η΄η¦ZιootVρu ΅k›MΚΎu’£HΒ°γœP/¬Ω‹ VκΥX²Ε!U'©ΏJ§S^H’έJπ‡³‘ΫscΆO­CHΒ–Ά2Ψκχ…ΏžΆρ+ͺξ*s“ΖGLΰ /ίIΤ4 .mνα°Ύ‚@’%“>jžΰσΕWΠ―­νtfδΫ%Δ*± €ξ ŸNŸbS²΄¨ντ KΔTΉΉ,H$νAΗnζ³|[₯Ec{hmaxκ%“Ιs“wZ³g}c‘YΩ]κιΧ…ΆΘ™]Xη·zΙΧ%΄7ˆΊtΧG€e™Ž]»A@5Τ:-–»k’>š%ΓF―pd!‹6γΣ‘Η½sΪ—Ω΄οέ²€ΆΡLΐ@IŽ@†ΧRυ}rΒυ¬ο?΄ΩγVUΗ•@ή{ρΧπ¬=b+kί₯εΧΩ`3>e—Αϊ ±β(μ€Π4»λ;(να€ ¨ΔύӁΙϊS|am{-λMέO [‘Ά/·Μ?_oλWξ°n4[ ?ϋp―ΩYΟ™φIνΗ=;VˆšcKpš…ΤΦν,.#RB‘κ>”oΔBέmQdΡ₯Σo·πF|·_ΗΏ΅Ό-¨Y#SLˆ-?zwŸίc}3Tυ½JΡ|:4Ψυu9ΜΒO5Ρ”Fθ3Ο¬Υ _Z[}ΎΫP‘β‚ξš«»aυΕRΥ―-―6΄°ŽΜ( „rΫ½ω§V:“«Αi&•‰*!–F€ϊΦΉMVήΚΪT]>ϋνˆW,ήQiτΑ«ή/Ύ·Τ5ešΞO2?%;HδzΠ›+m.=›ωwZ|­ε£‡Θ€*A‡Š~“£Εiy«ΛͺD%·Σ‘†Φΰ;žσώ’Ή…%X$Θ#΅vώ5ΤKh–”έ^’\\γ©Β€3ώ{PzΡE€νό"Ϊ@°ΤJ-π˜X·ΪI+‚ΈωΆ{ϊfΉLi’Iι vΉ$?ΪJυγΗγVΌ7}ogo«­Μ›{7Š?”Μz:V*1GV^ δS·Ή‹DΣυ¨tI4Α>JG%ΛHCξ`9ρ“§iPGγeΣg_:έfdΓΑ#?₯jOy _κπλSήΛ Λ±δ΅ςI,κ0έ1ΐλVN«ΐή2]Nδ˜`iYΞA;AŸ…hBΪ έέζ›%”VhΔWo1ΞΰxΞxηΣπ>¦½u’ςwC”iυΤ4€+³—J›Sπކ!šή//Ξϝ&Μεϋ~UΖVή«}o?‡4kX€έ=Ώ›ζ6ε²9θ `[ρ}Δ?a¬ε.§΄„²‘άΉ8ΰψΗς­-XθzN―€šTr$¨†YB6θ?ZαλoΕχΦϊ†¬³YΙζGδ’ηiΟZ³e£YέψΘιπΜ%±άX:>r‘w`ωUΛQ£λ«kk¦­œΒΑ2ΘIm½˜{Φ†u$u«{ΉT΄KΰuΑZΫ‚γCΡRϊηO½’ξyβh’‹Κ+ε†υ'( +ό>Χ—VQάΚ/VΌ‘…*=?΅­ΨiγOΦγ΅³XdΣ₯d‰gpAΝeXίΫEᦴy1poRm›OάsŒUνGV²š¬sdήI Aς7Ξ²{qψΠϊV•ΎixšCj—7%‰±¨8νάΦŠ4ϋ}+R±ž+fH&fkiό§?2g*{;λύ ΞΚοP—NΈ΄-Ά@ŒΚκΗ=»ΦF½%›έ"iςάO S,Μrνά€z κ5Kπ•€ηH… k–Q˜p§œΦ_ƒeŽΑ,0¬Άς±©Θ_ρšfŸs¦^xq4έBρ쀆s*ΈˆΘΣλPxnκΛJρLs=Φλ8ˁ7–Γp*@;y=θJΝ4b=JΞ <[Ι/43‰ fΫύο­Sπ–—έ½ύδφzm‚ˆνΤ‘½Žzγ«ψbώΪΚφώK©6$Ά²F‡i9bF κ6°Z_Ψ_M%Ό7AJΟ$ΖΚsΠs@|C₯FtΤ³[MΉIΌΉ"ΙΪκG 3ούk?W΄‚ θ—Diόί1ΗVΓ(ΦNŸŠCk¨\_ά—ΛΘw,jΎ›OSοVνnt½O@³°ΤoΚ{7b’yeΓ«žΒ€*x– []­βΣZ,’όL{ΧGs§ZXEl-τν‰Yξ‘Λ;g©toΕ:΅νΝ¬V₯€+3 ΗzΧΣfΡ¬ξ`Ί²Χ.­ RKF˜“άdpsτ4Ι^y&κ_³+€ŽΕΌ‘¨ͺξ·uφ―ws ŽY (=qT©Τh1XΗαφΌΊ²ŽζQz°δŒ)QιψΥ­nΓO~·­šΓ&,{$ K8s‚k*ΖώΪ/ 5£Ι‹ƒz“lΪ~ΰœb―j:΅”Πψ•c›&ςHZ‘Ύp­“ΫΖ˜ιZTvϊ₯βi ͺ\ά–$vΖ γ·sYώ(Σντ­JΖx­™ š5™­€cςœόɞΈ©μο¬oτ+;+½B]:βΠΆΩ3+«φοYτ–ot‰§Λq΅SBžΟMρD5Ξϋ8Ώ}°ŒŒή΄­ h7wwšl–QY’]ΌΗ;γ9γŸOΒΉύ&φΦΜΚnτψοCchw+·―₯U½u’ςwC”iυΥ½&ΣOΉY‘©"€mCI»Χ§J·γKH,uω ΄‰bˆ*£ ΘvτνΓφ7—V+}uz\#¨ͺqώ;Ε²hϊ•ΝΕύΆͺZrͺ³Έέ€ή5΅Ξ—ͺh6VZγY\Y³l“Λ.¬sΫπό¨/_:kάΕ.‘Ή#’0Bsϋ·ξ=Eu—:u₯„VΒίAώΡ±h•žι³ΆzJε5ω4ΣszDmδEV•² ­έ°zVφ›6gsΥ–ΉuiςZ4lĞγ#ƒŸ‘ JσΙ7Rύ™] άv+ύΰ= EWu»¨ο΅{»˜P€rΘYA늡¬G€.Ÿ`tΙe{’Ώιΐ8ΎωιH Š(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ žχώ>ŸπώUO{Oψ*‚Š( Š( Š( G•έ€bΞŘυ$δQ@ŽG·F̍κ§›EQEQEQEQEQEQEQEQEQE±oβm^ΪΡ- Ό) .ΥP‹>ΈΝd;3»3±fc’IΙ&’Š(’Š(’Š(’Š*Ξ‘}s¨άyχ’y’ν œ€: *΅QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQETχΏρτ‡ς¨*{ίψϊΓωPQEQEQEQ^Λβi<#αΏYi“xnΪh’‰'yJˆCeGN1’sή€ Ύ±Όd—[‘Ι†μ„cœδcž0sY †’ŸΫΒτΨν;…žί38γΈΖh>Šν&o‡žKω1ψ§ΝΪvn0c=³ΟJβ蒊τ₯]Cπ‡u[Ν-Bώι₯RBŠΐ9Λ63’sQ9ςΫKά5’»‰:Vg>•¨hΠ›{MNΡnD'ΛcΤΜWWβ7πŸ‡|Kg§MαΫy’ΈŠ&ΈζeγεΨΙ>υΫDά#’»­+Γ^£ρ=΄{K•Έ΄‚H€ ΉnΪuηεΟΦ΅tυπΟ‹ΧWΣ¬44ΣgΆΆ’βζ9Y‹„ώπ>ΉsMΦK aEzƒ-΄¨|ϊž‘₯A8ΥΩ|ΒF•sΣ―Sψ֏‹t}tOCa₯Ηk6‹q—:ΉfHΨ η°ΙΗΠRu’—-Ώ―ιε”W©xwΓ°Ωx;NΤγπΫkχχμμΚΜvA8ηό}+β‹eαέ{I»·°hν.’K™,&cς0?›gkΰ_ ^[Ϋ€wWB:AΥφ°?Jq¬₯o=δ(ΏΗšm†™αy,ΰHžλMŽiА2MvχΪ.£ΫΨ₯ŸƒΆτ—·G–ώ) ΘδύβιλΨ}):Ι$νΈ3EZΥ ©ΤnNŸΡΪy‡ΚIΎϊxάUZΩ«€h†―g{scΙ’ξ—ζγπ;τ5iWO£Iͺ*―Ψγ”@ΝΈgqιψΧqπΗQ]+@Χ/$Η—φ’LqŸk~„Ρβ 3ϋΑšε»MYL~θQJώ„V>Ρσ8—Κ­sΞh―EΠ΄(­<-a¨G 6·{zΞX;a@p:w?η₯Tρ‡a₯x³BahΡXίyRKi)'Κ%€uΟ^3Tͺ¦μ.Gkœ-]Ρ΄»­cQŠΚΕU$ΙPΜp <ύw7Ύ²ƒAρϋ:‹θξ¦kCΞVή<ψ=XΡm-l>.ΫΩΩD±GoF έΌ’Xώf₯ΥM;“]NWRπVΉ§ΩΙu-ͺΙc.ΠΚ―΄{€s\έz‡τŸψDcΤu­OR΄šΚHήŠΥΜ‚W<…R}8όj‘ΰνMΧn¦²ΎΥvϋE£:nŽG'•cΫΆσƒγŒ¬|rφγˆm­’Ž5μ3ύkΟΑΑΘλV"φΉ€έ蚭Ɵ¨GεάBΫHμGb=AŠ£^…ρyώΥ½όƒύ"λH…δ>§―υ5η΄QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQETχΏρτ‡ς¨*{ίψϊΓωPQEQEQEΨ|SΦl5ΟΗw₯ΟηΫ‹Xγ-±—ζΘΓk’€:/‡Ϊτ~ρ]–£p¬φιΉ% 2v° ‘τΘ?…u:Œή³΅Τ.£ρN©ͺQ…₯Šy±cΣ{ ~zךQ@—ΓοΨiΆΊΆ“­Ϊά\iš”j²}œρ²ηυύu ώ͏ΰδ©£Zή[Ω IUσIΞά—8γΫώ^m λz†φΝ"γμχ; oΨ­ςž£ νVΌCβ­oΔIk7ς\€Gr&ΥEΧ Ο½01(’Š@tϊm―†Α—Σί_\Ηβ|A©ΨÌvΖ99Ηη“αύfοAΤ’ϋO1‹…R£Μ@γ`πk:ŠνηψŸβ9‘’'’Οc©S‹TθF+ˆ’Š+Υf΄ΡοΎψN kP}8–’Έ™W‰ε sΞG>ΥεUzοV½»Σ,΄ϋ‰χΩΩξς#Ϊ£fγ–δ ž}k:r΅¬AρYΣ΅+2ΟEg’ΓM΅[d•Τ©Ž§žΓυ¦όLΥμu―₯Φ™?ΆŽ2Ϋ~`FΉ:)ƚ­ΠƒΐZδ~ρMž£pŒφιΉ% 9ΪΐŒ¦sψWYg}α? Η«_θڬڍεέ»ΑmoφvAoοΧζtR%'{ΨhΪΝ…·_Nš}·‡UŽδG±ξΒ€[8Ηn™ΝkkΎ$n­―u=•Ά ¨Rξ,au9œ?/zγ(’T”―ηϊΧψ¦MΫGŠΓZΎΦoΪMLΕQΠn§ίλZ:uχ‡υιš>·©Ύ—w¦Θζ9|†‘dF9#އ·αήΌώŠ=––ΈgΔ-nΓUΏΣντν§iΦ©kΈΪdΗ|uΊΧO‘έxcMΎ΄Τ4―κuœed—Nx€rΗΊ’>RN†Ό²ŠNŠqQΈή-Τ`ΥΌK¨ίΪΖc‚βftR0qκ}Ο_Ζ΅|W…cΠ΄wπυΔςjLƒνŠα°s‘€sžœbΉJ+D¬¬€θτmJΫΑΎ ±š]·WM…6“»kεΉΖ΅ΉψžΓSψ{kdΣΔΩZ1*lo˜&@mΨΗLwŠ—M7™\ΟcΉΣ΅M7T𾟦ίjσιv,α%XΩΦTcœ§¨χτχ¬\ΨF£ά]άE n.’οά€~θφ¬J(PIάz­ο‹΄IόS§ΙφƒύœΦΣ-ΛωoςΌƒ$c<ͺτΉέ _³‹βLΊΕμώ]›Ν3 61ωH`ΌŸNΥΖQR©E+›g]α}^Γϋ7YΡυ‰ό«΅2Γ)Fo.Px8žxό©ž Φ,­lu]/SΈšήωP­ΜJI‰Τδp§½r”U:iίΜ9™Σψ΄˜4Έν¬΅k½Vυ€άςΆδ‰Π+u>υoMΦt{ο ΪiZυ΅ϋ=“³A-¦X1ΙSžŸύa\mlhž%Υτ8$‡K»ς#‘·°ςΡ²qβ“†–@₯©ΡόO1Όώ3m°χG““ЏoιVtŸψE΄νWΣΗ‰LƒPXΧΜϋ £ΛΪIιί9φTΤnυ[ΆΊΤ'yηa‚Νιθ@*₯%OέQl|ΪάΫH4;_Ε·“_ιΗ4Q˜›‘ΩO<Wac«hϊž£εψ’ηU‚{wŠ…ΐι’ά tν^iET©σnΔ₯cSΓ„zWˆ,/¦Vh‘”3…λŽ‡₯β»} GΊΏ΅§ΉžyŒŸfkWM‘‰'ζ<W3E7n+ιc₯Τu;IΌ €iΡΝ›Θ.$y#ΪFΠIΑΞ0zϊΧ5E°7sΣ4 eμΎά]NŸιο%”§―ο0N>œŸΒΌΞΟͺ^O¦[ιΝ›+v/A@ž§ dυ=j•L!Λwάrw=CΗ6πši0ψ³E’9$‚Τ.£l\…rΨ=F3ψŠγΌαkΟ_Ό6­Vπαξg‘‚¬HO_~‡­XqK$EŒR:R­΄γ υΪ…–DγYc|nPp2;Υ’uί΅«=_Δ1E₯?™§ιφιg ŽŽ9aνΞ? γ¨’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ žχώ>ŸπώUO{Oψ*‚Š( Š( Š( Š( Š( Š( Š)πDΣMQŒ»°Uϊ“ŠeΉuαmVΧ]·%Eμΰ4jAΟ9όεYΊŸ>—¨Mex‘g„αΐ9γ=JIμ;4U’Š)ˆ(’­ΩiΧwΠέKk ’;dσ& ±}y’φ₯ͺ 0©8²_‡ž!@Αm‘‘Τd’N›Ώ,rQݍ&φ9*)σE$2ΌS#$ˆJ²°Αv"™LAEPEiψsG}sRq\AnΕ ο™°ΌvϊΦ|ρ˜f’2ΚΕ©*rcιJκφ ’Š)€QVυ-:οL™"Ύ„Γ# ‘A εOCΕT‘;€QEQEuπ™Φ­΅Bυ4έΣk©vIώΟ?¨ ^Šžωmϊαlδ΅YDξ0Μ™ωIΈΕA@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@O{Oψ*‚§½§ό?•AEPEPEP^Λβi<#αΏYi“xnΪh’‰'yJˆCeGN1’sήΌj»ŠzΝ†ΉβXξτΉόϋqkeΆ2όΓ9` ^Ό)₯jE²Ή[9I ‘·F~ΠΓ―?.zυο]tΎ΄ΦμυkY<&‡φx[+Πηη+Ρ_>ΎώυζΏ΅θό7β»-FαYνΣrJdν`A#ι κuΌ3gk¨]GβST2£ Kσb(Η¦φ=@ό8υ¦‡zn”š&Ώβ nΜ_E¦€b+fbέΙώƒΏSW΅ΈtOα•Ζ·₯θρiχŸoXdUrαΠHR{AΗ©5πϋΔ6m­€λv·f₯¬ŸgΌlΉΑύA]Gˆ?³cψ9*hΦ·–φCRUFΌΐ’s·%Ξ8φ€Π’Υ­#ώBΆ_υέ?τ![ž‡Γsj“―‹¦–+A 1έ‚ωv‚zg‹ΫΑ¬Η$nίeŽΰ2³vΰ‘λŠO`G±κϊ–žšΕΕΔσΔΊ­ƒ½€άK³kΤ…άί­s&ΒΧRψΗuk} ΝnμΕ‘ΊE‘\߈υK;ΟI¨ΫMΎΜάFβM€| .NΟcΪ΄ΔΆvΏ$ΦΰfžΔΙΛ*J”ΪHι\Ρ¦Σ±«’oζSπ.Ÿi©κ±ή@²€V3JΏ…\Φ§ψs₯YκSκR\Ϊ­υΝΌνμΪM‚Vη<ϋqω֌7žπτZ΅ζ•©I}u{ΑC'”ϋΔυΖε\ί…—F‘ξX»Ή±›Ϋ]D ۜδOoΦ­ΆΣz“’±£βρhΆ1¬ήŸFΤΓπW>T‰ψχϊVχυm=΄ eF‹΅΅€3·˜p9έιŸoZΞρ.³`ž[1†δgρΕ_½mΪΪςxόA¨4ŠE΅ͺ #(OχΨυ”“Ί°+u*ψ*ΗN]+YΦu[Qw‚ ŽΔ+3’9ύ?:·«E£ίx ][OΣΚλν’' ε‚όΉΒη±ΰγλYžΦμμ-υ-;V·žm>ύ?‘θTœΧτΏ¬ύ~:ιp]Cj5±ζJvςάqνψS•ΤΎ`Ά)|=—IΤ5 ϋD·žY ›šCΈαY‡†+ŒΌP—sͺŒ*»=k²π+xIΏ°Υ―uΣΜaΛΪύ’C‚U—ΖG|τ¬OZi:Ν₯jηPidbιφg‹`λΥΊΥEϋοΔOα;«Ν&ΗJ‚Ιm|-ύ―¦Ό*ςήΖε€lυ ž½‡Έ+;ν6ΓZΊ›ϋ3ν–-Ήb·Ή}₯9GqŒ~5ΦθχΣο-o΄ί_XZ‘W–Αβw,{©#ε ύ q~%Ύ‡SΧοοmΗ ς—U#§άυ©¦Ϊ¨εάοΎ k:m΅ύΌ7:½Τ―e,­+€η v¬θ_ZjšΝŒš‹Yͺmˆσ‰λŽp1όκLj.<=β(-―₯Φ$²½ŠΡakf΅wάΚF “T<¬YZΨjš^§q5€Κ…nbRLN§ ΰsπχ€“P²άχ΅4Ό[‘Β|.ΊΈΡΫFΌŽΰC,‰WR8`NxόιΆ‰£i~υ[Ν&;λΙg’0Κ©ž[pχ¬ΏΆ“—΅–­wͺή΄›žVά‘"ϊn§ή›¨κv“xHΣ£›7\HςG΄ “ƒœ`υυ¦“i/0ΊΈx-—MΎΡ<¨Eά%§΅I7ω1Αξ3Ÿ·|Jζίΰ„ΰ„ΈžydΗρ0v?ύ+Οkό=^3ψ}‡mηŠ-oL¦ΆŽVΪ'‰$λ–?υγh«+έΟ4’₯»·–κkk„Ω<.ΡΘΉΞΦqξ**b (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ žχώ>ŸπώUO{Oψ*‚Š( Š( Š( Š–DQ,ΜΩΟηQPEPŽƒ­κΫ4‹³άμ)Ώb·ΚzŒ0#΅ZρŠ΅Ώ$I¬ίΙr‘Θ›U\(>υ‰EQEQEQEQEQEQE]Ρυ[έσνZlήLϋJnΪ­ΑλΑUoΔ:Έ#₯γΞ±œͺν  ϊΰ3YTRεW½‡w°QEΔQEQEQEͺΕ2’¬AJ(;I#<ŒΞμK31Ι$χ&›EQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQETχΏρτ‡ς¨*{ίψϊΓωPQEQEQEO7όzΫΐΏASΝΆπ/ηPPEPEPEψc2Μ‘7;υ4Κ+Υ5©<#αv?έθIu j‹u~ς7˜ (;€€ƒ€~+šπΆ¦λŸM·žI΄ƒ#ΊΎ ³Ζ 9δ‚²U“\ΝiΈ…tήπF³―X-ޜ–ν1@eVΘφ5ΤιλαŸ―§Xhi¦Οmm%Ε₯Μr³ ύΰ}r:ζΉ/‡ς2‘Ώ\―ιτcWEπΟώAž1°<ίΘӜ€ €€αh§CK*F˜άμgΤΧΆIα]?OΥm΄Tπ„Χφ"Oͺ>ζκγΟ8ώ”κUTχΔhίFπ½ΗΔιυΚA’h²|LM).γ—E{€T”2²•άx>Ώ.­(ΦM^έ.Ez·Š­,, Τ`Τό5ͺ[kλF/†ώcΣ―?JςšΊu9Υΐ+Vγ@Τ Π`Φ$‰~Γ3mW ΞHδvθk*½oK ΰ]C“nuK“η¬n?­*“q±QW<ΛR΄θlεΊUT»ˆO©ιŸJ£]ŸŽ£f±π€XÝ:5Αγž•ΤΙα»+NίI_ Λ{dB$Ϊ‰v ΈυaŽ€g΅/kd›%ή‡‘Ρ]ž›‘ZΕβiF&h-g6ΞέC ž;β·‘πƘσψ]~̘‘Χζo!eηπ&›ͺ”8 DΏΧnΝΎ›šκ71$QκI©όAαOAX€Ώ…|™NXά:ι‘ή·|=(OxΒ{qεohTc²—#oδH¨υm#ΔG„€·Ί{W„λ! rx=©sΎk•XγhζΦ-ΓήΣ5 ύ-5;έEœ…’B«)ΗοΘόύͺ—Œ΄« MCIΊΣ#1Yj0€β9ΨIδdφδU*‰» ”e§€υϋ«ΉŽΥH»7•UΨ{ύk˜–7†WŠU)"1VV Ž Χiρ"ώζΟβ$ΧHV[_(Δ{.N>™'σ¬ ΪΒ[γHΧSn.₯Ÿ`Ϋ»œLγυ©ŒŸ/4Ά•μŽfΊ Β:΅f·6 FΜTn™Tδ{θμWΓώ(]RΖΛG[ ­ΰyνBKmώπ>ΉΜxώG #ώΎωΣsm;hΠrκdήΫIgy=¬ΰ ‘‘£p@e8?ΚΊ |¬Η§K|c·6ρΒgb³)!@ΟO₯fψ―ώFcώΏ&ΠΝnό?Ψ*_εD€Τy$―cŽ’$D_ΌΔ(όkΦ€πέ•Ž§o€―…ε½²!mD»άz°Η@3ڜκ(nΟ#’Ίν'ΓOρ τIέΪΦ)_qΞ‘A }OΥ‰΅O jPίZΙ₯&˜Ϊ\ΖΜμΜ:οοΧ£ΪvAΚrsίήEki’yNΤ@@Ιόj9α’ήy!™vΛeτ ΰŠμ~jpλvV“i‘Mu,ωK¦r1· CωΥjϊuΝΞ‘k‰΅Κά°7K),Hc“Žœη|άΆ +\δθζΦ-ΓήΣ5 ύ-5;έEœ…’B«)ΗοΘόύ«7Ηz]”ϊ}攍¦‘l· ωdυ=ΊSUv.sW¦λ­α­ _΅°—B†XηŽ6žf•‡–”{uΟ½pώ"³³΄ρΥ›:Od$TˆαΑRΖG\g…Ÿ7@q±΅„`²π―φψ5dχ1;XY„Μ“>R}8όj‘ΰνMΧn¦²ΎΥvϋE£:nŽG'•cΫΆσƒγŒ¬|rφγˆm­’Ž5μ3ύkΟΑΑΘλVI{\nτMVγOΤ#ςξ!m€v#± ŽEQ―BψΌj„^ώAώ‘u€BςSΧϊšσΪ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(“€2MΉΰΫ%»Χ"y°-큸”ž€/?Οˆ΄Έτ‹‹{q+=Α…^`GΗψEWΡ4φΥ5[{4$y†aΩG$ώTέ^υ΅Nζνσ™\°°μ?ŠάπΟόKtMSWn$ΫφksώΣu#ιΗλL F(`ΏΈŠΩ̐ΖεUΟVŒΥz(€ϋ-&ξφΖζξή0ΠیΘw@ΖzP4›Ώμƒ©ωcμ›Άξά2NqΣλ]?‚n’ΟCΌ–|yζ8εΟM­ςœώyό*}iνΧΒW––R¬ΆΦ†ƒ‘3gssϊS‚’»-+JŽί@΄ΌM!΅K›’Δ‚NΨΤvξk?Ε}Ύ•©XΟ³$F³5΄Œ~SŸ™3ΧŠφw d—Ξες9aΪ«ΧyqͺX/„­':D-\²ˆ<Γ…8<ζΉύ-u/Ϋ£Z’ZΚηχ’ΪxΝaΣαŒΛ2FT»ΛŸZλamξξσM’Κ+4@β+·˜ηpΡξnγ1ΈyŠXdγ >υoΑgMώΣ΅Kto|ρεΚωc¦7gžΉ₯ρCθΖοP-φ‡žΩ.WΛέ»ζχΗ\S›’Ί»tΣl|+cs§₯ΥΜ’Ίaœ¨ ΙΗ\cχͺ>"‡N‘¬.4Ÿ.?΄§ο-ΥχyOΗΈλϊPά\Ε’iϊΤ:$š`Ÿ%#’ε€!χ0ψŠ‘€ιV°ψU΄Ί‹νΫC+(c‚qŒtοŠε¨ϊΚΣJ½ŸL‹ϋ2(Ξ₯nε™Xώμ¨8*? ΰh­m'Γϊ†©MkˆAΫΎF τλY5ΦήΫMyαΏ Ω[S/žΨfΪ€ƒœ“ωώtΝκV:mΣ[ήDc”sƒΞG¨=ΕV­ίΫκ‰%„:£DΜ"ΒΘAΚƒŽHλ[w1hš~΅‰&˜'ΙHδΉi}Μ ~"€8z*ζ³f,5[«UbΛ…Tž€vͺt€(Β–Ά2Ψκχ…ΏžΆρ+ͺξ*s“ΖGLΰ /ίIΤ4 .mνα°Ύ‚@’%“>jžΰσΕ09Κ+sW΄‚ θ—Diόί1ΗVΓ)ή"³·Ά·ΡZ• φ‰$„¦4W{¨&‡eβe²QΦfDy ”,6ΔΖΉ©EΆ―^Γ=’ήΓ4j’1^όŽψ¦}νΕŒ‹Τf7d εOCΕE fY’0Κ₯Ψ.Xΰ ϊΧoβύJΖΈc›I†w{T+#HAPsψW+€ήΪΩ™Mޟθlmεvυτ k{iwΝlσE3(tM‘ΝR­ΟZAc―Ν€KAP…@­ϋK,m6žŽΧ6{Κ†άxόp”WAβ kitύφΞΩ-šνdV Ϋ•`ηλ]θ–Ά·ΠιΓA’ζΨνYoK6rz°ΗašσΚ*ζ³f,5[«UbΛ…Tž€vύ* (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ žχώ>ŸπώUO{Oψ*‚Š( Š( Š(  ζ[ψσ¨*yΏγΦίώόκ (’Š(’Š)ΡHΡJ’'ήF >’›Ez–«uΰ―λqx‡QΥfΆvTk­8Ϋ»@ 8ΑπkΓ~#±ΡΌ|Ί½΅£C¦yŽ’ε’6§¨ΰΧ%Ed¨€Ήo¦ΐzeχ„ό+­£j³j7—vο΅ΏΩΩ!ΏΌO\`W αE4ιΪ„ˆ^;yΦFUκ@<γί™E8ΣI;»άΫΕφήΌ›RΥtίI%έč:Ω=“‚Y›%wτξj―ΓΝgOΣ.΅;maδŠΛQ³{Wš5,cέίρύ+“’gξςΆώΏe£i¦Ϊ]\:œ›Ι`m/ όέϊΥΫꚷ†όC©Η¬άψ’NVD7:rG!bΐ„aΐΞ=?*ςš):W΅ή u~ρ‹γ΄Υ–9Ν‡˜κUΫ|‚6džδp ֚ίΐΪTά:ƒκςΝ-₯™γςXτ,άgΛ±―>’›€›½ΐΧπ†§βm;PY‘‚PΞή‡kψΞΫΓ’Ιy©hϊσέάά\>Θ֎›COΞx8FŠn—5ΐτ xƒΒ^•κRiwšc8Ž_!₯YŽHγ‘ΰ};Φ_Δ-nΓUΊΣ­4o1΄ύ6Υm’’Aƒ&:Ά:ϊuNŠJ’R½ΐλ>&jφ:׈λLŸΞ€[GmŒΏ0#X~:hΥν·c§DΎIÁƒ‚>‡…gΡT £T¬ιΪΦ‡αΫLΗβ«½fΪβΩαƒNx$g¦Kp1Σ·•yžˆΆ-¬Y¬ς&že_=£`™ηJŠP¦‘wά ίE‘Γβ “ΓΌΊhUΪ͟½Ž@Ο$}kJγΔ[ι6RοΌΣ^W™6‘·.# •ΘQU(©n4μvΏ΅Ν;UΤ΄ι΄YΌΘΰ‹δeΪΫ³Œ+OQΤ΄ sPMZγ_½° ͺn,R7$°Β°ΰgζτT{$’Iμ>vtΎΥ¬μΌh—΄±iΜ+I‘‚27c’yΕβέ0“9 #ΣώFωΟ”bΈΰ/\WšΡD©);°RhκΌͺiΠιϊΆ‘¬ΚπZj˜·–ΚIŸOΚ¬kwΪF›α3‘θ׏¨I5ΐž{ƒFύλ\mέ5{‡6–;k;Ν[𾝦λςiΧZ{8I|“"ȌrGOΚ¨xΧY³Ύ»Σΰ7›=:‚)`ΉŏʹŠ(TwmGΤ.ό'kλ·ϊŒ>Τk‹·fήΚΖαΖ1ώΟθ~ ΅Σ š·€Ϊiχ+!Τ5#dT£Θi7zτιYΤR«ρlš>₯sqmͺ–œͺ…ƒμξ7`χGms₯κš •–£xΦWlΫ$ςΛ««φό?*ζ(¦¦Ώ&šnbHΌˆ£ ΆA•»ΆJήΣfΡ¬ξ`Ί²Χ.­ RKF˜“άdpsτ5ΖΡ@u»¨ο΅{»˜P€rΘYAλŠ₯E€Ώ \Ei­Y\\6Θ£•Y›ΰ~±2\jΧ³BΫ’’wu8ΖAbET’€6οo­δπ¦f’fζ)6ž'τ¬Tbެ½AΘ€’€;iο4 ύ^j{Ωa™v<–ΎI%@Ζ¦8ύjΞΣ΅›vΧukΫ–ςRζ UςΨΪ8ϊW5E0:ύ#X°·½πό“O΅-a•&;ν'v;sΤtBŠ(žΦηKΥ4 ;Fρ¬§³fΩ'–\:±Ιιίό+˜’Ύ&Τ­g²‡N,ΦΦQ,Hμ0\Žψό«f{ΝW‡ZžφXf]%―’IgP1†ιŽZΈš)oWΌώΠΥ.ΒνΘX)μ;UJ(€ή…}ok€λ0Ο&Ω.!Uˆm'qϊtόkŠ(§΅Ήυ=ΞΓQΌk)μ݊Iε—¬rzw ©β}FΪφς;Ζ…† cΎ+Š`tšΦ§isγHοα—u –2m#…ΫžΟcY~!ΈŠο[½Έ·mπΙ!el‘ψΦ}ΥjσhϊΜ0]I©=­Τvλ€ΐΟ–Pz0γšΖm4ϋ•κ‘²*FΡδ4›½zt¬κ(«ρlš>₯sqmͺ–œͺ…ƒμξ7`χI³`·ZS΄,{A!Ψί+ν#?^•ΘQ@Z•όθ:$I›‹_8Θ»OΛ—sΠώ΅{{€j·‹¨M«\ΪnUσ­’@Ζ‡βΈΊ(kΙ[©^β6bT;nlvΙυ­b=!tϋ¦K+έH ΐυχΟJΘ’Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@O{Oψ*‚§½§ό?•AEPEPEPσΗ­Ώό ωΤ<ίρλoώuQEQEQEQEQ]7‡ό¬λΦ w§%»DΜP™U²=)IE^LfŠžώΦ[λ‹K€Φς4NΘ §Ÿ¨žo‡ΪμZ\ΪƒGlm’„ά9YԐw₯'8Ηv#EUQEQVt۝Jϊ;Œ·3¨€Έώ΅›-ρŽάΫΗ ŠΜ€…=>”$ήΐδ£»9Š*Ξ›e6£} ₯Άί:VΪ»›hΟΦ΅uο κš’]ί€"D9CόΨ'·ΠΡgΈ9$μΩƒER((’Š(«vZmέτSZΒdŽΥ<ɘ6/―5R˜QE!…V–ƒ‘ίλ·fίM‡Μu˜’Tz’i₯q6’»3h­―ψgSΠO¨B’xIcpθΗΣ#½bΠΥ·Τ•ΠQE[“M»L‹PxH³•Μi.F £{P±RŠ(€0’•Af 9$ΰWgγo ι^΄ŽΦMR[ςΫ¬X†~χ―NτΕΡ]―‡Ό)₯ψƒΓw3iϊ€«Z[½ΜΦ’EςR~λ}1λΙ*€ +―Χ|#Z λΎΤ₯¦+œl+-»8aιžόuZδ(’Š(’Š$ΰ “@«β-.="βήάJΟpaW˜Β1ώUτM=΅MVήΝ ca˜vQΙ?•R’¬j1CύΔVΞd†7*z°f«ΠE_²nοlnnνγ ΈΜ‡p g₯I»ώΘ:Ÿ–>Ι»nνΓ$η>΄BŠ( аφw d—Ξες9aΪ«ΠEψc2Μ‘†U.ΑrΗgΦ€E]Φ4φοšΩζŠfPθ›#š₯@Q@Q@Q@jβΒ{{[ΉT.wyg9'iΑβͺΠEPE-₯Ό·wΑn…εαTdΠTS₯α•γmtb¬=λM Š*ΓΩά%’^4d[;”WΘε‡j―EYΣlgΤ―ΦΡCLωΐ'₯V#ƒΤq@Q@Q@Q@Q@Q@Q@Q@-₯Ό·wΑn…εαTdΣ%α•γmtb¬=λ@ ’Š`SΕUΫ­.κΧTtΘ’θ² PΐŒΆ1Οβ)πθχ“jν¦’)»RTጁ“ΝgΡWβ/%ΎΊ΄Xǟl¬)`0―Φ—H.υf‘lΥ ·8^½:ύ(>ŠΥΥ΄ ύ&-βΖͺ\'Λ cœΠ}*΅ή›skgmu*―‘r ΥuΠΠ:*εφsc΄·*\&ψΖ᝾€vͺtQEQEQEQEQEQEQEQEQEQEQETχΏρτ‡ς¨*{ίψϊΓωPQEQEQEO7όzΫΐΏASΝΆπ/ηPPEPEPO†3,Ιγs°QŸSL§E#E*HŸy0ϊŠυ-jOψc]Γ·z]C’έ_ΌζΚΰ  ΰ§JζΌ- iΊηΔΣmη’m Θξ―‚¬ρ¨$y UΊπWˆυΈΌC¨κ³[;*5֜m݌Œ  `€ψW5αΏΨθή>]^ΪΡ‘Σ<ΗQςΙSΤpk’άΧ½Ώ:-=|3βυΥτλ 4Ων­€Έ΄ΉŽVbα?ΌG\Χ%ποώGώΎ’Ί«;ο ψV=ZFΥfΤo.νή k³²CxžΈΐΓŠi!Σ΅ Όvσ¬Œ«Τ€yΗΎ*ΰ›Œ’½Όΐ—Ζ_ς7λŸυύ?ώŒjθΎΘ3Ζ?φ›ωΕφήΌ›RΥtίI%έč:Ω=“‚Y›%wτξj―ΓΝgOΣ.΅;maδŠΛQ³{Wš5,cέίρύ)ΙσRΡΚΓK*F˜άμgΤΧΆIα]?OΥm΄Tπ„Χφ"Oͺ>ζκγΟ8ώ•ζύ–¦›itpκro%΄x|Ό`ƒσuλWoͺjήρ§³sβKύ9YάιΙ…‹‡8τόͺj·+5{kά Β6χ€πύĎΦpΝ&β‘A`3κxρ«Sλ Υ`ΤlδΡΣI +Έ™έ™‡έ οοΧ¬Ÿ ψŽΧEρΪjΛζΓΜu*νΎA2Or8?…kMoΰm* FξAυyf–Μΐρω,zn3εΨΡ$ω½λμΆοΤ|$Τμ ρ…”ΪL3έΛpZ;Ζr!· CωΥ_λz]Υή§goαϋk[΅ΊpoV,Δ9ΙΖ1ΝaxCS‹Fρ6¨N¬ΠΑ(g ΧoCΞ΅όgmαΙdΌΤ΄}yξξn. ŸdkGM‘‰'η<U8₯VξˆΆθ~πn‘©κZBjΧϊ£HΑeͺƈqΖη‘ωϋV_Δm#O°ΉΣ/΄hΪ-NΥnV$ωdυžάŠΡ±ΏπχˆQνŒ“ο\€&‹'ΔΔ’ξ9tWΈeIC+)]ΑwƒλςηϊΤ_5{kΔiu¦Oη@-£ŒΆΖ_˜‘‚¬?4jφΫ‹1Σ‰"_$αΐΑΑCΒ85 έήΐz7Š­,, Τ`Τό5ͺ[kλF/†ώcΣ―?Jςšυ;ZΠό;c©˜όUw¬Ϋ\[<0iΟ€ τΙn:vγς―3ΡΕ΅‹5՞DΣΜ«η΄c,<❠κŸλϊJ½oK ΰ]C“nuK“η¬n?­p>6‹C‡Δ'†%ytΠ«΅›?{žHϊΦ•Ηˆ ·<$l₯ίy¦Ό―2m#n\2F@=*ͺΕΚΦ*.Χ$ρΤlΦ>‹s§FΈ©$¨Λkjaxό¦= 7ΗωSΑzΕ•­†©₯κwZA|¨Vζ%$Δκr8zeςά:κix·C„ψ]uq£Άyΐ†X7€pΐœρωΤή-ΏαQ΅ΡcΦοήvI£i1δ¨ιςχΟךΓρi0iqΫYjΧz­λIΉεmΙ/ Vκ}κo&†ϊdMύΉw’κΘΔI We‘sΖ6γc©’Ο—ώώ4Ή›βΣbu%ϋ›s¦>ΑηΫMό/ίnyΕwwšMŽ•’Ϊψ[ϋ_MxU彍ΛHΩκ@={₯rΏu«=ZσO[)€»Άβ.€M3zγ―¬Φ֏qαν>ςΦϋMρ5υ…ͺyl'rΗΊ’>RΠ•ωWόV»(|9Νρg‰l ¦%—ο(ΨΨήΉέ?]ΏΣοg·”»FŽmγppǞ=kbΛΔΦΦΏŸ\H\YΌΞJσm`FqλΞjλ―„4¨΅ »{ΓͺΝθ―ޏκ–_Ϊ–z¬―΅ύ±ƒΞD-εŸ\{Σ”o . ΪF~΅}iͺάۍ?K‡Nώ±ΘX9'‚s]­ά>|Eoα©tasΈΗ׍+ήΰ`€>£§τ#Y·Σ¬.ΰ:>§ύ ΈάΞmΪ-¬L7Zνnu κšυΏˆξ΅)­ξΛ’[/!˜³ Γ1ΐλQ>–½Ύ`ŒM#CΆ‡βJθχ(.-αΣk…$gτ­Ky<-¨θιΠiΡΖ$_½Α ]N9ΐη? Θ5ϋgψˆΊΥλ{Vδ$‚ΕT©’{W9©J“j7RΔwFς»)Ζ2 $SεrzφZ_ΑΈ–_ˆΪHqΎkξ#lW3άIw­_άLKI,ξμIΟ%^π>²žρf›©Κ Š?yŽ»cωk_β/…ίK»mbΒh΄=BbφσΖΰΰΆ[iάώ^ΌVΔqhžπn‘©κ:DzΆ‘ͺ4Œ«4…R4CŽ8λΘόύ«Ÿρbθwzœžέw1©–ΩΓb IεA=G=«vΖϋΓώ!π~—₯kz“ιWΊc8Žo!€YŽHγ‘ΰuτχ¬/]h‹©Y§…βaok«\8 Ο κδŸ§zη…ω΅½υτς·½‡Βš/Š-|).‚·[ŒPΟ|σ0“|€`€?ήjσ―i‹£xQΣγrρΫΜȌz•νŸ|b½ οSπn±βK_έκ³Ϊά§—,Φgf-"Œ0γ(λWψ›SώΪρώ’Ζ·³ͺž vί₯GšϊίmoάŸβίό„τ/ϋΫ7¬‡ςρ]•s¨k²ιWΆΦqΪΛ ³yΫžA_©ύ+π摍β[ς °Ϋ\+œ PyΗΎ*‘wMΖΪ€ΘίΧτϊ1«Ίπο‡a²πv©ΗαΆΧοοΩΩ•˜μ‚0p8ΟψϊV‹νΌ-y6₯ͺιΎ"’K»‰u²{'³6JοιάΥν+X΅iΊV‘­άh—Ίs8I’7t•ηiOz™Άΰ­=ΐ‘ρΓ–ϊV―¦:ήK8΅_²ΚĘ$' Ή<ΰqϊΦώ΅'„|1ΗαΫ½ .‘Qn―ήFσepΠpΣ₯qž,ΌΣΏ΅m°ξo.α·EβιΙ28䐧ξjμu[―x[‹Δ:Ž«5³²£]iΖέΨΘΚΐaΖ…&£Ν{k6ΪχGίμΦo!1Cœμ^Β»Ÿ]xcΕZjk’Ψ_Γd°΅£YΌAΖp2MTΰΉ£'Ητ?ΐzn–4mo_ΦνMδrΖ±Ϋo*άΰd|~f¬x†ΣGΦ| “§.—sot-§‚7,ŽΘ#=:ΦͺxX‘΅_–K{-EP­Β!)ΠδdOoΛή¬x‡RΠτΟθ7²jRMr.n.ŒF5ΰ`=‡λIσ{N»ό¬Ϋ$Π΄‡šF±}’Ε¨_Mq$@<…€ΝΛczΔρμ:•¨ψΙ€^ΐZβΞ9CύžAŽqœϋt£TΥμgψs’ιqOΊϊΪζY%‹c ͺK`η=GC\˜κ22*ιΑί™ίv³_hΊvob–~ώΫ^έ[ψ€/#“χˆ§―aτ―#Υ ©ΤnNŸΡΪy‡ΚIΎϊxάW€θw^Σo­5 +ΕΊ†gY%Ӟ)±ξ€”ƒΣ‘ ΕΊŒ·‰uϋXΜp\LΊF=OΉλψΤQΊ“Nυχ“]dΤΌβ‹H^(δ—Θ₯mͺ0Δς Νρ\>BΡίΓΧΙ©2Ά+†ΐ8ΞFΞzqŠ‹AΥ,ν|β+ζΩuwδω)΄ϋX“ȍuΗG©TάtςόΝΛΈβπ瀡-.ϋP΅ΊΌΌ• Vφςω‚ %§OεοQY¦₯ψKΥo4˜ο―%žHΐw*ςΨλ€Η½pUΣjZ₯œή4θζΝδ<‘ν#j’psŒΎ΅JD85eέκ?ΕφϊDο₯]θ>T?mχΦ©.!ς8=Η_Ί[Θ|3€ψŽΫΓRθ«sΈΗ׍+ 7Έ ¨θ•yœnc‘~ςΓκ+nu jΊύΏˆξ΅)­Λ’[/!˜³ Γ1ΐλQqN-YkmΰšW…ΰŸβ#θs;΅€RΎγœ3"‚@όxbmSΒz”7φ²iI¦F6—Q3;3€ύϊυOKρLvώ?}vh˜[Λ+–AΛ`@όGπ«’Αΰν6ϋ¨―ŸT’XΨZژ^?)BΝΖqώE5n€οuΝ}–έΘΎθvχφš¦£sbϊ‹Yͺ,6ˆΔyŽΩλŽΓΞx»B„ψYuq£Άyΐ†[}Δ«©0§<~u™ΰ­bΚΦΓU΅K‰­ ΎT)s’bu9œtό½κ?>“—΅–­y«^΄›žfά‘"ϊn§ή9A©{Oλώέπ‘m|z¦‰Ή$μ“FςcΙQΣ ί<^k–ρq±:’ύƒMΉΣ`σν¦ώο·<β΄Ό<šι‘7φεή‹«#,]’EΟیqަ“β΅e«ήiλe4—bάE%Τ‰±¦o\uυšNά‘σΓΓ]ξ‘a₯AdΆžώΧΣyobrς6zO^Γι\Ájίβ6qΘ–ΓΝ1$Ώ}FΖΐ>ύͺώqαέ>ςΦϋMρ=υ…ͺyl'rΗΊδ|€ cXψšΪΧβ#λ‰ ‹7™Ι@>m¬Ξ=yΝSj鐔š’ςσ1΄ύzMΌ½žήP^νZ9·ΑΓž=kcΑz~œ4c[ΥνΝά6 ‹Ύβ‘ݎHό?:Όλΰύ*-Bξήπκ³O-΅«Ϋ²ˆ‰θI>•ŸΰέSM‹MΥ΄}nI ΄ΏT"tBή[©ΘΘϊ~U)YκhέβάWbΦΉk₯jήώέΣ,NΈ‚δ[Ν 9d`FAϊΦ™πϋώAώ*°TΏΚwPΡτ  E»{χ–γνάŒkΐΐ ͺ~ΥltλFίUwŽώΡνšT]Ζ<χΗηONd+7s5Ω\Ι&΄°©ΡmXΊύŽ‘f#X:‹1;ΤΫ4[o½ΦΆ΄KύϋΑν’k7iοίΪb™aiC|ΈΑžητ©Š³hΉ»€Χs+Αφq€ϊώΤκšlzn­£λr<—κ…gD-府ŒΟ§εLΧ“Γ–"YιSKQiw½α£Έϋ ώΏz_d―·­Ξ—ΐΪΆžήΦUtX­lΌΓώ“€s»Σ8ύk‰Φ―¬υk›eΣ΄Έtοΰ+…ƒ’x'5£ΰmSO²ώΥ³Υ₯x-―νŒr!,ϊΰsή³5›};O»€θΪ‘ΤT μζέ’Ϊΐπ0έhnρA₯7ξo!πΞ“β;o K’­ΞγS^4¬$ήΰ`€>£‘ώU…£θv°όK]εΕ’\:mβP€Œώ•΅s¨xSUΧνόGu©Mmpž\’Ωy ŝΖqŽZ°t~Ωώ"·zΖήΥ§y ±U*@Θ'·J§kόȏ5žϋ~&½ΌžΏΏΤtY΄Ψ4θγ/ήΰ†.§œΰsΧ;V…‘ψ}βΙ";\ωXuΑ|ωωΧ)ͺJ“κWrΔwG$ΞΚqŒ‚ΔŠθΌͺi±iϊΆ‘­JπZj˜·–ΚIŸOΚ₯JμΉBΡϋ‹6Ξ|%»Y a€»ώ¨ιωŸΞ­¨Ρ4θ:•֏υνΙ•Hy ©Ο'HλT΅λύOπšθ:-γίΌ—?hžΰΔc^ύkΛm₯^|?πΔ:½σΨΣη‰Tλ‘Ο΅?ς!χ{7ϊή3±ΣtνGFΤ΄ϋP,oaK¦΄f8κ \ϊΗη]%ζ·₯§€l.ΫΓφΟlχn‹jem¨Ψ?089Oǚ΅†‘>i€3Ιe§Ϋ-ΊJΚAr:œ}*ζ“}’κ>‹FΥυ 4ι­ξLι ₯W0ΏSBz» Ζρ‹w2τH΄ύoΖV±Ο Yiχs ΉΒŒ}άϋ‘ΖΊ―ZΩYC‘ΰωlνΤ2ΫήZ±lα,z`υζΈ»HτˆΗ|χUοZί.<^/•$fγ‹.0_ χΎ‡5Γ ddΰw―NψΫ€ήΛ­ r„š<ΕW(κA8ιΧ5™ΠSψ2 Ζ«­iΰ7šdΡ}£ŒCΣζon•s'ΠWB–M[LΤΌΠΗ63ω›1½ιœώ•Ϊ|0μ|?β-_PŒ[θχZ\Π₯Γ0Λ6q€:φ#λŠσ @zΒ Ώπ”iς Φσι3;―Ίΰύ מרiΆΐ>ΥυybMcWΆϋ5­ͺ8gHΨrη:ηπΝyxΙ4ΐ(ίβf‡₯xlι:uŒoύ₯φe–φBδ‚Δ!β+ˆ€[ž ²[½r'›ήΨ‰IθσόρXuΣΫΔ«ΑsΟγR“ΚO_-zŸζ?L =^υ΅Nζνσ™\°°μ?ŠάπΟόKtMSWn$ΫφksώΣu#ιΗλ\ΐΙ=«¦ρi:fŒ‡˜#σ¦Ηyό9όθ™’Š)Ϋx&ι,τ;ΙgǐncŽ\τΪί)ΟηŸΒ§Φžέ|%yie*Λmhaˆ:C6w1χ?₯s–WΦρxWQ³y1s4±²&ΣΘžzQg}o…/μήL\Λ2:&ΣΘΟ=)±₯iQΫθ—‰€6©srXIΫƒŽέΝgψ£O·΅+βΆd‚hΦfΆ‘Κsσ&zβ§³Ύ±ΏΠ¬μυ tλ‹BΫdΜ¬sΫ½dkY½&Ÿ-Δρ"2ΜΗ.έΘ  ͺγT°_ ZNtˆZΉey‡ pyΝsϊ Zκ^+·F΅D΅•Οξ$΄ρš³§άι—žM7PΌ{)!œΚ"2tΐϊΥM {=7ΕLΧ;μβvύφΒ20@;zΠ΄- έέήi²YEfˆEvσξŒηŽ}? ητ›Ϋ[3)»Σγ½ ‘άήΎ•VυΦKΙέQ€fΤVτ›M>εd:†€lŠ‘΄y &ο^(ߍ- ±Χζ‚%Š ¨BŽƒ UΨ#Σ΄Ψή]X­υΥιrŽB’©Ηψ~tοΙ£κW7φΪ©iΚ¨X>ΞγvxΤvΧ:^© ΩYj7eqfΝ²O,ΊΊ±ΟoΓς  ½|ι―sΊFδŽHΓI ΟξίΈυΦ\ιΦ–[ }ϋFΕ’V{€rΞΩκ@+”ΧδΣMΜQι·‘aZVΘ2·vΑι[ΪlΪ5ΜVZεΥ€ CΙhΡ³{ŒŽ~†€9+Ο$έKφetƒqΨ―χ€τ5]Φξ£ΎΥξξaB‘Λ!e*• 6Ό3 ΄³Ng°ΉΤ%TΜPΔ}XŽ@­Oi‘¦‘ύšΪmMε+†ΧPΈΏΉ/—ξXΥ}6ž§ή€0ιQKΊ¨κΗ’•£«/Pr)Ωκ ‘hښιSι’hΠ(žεœοΙδθjΝπέ•ί‹–Ψ΄Ψ“&ΝΰΚ‘šΡΎ›ΓΪΆ’š­έ쐱 f΄11,@‡n?ύU€κΆϊ‰ώ v‚FΔ`δͺGηΞi'…,νξοoζ%‘c΄’E³ `ΤΎ΅±–ΗWΈΤ-όυ·‰]WqSœž2:gUΘ4]=BβΒωξηΉ‰’Š/(―–ԞΈ¬½ ϊήΧIΦažM²\B«ΪNβ τιψΠ‹χu K›{xl/ (‰dϚ§ΈόρV-ΣM±π­ύΞ—W2Jι†r €O'qŒcήΉJΫ½Ύ·“ΒšušI›˜¦vtΪxœs€Δpι5…Ζ“εΗφ”ύεΊΙ»Κ~8>JιίD΅΅Ύ‡N —6ΗjΛzY³“Υ†; מ£`ΛΤŠμοotVρu ΅k›MΚΎu’£HΒ°γœP-I·_6εΦθς.Έ HΞ? ³dšF―£eo§ y-αyaœHK6ίο}k;ڍ₯§Š£Ό™ή+@_ ωv©8'₯3ΓφΦW·ς]I±%΅’4;IΛ08  ^ΌΆ‹T΅·’Ζ9gy²·ˆ)Η@?Φ‘ρ&‘g4χC₯Ε βfu’pΗ<{Φn…xš~―iu ,‘H€λŽυ{ΔιLσέΨjm<²Κ_Θ02ν’~cΗ‡N‡ύjΌ)΄Au―ρό”hΏλβίω%Yδ¦Ο]%ΠM$ΧΊ ώ―o­\_I Ι±δ΅ςX’λŒaΊcΦ¬ΝX·_6§vΖδl[h ΰqψSΠZ¨ΊΎ:²ΆχK“ΜΗi ίΈM3ώBVŸυΥ?˜—Βšν₯žg&ΖΓrYH#ΗAωΦ.ƒ]yΊ…ΩLƒΙi7σ’8ιΠ~t ŸΖίς4ίΌΏϊ­’κφ·:Mμm%¬l·ΓψGγώ5βχΣ.ο&Ώ°Τ|ωff!—hیξ=zΞ‘υH4νΦΣJœ›©Os(RΈaΚ¨ΘηΣή€(ψ’φkύfζYΠΖUŒkώ¬ΚάρMέ–£5½ύ«…Ή™ΪaΪFΧΑΖ₯akΑΆ^ψŠΦήκ1,,rž‡ MkΨΗ€jλ¨X[ιΒέΰ‰δ†ΰHK6ίο}k?ΐς5Ωύ@j½is’ι+yky$Χ3ΔρGlb Ζ[Ττ8υ¦? ZΨΛc«άjώzΫΔ«Έ©ΞO3€(Ώ}'PΠ$Ή··†Βϊ ˆ–Lωͺ{€Ο_BΎ·΅u˜g“l—ͺΔ6“Έ‚}:~5‰@LιΊ>cywb·Χ7₯ΘεUN8ΗαωΥOiφΠ\ΨΝ§)Ž ΨVUŽvΫ5fΪηJΥ4+-Jρμ§³fΪώQpκΗ=»τόͺ§‰΅;k«›8τνΖΪΞ‰Ζ γΎ?*ΨΤBΡ΅5§ΣDΡ Q=Λ9ί’ΘΠՏ£i–š—ŠΞμK± Ρ™$…kίMαν[QMVξφHX…3Z˜– €Γ·ώͺΗu[}?ΔΛ} ;0μ@δ„ Ο½t-€Co}hRiήTM%Όϋ›’:Ο­cx2ΒΪφ[֚Ίž·Cl_o˜~ΎίΦ₯Ί:D\ʚΕέγ:‘ 6“ύβzYš ιΣ.₯q5¬˜γ„>ΰsι@ύv™?ΟZ­i|?tχ2Κ5@ίΊ@γπυ  Š(’Q@Q@Q@O{Oψ*‚§½§ό?•AEPEPEPσΗ­Ώό ωΤ₯Ψͺ©?*τ€ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ŸζΙ䘼Ης‹nٟ—=3ZeQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEU˝NςηO΄±žmΦΆ»Ό”ΪΝΗ'2yυͺtS‚Š(€0’Š(©~Σ?ΩώΟηIδg>^γ·>ΈιQQ@΅Μο@ΣHΠ§+bU~ƒ₯EEω₯’i “HςHz³œ“ψC#Γ*IΪθΑ”ϊ›EZΥ5 ½Vϊ[ΝBwžκ\o‘ϊœ Π «ESšGeUfb«χA<₯6Š δpi]ΪF,μYRNM%QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEbΒφγO»K›I<ΉΣ;[γ#ƒΗCUΙ$’zžh’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ žχώ>ŸπώUO{Oψ*‚Š( Š( Š( ΊύwΒ0E »αν@jZb°IΖΒ²Ϋ±†™οΗQυB½ α †_ψJ4ωλyτ™Χέpώ†hΟh’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*{ίψϊΓωT=οό}?αό¨ (’€ (’€ (’€ υ 6ΐψΑϊ΅ή―,I¬jφίf΅΅G ι\γ§\ώΉ―/§Ν,“HdšG’C՜δŸΖ€EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPSήΗΣώʊ( (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€?Ω endstream endobj 173 0 obj 31404 endobj 169 0 obj << /Font << /Font2 12 0 R >> /Pattern << >> /XObject << /Image21 172 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 174 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 175 0 R /Resources 176 0 R /Annots 178 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 175 0 obj << /Filter /FlateDecode /Length 177 0 R >> stream xœ΅SΑnΤ0MΈu~‚λ¦R½cΟ8φ© *­TΙR€ Ϊ]‘lΫ-ψ~…ΰ_zΰ+˜Ι6›ΠRP‰•xό<3Οy3ή€w6ΆcΤωύ6€ΡK›#rοqw­N6­Ϊ˜ZμΓ»q0&6£ƒ; ϋΰ.”dσgέΥκaωI‚½)3yεp„’‘„ΰzωOT+8ί‡c› “ο™ϊ‘i}ΚΡ;ζž#™JΒ’Ό;¬›`Μ·Ψ;b;J#₯<¨;Z½΄ΓΒfn]Žμ%ͺ“σ$Σ Ώ€YΤhUwL9Y r „νπ‡Es”k˜ΏΌΌψ ͺ£=Κω―u}cp-CΩ­|€70«ήΥ{ΥMuS?m€L²Yυ£QΝͺΏ Vυ½^4ΐ·ϋuyς­ϊΪ€ž΄w[Τ{υQ}€‹‡Cx ε5Ό(ωS E“eΉχg³ΚG#ϋKώΨΪx1:͞29k νA—σvΠ'€ΔN+ΩMβ§θ€!ΑΙ~―| ™β —‘)Ϋ(Ubώj}Ί< ž_ξD{H™³Xbο·χΕs‘uze¬›`^2avhΗb§ΨD“ΗO=¨ιEφρΆ{4™$σΉ5ͺA£6~aϋο endstream endobj 177 0 obj 471 endobj 178 0 obj [ ] endobj 179 0 obj << /Subtype /Image /Interpolate true /Width 1300 /Height 702 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 181 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐΎ"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊŠ(ͺQEQE<ίρλoώuO7όzΫΐΏA@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ΝΆπ/ηPTσΗ­Ώό ωΤQEQEQE§‘ήΨθΪ~©pˆ-/χω0$ν89«2½vγRτ―†>ΈΥ4”Υ$Μλ 2ΘQo;˜ΰžάΧ1ρ?HΣlntGE„ΫYj–‹r Ι>Y=@ΟΤ~΄ΔΡ^Υ’θϊ\ιφ6ήΎŸKU%ΤnΑIrέ_€λΑΔΪxsOβ˜Πoe#N[ƌ³6 (ͺ“οΒηή€8Ί+ΧΌYi§Ψ[κVϊ§&±΄@ΛkdΫΘ#ξ³˜=y>Υ…πΏΓ–Ϊ•Ž³«]ι―ͺ΅Š’ΫΨ£σdlυΗaΗλ@}Ez‡ŽΌ7x1uΡ Ά¨Cr!šΨ1)"Γۜ~ΎΥετQEtϊn©αθ|}cy€Ι.·#“ Ψ#8Η9ΘΗ<`ζ€9Š+CA:PΤSϋx^›§p³ΫζgcwΝt“7ΓΟ%ό˜όSζν;71žΩη₯qtQEW₯*θ€ό;ͺήhqjχM*ςVΞY±œ{šΖψ“₯iΦsιZ† ·΄ΤνδA’|Ά=@όΕe©»[ΏΰEzηˆίΒ~ρ-ž7‡mζŠβ(šβw™”D”{c$ϋΧ;₯xcKΤ~'Άir·@vI· MΫCΌόΉϊdΥΪ²΅ΐαh―OΣΧΓ>/]_N°ΠΣMžΪΪK‹K˜εf.ϋΐϊδuΝRπeΆ•ƒSΤ4¨/η’[/˜HΒ²zuκ=΅–«P<φ΄otkΛ-"ΓRZίoςH`IΪpr;W‘x·GΡWDρT6\v³h·ys«–i‚{ œ}:γQΣ4Ο†ήŸRΣS—3¬QK!TQΌξcާ€ΤΤϋkΩΕuύ.•UΩ4«Ψ΄˜u7€‹d1$Ή,3‘Œη±«Ηš~—₯k&§¦Ω§ί[Εxlَ:δ¦{0?:κ―ΌA€'Γ}6ρό5jφ’^Ί-™™Ά£ί08ΞxύiΊΞΙΕnUέ[J½.#‡Q€Α,‘¬ͺ€ƒ•=Ϊ΄¬υ­6 ~ζϊ]ήk9TͺY4€$GŽAΖOCωΧρ3]¬υ;h.Ό;ky,–²Lσ2˜ΑΞ;UJ€”’Kp<†Šο<c£Ιακ:Υ€ΌBw”9%Ύ\Ž€>”ύ~ΫGΦΌύ½¦i‘ιwv·BΪh’rΘκ@ σί‘ϊΠκ₯.[yΐQE¨r|=מ=λΟ_΄/­rχ–ςYέΟm6<Ψ]£}§# ΰΰΧY€Ι/ΧΏλξζ΅GαՍΆ₯βΫ;[θVkwY7#t8BGκ+%&“rθ[KDŽnŠτ=:=_‡WΣmt…΄–ήIνξ„₯φq–ϊδqοYŸt«=J}JK›UΎΉ·ƒ}½›I°JάηŸn?:~ΡYΆΆ.§Vμ΄λ»θn₯΅„Ι²y“@ΨΎΌΧGβρhΆ1¬ήŸFΤΓπW>T‰ψχϊVχυm=΄ eF‹΅΅€3·˜p9έιŸoZ%Q¨σ$ :Ψσ:+S^Τl΅ak .-9PΛ–ίοΝw:λxkBΧνl%Π‘–9㍧™₯aε†γεέsοMΞΦΠoΤσ*+ΉΠ4m*_‰GNŒΕ}₯εΚaχ«,°pxό+?ΐΊ}₯ώ§ͺΗyΚ‘XΝ*ώpZ=’S–’» Ϋι°ψQυν6Ω†’–γΜ$aYFz}OγWΌM₯i+€x’+-=-₯'‡dΑΙg69μ3ΗαKΪ«ΪΑΛ₯Ο:’½BΠ’΄π΅†‘€Ϊένλ9`Xν…ΐιܞ•γΝΫJΥ,$΄·{h/aYM΄„“gζ^yτύhUv•ΞJŠυ=Y<5§xΞ=ϋ)ᣎILŒ eΐhμ9y5ΗN,Ό9β­FήζΑ5h]βHεrΈδr;γΖˆΤζθ625-:οL™"Ύ„Γ# ‘A εOCΕ>ΟJΊΌΣo― U6φ{|βX7 υθ_56Ϊώޝ ήκW²–V•@s€;V_€­c½π—Š-湊Φ7ϋ83KχSζcΝJ¨ω9š*½ŽE4«§Ρ_U ΏcIΌ‚Ϋ†wΰcθjz©§A¦ό2Έ†ΫP·ΏFΤU̐}Πv·λΖ©α[k_μUšίΓ7zΝσHD"‘ /’‘ΤτνMTΡ±rλcˆ’ΊοθΦΊ^«§½³ΪΕyΜΦΞI11<―ωχ—VO iή3CώΑŠDΈhγ’S#pΪ;AλžM?j¬šAΘye^4«­ZYγ²Uf‚χ0EΖ˜‹HπΥ΄dΡ¦,ΦqM&yΑdPHό…t^ΤτmBο[n’–Ηa0γ‘$|}ΰzΰώ4₯RΛA¨χ8έΒ:΅f·6 FΜTn™Tδ{Ε½Ά’Ξς{YΐC#Fΰ€Κp•kxώG #ώΎωΥΘΡ¬ΧδίϊͺMσYŠΚΧ2θ―EΠ΄(­<-a¨G 6·{zΞX;a@p:w?η₯b|BΡmτ‹ϋ9lΰ’ΦΛq1·’aβ^Φ’¨œΉAΕ₯s•«Ί6—u¬j1YXͺ΅Δ™*‚Ž'Ÿ ―@Χ[ΓZΏka.… ±Οm<Ν+,7(φλŸz§ΰϋ[K/ŠΙo¦Ξ“Ω©Ε"8pTΔN2:γ8ό){[Ε΄Ί—[Z—‚΅Ν>ΞK©mVH#v†U}£άšζλΤ|?€Β#£­jz•€ΦRFπ,VdΉδ)γΰΦ€tH/­5MFζΖME¬Υ6ˆΔyŽΔυΗ8ώt•M`γΨγhχΕΊ'Β뫍΄kΘξ2ΑΈ•u#†τηΞ£·‹GΠ|¦__iI©^jM!Δ’ŠqΖ;τόύͺ½’jθ\§ Ev>:ΣτΫYτ­ό›{«D”‚I-“ΤϋβŸβM.ΚΫβd:|θ–Fβέ C8ΓΘόriͺ‰ƒ‰ΕΡ]¬΄Τ>&O€„ς¬VwΚ!ΖA8\cρ­ηπύΎ«k©@ώ“Hς!ymn·7ΜW’Άzζ₯ΥH<²Šμ>ιVz”ϊ”—6«}soϋ{6“`•ΉΟ>ά~tί‹E±fπμϊ6¦‚Ής€OΗΏ«Ÿήε].s–Zuέτ7RΪΒdŽΩ<Ɉ l_^j₯zgυm=΄ eF‹΅΅€3·˜p9έιŸoZβ5έJΟP–°αΣΥ ±ΉpηΤζ”fܚ°4’Ή©iΰ=~κΙ.c΅E.τεUvΐZζfŠH&x¦FIв°Αu½*ω!ρv©m¬ψVŽΫXm•ΑΪΑ—Ÿžό1λήΈ™―&ƒΔ²έkΦ‹wp²7Ϊ “°G;GσΕ(M½Η$–Α©hrXhϊ~ χV%ΰ$GεΣκ+"»?Γ§Mα]TΣτΨ¬κIƒ€l[…lOΣυ¬_ ίΪYΙ,wzbŠΡπώ³w κI}§˜ΕΒ©Qζ q‚0x5ΣOρ?ΔsC$O%žΗR§©ΠŒWEQEz¬Φš=χΓ_ Α­j§Σ΄W*ρ!ά€yΘηΪΉˆΊΞ©\i–z+<–mͺΫ$₯L„u8<φ­sχz΅νή™e§άOΎΞΟw‘Υ7· dσλTkRεwoΏβYρ3W±ΦΌF—ZdώtΪ8Λleω€9 §ΰ-r?ψ¦ΟQΈF{tά’…ν`FGΣ9ό+Ÿ’­S\œτΛ;ο ψV=ZFΥfΤo.νή k³²CxžΈΐ¬=Y°Άπ+ιΣOΆπκ±άˆφ1ύΨP gνΣ9>Š•EuwΡ΅ίi7Vž:H.·6§5³Z-ǘn£Œ\V/ˆ΅{ΟxcO·Ÿ}域ηΗ±†ΝΝ‘ΙœΪ” ₯ά]\ΫΒͺ{†$ΘέȐ=«Šw+ˆυ› ψΠj–Σο±YνάΛ±‡ ·qΑγ΅bxΆς κ7Vζ[Λ1dl‘τ<ΦMγ Κηu⠏xŠ kιu‰,―b΄XZΩ­]χ2ƒΡ‡$ΦVƒ©ΪZψKΔVSΛ²ζμCδ¦wνbO `~5ΝQISIZγζΦηI§hΏn4Ζ—Ο¨ Δ{O)° ηκ=kmuM+TπΎ“i&Ή>-Š”–$‰ΨK’>a·ύ}MpPι¦Η]γ[NΤdΡF›q$ρΪΫ,N© =ς9?LΣόG¬Ψ^|FƒTΆŸ}ŠΟnζ]Œ8]»ŽΟ=«Ž’…M rlμνΌGgeρ&ma₯°yŸ,ͺA(ΐŒΰσοZzMΗ…tυY-5y.ξΦH’guƒŒ)8δ“Žp:WœΡIO¨)3CΓχλ¦k–7²)t‚evQΤ€yΕnψ’ίΓ·Rκ–Ÿ»άΟ#LΆhΰξfΙϊw5ΙQTγwq'₯ŽηNΥ4έSΒϊ~›}«Ο€]Ψ³„•cgYQŽpvž£ίΣήΉΝ§Ι}zLχW0EVžα‰27rθ=«ŠJ ;ƒ•Ρό@Τν5myntωΌΨEΌi»i^@δ`Lψ©Zi>*΄ΌΤ%ςm£φ–ΖPΐυ5ΞΡO‘rς‡6·:ο κφٺΏ¬OεXέ©–J3yrƒΑΐσΗεLπ^±ekcͺιzΔΦ–χΚ…nbRLN§ ΰsƒύ=λ”’“¦όΗΜΟΔm€Α₯Ηme«]κ·­&η•·$HΎ[©χ­ [ΝZπŽ§κΪ‹ιΧzsΎΦςZA"1ΙΖ;τό«ˆ’ŽM7cΉψ˜ΠαΖ²ά-Ɵ‹w]½³οŒV•Ζ₯α}S^΅ρ%Φ₯-½Δa$–ΛΘf-"caΖ8ύjΰ5 NοPŽΥ/&σΦ! #hPt§R©θ“cζΤκt―₯·\š&ς%™ΩΠrΑωŒΚ―ήΆmmy<~ ΏΤE"ΪΥ‘”'ϋμz\=Nš½ΕΜnψYtiα5‹»›° ΅Τ@°ΉΞ@δφύk{ΔΊΝ‚x@hρkkWMp%σ䍔D tΉ?Ÿs\%8]έ°R²±ΣψT°²ώΤ³Υex-―νŒr!o,ϊΰsή³u‹m2Βςίϋ/QώΣ‹ο9h ?w­eQO—[ŠϊXοΥ<6©o¬AͺM§€l’΅‚Ϋ±eeΗ ΓŽ£ίπ¬ BξΗΔ>-»»ΎΊ:uΓ–Œ…@\ͺχ8ΟΡIBέFεsΡ/α»πζ—€ΒJPX΄ζύ†SΏ{ΣΆ3λYΏξ΄=2φφοR½Xn£l€xEη/΄£Ž k’—³Ρ«‡6·±ΡψŽΧHςεΌ΄ρκwI—F΄xΛg«nπξ§βKζ΅mόΧUάμHUAκI  Š+’ρGƒu E Ϊ”1›iNԞ„ϊdt‚K;9€·u‘ˆ‘Aq\ 08?‰?ž%³ΡΎ!Η¬lΈώΞσH‘ΌΙl₯A'Ήο<eα‹=KΔ/ j²jΟ§NκžCF°EΖT“χŽJώTΓψcL²Ίψyβ»λ‹t’ξΤΑδΚz¦ζΑΗΦ’ΛL²„Ϊ†€φθoγΤΦ›ψ‚lS§&ŸπχZ­τΝsCΧζ’ΪΛSΈD/ε:’A sά~UgΔڞ‡₯ψ"? ψ~ωυ)%ΊϋUΝΧ”c\Œ~ƒΧ₯mψkΓPXx/MΥ"πΛx‡QΤΩ՜„‚0H8ΙJη>*xvΧCΤ΄ωμ-€³‚ώΨLmdbLόKΟnŸ­jiή“¬ψ7L5 zηBΏΣ™ΒL‘»$±±Ξ9}=λ—ρ­Φ•6₯z-Ννν΄…{‹©™_ΉPyQ@›‘ιΊ-½‚Yx,kšCΫ£Ν¨E!y\ŸΌ@ϋφφΕy…ާ€i~#½ŸϋνϊknHmokG–Fy#ρηB»π™}g¨ι0Τ4Ϋ(ΚΙ6™$R9cέr>RN†ΌχΖ:”NJ5-BΞ3½ΔΕΡHΑΗ©χ=τŠ> ,u[X/<5k}4–ΊLσ1ƒ» ;W#πΫYΣ-lυ½XΈ’Κ Z$nΡsε»ο{Υ§β«Ώ x²=J}zm>ώ%­Νδ”aΐΙ8¬Να©΄ύCLρ(6―9V·Τ2ν TΞ―JΏβ­\πχ…RΦίS·Τό-q0‘f· Κ$χ<•ιΨγρ« .tMORΣt GΓΆ·JeέzςΗ Ξ>\{Φ’Χu-Eπ-Η‡4=JMZ{»•žiΜF4ϋ χ;G―~jO‡ α]RΣ5»4w‡2Yύ†R²²γxΉι@€‹£t‘€¨²Ί€;Mzίƒ<=Ε{{}α :ΓG²BΣέ΄Μί68U?ηΈ Εv^ŠtŸGΧΫQiζc*}‘βς”œη-Φ»]x3RΡ¬t{6Ÿ₯ZŒω §LζY;»ΆOαλψr^,ρδW–χ}¦Dν™c(FΚFΰ§‘ŒηΥ½¨Να›;]Bκ?ꚑ•ZX§›F=7±καΗ­y₯»ΰmuοiΊt‘Œ3K™@ΰμPYΉνΐ4ίE¦ΫψžώίDŒ₯„yI—,X― r}N @bQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE<ίρλoώuO7όzΫΐΏA@Q@Q@OόzάΐASΓ·πη@QEQEQEQEQEUύXΏΡ¦ž]6"IαkyΕmΘΨΘδAΟZ‘EQEQEQEQEQEQEQE\uKέ"ονZmΓΫάm)ζ&2λΦ©žNMPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPσΗ­Ώό ωΤ<ίρλoώuQEQE₯₯¦§.gX’–B¨£yάΗO©¬iϊ^•¬hšž›fŸ}oα³f8λ’™μΐόθ…VݚοψΚΙ₯^Ε€Γ©ΌXΛ!‰%ΘΑaœŒg=R―aΎρŸ τΫΗπΥ«ΪIzθΆffڌ|ΐγ9γυ―=³Φ΄Ψ5ϋ›ιty¬εR©d‘9=ηD*JIέ›«iWΊEΔpκ0%’5•Tr§‘ΰϋU*υο‰šξ•g©ΫAuαΫ[Ιd°’g™”Ζp ΪΉίXθςx_ΔΊŽ΅`/…£]εIo—# $O₯(Φ|œ@ptW―ΫhϊΧ€Ώ·΄Ν2=.ξΦθ[MNYH{ς?Zΰ+XO™W\ŸuηzΗk³Χν Ηλ\vZGό’ύ{ώΎαώkJm«X¨€χ9;Λy,ξηΆ›l.ΡΎΣ‘ppjι>XΫj^-³΅Ύ…f·u“r7C„$~’·τθτ ~_M΅[Ky'·Ί–wΩΖ[λ‘Η½)Tεv°(άσΚ+°ψs₯YκSκR\Ϊ­υΝΌνμΪM‚Vη<ϋqωΣ|^-Ζ5›Γ³θژ~ ηΚ‘?J|ώχ(rιsœ²Σο‘Ί–Φ$vΙζLAbϊσU+Σ<«iν k*4X­¬ΌΓώ“ΞοLϋzΧ―j6ZŒ°΅†—œ¨eΛoχζ”fܚ°4’Ή—EznΊήΠ΅ϋ[ t(eŽxγiζiXyaΈωG·\ϋΦ^£iRόJ:tf+ν/.S½Xye€ΘλƒΗαIUφMlpΤWSΰ]>SΥcΌeH¬f• Έ?­^π­Ύ›…QΎΣa½˜j)n<ΒF”g§Τώ5N’@£sˆ’½ΔΪV’ΊG‰"²ΣΪ]"xvL–q#`ƒžΓ<~hZVž°Τ#Π[½½g, ° 8;Ÿσ§Ϊ«\9μyΥΦψσDΆ΅K --ήΪ ΨVSm!$ΔΩω—ž}?Zι΅dπ֝γ8τ?μ€K†Ž9%201— £°δΉδΣφͺΙ€‡–U½KN»Σ&H―‘0Θθ$PH9SΠρZσ‹/x«Q·Ή°MFΪx’9\9Žψγρ»β³¦Ϋ_ΫΓs‘[έJφQ²Κ°(pΗjέKpQΣSΟlτ««Ν6ϊϊSog·Ξ%€#qΐΐοBiWO’Ύͺ~Ζ“y· οΐ8ΗΠΧ]ΰ+Xο|%β‹yb΅ώΞ ύΤω˜σSjštoΓ+ˆm΅ {τmE\Ιέ`~Όgρ€κYΫΜ|Ί\σΪ+·π­΅―φ*Νoα›½fω€"G‘H…ΡHκzvͺή?Ρ­t½WO{;g΅Šς™­œ’bby_σοTͺ.nQrιs‘’½OVO iή3CώΑŠDΈhγ’S#pΪ;AλžMsšG†­§ψ‹&1f³Ši3Ξ "‚@Οδ)*©«΅ζ;€iWZ΄³ΗdͺΝ-;ξ`0‹Œ1ZZ'„u]jΝnl˜¨έ2©Θφ5Ωx[SΡ΅ ½liΊJXK„Β7ŽBD‘ρχθsƒψΧΰoω4ϊψ_ηKžNύ,>U‘“{m%δφ³€&†Fΐ9”ΰ*†΅QνΧ>τ½¦ŠΛpεξy½₯΄Χ—Q[ΪΖΟ+DQΙ5ΠκžΧ4Ϋ.ξ-γh’”G cυ V烬μ¬ώ*ˆ4ι’βΞ?0Γ"Έqƒ=G\g…rZ~»§]ήΟo(/vΫΖΰᏠk:m΅ύΌ7:½Τ―e,­+€η v¬θ_ZjšΝŒš‹Yͺmˆσ‰λŽp1όι*žο4άu²8Ϊ+½ρn‡ πΊκγGmς; °n%]Hα€=9γσ¦Ϊ&₯ψKΥo4˜ο―%žHΐw*€yluΐcޟ΄M]!rκp•ΤxCΒgZΆΊΤu ΤΣt[L €]Ω'ψTw<ώ’™γH΄v]6ϋDς‘p–žΥ$ίδ8ΗΈΞJέρ+›ƒώ‚>βyε“ΔΑΨ ώτ«‹ΊΈš±Β_-Ί_\-“Ό–«#Ζ“?)#Χ¨(’˜‚Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  ζ[ψσ¨*yΏγΦίώόκ (’Š(’Š*xγΦγώόκ žψυΈ€:‚Š( Š( Š( ½VkMϋα―„ΰΦ΅Σ‰iΪ+ •xξR<δsν^UWυkΫ½2ΛOΈŸ}žο"=ͺ6n9n@ΙηΦ³©+YΪΐtu;RΈΣ,τVy,4ΫUΆI]J™κpyμ?ZoΔΝ^ΗZρ]i“ωΠ hγ-±—ζδ`€k“’œi¨Ϊέθ<GαίΩκ7Οn›’P£¬Θϊg?…u–wήπ¬z΅ώͺΝ¨ή]ΫΌΦgd†ώρ=q^gE)RwΈ†¬Ψ[xτι§ΫxuXξD{ώμ(³ŒvιœΦΆ»βM&κΣΗIΦζΤζΆkAεΈσ0-ΤqλŠσš):1nΧOς¬ρ―cyΰo iφσοΌ³σόψφ0ΩΉ²9#LxίW²Ττο Ec?›%žœN62μpG gκ8RŠ₯M+|;ΝPΠuOC‘kZœΊ\Φ·mp’‹v™\xΒύMqšœ6Π_ύΟΪνQˆŽ,¦ρλ΄ς*΅F­΄ΐτ_]xcΕZjk’Ψ_Γd°΅£YΌAΖp2M;αΈ²oψ½uG’;6λ$ˆ»Še˜Η|{WœUλ=ZφΟN½°ΆŸe₯ξί>=ͺwν9‘‘Ο₯C₯ξς§ΫσΧυ Kπ8πώ‡~ϊœΧ"ζ{%£U Π~΅“ΰ|76©:ψΊib΄“MΨ/‘Χh'¦q\Ν€!Κ€’θD.eŚηΛ,0JηŒϋβ½Θψ^ίΒΧΪAρ!?j•%2ύ†_“n8Η~ž΅ηtQ(σuv:ίiϊ'bΈžο:|-*­Η–ί2ν`­΄FxγΆi<ͺΩ麞©5μήTsΩMgimΜΔ`p=«˜’“‚wΈ)Xέπ²θ=Βkw63`k¨asœΙνϊΦχ‰u›π€ΡβΦ&֚ΰKηΙ(‰@θ r>ζΈJ(p»»cR²±ΣψT°²ώΤ³Υex-―νŒr!o,ϊΰsή²υΫM6xΧIΤΞ£.]Μ Ӟ˜n΅™E>[;ŠϊXι~ jvšΆΌ·:|ήl"ή4έ΄― r0@ͺž ΥΣCρ%όΚΝ d‡ Χk)¦sψV-(.^PΎ·=Ο ψz-ZσJΤ€ΎΊ½ΰ‚!“Κ ύβzγς¬m/U²ƒΑ­c,ΫnŽ₯ΖΝ¬~@ œc·N΅ΛΡSμΧV>c»Φuν6βΫΖI ΞζΤ%·kaε°σΆ[·Έ¦ιΪ¦›ͺx_OΣo΅yτ‹»p’¬lλ*1ΞΣΤ{ϊ{Χ EΙZίΧ`ζfη‰'Σ›Rt»‹«›xUCOpΔ™Ής΅jψY°Όψ©m>ϋžέΜ»p»wž0{WEW"1­βΫΘ/όK¨έZ?™o,Ε‘°FGΠσ]'ˆ.<=β(-―₯Φ$²½ŠΡakf΅wάΚF “\-œ6ςc₯Πu;K_ xŠΚyv\݈|”ΪNύ¬Iδ Ζ’ NΡ~άi./ŸPˆφžS`Ξ1ΤzΧ7E>DΗ~Ί¦•ͺx_I΄“\ŸG–ΕJKDμ%Ι0ێ~Ύ¦³Όs«iڌš(Σn$ž;[e‰ΪU!ΎG'ιšδh©Tw•ΥŽΗΔzΝ…ηΔh5KiχΨ¬φξeΨΓ…ΫΈΰŒρƒΪmβ;;/‰3kΝ-ƒΜωeR FgŸzγ(§μΥ­ε`ζg£i7ΠgΥd΄ΥδΈk»Y"ˆ}ΤF0€γ’N9ΐι\O‡οΧLΧ,odRιΚ죩σŠΟ’… _ΜNG[β‹έK¨jZ~Ίοs<2Ϊ5£ƒΉ›$oιάΥΝ;TΣuO ιϊmφ―>‘wbΞUeF9ΑΪzOzᨣΩιk˜ΩρLΪ|—ΡΗ€ΟusQ…iξ“#w ƒΪ|@Τν5myntωΌΨEΌi»i^@δ`\ΥΤR·mx3WM Δ–wσ+41’²롁¦sψW@λα *-Bξήπκ³O-΅«Ϋ²ˆ‰θI>•ΒΡIΒξχ+Wƒ΅M6-7VΡυ© KυB'D-岜ŒΟ§εSλ—ϊFŸαA‘h·o~ςά}’{ƒxτΗQG³WΈω΄±ΫXήhšΧ…4ύ/WΤMΉΣέΚKδ™Dc’8θΓ½Pρ¦±e¨κ:|:fσaa[Ζξ0\/ρc―₯sP©€ξΪXμ|G¬Ψ^|FƒTΆŸ}ŠΟnζ]Œ8]»ŽΟ=«Ε·_ψ—QΊ΄2ήY‹#`Œ‘ζ²h§(ΨNW;―\x{ΔP[_K¬Ie{’ΒΦΝjοΉ”Œ8&¨x/X²΅°Υ4½NβkH/• άΔ€˜NAΐηαο\₯½š·-ΗͭΟΔm€Α₯Ηme«]κ·­&η•·$HΎ[©χ¦κ:€ή4θζΝδ<‘ν#h$ΰη=}kš’š†Βζ τΏAŒώCαΫyβ‹[Σ'i­£•Ά‰γbIϊεδ=xσJUbŒIV ƒ‚ P‰.νε΄ΊšΪα6O ΄r.s΅Α{ŠŠ#΄’3ΘΜξΔ³3’Ori΄QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE<ίρλoώuO7όzΫΐΏA@Q@Q@OόzάΐASΓ·πη@QEQEQE,h¦ ˜™qΞ’©α[ψσ¨(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’н¬iΪ5Δpjvζ deU,Pτ<θhQ@ΪιŸ όC©XΫέΪ%£EθzLSξΤ-₯’XΆ0Ϊ€ΆqƒΤt5ΙC#C2KΓ£Sξ(έ$𖝧jΦΊx6[ύ9‚%Ζͺ6ύΜ9aŽΓ<γϊW ‘x>ΪoŠΟαλ¦i,`šBάαK($w<zθu]cΓ>"ΤβΦξ{ i,ΰΏΆY“σΫ§λ]Νώ‡¦θΆφ eΰ±in6‘…εr~ρsοΨsΫζ^5Ί¦Τ EΉ½½Ά‚0―qu#+χ**+·Πό+¦_Yκ:GŒ5 6Κ2²M¦IŽXχ\”ƒΣ‘ ΗS4ΏήΟύφύ5·$6·΅£Λ #<ŒψΧ£|Qρ‘cͺΪΑyα«[ι€°g˜©ŒΨP1ΪΌΓΖ:”NJ5-BΞ3½ΔΕΡHΑΗ©χ=νYcždaΠtυο[Ύ*»π§‹!³Τ§Χ¦Σοα²XΡ¬ή@YA  “Š©πϋ\Σ!𾳑ίj’θΧ’$‘_FŒέ1ςΌΗ·ή4£γΟZΏ‚S\:Π5nD[‚vΘ„pΐ}Hόf|.Gμ 7ς5o_Φ΄8Ύάθ–ZεΞ©~Χ‹1’x€]γ;wg 1Мη5‹πΫ[Σt«­VΣZy!±Τ¬žΥζKσίž™ύ(’·όM¦θ61ΐΪΌΪ£»"›G‡ΛŽ[­laiV? ZΎ‰ίUΎΉ1ZδPpN;ύΦόΕ 8z(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€'›ώ=mΰ_Ξ ©ζ[ψσ¨(’Š(’Š(©α[ψσ¨*xγΦγώόθ (’€ (’€ (’€'‡ώ=n?ΰ?Ξ ©α[ψσ¨(’Š(’Š(’Š(’Š(’Š(ώ¬_θΣO.›?‘$π΅Ό‡bΆδldr η­P’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*νξ©{{ggkupς[Ϊ)X#8Δ`υΗδ*•QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE<ίρλoώuO7όzΫΐΏA@Q@Q@OόzάΐASΓ·πη@QEQEQEυΞι^υ‰ν£Ϊ\­Ζ€E mΘvΠΓ―?.~΄£Y5v¬­p8Z+ΣτυπΟ‹ΧWΣ¬44ΣgΆΆ’βζ9Y‹„ώπ>ΉsTΌm₯CΰΗΤυ * ωΖ¨–Λζ0¬«žzŸΖmeͺΤ=­έςΛH°Τ§E·Ϋό’vœŽΥθ^-ΡτUΡΪφq]KεUvM*φ-&Mΰ"ΖY I.F δc9μkͺρζŸ₯ιZΖ‰©ιΆ`iχΦρ^6cŽΉ)žΐŒΞΊ«οi πίMΌ Z½€—‹ffm¨ΐ7Μ3ž?Zn³²q[γΥwV―t‹ˆαΤ`0K$k*© εOCΑφ­+=kMƒ_ΉΎ—A·šΞU*–M) γq“ΠώuίόLΧt«=NΪ ―ΪήK%„l“<Μ¦0s…ΥR©%$’ά!’»ΟXθςx_ΔΊŽ΅`/…£]εIo—# $O₯?_ΆΡυ―oišdz]έ­ΠΆš(œ²:<χδ~΄:©K–ή@pQEj\ŸuηzΗk³Χν Ηλ\½εΌ–wsΫM6hίiΘΘ885ΦiςKυοϊϋ‡ω­Qψucm©xΆΞΦϊšέΦMΘέ‘ϊŠΙI€άΊΡ#›’½N@ΧαΥτΫ]!m%΄·’{{‘)g}œeΎΉ{ΦgÝ*ΟRŸR’ζΥomΰίofl·9ηۏΟ΄Vm­…Λ©ΗΥ»-:ξϊ©ma2GlždΔ6/―5ΡψΌZ-Œk7‡gΡ΅0όΟ•"~=ώ•½ΰ}[OmYQ’ΐ­m` νζτœwzgΫΦ‰Tj<ΙŽΆ<ΊΤΧ΅-FXZΓK‹NT2Ζε·ϋσ]ΞΊήΠ΅ϋ[ t(eŽxγiζiXyaΈωG·\ϋΣs΅΄υ<ʊξt J—βQΣ£1_iyr˜}κΓΛ,G\? Οπ.Ÿi©κ±ή@²€V3JΏ…\֏hƒ”ε¨ίΒΆϊl>}FϋM†φa¨₯Έσ VQžŸSψΥοiZJι$ŠΛOKit‰αΩ0rYč‚{ ρψRφͺφ°rιsΞ¨―EΠ΄(­<-a¨G 6·{zΞX;a@p:w?η₯cψσDΆ΅K --ήΪ ΨVSm!$ΔΩω—ž}?ZD݁Ε₯s’’½OVO iή3CώΑŠDΈhγ’S#pΪ;AλžMqΣ‹/x«Q·Ή°MFΪx’9\9Žψγρ’59ΊŒKN»Σ&H―‘0Θθ$PH9SΠρO³―4ΫλθM½žί8–Η½zΔ gMΆΏ·†ηB·Ί•μ£e•₯`PΰŽΥ—ΰ+Xο|%β‹yb΅ώΞ ύΤω˜σRͺ>Nf‡Κ―c‘M*ιτWΥB―Ψo Άαψϊ£^…ͺiΠiΏ !ΆΤ-οΡ΅s$t€mϊρŸΖͺxVΪΧϋf·πΝή³|#Θ€B‹θ€u=;SU4l\ΊΨβ(»Ηϊ5—ͺιοglφ±^@³5³’LLO+ώ}λ₯Υ“ΓZwŒγΠ°b‘.8δ”ΘΐΖ\6ŽΓzη“OΪ«&rYW΄*λV–xμ•Y …§}ΜqŸζ+’<5m?ΔY4i‹5œSIžpY!]…΅=P»ΦΖ›€₯„±ΨL#xδ$Ix‡8?)T²Πj=Ξ7DπŽ«­Y­Ν‚@Ρ³¦U9Ζ±om€³ΌžΦpΠΘΡΈ 2œεZή‘ΓH―…ώu_Ες4kυω7ώ†j“|Φb²΅ΜΊ+Ρt- +O Xjθ ­ήή³–ŽΨPΟωιXŸ΄[}"ώΞ[8$΅†ςάLmδ$˜_ψ—ŸΓυ€ͺ'.Pqi\εjξ₯έkŒVV*­q&J†`£€Iηθ+Π5ΦπΦ…―ΪΨK‘C,sΗO3JΓΛ ΗΚ=Ίηή©ψ>ΦΛβ²[ι³€φjd1HŽ1ŒŽΈΞ? ^Φρm.ƒεΦΖ₯ΰ­sO³’κ[U’Ζ]‘•_hχζΉΊυι?πˆΗ¨λZž₯i5”‘Ό «™y xΖx5ΰ λMSQΉ±“Qk5A ’1c±=qΞ?%SFΨ8φ8Ϊ+½ρn‡ πΊκγGmς; °n%]Hα€=9γσ©Ό-€[Β!£k’Η­ίΌμ“FcΙQΣεοž―5^ΥZβδw±η”VοŠ~ΒΪ΄bΛMΈΣ[hΫMŸ•ϋνΟ8ΫW_ ιž2Mθ1H— I)•‡–_m―&‡RΦΠO,’» 7ΓσόE“D‘άΩΗ+矘’‚ΐgς§bΎρBκ–6Z:ΨMoΟmp’[oχυΘ‘ΤHO<’»/ZioαΝ~V²BΟΚd]ΕNIζ―³KlJ°Ϋœσυ­?i­¬Ί\β¨―CπΆ‘m„z‹·~σ²MI%GO—Ύx>ΌΧ3β•³—V‰4ύ6γL‘”,ΦΣtY3ό9η*‰»•Μ*–Ϊk˘­νcig•‚’(δšυy<7ec©Ϋι+αyolˆD›Q.Α·¬1Π φ6ΒX|ρ™CMog;§,P‚ϊΰζ₯UζO”n܏Sπ>Ή§XΙw=ΌmC2ˆ₯ яRsΆΡξ"„2‘‘‚s…8Ι>•ήΝ₯ήZ₯¬xCXŠώ ‘Μ`*ΖܝΚΩΟΧƒ\¦©YiΝ9Ώ‘ΤC΄I!]˜Ξq\ώ”γ&Σκ&’d~"DΤήΚ[ˆ.T6ψ[+Οo­fΧOρ"ΒΧMρTφΦ¬,hB/@JŒΥΏΝi~φšRψnΪϊθ“ΎζIY~\“Ή°8~)ϋŠAmlq΄WKダΝβ!oαθ+xΐ„²–GΙΙ܁Ÿjνδπέ•Ž§o€―…ε½²!mD»άz°Η@3Ϊ‡U$›[‚…Ο#Ύ?Αeα_νŸjΙξbv°³ ™' |€ϊ.qψΥ‡―i«¦x‚σOV,ΜcV=JηŒϋγΦόq•Ž^άq ΅΄QΖ½€Ζ­hΥΙ<ώŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  ζ[ψσ¨*yΏγΦίώόκ (’Š(’Š*xγΦγώόκ žψυΈ€:‚Š( Š( Š(  α[ψσ¨*xγΦγώόκ (’Š(’Š(’ŠυY­4{ο†ΎƒZΤN%§h&UβCΉHσ‘Ο΅su;RΈΣ,τVy,4ΫUΆI]J™κpyμ?ZηξυkΫ½2ΛOΈŸ}žο"=ͺ6n9n@ΙηΦ¨Φ0₯ΚξίΔ³βf―c­x.΄Ιόθ΄q–ΨΛσr0@5OΐZδ~ρMž£pŒφιΉ% 9ΪΐŒ¦sψW?EZ¦Ή9:ι–wήπ¬z΅ώͺΝ¨ή]ΫΌΦgd†ώρ=qXz6³amΰWΣ¦ŸmαΥcΉμcϋ° Ξ1Ϋ¦s\}*Šκξ£kΎ$n­ϋΛ??Ϗc ››#’0xτΝrtQJ6·υ₯€κόo«Ωjzw†’±ŸΝ’ΟNH'v8#3υVŽ¨h:§‘Π΅­N].k[ΆΈIE»L›T|]4±ZIˆ¦μΘλ΄Σ8vθD.eŚηΛ,0JηŒϋβ£’ΆΡ,…νό-}€φ©RS/Ψeω6γŒwιλX~ ΎΣτOΕq=ήtψZU[-ΎeΪΑ[hŒρΗlΧ/Egμτjϋ•Ν±Σψ+U³Σu=RkΩΌ¨η²š(ΞΫ™ˆΐΰ{U_ .#ά&±wsc6ΆΊˆ·9Θžί­aQTαΈw~%ΦlΒG‹X›ZΊk/Ÿ$l’% -ΙόϋšΛπ>©aeύ©gͺΚπ[_Ϋ<δBήYυΐη½sRTΥΉGΝ­Ν=vΣM΄ž5u3¨ΖΛ—sE΄η¦­i|@Τν5myntωΌΨEΌi»i^@δ`\ΥωuLW6Ό«¦‡βK;ω•šΙΦR LηπžΟ ψz-ZσJΤ€ΎΊ½ΰ‚!“Κ ύβzγς―>’” €ξ5+F—ͺΩAΰΦ±–m·GRŽγfΦ? P Ξ1Ϋ§ZΣΦuν6βΫΖI ΞζΤ%·kaε°σΆ[·ΈŠ=š½Γ™ΞͺiΊ§…τύ6ϋWŸH»±g *ΖΞ²£ΰν=GΏ§½ax’}9΅(KΈΊΉ·…T4χ I‘» {V($ξW;λ6Ÿ Υ-§ίb³ΫΉ—cnγ‚3ΖjΔρmδώ%Τn­Μ·–bΘΨ##θy¬š)Ζ 6•ΞλΔρΧλY^Εh°΅³Z»ξe£I¬­S΄΅π—ˆ¬§—eΝΨ‡ΙM€οΪĞ@ΐόkš’’¦’΅ΗΝ­Ξ’ NΡ~άi./ŸPˆφžS`Ξ1ΤzΦΪκšV©α}&Mr}[),I°—$|Γn9ϊϊšΰ(‘ΣL9Ž»Η:Ά¨Ι’6βIγ΅ΆX₯R{δr~™§ψY°Όψ©m>ϋžέΜ»p»wž0{WE š@δΩΩΫxŽΞΛβLΪΒ3K`σ>YT‚QΑηή΄τ› θ3κ²Zjς\5έ¬‘D>Ξκ#RqΙ'ΰt―9’“€ŸPRf‡‡οΧLΧ,odRιΚ죩σŠέρEΏ‡n₯Τ5-?]wΉžF™mΡΑάΝ’7τξk’’©ΖξβOKΝͺiΊ§…τύ6ϋWŸH»±g *ΖΞ²£ΰν=GΏ§½sώ)›O’ϊ8τ™ξ`Š0­=ΓdnδΠ{V5”w+£₯ψ©ΪjΪςάισy°‹xΣvΌΘΑ™πR΄|Uiy¨KδΫF3ν-Œ‘€ κk’Ÿ"εεmnuήΥμ?³uXŸΚ±»S,2”fς僀 ηΚ™ΰ½bΚΦΗUυ;‰­-ο• άΔ€˜NAΐηϊ{Χ)E'M;ω™?ˆΫIƒKŽΪΛV»ΥoZMΟ+nH‘}·SοSxy47Σ"oνΛ½VF"I»,‹ž1·γMrTQΙ₯.mnuή<Φlυ}CMK)δ»°,/u"mi›=pyυšλ|U‡SΗoΤυ)-n- R=Ώ’ΟηRtμφ―$‚κ*ή«©]κΧΟy¨Kη\ΈŸh\ΰ`pO²Ω&W9Πιή(Šίβλ²Df’Wάƒο`@ό@Α­K[Ώ ψq5;Ν+R–ϊκκ†<†AoοΧητStΣ“:] S΄΅π‡ˆ¬§›mΥί“δ¦wνbO `~4[κv‰πϊλLi±zχΒeiε6œγG­sTUr!so‡“C}2&ώά»Ρudb$+²ΘΉγqŽ1ΤΡγνrΧSΏΣΏ³η{£gΖΧr&Σ3œΰžMrTRδ\άΓζΗ€j:–j «\kχΆ•MŊFδ–V βΉM*K‹Δνs¨ZIq₯»0)+op§£܎+ Š4•W=KΈπΧ…ήςOΥζΤg–Šo!“±χΙΰτφϊW/ Ψι‰1Υ΅ƒ§2 f—xξ~^•E κΗwγΩ|=¬ή]j–zα{’ŠΧμ’ Δ>ρΐ/‡/4 _½ ΦŽ©ήd]KφY%`™8E ` cΉκ?’—³χynΪάΤΦm΄ϋ ¨©AqΉœΫ΄[X˜n΅Ϊj:–j «\kχΆ•MŊFδ–V βΌήŠnκ V,j3E=όςΫ‰D,δ •χ>;dχ5ι9°„ΣI‡Εš,‘Ι$‘ubΰ<,ƒ–Ακ1Ÿΐ W—Σβ–H‹€t,₯[iΖAκ΅Z$eQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ΝΆπ/ηPTσΗ­Ώό ωΤQEQETπΗ­ΗόωΤeΖ?:Ч‡ώ=n?ΰ?Ξ€ ’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’ŠιΌ3ΰ}oΔvwaih­³Ξž@ŠΝθ=h™’΄ΌC‘κΤZΛU·0Nΰ2eμAE\|5.₯α½OXKΛH£± 42>$~όǏS@4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEO7όzΫΐΏASΝΆπ/ηPPEPEPSΓ·πηPTπΗ­ΗόωΠQEQEQEOόzάΐASΓ·πηPPEPEPSΓ·πηPTπΗ­ΗόωΠQEQEQEιΆ  hί ΄mjC‡QΏšζX€w(Ήluΐο^e]†­¬Ψ\|3Πτ˜§έ¨[]K$±la΅Ilγ¨θhOZhw2θ—Ύς mF/ίΩG0³Ι0{ŒηΫ¦kΠδ𖝧jΦΊx6[ύ9‚%Ζͺ6ύΜ9aŽΓ<γϊW…Γ#C2KΓ£Sξ+Φυ]cΓ>"ΤβΦξΥηφ—:-Ο‹ŒΪ’^bΙ+nύαi•pB’έΘΰŸΖ½MΧt Ψꍋnυ«k‹g†ίM’0Ήι’ά tνΕ`|:±Ρ€π§‰υ-oO[Ρb!xΧqS’[ε :@ϊTž"ΆΡuί‡ΗΔ:V••wiv-¦Š&,Ž?¨ύjΗΓ²xΕ5W’;'λ$‘ζ@KΐwΑΑΗ΅Sρ₯ i>ΠuΥ'ΉΉ7KFͺ?AΗΦ€'³‡Aπ§‚t}SSΡ£ΥυU€`³HUcN8ΰσΚώ~՝ρDΣ,uϋF‰‘Συ[tΉ1'Λ$Œ€OnGλW¬5 ψΑšN“―κriWΊ[8Žo!€Y#c’8θpηΣ½fψΔn§©hφΊ1ιšUΊ[Η,ŠA“Λc0_zξ5΄πŽ“γθ|:|5©vΡG$ζF&p„^Γ‘'9δϊWiαΝ>?ŠΨ7²‘¦­γFK6 P U'ί…Ο½[ρgˆ4ˊφΊΝ₯Ο™¦₯Ε³΄ή[ *mάv‘ž0{U _PΠ΅?‰—ΊƒM6‡q;’UΆ•ΐ`Οc₯uή,΄Σμ-υ+}Sΐ“XΪ e΅Ώ²mδχYLΌŸjΒψ_αΛmJΗYΥτΧΥZΕQmμQŠω²6zγ°γυƒMΧt Ψꍋnυ«k‹g†ίM’0Ήι’ά tνΕrί5ύ>ΛMΦtmbξ{mAPΗw ’au9Ξœ?/zΨρΧ†ΰo.Ί4Π5nD3[%$B8`;sΧΪ‘Ρn4ψOπεζͺšEύ„―$m8Δ3ξby9?6?Ζ²Ό[.‹m’Gea_λzƒΛΊIΨΊBˆ:œŸ|ϊՍ2/kž°·Τ/°΅k\¬²‹s"άzœwΗΈοΦ€3~ Γβ+λ;Κ'ϋ,!-eP»^.€†ιߚιmeΠΌEΰŸ][ψnΣOΉΣ‘ˆ€±Θ\’ΔŒτϋΏ­b|AΦτ­RMLfšM;L€[ύT!Ÿ8ΙΫΧ]„|€θξ˜<\Q#C!Σ¦^ΒΗ¦9Ξοjσ} ςΫOΥ`Ί½±Žώή=Ϋ­€mͺωRO± ώκ7αΨόq«κ~³Σ¦»FO‰$-$„υœ…?β3Ειvž΄ρ₯¬wš³^θ(<Ι.>Μι½€$!LΖp+£ρ¬žρόχσxΝ‰D+mjšd‘#P>T·Φ€(ό/πεΆ₯c¬κΧzkκ­b¨Άφ(Ε|Ω=qΨqϊΥxnπbλ£AmP†δC5°bRD#†·8ύ}«αζΏ§ΩiΊΞ¬]Οcm¨*ξαRL.§9ΒσƒΗεοLρlΊ-Ά‰•†Ή­κ.ι'bι θ6r}σλ@UΫ|5ΠtΝN=oQΧΡίNΣmΌΖTr€ΉΙe#βΈ§ »]ͺN@ΞqνH’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(yΏγΦίώόκ žoψυ·:‚€ (’€ (’€ žψυΈ€:‚§‡ώ=n?ΰ?Ξ€ ’Š(’Š(’Š(xγΦγώόκ žψυΈ€:‚€ (’€ (’€ žψυΈ€:‚§‡ώ=n?ΰ?Ξ€ ’Š(’Š(’Š(’Š(’Š(’Š(BΛXΏ²Σ/΄ϋYφYήνμSΏiΘ䌏ΓŸEQEQEQEQEQEQEQEv RφίLΉΣ‘Έt²Ήei’Γ‘Σ?•R’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Šžoψυ·:‚§›ώ=mΰ_Ξ  Š( Š( §‡ώ=n?ΰ?Ξ ©α[ψσ (’Š(’Š(’ŠžψυΈ€:‚§‡ώ=n?ΰ?Ξ  Š( Š( §‡ώ=n?ΰ?Ξ ©α[ψσ (’Š(’Š(’Š(’½)W@ΠόαέVσC‹PΏΊiT‡’°r͌δ€άΤN|ΆχΝhΗβN•§YΟ₯j4&ήΣS΄[‘IςΨυσΥψό'αίΩιΣxvήh"‰'y™DAΈωGΆ2O½GΆΡ4·ΘθλJπΖ—¨όOmεn4€ν ’)n@›Ά†yωsυ­]=|3βυΥτλ 4Ων­€Έ΄ΉŽVbα?ΌG\Σu’θ˜Q^…ΰΛm*>§¨iP_Ξ5DΆ_0‘…e\τλΤώ5£βέE]ΕPΨiqΪΝ’άAεΞY€69μ2qτd₯Λoλϊ`yνξye€XjS’‹[νώI ;NGjΞ―UΈΤtΝ3α·„§Τ΄΄ΤεΜλRΘUo;˜γ©ΰυ5ƒγΝ?K΅SΣlΐΣο­βΌ6lΗrS=ͺΫ³]9Y4«Ψ΄˜u7€‹d1$Ή,3‘Œη±ͺUμ7ή αΎ›xώ΅{I/]ΜΜΫQ€o˜g<~΅ηΆzΦ›Ώs}.ƒo5œͺU,šR#Η γ'‘όθ…II; 3um*χHΈŽF²F²ͺ’Tτ<j₯^½ρ3]¬υ;h.Ό;ky,–²Lσ2˜ΑΞ;W;ΰ O ψ—Q֬಴kΌ‘Ι-ςδt€ τ₯Ο“šHŠουϋmZπφφ™¦G₯έΪέ i’‰Λ#©ƒΟ~Gλ\k σ λ“αξΌροXνvzύ‘xύk‘ΛH’_―Χά?ΝiM΅kžη'yo%άφΣcΝ…Ϊ7Ϊr2 C]'Γ«mKΕΆv·Π¬Φξ²nFθp„ΤVώ―Γ«ιΆΊBΪKio$φχBRΞϋ8Λ}r8χ₯*œΦžyEvt«=J}JK›UΎΉ·ƒ}½›I°JάηŸn?:o‹Ε’ΨΖ³xv}SΑ\ωR'γίιOŸήε].s–Zuέτ7RΪΒdŽΩ<Ɉ l_^j₯zgυm=΄ eF‹΅΅€3·˜p9έιŸoZαυνFΛQ–°βΣ• ±ΉmώόŒΫ“V’W2θ―MΧ[ΓZΏka.… ±Οm<Ν+,7(φλŸzΛΠ4m*_‰GNŒΕ}₯εΚaχ«,°pxό)*Ί^ΑΙ­ŽŠκ| §Ϊ_κz¬w,©Œ oα`Wυ«ή·Σaπ£κ7Ϊl7³ E-ǘHΒ²ŒτϊŸΖ©ΤHnqW’ψ›JWHρ$VZz[K€OΙƒ’Ξ$lsΨgΒ BŠΣΒΦ„zkw·¬εcΆ§sώzTϋUk‡#½:’Ίίh–ΪV©a%₯»ΫA{ Κm€$˜›?2σΟ§λ]6¬žΣΌg‡ύƒ‰pΡΗ$¦F2ΰ΄vƒΧ<š~ΥY4ƒςΚ·©iΧzdΙτ&Š *z+^qeαΟj6χ6 ¨ΫBοG+•Η ƒ‘ί~5Χ|@ΦtΫkϋxnt+{©^Κ6YZVΞνC›ΊIn :jyνž•uy¦ί_@ͺmμφωΔ°n8θM*ιτWΥB―Ψo ΆαψϊλΌkο„ΌQo5ΜV±ΏΩΑš_ΊŸ3jmSNƒMψeq Ά‘o~¨«™ ϋ μo׌ώ4K;y—Kž{EvώΆ΅ώΕY­ό3w¬ί4„Hς)’ϊ)ONΥ[Ηϊ5—ͺιοglφ±^@³5³’LLO+ώ}κ•EΝΚ.].r4W©κΙα­;ΖqθΨ1H— rJd`c.GaΘ=sΙsHπΥ΄dΡ¦,ΦqM&yΑdPHό…%U5vΌΑΐηt*λV–xμ•Y …§}ΜqŸζ+KDπŽ«­Y­Ν‚@Ρ³¦U9Ζ»/ jz6‘w­7IK c°˜FρΘH’>>π=pβ| #†‘_ όιsΙί₯‡Κ΄2om€³ΌžΦpΠΘΡΈ 2œεPΦ§ŠδhΦ?λςoύ Χc‘hQZxZΓP@mnφυœ°,vΒ€ΰtξΟJ§>T›ΩηTWUρ E·/μ峂KXo-ΔΖήBI…‰yό?ZθυΦπΦ…―ΪΨK‘C,sΗO3JΓΛ ΗΚ=Ίηή—΄ΡYn½Ο?Ρ΄»­cQŠΚΕU$ΙPΜp <ύiκώΦ΄«FΊΉ΅VΆ_½$R+…ϊΰδWCΰϋ[K/ŠΙo¦Ξ“Ω©Ε"8pTΔN2:γ8ό*§Γ¦gΤυλf$Α.Ÿ>τΟ ‚1όΟηS)»έl5q4WO ΨZάx/ΔwsB―sl`ς€=Ssΰβ‹k Vψsw~Π©ΌKρΛά.ΐqϊ֜θžS˜’»»DΡ΄Ώiz­ζ“υδ³ΙεT€O-ŽΈ {ΦOŒβΡΩtΫνΚ„]ΒZ{T“γγ9ύ))έΪΓq²9ͺ+Τt3O–K+H<y6Ÿ0T’ϊδ2I“Υπ:Χƒ\„βΛÞ)ΤmξlRΆ…ή$ŽW+ŽA ‘ί~4•Nm–w¦L‘_Ba‘ΠH r§‘β ΆˆΟq!• Œ3œ(ΙΖIτ―Lψ¬ιΆΧφπάθVχR½”l²΄¬ œ1ΪΈ]R²Σšs₯C¨‡h’B»1œγΉύ(„ά£{I;ψ‹H}S{)n ΈePΫαl―=Ύ΅›]?Δ‹ ]7ΕSΫXB°@±‘½*3ZV±hώ𦙨_ιi©ήκ,δ,’XΡN8Η~GηνBŸΊžχ]YΓQ]W΄«;Ν.οK’³ΤmΰBĝ„υτδWS«'†΄οΗ‘`Ε"\4qΙ)‘ŒΈm‡ υΟ&‡Wk ε<²Ίψό#—…Ά|A¨ 'Ή‰ΪΒΜ&dœς“θΉΗΰ{VΏ§¦β+Ϋؘ’œΖ€υ۞?Jλ~8ΚΗΗ/n8†ΪΪ(γ^ΐc?Φ΄NκδžEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPσΗ­Ώό ωΤ<ίρλoώuQEQE›T|]4±ZIˆ¦μΘλ΄Σ8fŠε@It"2‹bΝsε–%sΖ}ρ^d|/oαkν ψŸ΅J’™~Γ/Ι·cΏOZσΊ(”yΊ;G‚ο΄ύΖ±\Ow>•VγΛo™v°VΪ#o6onΪW9 UOκι‘ψ’Ξώef†2C…λ΅”‚GΣ9ό+Š/(_[žƒ η†ό=­y₯jR_]^ΐπAΙεώρ=qωV6—ͺΩAΰΦ±–m·GRŽγfΦ? P Ξ1Ϋ§Zεθ©φk«1έλ:φ›qmγ$†ηsjΫ΅°ςΨy[-ی\StνSMΥJm'~Φ$ςγI§hΏn4Ζ—Ο¨ Δ{O)° ηκ=k›’Ÿ"cΏ]SJΥΞκ#RqΙ'ΰt'Γχλ¦k–7²)t‚evQΤ€yΕgΡB…―ζ'#­ρEΏ‡n₯Τ5-?]wΉžF™mΡΑάΝ’7τξjζͺiΊ§…τύ6ϋWŸH»±g *ΖΞ²£ΰν=GΏ§½pΤQμτ΅ΗΜlψ¦m>KθγgΊΉ‚(Β΄χ I‘»AνW> jvšΆΌ·:|ήl"ή4έ΄― r0@jŠj)[ΘW:/‡ϊ•¦“β«KΝB_&Ϊ0αŸileOSZφχΪ‡-΅)τ½JmOP»νγΕ»B‘κNξ½pΤR•5'q©XκΌͺiΠΨjΪN³+Αi¨":©o-”’ ž₯O―_ι6BΡΪύžγν3άΜkœcΓς:Š9ξΪXιuNoitsfς ‰Hφ‘΄psŒΎ΅e2ΫήΫΜθ$HδW(ˆœT4U(₯ ›ΉιΧϊΖ‡uβH5·ρ%ΰƒΜώΒ!|‘\pOMΌdΰzυΕ·_ψ—QΊ΄2ήY‹#`Œ‘ζ²h©5Ή\ξΌAqαοAm}.±%•μV‹ [5«ΎζPz0ΰdšηt"ρ&:Ά°tζRlοΟΛ±θ‘BΚΙ‰ΚξηwγΩ|=¬ή]j–zα{’ŠΧμ’ Δ>ρΐζ‡­ψ_NΣu‹ω4λ­=œ$ΎI‘dF9#އ§ε\M•;$―°ω΅ΉΣψΟX±Τ/tλ}/y°ΣΰHG/Ž­ŽΎ•kΔzΝ…ηΔh5KiχΨ¬φξeΨΓ…ΫΈΰŒρƒΪΈκ)ͺi35ΌYy‰u»Gσ –bθψ##θyλΗ6πši0ψ³E’9$‚Τ.£l\…rΨ=F3ψŠςϊ|RΙcŽ…”«m8Θ=Aφ«JΚΔ½FQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE<ίρλoώuO7όzΫΐΏA@Q@Q@OόzάΐASΓ·πη@QEQEQE‚K;9€·u‘ˆ‘Aq\ 08?‰OΓe•ΧΓΟί\[€—v¦&SΥ76>΅άx.ΛΓz—ˆ_@ΥdΤ'ŸNΥ<†`‹Œ©'ο•ό«‰ψ{­iVϊfΉ‘λσIme©Ζ€\"ςI 9ξ?*e–™d ΅ IνΠίΗ©¬+7ρΨ§NMtώπΤ ΣuHΌ2ή!Τuvug! ŒN2Η±ώ%­Νδ”aΐΙ8€OΙ0ρΏΫC4[;\όΌ±[jͺ!άs°\}7ζj/κZ,~ρ‘­κŸΩΗP0ˆδϋ;ΝΒ’O >ΗZo‰5ΓΑΡψoΓw3ί$—?jΉ»’3bͺžGAω{Σι–Vžπ•ν½ΊGut'σδdΪΐ ύ)> ι–Z~“αI,­.΄Θζ™—ψ܁’}λOMΏπ₯θΪξ¨ϊUζ™#˜ε0HΨδŽ:ƒŸNυ‘ρ'^Συ‹ν:ΫEήΪn›j–±HκA“πyΗNΎ”ΫxšOψoΕZdήΆš+¨’k‰ήR’ΗQӌdœχηKΡ`ψŠφ΄ϊ†Š&ω‰<ŠWpE σΙΪNsΑοOψ§¬Ψkž%ŽοKŸΟ·±Ζ[c/Μ3‘†Σ>kΆ^ρ\wšžεΆhž#"γoβΗαΖέ–·§κφχ “B[{wšΞσqάJτξzγžώ™Wΰξ«coβ ΄ˆ'Όšδ΄wΜδ7…t=KLΦοόHΡήBΙgφHRΚˍΰzη₯p·Vαυ‰­‘AœΖƒ°ω°+Υ―‘π†‰β«OΛατ»ήb‚{χ•„‚IΑΌ:ΧΪΈ_ΫθvWQήθιΤηy̏΄xD|δ·^kΆ»Υ<¬ψšΣΕ—z΄φ·QωrΝ§ύ™šDnq”~]¨ΒΎ±‡βτšμKweΜ‘dώ%Ysο΄΄¨|/∡έΛBK¬­₯žΦρe,ο°γ-ΗrAΗNMdxcΕ–?π΅€ρ¦ζΚW•²TΉPPͺ‚ž•Kαζ·§ιξ³s¨\y0άXΟ M±›s³)Q€:΄ΕΡ[ΎΡΧ^ρf›§JΓ4Ή”Ε›žάMρ€ZmΏ‰οντHΚXA'”™rŊπΗ'Τηπ€%Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ΝΆπ/ηPTσΗ­Ώό ωΤQEQETπΗ­ΗόωΤxJ}KKMN\Ξ±E,…QFσΉŽ:žSX><Στ½+XΡ5=6Μ >ϊή+ΓfΜqΧ%3؁ωΦ0ͺΫ³]9Y4«Ψ΄˜u7€‹d1$Ή,3‘Œη±ͺUμ7ή αΎ›xώ΅{I/]ΜΜΫQ€o˜g<~΅ηΆzΦ›Ώs}.ƒo5œͺU,šR#Η γ'‘όθ…II; 3um*χHΈŽF²F²ͺ’Tτ<j₯^½ρ3]¬υ;h.Ό;ky,–²Lσ2˜ΑΞ;W;ΰ O ψ—Q֬಴kΌ‘Ι-ςδt€ τ₯Ο“šHŠουϋmZπφφ™¦G₯έΪέ i’‰Λ#©ƒΟ~Gλ\k σ ˜ΤρZ—Ϊ υ–ΊšDθ‚υέ(pF_yόEfΓώ΅?ήλώ!Ρ-.>#ΫίI­YC:ΟnΒΡσζ»p>§}kXΖθΚu9ήy6₯e6=Π <.Qΐ9z―]nΉ΄ocΎŠζkf»mρΫ.ιΨs]Oφ­e©Γ7…dΡΦk[’[$―@ΩξZ/°^TyMΪx&ΣJo λχϊ΅Ίϋ”Θ»Šœ’~\Ž€œνNΧmτ­WΑi­ιΪziΧ0]}šXγbU†ά矨ύhεε{OzΦ8šΨoκ s¦@Ι}F5– Θ0TτΙν]1θήπ~—{}₯G©^κfCϋΙ „E8γ#σφ¦όO0ό8lΥ–ΨιΘb rBφπ£–ΚμŸhά¬ΌΜM{Βz¦‡d—wιδŽP6 ντ5ƒ]•Οό’kOϋ ŸύΥ•ΰ-sΔΦ–7%…»ny6œͺ ΗγŒPΦ©!Ζv‹rθaQ^ͺώΆΥm58ΒςhώD/-­ΦζωŠτVΟ\Χ7ΰ;-2}3ΔZ΅ ΊK8T]ΕNrά:gfŽG{¬šo±ΗWI₯x+XΥ4Ψ/­cƒμσgay•IΑ π}Ε^ΥeΠ5 M{iim₯κ–²ͺˆl™ΰdΙΖOzΥ“GVψ{α‘&§c`#7Ή6Μ‡§εMDR¨μΊjqΪώ} Ό+¨˜Ύ\ϊc=>΅“ZΪΆ•™¨Ϋΐ—φwθΰ1{Y7¨η'׏ַόK₯Ω[|M‡N‚έΙ-ΠΔ3Œ6̏Η&§”₯;nqTW}₯hϊ|Ώ§Σd΅¬VI@„ηh ­O¦ΕαE¬i–ΊBΪKio$φχBRΞϋ8Λ}r8χ¦ 'U.‡Q]o‚μ4α€λή―oφΈl;}ΕC»œ ‘ψ~uΏyαύOEK›5Σud—k[ΗΉ’DΗήΞ0_Ϊ—.—>Ά±α_ήx—X‹O°3 Hίv$Y½©|Sc¦iΊ’Ϋhϊ‰ΤbHΗ›8MͺdΙΘ_lcžkͺψ|ζΫΐ^9Ί‹‰„ΔpB±`Ÿι\ ―’.b7AΝΎρζρ»nyΖ{β€ΠΥΠ|3ͺkΛ6Ÿ ΄1­#ΈEӚ£ͺΨO₯ίΛgvM7l`ÐQμkΡf“ΓαόΗ«fς‚žo™°υν·Οx>ΛIΤόw΄6ςΙ₯ΊΉXξHέΔd󷎡„j½dφGD¨―v)κΞBŠκ| §Ϊίκz€w,©Œ oα`Wυ«> ΄ΫΓΊύώ­f.ΎΙε2.β§$ž2:p΅\ͺ%—βDi9[]οψmΪkiz§ƒSZΣττΣξ!Ίϋ4±ΖΔ« ΉΟ?QϊΤ–±iπ™¨_i‰©^κ,δ,BƊqΗΏ#σφ₯νtΫ]ƒΩkΎ–½ΞΊxLλVΧZŽ‘zšn‹i5Τ‹»$ ŽηŸΤU/[Έ'Π7G±– ϋ™;¨'¨ŸΔmώψNψK‰η–L`3ψ΄‹ΊΉœ—+±Β_-Ί_\-“Ό–«#Ζ“?)#Χ¨+ψw§Zjλ–wVρΛ1Σ&–Ω›ͺJΈΑ™ξι/sΰΥ6q|“Sαίμλ7Νώ{ΣβΤW‘ό=³Ρol|]¨jΊrά[ΩΔ³Εb₯F\νtΞΝG­ΟαwΑ7…•¦¬YΞ¨ΆΡΟ“ΎώυΘό2Στ‹ΕšέˆΌŽΖέ&EάTηζ8tΞΝp4W­ΟαwΑ7…•¦¬YΞ¨ΆΡΟ“"|:φŸίx|όI]+QΠγΌ–υ‘Šk§•ƒ!`BΠŽzς}+*•$’Wά«ΊΆ•{€\G£‚Y#YUI*z΅n\  ψΗTΆΊΣ£Υ-aw†8¦rΈω ‘܏ƻ_‰šξ•g©ΫAuαΫ[Ιd°’g™”Ζp Ϊ“ͺω’JιεZmΞ₯} ŒF[™ŽΤ@@ά*+˜$ΆΈ– Χd±9GSفΑέ|$Τμ ρ…”ΪL3έΛpZ;Ζr!· CωΥ_λz]Υή§goαϋk[΅ΊpoV,Δ9ΙΖ1Ν?i.~[ΕΡ^”« h~πξ«y‘Ε¨_έ4ͺCΘQX9fΖr@ξkβN•§YΟ₯j4&ήΣS΄[‘IςΨυσFͺnΦοψΗUνKΊΦu¬lUZβ@J†`£€Iηθ*uί ?δy°v_ύΥΌUΪDN\±mu?λΊ}œ—RΪ€F2ν ͺϋGΈ5ΝΧ©ψ{H„A5oSΤ­&²’7b΅s •Ο!OΟΉ‡ϊ½ύ¦©¨άΨΎ’Φj‹ ’1cΆzγ°ΗσͺpΪΖq«£o[eίψ»B„ψYuq£Άyΐ†[}Δ«©0§<~u7…t‹oψCγΤm4HυΛω'dš7“JŽ˜^ωΰϊσK‘ήΕ{eΛsΞ¨­ο}…΅h…Ž™s¦6Π'Ά›ψ_<νΟ8ίX_ ιž2E: R%ΓF’Jdaε—ΐGδzη“B˜:–Ά‡•Q]Ž›α{yώ#I’Hξlβ•Ιηζ( °ό…iΨ―‡ΌRΊ₯…–Žš|Φπ<φΧΘImΏήΧ"…ͺGΡ]§‚m4¦πήΏ«Y ―±ωL‹Έ©Ι'εΘθ ΐ>ΤνvίJΥ|šή§¦sΧΩ₯Ž6%XmΞyϊΦŽ].?iοZΗEz/…t‹oψCγΤm4HυΛω'dš7“JŽ˜^ωΰϊσ\NJ’Κ]^(τν2γL‘”,ΦΣτY3ό9ηœl ’r±ƒW΄ν*λQ·½šΥU’Ξ/:\°/¨υ―P“ΓV6:ΎΎ–φΘ„I΅ν»qκΓ†{V†tρ§x£Ε*±xΪΖβ'©θTύqUΙg©Ω4Ϊ9αL$yIPmσ›λιΤVMΤms4γΜ‰Κ6FAΑ―j²‰^B‰Ύξ‘0„ŸAφ5oζ+†π]Ύ}iβMCX΄Bή1:β§$± Σ848tBfΣoϊΤβ«SΓz4šξ¦,βΈ‚έŠί3axνυ­νV]Wπ€ΧΆ––Ϊ^©k*¨&Ι™@<œgτχ©ώM€κ…†}’[Ο,†MΧM!άp‡†)(λbεQςΆ–Η²Σ'Σ؝7ΖΡl#YΌ9>©‡ΰ|©ροτ₯Λ₯Κφ‹›”ζμ΄Ϋ»θ.¦΅„Ιͺy“0 l_^j₯zo΅m=Ό=¬ͺθ°+ZΨ;y‡ύ'ηw¦qϊΧ―κVZŒ΅†•œ¨eΛoχζ›ŠJχfܚhΪΧ|#Z λΎΤ₯¦+œl+-»8aιžόuZδ+ΠΎΘe„£On·ŸI™έ}ΧθfΌφ Τ)T`£’N%t~πΒkθμΪΦ“§'—y>Η|χUο@>6π•α{HνdΥ%ΈΧπ-ΊΕˆΡXgοzτο\]w?.<^/•$fγ‹.0_ χΎ‡5ΓPEPEPEPEPσΗ­Ώό ωΤ<ίρλoώuQEQEή}χ–~ŸΖ76G$`ριšOκφZžα¨¬gσd³Σ’ ΖΖ]ŽΘδ ύGΚQP©₯oŸβy£j©ΰht-kS—KšΦνQnΣ+‚_©3S†Ϊ ωβ±Ήϋ]ͺ1Οε”ή=vžEV’ˆΓ•Ά˜‹βk― x’ MBmr[ ψl–΄k73¨8ΓI§|7MΰŸ¨ςGfΒέd‘qL³Ψjσнg«^ΩιΧΆΣμ΄½ΫηΗ΅Nύ§#’29τ¨t½ήTϋ~`uΪώ‘‘ι~ΠοίSšβδ\Οqδ΄j €ϊΦ²|†ζΥ'_M,V‚b)»ς:ντΞ+™’΄„9PKδ₯λύ˜Ϋ‰ΒΓ’ΉΰŸ|W[β-oOΌψ“mͺΫάo°Iνέ₯ΨΓvξ8#<`φ2Š΄μKŠnηu₯ψN³ψ‘{ͺΘμΦ3ΌfT9@έ3ϊw­ 'RΡ4y΅'›ΔΧZ”·²F›‘ 'Ξs–?ζΌΦŠ₯6ˆtSκtΪ©gkΰXΟ6Λ«Ώ'ΙM€οΪĞ@ΐόi-΅;4ψ{w¦4ΨΎ{ρ2Η΄ς›@ΞqŽ£ΦΉͺ)sΘΏSΈ·ΌΠ΅Ώ iΆΆ’ϊuޚΞΌ–HŒrqŽύ?*§γύSLԎŽš<­$Άk …Jγ 9œzW'EWV¦“½ΞΛDΏΡ―ΌΪ&³}&žρ]ύ¦)–”7ˌ9ξJ«‘κρ•½ΥΫjό­(ˆΖX2ΰαO<ψβΉz(ζf΅μΞκωό?km{<~!Τ5‘HΆ΄A${ ώϋ ~—αmRΞΗAρ΅Τή\Χvκw°'ŒΗ^υΜΡG6·f­fΒΊ]kS³Ήπ_‡μ!›uέ«LfM€mάω‘ƒΗ₯sTRNΕ8ήΟ°ͺΕX2υ"½.γRπΆ©―Zx’λR–ήβ ’Kcδ3‘1Œ0γώ΅yΤ¬)Γ›©ΩxsΔV‹ρ΅­AώΝk$’Ή%Km ¬`{Š«ΰVΛLΥ5I―fς£žΚh£;Y·3ΐφ^Š˜4Ξ―ΑΊ¦››«hϊ܏₯ϊ‘YΡ yn§# sιωS5δπε†ˆ–zTηRΤZ]οxchΒ.>θ―ήΉz(ζΓδΦχ;―…Ϊ…ˆ:ΖƒͺΞ-­΅˜+;tIvηώϊ?oΔϊχ†υCa©* v‰‘ƒ+‘Ξΐυ¬š|’Ι(A$Žαjξ9Ϊ= ©,θgΤναυΎ˜²ζυ/Μζ=§„ΨFsŒu>΅SΑΪ²h~#³Ώ™Y‘Œαzνe ‘τΞ Ζ’£‘YεϋGu.Η CyαΟE«^iZ”—ΧWΌ0Cδ2yAΏΌO\qωV…©ΪZψGΔ6SΛΆζοΙςSi;Ά±'0?ζ耩+j€S¬ο’Ά‰[κv‰πώλMiqzχΒeiε6œγG­iZ^hšη…τν7WΤM»ΣΩΒKδ™юONύ?*βh‘ΣO―˜*­tιcoΕrθνw:L-αˆ#ΜΩgξΨ=?Jμ<=^3ψ}‡mηŠ-oL¦ΆŽVΪ'‰$λ–?υγΝ)UŠ0e%X‚5q\ͺΖr|ΞηSΰ;θό3γ˜Xco--½ΧΆεYHΒη88ιι]΄^;Ρ”xΑΎVI\Ύ˜|§ύας C·Λΐ^Έλ^C#΄’3ΘΜξΔ³3’Ori΄Δv Φl4ί x²φ.βϊΥ#·]Œw°έ‘0:ŽΈ>Š(ΡΎ7…t=KLΦοόHΡήBΙgφHRΚˍΰzη₯sΎ0³Πaqq‘λ­©Λ<¬Fm,s–λ\έθ:.£ανWΐ0hζ©.•=­Ϋ\G(·i•ΑŒ/ϋΖ²ό'¬XψOΗ‘^[ά=φ™΄feŒ£I)‚žF3œ{W%Ez^£7†lνu ¨όSͺj†TaibžlEτήΗ¨‡΅‰ΰ½fΓMπΧ‹-/gςξ/­R;uΨΗ{ Ω¨λŠγθ Š( ΐΑf›€ωΧoβ{MΎψ₯o«ΪάοΣ’βΩΪmŒ0©·qΪFxΑν\-. »΅γ[λ}KΕz₯ε”že΄Σφ•ά=py―ΔΧ^ρDš„ΪδΆπΩ,-hΦo gPq† “^uEK¦΄³Ψ jqhή&Σ΅ ՚% αzνθqωΦΏŒνΌ9,—š–―=έΝΕΑ“μhι΄1$όηƒŠδh¦αys\UšΣGΎψkα85­AτβZvŠΰBe^$;”Ο9ϋW1ρYΣ΅+2ΟEg’ΓM΅[d•Τ©Ž§žΓυ~οV½»Σ,΄ϋ‰χΩΩξς#Ϊ£fγ–δ ž}jD)r»·ίρ«απ«x#P’ώβuρΏϊ<`6γ1Χ9ητΝ‡Ί•¦“β»KΝB_&Ϊ5pΟ΄Ά2„'©rŠέ;;“(σ&™Χψ[X°ώΝΦ΄}f*ΖρL°ΚQ›Λ”'ž?/zg‚΅‹+[ WJΥ.&΄·ΎT)s’bu9œ?/zδθ§ΜΙtΣΏ™Τx‘τ˜4Έν¬΅kΝZυ€άσ6δ‰Π+u>υ7‡“C}2&ώά»Ρudb%+²HΉγqŽ1ΤΧ#EΪά94΅ΞΏΗΊΥž―¨i‰c<—ea{ΉkLΩλƒΟ¬Χ]βΈό:ž<ϋ~©©Ikqhb‘νό–a1!‡Nΐjς H Ž’­κΪ•ή­|χš„ΎuΛ€φ…ΞΠUsοr]-’z+β˜­ώ Ύ»$Oφi%}Θ>πFGβ jZήxgΓi©ήι:”·χWP<0Aδ2yAΏΌO\`WžΡIMLι΄RΞΧΑώ"±žm—W~O’›Iί΅‰<ψ[jviπφοLi±|χβeiε6œγG­sTRζ+‘~§]αδΠίL‰Ώ·.τ]Y‰d μ’.xΖάcŒu4x]΄ΤοτίμωήθΩ@±΅ά‰΄Μΐη8?η“\sia{5ΝΝs΅O@Χ5Υ5ϋΫΚ¦βΕ#rKŒ+q\„υ‹­το,ZsŒ€Θα 3’sŠεh¦ζοq*I&zu‹τΈξ™γ ½+Γ#IΣ ŽΪSt·2]‘;δΪAU>ΐωtλžbŠέρNΎΎ!ρφ£YΓfξΝX‰!ΨusξΞzΦοŠuν6ϋβ•Ύ―ksΏNK‹giΆ0Β¦έΗiγ΅p΄TΚ NΰmxΦϊίRρ^©ye'™m4Εγ}₯w\k«ρ5Χ†ΥΜ|EΦtνJγL³ΡYδ°ΣmVΩ%u*d#©Αη°ύkŸ»Υ―nτΛ->β}φv{Όˆφ¨ΩΈεΉ'ŸZ£Q \νχό@κτΈ|*ήΤ$ΏΈ|D―ώ ‚8ΗAŒuΞyύ3_αξ₯i€ψσP—ΙΆ\3ν-Œ‘€ κkœ’·NΞδΚ<Ι¦uώΦ,?³u­YŸΚ±ΌS,2”fς僀 ηΛή™ΰ­bΚΦΓU΅K‰­-ο• \Δ€˜NAΐηΛήΉ:)σ2]4οζu$}& .;k-ZσV½i7<ΝΉ"Eτ έO½hZήhZΧ„4ν;WΤ_N»Σφ·’ ŽHοΣςŠ9ƒΩιkΧΔΧ…G†ΪΛp·zwuΫό9χΖ+JγRπΆ©―Zx’λR–ήβ ’Kcδ3‘1Œ0γώ΅yώ‘©έκΪΗy7˜–±a@Ϊƒ ΰsψΥ:|ϊ’©{©6uZWŠΫΗ­ΝyΜεΠrΑωŒΚ΄/ŸΓφΆΧ³ΗβCPi‹kDG°Ÿο±κα\-Ή™Nš½Ρ½αUΡ€{„Φ.ξlfΐ6ΧQΒ6η;€ηΣυ­k6 ΰρ£Ε¬M­έ5ΐ”O$l’% -Ιόϋšΰ¨‘JΚΐι¦ξΩΤxTΣμΏ΅lυi^ kϋcœˆ_Λ>Έχ¬­zΣM³ž%u3¨ΖΛ—sE΄η¦­fQEτ°ωm.cΤ4ΫΰκΧzΌ±&±«Ϋ}šΦΥ3€l9sŽsψζΌΎŸ4²M!’iIVs’eIa@ΖFNz( NψΫ€ήΛ­ r„š<ΕW(κA8ιΧ5ζ5/Ϊgϋ?Ωόι<ŒηΛάvηΧ**(’Š(’Š(’Š(’Šžoψυ·:‚§›ώ=mΰ_Ξ  Š( Š( §‡ώ=n?ΰ?Ξ ©α[ψσ (’Š(’Š(’ŠžψυΈ€:‚§‡ώ=n?ΰ?Ξ  Š( Š( §‡ώ=n?ΰ?Ξ ©α[ψσ (’Š(’Š(’ŠžψυΈ€:‚§‡ώ=n?ΰ?Ξ  Š( Š( ₯Α3σ.1ωΤUβi^αΚφ9Ί*ώ΅£ίh·fΤνΪ Hά † Ž lψCΒgZΆΊΤu ΤΣt[L €]Ω'ψTw<ώ’©;κ„rτTχΛn—Χ dο%ͺΘΒ'q†dΟΚHυΖ* (’Š(­―θx—Wέ[Z·–y“ΆŽΓߟηY7P›{™afGhά‘d9SƒŒƒάPtUιt‹θ΄xuY-ΘΣζΕΫ†Ζr1œφ=ͺQEQEQEQEWAΰνMΧn¦²ΎΥvϋE£:nŽG'•cΫΆσ¬έsI»Ρ5[?PΛΈ…Ά‘ΨŽΔz‚9FŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  ζ[ψσ¨*yΏγΦίώόκ (’Š(’Š*xγΦγώόκ žψυΈ€:‚Š( Š( Š(  α[ψσ¨*xγΦγώόκ (’Š(’Š*xγΦγώόκ žψυΈ€:‚Š( Š( Š(  α[ψσ¨*xγΦγώόκ (’Š(’Š*xγΦγώόκ žψυΈ€:‚Š( Š( Š( ½vηSτ―†>ΈΤτ˜υI32Ε ²EΞζ8'€ΤΧ‘Waβ]fΒχΐ^Σm§ί{eηύ’=Œ6nlŽHΑό   ~(imζ•’Βmμυ;4ΊdŸ,žΈΟlϊΧk’θϊ\ιφ6ήΎŸKU%ΤnΑIrέ_€λΑΖψ§Δuψ1ν_νGL³….b(Λ†R€― g‘δdW[©kήΌρe·ˆ_ΕχλkζE'φjΑ'ΘWΠ/€βΊί†Ϊή›₯]jΆšΣΙ Ž₯dφ―4jXǞψτΟιT|Ae‘ιmk7‡΅ζΥ%Ή•­/ όέiκ²xKNΣ΅k] <-ώœΑγUi~ζ°Ηažqύ+…Π<9imρu4+ΈΕΥ”w2GΆOγPŒW8οΊWXπψ΅8΅»jb²!ΊΣcI7V γ¨πGΒZ֝cρ"ΫUžI ΣRi|Ε₯uRŒβ$ς)ΣΪΛΰ½KSΥΌ?q€ΪιQB%[}JKœ1‘N%°zγ8νŠςŠΉ­MΞ±<-Ί)g‘Ρ±Œ‚ΔƒΝ.ˆΆ-¬Y¬ς&že_=£`™η€₯]Ξ—>™β YhwZŠι—–R;ΖΣέMΈ“Ιμyυ֍’ΠαρΙα‰^]4*νfΟήΗ g’>΅£a†u]ΞΫ³€j6ωY$qž§ρώMEM‘Q*xΊί[‡P³°Φδ΄1¬v6΄yΐ!€ΙόyζO ΩXκvϊJψ^[Ϋ"&ΤK°mΗ« t=«Œρž³etϊU¦ςKm¦Β"Iδ\γӁ[ϊŽ₯ kš‚jΧύν€eSqb‘Ή%€Ζ‡8¬₯ΝdR΅Ω£hvΠόIMιΕͺ\<{_ψ”)#8ο΅-δπ΅ύώ££K§A§GA~χ1u8ηžΈό+Γ:₯ŸŽ-υ žXlWm“#…*@ΞIδV₯*M¨έKέΚμ§Θ$‘WΚδυμ+€Ž‡ΓZu¦­α}rRΥEΤ2Aχ—τΗ¨}₯—ΓΣu½υύΟ—lΗ9D_ΌGβόERπFš/‰-n-[1OΖ~FŸ• Kšέ7 -swBΠ’΄π΅†‘€Ϊένλ9`Xν…ΐιܞ•γΝίHΥ,%³‚KXo!YΌ„“ ηζ^ΦiΪ¦›ͺx_OΣo΅yτ‹»p’¬lλ*1ΞΣΤ{ϊ{Φ‰§ΣŸQ…4«‹«›x+OpΔ™ΉτΥ1ζζΤnΦ=Δ:-₯ΗΔk{ι5›(gYνΨZΎ|ΒWnΤ㏭yηŽδpΥλ῝kx‡ZΣξώ$[κ–χμ{wiv0ΐ]»ŽΟ=« Εwp_ψ“QΊ΄2 ¦gFΑΎ4R‹M_°I§±Ήγ_ω<#^―όΦΉ­ώC?υή?ύVϊ5;Kν ΓΆφ³ošέ’eΪFΖ$q’9ιΪ°τΙR JYNΨTf8Ξ š έϋΙ{›ŸδwΥί_ύk’ŸBΈΦόα•Άž+Ο,n%ٜΏo^•ΚxήϊΫSρMύε”žmΌ¬₯i\ό t<φ«:ξ§iuΰXΑ6λ«O;ΞM€lάΩ‘ƒΗ₯EŸ,mύh;«³Cβέ°Σt-*;Θο¬ba<ρΆεΙΖ7|cωUίΉ·ψ?α8#α.'žY1όL€ΟΰJσΪτΏAŒώCαΫyβ‹[Σ'i­£•Ά‰γbIϊεδ=xΦ1εV%»»˜_τλMZ]rΞκή9f:dΫ3uIW#σ5έΑΰέ%ξ|¦Ξ/2jcœ;ύfωΏΟzΰ<}†|sλ mΰ…₯·ΊΰΆά«)\η=+Ά‹Ηz27ΪJΙ+—Σ”Ό>Aˆvωx Χj„a|=³Ρol|]¨jΊrά[ΩΔ³Εb₯F\νtΞΝG­ΟαwΑ7…•¦¬YΞ¨ΆΡΟ“X<η-֘β=?†zeσψbΡμδΎxΘΜvΖΐ7Ξ:π:αΌ%¦YxΗβ 6βΠXιΣ3Jφρ9;UW;Aχ#υ­ Qπφ«ΰ4 sT—JžΦν#”[΄ΚΰƒΖύγY~Φ,|'γΘ―-ξϋL‰Ϊ32ΖQ€”ΑO#Ξ=¨Ώ—Β֚ݞ­k'ƒδΠώΟΛezόεz+ηΧίήΉ†Z~‘s£ψ’σ[±‘ΨΫ€Θ»Šœόǎ™ΐ«ΊŒή³΅Τ.£ρN©ͺQ…₯Šy±cΣ{ ~zΦ'‚υ› 7Γ^,΄½ŸΛΈΎ΅HνΧcμ7dd £(ώ·?†uίάjV6š6±g:’ΫG>Lρœ …8'Ξqό=yŠνΎθ:f§·¨λθο§iΆήc*9R\δŽG²‘qH&ŠW »]ͺN@ΞqνI@7ΓKmKΗU₯ό)=΄αγ~„cόΐΖΦ_κZž­αϋ&ΧJŠ*ΫκR\ጊp -€3ΧΗlWπηR΄Ρόi¦_κ2ω6³ile'©‘­MΞ±<-Ί)g‘Ρ±Œ‚ΔƒΝS#­zΕηϋWό"χςτ‹­"ϊžΏΤΧ9ΰο ^x’ύα΅hβ·‡s<ŒbBzϋτ?ύjψ₯­Yκώ!Š-)όΝ?O·K8\tpΉΛnqψSŽ’Š)QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE<ίρλoώuO7όzΫΐΏA@Q@Q@OόzάΐASΓ·πη@QEQEQEΐΜ7I#}ؐufφ₯ρMŽ™¦κKm£κ'Q‰#lα6©“'!}±Žy  z(’€ (©μ,ηΏΌŠΦ3$ς¨€“ψΣI·d&ν« ’Ÿq –σΙ ΛΆXΨ£/‘WA€ψ7WΥ4θo­R³Λ…ζ N ƒξ*‘NSvŠ»§«Ιœε«―h7Ί₯ψˆ4 •ςδΣιYT₯i+1ΖJJθ(’Š‘…Q@U:Ξ]BϊKmΎt­΅w6џ­4›vBnΪ²½»ψWSΠμ’ξύ!Ό‚ RPί6 ντ5…U8JVbŒ”•βξQEAAEi^ Υυ=:λTƒμσgay•IΑ π}Ε\)Κ£΄UΙ”γy;έ«―θ7ΊΒ·β e―— ~˜ΟO­eR”\€¬Η)+ ’―hΨάjΆρjΧkdν‰&EάP`ΰγΏ8­?xZMlβxοtϋ΄σ-―"$ƒϊoz‘œυQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ΝΆπ/ηPTσΗ­Ώό ωΤQEQETπΗ­ΗόωΤΫΓͺΗr#ΨΗχa@-œc·Lζ¦Ν¦•ν§˜‹t}tOCa₯Ηk6‹q—:ΉfHΨ η°ΙΗΠS53Lψmα)υ--59s:Ε²EΞζ8κx}MPΧ|I€έZxι ΊάڜΦΝh<·`FΊŽ0=qXΎ"Υμo< α>ή}χ–~ŸΖ76G$`ριšQ„šJWίτ1όy§ιzV±’jzm˜}υΌW†Ν˜γJg°#σͺϋΔB|7ΣoΓV―i%λ’Ω™›j0 σŒηΦΈŸκφZžα¨¬gσd³Σ’ ΖΖ]ŽΘδ ύG££j©ΰht-kS—KšΦνQnΣ+‚_©ͺpn1rΎΜfž΅¦Α―άίK ΫΝg*•K&”„ˆρΘ8Ιθ:οώ&kΊUž§mΧ‡mo%’Β6IžfS9Β€jς­Nh/ηŠΖηνv¨ΔG?–SxυΪyήxšλΓ(‚ΣP›\–Βώ%…­Νδ κ0Á’j§Νko˜Όc£Ιακ:Υ€ΌBw”9%Ύ\Ž€>”ύ~ΫGΦΌύ½¦i‘ιwv·BΪh’rΘκ@ σί‘ϊՏ†βΙΌβυΥHμΨ[¬’"ξ)–`πpqνU5ύCCό½³]NJμ΅#Αi~¨Dθ…ΌΆS‘9τόͺ}rHΣό(4-νοή[΄Opb1―~‚“Ώ?Οπ ,t:~—’τ‹9τ˜€{Ν+ν2NƒUΟ„σϊW9β‹[t κvvQΩύΈH²Γ%rŽ<ϊζ΄ν|E₯Η{‘ΘΧXKm%­₯>[|²#oN~£ŠΐΦuKiό/α«[iw]YyζdΪFΒΞ ςF΅LTΉΏ―1Ά¬iόHΏΉ³ψ‰5Δ–ΧΚ1Λ„S¦Iόλ?Γ6Ώπ–ψ5ΤΫ‹†igΨ6ξΐ'Σ8ύk‘Τ.ό'kλ·ϊŒ>Τk‹·fήΚΖαΖ1ώΟθ~ ΅ΣΊΣl^½π™cΪyM g8ΗQλNπ>©aeύ©gͺΚπ[_Ϋ<δBήYυΐη½9EΈ΅ζ κgλW֚­ΝΈΣ΄Έtμ|₯c°rOζ½O ΩXκvϊJψ^[Ϋ"&ΤK°mΗ« t=«Νυ›m>Βκ£κgP\ng6νΦ¦­všŽ₯ kš‚jΧύν€eSqb‘Ή%€Ζ‡8’iΩ[o˜GΜζL6^ρœφΊ…ΊήXA3DκύJvn;ƒ]£αν+ΓZ†₯wε_Es„β$Α€mν@Oq\Ύ–t‹Ώu9ε·Γ™?yΊGu„$Ιξ~΅\xΓΔpjz~ΆVΞП3OF[μεF œΧρφ’\Χ_ˆ+ώjpλvV“i‘Mu,ωK¦r1· CωΥjϊuΝΞ‘k‰΅Κά°7K),Hc“ŽœΦ?†5τŸΨίL E‘˜/\t8­/ΫθR=Υώ•­=ΜσΜdϋ3ZΊm I?1ΰβ©Ε)άWχMΟ‡ΞmΌ㛨Έ˜A A‡+ωώ•ηρ‘’EEκΔ]ΗΒνBΔcAΥgΦΪ̝Ί$ƒ;s}ΘW9β]Γ·Ψ΅E˜(‘6 €œ0?λ[vχ°xsMρ5†δΡ–aΊ$’μΘΑΛΆΘξ9ώΥ‰oαϋ]Cβ\ϊPO*ΕgrQ0Š ΐώUΉc¬hšχ‰t½EτύCϋe€/“Έ7“ΧsψV4ΪΔz'ΕΛιTΌ s"H“΄‚>Ÿ½:žΝΪNάΌέO3Ο‡:ΊW½Ώuό?oͺΪκP?†d<ˆ^K[ Νσ譟Zΐψg¨ZC­ΩΪK¦Ε5Τ³’—Lδ4co@;τ?Izϊ­½δρψ‚Pi‹kTFPŸο±κs~Τ#ΌAc}2³E œ/\t8όλ9Ԍ*Α«yμϊωiϊ—9S’ΧρύMκϊ}ΝΞ‘k‰½Κά07K!,Hc“Œw­‘¦Ϊκ_ό>·šΎžIΚ΄ΐ9ΰb°Μζu{;}/P-omυΒ‡.Švη'ε#πύkΈ·πώ‰ͺ}—ΔQlΆΡbˆ½ν°')"cδΗ#όšγ5{*ήκΪ=3XϋdRK+[Όb.zΰς}xτΉ<]₯ιΧvz=Š ό8±nY£!¦/χ€Αγό}ͺhςFRφ–Άžz—qΥηir^vŸηΨΐπε…―‰Όikc+³˜c8ڊ Ÿ| ύMu―αϋ}VΧRό3&‘δBςZέo˜―ElϊΧ%’jV>ρ’]ZLךlnΚP«aŽ„‘ŸΗ₯zϊ­½δρψ‚Pi‹kTFPŸο±κ]Νfξο·υχQIΙZφ²ΆΧή'… Σbπ£κΪl7“ E-ǘHΒ²O©όjχ‰΄½%tΕe§Ηm.“<;& K8‘°AΟaž? Γ΅[(<Φ2ΝΆθκQάlΪΗδsŒvιΦ΄u{MΈΆρŠCsΉ΅ mΪΨyl<ΐ¬ vγψ’2§μν¦ή]Ÿλ`qŸ=υίΟΊ‚H£EΡό‘j7ZDW·—U!άͺς}HλY^=Σ¬mfΣot¨ŒΊ…²Ξ!Ξvΰ~b·₯Άξόα¨ukη±Ι˜Η8ˆΘ>ωʐ=r9φΗZ­όϊ}’Ν%•…Ίΐ’° ΉN=…*Ι*vvΪ6ΪχΆΎaJξz_w~Ε›Ÿω%Ÿφ?ϊ-«žΠbΆŸX΅Žϊ+™­Ωώxν—tΗ@=Νt:%φ}α’λ²iοΧΪc™aiC|ΈΑκJO _ι>ρ€•/σOςŒbθBP©aΧiηŽ•›Œe(I΅mτ‹MΕM$ο―υs€ώΓ΅Υl΅(fπΌš@†–Ϊδ“’W osψχsΐ–ZlϊfΏuͺΪ ”΄%UάTηζΰΣ85±€κZ.6’σx–ηR–βΪHΣt2mγΞrΗςΧ9α}NΗBρ½ΤΫ&»·T…v“Ό‚xΘuο[IÞ-Ϋ―nΪm‘œTωd•ϊwωο©sU—AΥΌ+5ε­₯Ύ—©ΫJͺ I²fC'ύ+RM"=Wα†Δš•€ŒΞAΊ“`|Θz~UηUλ:₯Οƒ4 fέwjΣ“iw6G$`ριXΒ΄eΜδ–ή—ΥΞ›\ͺ/―­΄fv―₯Η¦_Α_Ωί«€Εν_zŽqƒοΗλ]ώͺžΣΌeˆt(€K†Ž9%201— £·PsžζΌΊ"T' `Muή#Φl/>"Αͺ[OΎΕgΜ»p»wž0{QF€b›In·ΧMoΈT„›I·³ϋτ0ΚUа!Α΅%t?‘HŠΊ'Š‘°γ΅›EΈƒΛ\³H$lsΨdγθ)ΧŽ™¦|6π”ϊ––šœΉbŠY ’ηsu<>¦§Ϋ^Ξ+―ιp<ͺΙ₯^Ε€Γ©ΌXΛ!‰%ΘΑaœŒg=u^<Στ½+XΡ5=6Μ >ϊή+ΓfΜqΧ%3؁ωΧU}β !>鷏α«W΄’υΡlΜΝ΅ωΖsΗλMΦvN+pΥ₯g­i°kχ7θ6σYΚ₯RΙ₯!"΅ΰ/νν3LK»΅ΊΣE–GRžόΦ‡U)rΫΘ¬ι–3κWπYΪ…3ΜΫP1ΐ'λU«OΒσύ›ΔΊTΩΐK¨Ιϊnύ+G’Πγ›@ΤNΏ½1/Ωμfς';†Cd ί’*Ύ―₯έi3Ε κͺΙ$K2€Ωω[₯zž§jaΣuύ5G7ς^݁ξΦΉO^ΑmρfΈ΅KΛkUHΌ—b‘ΐŒwητ¬‘QΙ—(€`κZ–>Ÿ¨=Υ΄‰x ΖωtϊŠΟ°³žώς+[HΜ“Κv’Oγ]g‹αΣ¦π‰ͺiϊlVu$Α6-ΒΆ'ιϊό2Τ,αΦμ­&Σ"šκYς—Lδ4co@:‡σͺη|‹•^Η<2[Ο$3.ΩcbŒΎ„Vξτ««M2ΚώdQmyΏΚ!'iΑΘν[ή2Υτ뛝BΦ  k•Ή`n–RXΗ'9­Ιο΄ύ?ΐ>šNMBLΜ#ŽG*Š7όΔγ©θΦ“›²ΣpεZžo]{|<הᣡSθnT>>Σllξ΄λ½.#­ύͺ\ˆI'a=@ύ+§ψ‘ιχή$–{zΞΚS ͺK (ηŠN¦Φκ5ξyΖ₯e6}5₯ΘQ4Gkm`Γ?QU«[GšΗNΧΧνπΗ`’ίƒ†\γz:λ΅i^²Τ5+Ώ*ϊ+œ&—$† olzϊ{Š·>]”nyέΩxD‚ϊΣTΤnldΤZΝPChŒG˜μO\sηVό[‘Β|.ΊΈΡΫFΌŽΰC,‰WR8`Nxόι:‰K”9]pTW©iϊ^ˆc,ηb‘ο4―΄Ι8v WΑ·v8™ΗλJ2|ΌΨW²9š+ΠμWΓώ(]RΖΛG[ ­ΰyνBKmώπ>Ήΰ«M-ό9―ίκΦBθYωL‹Έ©Ι'ŒŽ€œνOΪiͺS«vZuέτ7RΪΒdŽΩ<Ɉ l_^kͺΧ`υ_&·§iι§άΓuφic‰Vsž~£υ­κΪ{hʍkkgo0€ΰs»Σ>ή΄GΛtG[gEkλW֚­ΝΈΣ΄Έtμ|₯c°rOζ½O ΩXκvϊJψ^[Ϋ"&ΤK°mΗ« t=©Κ§.θo±δtWDa²πχŒη΅Τ-ΦςΒ š'WκS³qά θ΅i^²Τ5+Ώ*ϊ+œ&—$† olzϊ{Šn’Vσ‚°³žώς+[HΜ“Κv’OγQΟ –σΙ ΛΆXΨ£/‘WcπΛP³‡[²΄›LŠk©gΚ]3Ρ½θzΞ«ψΛWΣnu X4H-V偺YIbCœtζ—;ζε°YZζW…|?yβ]b->ΐΜ7I#}ؐufφ₯ρMŽ™¦κKm£κ'Q‰#lα6©“'!}±Žy«ασ›oxζκ.&CaΑ Łώ₯yόhd‘Qz±V€’½:φiΎ&±πܚ2Μ7D’]™9vΑΗ##ίΪ±-ό?k¨|KŸJ εX¬ξJ!ΖA8ΚΊe…’vM7{|ΞxβWjΚΧωeOag=ύδVΆ‘™'”νD ŸΖ½1ό?oͺΪκP?†d<ˆ^K[ Νσ譟Zΐψg¨ZC­ΩΪK¦Ε5Τ³’—Lδ4co@;τ??ͺςΞ1“Ρϊ{{ΑΈ­QΗ\C%ΌςC2ν–6(ΛθAΑΠi> ΥυM:λTƒμςηay‚“‚Aΰϋгγ_OΉΉΤ-`Ρ ·Ή[†ιd%‰ rqŽυ²4Ϋ]Kαί‡ΦσS·ΣΒI9V˜η< S§BrW½—§_1N¬”bφ»υιδqϊφƒ{‘I _ˆƒJ _.@ύ>••ZZ½Ύ—¨F–·ΆϊŒaC—E;s“ς‘ψ~΅ά[ψDΥ>Λβ(Ά[h±D^φΨ”‘1ςc‘ώMDh:’j[Ου)ΦPŠrΦηšΡ]7‡,-|MγHΰ []œΓΖΤPH\ϋΰgκk­ΫκΆΊ”α™4"’Φθ3|Εz+g֊xYTNQžΏΧ˜O;3Λ(ߐi±xQυ ν6Ι†’–γΜ$aYG§Τώ5{ΔΪ^’ΊGˆβ²ΣγΆ—Iž“%œHΨ η°Ο…5…nχ[_σ£”ΉmύLσͺ±§YΛ¨_Cim·Ξ•ΆζΪ3υΩF‹£ψ7BΤn΄ˆ―o. ͺCΉU 9δϊ0Φ²Ό{§XΪΝ¦ήιQ-u eœCœμ=ΐόΕ)aω#Μέφmy1ͺάΟ•+oψυί κz’]ί€"D JζΑ=Ύ†°«°Ή’QiaC’ΪΉν+iυ‹Xο’ΉšέŸηŽΩwHόtάΤΥ§$‘Υ/Δtζω[—K”(―SώΓ΅Υl΅(fπΌš@†–Ϊδ“’W osψχsΐ–ZlϊfΏuͺΪ ”΄%UάTηζΰΣ85o %%ο~ύ X„βέΆύN>ΊM+ΑšΎ§§C}j}žlμ/2©8$Έ«Ί¬Ί­αY―-m-τ½NΪUQM“2 €y8ΟιZ’iκΏό6$Τ¬lfr Τ›ζCΣςͺ§‡M»ϋΪ]YΫ­ΊŠu•΄ΦΪϊ~Ώ ήθO ߈”Ύ\ϊc=>΅•ZšΎ—™ g~΅}κ9ΖΏ­wϊͺxkNρ”z!Π’‘.8δ”ΘΐΖ\6ŽέAΞ{š•C½yRikώ…:ά©u<λD†ΖγU·‹VΈ{['lI2.βƒωΕiψΓΒΣψrkgΗ{§έ§™myω$Πϋ{ΦˆμLΧ―μ’$Η̊O\gŒώΨω†σΰwο†M–­²#θ τ3\ς‹‹iτ6MI]{ETŒ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Šžoψυ·:‚§›ώ=mΰ_Ξ  Š( Š( §‡ώ=n?ΰ?Ξ ©α[ψσ (’Š(’Š(’ŠžψυΈ€:‚§‡ώ=n?ΰ?Ξ  Š( Š( Š( UšΣGΎψkα85­AτβZvŠΰBe^$;”Ο9ϋW1ρYΣ΅+2ΟEg’ΓM΅[d•Τ©Ž§žΓυ~οV½»Σ,΄ϋ‰χΩΩξς#Ϊ£fγ–δ ž}jc \νχό@λ>&jφ:׈λLŸΞ€[GmŒΏ0#TόGαίΩκ7Οn›’P£¬Θϊg?…sτUͺk““ ™g}α? Η«_θڬڍεέ»ΑmoφvAoοΧ‡£k6ή}:iφήV;‘Ζ?» lγΊg5ΗΡR¨ΰz6»βM&κΣΗIΦζΤζΆkAεΈσ0-ΤqλŠΕρ―cyΰo iφσοΌ³σόψφ0ΩΉ²9#LΧ'E€£kZX―Ζϊ½–§§xj+όΩ,τδ‚q±—c€29?QΕhθΪ†ƒͺx ZΤεζ΅»k„”[΄ΚΰƒΖκkƒ’Ÿ²\ͺ7Ψ :œ6Π_ύΟΪνQˆŽ,¦ρλ΄ς+Όρ5Χ†‘vnΦRςΔλΈcnzξsΦ²υNoitsfς ‰Hφ‘΄psŒΎ΅ΝQMSH…S†ϊΧGρ S΄ΥόSsy§Λη[Ί WΪW8P\έ\ΊάWΖη‚/ν΄ΟΨ^_Iε[ΔΜ]φ–ΗΚGA“ή³5)RmFκXŽθήWe8ΖA$Š­EΦα},u^Υ4Ψ΄έ[GΦ€x-/՝·–Κr2>Ÿ•O_ι……’έ½ϋΛqφ‰ξ F5ΰ`ΠWEO³WΈω΄±θVΎ"γ½Πδk¬%Ά’ΦŸ-ΎY ‘·§?QΕ`k:₯΄ώπΥ­΄»¬Όσ2m#agy#ΪΉΚ(TwώΏ­Aɞ¨]ψO\Φ!Χoυ }¨Χ nΝ½”ΓŒcό+ŸΠόAk¦xάjΡZω6GJ”QΑbŠJšJΐεΤτ [Ώ ψq5;Ν+R–ϊκκ†<†AoοΧ‰‘jv–Ύρ”σmΊ»ς|”ΪNύ¬Iδ ΖΉͺ)ϋ5Υ‡1Ϋκv‰πϊλLi±zχΒeiε6œγG­;ΐϊ₯…—φ₯ž«+Αml`σ‘ ygΧžυΜQMΑ4ΧqsšΝΆŸauΡυ3¨.73›v‹kΣ Φ»MGRΠ5ΝA5k~φΐ2©Έ±Hά’ΐc ÁœW›ΡIΒύF₯csK:Eί‰ŒΊœςΫιa̟Όέ#ΊƒΒδχ?Zι.ΧIf’ΚΒέ`IX\ާžΒ±.u;»>Ζy·ZΪξςShwžq“ψΥ:ͺΈŽhςΕt^Ί!S£Κω›οψ†‰}£ίxDθΊΕμš{Εuφ˜ζXZPί.0@ϊŸ“ΓϊO‡<`%KΖΌΣό£Ί”*XuΪyγ₯rT¬C\Κλ¨έξ―£=#IΤ΄]mEζρ-Ξ₯-Ε΄‘¦θdΪ Ζ3œεδ9sΒϊ₯Ž…β+{©ΆMwn© ν'yρ8λήΉͺ)ΌL›VIZύϊόΔ¨+;½νψtΊΞ§isΰΝΒ·]Ϊ΄ΖdΪFέΝ‘Ι!Bxγ\Ž!΅>Χ!Σ'?Φ€9κ(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€'›ώ=mΰ_Ξ ©ζ[ψσ¨(’Š(’Š(’Š(ΠΎθΦX> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐxͺ"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊŠ(ͺQEQETφ_ρτŸς¨*{/ψϊOΗωPQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE=—ό}'γόͺ žΛώ>“ρώTQ@Q@Q@WMπΖΫRρΖ•i Om+Έxί£a0(™’½^Φ_κZž­αϋ&ΧJŠ*ΫκR\ጊp -€3ΧΗlVOΒ[jV:Ξ­w¦ΎͺΦ*‹obŒWΝ‘³Χ‡­yυκ:πά ΰΕΧF‚Ϊ‘ Θ†k`Δ€ˆG nqϊϋT6°θ>π‘¨κZ,Z΅ώ¬ςK!Q)ΗΚ@8==ωφ 5’½ βF—€Yάψ]τ[A­ε€s’K‚F gΎ .Ρ΄ϋO‹φΪ]΅€qινuj†ϋ€6ΝΓρΙ =’½ XκŸntEΙΣRwfŽ3Œ"v©ΐόk§—Β֚ݞ­k'ƒδΠώΟΛezόεz+ηΧίή€ΨΣζ€ρκΨ¦™\xNγ@Υğ+'ϊ‰ΈΙοτΊΠ!§iΪ•½μφVζX¬γσg`ΐlO^O=J€Š]ΥW–c^Γπγ\ΣΒΪϊ―‡ν‘¬΄ΠnJΣ0CqΖp}zןkšΎŸ«j-¦θ°iKaΦ) ω„‘‚rJΧ»ψ[β›xέ…€3² ˜βKγιžkˆudvGR§HΑ½[Ζ—Ϋ|v³x$hάάZ!*qB>„),4‹ G㦑c{k֏4ΞΡ0ΰ…³ωσL)’»†šUŽ₯λPίΫGLρœ …8'Ξqό=y«> ³³ŽβΧΒšώ€ς4“)XA8yΙιž;Π›Υιt‹θ΄xuY-ΘΣζΕΫ†Ζr1œφ=«²ψ“£iώρ{k§­n’K©tωXό¬挞ΐτφζΊ«θρό3Σ/ŸΓg%σΖ–FcΆ6ΎpqΧƒωΣΕk{XπΤΊ_‡τ½Yο-&ŽόebςρρžGστ5jΦ βν#£@l7ύŸζ˜ΫŒnΖzσΊΓ₯\ψ#ΓΪΞ™€Α¦Ιy,ΚιαX¨δύ3ψΟhλαφ—₯.‡ψ‹]΅ϋljΖ±[*ξp3}Ώ™«>#³ΡuΟΒI€i‹₯][] iΰΛ#‚gς?ZσΚ+Τ@πφΰ κך ύΩ•Hy +η,έr@©¬?ŠF›ay₯_θ°›{=NΝ.„$!=†{`Φ€8ͺ(’€ +§ρ>©αλνIƒEd²ΎΉ™ˆΔ‡=ΞyΙΙΕVπΡπȊψIWW2nWΨ<ΌcΎνύώ”ƒEtΪσx8ιΝύ‚šπΎά6›Ο+ΛΗ|νη5ΜΠE: ¨ °μβψOHρΤz πδ2ΗrΡΗ,ΖV"ψjϊ ‚NsΙτ¬ηS‘ΪΧΗhλGπυœWDΈŒ\X₯Μ‰±‰v1ώ•«m/ƒυGTΠgν΄Έβ­Ύ£%Ι ]N9ΐη:v€λ%²ΏP<Šν|¦ιcFΦυύnΤήA§,kΆς‘έΞHχΗζjLjm4}gΐπι:rιw6χBΪx#rΘΰŒ‚3Σ¨ύiΊ©JΦς‚’½‹K<>Ρhv:,2=φφΉn°pΚΉγОyϊW!γ«]=τ/ λu„Vώ9–Xb$¨1ΈPF~΅1¬₯+[ϊώeμ:6“¦M-…•Ώο§Σ' ’κa’\·Wt9ΰŠηό-αΛψ―.‰wΊ²ŠI”$ΐRW8ο’΅Σm@σ곦ΨάκWΠΩΨΔeΉ˜νD Ηρ⺟‡Ze–₯¬k_[€ΡΓ§Ο,jίΒκWυ«Ÿ 5;(‰©½”·\2¨mπΆWžίZ±€jφv·7sj:T:‰·$…v’q\ώ•wβE…›β©ν¬!X XΠ„^€•­9Ÿ5‰Ά—0μ΄λ»θn₯΅„Ι²y“@ΨΎΌΥU˜ԜW₯ψVΣΫ@ΦTh°+[X;y‡ύ'ή™φυ/XΤl΅»f°βΣ•crΫωλΝ(͢Ձ₯k•5­.λFΤd²ΎU[ˆΐ,ƒFG?R―\ρ=ވ||4Ϋν.€»h£–αδ!°BΠ~kΝ΅ύ=4ο^ΨFΔΕζ5'άρϊQN|Ι]£cr?Αeα_νŸjΙξbv°³ ™' |€ϊ.qψΥΘW |q•Ž^άq ΅΄QΖ½€Ζ­7α–Ÿ€\θώ(ΌΦμEδv6ι2.β§?1ΐ#¦pkBNŠουΉό3ψ&γP²±΄Ρ΅‹9ΥΪ9ςgŒΰd)Α8ΞsαλΝmψkΓPXx/MΥ"πΛx‡QΤΩ՜„‚0H8ΙJςZ+Ίψα›m#XΣMΆ{8΅(O²ΘĘ$' Ή=Ή­uz…Ώ„΄iΎ“ΓρΞ7Β’_4¬$2>ΘΗ δdgϋSΚ4Hln5[x΅k‡΅²vΔ“"ξ(0pqߜVŸŒ<-?‡&Άq”Κ–ρB]Ξͺ0ͺμτ―QΌlt¨,–ΧΒίΪϊkΒ―-μnZFΟRιλΨ}*₯>[ Fη”Υ½KN»Σ&H―‘0Θθ$PH9SΠρW¬ο΄Ϋ jκoμΟΆXΆεŠήεφ”δIΖ1ψΧoρYΣm―ναΉΠ­ξ₯{(ΩeiX8c΅'6šIбετWYΰΫ 8iZΎ΅«Ϋ›ΈlvϋЇv8#πόκΖΉk₯jΎώάΣlNΈ‚δ[Ν 9d`FAϊΦ›žΆ].qtWso ψ?LΎΎ“RΌΤšC‰$*γŒwιωϋUOˆ6:u™Ρ€mόˆ.l–lI9ξ}ρB©wkŽ—9+ΣuΦπΦ…―ΪΨK‘C,sΗO3JΓΛ ΗΚ=ΊηήΉ[?K‡ΖΝgM{₯ ~QfDŽκFB©žN?:Q©~€γcœ’½OϋΧU±Τα›Βθβkk’[$―@ΩκOγίλX~·Σaπ£κ7Ϊl7³ E-ǘHΒ²ŒτϊŸΖ’ͺ­°ω"―κZMޝoe=(Šς/6V+ύ=+Άρ6•€‘βH¬΄τΆ—Hž“%œHΨ η°Ο…gά#j 4χŒoΈΣ― Ύ;μ~GκT~*—³-ŽfϋI»±Σμo.UVΐΝΜ u$vκ*…v_HνŽ‘4ϋh­€νΈŒ“ϊΚΊ©<7ec©Ϋι+αyolˆD›Q.Α·¬1Π φ£ΪΩ&ϊ’οCΘθ»IπΔόB}wv΅ŠWάs†dPHSΐ5bmSš”7Φ²iI¦F6—1³;3†;ϋυκ½§d.SΆ‚[«ˆ ·€šVˆ£%‰ΰ]?‹ό1gα›8-ηΥγ]gS=¬Kς@…s‚έΫ8τϊUŸƒq,Ώ΄γ!|ΧάFΨg]Έ’οZΏΈ˜–’YέΨ“žK²J4QEQEQEQE,UΨ#nPH ŒdzQEQEQE=—ό}'γόͺ žΛώ>“ρώTQ@Q@Q@tu+Mƚeώ£/“i 1‘φ–ΖQ€ΰz‘\εsZš;bώx[tRΟ#£c‰šλ>kϊ}–›¬θΪΕάφ6Ϊ‚‘Žξ$Βκsœ/8<~^υΓΡ@―‹eΡm΄Hμ¬5ΛύoPywI;HQ@³“οŸZ²Ώπηˆ| ₯ιzζͺϊ]ξ”ο΅ό†”JŒΩ ίQ^qEzWΖ -Ρ<%&ΈZšρΞΞ6ηί­k­[ΑšΟ‰lΌ[y«ΝksŽI΄³³3J˜Ϋ†cω•εΪ¦±ͺCeόώlvP‹xΕ]ˆ:ΟΤσT)ΫhΎ2ŽΧβdž#ž'³M!xΖ ,lˆΰώ«¨Να›;]Bκ?ꚑ•ZX§›F=7±καΗ­y₯€ιΌΊw½{u§\¦φΔDάηp^}?Zιό_β 2? -zή΅ΚΜ.e‰”B tΉ?™κzW™Q@ŸΓkKΣ†΅a­Ν%΅¦§hmώЈ_Λ<σΟsY垍§_ΪbλT„တΫ<;=0έx¬:(ΨuΝSΑ7ž6_Λ―ΟpΡ4r%”6R)-ωΨŒι\†…γ΅ψ• %άL –yHΧ’¨ΰ\WEz₯Ύ‘α/ Ε­κ:.­&₯{¨A$Φβέ“ΙW9;‰λ‚‘γ₯s~ Φl4ί x²φ.βϊΥ#·]Œw°έ‘0:ŽΈ>Š+Τ“ZΡuŸθvRx–ηAŸMŒ€ΠΗ Œ&ισ €dρŸΔΧ–Ρ@ΟΕ oJΦAMξ[˜μμΔΣ+cο9 ρΦ΅―i­c¨=±·f Dp*ŽœŠε¨’€ϊψήΞ½§ΖQxa>"hκϊ¬Ά—6F)$ΆςΔΕB²•aΣ°#ΪΌMIVuŠ»¬κ·ΊΦ‘%φ§7Ÿu Ÿh\ΰ`peR›œ“½·©Όχw7O²5£¦ΠΔ“σž+JΖΓή π†—₯kΊ”š]ζ˜Ξ#—ΘiVDc’8θxŸNυητQμ΄Jο@:ψZέ†«u§ZhήciϊmͺΫE$ƒLuluτλI₯ΓαVπF‘%ύΔλβ%τxΐlΖ: csΟιžRŠΈΕEYΠxRΆ|Oms'—i΅VΪ[‘=q]e‹΄Θξ‡šΙ’ˆΑFΐεsΤJm'~Φ$ςγ\Υ*i]ƒ™$’ό=ΈΣ\_> 'ν<¦ΐ3œc¨υ­?·‡τ›ϋ Zχ]1άΖ½―Ω$8%YqΌdwΟJβ(¦αtΥχ.¦η‰-4ˆf΅s¨4²1tϋ3Ε°uκέkͺΡξ<=§ήZίiΎ&Ύ°΅B―-ƒΔξXχRGΚAϊσš(pΊ΅ΑJΞζ—‰o‘ΤυϋϋΫd1Γ<₯ΥHΑΗ©χ=k¨ρΗ‡ΌE΅τΊΔ–W±Z,-lΦϋ™AθÁ’k…’‡ ­Π\ΗUΰνSM‹MΥ΄}jG‚ύP‰Ρ yl§# sιωTϊεώ‘§ψPhZ-ΫίΌ·hžΰΔc^ύqΤQμΥξ>m,vZn³£ίxfΣJΧ­―Ω읚 m6’ΑŽJœτλ Ÿβ›!}d&ώΟB!=c”ύ:~Οhž%Υτ8$‡K»ς#‘·°ςΡ²qβ©jšή«vΧZ„ο<μ0Y½=θJ¦Τ―Π|ΪXΪψ©ΪjΪςάισy°‹xΣvΌΘΑ›ΰ ^ΧDρwWϋ„6ŒΘ£&2GήόυrŠΎEΛΚO6·=#IΤ΄M]Eζρ-Φ₯-Ε¬‘¦θd Ζ3œεδ9KΥl πkXΛ6Ϋ£©Gq³k(ηνΣ­rτTͺh|Ηw¬λΪmΕ·Œ’Ν¨KnΦΓΛaζl·n0=qP|7Φτέ5ο­uΉLvsyR©ΨΜ<Θά0‘\]{5ΛΚΞχ45E―υΫ½@e₯\φγτΕwŽ₯ kš‚jΧύν€eSqb‘Ή%€Ζ‡8―7’›‚v+'‡uΫ}'ΖI©ˆζ6aάvί&Ζdžδd–ιΠί\Ε|ϊ€’£-­©…γς˜τ,άgδWEwΈ)žΦSΓώ,Σu9A1C'ο1Χc¬"MkόEπ»ιwm¬XMΦ‡¨L^ήxάΛm#۟Λ׊γ)ώlžI‹Μ(Άν™ωsΣ8υ«$eQ@Q@Q@Q@Q@Q@Q@OeIψ*‚§²€ό•AEPEPEPRέ"€μͺ0£Κ’©ογιε@QEQEQEQEQEQEQEQEYΣlnu+θlμb2άΜv’γψρCv΅%Μ[\Kλ²Xœ£©μΐΰŠ»{£^Yi”θ’Φϋ’CNΣƒ‘Ϊ•ΠΤQE0 (’€ (’€ (‘AfuŸπώUO{Oψ*‚Š( Š( Š( ―α~ŸiͺψΪΖΣPgΆu΄mΠβ6#υι0ψkΔ£YΡ¬τE²–ΦήI­o¬Ξε2ί\ƒŽEb|’‡¦»/ώ‹jΩΣοό-ᱬκ–œΧWχpΙM)„±δ3t88ηΣΦΉjߝ₯{Ω[ο`e|9°n4ŸήkVBξ;+t•qSœ·Ž™ΐ₯Φfπή΅ΰΩομμ­t^eAoω3Ζp2ςqŸNήυGΒ½ŽŸαΟZήOεΟ{l‘ΐ»ο`[# `uq\h άΫwάC΄‡CπΗƒtORVΏΥF ,…V4CŽ0<ΟΪ™β-K‡Ε^ŸM€¦™«ωg$μάΰ2η07ώρ„4½+]Τ€ο4ΖqΎCJ²#‘ΗCΐϊw¨όCβ=.ηΕ]9€NδD&‘N]UfΗ^ƒλYnn·Χώ&©‡, Φ§_Z±u·Eσ‡ΰξυΗ8JΕ›Β7ζΠ£VN%dC‚Κ΄©Η’Χ‡€½ρ}…·ΕΙ¦ΉΫxrY/5-^{»›‹ƒ'ΩΡΣhbIωΟίjφ7žπƟo>ϋΛ??Ϗc ››#’0xτΝ>E%―ΏŸ`'ψ‰£X[j:EΞ‰Ων΅[XξI³vΙνΘύk»“ΒΊ~ŸͺΫh©α ―μDŸT20}ΝΥΖ:žqύ+Οόg­YίYx\iΣω“XΨGΓc ’.8δsΣΆEu¦­αΏκqλ7>$ΏΣ•‘ Μ‘ΘX°ap3OΚ’J|ͺχλίδO…|7eΕi4;θ…ΥœO2…“ψ€RTœwιT~i–Z–±¬E}n“GŸ<±« ©\Φ«xgΔ6Ί7"ΥΦ;ƒb²Έ+#ο“Λ`W$χ ώA}α_ E­_hϊ¬šεύΌ[Ϋύ“ΙW븞Έ ~USηZkͺ@eό-ΡμuKV[«DΤ.νmχΪΨΌ›Μsž}°=Ή¦ψΰY&Oαk Vpɟ&DοΧΏΣσ¬Ώ.…$—Qλ—·Z|εA΅Ό„·9ά'·λ]'‹5έ9<48΅ΙυϋΖΉ ‰be¨nOζzž”εiΧρ†Ξ)Π­Oχ…tž‡Γsj“―‹¦–+A 1έ‚ωv‚zgΟΛδ₯λύ˜Ϋ‰ΒΓ’ΉΰŸ|WH·βγβ=½τšΥ”3¬φμ->a+·κqΗΦΈo\ΓgρRžκΡ/!K—έ±PόΤ~…[ρ·§ή|IΆΥmξ7Ψ$φξμa€»wž0{V~©&™¬ψΞώiυk§Ο+ΊάˆYψνςυζ΅“Onη58΅nnƏŒ!Σ¦π¦‰ͺiϊl6]I0t‹p­ΙϊS>iVz”ϊ”—6«}soϋ{6“`•ΉΟ>؝j_Β+wα½/I„˜ ±iΝϋ§~φ'§lgΦΉ― &ˆΧqj··6Ž1φKΘ”€Λ(ηž?ZĘΣn kψχ/ψΐZ-„k7‡'Ρ΅0όΟ•"~=ώ•½ΰm[Ook*Ί, ΦΆΞήaIΐ9έιœ~΅ŸβmfΑ<4x΅‰΅»¦Έ‰δ”D tΉ?ŸsY^Υ4ϋ/ν[=ZW‚ΪώΨΑη"ςΟ=θ½€.W*{~fv΅}g«\Ϋ.₯Γ§Xδ,“Α9ής ι>#ΆπΤΊ*άξ1Ε5γJΒMξκ:ε\6³o§iχpT:Ё½œΫ΄[X­vΧ:‡…5]~ίΔwZ”ΦΧ εΙ-—ΜYΠ a‡ΰυ©DsΩZφΧΉ‰€ψbή_ˆΝ’NΜφ‘Lωη‘A`?­½ό9―άκρC‘ElφΆ’Ι,ŒC’;7Cψšζν|P`ρΫkλdy™ŒYδ£ΈϊΰώuΨψbM ₯Χ₯Ρ,υΜ–3I,·ABF8ωŸ>•Q·Bjs%wΩΗ€μ΄ΙτΟ]jΦ‚ι,ΰIQw9Λpιœš]V]Wπ€ΧΆ––Ϊ^©k*¨&Ι™@<œgτχͺ~Υ,μtΫ]MεΝwn© ν'{xΘuο\ΝEμ¬iΚά›; [Zb,Φώ»ΦošB$yˆQ}ާ§j‰τ +θ+£[ΫjKΛi!'Λ%ΐe>υ2κΊV©αm"Mv}k),I°—$|Γn2~Ύ¦‘ρΉ₯\λ^–ΚκIm¬R%™εFή»\Oœ ρš­,fΉΉ―λάΧΤ‘Πm!Υ¦]ݎ™|°*οlHο§8Jf‡¦[i^ΥΑgzνέμϋθΦ>³ιΧ~$Hn75εόsΐ60ή€œžœ~5-ߊlmώ(ΎΉlνq`J©eR _(! ς§ut%Y―'ϊΑπβygΦ5Ρ+—ισ΄€Θδώgσ¨|g₯?‡|A«Ω ‘f"d]ΕNIo—# $}«BήοΓ>U½΅9/ξΰx ƒΘdςƒxžΈΐ¨|-Β>)]Eέ-X@θ2S,ΐ6;ΰΰγΪ’θ½J“ΡΙyλvϊV―ΰΏν­;NM:ζΪδ[ΛlY\Αηκ?ZΦπ6­§·‡΅•]k[go0€ΰξτΞ?ZΖΦο΄m;ΑΓDΡο[P–{q4ώQWƒτ­Sπ6©§ΩjΩκΌΧφΖ9Ώ–}p9οBv8ή}ΜΝR²Τd…¬4¨tε@C,n[Ώ5θwΊE†•’ΪxWϋ_Lh彉ΛΘΩκ@={₯yΦ»i¦YΟι:™ΤbeΛΉ‘ΪsΣ­vš=Η‡tϋΛ[ν7ΔχΦ¨Uε°xΛλ‘ςzt4£»Έκl­Ηώδ¬4»]c_žΪςΫL΅%ž7ΤeςΒ€xRyηό+°ψ‹h4ox[HGzη˜^[ΠΆXͺέώχι\G‰―αΤόA{mŽε.ͺF=OΉλψΧyu€ήk΄€F.ΎΓ5Δ—J‘’ω˜ς τηρ ή;aERQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQETφ_ρτŸς¨*{/ψϊOΗωPQEQEQE=οό}?αόͺ žχώ>ŸπώTQ@Q@Q@tmRσFΤ#ΎΣfς.£ΘWΪ#‘5MΨ»³1Λ1Ι5%*NΚ£ 1όͺ*,―p (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€―ρΝm’6§Α"·u/kϊ•œ–·š‹Ό :ͺ"n„¨ΟΡM6‰qOV‚Š(€PQEQEUΛ]NςΦΒξΚήm–Χ{|δΪύ§#’2? §E15}Š(€0’Š(©`Ήžά8‚i"0ΫαθqΦ’’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ žΛώ>“ρώUOeIψ*‚Š( Š( Š( §½§ό?•ASήΗΣώΚ€ ’Š(’Š(’Š({ίψϊΓωT=οό}?αόͺ (’Š(’Š+KΓΊ-ηˆ5Xτύ5Qd ΚΆŒ“ΟαY΅έό’‡c\εΠ `ΪψWUΉΦ΅ *8^X£Ι2³€‘ χκ1XUοZlk¨kΏπ’ΐΝW@œM· ž2Šγω~FΌΣαΥ₯…ΕΥλήh·ΪΥΜQƒokŸ,±Ο20θ:zχ BŠυ/xzΥόšαЁ¨Γr ’άΆD#†κGδkgIΡΌ:πh6ZΙ£}[€ε\2xτ'œŸ₯x₯έψζΒΒλGπ©₯iπιςj‰,oDμ܎ͺ?Zο$𖝧jΦΊx6[ύ9‚%Ζͺ6ύΜ9aŽΓ<γϊP„QZή,—Dρ.£¦£—ŽήfDcΤ―QŸ|Z>'Υ<=}’ι0hΊL–WΠ 31ΰgΉΟ998 bŠ( Š( Š( ―i]Φ­<Ω"³Η•`0£ώuFΆήK»Έm‘Λ3¬h ΖI8λϋIl/f΅Ήf…Š8 ο^‡(Π΄iϊ$zXi!–ήy„Iζ€t#‘‘ονTm,m΅Š·vΧ±,Π<ΣFθp€ŠΛΪuΆ–2φm₯ptWKΰ« [νCSŽξ•"²–DψXƒϊΤή ³Σ§Σ΅ΛRΧν)i Θ«Έ©ΞOŽ™ΐ«sJε9₯s”’ΊΝNMTπΜΧvΆΆϊn₯m*¨%Ϝ‡ N3ϊ{ΤΎ·ΆώΗY`πεΦ―zΞDŽκD(ΎŠGSψRηφ}/cŽ«Oatštwο’9dΘΑaΫΦΊ/iΆš6±§\AfΡΑq\Ig#”ηζLυΗoΞ·υ5|erΪ»[½Ϋ"Ϋ[jœ›=i:š&–δΊš&–ηšΦ¦££Ic€Ψί΅Ν΄‰v ΖωtϊŠbίZ kν‡NˆΪn'μ›ΞάcΟ^ΌΦοŠαΣεπ΍©XιρY=ΣΚ‹}Φΐδύ)Ή4ΡNM4ŽFŠκ<#c§3VΦ5X ΤV* άT;1ΐΙ‡ηSλ6Ϊf§αA­iΦ"ΒxnΌΡ#–VdŸ¨ύhηΦΑΟ­ŽBŠξΡτŸθš…Ξ“εεΑ”ξUHy8κ@ΐZΜρΟeiuau¦DaΆΎ΅K9ΨOaϊP§wkέ¬sTQZž΄ΆΏρ­σμΆ’L9Ξ3νžΩ<~5mΩ\¦μeΡ^ƒβkK8―aΎπ€Ά(e‚ξέ‹` cΣ²ό £A{k©ίάYI¨EAͺ1c±=qΞ*=’΅ΘφŠΧ9*+·ρN‹πκΏΩ/€]Η8ŠX2vΊ‘ΓzsΗηQΫG₯h>ΣoοtΤΤo5rW*±’œqŽόΟڏhšΠ=’kCŒ’ΆΌF4›‹λi4ΡΗ:)’Οξ€=TΤWWw‡tΏAαΩtq“Rέ΄¬{‚ϊŽ”9Ϋ άνΠσͺ+±Π4;TψŠt›€±Ι*νβXŒγπ«z|zΉ«§ΪιBΦK[y&‚δHYΫo7Χ#ŠD„κ$puutΛ–S ΏdIΌ‚Ϋ†wc8ΗΠΦοƒμττ΅}cTΆϋZY*,p!Y˜γŸΣσ­-JζΚοαΔΣXZ 5mA|ΘUΛ(}ƒ‘žΔcŠNzΩžΆGEwΎ­αKϋ]5›η™’XΩρδ¨ιςŽΉλψΧ5β“fuϋq§0Aη[͟•ϋνΟ8¦§wa©έΨ}Ώ…υK‰μbŠ$/{ žd Ιτ¬CΑΖΓΕΡ[_h“›yJιφnΐσΘύ+ާ.‘.‘EUQEQEQEQEQEQEQEQEδ’{ΡEQEQETφ_ρτŸς¨*{/ψϊOΗωPQEQEQE=οό}?αόͺ žχώ>ŸπώTQ@Q@Q@ήΗΣώΚ ©ογιεPPEPEP]oΒέ^ΗCρ₯φ©?‘j‰ gΨΝ‚PΒ‚zΧ%Ez—Γoιš_†5}3YΈ17ο̘ٳ½HeωAΗ }k;αφΉ¦Cα}gCΎΥ%Ρ/$I"ΎΊcε;yoΌkΟ¨ JΧυ­/‡w:%–Ήsͺ_΅βΜdž)xΐΞέΩŒt'9Ν\°ρn‰†δ’χ i’5œηΚ’RΈ Ӟ{Ž=λΚh »_Φ­'π‡„-,§έ}§} Ξ›ye€V^HΑΞ;f» WXπψ΅8΅»jb²!ΊΣcI7V γ¨π―!’€.kέj—SΪ‰…»ΘLbgήϋ{nnη·β{_ A’ι2hΧ7‹¦nγ•H qΟaƒœŒxόΟ1EQEQEQEQEΠλZ­Ο„τ (eέskηyΙ΄»›#’0xτzŠM^Βjφ:κ6·φzZKζ5΅ŠC(ΪFΧG#ŸΒιwšE„γuKω4ω`Ή3$‚•\Σλ\Ή¬O"΅‰ο£‚Ιc΅Ÿν+’μ)Όzΰς+Χn4~ kΩui,ο"΅XšΩ­™χ2ƒΡ‡&Έͺ(q½†γ{jvή­α_-ϋ:[0]ΠdY€lwΑΑΗ΅WΦ/4› IΌkωfΈΝ7”c`ύλ\εΆ£umcug»mξΆωΙ΄ΫNG$d~R—&·dςjΫ7m|%έΫEqo§ΘπΚ‘Ρƒ/ τ=jž―’j:?•ύ₯jΠyΉΩΈƒ»ΟCξ*ˆšU,Žμ<ŽψήμΨι“š₯Ν}J\ΧΤίρΦ£kͺkkqc/›‚4έ΄― r9«xGVMΔ·«ζΑά€žQ‘]δŽ:πeu₯ίNYqfωΖ=£—Ζ3œg§½T€‘έ‰SξΏΖ½­υυŒz^σiaAΈΑ}ΏΕΚ·΅ CBΦ―ΣTΈΧ.μw*™μ’7$1…aΐΞ+Ο¨§μցμΥ•KitΩ΅2ωn³^Cœ>ισ‚OsΣ5ΨYjšN‰gεψ†ηS‚h(lšg¦Kp1Σ΅yέJ C”/ ί¦—Ω^Μ¬ΡΓ f ΧρZ>'ƒDwΉΎΣ5†Ήži‹ύ™­™ †$Ÿ˜πq\εάuΈάuΉ»kα-vξΪ+‹}>G†UŒy‘λUu=RΡ$·}FΥ .Iqvάg‘χž&•@ #€;4#Ύ7»6:dζzϊ‚ζΎ§‘]κΏρ §ˆ&ΤeŠmΡΌ–žCpέΣ¦sŠΖ‡_Ά²ψƒ.±i¬Μξr ‚Qύs\₯•4‰T;¨nό= Εͺ]išŒ—·7ΌΓδ²yAΏΌO\qωV7†υ[=_·Ή—dΧP*B»IάA£J]OC²Υ4ΞΛρ Ξ§Π4PΩ4.ΟL–ΰc§jΒπ†«gme©ιš”ςΪΑz¨Vβ5$ΔΚr8γό+˜’—³Vdϋ5ft~ m. 6;{=RλS»gάςΆδWΠ)κ}κυ₯ލ¬ψkOΣ΅[χΣ¬ΒIδ™юONύ?*㨣“MΗΙ¦ζ׈η…υΊh°‚ΥZgœulŸ₯u77ώΤυΛ\κ3[Ξ»$–ΛΘf,θ0Ìp?ϊΥη”Pα~ α~§[ λφ£βΦ/˜ΫΫ;ΚΔ•,T }ͺ·ƒυ;M?PΤεΌ—ΛI¬ε‰rΜFΪΉΊ)ς pGQαCN]7Uu‰šήήωP¬κ…Ά2œŒΟ§εVuKΝΧΑri:mσέ\}¬LΜΠ²ωpHΟAΠrsΕqΤRpMάw:4gΣ’oν›­TF"G Μ².xΖάc·SIγΝ^ΣUΊ±[9žθ[[ˆžκDΪfo\ύfΉŠ)ςkpδΦα@Ι4S‘‘α•$Œνt`Κ}ιTYΪόLΠτ― 'N±΄ΎΜ²ήΘ\X€ δ1όEqkTΤ.υ[ιo5 ή{©qΎGκp0?@*­QEQEQEQEQEQEQEQEQEQEQE=—ό}'γόͺ žΛώ>“ρώTQ@Q@Q@O{Oψ*‚§½§ό?•AEPEPEPχΏρτ‡ς¨*{ίψϊΓωTQEQEQEhψ{FΌΧυX΄ν9Qe T;mO?A@ΤV‹ _k7w–Φ(-¬/<‘œ½EePEΩ\|7ΧΰfΤ]- ΄0‡+:’.γΗ€8Ϊ(’€ (’€ (’€ (’€ (’€ («ΪF—u«O$6H¬ρΖe`X (Ɲ Ϋq7mΚ4Uλέ.κΚΒΚςtQΰc !qœŽέEkΨψ+YΎ΅†{xΰhεA"ώωAΑδf“’ZΆ'$΅lζ¨­]s@ΎΡD&ωb\…Ω ~˜ΟO­eSM=PΣOTQE (’€ *νΞ™sm¦Ϊ_ʊ-‹˜0$ν8΄Ή•μ.e{h’Šc (’€ ($ΤΦ•ζ‹{g­&•:(ΌgD –Ζ9όEBΊ3h­k_ίέjχdk»ƒ%ΓH OλQΌ(’Άτ&αyύj\β·bsŠέœ­΅£xgQΦ ylVDΖwΚͺs€z­MͺψCVμεΊΌH(±»)#$Ÿρ½ρ½sτWC¦ψ?VΤl!ΌΆŽΩΨZeRpHθO¨¬½_J½ΡξΎΟ¨ΐΠˍΐ#ΤΑ¦€›²`€›²e*(’™AEPEPEPEPEPEZ³°ΊΌ†ζ[hŒ‘Ϋ'™) «λUh’Š(’н€iwZ΄ςCdŠΟfV€ΒŒgωΠέ·vά£E^½ξ¬¬,―'E^0ΐ’ΘνΤUΈ'p’Š(QEQETφ_ρτŸς¨*{/ψϊOΗωPQEQEQE=οό}?αόͺ žχώ>ŸπώTQ@Q@Q@ήΗΣώΚ ©ογιεPPEPEP]ΟΑOω(Ϊoϋ“θΆΊΏ…ϊ΅–‡γK+ύRo"54›±”`8POR(Ώπ_‡lt­GΔ7VΎ °Τe}:αZήΌ€•9<τΗγ\·Β[jV:Ξ­w¦ΎͺΦ*‹obŒWΝ‘³Χ‡­Rψ­ιϊN·άjT76ΔΫ·;2•Œΰυβ€ψy―ιφZn³£ksΨΫj †;ΈT“ ©ΞpΌΰρω{ΣcΗ^ΌΊθΠ[@Τ!ΉΝl”‘α€νΞ?_jΞψ] Ψoδj―‹eΡm΄Hμ¬5ΛύoPywI;HQ@³“οŸZ‹αΆ·¦ιWZ­¦΄ςCc©Y=«Ν–1ηΎ=3ϊP%nOaX?φu|!£ψφ·†`•.Ϊ(εœΘΓΚ/€/aΠ“œς}+Νυέ7A±–Ν΄-y΅Gy1"›G‡Λ`εΊΧ©x/ Ηρ!u=cW–ΞκΗΚ‘ν|†q9P °ιΨν@Gγ-.=Εž†ήb¨[ή£?«ή'Υ<=}’ι0hΊL–WΠ 31ΰgΉΟ998¬j«x—QΤ£B‘άL]υ ΠgίV‡‰ν|1‹€Ι _\άj.™»ŽU )Η=†r0 γσ(bŠ( Š( Š( Άφq€iώΤ΄ψτύSIΦ$x-o•·–Κr2'·εLΦΣ@²ΡΣL˜κν&χ»1΄atώzΥ}­nWΪΦζγh·Ίί‚ό-Œ%ρ$αίψcCΙφλ\χ‹³`ΎK "%ςνΛ’γψ¦~ηιΧφ«ςxμžπτZeΫ­ν›ΚσFΛεAμΐ­RρΞ™¨^Ũ鏢K•ίsm΅‡—'|`ƒνύiA4υΫQA4υΫS»¬΄ΘlΕ·†΅tζ…^KΘά³ΆG$Όβόΐog6i"[ο>ZΙχ•{ο]Ζ“>cwm{§ψŽφΖέ Ό–O±cέr89ϊδ|E{£_^[‘H¦”Ί©γΤϋž΄ιήαNχ3«―ψs}i³gk.Χ2O”Ή.CF1Π‡‘ό됭/ ί¦—Ω^Μ¬ΡΓ f ΧρW5x΄i5x΄kx·T°ΈΉΏΆƒF‚ήΰ\07+!,pΗ'9­™―l,< αΉo΄υΏ“3γ‘Κ¨ώbqΤτ`ψž ήζϋLΦζy¦/φfΆd*’~cΑΕ7ZΤmn|' YC.λ›_;ΞM€mάΩ‘ƒΗ₯gΛt‘Ÿ-KϊΠ›ΖΊe½ξ>—†ίPΆIΦ"s°·lϊtΆOYΩjPiKα©o,ΘD›P.Ϋ·e†:žΥΗx£TΆΌΆΠE”»δ΄²H€ωHΪγ·#ŸΒ·΅ CBΦ―ΣTΈΧ.μw*™μ’7$1…aΐΞ)5+"Z•‘ΖλφLΦ―l•‹,²+€gŒϋβ¨TχςΗ5μς@$3’‚FάΨν“άΤ²ΫSuΆ¦Χ‚δlΏλα?Wρ?όŒΊ·ύ}Ν‘šB½]7Y²Όu,JΚ:8­ΏΑ \Ι}¨ΨkNχHe[V΅prΝ’7τξj^’ΉI<3omύ޲ΑαΛ­^υœ‰ԈQ}ާπ¨Όi¦ΪhΪƝq›GΔIq%œŒ~SŸ™3ΧΏ:ΊΊ–™©xkK΅“Z›I–ΙYd‰"vδύα·ΏΧΤΦwŽ5; Gϋ%tΩδ™-νV&2) υΟSτ¨Wζ!]Θθυ5|erΪ»[½Ϋ"Ϋ[jœ›=k—πν…·ˆΌ_@΅³•‹΄Q±;T.p υΗλW4»Ν"Βqι:₯όš|°\™’A JιυͺΤmΌ?βΈ’•μ’vO0&θA zuΞ=¨JΙ₯Έ%dάλB·Τνu_Γri^D/-΅ΞζωŠτVΟ\ΦƒνtΖΠ5ΫνRΠ\‹O)‘w9$ρ‘Π€j[Σ‘[[έΝ½}~Ξ€[Ϋ*Ό{Iώσ Vv‰¨ΪΫxW_³ž]·7^O’›Iέ΅‰<ψIΫβώ΅™©xA5‹ °Έ†ημΗ¬6η<ύGλOΆJΠ|1¦ίή驨ήj δ,UcE8γωŸ΅fΑ¨Ϊ―€ξt族|&XφžShΞ1ΤzΦ…₯ލ¬ψkOΣ΅[χΣ¬ΒIδ™юONύ?*m4­γi₯n—1ΌNt‰.α›C RΔX?Ί~κ κ+~΅ k—θΠYΟd‘‘$f$³ίιϊΦ‰$ΡήφήmbRIΨΚέί§ι]&—Ν†«XΒFdϋzΖ»ώΓ Ω΄“ΣΎsνN_ ά%π­ΞoΑΊTz׈­, –}§€ ΗγŒWbϊΎ§k¨Βώ“Jς!ymw7ΜW’Άz湍ϊΗÞ,·Ή΄Ίkϋ(ψiF2C) }3ψβ―^ Ϊήξhυλλφu"ήΩUγΪOχ˜υ”ξή‚ΫΠ‡ΐe¦‘6 χΛ{q;ΰ΄i6 [λνΗηLρX΅[(Φ_Ν€j!ψ+Ÿ*Dό{ύ*‡†—H‘ξVΊΈ²—ΫάΔ nω“Ϊ·τνoΖΩΪύ‘4Φ%±)a Ή ‘Η$~TΙ΅Vπp—ύ1oŒΖ=§„ΨFsŒu>΅[Β²hž ΅Ύ™YαBUΒυΪALζ²Qi;¨΄·:K%ΠΌHΊ••ž’Ά3AΟo:HIm½˜\Φw‚lτιτνrηT΅ϋJZB²*ξ*s“ΐ#¦pjύ΅Χ‡|>šή—¨Λ{ss ΓC'”ԞΈΕcxoQ΅³Ρ5ϋ{™vMu€+΄ΔΗ޽ιYΩΪύggkτ-κrhz§†f»΅΅·Σu+iUD .|δ8ςqŸΣήΉ:(­b¬kΨtλκ+ΥuνΦˆ0^>―g ΒxZΎw’6ΰ}N8ϊΧ”‘Γ©=·^Φ,nΎ!A©Α>ϋž2laΒνάpF{ΥM½<ȚmιΩ™^4‘³U―‡ώu©γωό+^―όΕbψžκίκ6―Ύ fgFΑϊjχ‰5[Ν@·Ά—|Ά°2L»HΪIr9ό(³χƒIϋΏΧC#H­—ύwOύVΗΔ?ω΅?χΧA‹§H°κ²Θp‰*³@ΝhψΚφίQρ5υݜžeΌ¬ >3ςΠσΪͺήπνοάιζΡgΦ< αΑo=¬>WžIžP™ΛφυιYώ:Ί·v‰¦GwνΝ”L&ž6άΉ8ΒƒίώUCZΤmn|' YC.λ›_;ΞM€mάΩ‘ƒΗ₯sΥ‹έω“½ί˜Vί‚m ΎρE…΅άbX$f ‡‘ωI¬JΩπmνΎβk»Ι<»x˜—}€γε# η½i/…ΨΉί•ΨθνίΓ7··ϊDΊ|6 CzσΕΤΰž9λΒ¨xF‚φΧSΏΈ²“P6Š‚+Tb<Ηbz㜠W5¨H³_άΙΚ<¬Κ}A&·ό!ͺΩΫYjzf₯<Ά°^ͺΈI12œŽ8 ΝΕ¨θC‹QΠΠρN‹πκΏΩ/€]Η8ŠX2vΊ‘ΓzsΗηL‚='Dπž{{¦&‘w¨΄Ÿλ$*γŒwιωϋVwˆKƒMŽήΟTΊΤξΩχ<­Ή#Uτ zŸzΏmw’κώ°°Υ/ήΒλOgΪήIHŒrqŽύ?*ZΩ_k“­—kψΦΓO΅›Dm2* ›T”‚I-“ίίι–vί’°‚K3=Ί†q† ‘ψδԟZ<>Φ{„Α [ΊννŸ|VŒϊ‡†΅-rΫΔ7:ŒΆχμ’[/!˜΄‰ŒaΊcΦ€›²~ ›I?S* Φϋβ4ΪP_*Ιf|ͺŠ œΛΈϊΎ§k¨Βώ“Jς!ymw7ΜW’Άz湝3ΔioγvΦ₯‰Ό™&vdŒόΖGεWoN…mow4zυυϋ:‘olͺρν'ϋΜzCRΊ )]ψL΄Τ&ΤβΩon ‡|&Α+}}Έόιž+«eΛαω΄D?sεHŸ₯Pπι=ΒjΧWRΰ{˜`ί r{V爡{%π’ι1κΣk&q/$l’% -Ι뚧~q»σ—όͺX WQ€@ήΛ37˜09Ο¦}«ŒΦον/䉬΄Ψ¬A ±ΉmήόΦ—ƒ5+?ν;MNG†ήϊΨΓη"–Ψ}p+3Z΅Σν'tΝDκ•Λ?Ρm9ιƒΦœb”˜γ€ΞφοJ²Σ!³ήώΥӚy/#rΞِJσ‹σ½œΩ€‰oΌωk'ήUμ½wLϊέ΅ξŸβ;Ϋt*ςY“ρώTQ@Q@Q@O{Oψ*‚§½§ό?•AEPEPEPχΏρτ‡ς¨*{ίψϊΓωTQEQEQEQEQEͺΕX2œr*ξ·«ίkšŒ—Ϊ€ώ}Σ€φ*δΒ€:U(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(έφ£u~–Ιw/˜ΆΡb@Ϊƒ ΰsψΥJ(’Φ¬QE (’€ (’€ (’€ (’€ (’€ (#­QEQETφ_ρτŸς¨*{/ψϊOΗωPQEQEQE=οό}?αόͺ žχώ>ŸπώTQ@Q@Q@ήΗΣώΚ ©ογιεPPEPEPZ>Ρ―5ύV-;NTk™CΫG“ΟΠVuw??δ£iΏξM’Ϊ€*k_ί3Ζ―=³ύΔ™εA=Gӎ+Σ#έκΪΚ4΅&žvι UAί“Χρο@EvήΣ΄|FŽή+E±€f"#‚#E$ ϊœ ύN+Ά—Β֚ݞ­k'ƒδΠώΟΛezόεz+ηΧίή€† ΤM‘ΌιΒakΖΑ67τη8γk ρό}ι?φ ‡ω΅ sSŠ{5ΫώrΑΒMnΌΞ^Šι<-ecύͺjΊœζ+0 άT;1ΐΙ‡ηSjφϊv£α«ΨY‹’ΈK9e`FAϊŠnΊSε·[_ΜJƒq濝ΌŽVŠλ<;ΏφRˁsͺή3ξκDH=ަ£ρ~k€κΪ|πΪΰž$ν$cςœόɞΎΤ,Bsδ·δ7A¨sάΐ{”°Žυ’"ΦG1¬™,;zΥjτ;­[O_Yά6‹@ΧL«oζΆΰόΩλ\Ύ‘cΏβXα‚΅·‘·²+dF€dΰŸσΝM:ν©JjΙ_πJ 8ΖνΫρ(άι—VΪu΅μκ©Ι",°άΨκqΧJ»½~ΚΫΔwW €jqJφqb+1@#_ξ±ΰώ^•‘ΰλ<Ιυ}D iΰ9_ωι'π―ηύ(†#χnRί·Θr‘ο¨Ηn›25M.λKxRυ9%ŒHp,ι‘Ϊ­ψGC—Δž!΄‘•biΙΜ„gj€Xœwΰ*MfBΑόCs2±ΈΉ0ωx9^2?+ΈψKα₯ƒ]Σu±¬ι“4qI/Ψ ›}ΙΜl6μμy­©IΚ:οΤΖ€Te¦Ηβϋ NΤVίBΏžωšIcΩ‡ŒQS[ψ3ZžΩ&[xΥ€]ιΚ«#P€ΦT’ u€1”YnKΟ`[‘ΧΔV¦Oέj?ΪG-­εΌin[χŒNTzrZήM]œuͺΚ2QŽŸ3Ο€GŠFŽE*θJ²‘‚κ)΅»γ₯ βνP(ΐσsϊ Β¨’³±΅9sΕKΉoJΣnυ[΅Ά°…¦•»€z“ΨS΅.λG½6—Θ©0PΔ+>β–ΛVΌ±²Ί΅΄˜ΕΞί4― @Ομ9­ί‰Ώς3ΫΌΚͺΛ–ύLάζͺ¨½C”’Š* Β₯΄Άšξζ;{hΪI€;U©5u_ δk‰Ώ‰aƒθvš¨f‘Yϋ89.…]GΒ:½…œ·2ΓΗ2ˆ₯W1Όsυήx2ΛμΧ’o·Γsφϋ ήX‘²ΙΣ‡χητ5ΑΥN)$ѝ’“q“½ΎA[Ί_…u=NΖ;»U€Γ&vξ™TπHθO΅aWCΰ‰΄‹m[νΫ•XΖaΚ]ωκΐzu₯›³.³”`ά7τΉ­ιz-βΫ_’€Ε€¬‚Hντ5Ÿ[ώ7³Ό΅ΧKλ‘vnPOκ0Lέ:V)+;”œ €ΨQE&…ύG½Φn|ΖEάμHUQκI©΅­PΡ)/#SΌ$±Έtcι‘[^]ήΧUdXL³ΫΔ€Ά9>œš±uh,Ό¬Y‹¨γ·Ύd±œ©%Fqωγσ­T)ΘλΙT·KΫςΦ3ˆ’ŠthH¨€³±ܚΘλ.YιWWvw±"‹kP ŽΜdτΤϋUτSLΣ£±°πΐΦ#΄ΉR$™<’ΒY˜qΉ{~Υηϊ”Ϊmόφw ‘b­ƒ‘υ€αΚsΡͺίπτ+QE™Π―‘ψwSΦΓΆŸn^4κμB}2zšΘΗΐš΅εLj4M=ζ"ΞݟdKΐ$«ŸSΝ\nΜΖΌ§9C‘ΘKE+Ζ㠌TύE6¬κς»―όΝV©f©έ\(’ŠC4τMχZ3 ς±»|:η~†§ΦΌ3©hΦ‘άίGΓ#μVIdΰžίCYϊX΄mFάj,λgΌy₯;}«¬ρδbσO³Τ΄Λ¨ζΡPύž(Q y Ž„€γ­h’œ[κsN€γUFϊ?/ΧΉΔΡE™QZΎ޳[YηllwHވ9?ηޚWvDΚJ)Ιμˆ.΄««]6ΦϊtT‚δ‘Xn`:œuΗΏΈͺ5ίψŠΖΧΔΧw£κ±JφPν†ΘDQDkύΦ'ςτͺqεzΠ«ν#ύ‚Š(¨6 θ­ό­Οl“-ͺ©uή‘<ͺΓΤ)?Ξ°μ€H― ’UέH¬ΛκδW‘j:φ±γ(5]6ξl₯’9#fŒ2»sœŒ1υοZB*G5z›I4·ΥώGœΛΕ#G*²H„«+ GcM­―\CwβJklŒΈt$ όH&±j³±Ό$ε'Τ(’ŠEz7†5M^Ϋν±"Α»h’Wϊ υ¬ύSNΊ―ΦώΛΞ9 χvK^M7G„XIXQWΟRΗϊύk_Ζ—0άkϊe”r‹°Ε¬³}ΑωΏΟkNXΈέΚ€ΥNY[―Λ·ήS·πf΅=²LΆρ«H»'•VF‘I¬νΪΑ΅˜νυι糴–g7:>ΈΨψŠΤΙγ;­GϋB(ε΅Ό·-Λ~ρ ʏNOλ\ώ”/‹΅@£ΝΟθ)Ξ - ‘ZSiKͺΏ¦ίζXρΧ†SΓWφ«mx/,― [›yΆν%LσΦΉͺυίh β-ΓZ“κΊn’LŽ1m8›nNδλsό«Θ«#¬(’ŠWmΜXχ9€’Š(’Š(’Š*{/ψϊOΗωT=—ό}'γό¨ (’€ (’€ (’€ žχώ>ŸπώUO{Oψ*‚Š( Š( Š(  ογιεPTχΏρτ‡ς¨(’Š(’Š(―α~­e‘ψΚT›Θ΄d &ΖleԊε( QΡ΅ψFMCTΣυ«cR–"Š΄xPnώφαύ Δψ{­iVϊfΉ‘λσIme©Ζ€\"ςI 9ξ?*βh Δڞ‡₯ψ"? ψ~ωυ)%ΊϋUΝΧ”c\Œ~ƒΧ₯X°Ώπη‰|€ιξ¨ϊMώ–Ξ#˜ΐdY#c’8ο€>λΞ( ›Ζ—mFΞ BΒΪ%I.X0k‡ξΔŸο]©ρΡ>"Οs Λίxjξ·Έ‰•φm*Œ ϋr3λ^IEvš―₯ψOβ*_i· {£#²‡Teo-Ԍa€9\ώ8χ­}Fo ΩΪκQψ§TΥ ¨ΒΕ<؊1齏P?=kΝ(  ―j±hž)Σu…f†ήPΞά`γσ­ΪψfY/u=Δ]έ\ά~ΘΦn›C1'η8fΈΪ(»πͺψrM_^ψ{\F"i]’UΟیqާx¦|Tρ†Ή{₯Η§\I{φ+a —²&Ɲ½pp}\=ΣιΆΎ_O}}sˆρ §c1Ϋ<δδcŸ1EW[π›ώJ‹][@jδ©πΛ$¬ΘρΘ½ ~4ΡψχBΤτrξγQ΄x!»Ή™ΰf ﳑƒθΓσ­_„z₯yβ7TΆ΄y,-vΛ0#vύsά~uΕέ^]]νϋUΜΣνΞί1Λcιš[kϋΛT)kuq ’±ΘTλΑ  ώ0‘·[―ιτcTςκΝΰ˜tρ'ϊZή™Œ{OάΨFsŒu¬'v‘Ωέ‹;–'$ŸSIS()Zύ5*3q½Ί…v7σhZυΎŸ5ή«%…ΜΙnρ›fΉδυ5ΗQSRŸ;Nφh¨TδMZ靆u ¬υ=/T•β΅Ό ΆuBΫNA#―§εRκχΊe—†Ζ₯\½λI?Ÿ4ζ2ƒ€?…rτTΊ ˚コ\₯]¨ςΫΚώGfΊ†¨xwMΆ“W›K’ΝJΙΔΜ$ΙϋΓo―©ͺ3Τl―²ΧOšI’ήΨDΖE!²=sΤύ+›’”pρŒΉ“οψŽX‰J<­vό§MΊ―Ό1—©^½Œ°\’A 0#¦Φͺh:‡β&‘dk«4-"©BθxΘ§+Š~Α{Κϊ>‚φΟέvΥu;>} Γς\_XjRί\΄lCδٞ2ΔπqXΊ7ˆot‹i`΄ςLR6φFŸΖ²(‘PŽΌΪίΏ:ςΣ—Kv:­oΔ «xR'x…ϊέο1ΗQ³i鎦§ψC$1|DβAnΗq€‰ WE]:q¦­*T•GyŒ4O@ρ§SΆς$–fž/˜0uήpFJΫ»Ήπζ§­ΕΟ©ΛnωI%²ς˜ΊΐaΖZΈ‹‹™ξ ›‰€”¨ΒοbΨƒ5mXη©IMήφ/k·ΪšΕεξ‚y =‡aωUνv= 4½5΄‰¦{ΦOτ•pp¨υΟJΓ’—6γφiZΞΦ54K=2νfώΤΥNžWΩΪ]ύsΣ¦8όλΗ3hz€²κZΑ’εcDKo³8݌wΖOα\eΤ¬­beJσSζzz‘Ϋ|5ΠtΝN=oQΧΡίNΣmΌΖTr€ΉΙe#βΈ§ »]ͺN@ΞqνW Υ/mτ˝:‡K+–Vš!Œ93ωU*ƒ`­κ±θΪυ½άθΟά’롆8ώuE4μξ‰œTββφgig>ƒαα}w§κr_άΝ ΓoΙ³wv'+“ΣE³jΒύ- ‹ζ²Bηœ~^ŠnW"Ήo«mυ4όHšdz΄«‘ΘςY`m-žΈηη­d<;©θ֐ήάeί[ξH°x„tͺ”ωˆ§ESw»}>Gkρ3CΌ6t:Ζ7ώϋ2Λ{!rAbƒΗρΔU­SP»Υo₯ΌΤ'yξ₯Ζω©ΐΐύͺ΅Α]ƒ?°τλ»NχZ1\ΖX½·Ω]±ΑxqΠζΉ *£.Ws:”ύ€yoccĐi‘ά‰t½LίyΞν ς//G^ΉΙό« ώΒ¬~&΅}Ύ«}rb΄;Θ  ΰœwϋ­ωŠακνξ©{{ggkupς[Ϊ)X#8Δ`υΗδ)7wr‘Ukά₯ER(ίπάΊ<–—Ά:Πςm¦ŏyˆƒΘΐηόjή·}¦Yψj=HΉ{ΝΧhšΰΖQIΖ0ηΣςVŠΎ},bθ§.fί{t;o†Ί™©Η­κ:ϊ;ιΪm·˜ΚŽT—9#‘μ€cάWδb«΅IΘΞ=ͺδ₯νΎ™s§CpιerΚΣD1‡#¦*₯Pl³αZ=ZŽβανΩZ)BυΪΓ¨ύ+ŠiΩέ8)ΕΕμΞΧNΈΠ<9%ΝώŸ©ΛtΡ2[Γδ4{7q–'ƒŠΗπ6ŽΊχ‹4έ:PΖ₯Μ pv(,άφΰΒ«šN©{€]ύ«MΈ{{₯<ΔΖ@=zΣrΉ0§ΘΫ½Ϋ/ψ-6ίΔχφϊ$e, “ΚLΉbΕxc“κsψV%““EI WK‘jVz6ƒ}<nΦq…?ΉŒυlγ>ΗΣήΉͺ*“Ά¨‰ΑMY€œ’k·ψ™‘ι^:Nci}™e½Ή ±AΘcψŠβ‘‘α•$Œνt`Κ}ιV5MBοUΎ–σPηΊ—δ~§τ€²­Q@Χ†o4; Όk«}ƒVΉΚΝ7ٞFDΙωT‘ƒœLsZ΅ΎŸaqnϊN§ύ‘Ξζ&‹ac―ZΚ’­ΞκΦ1Y9]λιώW;Λ»ŸjzάZμϊœΆο”’[/!™‹¨`ΰυ«š;Οx’q¦Ϋ4·7r3Η OSΗV-> ₯·”Iƒ£##ρJ|ΑNЦο{τωρ™D:†ƒk+§Ϋm΄Έ‘ΈB0ΟΟτgΐΪ:λή,ΣtιCf—2ΑΨ ³sΫ€k ݝΛ;brI9&­ι:₯ξ‘wφ­6ανξ6”συλPl_ρ€ZmΏ‰οντHΚXA'”™rŊπΗ'Τηπ¬J'&Š(’Š(’Š(’Š*{/ψϊOΗωT=—ό}'γό¨ (’€ (’€ (’€ žχώ>ŸπώUO{Oψ*‚Š( Š( Š( wgbΜrΖ’΄4΄ιυXcΦfΆ°;ΌΙbMΜΌ`}qZΎ:πΚxjώΥm―ε•δ so6έ€‘ι‘ώzΠ5EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPA‚0Eι\Ι+Ήΰ±&›@Q@Q@OeIψ*‚§²€ό•AEPEPEPSήΗΣώΚ ©ογιε@QEQEQEWψΛ@_hήԟUΣtΊdq‹kωΔlΫrw'\ƒŸε^]€i—šΖ‘Ž›Ou.vFΐ$ςxθ v”C¨h6²Ί}ΆΫKŠˆΠδ# ρόJσΚ+wΐΪ:λή,ΣtιCf—2ΑΨ ³sΫ€iΎ4‹M·ρ=ύΎ‰K$ς“.X±^δϊœώ‰EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPSΩΗ~?Κ ©μΏγι?ε@QEQEQETχΏρτ‡ς¨*{ίψϊΓωPQEQEQE> ₯·”Iƒ£##ρΧvw,μY‰Ι$δšJ(ζ“ͺ^ιjΣnήγiO11^΅Lςrh’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€X†Α΅ι]₯•δΌΔ±ϊšmQEQE=—ό}'γόͺ žΛώ>“ρώTQ@Q@Q@O{Oψ*‚§½§ό?•AEPEPEP]χŽ<-αί ΪSSΎ“Xhcš8Z!±ƒœ°›Ώ*ΰkΠ>6ΘΧi`ψφj`ržƒHΈΏdρέΕ₯§–JΌ ½‹δ`cΣ­?ˆ~΅πΦ³mkaq5ΔΪ₯Θy@ σ㏠^½γGό‡τŸϋAόސEvώΣ „a/­΄”Υο^fYQŸύRŽŸ(λλψΦΉ%ŒzΌ[ι“ZΪg΄˜ ΘπkΧS“Š[zJƒŒT›ίΤΞ{”°Žυ’"ΦG1¬™,;zΥjτ;­[O_Yά6‹@ΧL«oζΆΰόΩλ\η‡c΄Υ|alh‘ΪLηχ‰mΰπl:ξΏͺKlמbΩΑ [Λ•Θωa‘YθpίxΎNŠςΓL†7}²]ΛεΖ?w<σ]7Δ[A£x ΒΪ@š;Џ<Βςάξ…²ΔνVοχΏJή2ζŠ—s G•΅Ψΰτ.λVžHl‘YγŒΚΐ°QŒ:/t»«+ +ΙΡDŒ$0$…Ζr;ukΒϊΊθ··Όm –έαOBΨΑύ(Υ΅uΎΡ4{•μVEf'†άΐŒ~•εΝδgysyτW₯XιΊ1M*}.7{½3ν2LƒU'Lΰώ•Ξψ¦Φm/AΤ,-#΄{ε‘(Ι+”` συ©Uv¨›΅Ž^ŠυI<=ge©A₯/†₯Ό³!m@»nάq–θ{W*Ϊψ{Δ—φχVI¨A 4H’Ή^ΰ†ΘοηDj)l¨₯±—¨X]iΣ$W±€t($©θx§Ϊi—7Z}εμ(¦ήΣošKFγΗzξόw«iΦχΦρ\h\HφhΛ+Jΐ 9ΐzVo‚$Ά‹Βž%’ϊ=Ίˆ’ ·yάp2:qKςσXJ£εζ±ΔΡ]†΅›©xA5‹ °Έ†ημΗ¬6η<ύGλOΆ‹IΠΌ1¦ίίi«¨ήj δ,’TE8γωŸ΅W>›ŸMŽ2₯΄·’ξξh@2Μλq’Nt>1¬νξτιτ΄1[j0,Λωdυτι]$£BΡόY§θ‘ιa€†Xsyζ'˜vqЎFGΏ΅'SMΤΣDp2ι·1jΗMu_΅‰D;w n'ΟΦ­άψwPΆ‡Q–XΠ%ƒͺNCƒ‚ΨΖ=zŠ·βKiγΛΛ’ ήω˜πΩ©υΗwkβ– ϋNhδBHωœΰώBδν`Όš9j(’¬Π(’ŠΫ·πΎ©q=ŒQD…οa3Β ƒ”9>•ˆx5ΨΨxΊ+kνso)]>Ρ­Ψ>bA₯dψ3J‹Zρ­Α"άΟ΄ΰ8όqŠ…&δf€Υ܌J+±—RπΖ‘ ν³ι‹§lF6·1³;3†;ϋυκ·„ltρ¦jΪΖ«ΊŠΕP$Їf8#πόθηνŸK΄rτW_¬ΫišŸ…΅§X‹ αΈσDŽYXF~£υ©aIΠό)¦ή^鉨]κ%Οο$*γŒwδ~tsω ŸMŽcQΣ.tθνιUVκ[0ΛΨF" rBž€šθ$πυ–₯”Ύ–ςΜ„I΅ν»qΖXc νSν,“bφΆI³Λν`’κζx@2Κβ5γ$œ ΣΉπξ‘m£,± KTœ‡±Œzυ_@ΊŠž0ZD³Ί}YU²?V–£βxξν|CΑ"iΝˆI SœΘU6τΆΕ6τΆΓ| £hΪνγΨκΊ”Φ7“:Gi²-κμsΓzs·ΈλXΪξ›.¬^iΣ²Ό–΄E—£`υsΑ7eρ†7’Σl»‹χiχ›ζzκ>(xalυcT:ή—3ΙpdϋŸύ!w·BžΩό…YgžΡEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQETφ_ρτŸς¨*{/ψϊOΗωPQEQEQE=οό}?αόͺ žχώ>ŸπώTQ@Q@Q@zŸΖ} S›P‡XŽΡΫM†Ζyς0§$cΟVyeZ›QΎš Χ—2Dp 4¬Tώ  ΄MPΧ/ΧIΆ{›…C!E  €O'άWeρΆ6‹Δš\r.ΧM.`{_5Α[\Οk!{i€…ΘΖθΨ©Η¦E73έHζi&p1ΊF,qι“@ϊ"ι akάιZ’±αY•ΧNDާMΊ―Ό1—©^½Œ°\’A 0#¦Φ©ψzβΛJρmΌΝuΎΚχώ[ ΓiνδΦ{i+»;ώ!νβμΏB{ω[λ‰#9G‘™O¨&hΦzmΚu-PΨ²‘°}₯ίλΣ₯fQZ8ή6NΖjVwjηcγ94MVκηQ΅Φ NQB[ύ™Ζβxΰ ΜΥον<1‘ΪC.λ‹o;ΝM€mάΩγπ¬+(PPQWnΫmΪݍ']ΙΙΩ+οχάίρ6£mym’­€»ήΪΝ"“ε#kŽάŽ θm5]#Yρ|φWΏΪΝ$jΚΈςwςzπ9ό+ΟλnΫΕZΥ­œvΆχΝΥQd3YΤΓή)CΟ­·ωSΔZMΟΛ₯φ"ρqΔϊ¦?ηαw7ZMζ·π{@Dbλμ3\Itͺκ/™ ŸN^bξ;;±gc’IΙ'Φ€‚ζ{pβ €ˆ8Γlb»‡‘ΗZι„yb£Ψ眹€ε܊Š(ͺ$ξνυύ5/tYη o₯΅΄§Λo–B€mιΟ^£ŠΔΥ΅+yΌ5αΫkyw]YωζUΪFΒΞ ςF΅sτT*ijB‚Nη κ†…­_¦©q]ΨξU3Ω$nI c ÁœW ,s^Ο$A9($m͎Ω=ΝAE8Γ”#S΅Χn4~ kΩui,ο"΅XšΩ­™χ2ƒΡ‡&²τMFΦΫΒΊύœςνΉΊς|”ΪNν¬Iδ ΖΉκ)(+X,¬t0j6«ΰ;9₯Εγί –=§”ΪsŒu΅‘iw’λ>ΣτνZωτϋ›}’y&Etc’8θz~UΗQC‚t~/Υν//,"·΅¦ŸΓΈΑr;γς†οPπ͈mΥ“Dρ­τΚΟ Θϊg5E&¬ΔΥΥ™ΨΛ„τψ―n"½}NIQ–ΪΨΒρωdτ,άgSΒZ–ŸŸͺi:ď ­ς‘’–ςΩNF@δφό«™’§“K6O&–lλu«ν*ΓΓEΡξžω₯ΈσζΈ1˜Χ€?ARΫέθΊΗ…΄ϋRύτϋ­=Ÿky- ‘δγϊ~UΖΡG"ΆαΘ­ΉΤψΧTΣοd?²%gŠΥ"Γ)H<‘Ιϊq[†‘‘kWιͺ\k—v;•LφI’HΒ°ΰgηΤQμՐ½š²'Ώ–9―g’ ‰œ”6ζΗlžζ ’гC²ψU£j:‹,/,-όΛ{ˆδΈ°5Ιυφ₯exξHfρž·-΄‚X^ξFW εŽqνšΗŠζxc’8f’4“‡Ub}GzŠ€;o†Ί™©Η­κ:ϊ;ιΪm·˜ΚŽT—9#‘μ€cάWδb«΅IΘΞ=ͺδ₯νΎ™s§CpιerΚΣD1‡#¦*₯@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@OeIψ*‚§²€ό•AEPEPEPJξΞŘε%^Ρ!±ΈΥmβΥΦΙΫL‹Έ ΑΑΗ~q@h‡ΖŸΓ“[8ž;έ>ν<ΛkΘ‡Ι ώ‡ΫήΉκ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š‚IŠtΎF`0 '΅6€ (’€ (’€ žΛώ>“ρώUOeIψ*‚Š( Š( Š( Š*ή‘§]jϊ•½…„~eΤν΅ dυκh·σ ηΐοί ›-[dGΠθfΌφ½ΗOmαοιΎ‚ζ;‹υœή_4G*ŽA3ί―ώ:=kΞ¨’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(©μΏγι?εPTφ_ρτŸς (’Š(’Š(’Š)πΛ$2 !wΗFS‚?eQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQO›o'—χ7ΏJeQEQE=—ό}'γόͺ žΛώ>“ρώTQ@Q@Q@WMπΖΫRρΖ•i Om+Έxί£a0(™’½^Φ_κZž­αϋ&ΧJŠ*ΫκR\ጊp -€3ΧΗlVOΒ[jV:Ξ­w¦ΎͺΦ*‹obŒWΝ‘³Χ‡­yυκ:πά ΰΕΧF‚Ϊ‘ Θ†k`Δ€ˆG nqϊϋT6°θ>π‘¨κZ,Z΅ώ¬ςK!Q)ΗΚ@8==ωφ 5’½ βF—€Yάψ]τ[A­ε€s’K‚F gΎ .Ρ΄ϋO‹φΪ]΅€qινuj†ϋ€6ΝΓρΙ =’½ XκŸntEΙΣRwfŽ3Œ"v©ΐόk§—Β֚ݞ­k'ƒδΠώΟΛezόεz+ηΧίή€ΨΣζ€ρκΨ¦™\xNγ@Υğ+'ϊ‰ΈΙοτΊΠ!§iΪ•½μφVζX¬γσg`ΐlO^O=J£^Επγ\ΣΒΪϊ―‡ν‘¬΄ΠnJΣ0CqΖp}zלψ›XΣυYν€Σ4K})b:E!q!ΘΑ9€6l~xšσNŽξ;H“ΜMρΓ$Κ²8φSΣρΕqΧ0Kmq,΄sDΕ`©υύJ;kz…΅Θ­5θc]Ί}Ι Αӟ“<ψ{χ―;ŸQΈΆρ„Χž'±[뀕ΎΥm(‡lΞсΞ΅&±α©tΏιz³ήZMψΚΕεγγ<ηθk½ ΗpιW>πφ³¦i0i²^K2ΊDΕΈV*9?Lώ5ΟxCT±Σζš+έf[†E…$r₯<Ξr?*η¨―Nψ©…¦iϊE­ŽΏ!Yέˈδ-ܜΛι›žπΤ ΣuHΌ2ή!Τuvug! ŒN2Η€<–Šνώ*xvΧCΤ΄ωμ-€³‚ώΨLmdbLόKΟnŸ­qQEtώ'Υ<=}’ι0hΊL–WΠ 31ΰgΉΟ998 bŠήπΡπȊψIWW2nWΨ<ΌcΎνύώ•c^o9Ώ°S^Ϋ†Σyεyxζ€9š(§B•δ€E{ΈΎ„‡IΣ—KΉ·ΊΣΑ–GdžGλ].—€x}’Πμ.tXd{ννrά`α•sΗ‘<στ€λ€―`ycVώRΈ?­7U+Ώ+ΛiΆ7:•τ6v1nf;Qqόx¨`’ΪβX']’ΔεOfWuπ“S²ƒΔSi0Οw-ΑhοΘh†ή€t=ηU|w­ιwWzΏ‡ν­nΦιΑΌIX³η'Η4{IsςΨ.Šτ;Ht? x7HΤυ-!5kύQ€`²ΘUcD8γσΘόύ«/β6‘§Ψ\ι—Ϊ4m –§j·+ |²z€OnEͺœ­oιΘUν;JΊΤ-οf΅Ud΄‹Ξ—, κ=juί?{w¬Ϊ—:dθΏώ΅svWCJξΖXπΞ¦N”<₯Ξ¦ ΆωΗ͌uτκ+4ΩΘΊ‰²vD”Kδ–fωAΞ2O§½{%”JχϊMχt‰D$ϊ±«0kΛt^ΞΦζξmGJ‡Q3Άΰ$Γ’N1럳…G+•(€Wρϊ&¦φRάApΚ‘·ΒΩ^{}j -:ξϊ©ma2GlždΔ6/―5Ήρ"ΒΧMρTφΦ¬,hB/@JŒΧKΰ}[OmYQ’ΐ­m` νζτœwzgΫΦ››PRZ‡*ζ±ζŠ 0©8«šΦ—u£j2Y_*­Δ` Α‡##ŸΖ­λ–£wlΦ\Zr‘Γ,n[=y―Dρ=ވ||4Ϋν.€»h£–αδ!°BΠ~iΚm5 ”S<ŽΊψό#—…Ά|A¨ 'Ή‰ΪΒΜ&dœς“θΉΗΰ{VΏ§¦β+Ϋؘ’œΖ€υ۞?Jλ~8ΚΗΗ/n8†ΪΪ(γ^ΐc?Φ΄NκδžEwί ΄ύ"ηGρEζ·b/#±·I‘w9ωŽ3€3K­ΟαwΑ7…•¦¬YΞ¨ΆΡΟ“ΆπίΑαωεή²Α΅—Μχ=TρΨβ—3ζ°YZη#Etώ °΅·πw†ξΰ…RβδOη8κψ`jώ«₯XΕ{ΰԎΩo Οο 0Ι?Z―hΏ― ε8š+Τ5(tHui—A·c¦_, Ύcb@άίNp>•VK·ρώΏe-’Νemfσ€EˆΑڍΑλόDTͺΛ°ω9’½WN°Πυ­μX"mbFfWoά²‚ƒπώ^υΗx*ήΞk›¦Ί―5YΡ‚ή; zΉš¨šz ”ζθΕΪ, αDΥΏ±›F½ŽΰC$;]HΘ`ωλQΪ&₯ψKΥo4˜ο―%žHΐw*€yluΐcޏhšΊAΛ©ΒQ]WІГ閏";„\X‰wˆΩHʞΰγ·JΣΥ<-osγm*-2=ΊV€‰p›z*—ύE?hΊ‡)ΘθΪMή±q,(―,q4₯K•Ξ=O=)4M&οZΏ[;W˜©o™‚€δ’k¦5;;/‰±O§Diζγμκ©χJ³?‰ω«GM²„rO^cgΩPΪ@λ£|Έό6ŸΖ¦Shj(σ’0HΘ8τ’»/θ_ZjšΝŒš‹Yͺmˆσ‰λŽp1όκί‹t8O…ΧW;hΧ‘άeƒq*κG ιϝ7Q)r‹•ΪηEw±i𦙨_i‰©_j,δ,UcE8γωŸ΅ax¬θέΑ>Ί8₯ˆ4Άμχ2wPOQMNξ֍‹Ύπ™Φ­΅Bυ4έΣk©vIώΟ?¨zωmϊαlδ΅YDξ0Μ™ωIΈΕw~%soπΒpGΒ\O<²cψ˜;Ÿΐώ•η΅b (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ žΛώ>“ρώUOeIψ*‚Š( Š( Š( Ί?‡:•¦γM2Q—Ι΄…˜ΘϋKc(ΐp=HrŠΉ­MΞ±<-Ί)g‘Ρ±Œ‚ΔƒΝuŸ5ύ>ΛMΦtmbξ{mAPΗw ’au9Ξœ?/zαθ ΧΕ²θΆΪ$vVεώ·¨<»€‹€(ƒ ΩΙχΟ­iY_ψsΔ>τ½sU}.χJwΪώCJ%FlοŒ¨―8’€=+γ–θž“Nά-WMFƒxηgsοŒV΅Φ­ΰΝgΔΆ^-ΌΥζ΅Ή„G$ΪΩΩ™₯LmΓ1ΐό‡JςνSXΏΥ!²Šώ6;(EΌbΔgκyͺΐν΄_Gkρ2OΟ‹Y¦Όc–6Δp ΥΤfπ͝‘uŠuMPʌ-,S͈£›ΨυπγΦΌŠ@tή ]G»^½ΊΣHSi{b"nsΈ/>Ÿ­tώ/ρ™ƒ½?ˆoZεf2ΔΚ!P:ܟΜυ=+Μ¨ ΟαΖ΅₯ιΓZ°Φζ’ΪΣS΄6hD/εžyΐηΉ¬vΧFΣ/νFΥ?Ά`ywΫ4 ~ι Χ"°θ RTπ ϊΥΏm¬Ν₯€N“6šΆΜY]pp¬1‘οΧ¨_TΎΣεΛ L&R ( •^ησVŠυ}Hψ.χΒZ>†|\ΘΊ{Κβoμ鉓{ιŽ1ŸSY? ο|7£jξ­¨,7‘|–Ιlς¨ΞA“j޽8$u5ηΤP[βΫ=’žώΛΕRκϊ”²ξxήΚH‹g«nn? ή5½'Yπn™€jυΞ…§3„™#vIccœ€r8ϊ{ךQ@ξ΄ΉυbΡ.―o-αˆ+\έHΔΚύΚƒχG΅s΄Q@tώ'΅πΔ.“&}sq¨Ίfξ9T€§φ9Θΐ'ΜσPAαjžŠxτΆ€,ΜόΘUω™«> ρΦ΅―i­c¨=±·f Dp*ŽœŠε¨ ŸϊψήΞ™B’¬κ9νž2‹Γ ρϋGWΥe΄Ή²1I%·Ξ&*”«ΥΔι%³Šk―ή±Ά²k‰$$©bͺU‚δ('=:W-¬κ·ΊΦ‘%φ§7Ÿu Ÿh\ΰ`pR¬!BΡ΄ŸKoW™.5[Ω‘mΡΙ;Ίœc ±"ΊλT:V³‘λςΙoe¨ͺΈD/ε:ŒΙνω{ΧEk()G”λΔ:–‡¦x0xwA½“R’k‘sqtb1―yμ?ZΤ²ρN‡€{Μ%¦ŠΦ“)ώYJ§<χW˜ΡQμSVlΓRΦμÞ ‚6Ο¦Όοs R0 ͺΐdŒ€zfΊέK\πυ犭υχρ]πΆσ#“ϋ9`“(WΣo8σŒΧ‘QIΡO―ΔζΩΨ|U›^…š}=ξU ²2•ΘŒηΥ©χ…|1΅}£κ²j7—φςAooφvO%_βzΰωW™QMΡO¨ώΤβΡΌM§j«40JΒυΫΠγσ­ΫxrY/5-^{»›‹ƒ'ΩΡΣhbIωΟΘΡTαys\@±Ώπχˆ'ΆΉΏ“Λ΄Ϊι+m-€PŽƒžΈ~ŠΉ.ef ΩάτΛi‘άx²In1φ†/cϋΆωΞΗAێ6υΗZβτ"ρ&:Ά°tζRlοΟΛ±θ©TΤofS•χ;ΏΛανfςλT³Χ ά”P–Ώdn χެΏκ–_Ϊ–z¬―΅ύ±ƒΞD-εŸ\{Χ1E šεεΈsksWX΅Σ,ΰV¦uˆάξ`hΆœτΑλ[ž#Φl/>#Aͺ[OΎΕg·s.Ζ.έΗgŒΥΗQO“Έkx²ς κ7vζA,ΕΡπFGΠσ]׎l?α4aρf‹$rI¨]FΨΈ ε°zŒgπετψ₯’"Ζ) )VΪqzƒνT••„υ:ίλ6o†ΌYi{?—q}j‘ΫΖ;ΨnΘΘG\WEιzF·€λ> Σ4C^ΉΠ―τζp“$nΙ,lsƒ΄ŽGŸOzζ©nΊ έυά6ρ€n€bd~μ ύΡν\έμϊn»αίx·E՟IΥNΌE"ϋ8`@σ κBŽ{t#ΖZ}Ξ±ρ;U±ΣΠKs=γ".ΰ2{ςxμjˆ>(°Σ‘°΄ΥZ+XPG,1εTvΞάώ΅Ν}¦΄΅Η'Ϊ–2n;‰=Nzσ“L@ρΣΫx{ΑΊo„`ΉŽβύg7—ΝΚ£@Lχ뎏ZατE±mbΝug‘4σ*ωνΛΟ8ͺTRwΖΡhpψ‚dπΔ―.šv³gοc3ΙZΈρϊG„”»ο4Χ•ζM€mΛ‚HΑΘ₯rR”T·v;_‰ZζͺκZtΪ,ήdpEƒς2νmΩΖ§¨κZΉ¨&­q―ήΨU7)’X aXp3Šσz*=’I$φ;:_ κΦv^4KιZX΄ζiŒ€ΘΑH±Ι<Šιbρn˜‰Ιœ†‘‹i#|ηΚ1άp+Νh’T”Ψ)4t^“B–φΗ^έnσmh/Q ˜ˆκψ֎―}£ι~›D/€Τ₯Ήf–cΰ߁\eά.οpζΠν¬o4Mkš~—«κ¦άιξε%ςL‹"1Ιt?αή£Χuν:ηΔΪ±gf˜!ˆJκrΚ¬ luιψρ\m{5{‡1ΫkζqgβD†γs^_Η4c θ ΙιΗγW'ρ”ή9ΧυΊΝΥ‹C ž[όΞcAŒc#zŠσΪ){%ύ^AΞΟAΠ|E₯Ϊκ>–{­‰cm4wΛc±˜6ž£¦jƒuk΄ WIΌΏ“KšιΥγ»Dfιό'o8γυ5ΖQG²AΜΞηXΤτ˜ό6•iͺΟ¨]›΅”Ό±:ξΑ۞€{œυ¬½GS΄›ΐšFΩΌ‚βG’=€mœγ―­sTST ―LΠ5—²ψcqu:€[Ό–vRžΏΌΑ8ϊr σ:»>©y>™o§K6l­ΨΌqzœ“Τυ’pζ²»ъ0e$09v5θ><ρ>›ͺhΕ¦ΚZξξTΈ½]Œ»Yc Œ‘ƒΠtΟJσΪ)Κ M7ΠIΩXκό¬YZΨjš^§q5€Κ…nbRLN§ ΰsπχ¨όFΪL\vΦZ΅ή«zny[rD‹θΊŸzζ(₯Θ―pζΗmgy’kžΣ΄έ_P}6οOgΛδ™Dc“ΣΏOΚ±ΒήΞ©a©Νuw AdΠ2˜KC7CƒŽ}=k–­ωΪW½•ΎφWΓ› &γIρ-ζ΅d.γ²·IQw9Λpιœš]fo λ^ žώΞΚΧHΥν&TρΟ“#ξ|Qα΅ΣšA€θώDBiεΥXluθ>΅šζζλ}ΰjxrΚ juπε«'PKt_1±(~ο\sτ¬YΌ!cqρ~m 5hτΰβVD8!| ϋAϊœ}*-sΔZ]ՏŠ£‚λsήκQ\[-†τ“ΘγθpjKίΨ[|\“ΔŽΧ:kmFeB€©…PΑώU1ŒvΎΟτ‚#vO Ϊλ6z­΄ž—Dϋ<-ΰvωŠτWΟ\ϋϋΧ7π“S²ƒΔSi0Οw-ΑhοΘh†ή€t=ηRκxjΦώζ/jZ›JŒ-lΠIBzocΤΓ5ΙψCS‹Fρ6¨N¬ΠΑ(g ΧoCΞͺ0r„—ωŒέρή·₯έ]κvvώΆ΅»[§ρ%bΜCœœcΧCq¨ιšgΓo O©ii©Λ™Φ(₯ͺ(ήw1ΗSΐκk˜ρ·‡%’σRΡυη»ΉΈΈ2}‘­6†$ŸœπqMρ―cyΰo iφσοΌ³σόψφ0ΩΉ²9#LΣδRQJϋωφˆš5…Ά£€\θύžΫU΅Žα`$‘7lžάΦ»Ή<+§ιϊ­ΆŠžšώΐ„IυC#άέ\c ηΌΖz՝υ—…Ɲ?™5„qL60Ω"γŽG=;dWQͺjήρ§³sβKύ9YάιΙ…‹‡8τόͺ$§Κ―~½ώ@dψWΓvQόV“CΎˆ]YΔσ(Y?ˆ%IΗ~•GαΦ™e©kΔWΦι4pισΛ·πΊ•Αύj·†|Ck£xς-]cΈ6++‚²>ω<ΆrOrΟα]$ήπΔZΥφͺΙ¨ή_ΫΙ½ΏΩΩ<•~»‰λ‚εU>u¦Ί€_ΒέΗTΈΥeΊ΄MBξΦί}­‹Ι°LΗ9ηΫۚoŽ’iΡ$ώΈΠ΅a' ™ςdNύ{ύ?:ΛπrθRIuΉ{u§ΞT[ΘAasΐr{~΅x³]Σ“ΑC‹\Ÿ_Όk‘0Έ–&Q Πδώg©ιNWφψ`<β€pA›ΐ0ψnmRuρtΕh!&"›°_#ΠOLβ°$hbΎf€mBPH0YAγ?Q] z=ςCβύRΫYπφ­Ά±.Ϋ+ƒ΅ƒ/?!<ψcΧ½bψNΡυˆžGˆΰNν/Ϊ#u — { £΅\TπlΪ­Ύ±©6ž‘²JΦ nΕ•—+:Β³­»Έ³ρn™%’—v˜FP·~Gτ­?Š7ρ\x‹μRΟNAo/@z·λΗαFœ·~~^›’x₯Ϊ?‡ή‰#=ΩGBC όxώtοˆ g΄π€²ςI§GΉSΣ―ζiΦ7šΉα];LΦ5Σn΄χ}’ω&E‘δŽ:ƒποYώ4Υμ΅-CN··΅„ mŽ0_ρΧ›ΫξSζJΫ\λu…πΞ™γ(τS Ε"\4i$¦FY|΄~Gy5Η]-—†ΌY¨ΫάXG©[DΝG+•Η ƒ‘ά?ξ|W‡SǟoΥ5)-n- R=Ώ’Μ& €0ιΨν^iβMEumzϊύ’O)eSΤΩό(ž‚’Ή»μw΅­6ΧP·†ηA·Ί•μ£e•₯`Pΰ;W?πγJ³Τ§Τ€Ή΅[λ›x7ΫΩ΄›­Ξyφΐόκ߈n|;β8m―₯Φ$²½ŠΡakf΅wάΚF “X>]GΈMbξζΖlmu,#nsΈ}?ZΌ©Ω^?λξ4|`-Β5›Γ“θژ~ ηΚ‘?Jι~ψi`Χtέlk:dΝRKφ&ίrs »;k#ΔΪΝ‚xζ©ό!’Ύ"iq 7HcΈΖΐĐ*eΉ­+ςκrڌΎ~‘u0C™+>ΓΥrIΕW­οθš–‹ά.«mδ<ς<±όΐ‡RΗ‘ƒ°j Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( §²€ό•ASΩΗ~?Κ€ ’Š(’Š(’Š(©ογιεPTχΏρτ‡ς (’Š(’Š(’Š»£j—š6‘φ›7‘uBΎΠΨΘ πA ͺnΕέ™ŽYŽI©.‘RvUQεQQe{€QEQEQEQEQEQEQEQEQEQEQEQEQEQEkKΤ.t»θο,d\ǝ΄621Π‚:‚i^y€–V-$ŒY˜υ$ςM2Šb·P #¨’ŠC-κΪ•ή­|χš„ΎuΛ€φ…ΞΠUJ(¦$­’ (’ΒŠ(  n.gΈ*n&’R£ ½‹`z ΤTQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@OeIψ*‚§²€ό•AEPEPEPSήΗΣώΚ ©ογιε@QEQEQE=οό}?αόͺ žχώ>ŸπώUQEQE₯αέσΔ¬z~š¨Χ2eΫFΙηπ¬ΪξώΙC±rθ€0m|+ͺάλZ†•H/,Qδ™YΐPŒ{υ¬*χ­65Τ5ίψI`f« N&ΫΠOEqόΏ#^iπκΒβκυο4[νjζ(Α·΅O–Xη™t={Π!Ez—<=jώ Mpθ@ΤaΉIn Ϋ"Γυ#ς5³€θήx4 ­ dΏΡΎΧ-ΐrWψ₯Š[ Ά(UΫM2ζλOΌ½…ΫΪmσI`άp8οT«ΆπD–ΡxSΔ²_Bg·_!š ΫwαŽ{qNo•]9r«£‰’» b 3Tπ€Φ,,Β⠁o,q±e`FAηκ?Z―¨ιΦΧ~ Συ=>IαΫ]ͺdξoαoǏũ)‰LεκΣΨ]&ϋΔE€ŽcY20XvυƒΕvΆ:%ή“d–±Ι=΄I-ο'χpJAη]ή±¦―μ[B·kw»d[c+mSƒσg­'7£Kr]GdάσZ+’πν…·ˆΌ_@΅³•‹΄Q±;T.p υΗλ]KθVϊ£ ψnM+Θ…εΆΉάί1^ŠΩλšr¨’μΗ*Š.ΜσJ+¬π™i¨M¨=Ε²ήάAψ-M‚VϊϋqωӟπώUO{Oψ*‚€ (’€ (’€ λ~κφ:Œν/΅Iό‹TI>Ζl„ΦΉ*(ΤΎxΟLό1«ιšΝΑ‰ΏxΦdΖ͝κC/Κ9σλYί΅Ν2 λ:φ©.qy"IτhΝΣ)ΫΘ{}γ^}EzVΏ­hq|;ΉΡ,΅ΛRύ―c$ρH»ΖvξΞc‘9Ξj凋tH―ό7$—ΈKM¬η>Sό’•ΐ^œσάqο^SEuΪώ΅i?„λν;νtΨΓΛ-"²ςFqΫ5ΨjΊΗ†|E©Ε­άx£PΣ‘ Φ›IΈ°Β°ΰg@?…y sXΈ†λTΊžΤL-ήBc>χΫΫsw8­ΏΪψb I“@ΎΉΈΤ]3wͺ@SŽ{ δ`ΗζyŠ(’Š(₯Œ€κO@E%ΦψƒW±»ψƒ§o>ϋ%ž2laΒνάpF{Ս⋨oΌC¨]ZΎψ%™™d}5—EJŠD¨%c΅Χn4~ kΩui,ο"΅XšΩ­™χ2ƒΡ‡&ΉΟ ί¦—Ω^Μ¬ΡΓ f ΧρY΄P‘ea(YXθόOˆοs}¦k s<Σϋ3[2 I?1ΰβ·₯·Σ.Ό αΘuKΧ±$Μc˜Dd• zδsν^}Vξ5«‹ [)₯έmk»ΙM mάryΖO>΄œŠβpz+μnxΊϊΧUΎΣ,4]σAk ZΔμ6™8ΞαΦ’„+Δ?τ —ώϋ_ρtAΑ'Ϊ&ž²ίFŸ+JΡ+JΡ7Ό;² ―ΩΫ2δn+”8ϋΉυ‹¨H³_άΙΚ<¬Κ}A& f,Δ±$žδSK[-ntώΥlν¬΅=3Rž[X/U άF€˜™NGœ…GβΰΣc·³Υ.΅;Ά}Ο+nHΥ}ž§ήΉΚ)rkqrks²Ά»Ρu ΨXj—οau§³νo$Θ$F98Η~Ÿ•/ΔV„΅žα°Cξ»{gίΖU»νFκύ-’ξ_1m’Δ6΅Aΐηρ₯Ιgt.K;£ΉŸPπΦ₯[x†ηQ–ήβ=’Keδ3‘1Œ7Lp?ϊՁ¦x-όnΪΤ±7“$ΞΜƒ’˜Θό«š’…M-SKC²½:΅½άΡλΧΧμκE½²«Η΄Ÿο1κcψit‰α5k«‹)p ½Μ@°Fο9=«ŠjZγPΧ;ojφKαEcΥ¦Φ.Lβ_:HΩDJ@[“Χ5›ΰΝJΖΟϋNΣS‘α·ΎΆ0ωΘ₯Ά\ ζθ₯Θ­`δV±©©ιφI{oo’ߝH˅ϐΡa‰ΐ\5^„+Δ?τ —ώϋ_ρtAΑ'Ϊ&ž²ίFŸF;K£4mμ’Σ΅Τ΅ρ3GL‘‘½A\ƒίΤλμ΅M'D³ΏςόCs©Α4 6M €3Σ%ΈιΪΌρ˜³Δ’{“IJPζάR‡6μΥΡ,΄»΄”κš±ΣΩHΨ>ΜουιΊK κχwZ¦΄^ΰ’„Άϋ+Δ>ρΐ΅ΔΡMΖξχ»άξΌ?w‘[xQνF°tύFο"ζO³<Œ'€ F;χ?‡/«ΫΨXάΓύ“©}½qΈΉ’ΪΩι†λY΄P‘g{‚…ξz‘¨hZΥϊj—εݎεS=’Fδ’0¬8Εr1XΟ­κΧισM’Ξ¨ξ „ΟROSΘ¬ΚTvC”b§ΤRPεΨ#]އώ―Π2_ϋνΖ¬ψGP Π΅»ZααžR¦Δ,x'-Ηd΅ΜyσΟY?ο£QΣqmYƒ‹j:νfχI°π’θΪMγ_I5ΐΈšo(ΖΑϊΦ­ό,Ή w¨Ϋέ }?Θξθ†6σι\5\³Τμν.ν­¦ςαΊP³ –Άq‘Χ΅K‡ΊΠœ=ΦƒXΎ}OUΊ½—;§Ύ=aψ θ΄»Ν"Βqι:₯όš|°\™’A JιυFЧՊqMXίπώ£mαΕu­we²y6—BΘSΣqνZw§BΆ·»š=zϊύH·ΆUxφ“ύζ=@6ŠNw…έΝ― .‘#ά&­uqe.·Ήˆές'΅nx‹W²_ .“­6±rgωFΚ"P:ܟώΉ&Šnw »…QTYάaiV? ZΎ‰ίUΎΉ1ZδPpN;ύΦόΕpυvχT½½³³΅ΊΈy-ν¬œb0zγςJ€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ žΛώ>“ρώUOeIψ*‚Š( Š( Š( §½§ό?•ASήΗΣώΚ€ ’Š(’Š(’Š({ίψϊΓωT=οό}?αόͺ (’Š(’Š(’΄|=£^kϊ¬Zvœ¨Χ2†*ΆŽ'Ÿ   κ+WEΠ/΅›»ΛkF–ΦžPΞ„^’²¨’Šμ>λπi3j.–†Ϊ Γ•Iqγι@mQ@Q@Q@‘m€^\ι)ΆI„‹wœ`cρ^θχvzΘξμΊ&7Œe±Žzw…ΜŒϊ+ͺΧ –[mOΪΞ°5]>}.ϊKK°‚dΑ;0δg¨ϊROf%8½™RŠ(ͺ((’Š( rj汦\ιοg|ͺ“ €ΐŽFG"‹Šύ tQE (’€ *՝…Υδ72ΫDdŽΩ<ΙH m_Zͺ$ΤΡq\(«šΎ›s€ίΙgzͺ³Ζ`ΘΘδ}j ίPNϊ…Q@Š( Š+RΓF’σF½ΤVζΪ4΅ πνŸACvάMΫs.Š( aEPEPEPEt6>Φo,’»Ž Wr%U,=pMsΤ”“ΨJIμQWn΄Λ›m6ΞϊeQow»Κ!'iΑγ΅;…ΚTVŒϊ-διρʈ­~ˆπ|γ1ΐΟ₯lk…K­ΆŽ§ν ηRη»œVμεh­¨Ό5¨Ι¬M¦*Γφ¨“Μ`e]ΈγΏOβ ήΧΡ[zpΌώ΄9ΕuœWS•’΅τOjΠΈ6)-ΉBς9Η_‘₯ΦΌ7ͺhΠ€ΧΦΫ`s…•:ηΣ ρO™^Χ2½cΡEΚ (’€ (’€ (’€ (’€ (’€ *k+YοβΆ΅ŒΙ<‡j dώ4Ιβx&’)Wl‘±F_B WEP0’Š’Φ .a·„,#PN2Iΐ θ­{ŸκΠκ2Λ°uIΘpp[Η―QY&žΒM=‚Š( aEPEPEPEPEPEPEPpIΐΐ’•€ Bΐ­%QEQE=—ό}'γόͺ žΛώ>“ρώTQ@Q@Q@O{Oψ*‚§½§ό?•AEPEPEPχΏρτ‡ς¨*{ίψϊΓωTQEQEWsπSώJ6›ώδίϊ-«†―α~­e‘ψΚT›Θ΄d &ΖleԊοόαΫ+Qρ Υ―ˆ,5_NΈV·ƒο %NO=1ψΧ-πΏΓ–Ϊ•Ž³«]ι―ͺ΅Š’ΫΨ£σdlυΗaΗλTΎλz~“­λ·…Η• Ν…Δ16ΖmΞΜ₯Gγ8=x©>kϊ}–›¬θΪΕάφ6Ϊ‚‘Žξ$Βκsœ/8<~^τΐΨρΧ†ΰo.Ί4Π5nD3[%$B8`;sΧΪ³ΎΘ#ΖΏφ›ω«βΩt[m;+ r[Τ]NΕAΠlδϋηΦ’ψm­ιΊUΦ«i­<ΨκVOjσF₯ŒyοΟLώ”Ι[€ΣΖdΖ½£]_hώ=‡Γνα˜%KΆŠ9g20ς‹ΰ‹Ψt$η<ŸJσ}wMΠle³m ^mQήLH¦ΡαςΗ9n΅κ^4‹Β±όH]OXΥε³Ί±ς€{_!œNTB¬:v{P‘ψΛKDρF§§@Ε‘·˜ͺλ·¨Οΰjχ‰υO_hΊL.“%•τΜΜF$8ξsΞNN+?ΕΪͺλž%Τu(Π€wE=Bτχΐ‘β{_ A’ι2hΧ7‹¦nγ•H qΟaƒœŒxόΚ˜’Š(nΛZ[o M¦ynd{€Έ8ύ*j‰­kΧZ„q΄i1\+‘… ύ+*ŠJ);’’“ΉΦι_ςMυΏϊϊ‹ωŠΝπM€ή(°Ά»ŒKŒΑτ?)56Ÿ¨ΪΕΰRΒIqw<ρΌqν?0dηͺώ ½·ΣΌMcwy'—oﴜ|€tχ¨³΄ˆ³΄Ώ‡Gnώ½½Ώ%Σα°HΔ‚ל†.§œρΟ\~‡ΰψ-&ΈΉk2οS™0ΫΒ§a>G t¬}BEšώζHΞQεfSκ 5ΣxGT±‹BΤτ»»ι4ΩnY].‘ tώ·ŸY€ΣŒtθ[ρV‘πΒjŸΩ €^%ΐ…αΙΪκFCΟZ†Ϊ=+AπΖ›{¦¦£y¨3²ΉUγŒwδ~~Τjڎ—ƒeνu9―Κ^HΩw ΈωsΠsž΄ΫK½Yπ֟§j·ο§]X3„“Ι2+£žϊ~U*φΧk’―mvΉβS€I{ϊhβ–0ΐΩύΣχPOQ]Η‰|:Χή6»Τ5%hth#Ie˜τpͺ>QξMpώ%—H7E‘FΒήΒ<͐fnνƒΣτŸPρ…Ίψyβξ΄KˆΦ£`ΫJ•ˆSάnyυ§%-9BJZrφg=¦¦Ÿ¬ψΖή$³Σ¦›5la@ΰg=NΟ½t^!Ά΄³Šφο Ki†X.νΨΆπ–=0k–ςτh|HQη–ηFήy*αHγ‚3qž9Εu–Z¦“’Yίω~!ΉΤΰšŠ&…ΐι’ά tνDοu`ξ­ϊžwEVΖη’ψ3T°:£H€5½–fo0€`sŸLϋW«_Ϊ_άΫ΅–›‚― ±Ήmάυζ―ψ3R±³ώΣ΄Τδxmבֿ>r)m‡Χ³΅{m:Ξκ¦jFώ"2οδ4[Nz`υ¬£I™F)IžƒβK­ψθiχΊJάΙtΡG-ΓΘABΐΪ@=ωWMπμ=}ΩΝ¬s8$˜’‚@ύ§ψƒW±»ψƒ§o>ϋ%ž2laΒνάpF{Ԑψ‚ΪΛβ ΪΌE¦³iœ’ ‚QύsψTΖ2KNΔF2QΣ±ΎϊΎ§k¨Βώ“Jς!ymw7ΜW’ΆzζΌ»+Σ‘[[έΝ½}~Ξ€[Ϋ*Ό{Iώσ WWNζ”ο¨W{α­*ίώDΏ΅ΡΣYΎy™%ŸJŽŸ(랿pUΤh)£>lέhϊ’18Ve‘sΖ6γΊšu6 ›ώ)6gP_±iΧsuΌΩω_ΎάσŠί΄­_ΒΪεΔ:4sΩ$E$I‰,Δwϊ~΅GΗ:΅ž­{§₯­Γά-΄ —n…L§<œuυšΥα°ΡυkψH̟oXΧΨd6’zwΞ}ͺΒ·ΏΜ—π­οσ8½.βKθ¦Ί΅KΈW;‘v* Ž£σό+ΉΈώΖ_ M¨ήθVφRά©K$YΞ>=ΰϊΖy» mίΔπGu¨!~g›Ιdάq»y8Ξlψ΄=bκkΗρ6YP¬λa TP>T·ΦœυkΔ'«[ώ%OhΠ^ΪκwχRjΡPEjŒG˜μO\sŠ΅β#α₯Υ²_H»Žq°dνu#†τηΞ³ό!ͺΩΫYjzf₯<Ά°^ͺΈI12œŽ8 Δ ₯Α¦Ηogͺ]jwlϋžVά‘ͺϊ=O½'~piσœε:42H¨½X€)΄¨Ε]z©Θ­D»‡ΓΊ_ˆ πμΊ@ΈΙŽ)nΪV½ΐΑ}GJζ'²τ―ίYκίk’ΞdCnWy9sž:WKsαO\·ρΞ£5Όλ²IlΌ†bΞ€c 8Η­\V»ύ©¬^^…('”ΈSΤΓς¬`Ÿ™„σ‚wž5 ‰τΡ¨Ηͺ³ύ†?'Ι)8Ξ{υΞ+Νk‘ρ¦£k©]i―e/˜°ΨΕ €aΖμŽGΈzœmιΖΡ τ tΛ}KΐΎ:•΅€ΟΑŸ?>_·Σ­yύt:Ξ£ksα-Κw\Ϊ™ΌδΪFέΝ‘Ξ0xτ’i»X&›΅ˆΡ,  E©2G§Ζ’DϋΖ’Ώδ›λυυσOŚ­ύΆ†–’ωma2€mqΤr9ό(ΣυXΌͺXI..ηž7Ž=§ζŒœγ)>TΏ­ΙIς₯ηϊœυuΎ0‘oΒΏυκΜW%]‰5[Ν@·Ά—|Ά°2L»HΪIr9ό*δ΅EΙj_ΩΎ‘αOΪΔρ#ΙδΆΥby?…Ir‘hΤ4ΫΛϋk›»ΙPΕy‚0%§OεοXΪ&£kmα]~Ξyvάέy>Jm'vΦ$ςγ\υG+mίΉ<·}QEjjz6ΆήΡ5Λk)4X₯Žhγi₯iXyaΈωG·\ϋΦ-†a{γΣ₯ΫN&Σw—†Κέ€Γ―¦j§Ž΅]S[[‹|ΨD¦ν₯y‘Θ[Β:²hΎ ΅Ύ•YβBUΒυΪAž ΙE¨έoc£u½ŽΝτ+}NΧQ…ό7&•δBςΫ\ξo˜―ElυΝsή³°]3WΥυKo΅Ηb¨#€±™‰ώŸX½:΅½άΡλΧΧμκE½²«Η΄Ÿο1κUπ†£§&ŸͺιZΌΝoo|©ΆuRΫI# sιωT«ς±+ς²ή©“{ΰ‰5K9-.~Ψ"p°_—8\φ<V~»cmoα/]C ₯Εΐ›ΝqΥπΐ ΦΞ₯„&‹KΉ{¨—P]σ4e7ΆΑΠ@Ζ*₯•ލ¬xbΓMΥoίOΉ°w)'”dWF9#އό)§ΧΜ{ω”όU§[Ϋ[x쐬r\ΩG$„žζΊω<=ge©A₯/†₯Ό³!m@»nάq–θ{Wγ ^ΦϊϊΖ=/y΄° ‰ά`ΎίβΗε[Ϊ†‘‘kWιͺ\k—v;•LφI’HΒ°ΰgŸ5š•‘ƒm’ΪΗγ‘€^JE’ܘΛ‚Κ2@'±<Ζ·ΌCmigμ7ή– °]Ϋ±lα,z`Χ%m.›6Ώζ_-ΟφkΘs‡έ ^pIξzf» -SIΡ,οόΏάκpME “Bΰ τΙn:v§+έwΊ2ΎίZC¬ΩΪΛ§E5Μ“ε.KΡŒt‘θ:ƒΕΊ₯…ΕΝύ΄4χၹY c†98ιΝdψnύ4½vΚφefŽ0^ΈοŠΡρ<#½Νφ™¬5ΜσL_μΝlΘT1$όΗƒŠ§§rœRΝ― iVπŠ%ύŽšΝσΜΙ,lψςTtωG\υόkšρI³:‚ύ‹NΈΣ˜ σ­ζΟΚύφηœV†‚š3ιΡ7φΝ֏ͺ##…fYιΐ ϋrΐα@*QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEmu₯ίNYqfωΖ=£—Ζ3œg§½T’Š,+Q@Š( Š( Š( Š( i:₯ξ‘wφ­6ανξ6”συλTθ ςrh’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*{/ψϊOΗωT=—ό}'γό¨ (’€ (’€ (’€ žχώ>ŸπώUO{Oψ*‚Š( Š( Š(  -:}Vυ«™­¬ο2X“s/\V―ŽΌ2žΏ΅[kΑyeyάΫΝ·i(zdž΅ΝWψΛ@_hήԟUΣtΊdq‹kωΔlΫrw'\ƒŸε@EEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPNI'½Q@Q@Q@OeIψ*‚§²€ό•AEPEPEPSήΗΣώΚ ©ογιε@QEQEQEsHΣ/5B+6žκ\μŒ3€IδρΠνώ3(‡PΠmetϋmΆ—7‘ΘFγωώ•ηπM-Ό’H$x€©ˆ¦»³ΉgbΜNI'$Π灴uΧΌY¦ι†0Ν.eƒ±Afη·Σ|i›oβ{ϋ}2–Iε&\±bΌ1Ιυ9ό*†“ͺ^ιjΣnήγiO11^΅Lςrh’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(©μΏγι?εPTφ_ρτŸς (’Š(’Š(’Š*{ίψϊΓωT=οό}?αό¨ (’€ (’€ (’€ (ϋΗπο†ν )©ίI¬41Ν-ΨΑˆΞXMί•p4V―†ΰ./ΩcΨdPE^4»­Zy!²EgŽ3+ΐaF3όθ½ξ¬¬,―'E^0ΐ’ΘνΤRΊ½…u{h’Šc (’€ *Φ‘au§L‘^Δb‘ΠH r§‘βŸi¦\έiχ—°’›{MΎi,ŽθΊάW[”¨’ŠQRΪ[Ιww ΄ fu8Ι'€"’K¦άΕ«5Υ~Φ%νά1Έœc?Z·sαέBΪFYc@–©9 cυκ)s!s#"Š(¦0’Š(’Άνό/ͺ\OcQ!{ΨLπƒ εΞO₯b $ΣΨI§°QEΖQEUέGLΉΣ£΄{₯U[¨DρaΚž‡Ϊ©PΔΒŠ’Φ .a·„,#PN2Iΐ­;ŸκΠκ2Λ°uIΘpp[Η―QI΄΄ŒŠ+§π6£k·cͺκSXήLι¦Θ·«±Ο ιΞήγ­ckΊlΊ>±y§NΚς[JΡ^ƒΤSFŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( §²€ό•ASΩΗ~?Κ€ ’Š(’Š(’Š(©ογιεPTχΏρτ‡ς (’Š(’Š(’Š+Π>6ΘΧi`ψφjσϊυ?Œϊ§6‘±£Ά› Œ(σδaNHΖ3ž¬?:`yezƏωι?φ ƒω½qϊ&¨k—k€Ϋ=ΝΒ‘’P@'“ξ+²ψΫEβM.9k¦— °=ˆ/š@Tπφ™ό# }m€¦―zσ2ʌκ”tωG__Ζ°΅Ι,cΥΰ’ίLšΠ&Σ=€Δ€X@οƒV΄EΒ6ώΧΉ΅%bΒ³+xΖάc·zOjΆΊΝ’ΪLχ?f€Dχ.»L§ΧύfΈ ₯νšw{χ†τ±Ω7d­nΏαύntZΆžΎ ³Έm™VίΝl)Αω³ΦΉΟΗiͺψΒΩΡ#΄™ΟξΪxΟ^ΥgMΊ―Ό1—©^½Œ°\’A 0#¦Φ©ψzβΛJρmΌΝuΎΚχώ[ ΓiνδΤΒ‘šŠwΧΏΛϊά©OžPm«iΫηύllΐώΌΌΎ€±†Ε8†ρη;·)γ9γŸOΒΉ­ϊΕ₯7šlWΑρ΄;•ΩŒϊzJ«"Λ}q$g(ς3)υΥΝΟMΊYN₯ͺR6³΄»ύzt­Υ5»·gnοώ ‹¨η%d―Ωΐ.ψξΚίOρφφq,Pͺ!½Tf΄€tΏ hΧΧdwww@C9U 7SާλIγ94MVκηQ΅Φ NQB[ύ™Ζβxΰ ΜΥον<1‘ΪC.λ‹o;ΝM€mάΩγπ¬b₯R8»ωξΊ3YrΒsjή[>¨—Ζ}₯½έ„ϊlf/­q9ΨOoε[·phV!΄Π_Kα£I.L„9vΑzr2=ύ«žρ6£mym’­€»ήΪΝ"“ε#kŽάŽ θm5]#Yρ|φWΏΪΝ$jΚΈςwςzπ9ό*&¦‘+θŸίεΑΑΝςΫVΏΰ˜rθpίxΎNŠςΓL†7}²]ΛεΖ?w<σ]7Δ[A£x ΒΪ@š;Џ<Βςάξ…²ΔνVοχΏJβό\Aρ>©ωψη]ΝΦ“y­όΠ‘Ίϋ Χ]*Ί†‹ζcΘ'ӟΔWu-aφG]&νάβ[|²#oNzυV&­©[Να―Ϋ[ΛΊκΟΟ26pW’0x«©_ϊσ2Š•Χυάν$πυ–₯”Ύ–ςΜ„I΅ν»qΖXc ν\L«kαο_ΫέY&‘,Ρ"Jε{‚#Ύ?tz†‘‘kWιͺ\k—v;•LφI’HΒ°ΰgΒίΛ׳ɐDΞJ scΆOsNšop¦›άτκΪu½υΌW$=š2Κ°(p•›ΰ‰-’π§‰dΎ„Οn’hƒmήw Ž€œRk·Ώ΅μΊ΄–w‘Z¬MlΦΜϋ™AθÁ“Yz&£kmα]~Ξyvάέy>Jm'vΦ$ςγIGά· ”}Λzυ¨4έKΒ ¬XX%…Δ7?f–8Ψ•a·9ηκ?Z}΄ZN…α6ώϋM]FσPg!dͺ’)ΗοΘόύ«6 FΥ|s§4ΈΌ{α2Η΄ς›@ΞqŽ£Φ΄-.τ]gΓZ~«_>Ÿs`Ο²O$ȌrGOΚ›M+tΈΪi[₯ʞ1¬νξτιτ΄1[j0,Λωdυτι]$£BΡόY§θ‘ιa€†Xsyζ'˜vqЎFGΏ΅s/Υν//,"·΅¦ŸΓΈΑr;γς†οPπ͈mΡ­Ψ>bA₯dψ3J‹Zρ­Α"άΟ΄ΰ8όqŠΔ­ŸjΙ’x‚Φϊeg… W Χid}3š‡'ΛΉ›“εάΨ—RπΖ‘ ν³ι‹§lF6·1³;3†;ϋυκ·„ltρ¦jΪΖ«ΊŠΕP$Їf8#πόκΜ°xOOŠφβ+ΧΤδ•m­Œ/–OBΝΖqU<%©iριϊ¦“¬HπΪί*:)o-”δdOoΚ£μ»\Ÿ²νrΞ³m¦j~֝b,'†ΰ[Ν9e`FAϊΦ₯†='Cπ¦›y{¦&‘w¨—?Ό¨DSŽ1ί‘ωΤΥφ•aၒθχO|άyσ\Μkΐΐ ©mξτ]cΒΪ}Ž©~ϊ}֞ϡΌ–HŒrqŽύ?*5·[\ZΫ­;βΕ!πςΩ†XΒ1c’τΧA'‡¬μ΅(4₯πΤ·–d"M¨mێ2ΓΟjεTMŸ*9[θAρSΖ H–w@―«*ΆGγŠΤ|Oέ―ˆbX$_ν9£‘ #δ sƒω ηoεŽkΩδ€H"g%Ή±Ϋ'Ή¨+n[Ω³nTμΩ΅ΰ›²ψΓF›ΙiΆ]Εϋ΄ϋΝσΗ½u<0ΆzΖ±ͺoK™δΈ2}ŒOώ»Ϋ‘OlώB³ώhڎ£βΛ Λ 2ήΖβ9.$,r}}ιY^;’Όg­Λm –»‘•ΑΘ9cœ{f¨³ ŠνΎθ:f§·¨λθο§iΆήc*9R\δŽG²‘q\S]ŠΥ' g8φ ’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(©μΏγι?εPTφ_ρτŸς (’Š(’Š(’Š*{ίψϊΓωTμμYŽXΠQEQEQEU©΅ι‘0Νys$G£JΕOᚫEKms=¬…ν¦’#£b§™\άΟu {™€™ΐΖι±Η¦MEEQEQEQEQE·mβ­jΦΞ;[{ζŽΧj¨2Χ¬J*eΟI+•Κ °ν#³»v9$œ’}jH.g· šHƒŒ6Ζ+Έzu¨¨ͺ$(’Š(’Š(’Š(’Š(’Š(’Š(’ŠΉ€κ—ΊEίΪ΄Ϋ‡·ΈΪSΜLdΧ­S<œš( Š( Š( Š( Š( Š( Š(  bΉžδŽ€$αΥX€ίQή’’Š»©{o¦\ιΠά:Y\²΄Ρ aΘιŸΚ©QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEPFZ(’Š(’Š(©μΏγι?εPTφ_ρτŸς (’Š(’Š(’Š*φ‰ Ζ«o­pφΆNΨ’d]Ε;σŠ£Et>0π΄ώšΩΔρήιχiζ[^D>Iτ>ήυΟW‘y†σΰwο†M–­²#θ τ3^{@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ νΉ‹η4”Q@Q@Q@OeIψ*‚§²€ό•AEPEPEPVτ:λWΤ­μ,#σ.§m¨Ή'―SU)πΛ$2 !wΗFS‚?τ/=·‡Ό¦ψF ˜ξ/Φsy|Ρͺ9Ο~Ώψθυ―:’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*{/ψϊOΗωT=—ό}'γό¨ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ *φ€_jVχ³Ω[™b³Νƒ±=y<τ=*QZήΠ/|G~φzhˆΜ‘™O› A΄:Ÿ¨  š+½o…&P %‘7+Νpr)GdnͺH4”QW΄ν"ϋR·½žΚάΛœ~lμ ‰λΙη‘ι@h’Š(­― xgPρ,ΣΕ¦ Β‘ŸΝ'γŒΣΛMΦtmbξ{mAPΗw ’au9Ξœ?/z`lxλΓp7ƒ] h„7"­ƒ’!0ΉΗλνPΪΓ ψcΐZF£©h±jΧϊ³Θq,…Dh§)ΰτχηΪ²Ό[.‹m’Gea_λzƒΛΊIΨΊBˆ:œŸ|ϊΦ••‡%²ρmζ―5­Μ"9&ΣώΞΜΝ*cnqŽδ:P$>±Υ>0άθ‹“¦€ξΝgE\νSψΧO/…­5»=ZΦOΙ‘ύž–Κτ9ωΚτWΟ―Ώ½q:/Œ£΅ψ™'ˆη‰Ε¬ΣH^1‚Λβ8?…jκ3xfΞΧPΊΕ:¦¨eF–)ζΔQMμzψqλ@ΎhΆ΅Ζ―-έ’jWv–ανl^M‚f9Ο>ΨΣζ€ρκΨ¦™\xNγ@Υğ+'ϊ‰ΈΙοτΊΦG‚W@‘ξγΧ―n΄λ’Ϊ^Βˆ›œξ Ο§λ]?‹όA¦GΰA Ε―OβΦΉY…Μ±2ˆT€·'σ=OJΥψqiαm}WΓφΘΦZh7 %?ι˜!Έγ8>½kΞ₯‘iš”ςψ“L}BΩ’+&ΦΘηŽΩηέ+«½‡Βš/Š-|).‚·[ŒPΟ|σ0“|€`€?ήjςx€h₯Iο#Q^«w©ψ7Xρ%―ŠnυYνnSΛ–k³³‘Ζq”υ©Τ‹–­kχτ3ÞΣν|uβ6ώά^ΪXΪΟ$jδ‚v•*r;ΰΧC¦iΎΥ.τ+μh[\²•έ•Ϋχ €ΰ Ο|/|ςΪ'ŠlŸΖ"Υ―άΫEiq@©cΉ±΅NΠyΐλ΄|9βΟSπl·7{#Σν'ŽδωN|Ά`ΨzŽ™¬η½u½ΏGϊΞψΦΖ{«Ζ»Ρ―u›ˆγήΦ>YnyŽ@ιλήΊθ6ΝΰΨυ―μ&Π΅D[‚vΘ„d0ίω‘ΰMkN‡ΓZΖ‹{©K€Oxι$w±£7L|§o8γυ?Œϊξ―’ΗπώγF²Φn5;Σx³&‰Χpΐns…ξsœΥΛ›Ϊi}όφό€Λρ>›gkΰ_ ^[Ϋ€wWB:AΥφ°?J›ΕΦVL>Ί†Ζ&Y¬bΈΉ$ Οδϋτόjޝ}αύΑΊf­κo₯έι²9Ž_!€YŽHγ‘νψw¬―ˆzέ†­}ao£οm?N΅KX€qƒ&?‹ŸNΎ•QζrQwλΪϋΔB|7ΣoΓV―i%λ’Ω™›j0 σŒηΦΈΟ ιΆ^-ρμ6eZ|Μ5ΌNNΥUΞΠzςGλW΄mCAΥ< …­jrιsZέ΅ΒJ-ΪepAγ υ5™α]^ΛΒΎ8ŠςΪχN…Ϊ3*ΖQHάς:ηΥ1‹Š’ο―p:m=|3βυΥτλ 4Ων­€Έ΄ΉŽVbα?ΌG\טW¦YίxOΒ±κΧϊ6«6£ywnπ[[ύBϋΔυΖp"ΨΆ±fΊ³Θšy•|φŒe‚gœV”wv½Όΐ₯^Λ¦Mδ6‘­Ιν-Xϊ–UΏLΧ›ψΪ-Lž•εΣBΦlύμry#λ[Σx–Θ|<Σμ"›:€S.ψφ7Μqξχ§V.V±pv㨳ό7£Xcν7r0ϊK΄~•%»ιΧ„υλˆ4;{+‹β)"HΜIf#<ύ?Z«ρ+ZΣ΅½^Θι“ο΄Ž#Ήφ2α™ΙnΠ֎“Ά’κϊxρ)j ωŸa”y{I=;η>Υ¨+ήπGΤβτ;λ]>ρ₯ΎΣβΤ"(TE#•δ|ΩCωΧ |@ΦtΫkϋxnt+{©^Κ6YZVΞν^y¬[ΩZί4ZmιΎΆ1ˆΗ“άm<Χ[⠏xŠ kιu‰,―b΄XZΩ­]χ2ƒΡ‡$ΥM'%/σz4;ΐrZΓαI žΩ<†hƒήC Ž€œTδ^«ΰΔΦτύ=4ϋ˜nΎΝ,q±*ΓnsΟΤ~΅Ÿ‘jv–Ύρ”σmΊ»ς|”ΪNύ¬Iδ Ζ‹}NΡ>]i6/^ψL±ν<¦Π3œc¨υ£•σ7ζΖοΓη6ήρΝΤ\L † Γ‚‹όJσΪξΎj λ«8ΆΆΦ`¬νΡ$۟ϋθώBΉΏθήΥ †€¨%Ϊ$FF ‡8`ΦΆ τIα ψ’ΛL›ΓvΣEuMq;ΚTBγ*:qŒ“žυΜi^΅?Š’Ω\­ΖŒΘ$†PΫ£ Ώhaן—=zχͺ?υ› sΔ±έιsωφβΦ8Λleω†r0ΐ£πϋ^Γ~+²Τnžέ7$‘FNΦ>™π J—Β֚ݞ­k'ƒδΠώΟΛezόεz+ηΧίήΈ‡zn”š&Ώβ nΜ_E¦€b+fbέΙώƒΏSWυΌ3gk¨]GβST2£ Kσb(Η¦φ=@ό8υ¬o‡ή!°Σmum'[΅ΈΈΣ5(Υdϋ8γeΞλϊ `lkpθ:ŸΓ+oKΡβΣο>ή°ΘͺεΒ €φ ƒRk–ψyu%§Žt)"$3^Gη³°Sϊ]ψ?³cψ9*hΦ·–φCRUFΌΐ’s·%Ξ8φ€Φ?Γ=ZΛ‹5Ή’΅Ρl™€Ff¦‘x «Χ―ςβ€9οˆP€8Χ#ˆmO΅Θ@τΙΟυz―kΊƒjΪΥώ ΰ©ΊζΪNvξb@ό:Vξ—…[Α„—χ―ˆ•Ργ°Gθ1ŽΉΟ?¦PψQ#½—ϋ’θ ]…Š­ξͺΪμ@mΤtYΌάt&ΥqόΏ*α>jVšOŠ­o5 |›dW ϋKc*@ΰzšάπ/‰μ4jš~©7–Ψv΅;²]H+ΐ8δΎ΅ΟV-ΆΡ€΅™Kΐ:$֚¦£sc&’Φj‚Db<Ηbz㜠:·βέαuΥƎΪ5δw`άJΊ‘ΓzsΗηYΎ Φ,­l5M/SΈš εB·1)&'Sp9Ηψ{Τ~#m& .;k-ZοU½i7<­Ή"Eτ έO½6₯ΞrV i7¦™sqiΨ'βgLœyν LώfΉ_K·Σ΄- ϋmΕΜώkχ*°§ZΠ‹ΔΦpxΒΡ%'T‚u ›[ύZΚd8ΗP;Υ?ˆΊΥާ­[>/™iy °―Ξ]™Έ zŠQRζΤ¬Xψ‘sgρkˆ$+-―”b=—§L“ωΦ†mα-ρ€k©· Ο°mέ€N¦qϊΧC¨]ψO\Φ!Χoυ }¨Χ nΝ½”ΓŒcό+ŸΠόAk¦xάjΡZω6GJ”QΑ§ςY-R½ΩΉbΎρBκ–6Z:ΨMoΟmp’[oχυΘ¬=ΒΦγΑ~#»š{›c•!κ›Ÿ³kwαŸ&§y₯jRί]]@πΑΘ" ύβzγ²|ͺiΠΨjΪN³+Αi¨":©o-”’ ž₯ φv½΄‚umajίnοΪ7‰~"Y{…Ψ?ZΧDΡό‘j7ZφόJvΉ₯6©αMJλY4€Σ#K˜Ω™‡@Γύϊτίƒq,Ώ΄γ!|ΧάFΨ§KƒτθobΎ}RIQ–ΦΤΒρωLzn3ς+ΐϊΚxŚn§(&(dύζ:μ`UδI­iΫ₯ώdH£άIw­_άLKI,ξμIΟ%QΟβ/…ίK»mbΒh΄=BbφσΖΰΰΆ[iάώ^ΌWZQEQEQEQEQEQEQEQEQEQE=—ό}'γόͺ žΛώ>“ρώTQ@Q@Q@T·H©;*Œ(Ης ¨’Š(’ŠΏͺkϊ€6Q_ΟζΗe·€lUΨƒ ΰ ύO5BŠ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(«Φz΅νž{am>ΛKέΎ|{TοΪr9##ŸJ£E 'ΈQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@>Id” ’Gp‹΅wνƒΠS( Š( ΄toPΠ/ώΩ€\}žηaMϋΎSΤa«:ŠΫρŠ΅Ώ$I¬ίΙr‘Θ›U\(>υŽΘρ€o#΄iŠNBηjeQEQEQEQEQEQEQEQEQEQEQEQEQE6O$Εζ?”[vΜόΉιœzΣ(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€X†Α΅ι]₯•δΌΔ±ϊšmQEQE=—ό}'γόͺ žΛώ>“ρώTQ@Q@Q@O{Oψ*‚§½§ό?•AEPEPEPEu τϋMWΖΦ6š„ =³¬…£n‡±¨—I‡Γ^%΍g’-”ΆΆςMkx%fw(q–ϊδtκ+)ΥQv°_Ew?l4›'Δ·šΥ»ŽΚέ%EάTη-ΐ#¦piu™Ό7­x6{ϋ;+]#W΄™P[Η>Lρœ …<œgΣ·½―½Λ`8Z+Πν!Πό1ΰέ#SΤ΄„Υ―υF‘‚Λ!UγŒΟ#σφ¦x‹AαρW†'Σ`)¦jώDΖΩΙ;78 ΉλŒηB¬―kwόσϊ+Ψ5H<9e΅:ψrՎ“¨%Ί/˜Ψ”?w9ΐϊV,ή±ΈψΏ6…΄zpq+"ΎP} ύN>•1ξΏ―ιη5gM±ΉΤ―‘³±ˆΛs1ڈγΕz̞΅Φlυ[i<#.‰φx[;ΐνσ诞Ήχχoα&§eˆ,,¦ažξ[‚Ρή3Ρ ½θzΏmx·ͺ…Ή‚Kk‰`vK”u=˜WotkΛ-"ΓRZίoςH`IΪpr;WGγ½oKΊ»Τμνό?mkv·N βJ؇98Ζ9†γQΣ4Ο†ήŸRΣS—3¬QK!TQΌξcާ€ΤΣu$”]· <ͺŠμώ"hΦڎ‘s’Cφ{mVΦ;…€’Dlέ²{r?ZξδπŸ§κΆΪ*xBkϋ'Υ ŒsuqŽ€gœJx€ŸpycVώRΈ?­7U+Ώ+ΖΡ]ΟΒέΗTΈΥeΊ΄MBξΦί}­‹Ι°LΗ9ηΫۚoŽ’iΡ$ώΈΠ΅a' ™ςdNύ{ύ?:~ΥsςX"Š*KU s °Θ.hMiΰ~κΕ.c΅E.τεUvΐZεζα•β•Y$F*ΚΓΤν~$κ6fΈ·¬ΆΎQ„φ\"œ}2OηYώ΅„»Ζ±M†.₯ŸΛw`ιœ~΅n*φF1œΉyε΅sW’X―‡ΌRΊ₯…–Žš|Φπ<φΧΘImΏήΧ"±4 >ΦγΑ^$»š{›c•!κ™lQΚR©έLε¨’ΫO΅o‡wν ›ΔΤK/p»γυ­€4MΑš£u£Ε}{reRΚ©ΞIΗRϊεRΫ.Ά<ώ­Ι¦έΗ¦E¨<$YΚζ4—#‡Q޽«€ρ₯Ž›¦κΊF‘§Ϊcywf՘γJηЏλ]-ζ·₯§€l.ΫΓφΟlχn‹jem¨Ψ?089¦£Ίl—UΩ4·<Šιό5§ΪxŸΖ‘Aφqie+؝ͺ« ϋ‘ϊΧ\ώΆΥm58ΒςhώD/-­ΦζωŠτVΟ\Π ΨεUEٞUEv>²Σ'ӟπώUO{Oψ*‚Š( Š( Š( Χΰίό”=7ύΩτ[VΟαo gT°ΤζΊΏ»†H ²hL%!›‘ΑΗ>ž΅ηΪ6©y£jίi³yQδ+ν Œ‚К¦μ]٘ε˜δšΖTΉ€ΫzΥψCW±Σό9β‹[ΙόΉοm’8cμ dd £+“’ŠΡE&ίp=ΖΓή π†—₯kΊ”š]ζ˜Ξ#—ΘiVDc’8θxŸNυˆ|G₯άψ£Γk§4ƒIΡόˆ„)Λͺ°,ΨλΠ}kƒ’‘QW½¦ λž"ξ¬|U[žχRŠβάyl7 <žGCƒR^ψΎΒΫβδž ΄vΉΣ[j3*%L*„€ΐς―:’…F+ϊτ =P“ΓV–·χ1x›RΤΪTakf‚HŠΣ{ ~OΒœZ7‰΄νBuf† C8^»z~u‘E5M$ΣwΈwŒνΌ9,—š–―=έΝΕΑ“μhι΄1$όηƒŠoˆ΅{ΟxcO·Ÿ}域ηΗ±†ΝΝ‘Ι$ΏΣ•‘ Μ‘ΘX°ap3OΚΌ¦ŠNв³Ψ§Γ>!΅ΡΌy±ά•ΑY|ž[Ή'Ήηπ’ ο ψb-jϋGΥdΤo/νδ‚ήίμμžJΏ]ΔυΑς―2’‰RR{Ρψ9t)$Ί\½ΊΣη* ­δ °ΉΞΰ9=ΏZιŸπώTQ@Q@Q@έ"€μͺ0£Κ’©ογιεPPEPEPE₯αέσΔ¬z~š¨Χ2eΫFΙηπ  Ϊ+vΧΒΊ­Ξ΅¨iQΔ‚ςΕI•œΙΏQŠΒ Š( Š( Š( Š( ŠΠΆ/.tΗΏ‰Ϋ$ΒΕ€;Ξ01ψŠUΣnt½FKΕUΈ€`G ΟЊW[ λbsWΣnt›ω,οUVxΐ,9­S¦υο¨QV΅ ­:dŠφ#Ž‚Eƒ•=•¬χΧq[ZΖdžC΅2.· ­Θh§ΟΑ4‘J»dŠ2ϊpE2…Q@Q@Q@Q@Q@Q@U«; «ΘneΆˆΙ²y’@ΪΎ΄lh’Š(’Š(©¬­gΎ»ŠΪΦ3$ς¨€“ψΣ'‰ΰšH₯]²FΕ}8"\eQ@Š΄φI§G~ρi#˜ΦLŒ½j­ΈQEnθήΤυ‹EΈ±HZ2ΕFιUNG±€Ϊ[ƒijΜ**[»y-.梘,.ΡΈ8 ΰ*·m€^\ι)ΆI„‹wœ`cρξ‚θΟ’­κΪuΖ“¨Kez‘g€lŽ@#Ÿ‘R„ξ ά(’ŠQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE A$ιE:Fί#0“Ϊ›@Q@Q@OeIψ*‚§²€ό•AEPEPEPSήΗΣώΚ ©ογιε@QEQEQE=οό}?αόͺ žχώ>ŸπώUQEQEέό’‡c\εΠ p•Φό-Υμt?Ϊ_j“ω¨’}ŒΨ%('­zn›κοό$°³UΠ'mθ'Œ’Έώ_‘―4ψuiaquzχš-φ΅s`ΫΪΐ§Λ,š:ž½λ£ψmγ=3KπΖ―¦k7&ύγY“6w© Ώ(8δΟ­g|>Χ4Θ|/¬θwΪ€Ί5Εδ‰$WΡ£7L|§o qνχ04|yαλWπJk‡@:£ Θ‚KpNΩŽ©‘­'FπλΑ Ψ]hpK%ώφΉn•pΚΉγОr~•ΟkϊΦ‡Γ»Λ\ΉΥ/Ϊρf2O‹Ό`gnμαF:œζXx·DŠΓrI{„΄ΡΞsε?Ι)\ιΟ=Ητ‰γ› ­ΒΊ¦•§Γ§Ιͺ$±Ό³r:¨<ύkΌ“ΒZv«ZθiΰΩoτζ—«HΫχ0ε†; σι^m―λV“ψCΒ–SξΎΣΎΠgMŒ<²+/$`η³]†«¬xgΔZœZέNJ5 1Yέi±€›‹Œ+qΤψP›ψ³J]ΔΊŽšŽ^;y™R½F}πEhψŸTπυφ‹€Α’ι2Y_@€\ΜΔbCžη<δδβ±5‹ˆn΅K©νDΒέδ&13ο}½·7sŠΫρ=―† Ρt™4 뛍EΣ7qΚ€8η°ΑΞF<~eΜQE·e­-·†¦Σ<·2=\€~”Οκ‰­xŽγPŽ6&dΒ±ΙPΏ±ιc :“ΠK•'ryRw=OΔ—Z1ρΠΣοt•Ή’ι’Ž[‡‚…€ ΄€ {σ\TΒΟ@ρ6‘Ε’jρ;Δ‘ΚεqΘΑΘοŽ?½β ^Ζοβ :Όϋμ–xΙ±‡ ·qΑμ{V7Š.‘Ύρ‘ujϋΰ–fdl‘τ<ΦP¬ΌŒαYy§Žυm:ήϊή+ ‰ΝeiX8JΖψs}i³gk.Χ2O”Ή.CF1Π‡‘όκmvγAΧΰΆ½—V’Ξς+U‰­šΩŸs(=p2kœπέϊizν•μΚΝ2`½qίF>ε…ϋή-Υ,..oν Ρ ·Έ ΚΘK1ΙΗNkAWFΌ#’j:Tw——PCHUHy8κ@ΐZΚρ<#½Νφ™¬5ΜσL_μΝlΘT1$όΗƒŠή–ίLΊπ/‡!Υ/^Δ“1Ža}ώTλ‘Ο΅Ι-vIoψφ1ΦςL‚Dc“ŒwιωRόEh@πϋYξ 1nλ·Ά}ρBΏ7ή%~m|ΘόC¦YΫ|FŠΒ,ΜφθbΖ.Gγ“D ­χΔi΄ ΎU’ΜωT=A8–+V}CΓZ–ΉmβF[{ˆφI-—ΜZDΖ0έ1ΐλV™β4·ρ»kRΔήL“;2HF~c#ς‘s5§oΔ3ZvόN™τ+}NΧQ…ό7&•δBςΫ\ξo˜―ElυΝ`xL΄Τ&ΤβΩon ‡|&Α+}}ΈόκkΣ‘[[έΝ½}~Ξ€[Ϋ*Ό{Iώσ V?†—H‘ξVΊΈ²—ΫάΔ nω“Ϊ„Ÿ+Ÿ+/ψ¬Z­”k/‡ζ5όΟ•"~=ώ•ΉΰΝRΐθZΊ"ΦφY™ΌΓώ‘Ξ}3νTΏM/]²½™Y£†@Μ;β΄|Oˆοs}¦k s<Σϋ3[2 I?1ΰβ₯Εsά—§sBΪ-'BπΖ›}¦£y¨3²HUQγŒwδ~~ΥSΕ–6n‘₯_ΨΫζΖςΉϋ3± s’™λгiw’λ>ΣτνZωτϋ›}’y&Etc’8θz~UCΖz­ž‘qeo¦ok+u·ά`Ύ:œ~U1Ώ7ή(ί›ο:‹½cM_Ω\Ά…nΦοvΘΆΖVΪ§ζΟZβνΚΔQ΄ΆsGe$™6ΦΏ;γusΧ&Ά4»Ν"Βqι:₯όš|°\™’A Jιυ¨<'¨ιϊ‹ Ο;OdΔ·+8p§‘Χ‘.TνΈEr§mΞ—ϋΫS²Τ’—Γ2ι"kk’[$―@ΩκOψΧΰΏω4―ϊψOη]>—¨hϊTš‹ΛβB[‹i#MΠΘŒg9ΛΛ­qšκιΊΝ•γ©d‚UvQΤ€yΕNΝS³Dž'‘—V―ΉΏτ3Vl΅₯ΆπΤΪg–ζGΊK€ΰπ―x– ζKνFΓZwΈšC*Ϊ΅«ƒ–l‘Ώ§s\΅\m$‹€•Ν_j‰­kΧZ„q΄i1\+‘… ύ+*Šξ?°΄«…‰­_Dοͺί\˜­ς¨8'ώλ~b­++"’²²8z(’…Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@OeIψ*‚§²€ό•AEPEPEPSήΗΣώΚ ©ογιε@QEQEQE=οό}?αόͺ žχώ>ŸπώUQEQEQEQEQEQEQEQEQEQEQEnγQΊΈ°΅²š]ΦΦ»Ό”ΪέΗ'œdσλU(’Β°AΘ8"€ϋDίσΦOϋθΤtP1Y‹1,I'Ή4”Q@Q@[ΎΤn―Ω.εσΪ! ChPt©E‚Š( aEPEPEP£²£> βŸηΝ=dΎGEQEQEQEQEQEvχT½½³³΅ΊΈy-ν¬œb0zγςJŠ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(§Ν·Ξ“Λϋ›Žί₯2€ (’€ (’€ žΛώ>“ρώUOeIψ*‚Š( Š( Š( §½§ό?•ASήΗΣώΚ€ ’Š(’Š(’Š({ίψϊΓωT=οό}?αόͺ (’Š(’Š+GΓΪ5ζΏͺΕ§iʍs(b‘Ϋhΰyϊ Ξηΰ§ό”m7ύΙΏτ[P7’θΪΝέ塊#Kk Ο(gBΗ―QYUν^ πνŽ•¨ψ†κΧΔŒ―§\+[Αχ§'žƒόk–ψ_αΛmJΗYΥτΧΥZΕQmμQŠω²6zγ°γυ¦ŸWeqπί_ƒI›Qt΄6Πΐn¬κH@»JήρΧ†ΰo.Ί4Π5nD3[%$B8`;sΧΪ³ΎΘ#ΖΏφ›ωΰ(§Ϋ€ΣΖdΖ½£]_hώ=‡Γνα˜%KΆŠ9g20ς‹ΰ‹Ψt$η<ŸJ@x₯³γ-.=Εž†ήb¨[ή£?«ή'Υ<=}’ι0hΊL–WΠ 31ΰgΉΟ998 bŠ(  m"ςηL{ψ‘M²L ,XΌγˆ’χG»³ΦF—p¨·eΡ1Όc-ŒsΣΈ«vZΫxjm3Λs#έ%ΐpxΗιPψ«TMk^ΊΤ#£IŠαXδŒ(_ιRœBrΉͺ<,"ΆΪ:Ÿ΄.?`jΊ|ϊ]τ–—aΙ‚v0aΘΟQυ‹J’o­ΧΤ_ΜVo‚m ΎρE…΅άbX$f ‡‘ωI©Rjντ%I«·ΠΔ’»ΛwπΝννώ‘.Ÿ ‚F$ήΌδ1u8ηŽzγπ¬?Αi5ΕΛ\ι—zœΘ™†ή; υr9₯>}/bΉτ½Ž~Šξ|U€@|0š§φCi‰p!xrvΊ‘ΐσΦ‘ΆJΠ|1¦ίή驨ήj δ,UcE8γωŸ΅Ρ5 ½’jθγ&keΞ‘~φwΚ©:H δdr*ο‰N‘%μθa£ŠXΓKgχOέA=Ew%πλ_xΪοPΤ•‘Ρ %–cΡΒ¨ωGΉ4œνkƒ©k\ςκ+MM?YρŒΌIg§M6j؁ΐΞzœŸzθΌCmigμ7ή– °]Ϋ±lα,z`Σs³΅ΞΞΦ<ϊŠ(«4-YΨ]^Cs-΄FHν“Μ”‚Υυͺ @Mz/ƒ5K‘jκ4ˆ[ΩffσϊF9τΟ΅qϊ΅ύ₯ύΝ»Yi±X*πΛ–έΟ^j›mXΞ2m΅bΆ―¦άι7ςYήͺ¬ρ€Xr29Z§^©βK­ψθiχΊJάΙtΡG-ΓΘABΐΪ@=ωWMπμ=}ΩΝ¬s8$˜’‚@ύ₯—WbK«ΎΗ+Ez[θVϊ£ ψnM+Θ…εΆΉάί1^ŠΩλšσJ¨ΝH¨ΝH(’»€4}'Β:&‘s€Ηyype;•RžN:0Φ‰JΓ”ΉNŠκΆcηΦΜγθϋEΡb΅π͍ϊho¬ή^3–ŽΨtΝcψσGƒJΎ΄’ΆŠξ1·rI‰»―<ϊSUvQ7c™’½θšε΅”š,RΗ4q΄΄¬<°ά|£Ϋ}λŠρ­­ž·wŸ2Oh―ϋ§G 2:γ8ό(ŒωΊ3ζθgQEu±ΣΖ™«k¬κ+@n*˜ΰdΓσͺ“εWŸ*ΉΛΥέ#KΌΦ/Ÿ›1±©$ΧE¬ΫišŸ…΅§X‹ αΈσDŽYXF~£υ­_>„4ΝTƚˆtηϋY%0W7—οιš‡SέΊDJ₯£tŽ?\Π―tCΎ;;vH¦3Σκ+.΅5ΖјΓύ†—Κ9σ~ΤTϊcΛ«ν©q½΅.imΞ­’«O&v‚ΐ'Ÿ §iΊ]Φ₯5ΔV¨¬πDΣI– ΈΙύkoαόŽΆI?τ[WAαΦΒγYš ^ΞυΪΒu1CΚ89ϊqΖ’sεm:œ­£Ρ<5¨λVΝ=ŠΒΘ―εςͺœΰ‡κ*}WΒΆ—g-Υβ@±EΨ™I tόk'H­—ύwOύVΗΔ?ω΅?χΧAο.k ΉsX}‚΅›λXg·ŽŽT/ο”žFj†΅αϋνΘϋjΔ<βBl?Lztκ+_αόŒ^²*ε"ZŸQBrζi‚rζiCψ_R@·…œ μYΣwεšζn!’ήy!9cb¬Œ0A«Σ|S O?[RώΡ±³Z&/$α]B¨Ο…q~8Τ-υO_]YΠ1UVΖ7a@ΟιSNnDΣ›‘…EΥψ&ΟNŸNΧ.uK_΄₯€+"β§9<:gf΄”ΉUΝ%.Us”’ΊΝNMTπΜΧvΆΆϊn₯m*¨%Ϝ‡ N3ϊ{Φ–‹’Εkα›τΠίYΌΌg, ± 8θ;š—RΛR]K-QΐΡ]GŽ4XtέFΙ¬ΰ{hο!Y>Ο!$Δη‚Όσι[χ°x{Oρ%Ÿ‡ŸHY@x’K£+.Ψ#Žγ‘‘ονG΄VM΄VMqEvΪN“c7ΔΙτι-‘¬–YTDs€’+;ΑV·Ϊ†§ά+*Ee,ˆπ°#υ£nsTW[ΰm Ϋ]NώβΚM@Ϊ*­Qˆσ‰λŽp1VΌS’Δ|4Ί―φKιqΞ"– €pΐœρωΠκ+ΨN’Rε8Š+½πΦ•o’_Ϊθι¬ί<Μ’ΖϏ%GO”uΟ_ΖΉύ~[΅¨$·¦³TΪΧs’`r@ξP§wd5;»#1μ.“NŽύβ"G1¬™,;zΥZτ«½cM_Ω\Ά…nΦοvΘΆΖVΪ§ζΟZδtx¬uΫGδcρ₯Ά›hQ›iΆŒ:+Π|Cmigμ7ή– °]Ϋ±lα,z`ןUF\Ϊ•s+…h[i—:cίĊm’abΐηόEgΦέ–΄Άή›LςάΘχIpqϊS•ϊ―ΠΟΥ΄λ'P–ΚυBΟ7Ω€G?B*₯jψ«TMk^ΊΤ#£IŠαXδŒ(_ιYTFφΤq½΅ (’˜ΒŠ( Š( Š( Š( Š( Š( Š( Š( §²€ό•ASΩΗ~?Κ€ ’Š(’Š(’Š(©ογιεPTχΏρτ‡ς (’Š(’Š(’Šžχώ>ŸπώUO{Oψ*‚€ (’€ (’€ κώκΦZ,―υIΌ‹HΦ@lfΖQ€αA=HRŠν>λz~“­λ·…Η• Ν…Δ16ΖmΞΜ₯Gγ8=x©>kϊ}–›¬θΪΕάφ6Ϊ‚‘Žξ$Βκsœ/8<~^υΓΡ@―‹eΡm΄Hμ¬5ΛύoPywI;HQ@³“οŸZ‹αΆ·¦ιWZ­¦΄ςCc©Y=«Ν–1ηΎ=3ϊWEtzξ› ΨΛfΪΌΪ£Ό˜‘M£ΓεŽ0rέkΤΌi…cψΊž±«ΛgucεHφΎC8œ¨ …Xtμφ― V*Α”ΰƒ‘Wu½^ϋ\ΤdΎΥ'σξœΟ±W €,ψ»U]sΔΊŽ₯Žβb觨^ƒ>ψ΄R:{Φ5<ͺΝw'•YεBEšώζHΞQεfSκ 5ΣxGT±‹BΤτ»»ι4ΩnY].‘ tώ·ŸYFŠSV E5c³Υ΅.?Λ₯Ϊκs_]₯”Ό‘²ξqςη η=iΆ—z6³α­?NΥoίNΊ°g '’dWF9=;τό«Ž’—³Vܟf­Ή³βYtƒyZl-αŒ#ΜΩfξΨ=?Jιυ[―'ž)ήλDΈaš6 ΄©P…=ΑφηŸZσϊ(pOqΊiξlyz4>$(σΛs£o?Όˆp€qΑΘ8ΟβΊΛ-SIΡ,οόΏάκpME “Bΰ τΙn:v―;’‰C›v‡6μ(’Š²Ξ“Αš•Ÿφ¦§#Γo}laσ‘Kl>Έ«ΫiΦwP3R7ρ—!’ΪsΣ­fQSΛ­ΙεΦη[β ^Ζοβ :Όϋμ–xΙ±‡ ·qΑμ{RCβ k/ˆ3jρšΝ¦rJ‚ FdυΟα\Ή­ς³V·•ŽΚτθVΦχsG―__³©φΚ―ΌΗ¨ΖΡETcaΖ6 θu­FΦηΒz”2ξΉ΅σΌδΪFέΝ‘Ι“ρώTQ@Q@Q@O{Oψ*‚§½§ό?•AEPEPEP»³±f9cIZ Ztϊ¬1λW3[Xήd±&ζ^0>Έ­_xe<5jΆΧ‚ςΚςΉ·›nPτΘ=hš’Š(’Š(’»έ#Βή ²Χ5ύNϊΧν3<*°DeIφΟA\M’Ϋ½τ w#ΗjdQ+ Λ*g’3@Q]ΏŠό1’ΩxJΣ\Πu »¨gΊϋ6'Œ'EbN1žΥΔPEfΖζξ+‰-β.–ιζJA*ϊΠΪZ±€ήˆ­EP ’ŠΏ^ΟK²½k‹yθ#GΛ/ΤRrI€ϊE΄ΪθfΡEΔQEWWΰ Ϋkjwϊ₯ρ±τδWšDMμKgΓή°ξ­mε֚ΣH‘η·’a»Κ6³‚p3ι@(­{ŸκΠκ2Λ°uIΘpp[Η―QY&žΒM=‚Š( aEiμ.“NŽύβ"G1¬™,;zΠ+•h«šF›s«_Ηgd‘§“;A`“ΙφQV υ_ _ ”QE («ΊŽ™s§GhχJͺ·P‰βΓ•=΅ΚTVέΏ…υK‰μbŠ$/{ žd Ιτ¬CΑ€š{iμQE1…V…Ά‘ys¦=όH¦Ω&,ήqΔPέ„έ·3θ«zΆq€κΩ^¨YγΖΰ#ηθET‘;‚w (’…UΥΣ.[H}L*ύ‘&ς n݌γCEμ+Ψ₯EP0’Άνό/ͺ\OcQ!{ΨLπƒ εΞO₯TΠaΣ¦ΥaZΉšΦΐξσ%‰72πqυΕ$ΣΨI§±ŸEtΎ:πΚxjώΥm―ε•δ so6έ€‘ι‘ώzΧ5LaEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPζf‘G@Δ e+±wf=IΝ%QEQE=—ό}'γόͺ žΛώ>“ρώTQ@Q@Q@O{Oψ*‚§½§ό?•AEPEPEP^»γ-|E£xkR}WMBι‘Ζ-―η³mΙܝr•yv‘¦^k„V:l =ΤΉΩ g“Ιγ 5ΫόfQ‘ ΪΚιφΫm.(n#CŒ3Ησύ(Ο(­ίhλ―x³MΣ₯ aš\Κb‚ΝΟn¦ψ-6ίΔχφϊ$e, “ΚLΉbΕxc“κsψP%Q@­Ιπύ„%ΩλΟλΤΣBΤ΅οƒΪE£έKμΚ€ .\g’=kΜm­εΊΊŠΪ/<#DY‰ΐwzŸό‘-#ώΒ― ½cxN΅Ώšύη·[Ιΰ‡t¬ϋυφώ΅Σψ―JΎΡ~ιVz»[ά¨ΜQˆ'+ˆπςιnσ¦©s=€Έ ˆΑ`ί r{VUΣtέΏZ )«ώ%ο e΄eΠ¦―χπW>[§γίι[>Τ¬Ž‹ͺ¨‘ žeo0ώsιŸj£―κ–kα₯ΗͺK«\ΔΎs£(@θ sλ5ŸαBΚΣϋFΧR‘α‚φάΓζͺξΨ}p+‘ΑΞ‹Ίz?>y¦‘YY­W—ό1Ÿ¬^ΪήΙYιρΨͺ‚QΛnχζΊύa΄ Y·³“GŽXζŽ6šF•†ΐά|£Ϋ―γ\~±mck4k¦κnŒYό–‹iτΑλWόi¨[jZΒΟe/™…vΌΟQZΚξ)^Φ}όΎfqŸ"“v½Χo2υ°όK0"Ώ°ΙEσ2€p7Lώ•£βh¬dπYXΗfχ/(uF-χN'ιXd6·‹υίΩ ζ_,Ɏ8ΰs]uθπνΞ…§iΏπϋHήgΨδ;χ6zvΕ$‘»k}Φ}΄άtύψΟdžΫouί]Š΅Σ›CΦ―u+_΄}—ΚdŠœ’xΘθ ΐ4ν^;QπͺjΦ6Kcκln>κl“ΐ3ΕsρΪk{uΆ‰όΒ°©$'ξیš·`š½­ao₯‹Ym ’x.D…Ά{λ‘ΕdxJσOΡ|gς^o°„ΘΗ”Γp(@;y#“Mπ~§i§κœ·’ωi5œ±!ΪNYˆΐΰ{Q(κΪς Eέ΅ΩxFΗOf­¬j°¨¬UAΈ¨vc’?Ξ§Φm΄ΝOΒƒZΣ¬E„πά y’G,¬Θ#?QϊΥo jZ|z~©€λ<6·Κ„NŠ[Λe9“Ϋς©υ«ν*ΓΓEΡξžω₯ΈσζΈ1˜Χ€?AMί›ϊΨnόίΦΔπΗ€θ~Σo/tΔΤ.υηχ’ŠqΖ;ς?:oΔs ]Ϊ[s§‘Œ1Ι ΨΒ‹{½XπΆŸcͺ_ΎŸu§³νo%€#œcΏOΚͺxγRΣ΅€¦•+<6Φ‹ €#±ΟSJQO›_1E>m|ΛV.ŠΪϋDœΫΚWO΄kv˜FGι\uI “Z¨₯±ͺŠŽΑEv4=+ΓgIΣ¬cν/³,·²$ θ9 \E2‚Άμ΅₯ΆπΤΪg–ζGΊK€ΰπ±(€ΥχIξkψ›Q]wΔW°ΖΡ­Γ UsΘΒ…ώ•Υjα½WMηH[ˆ£·m#o€;€€ηΌύ£«―U9ίj7Χ5Xυ«νBX‚›‹ 1vP0qπ¬δ­eΠΞJΦ] Oθφ:·Œ–ΒžM8Θμ―‚¬Θ ![K‘x‘u++=%lf‚žήt’Ϋ{0>Ή¬][΄ό`Ί”Ν€‘€…NJ‘wξ3šΨΆΊπο‡ΣQ»υonnax`ƒΘdςƒz“Χ₯+ί©2½ϊ™ώ³ΣΣJΥυRΫνid¨±ΐX…fcŽOΞ΄΅+›+Ώ‡Mah,Υ΅σ!W,‘φF{Ž+/Β:†œΊn«€λ5½½ς‘YΥ le9ŸOΚ¬κ—š-―‚δtΫηΊΈϋX™™‘dςΰ‘žƒ δηŠ$Ÿ7Μ$Ÿ7Μ»’θ±ZψfΖύ47Φo/ΛΗlH:ζ±όy£Α₯_ZIiΫEw˜ΫΉ$Δέמ}*iΪ—†μtλέRm*κɜ,‹:ȌsΞήγόυ¬?Λ`χ¨š\χ7FLΣ±&Fξ@=΅Ώ6£ω΅6¬<]΅φ‰9·”ŸhΦμ1 ŒΈκ*摦^k„V:l =ΤΉΩ g“Ιγ 5ͺŠ[(¨μzŒ΄ρα­Iυ]7I ¦GΆΏœFΝ·'ruΘ9ώUδUθ”C¨h6²Ί}ΆΫKŠˆΠδ# ρόJζ| £½βΝ7N”1†is(Š 7=Έ¨£ ŠΫρ€ZmΏ‰οντHΚXA'”™rŊπΗ'Τηπ¬J@QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE=—ό}'γόͺ žΛώ>“ρώTQ@Q@Q@O{Oψ*‚•ݝ‹1ΛJ(’€ (’€ (’€ΫΚ$‚GŠAΡ‘Š‘ψŠk»;–v,Δδ’rM%sIΥ/t‹Ώ΅i·oq΄§˜˜Θ―Z¦y94Q@Q@­υΫx„vχ—1F:*JΚΰ VGdutb§!ΑΦ’Š±syt.&@rI }y5^Š(’Š(’Š(’Š(’Š(SHΧυ=")#Σ|”vάΓbΆOβ TΤ/u–Έ½™ζ™Έ,ޞžΥZŠ•N*\ΙjSœšεoAΡI$2,‘;G"τe8#ρ’YiI]žF9fc’OΉ¦ΡTHQEQEQEQEQEQES‘‘α•$Œνt`Κ}ιM’€-jš…ή«}-ζ‘;Οu.7ΘύNθU’Š(’Š(’Š(’Š(’Š(’Š)πM-Ό’H$x€©ˆ¦Q@ ξΞ坋19$œ“VτRχH»ϋV›pφχJy‰Œ€zυͺtPy94QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE=—ό}'γόͺ žΛώ>“ρώTQ@Q@Q@^Ρ!±ΈΥmβΥΦΙΫL‹Έ ΑΑΗ~qTh ‡ΖŸΓ“[8ž;έ>ν<ΛkΘ‡Ι ώ‡ΫήΉκτ/0ή|ύπΙ²ΥΆD}@Oώ†kΟh’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(d Αr‚@lc#Φ’Š(’Š(’Š(©μΏγι?εPTφ_ρτŸς (’Š(’Š(’Š*ή‘§]jϊ•½…„~eΤν΅ dυκj₯>d†A$.ρΈθΚpGγ@…γ§ΆπχƒtίΑsΕϊΞo/š#•G €™οΧ΅ηTQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@OeIψ*‚§²€ό•AEPEPEPEPEPEPEPEPEPEPE=…Ζ‘y ₯”/5ΜΜ#AΛ‚Šμ΅†ώ#΄ΩogΆ†H‘¦Xeьg$†k’³€έ]ΑnˆΊΖΞrq’{ ŠŠΨρfƒ'†υ‡ΣζΊ·ΊeE2ΚσΫΨΦ=QEQEQEQEQEQEQEQEQEQEUέ?J½Τ-ο&³€Λ€~lμΧ“όͺ•@QEQZQθ—²iφ—¨Š`ΊŸμΡΓ%ύνCinm΅?†u(.΅+ybA&Ÿ–œ`)ŒzπjhοjBΞ+ˆ-Ψ‘}σ6ŽίZ\ΚΧžΖeωγ0Ν$e•Š1RTδΗ¬I§]Η¦E¨<$YΚζ4“#‡Q޽©άEJ*ξ₯έkŒVV*­q&J†`£€Iηθ*›)V*zƒƒEϊ”T–ΠKuqρ΄“JΑd±<+§ρ†,ό3gΌϊ’\k¬κg΅‰~Hp[»gŸJε(’Š(’Š(’ΊhΪn»u5•φ¨4λ·Ϊ-Σtr9<«έ°sτUνsI»Ρ5[?PΛΈ…Ά‘ΨŽΔz‚9F€ )QK0QԜ ΨΥ|5©ιz₯Ÿy ­ΕΞΡΩm£Ÿ­&Π,cQVu+)΄λωμξ€YαbŽΘλU©ξEPEnθ>Υu»fΉ²…Ω[o›+„R}zΥ gI½Ρ―šΣQ„Γ0€Θ!‡¨#¨₯Μ›΅ΗgΉFŠ(¦ ’Š(’Š(’Š(’Š(’―Ε€έΛ£Mͺ")³†QΆαΗγΣ‘ΝΊMέΞ“w©F«φKR«#–8τ‚Ε (’˜Q@ΧΗα,Ό+ύ³β @Y=ΜNΦa3$δ”ŸEΞ?ΪΉ (’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š 8R°ˆSΈΑυ€ Š( Š( §²€ό•ASΩΗ~?Κ€ ’Š(’Š(’Š(›α₯Ά₯γ*ώžΪWpρΏFΒ1ώ`W3]ÝJΣGρ¦™¨ΛδΪBΜd}₯±”`8ž€Pik/‚υ-OVπύΖ“k₯E•mυ).pΖE8–ΐλŒγΆ+'α‡-΅+gV»Σ_UkE·±F+ζΘΩλŽΓΦΈ­jhξu‹ωαmΡK<ŽŒd$k¬ψy―ιφZn³£ksΨΫj †;ΈT“ ©ΞpΌΰρω{ΣcΗ^ΌΊθΠ[@Τ!ΉΝl”‘α€νΞ?_jŸΑZ πZ­—‡‘ρ§-Γ$ρI.<„ΖίτΟΝν\ο‹eΡm΄Hμ¬5ΛύoPywI;HQ@³“οŸZ›Β«αΙ4x|E{ανq‰€UvIWή‚T»h£–s#(Ύ½‡BNsΙτGβ_ˆ,5Ν[FNΈ’χμP,2^Θ›vΘηίρ5άx/ Ηρ!u=cW–ΞκΗΚ‘ν|†q9P °ιΨν@N“ΰΫKŠσxzWsa ΞΝΞΖp\ώC?ZΨΣ—Βή3Ζ™§θ1ι“ΪΫIqiu„— ΗΜ0:δuΟιXZ_ Άψ£/ˆε…ΕœΣ8d,#a΄¨ΰΦΥ•ƒό$šΎ£’jΣj7—–ο΅·ΩΩ!ρχ‰ΰΰψ”›πξΗF x›SΦτυ½>KΖ»Š’I?.G@Nφ§ψ’ΫEΦώ'ˆ΄­.=*ξΪπZΝLJ8#9ϊςΏ­exgY°²π'Štλ™φ^^ωgcϋX“Θ‰–zΝ„ /΄wŸŒΊŠΞ‘lnSjŒξΖ:ƒΖs@G‚΄;Aΰ8΅[/Cβ-N[†Iβ’\y3Œ/ΎιŸ›ΪΈGa>»ZV‘u£Ξκ©=₯ΐΐY κΉη—΅<*Ύ“G—ΔWΎΧˆšEWd•sΖ6γc©λž(ψβ[-[R•s%λiφλήΛƝΑΞpF{gρ4ήIα-;NΥ­t4πl·ϊsKU€mϋ˜rΓ†yΗτ―>Σf·πΕ&3‡žΖβHς/±”€~ 05ΤjΊΗ†|E©Ε­άx£PΣ‘ Φ›IΈ°Β°ΰg@?…q:.«’ΕγGΌΥ,₯ΊΡ₯wSνζHͺxV'Ή~΄ΦάhΧφcWΧό―Γ©[ά#΅Τ +L±·Μw#g=ωΐ>λ‡πΆ±§i-ru=ίV…Ψ&§—ŒηGε]ΎuαIͺizμϊ₯ΜΦο ½§ΩΩ1»}ˆΗQντ5ΕxkMΠ―’΅Νy΄§V56ράεzP§ΕΝ2ΛIρ€φΊmΊ[[,Q°:Wš½πςζΗR’ΛE_ Yκ7™c%ά³2αwY€€υ«.<+β λΝfΗΔlמR¬vŸb”*1χΘTήΤ|/eΰW±_+WΎΘ½œYΛ+„Ɂ€1ŽA=OΰΟ|G:%ϊΦΟΒΦΡCo3F~I$άrG· gΪ½O iΪv­k‘§ƒeΏΣ˜"\j­#oάΓ–μ3Ξ?₯yΏk₯iwΆ­αύ`κŠ>vΫ4;­z«¬xgΔZœZέNJ5 1Yέi±€›‹Œ+qΤψP›ψ³J]ΔΊŽšŽ^;y™R½F}πEdΥΝbβ­Rκ{Q0·y ŒLϋίomΝάβ©ζ5₯Ά­i6₯nnlγ•ZhAΑuΟ"―ψΖϋIΤuΩn4 ±±eP!lœrp 隑£%”š­’j²Ι ƒJ’y#eLςG¨ώ5Ζ0hΆΪμΡψjζ[8(ΪςΨδ ‘ψPŽ’ήtΪΙβ#}·χ¦ΨΓεη?Γ»œck/Δ‡@3Aκb-§Νϋ~ΜηΆέΎ΅―€|CΧ΄6 7΅π.Τίn¬qœςOΦ²ΌOβ]GΔ³A.¨Π—…J§—N Ο8  Zκώιφš―¬m5{gY Fέ#b?Q\₯vΏδ‘ιΏξΛ’Ϊ³ͺνNMvoI‡Γ^%΍g’-”ΆΆςMkx%fw(q–ϊδtκ+#αΝ†“q€ψ–σZ²qΩ[€¨»ŠœεΈtΞΝjιχώπΨΦuK Nk«ϋΈd‚ &”ΒXςΊsιλ\ο„5{?Þ(΅ΌŸΛžφΩ#v1ήΐΆF@ΐκ:β°IΈ»^ΪΑφ³7†υ―Οgek€jφ“* xηɞ3§“Œϊvχ«6θ~πn‘©κZBjΧϊ£HΑeͺƈqΖη‘ωϋWžW Xίψ{Δτ­wR“KΌΣΔrω *ȌrGsιήpεIkk^`"ΠtΈ|Uα‰τΨ išΏ‘1ΆrNΝΞ.zγωΧAͺAαΛ(5©ΧΓ–¬tA-Ρ|ΖΔ‘ψ;½qΞΉΏψKΉρG†ΧNi“£ω €S—U`Y±Χ ϊԺ爴»«GΦη½Τ’Έ·[ θ'‘ΗΠΰΦ|³|·ΏτΘ ž"ΡtΝ?β„ϊcΫ]>˜²«}žΡwΘCFbŒϊœ}+­„zΟYΣυh'π|ΊΫΫΌφ—e›q+Ρ_=IτηΏΦ²ΧΕϊ<o5Ώ5₯Σ'ŒD· e”‹Έ)ΰ‚:Tϊ.­ hsκ?ŠξυYnm%Š=πJKcΞrΗΧ η4₯Οe½μ»_xΗ‡4Ϋ;Ÿψ¦φ{t{«S“!κ›ŸZ-4Ϋ7ψ[}¨΄o“RXVnα6)ΗζM?ΐzΎ—­hΊμ[Ωκq …ό§BH$qΘόͺΗ‰5-Mπd~Π―_Qy.ΎΥqtb1BΰΠ~^υ«r淚ϋ€θ>λZkxk]UΠmΥ­4ΰnJπCqΖpzzΧ―jZΝέͺιš<_πŽBΑΙ#δqŠΤψ{«ιΆΫ:Μ[ΪκV†ίΟD/εŸ\OSY:ν—¦^ΫΆ…«MήΞmšŒ ֈΕF£ίρΠoaπ¦‹β‹_ K ­Φγ3ί<Μ$ί  χ‡CίΪΌλΕZbθή#ΤtψάΌvσ2#₯{gί―B»Τό¬x’ΧΕ7z¬φ·)εΛ5‡ΩΩ‹H€c 8ΗΚ?ϊΥη~&ΤΆΌA¨„1­Δ¬κ§¨χΖ)QζΎ·Ϋ[χ2½+ΐ0‹ ΨΔάύ“ZŽ’μΟτ5βΈ|+…£Ώ‡'“RdlW €p3œŒœτγsαˆlt}+[Šώo.Y=°ΨΝΉΒΈΗŽ£­kY7 †ϊ›ΊμζOλΊ±ϋΧφ RΔ†ώU‡πφ]'PΤ,t{νήyd2nΊiγ…f~¦κ~ ±Ÿα½†›ΩΤ•Υ&cpŠΞAΞ0zŽύι| ήoμ5kέtΗsrφΏdΰ•eΖρ‘ί=++Z »έ£“-Ά«ΉαYaŠ|˜‰ΐe χΕz=ζ·₯―€¬.›ΓφΝlχl‹jem¨Ψ?6q\O‰-4ˆXK€λPy]‹§Ωž-ƒ―VλZΪMψ>-VΤ$Σ₯·Ή3€‚•\xΐϊšΉ₯$Ÿω“.‰~άCuρΪkke΅…Δ…aV$'ξیšΉ§¦ƒβυ:ΫI[I­`’{{‘!g}§oAΗ½cx:χMΠόoΔ—»τθLŠ.|¦BΫ‚G&™ΰ­VΟMΤυI―fς£žΚh£;Knf#νJQwmvCO£.ό‰eψ€‡ ζΈβ6Εs:νΔ—zΥύΔΔ΄’ΞξĜςXΥολ)αiΊœ ˜‘“χ˜λ±V?‘&΅ώ"ψ]τ»ΆΦ,&ŠλCΤ&/oέ3QκΪΝ…ΗΓ=IŠ}Ϊ…΅Τ²KΖT–ΑΞ0zކΉ(dhfIc8t`Κ}Ε{€žΣ΄νZΧCOΛ§0DΈΥZFίΉ‡,1ΨgœJαt?ΫMρUό=tΝ%ŒH[œ3’©eŽη€qο]«¬xgΔZœZέNJ5 1Yέi±€›‹Œ+qΤψW ψ–=Ηi­YΓ<–«+²o‘£`W–=[?Z`vή“Β~'½Χ ƒΓvφ’YΩΝ%»¬ŒDŠΈŠΰΐΰώ&Ό€Ž΅ξ“ÍqβIό=a©ΔeΣζ–i―U"~ν1κryώνywƒΌ-yβ‹χ†Υ£Šή=Μς0U‰ λοΠυ¨£ψΌj„^ώAώ‘u€BςSΧϊšσΪμ~)kVzΏˆb‹J3OΣνΞ.rΓۜ~Sΐ0ψnmRuρtΕh!&"›°_#ΠOLβν·ό|Eώψώuμή,EΥu˜Κ€n4}NΫ8λδΚ#?ϊς―s _±˜Ϋ¬Ώ#0δx'ίθPψ³M‹βMυΪ7θχq¬o'–ίΒ‹ƒ·α—;Φ5bΫΊθ\Ω”e"Χ>+]Ψά5Γ΄›N UΗγŒVΓψ~ίU΅Τ  I€yΌΆ·[›ζ+Ρ[=s\μ>#΅±ψ6³i¬^gΙU ”`F@8=σψTχ­ [[^Oˆ/υ‘HΆ΅A$e ώϋ T5-=JΪ‘ψcF΅Υ΄ ϋ:•Υγ†gη- .H?Žjφ½£i–ΡxŽϊήΥ>ΛφkW³α ½Hό‰ͺ?΅ϋΟWP”£:,ΆΓkΚ‘°8ui5­~Ζλΐ:m„“¨‚‰p›Xa#ί·œ`ύαΠΣj\ώBV±6—>™β YhwZŠι—–R;ΖΣέMΈ“ΙμyυΦW‹ Φm΅++zA0‚5KwP6΄YΐΓ ιߚ΅a†u]ΞΫ³€j6ωY$qž§ρώMCγMbΚρ΄»=%δ–ΧM€D³ΘΈ29Η§ͺ?‚{·Σaπ£κΪl7³ E-ǘHΒ²ŒτϊŸΖ­h>"νu K=ΦΔ±Άš;ƒε±Ψ́ΟQΣ5₯κΆPx5μe›mΡΤ’γfΦ? P Ξ1Ϋ§ZV–ΪMŽθάρ6•€‘βH¬΄τΆ—Hž“%œHΨ η°Ο…Qπ­΅―φ*Νoα›½fω€"G‘H…ΡHκzv©5{MΈΆρ’CsΉ΅ mΪΨyl<ΐ­–νΖ*EΥ4­SΒϊM€šδϊ<Ά*RX’'a.Hω†άsυυ4.n[?Χ°is3β&m₯jRY[½€wvλ3[9$ΔέΧόϋΧC·†΄-~ΦΒ] cž8ΪyšVXn>QνΧ>υΟxϋUΣυ?μuξ$-­.© υΟSτ¨> jvšΆΌ·:|ήl"ή4έ΄― r0@ͺQrI?16•μ]Σ,τKoˆ2iςy7ΊLΞaŠ@ϋ‚ξ© $—?Z“Aπό~£β ΅¨ΦΊLl6?I Β~ΤW¬Qƒ)!Θ#¨5ι_5‚ήνΪ! ξ’‘έ݁Τα@\ύHΗiΙ4Oq+Zζ?€ΫτΟhΗ“siηΔ½·Ζr1ωΚ“R?ΩΏ 4ΛQςΛ©\½ΛŽεWεϋ)¬ꉣxšΖφv+ΉYN Β0 œΈΞ ΉγύVΗQΤ­b$ί§YΫ$₯sܜ ό(q|φιΈ_έ7΄- +O Xjθ ­ήή³–ŽΨPΟωιXώ=Π`Σu;cΪΗ} Ιφy &'ryΗOΦiΪ¦›ͺx_OΣo΅yτ‹»p’¬lλ*1ΞΣΤ{ϊ{Φ‰nl?΄ ώΗΈΊΉŠPgΉbLΤAνJ<άڍΪΗY«?†<=¬¦…u£-ΔQͺ-ΝγΘή`,άτ+„Τ"΅]Vh΄ωZ[?4ˆ€`A+ž2zξu+ kΪΌzεώ₯-»2‘Έ±03e`0γ?ΒΈMVkyυ+™l`ϋ=«91Eœν^Βͺ—Ε#Άψγ+½Έβkh£{ŒZσϊυΨΒi€ΓβΝHδ’ PΊ±pAΛ`υΟΰ+ΛλRŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( §²€ό•ASΩΗ~?Κ€ ’Š(’Š(’Š(’Š–ι'eQ…ώTQ@Q@ ¬Uƒ)Α"λz½φΉ¨Ι}ͺOηέ8Ÿb@(₯Q’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ »£j—š6‘φ›7‘uBΎΠΨΘ πA ͺTPΥτ`+±wfc–c’i(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ ›'’bσΚ-»f~\τΞ=i”PEPR[O%­ΜW6ΩbpθΨΞƒΝGEu·ΌO«XΛgͺΙ%΄£k’Ζ‰Έzͺ=«šYdHή5‘Φ7Ζε±Σ#½2Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’ŠjΪ₯ζ―wφFo:m‘m €:U:(·P (’€ (’€ (’€²DXΕ#‘e*ΫN2P}©”Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@OeIψ*‚§²€ό•AEPEPEPSήΗΣώΚ ©ογιε@QEQEQEQ]_Βύ>ΣUρ΅¦‘Οlλ!hΫ‘ΔlGκ+₯aπΧ‰F³£Yθ‹e-­Ό“Zή YΚeΎΉ:ŠΚuT]¬—Ρ]ΟΓ› &γIρ-ζ΅d.γ²·IQw9Λpιœš]fo λ^ žώΞΚΧHΥν&TρΟ“•‹7„,n>/Ν‘F­œJΘ‡/”h?S₯Lk§{―λϊ`yΝYΣlnu+θlμb2άΜv’γψρ^³'†mu›=VΪOΛ’}ž–Ξπ;|Εz+η}ύλ›ψI©ΩAβ )΄˜g»–ΰ΄wŒδ4Co@:‡σ£Ϋ^-Εj€αn`’ΪβX']’ΔεOfUΫέςΛH°Τ§E·Ϋό’vœŽΥΡψο[ξυ;;ΫZέ­Σƒx’±f!ΞN1Žk‘ΈΤtΝ3α·„§Τ΄΄ΤεΜλRΘUo;˜γ©ΰυ4έI%mΘ*’»?ˆš5…Ά£€\θύžΫU΅Žα`$‘7lžάΦ»Ή<+§ιϊ­ΆŠžšώΐ„IυC#άέ\c η‡^)'ά’½ΒΎ²β΄šτBκΞ'™BΙό@)*N;τͺ?΄Λ-KXΦ"Ύ·I£‡OžXΥΏ…ΤλMΥJοΚΰq΄Wsπ·G±Υ.5Yn­P»΅·ίkbςl1Ξyφΐφζ›γdštI?…4-XIΓ&|™Ώ^OΟ΅\ό–ˆ’ŠΑ΄ͺ΄πΏud—1ΪΖΎbοHžUWaμυbx€‚gŠdd–6*ΚΓΤτ»δ‡Εϊ₯Ά³ανZ;mb4]ΆWk^~Bx#πΗ―zΕπ£κ<ΐ&Ϊ_΄Fκ.φGjΡΕlŒ#QΩΉt8Ί+«πiͺj±ή@²€V3JΏ…\Φ―xNίL‡Βo¨ίi°ήΜ5·a# Κ3Σκ•—*‰5θώ'΄…[Ϋ¨υ Fγm³7Xγ^€}H#ρΉzΪ+Ψ§ xKVΧ-šζΚκΫ|Ω\"“θ3Φ³u.σGΎ{=F λΞ Θ#±uΣψ₯Ϊ?‡ή‰#=ΩGBC όxώtοˆ g΄π€²ςI§GΉSΣ―ζiΈ«Ι½vwό&Šυ]a|3¦xΚ=θ1H— I)‘‡–_m‘λžMqΧKeα―j6χκVΡ3F‘ΚεqΘ δwΖ‡ujσlŒmOM»Σ'Hoα0Θθ$U$©θxͺ•κ?΅­6ΧP·†ηA·Ί•μ£e•₯`Pΰ;W?πγJ³Τ§Τ€Ή΅[λ›x7ΫΩ΄›­Ξyφΐόθqχ¬…―“šHγ«cΒ:Ύ$ρ ¦• «NNd#;TΔγΏρZώ0‹aΝαΙτmL?sεHŸ₯tΏ |4°kΊnΆ52fŽ)%ϋoΉ9†έ5-YšF\Κηβϋ NΤVίBΏžωšIcΩ‡ŒQXUcQ—ΟΤ.¦cσ%gΨzI8ͺτŠ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€rI=蒊(’Š(’Š*{/ψϊOΗωT=—ό}'γό¨ (’€ (’€ (’€ žχώ>ŸπώUO{Oψ*‚Š( Š( Š( Χΰίό”=7ύΩτ[VΟαo gT°ΤζΊΏ»†H ²hL%!›‘ΑΗ>ž΅ηΪ6©y£jίi³yQδ+ν Œ‚К¦μ]٘ε˜δšΖTΉ€ΫzΥψCW±Σό9β‹[ΙόΉοm’8cμ dd £+“’ŠΡE&ίp=ΖΓή π†—₯kΊ”š]ζ˜Ξ#—ΘiVDc’8θxŸNυˆ|G₯άψ£Γk§4ƒIΡόˆ„)Λͺ°,ΨλΠ}kƒ’‘QW½¦ λž"ξ¬|U[žχRŠβάyl7 <žGCƒR^ψΎΒΫβδž ΄vΉΣ[j3*%L*„€ΐς―:’…F+ϊτ =P“ΓV–·χ1x›RΤΪTakf‚HŠΣ{ ~OΒœZ7‰΄νBuf† C8^»z~u‘E5M$ΣwΈwŒνΌ9,—š–―=έΝΕΑ“μhι΄1$όηƒŠoˆ΅{ΟxcO·Ÿ}域ηΗ±†ΝΝ‘Ι$ΏΣ•‘ Μ‘ΘX°ap3OΚΌ¦ŠNв³Ψ§Γ>!΅ΡΌy±ά•ΑY|ž[Ή'Ήηπ’ ο ψb-jϋGΥdΤo/νδ‚ήίμμžJΏ]ΔυΑς―2’‰RR{Ρψ9t)$Ί\½ΊΣη* ­δ °ΉΞΰ9=ΏZι›u§»μ—Ι2,ˆΗ$qΠτ‡zΟρ¦―e©juΎ•½¬l Khδq‚ψ•ΛΠ ΤQΝ₯SIάυίΗαΤρηΫυMJK[‹Coδ³ ˆ© :v{Wšx“Q][^ΎΏE(“ΚYTυΆ ƒVΤυkηΌΤ%σ\Ο΄.p08‚ͺS”*tω»ΤοŸπώUO{Oψ*‚€ (’€ (’€ ξώΙC±rθΈJλ~κφ:Œν/΅Iό‹TI>Ζl„Φ€=7Mu wώXΩͺθ‰ΆτΖQ\/Θך|:΄°ΈΊ½{ΝϋZΉŠ0mν`Sε–9ζFO^υΡό6ρž™₯ψcWΣ5›ƒ~ρ¬Ι›;Τ†_”rηΦ³Ύkšd>Φt;νR]βςD’+θΡ›¦>S·8φϋƘ><πυ«ψ%5Γ Q†δA%Έ'lˆG ԏΘΦΞ“£xuΰΠl.΄8%’Fϋ\·ΚΈe\ρθO9?Jη΅ύkC‹αέΞ‰e\κ—νx³'ŠEή03·vp£ ΞsW,<[’EαΉ$½ΒZhg9ςŸδ”τηžγzΔρΝ……֏α]SJΣαΣδΥXή‰ΩΉT~΅ήIα-;NΥ­t4πl·ϊsKU€mϋ˜rΓ†yΗτ―6Χυ«Iό!α K)χ_iίh3¦ΖYi—’0sŽΩΓUΦ<3β-N-nγΕ†˜¬ˆn΄ΨMΕ€Ζ‡8κό(ΝόY₯.‰β]GMG/ΌΜˆΗ©^£>ψ"΄|OͺxzϋE`Ρt™,― @.fb1!ΐΟsžrrqXšΕΔ7Z₯Τφ’anς™χΎήΫ›ΉΕmψžΧΓhΊLšυΝΖ’ι›ΈεRœsΨ`η#ž?2€ζ(’ŠΫ²Φ–ΫΓSiž[™ι.ƒΐ?Jg‰uDΦΌGq¨GF“2aXδŒ(_ιXτ±Iθ₯Κ“Ή<©;ž§βK­ψθiχΊJάΙtΡG-ΓΘABΐΪ@=ω*ag x›P‚βΙ5 xβHεrΈδ`δwǍ^ρ―cwρNή}φK<dΨΓ…ΫΈΰŒφ=«ΕPίx‡PΊ΅}πK326Θϊk(FΦ^Fp¬ΌŽΣΗzΆo}oΖ‰ďfŒ²΄¬ œ₯c|9Ύ΄‡Y³΅—NŠk™'Κ\—!£θCΠώu6»q λπ[^Λ«IgyͺΔΦΝlΟΉ”Œ85Ξxnύ4½vΚφefŽ0^ΈοŠ#rŒ}ƍoκ–7φΠhΠ[ά †εd%Žδγ§5 «£i^Ρ5 *;ΛΛƒ(!€*€<œu `­exž ήζϋLΦζy¦/φfΆd*’~cΑΕoKo¦]xÐꗯbI˜Η0ˆΘ>*@υΘηΪ‡d–ˆ;$·ό{ž8Σμ­fΣο4ȌΧφΛ8‡9ΨOP?Jζk§ρuυ«}¦Xh»ζ‚Φ΅‰Ψm26qœΓ­EWˆθ/ύφΏγWZ+™—Z+™x& οX[]Ζ%‚F`Θz”šθmίΓ7··ϊDΊ|6 CzσΕΤΰž9λΒ±|;² ―ΩΫ2δn+”8ϋΉυ‹¨H³_άΙΚ<¬Κ}A&“\\:_hΠ^ΪκwχRjΡPEjŒG˜μO\sŠ΅β#α₯Υ²_H»Žq°dνu#†τηΞ³ό!ͺΩΫYjzf₯<Ά°^ͺΈI12œŽ8 Δ ₯Α¦Ηogͺ]jwlϋžVά‘ͺϊ=O½KΏ8š|ζΧ†΄«ψEώΧGMfωζd–6|y*:|£zώ5Ξx—μMͺF,τλ9Ά5ΌΩω_Ύά󊽠¦ŒϊtMύ³u£κˆΔHαY–EΟیvκi|q«Ϊj·ΪzΩΜχBΪ‰ξ€M¦fΟ\ύfšΏ0+σ¬žΣ|\š9Ρ#‘'hIL¬<²Ψhό―&°4ο ΫΟγχΡ€v6‘Κω9ωŠ($ ώBΊΗ 'Νφ₯¨Ιm=©ή%›Ν €0ιΨcΪΉKΗŽί[xŸμςJε}ΰŒόΐΑ¨…ν§b!v΄νψš–K‘x‘u++=%lf‚žήt’Ϋ{0>Ήͺ΅Σ@Χo΅KAr-<¦EάTδ“ΖG@N«ΆΧ^πϊj7z^£-νΝΜ/ y žPoRz㍒j6ΆήΧμη—mΝΧ“δ¦wmbO `~5VvvΏB¬μν~…ύj 3Rπ‚k aq ΟΩ₯Ž6%XmΞyϊΦψkJ·„Q/νttΦožfIcgΗ’£§Κ:η―γXpj6«ΰ;9₯Εγί –=§”ΪsŒu΅>‚š3ιΡ7φΝ֏ͺ##…fY%[I5HΓNŸN¨YmζΟΚώΩηέIαλ;-J )|5-ε™“jΫv㌰Η@3ΪΉOλ6ΊξŸφήδΪ@±΅Τ‰΄Κΐη8?η“[†‘‘kWιͺ\k—v;•LφI’HΒ°ΰgμ…+΄ΏΰœnΏ`4ΝjφΙX²Α+"±κFxΟΎ*…iΕc>·«\G€[Ν6K:£Έ.=I=O"―ΒβϊK}―ψΦΌΙhΩ―2Z6Zπ™i¨M¨=Ε²ήάAψ-M‚Vϊϋqωӟύz½©xj Ÿι‘iΙ·LΤQ.1—ύEeψΧT²ΎΈ±ΆΩžΞΖέ`I`ΉN>•Ρhz»Yό8ΈΉ™? w΄³”υύζ ΗΣ“ψTΎeΙ|Κ)œέΦ‘₯Ϊψšϊh΄Έ.tπLq@\ͺŒ7η―8?tώ;Υ΄λ{λx4H.${4e•₯`Pΰ=+Νλ΅Χn4~ kΩui,ο"΅XšΩ­™χ2ƒΡ‡&ͺQI‘Κ)4ΚώΡ ½΅Τοξ,€Τ ’ ŠΥ1؞ΈηkΕ:,GΓKͺdΎ‘wβ)`ΙΪκG ιϝgψCU³Ά²ΤτΝJym`½T+q’be9qώˆKƒMŽήΟTΊΤξΩχ<­Ή#Uτ zŸzNόΰΣη6Ό5₯[Β(—φΊ:k7Ο3$±³γΙQΣεsΧρkΕ&Μκ φ-:γN`ƒΞ·›?+χ۞qZ hΟ§DίΫ7Z>¨ŒDŽ™d\ρΈΗn¦“Ηš½¦«ubΆs=ΠΆ·=Τ‰΄ΜήΈ<ϊΝ8ߜ#~rΥ‡‹’ΆΎΡ'6ς•Σνέ€#ζ$‘ϊWE@$֊)lh’£°Q]ΏΔΝJπΩtλίϋKμΛ-μ…Ιˆ:CΔWL ’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(©μΏγι?εPTφ_ρτŸς (’Š(’Š(’Š*{ίψϊΓωT=οό}?αό¨ (’€ (’€ (’€'½§ό?•ASήΗΣώΚ  Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ­άj7WΆSKΊΪΧw’›@ΫΈδσŒž}j₯XVH9TŸh›ώzΙ}ŽŠ+1f%‰$χ&’Š(’Š( GQEkTΤ.΅KΧ»Ώ—ΝΈp>ΠΉΐΐΰ: «EZΒ΅‚Š( aEPEP£²£> βŸηΝ=dΎGEQEQEQEδ‘Πa”{Sh ΄2α€r= L’Š*δΪ•άΪm½„“f-a@Α=N@ΙκzΥ:(°¬QE (’€ (’€ t2<2€‘ŒO‘)΄P­SP»Υo₯ΌΤ'yξ₯Ζω©ΐΐύͺ΄Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ƒƒΦŠ(’Š(’Š*{/ψϊOΗωT=—ό}'γό¨ (’€ (’€ (’€ žχώ>ŸπώUO{Oψ*‚Š( Š( Š(  ογιεPTχΏρτ‡ς¨(’Š(’Š(­hךώ«§*5Μ‘Š‡m£€Iηθ+:»Ÿ‚ŸςQ΄ίχ&Ρm@ή‹ _k7w–Φ(-¬/<‘œ½EeW΅x/ΓΆ:V£β«_Xj2Ύp­oή@Jœžz cρ[α‡-΅+gV»Σ_UkE·±F+ζΘΩλŽΓΦ˜}]•ΗΓ}~ &mEΠΫCΈr³©!ξ<}+{Η^ΌΊθΠ[@Τ!ΉΝl”‘α€νΞ?_jΞψ] Ψoδh€’ŸnOaX?φu|!£ψφ·†`•.Ϊ(εœΘΓΚ/€/aΠ“œς})β”Vό΄ΈτOjzt ZyŠ‘n»zŒώ―xŸTπυφ‹€Α’ι2Y_@€\ΜΔbCžη<δδβ€9Š(’€4-΄‹Λ1οβE6Ι0€±`σŒ ~"‹έξΟY]Β’έ—DΖρŒΆ1ΟNβ­ΩkKmα©΄Ο-̏t—Αΰ₯Cβ­Q5­zλPŽ6&+…c’0‘₯JrΉ Κζ¨πΈT°ŠΫhκ~ΠΈώuͺισιwZ]„& ΨΑ‡#=GΦΊ-+ώIΎ·_Q1YΎ ΄‚ϋΕΧq‰`‘˜2‡ε&₯I«·Π•&ίCŠο-ίΓ7··ϊDΊ|6 CzσΕΤΰž9λΒ°ό€Χ-s¦]κs"fxTμ'ΥΘδ”ωτ½Šηφ9ϊ+ΉρV‘πΒjŸΩ €^%ΐ…αΙΪκFCΟZ†Ϊ=+AπΖ›{¦¦£y¨3²ΉUγŒwδ~~Τ{DΦ‚φ‰«£ŒšΉ¬i—:EϋΩί*€θ 0#‘‘Θ«Ύ%:D—°O‘†Ž)c , Ÿέ?uυάx—Γ­}γk½CRV‡F‚4–YG £εδs΅₯­sΛ¨­ύ54ύgΖ0Fρ%ž4Ψ«c 9κp}λ’ρ ΅₯œW°ίxR[H2ΑwnΕ°„±ιƒMΞΞΦ;;Xσκ(’¬Π΅gauy ΜΆΡ#ΆO2RWΦͺ€Iu5θΎ Υ,…«¨ oe™›Μ?ιηΣ>ΥΗκΧφ—χ6νe¦Ε`«Γ,n[w=y¨Rm΅c8ɢՊھ›s€ίΙgzͺ³Ζ`ΘΘδ}jz§‰.΄cγ‘§ήι+s%ΣE·! hχζΉ]7Γ°\xυτgg6±Μΰ~bŠ τ”j]]Š5.ϋ­ιo‘[κvΊŒ/αΉ4―"–Ϊηs|Εz+gkΝ*£5"£5 ’Šο|5₯[Β(—φΊ:k7Ο3$±³γΙQΣεsΧρ’RεW₯ΚpU©a£Iy£^κ+smZ NψvΟ ©χυ+˜žΛKΌK}g«}K8Y‘ Ή]δδmΞxιP§~†j₯ϊ±πv³yeάpFJ»Ι*©aλ‚kž―Jρ«ψlO¦F=UŸμ1ω>ILωΖsίq^kE99+°§'%vvλLΉΆΣlο¦Uχ{Ό’vœ;U*τ tΛ}KΐΎ:•΅€ΟΑŸ?>_·Σ­9K–Γ”Ήlr跐K§Η*"΅ϊ#ΑσŒΗ>•²<,"ΆΪ:Ÿ΄.?XψΐΊQΚ“$z|j$OΊΰq‘μj-+ώIΎ·_Q1QΝ'Ρχυ(φšhƒΪit:’»C΅Oˆ§IΊAqk’Χώ ˆΞ? ·§Η‘kκΊ}”-d΅·’h.D…Άρσ}r8‘ΤHDŽŠλ<¦Zjjql··CΎ F“`•ΎΎά~tΟ‹U²eπόΪF’‚Ής€OΗΏŽ{”|ώχ)ΛQ]φ‹’Εkα›τΠίYΌΌg, ± 8θ;šΗρ揕}i%€mάcnδ“w^yτ‘TMΨJ’nΗ3Ezuή•e¦Cf-Ό3ύ«§4*ς^F坲9 •ηζ{9³IίyςΦOΌ«Ψz#>m‡ σlAW΄.λVžHl‘YγŒΚΐ°QŒ:£[ΥΧE½ΈγiΆο zΖιU+ΫAΚφΠ«{₯έYXY^NŠ Ό a!$.3‘Ϋ¨ͺ5±«jλ}’hφ++Ψ¬ŠΜO ΉόcΡΫQΖφΤ(’Šc (’€ (’€ (’€ (’€ (’€ (’€Ϋs=Ξi(’€ (’€ (’€ žΛώ>“ρώUOeIψ*‚Š( Š( Š( §½§ό?•ASήΗΣώΚ€ ’Š(’Š(’Š({ίψϊΓωT=οό}?αόͺ (’Š(’Š+«ψ_«Yh~4²ΏΥ&ς-#YI±›F…υ"ΉJ(΄ψ­ιϊN·άjT76ΔΫ·;2•Œΰυβ€ψy―ιφZn³£ksΨΫj †;ΈT“ ©ΞpΌΰρω{ΧEvΎ-—EΆΡ#²°Χ/υ½Aεέ$μ]!DFΞOΎ}j/†Ϊή›₯]jΆšΣΙ Ž₯dφ―4jXǞψτΟι\}ΡλΊnƒc-›hZσjŽςbE6–8ΑΛu―Rρ€^βBκzΖ―-Υ•#Ϊω βr 2aΣ°#ΪΌ-X«S‚E]Φυ{νsQ’ϋTŸΟΊp>Ε\€08PJ³βνUuΟκ:”hR;‰‹’ž‘z ϋΰ Πρ=―† Ρt™4 뛍EΣ7qΚ€8η°ΑΞF<~g˜’€ (’€ (’€:?Q΅‹Α:₯„’βξyγxγΪ~`ΙΞ1Uό{o§xšΖξςO.ή&%ίi8ωHθ9οXΤTς«5ܞUf»–5 kϋ™#9G•™O¨$ΧMαRΖ- Sξο€ΣeΉetΊD-ΣψNήύfΉ(qMX%ՎΟVΤtΈό.—k©Ν}tn–RςFΛΈmΗ˞€{œυ¦Ϊ]θΪΟ†΄ύ;UΏ}:κΑœ$žI‘]δτοΣς:Š^Ν[r}šΆζΟ‰e δhQ°·†03d›»`τύ+§ΤΥΐΡSμτ΅ΙφzZζύ…Ά‡oβx#ΊΤ ΐΏ3Νδ²n8ΞέΌœgΆ|NΪ±u5γψ›,¨V u°*(*Ϋλ\=8]ήγp»½ΞŸΒ­΅–§¦jSΛkκ‘[ˆΤ“)Θΰsπ¨ό@Ϊ\lvφz₯Φ§vΟΉεmΙ― SΤϋΧ9E>Mnšά)QŠ:ΊυS‘IEQg‘άίψgSΧ-όAs¨Νo:μ’[/!˜³ Γ1ΐλWίjk—‘J ε.υ°όͺ1‚‰‚‰ΠψΣQ΅Τ΄Χ²—ΜXlb…Ξ0γvG#άW=E²±QVV θuFΦηΒZ ”2ξΉ΅3yΙ΄»›#œ`ρι\υ5{W±Πψ³Q΅ΏΆΠ_1­¬#†Q΄:ŽG?…~£k‚uK %ΕάσΖρΗ΄όΐ“œbΉκ)r+X\ŠΦ θ|I¨Ϊήhš½΄»ε΅’eΪFHγ‘Οα\υΪ»Lm]¦t:&£kmα]~Ξyvάέy>Jm'vΦ$ςγ\υP• ZαESΠψλQ΅Υ5΅Έ±—Ν„AnΪW9UΌ#«&‹β [ιUž$%\/]€qωηπ¬z*yW/)<«—”μ―N…mow4zυυϋ:‘olͺρν'ϋΜzXώ]"GΈMZκβΚ\os,»δOjΕ’… -q(ik·ˆ΅{%π’ι1κΣk&q/$l’% -Ι뚷-Ύ™uΰ_Cͺ^½‰&cΒ# ϋό©Χ#Ÿjσκ·q¨έ\XZΩM.λk]ήJmnγ“Ξ2yυ©φ{Y“μφ³6Όe«YέέiΠi,Οk§ΐ°€ΈήG|Β·oό3©λ–ώ ΉΤf·vI-—ΜYΠ a‡ΰυ«Ο(§μΥ¬?f­c­ΠuϋQρλΜmνεbJ–* >Υ[Αϊ¦Ÿ¨jrήKε€ΦrΔ‡i9f#ν\έωά΅α₯${„Υ,₯ΐ6χ1ΑΎ@δφ­ΟjφKαEcΥ¦Φ.Lβ_:HΩDJ@[“Χ5ΔΡC…έΑΒξηg§κZv₯α»:χT›JΊ²g "ΖΞ²#σ·Έ=kΔ’Ψ=μi¦Mssh¦ŽdnδΠ{VE(Yά,ξwϊLϊέ΅ξŸβ;Ϋt*ςYŸπώUO{Oψ*‚Š( Š( Š( ½wΖZψ‹FπΦ€ϊ›€…Σ#Œ[_Ξ#fΫ“Ή:δ*ςν#LΌΦ5¬tΨ{©s²0@Ξ'“Η@k·ψΜ’CA΅•ΣνΆΪ\PάF‡!gηϊPžQ[ΎΡΧ^ρf›§JΓ4Ή”Ε›žάMρ€ZmΏ‰οντHΚXA'”™rŊπΗ'Τηπ  J(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ žΛώ>“ρώUOeIψ*‚Š( Š( Š( §½§ό?•ASήΗΣώΚ€ ’Š(’Š(’Š(πM-Ό’H$x€©ˆ¦»³ΉgbΜNI'$Q@4RχH»ϋV›pφχJy‰Œ€zυͺg““EQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE0*Δ0 Ž=¨§Jν,―#ύζ%ΤΣh’Š(’Š(©μΏγι?εPTφ_ρτŸς (’Š(’Š(’Š*{ίψϊΓωT=οό}?αό¨ (’€ (’€ (’€ οΌqαoψnΠšτšΓCΡΒΡ ŒŒε€τέωW^ρ·ώF»OϋΓ³S”πάEΕϋ'ˆ.ξ--<²UΰMμ_#˜ΝiόCπν―†΅›k[ ‰ žΥ.CΚo˜·}rυθ?δ?€Ψ*ζτ€σϊ+·πφ™ό# }m€¦―zσ2ʌκ”tωG__Ζ°΅Ι,cΥΰ’ίLšΠ&Σ=€Δ€X@οƒXFΊœœRΫΠΪTb€ήώ¦sΨά₯„w­²9dΘΑaΫΦ«W‘έjΪzψ2Ξα΄XΊe[5°§ζΟZη<;¦«γ d{DŽg?Έ Hiγ={TΒΌœe)FΦΏΰ\θEJ1Œ―{~'?O‚34ΡΖT»Λ“ΤŸJμΰή^_iRXΓbˆCxσΫ”ρœρΟ§α\֍}ib›Ν6+ΰψΪΚμΖ}=₯\jΉ'h»όˆ•%―%o˜έoM}'P{I&†fPψ›#š‘]Žμ­τΟogΕ ’‹ΠeFkH 'KπΆ}q¦Gwwpd3•Ru8κq€>΅*½©ΒV»—ω\§Fσ”odΏΞΗEt~0Σν-ξμ'Σc0Α}n“ˆ‰ΞΒ{*έ»ƒB°ρ ¦‚ϊX— Ird!ΛΆγΣ‘‘ονCΔ«&“w»ϋ·‡wi΄­oΗcΟλ΅±π¦—ƒaΧuύR[fΌσΞbή\GΜ{ ŠΞ—C†ϋΕχϊtW–d1»ν’ξ_.0ϋΉηšιΎ"Ϊ ΐ^Ρή„yζ–ηt-–'j·½ϊVρ—4T»˜J<­Η€iwZ΄ςCdŠΟfV€ΒŒgωΡ{₯έYXY^NŠ Ό a!$.3‘Ϋ¨«^ΥΧE½ΈγiΆο zΖιF­«­φ‰£Ψ¬l―b²+1<6ζcπ―.o#;Λ›ΘΗ’½*ΗMъiV“ιq»έιŸi’`μ2©ΣLΉΊΣο/aE6φ›|X7;Χwγ½[N·Ύ·ŠγD‚βG³FYZVΞ³|%΄^ρ,—Π™νΤ@Νm»ΞけΠŠ\ο—šΒU/5Ž&Šμ5¨4έKΒ ¬XX%…Δ7?f–8Ψ•a·9ηκ?Z}΄ZN…α6ώϋM]FσPg!dͺ’)ΗοΘόύͺΉτΨ|ϊlq•-₯Ό—wpΫB–gXΠŒ’p+‘ρŽ•gow§O₯‘ŠΫQfX˜ηΛ'¨Ο§Jι%βΝ?DK $2Γ›Ο0‰<Γ΄ƒŽ„r2=ύ©:šh¦š#—MΉ‹V:kͺύ¬J!ΫΈcq8Ζ~΅nηΓΊ…΄:Œ²Ζ,RrΖ1λΤUΏ\ O^\H†χΜΐο†ΝO¨ψž;»_Δ°HΏΪsG"GΘηςο'kδμΡΛQEfEPέΏ…υK‰μbŠ$/{ žd Ιτ¬CΑΖΓΕΡ[_h“›yJιφnΐσΘύ+'ΑšTZ׈νlξ 6ζ}§€ ΗγŒT)5w#5&δbQ]ŒΊ—†5omŸL];b1΅Ή™Ω˜t 1ίί―UΌ#c§3VΦ5X ΤV* άT;1ΐΙ‡ηG>—h|ϊ]£—’ΊύfΫLΤό(5­:ΔXO ΐ·š$rΚΐŒ‚3υ­K zN‡αM6ςχLMBοQ.y!Pˆ§cΏ#σ£ŸΘ\ϊlsŽ™s§GhχJͺ·P‰βΓ•=΅RΣβΕ!πςΩ†XΒ1c’τΧA'‡¬μ΅(4₯πΤ·–d"M¨mێ2ΓΟjŸid›΅²Mž_k—W0ΫΒ–W¨'$ΰVΟ‡u hueX:€δ88-ŒcΧ¨’ϊΠ|Tρ‚%Π+κΚ­‘ψβ΄΅Ηwkβ– ϋNhδBHωœΰώB©·₯Ά)·₯ΆΰmFΧoΗUΤ¦±Ό™;M‘oWcžӝ½ΗZΖΧtΩt}bσN•δΆ•’,½¨«ž Έϋ/Œ4iΌ–›eά_»OΌί0{ΧQρCΓ g¬k‘ΦτΉžKƒ'ΨΔι ½ΊφΟδ*Λ<φŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( §²€ό•ASΩΗ~?Κ€ ’Š(’Š(’Š(©ογιεPTχΏρτ‡ς (’Š(’Š(’Š+Τώ3θZœΪ„:ΔvŽΪl60£Ο‘…9#Ξz°όλΛ*ΤڍτИfΌΉ’#€Q₯b§πΝM’hΪ†ΉxΦΊM³άά* )…y>β»/±΄^$γ‘vΊip«Ψ‚ω Ϊζ{Y ΫM$.F7FΕN=2(ΉΉžκ@χ3I31cLšίΡHkΫϋ^ηJΤ•ˆw ΜΉγqŽέι΅OΓΧZW‹mζk­φPΘίΏςΨnHo&°¨£Ψ«I]ΩίρlοeuϊίΘ²ί\IΚ<ŒΚ}A5sF³Σn–S©j†Ε”ƒμν.^+2ŠΡΖρ²v3R³»W;Ι’j·W:°ZrŠίμΞ7ϋΗVf―mqαw\[yήjm#nζΘη?…`ΡYB‚‚Š»vΫnΦμi:ξNNΙ_Ύζ‰΅kΛmm%ήφΦiŸ)\vδsψWCiͺιψ4λη²½ώΦi#VUΗ“Έ7“ׁΟα^[vή*Φ­lγ΅·ΎhΰvͺˆΣ }qšΞ¦ρJ}mΏΘž"n~]/±‹ˆ>'Υ1?όλΉΊo5ΏƒΪ#_ašβK₯WPΡ|ΜyϊsψŠσv‘Ωέ‹;’NI>΅$3Ϋ‡M$AΖcά=:ΧL#ΛΗ<εΝ'.δTQEQ'wo―ι©{’ΘΧ8K}-­₯>[|²#oNzυV&­©[Να―Ϋ[ΛΊκΟΟ26pW’0x«Ÿ’‘SKRw=PΤ4-jύ5KrξΗr©žΙ#rIV βΈ[ωcšφy ™ΙA#nlvΙξj )Ζ‘r»q λπ[^Λ«IgyͺΔΦΝlΟΉ”Œ85—’j6ΆήΧμη—mΝΧ“δ¦wmbO `~5ΟQIAZΐ‘ec‘ƒQ΅_άιΝ./ψL±ν<¦Π3œc¨υ­ K½Yπ֟§jΧΟ§άΨ3μ“Ι2+£‘ΗCΣς:Š8#£ρ~―iyya•½­4ψέΖ ‘ί•t7z‡†oόCiβ ΅b›to%§Δ‡\wtΐΐιœβΌξŠ=š°½š΅?έC{βBζΥχΑ,ΜθΨ# ϋk2Š*²±iYXέπ6ŽΊχ‹4έ:PΖ₯Μ pv(,άφΰo"ΣmόOo’FRΒ <€Λ–,W†9>§?…PuKέ"ονZmΓΫάm)ζ&2λΦ©žNM (’€ Ωπ†¬š'ˆ-o¦VxP•p½vFGΣ9¬j)5uf&¬ΞΖX<'§Ε{qλκrJŒΆΦƏΛ'‘fγ8ͺžΤ΄ψτύSIΦ$xmo•·–Κr2'·ε\Ν<šY²y4³g[­_iV.tχΝ-ǟ5ΑŒΖΌ ϊ –ήοEΦ<-§Ψκ—ο§έiμϋ[ΙiˆΗ'οΣς6Š9·EmΞ§ΖΊ¦Ÿ{&‘ύ‘+’f¬…μΥ‘=ό±Ν{< Lδ ‘·6;dχ5Uš—Β­QΤ|Yayaoζ[ΨάG%Δ…€O―°=++ΗrC7ŒυΉm€Βχr2Έ9,slΦ0π΄ώšΩΔρήιχiζ[^D>Iτ>ήυΟPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPΔH”S€mς3€I8©΄QEQETφ_ρτŸς¨*{/ψϊOΗωPQEQEQEQVτ:λWΤ­μ,#σ.§m¨Ή'―S@Ώ˜o>~ψdΩjΫ">€ 'C5η΅θΎ:{ox7MπŒ1ά_¬ζςω’9Tr žύρΡλ^u@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@OeIψ*‚§²€ό•AEPEPEPO†Y!I Όn:2œψΣ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( §²€ό•PQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEΩ endstream endobj 181 0 obj 63345 endobj 182 0 obj 98576 endobj 176 0 obj << /Font << /Font2 12 0 R >> /Pattern << >> /XObject << /Image22 179 0 R /Image23 180 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 183 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 184 0 R /Resources 185 0 R /Annots 187 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 184 0 obj << /Filter /FlateDecode /Length 186 0 R >> stream xœ΅TΝNAξρFέδnΌ²$6ύSύwΤ FIˆΚΘŒ&DbpΡ/β«ψΎ ŸΒ―g˜ή]!²ήϊ¦««ϊ«ͺž–ŠςxΤ ¬Φ§4!%•ΙG§Έέ1―cS^NΙzΌjΝ›A1ΚΞBCsJώ?‘1ΑΙ„Ά7_N…“gˆl5|H«RT6YΊ8Ύ•«:Ϊ€W“Β“n=΅ΗꝖ́4;›9€NAgpŠ5Ζl]‡ Ά6u™ΪΨ³;H-΅½’Wφ2:ΦΙa“Τ6izώS0ŽήUˆ!η λLβό“gΤ΄΅s~φ͐ΓΖό‹TΝζ5a:#=Sέ%­ώHoiCΌ―ΦΔ•ΈͺŽΘfΚ6Δ―ΜRuΩKβg΅7"Ύώ^Υχ~ˆο#B€νΆ½j­Ϊ­vρaοΟ&#zGυ zZΟK•pXL 7ΫQύ9;[‘‡ΏΥ…‰)°T .Dνl[5)u6¨½qΡI\£)μK΄(Θ»r0ήlϋ d­ƒMG—JžY¦ΈΤ Tl=?=<ώd˜ΆΟ§¬­ ¦;ΐ·£yk ,£»†4‹ΠΝ&ΰ|ˆ•—ΩmYl.μ &H kiƒΆ tŒΉ}[ŒϋN˜%yΣω4ΝιZnFΦ*τn‰ό,₯―§α\Ά)Θ1~³ hy/“`Τ\Θ‚^Xε{ηhϋyΣΰ$mΎ›ΏΥc—ΗoΓ„f endstream endobj 186 0 obj 631 endobj 187 0 obj [ << /Type /Annot /Subtype /Link /Rect [ 63.785435 61.39882 237.98407 78.19882 ] /Border [ 0 0 0 ] /A << /Type /Action /S /URI /URI (https://rss.com/podcasts/oat) >> >> ] endobj 188 0 obj << /Subtype /Image /Interpolate true /Width 2024 /Height 706 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 189 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐΒθ"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ςψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ(…―mBοώOώ"ΌŠυOψZφίτ.δρβ+Σώ ›o‰ίΫ?θίΩΩήOό΄3ωžg™ώξ1εϋη>Υςε}=ϋΜεn_ϋ^’£q‹hqWgͺΒͺΆ ‡ώ@?ό]πͺ­Ώθ!^‘š3\ΎΪ}Ν9Qζπͺ­Ώθ!Gό*«oϊδΕΧ€QGΆŸpεG›ΒͺΆ ώ@?ό]πͺ­Ώθ#^‘š3GΆŸpεG›ΒͺΆ ‡ώ@?ό]/ό*«oϊδΕΧ€FhφΣξ¨σψUVτΘ‹€…UoAό€ψΊτš3GΆŸpεG›ΒͺΆ ‡ώ@?ό]πͺ­Ώθ!^‘š(φΣξ¨σoψUVίτΘ‹₯…UmAό€ψΊτŒΡš=΄ϋ‡*<ίώU·ύςβθ…UmAό€ψΊτŒΡš=΄ϋ‡*<ίώU·ύςβθ…UmAό€ψΊτŒΡš=΄ϋ‡*<ίώU·ύςβθ…UmAό€ψΊτŠ3GΆŸpεG›ΒͺΆ ‡ώ@?ό]'ό*«oϊδΕΧ€ζŠ=΄ϋ‡*<ίώU·ύςβθ…UoAό€ψΊτŒΡš=΄ϋ‡*<ίώU·ύ?ςβι?αU[ΠC ώ.½&ŒΡν§ά9Qζίπͺ­Ώθ!Gό*«oϊδΕΧ€ΡGΆŸpεG›ΒͺΆ ‡ώ@?ό]'ό*«oϊδΕΧ€ζŠ=΄ϋ‡*<ίώU·ύ?ςβθ…UmAό€ψΊτŠ(φΣξ¨σψUVίτΘ‹£ώU·ύ?ςβλ(£ΫOΈr£ΝΏαU[ΠG ώ.—ώU·ύ?ςβλ3EΪ}Γ•m ͺΫώ‚ωρtΏπͺ­Ώθ!^‘š(φΣξ¨σψUVτΘ‹£ώU·ύ?ςβλ3EΪ}Γ•o ͺΫώ‚ωρtΒͺΆ ‡ώ@?ό]zE{iχTy·ό*«oϊδΕΒͺΆ ώ@?ό]zFh£ΫOΈr£ΝαU[ΠC ώ.ψUVίτΘ‹―H£4{iχTyΏό*«ϊδΕΡ ͺΫώ‚ωρuιQν§ά9Qζίπͺ­Ώθ!K ͺΫώ‚ωρu钏m>αʏ6…UmAό€ψΊ_ψUVίτΘ‹―H’m>αʏ7…UmAό€ψΊ?αU[ΠG ώ.½"Š=΄ϋ‡*<ίώU·ύ?ςβθ…UmAό€ψΊτŒΡGΆŸpεG›Βͺ· ‡ώ@?ό]/ό*«oϊδΕΧ€fŠ=΄ϋ‡*<ΫώU·ύ?ςβιαU[ΠG ώ.½"ŒΡν§ά9Qζίπͺ­Ώθ#K ͺΫώ‚?ωρuι£4{iχTyΏό*«oϊδΕΡ ͺΫώ‚ωρuιfm>αʏ7…UmAό€ψΊ?αU[ΠC ώ.½#4fm>αʏ7…UoAό€ψΊ?αU[ΠC ώ.½#4Qν§ά9Qζπͺ­Ώθ!I ͺΫώ‚ωρuι9’m>αʏ7…UmAό€ψΊ?αU[ΠG ώ.½"Š=΄ϋ‡*<ίώUΏύ?ςβθ…UmAό€ψΊτŠ3GΆŸpεG›ΒͺΆ ‡ώ@?ό]πͺ­Ώθ!^‘FhφΣξ¨σψUVίτΘ‹£ώU·ύ?ςβλ3EΪ}Γ•o ͺΫώ‚?ωρtΒͺΆ ώ@?ό]zE£ΫOΈr£ΝαU[ΠG ώ.“ώU·ύ?ςβλs@4{iχTyΏό*«oϊδΕΡ ͺίώ‚ωρu钏m>αʏ6…UoAό€ψΊ_ψUVίτΘ‹―HΝ£ΫOΈr£ΝαU[ΠC ώ.“ώU·ύςβλhΝΪ}Γ•o ͺΫώ‚?ωρtΒͺΆ ώ@?ό]zFhΝΪ}Γ•o ͺΫώ‚?ωρtΒͺΆ ώ@?ό]zFhΝΪ}Γ•o ͺΫώ‚ωρtΒͺΆ ώ@?ό]zFh£ΫOΈr£ΝαU[ΠC ώ.ψUVίτΘ‹―HΝ£ΫOΈr£ΝΏαU[ΠC ώ.—ώU·ύςβλ(ΝΪ}Γ•o ͺίώ‚ωρtΒͺΆ ‡ώ@?ό]zFh£ΫOΈr£ΝΏαU[ΠC ώ.ψUVίτΘ‹―IΝ{iχTy·ό*«oϊδΕΒͺΆ ‡ώ@?ό]zE£ΫOΈr£ΝΏαU[ΠC ώ.—ώU·ύ?ςβλ(£ΫOΈr£ΝαU[ΠC ώ.ψUVίτΘ‹―H’m>αʏ7…UmAό€ψΊOψUVίτΘ‹―I£4{iχTyΏό*«oϊδΕΒͺΆ ‡ώ@?ό]zM£ΫOΈr£ΝαU[ΠC ώ.ψUVτΘ‹―H£4{iχTyΏό*«oϊδΕΡ ͺΫώ‚ωρuιQν§ά9Qζπͺ­Ώθ!I ͺΫώ‚ωρuι4fm>αʏ7…UmAό€ψΊ?αU[ΠC ώ.½"Š=΄ϋ‡*<ίώU·ύ?ςβθ…UoAό€ψΊτŒΡGΆŸpεG›ΒͺΆ ‡ώ@?ό]'ό*«oϊδΕ׀њ=΄ϋ‡*<ίώU·ύ?ςβι?αU[ΠC ώ.½&Š=΄ϋ‡*<ίώU·ύ?ςβθ…UmAό€ψΊτŠ(φΣξ¨σψUVίτΘ‹£ώU·ύ?ςβλ(ΝΪ}Γ•o ͺΫώ‚?ωρtŸπͺ­θ!^“FhφΣξ¨σψUVίτΘ‹€…UmAό€ψΊτš(φΣξ¨σψUVίτΘ‹€…UmAό€ψΊτœΡš=΄ϋ‡*<ίώU·ύςβθ…UmAό€ψΊτŒΡGΆŸpεG›ΒͺΆ ‡ώ@?ό]πͺ­Ώθ!^‘š3GΆŸpεG›ΒͺΆ ‡ώ@?ό]πͺ­θ!^‘š3GΆŸpεG›Βͺ· ‡ώ@?ό]πͺ­Ώθ!^‘FhφΣξ¨σoψUVίτΘ‹₯…UmAό€ψΊτŠ(φΣξ¨σψUVίτΘ‹£ώUΏύ?ςβλ(£ΫOΈr£ΝαU[ΠC ώ.ψUVίτΘ‹―HΝ{iχTyΏό*«oϊδΕΡ ͺΫώ‚ωρuι£4{iχTyΏό*«oϊδΕΡ ͺΫώ‚?ωρuιQν§ά9Qζπͺ­Ώθ#Gό*«oϊδΕΧ€fŒΡν§ά9Qζίπͺ­Ώθ!K ͺΫώ‚?ωρuιњ=΄ϋ‡*<ίώUΏύ?ςβι?αU[ΠC ώ.½&ŒΡν§ά9Qζπͺ­Ώθ!Gό*«oϊδΕΧ€fŠ=΄ϋ‡*<ΫώU·ύςβιαU[ΠG ώ.½#4fm>αʏ7…UmAό€ψΊ?αU[ΠG ώ.½#4fm>αʏ7…UmAό€ψΊ?αU[ΠC ώ.½#4fm>αʏ7…UmAό€ψΊ?αU[ΠC ώ.½"ŒΡν§ά9Qζπͺ­Ώθ!I ͺΫώ‚ωρuι9’m>αʏ7…UmAό€ψΊ?αU[ΠC ώ.½#4fm>αʏ7…UmAό€ψΊOψUVίτΘ‹―I£4{iχTy·ό*«oϊδΕΡ ͺΫώ‚ωρuι4Qν§ά9Qζπͺ­Ώθ!I ͺΫώ‚ωρuι9’m>αʏ7…UmAό€ψΊ?αU[ΠC ώ.½"Š=΄ϋ‡*<ίώU·ύ?ςβθ…UmAό€ψΊτŠ(φΣξ¨σoψUVίτΘ‹₯…UmAό€ψΊτŒΡGΆŸpεG›ΒͺΆ ‡ώ@?ό]/ό*«oϊδΕΧ€fŠ=΄ϋ‡*<ίώUΏύ?ςβθ…UmAό€ψΊτŒΡGΆŸpεG›ΒͺΆ ‡ώ@?ό]πͺ­Ώθ!^‘EΪ}Γ•m ͺΫώ‚ωρtW€ζŠ=΄ϋ‡*?1(’Šν2 (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ ϊwφ*™ΛώάΏφ½|Ε_N~şσ9۟ώΧ¬λ| ¨ξ};š3IEq‹š3Iš3@ š3Iš(sFi Ν€Ν f“4”f€šLfŠ\њLΡ@Ν&i(ζ€šJJ3@ š\Σh Ν€£4Ή₯Ν6ŒΠζ—4Ϊ(Ω£4Ϊ(sνFi(Ν.isMΝ Ν€£4Ή£΄Ή¦ζŒΠ³IšJ2hsFi ₯Ν74P³FiΉ£4Ή£4”PζŒfŒΠζŒfŠ\њAFhsFi3FhΩ€Ν% f“4™’€4f“4P³IšJ9 f’’ŒΠζ—4Ϊ(sFi(Ν.isM£4Ή₯Ν6ŠvhΝ6Š\ϋQšJ3@ š\ΣsFhsFi(Ν.hΟ4™£4Ή’“4f€4f“4P³E6ŠόΗ’Š+Ρ0 (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ ϊoφ-™Ηώάφ½|Ι_M~Είσ8۟ώΧ¬λ| ¨ξ}9š3MΝ#QΤf›š3@’›š3@’›š(Ωͺš–£g₯Ϊ5Ξ£u ΅Ίυy\(ϊsίڹψ^5³π~š@'Τ&[Ϋηο΄ήŠ?^ŸOš|Gβ OΔwζοVΊyδηjτHΗ’―@*αMΛR[±ξΊΗΖΩ»%„7wμ?TF‡ρnJΔ…μ›ρσlυϋg?–Κπϊ+ogs3θ½γ?‡ο$Xοΰ»°cόl’DŠσϊW’iš–©h·ZuΤ7VνΡβpΓιΗjψΒ΅Ό9β OΓ—βοIΊxdγrυI£/B*]%Џ±(Gαχ¬ό_¦™# BΕΉ?wύ₯υSϊt>ύe`Υ΄e’›š(κ3MΟf€P]έ[ΩΒf»™!ˆug8•βA‘Zn`$Ή“ύTYλξ}y&«ͺ]κ—&kٚFώό*=νT£q6zEχ΄Θ­΄sά‘ό@m_ΜσϊVwό,uέ ³·ΧΟμkΟ(«εDݞ©aγν2v sφΔ”~#ŸΊ›K»{ΘΦ³G4Gψ‘²+ΐ³W4­RοJΉΩLΡ·ρͺΓЎτœ;η»ΡX~ρΎ»iΉqΚήŞžγΤVΦk=†;λE74fŽΟ΅¦ζŒΠ¨¦ζŠuάњvhΝ74f€@¦ζŒΠ¨¦ζŒΠ¨Ν74f€š)΄f€FiΉ£4κ3M£4μΡMΝ C³E74gš;4f›š(ΤSsFhΤf›š3@£4άњuάњuάњu¦ζŒΠ³FiΉ£4κ3MΝ QšnhΝ;4f›š3@Νάњvh¦ζŒΠ¨¦ζŒΠ¨Ν6ŒΠ¨¦ζŒΠ³FiΉ£4κ)Ή£4κ)΄f€E6Œρ@Νάњu¦ζŒΠ³E74f€E74f€GΦ›š3@£>Τάњvh¦ζŒΠ¨¦Ρšu¦ζŒΠ³E74f€(¦ζŒΠ¨¦ζŒΠ³FiΉ’€E74f€š)Ή’€š3MΝ QšnhΝFiΉζŒΠ1Ω’›FhΤSsFhΩ’›š3@ΝάњuάњuάњvhΝ74f€šΗρ‰΄ΔXΏ†ά‘•ŒΞίEŸΚΈ_‰ŸIœθžmaΞΗ‘Fα =οό«–πΗΓΤΥ-.5j>~KC?;Ηg~N{`crj’]IΎΆGA©|oarΊ~™yrρHΛ?OΌk;ώ·ύKΏω=Ϊι4OXiZΔ©€θΦ"А"+l¦B=AϋǎδΧO₯xΊΟΔ ΪάA47(£oš§Κ`mμN~•RI+Ψ·Ni\ζα{ΤΉ“ίύ“ώ·ύKŸω=Ϊλg]π6ͺ\'²ŠΖς\”–Τω|‘‘•ϋ§Ÿjς/ψ/Pπ₯ΘσΘΉ±“ύUάcεocύΦγ§εšP9θCM‰ Ϋώ₯ΟόžνtΒφ©s'Ώϋ]x•·³bnΟm…νRοώOφΊ?α{ΤΉ“ίύΌJŠ=œBμφίψ^ίυ.δχk£ώ·ύKΏω=ΪλΔ¨£ΩΔ.Οm…νRοώOφΊ?α{Τ»“ίύΌJŠ=œBμφίψ^ίυ.δχk£ώ·ύKΏω=ΪλΔ¨£ΩΔ.Οm…νRηώOφΊ?α{ΤΉ“ίύΌJŠ=œBμφίψ^ίυ.δχk£ώ·ύKΏω=ΪλΔ¨£ΩΔ.Οm…νRηώOφΊ?α{ΤΉ“ίύΌJŠ=œBμφίψ^ίυ.δχk£ώ·ύKŸω=ΪλΔ¨£ΩΔ.Οm…νRηώOφΊ?α{ΤΉ“ίύΌJŠ=œBμφίψ^ίυ.δχk£ώ·ύKŸω=ΪλΔ¨£ΩΔ.Οm…νRηώOφΊ?α{ΤΉ“ίύΌJŠ=œBμφίψ^ίυ.δχk£ώ·ύKŸω=ΪλΔ¨£ΩΗ°]žΫ Ϋώ₯ίόžνtΒφ©s'Ώϋ]x•{8…ΩνΏπ½Ώκ]ΙοώΧGό/oϊ—ς{΅Χ‰QG³ˆ]žΫ Ϋώ₯ΟόžνtΒχ©s'Ώϋ]x•{8φ ³Ϋα{ΤΉ“ίύψ^ίυ.δχk―’g»=ΖޱmΡ}Rμ1όΆ κτ‹Υ€Xζž]>fγk΅IxγŠωŽŠN”GΜΟΆ#‘$^6WFVSG¨4μΧΚΎρξ©α;”DvΉΣ ~ςΡۏr§ψOιλ_LhΝ–½₯C¨i²‰mεz©ξ€v"²”JNζ•›š3P1ΤSsFhΤSsE~eΡEθ˜Q@Q@WΊόύŸυ/G―βWŸIΠ·‰εβ{‘ώΞ~κ΄AΟ`z€΄Άžςζ;{HežβFΪ‘D…™Ο ’k½Ρώ όCΥΰI¬ό-|#Ίn-σΖs‰N0zώχƒΌαΟX­―‡4›k4zE]9Ζ2ΞrΔςzžυΡPΐσώΞίγ@SB†SœmKθϊςβΈο|;ρ†’3k~Τ­`ΜΖьdœΊεGž½kτ¦Šό«’Ώ@~&|πŸŽ"2‹T5@»VξΚ%\ς9tΐΐΟ ½+γ/‰Ÿ ΌCποTϋ6ΉjM€ŒE΅μ|Ε8‡ψOϋ'}0h‹’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(―¦bωœνΟkΧΜΥτΗμa3‡ύΉνzΞ·ΐʎηΣY₯¦fŒΧ ϊ3M£4κ)™’€U5[ψ4½6κϊνΆΫΫF9φ<{Պσ?Ϊ›Zx>(Ψ†½Έ ήθ£qύvӊ»°3ΓΡoόC«A¦ιP4ΧS:(ξΜ{άΡανΔ:΄n•Ou1ΐ’ŽμΗ°ΝzΎ»«ιί tY|?α™RηΕ ώ’|φWΠϊέO4μ™xΟΓοαάι3]ΫέΙ7I8Œΰη‘ΕbRΘο,$ŒΞμK31Ι$υ$Σi­α}rλΓΊεΆ₯dy |ɜ υSμE}o₯_ΑͺiΆ·ΦΊήβ5•±ηήΎ2―’>κmwα ¬€bZΚΰͺϋ# ΓυέYUŽ—*'¨fŒΣhΝ`PΉ¨onc³΄šζvΫJ]°©kψ™x`Π£N Δ χG?Ο»ΞυFmWQšξΰόΞx^Κ;T©(­ˆ4΄1υN+(ζŠ4‡ tϊš‡T°Ήο€΄½ŒΗ4g‘؏P{ЍŒQ•‘а9kΎΣ―­£6•¨Γwn~d<―fΑ―o³ΉŽςˆc•©φ5ΰUκ_ ο ϊ1Ι·”ώιηωζ’k©Hμ3Kšm%f1Τf“4™ ζ“4Ϊ(Ω’’’€šJmμσM’€—4ΪNτϊ)Ή£4΄f’’€šLΣsK@Ν&i(Ν.MQ@ KM€Ν:—4ΪLΠθ¦QšvisMΝ%;4Rf“4κ3MΝμΣ3K@€Ν&h QŸZe.hΩ€Ν% ₯Ν74PњLf€E34΄μΡMΝ&hτS( QšJ(ΐSihsFi);Π³Fi( Qše-;4™€Ν΄f›K@ KLΝϊ3L’€šJm-;4™€’€šJm.hsKšfh fŒΣihisL’€Fi΄΄ξi)( fŠgz\Π©)3E.isL£4μζ›E.hΙ€Ν€QIE:’›šZvh¦fŠ}&iΉ₯Ν;4™¦ζ€ŠnhΝ;4f›FhτShΝ.k“ψβψEΌ/5Μ$}ΆsδΫύς>χΰ2~Έλ«― ψΕ+λŸτ} x!E.‰Ι˜ΎΕQZκ ₯πϋ@Ί΄Hυ{ϋKƒwtwΗ4ΉΖΣ†Θγ%˜gŸCυΛΗ–’ψ‹BΆ—L•-mΠ•’-γ=ρΤζŸkΩιZ^Ϋydž#σyρ‘³ 0p=z Γ:”w‹Α<Ο&Ÿ?ΙΒνΘ<ƒωσ\S•GWΉTW,Ή› ίHπœPyKuw*δL¨_ŽΩ•£Ž Ψ58ΎNJ2wo”duοϊW;΅€ιSΑ¦ΪΩ»­’ΛέΞ~κγ©Ι­9u¨^mά™¦ΞΤθΚv’2:ŽEuΕιkξvΞ=Z4&΅ΏtΨο/&Ιο sΧΥέ2ξΛΔΊ9Σ.’qR³€Ι°Kž~_‘=¦½ί†mdΣ^XY:†2H‘ΐ¨Ό/umk­Λ,rjn<΅.€m=[,O#Ž•ΛR7‹ΎŒδnη‡ψλΓsψSΔwlΝΎ1‡†OοΖz―P}Α~½Ϋφ‚²Ά½­oνˆk›)r€1„qΗκ>¦Ό"»θTφΉƒVŠJϊ'Δήψgα=?J›^Σ.ΑΎL«E4­Θ XŸŸΌ+k\GΞτW«όTπ‹₯ψfΓΔώΉ–M*ε•LrΨ VRFGLyΝyB©c…Ÿj’’Š@-Ϊό0π ή;½½…/~Ε¬aΜ¦0Nυ=Oα\Ο‡ΰŽη_Σ`CΓ-ΜHκ{©p  W₯||πώ•αΟXΪh–iio%’ΚΘ¬Η,dqžIμε^j'}©€QIE ŠB$‚;RAΑz(ηΔ~ “αή“‘k*x™~Υ! θw’OΚA8ΐ=ΉΟ  ±Β‚O  ŠJξΌ}yໍCO ZK’‰ώ–Μvδ1<3nΙΘγ€5{Γφρ^kΪm΅Βξ†k˜£uΞ2₯ΐ#?C^υβ |*πž£oc­XέΓ,ρωͺΙ,ξ䌜7¨=©€ΞτW§|Zψ§x{LΣ΅ έ=Ζ‹|B¨sΈ‘eά€ΰ€zς1οW<ύ©l΄½RοOπΎ†u4_lΊ›ΛFa‘•@ eΟ9%I…}-E|=ͺ~ΣΎ>»ή-F‘` eL6₯ŠO˜Λς¬y?h‰*Ίλρ"ŒeΖί υΚϊΠί4WΒVΏ΄ŸΔX_2_X\ ƒΆK4ιςγ­uΪνcE ώέπζ›t›Ή6r½ΉοΙλυφλ@_Φ?‹|7₯ψ³AΊΡυΫUΉ±Έ\2ž žΜ§³ΖΌ·Β΄΅έ±κS\θ—'wΛyc8ι‡\ŽG9zgΨ΄ϋΫ]FΚΝ>ζ »I—tsΑ ‘z«ϊPηΕ?κ|_u’κΌ@ω–·8ΐΈ„“΅Η‘γv ŽzžBΎνύͺ< ž+ψw>©m6­’+\Γ°rρqζ©φΪ7}WήΎ Š+κ_†?²ςήiκ<ΎΉΆšeάΊu¦£qζ9ζηξΖ:œΰ|΅E}Ϋ{ϋ5ό;Έˆ€6z…«#|7ŒH'ΏΟΈd}1λšρΏŠ³6§ Y^jžΏ:­Œ Θmg “DZݐ―€@ ΟŽ@>v’Š(’Š(’Š(’Š(’ΎπWμΘώ'πn“ΒXΆ―¨Z­ΚΫgο Έd)4g·8―œ¨{{K›”•­­ζ™aRςΠ°EΞ:sPWί?³f­αΏψSϊJi7°5¬gϋAXͺ2OŸŸλΖφΫιŠψηβ{iΊΟΕMpψPE%…ερ’/•±εΘΔγ·?q”WήΎψ!ΰoψn6Χμ4ύNς4]ίj*­n3€ί* =23Ž€ΧŽ~Τ:_ΓΨό+€κ>_ύ­―Œ2Ύ“4dlΨX‚±½vφγ#Φ€>m’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(―¦?cψL?νΟkΧΜυτΏμg3‡ύΉνzΞ―ΐʎηΣ£4άΡ\Fƒ³FiΉ’€FiΉ’€^/ϋGξςό?»™συύή?­{6kΜώ>ιyαocRZΚΰ3{# §υΫW‰ μ|σE%Aο_ Ό―ψUΪ—ό+ύŸπ—νLσρηm¦]±»οלW…\yΏh—νόύΗΜσ3»vyΞyΞj»jπjZTνΤ' ŽŒ;«ΰχλόVΡeρ†bKo[¨7ϊp8σΪ_Sθ{τ<Υn‹QK"Τf›š3@Ν¦Ρ@Ν¦ζŒΠ³E74P³FiΉ’€š3MΝ fŒΣsFhΩ£4Ϊ3@ΝΪ3@ΝΪ3@ό(Ν6ŒΠ³FiΉ£4κ3M’€š3M’€š3M’€š3M’€š3MΝ fŒΣs@ fŒΣsFhΩ£>ΤΪ3@Ν¦ζŒΠ³FiΉ£4μњnh fŒΣhΝ;4f›š3@Ν¦ζŠvhΪ3@Ν¦Ρšu¦ζŒΠ³E74P³Fi΄P³Fi΄f€š3M£4μΡM£4μњnh fŠnhΝ;4f›š(Ω£>ΤΪ3@Ν¦ζŠvhΝ6ŒΠ³^―KΩoPxθ+½ρž©k‘ψ^οWVY-"ΝΆεΘΰ(Σ'ς―šυ―k:Ε·Ω¦cŽXD “κG${t₯C δRσ;‰υk›ϋυΡ¬ςΕ‰[{md,HΞ ПQš½πΗD{]y.5νRΩ/oj $œv0NOα\ΧƒΎkzόZΤz¬z|3"γšƒ?)\qœ`η5ΡxΧΰγi_ρRιž!™ΪΗmά¦ω‹» ό;œ{ΧjΓ$ό‹x†Υ‹Φ^+Y Υ΄yಜ^ά”vαw€0Ο͎:V¦“c%„ž}δ3₯Δq³¬›Γύ‰aœŽ΅αwR„ž]Ϋ$ώ΄Άz₯݌λ-₯ΜΠJ½'*Gβ*ͺΰ£&Ϊv1Rg΄ψσG[?‡ϊŽ‘$Θνv±η%›ΝR~œfΌBΆυOλ:味ԍΔ*”1“Ϊ°λRt―&-}Qρ5ΌΊG‡ŽεΣΛo³7u7givΎV―’ΌUβ?†^0Σ΄˜uΝvιΕ0’&^X(`vsχEj‰e_Œρ5Γ-&σΒsΫ7„-Κf(Ρ•Α’’[’8 €rrsΪί€υ vΫΑZ\^πzΗ#n―uˆ“ž2Κw†lœϋ€3Ϋ–ψ‰γίGαΕ+XΎd+(Ϊ~ο˜’Ψ$‘ΦΩΥΌSΰΏψ+G΅Υ΅λΝμVkH#cΏ  Ap{g‘L?hύΪ -Y°[jWŠλΘϋΫAΞ{ΰδg©ίǞ&< xRΈΡ‘ΏΤž/*ΥN`*…Ϋv:/lώ΅ζ_|aαΟx?ΓΦ^Έ}Φl[I«D6€X€ŒΑ5ΖΏθž%Ρό1‹{φ™lγu|§M„¬`}εϋ§¦zRΈ•π+Ζ’ψ‘uK±ŠΪ+Wk…drŌ²»x3ŒϋW™θΧ‹ρ3β]­ύτ–ZvPΗ+s•}’d™‹ώ5Wΰg4οk·ΏΫ,ρΩήΔ¨fT-岜ŒΞ9=3Ϊ²°Ν$²+Œ$Λ•€μ/ £ϋD\ι“κz~ŠΊh}vυ! |ΨΔqyŒrΫ³Σ―SVΌeβ‹/„iš†τ‹in$„M<σdΫ’G%‰SߏO;ψγβ/Δ~0Συήˆ ΄D2έ6Έ‘Ϋ£{Šλο|Mΰˆϊm„ή1ΉΈu‹TΨν ?s†Ϊΐ©<€pFOβΐ«ρ_OόOπγMρΦ›b–7’8K„@0ΰ±Cœc$2πzy펷Δ^%Άπ_ΓOj±ιV·š‹ZΑ *ΰG˜AfΘΟ~=kΞ>*xηE½πν‡…<Π†iJω„gΟRI$OκΏ|[’k_|)₯ι—Ύ}υŒq-Δ^SΒ°…<²€yγ‚i\Mρ'‰΄˜Ό ¦|@}Φ}]γXΰ9Γe±Θ[τΖMsί/--Ρ5ƒ>Π¬ο|ΝVΦHšh<§B£ƒσΪyaΠΦΝΏŠΌγί ι–6½Ί΅]=|΅ΈˆH0 νaΘPH s˜?<9φXψPΣν¬5ψ€Xο±\6G^ό…#<€HͺβŽ?x)£΄C%T ώι+’ψ™¨ψ-t» 'ΑΆΝ<6fΤ€άΗ?/8άrz‘Ζέ‡ΗΐWΐ^ Vaϊδ”˜Aα?ωtoϊύ‡CτΕ­ΑšΏeqβέv]:β;p© :ψχ1Ο*O\ΒΎjπυΔVšώ™spΫ!†ζ)°N8$ΰsΠWwρίΔϊGŠ|Kaw‘]ύͺή+AΏ”ι†ήΗ`B([ άψ‹βΔ°xwΑ—f™Μ1ΉC*χ―$ Δ’}«Όρ³θžψE₯A¨A½mΛ{WLym/–αdκFέλΫλ_.W«ψΣΕΊ&₯πoΓΊ•ο™ͺΪI M”λ°,nΜWiε‡Cή‹ˆθΌ™ΰ… γ΄ψο΅‹ΗΫ˜ξΑbͺ φRΗž•© κ–_Ό1¬ΪjΪ]½Ά―d Έ‹œ ΄‚yΞύ9‡Ύ6πνΧ‚dπwŽD‘X-otŠNΠ[vΠH`ĐpFun<[ΰΏψ_RΣό q>£ͺ_ΦΈ“‚f* ΰ1ΐQΤσ@Ew#Α?π¬Νџώο3χXίΣpΖ?ƒnάη<ηπ£ΓcΑ?π€k?ΫfψI²ίcΫΏtlΖ>\nΞwvιHgEvώ >Χα*3[aϋΝέγnή7nΗήγpτ΄RQH :}νΟ{ ݌ΟΜ,9ΰ©Ε}Wπ“βM·Œ¬…ρH5ΘW2F8όiύGo₯|—V,/ntλΨ/,fx.‘`ρΘ‡Hξ)§`>λΤ/m΄λ)―/¦H-‘RςHη@ο_)ό[ψ“sγ+Σib^ Μqž ΔAΫλYώ<ψ“­xΚΚΞΞψΗ΄* ‘Ð&AΠWM»‰!h€ HdžΒ€gΤ_KΒ·ΡχυΔΏ—šψύ+³Νbψ?MmΒΪ]ƒŒI Ί+φρ–ύI­Šδz³D8Qšnh€³E74Pζ•Q^‰ˆQEWΠ?±Ž…‘ρV›%΄»2bδ;3žί.ρΗ'=p??WΥ?°Χ•ΏΖy#ΟŞ;}œ½qŸΒ€>«―Τeίψ†σP}GV‚βc0³,yδ¨b€γ=;Ζ{Χ½Χ̟΅₯ρ-PΌ+·d΄EΉk9ύkε+?ίύ›|_αΈοF1x†ΝrXZ![…π|£’ΩαKηŒ Φ7μχͺψ³Gψ§£ιZί€SήFΊ…ŽΛ0δ Ππ ¦HcΘγθ}Οα·ν=’jώUŸm±―Nνp†’ΩΟΈε£όwε…} nΦΧ)ε³C2Λ1Ο # :ƒΧ€ξΪΛY­£YmζFŽHΨd:‘‚±Ώ1;ρ~—~ΧΎ$Φ ΊΞ›Ι lv`O?C]׌>?xŸΕ_Ο†5(­ΔΣ·z„#ά mΑv( Ή g1“__j~πΔ+VΈΈΣτMj7λwnQŸGΖwwυχν_>όgύ›’Ρτ‰υΏM<°ΪΔάΨ\Ήw* dΔBδœd•o|‚€0>|Ρ~$ψ:σXΥu-FΦx/ήΡRΫf«m“ΉIΞ\ώBΊ}/φXψΓVŽϋVΉƒΓVμ«i n.IXž›UU™—8ΙΪxk°ύŠδ–jΏφ—DA\—νMρ{[ΌPήπ½όϊrZď{q1Μ:ο9 ‘ΘΑ$‘Ϊ€:mWφTπ”Φ…t½cZ΄Ί …’fŽdΟ«(E'πa_2|Qψw­|8ΧOΦΦ'Žu/ms ΚL€γ#Έ#ŒƒΣ#ΨΧeπgγG‰τi–ϊή΅}©hw,^Lf1«aC«1%vπp0ΧΣ_΄ί‡‘ΧώkNρ©ΉΣ•o sόΟω‘qψŠψ«αρuŸˆ!M'A„Ζω$Ȋώσ‘ϊ§΅}= ~Κ^·€w[Υ/n8ΟΩ‚ANFbyο‘]μσαk_ ό(ΡΩURγP·MBκFΘ‘€'αTΞqΟ5ςoğŽ-ρn½=Ɲ«j6”―ώ‹gg9ˆ’Œ`»& 6Fy$€=Ζ_²ˆΣ€—ΑϊΥοΫr°j;e ’άό£qΟαβ_ >Λ―|X‡Αž'Z\ͺ%ϋB¦ί1 Ζ\NGρEόϊ”ΚζΦζαšI£•W;K“’₯UΊηœsΦΊOΪσLΉΡ#ΠΌw ^\iϊΔ6I혣΄nŽΚI1‡ϋΗ₯{ί…4H<5α­3E΄’Ymμ-έ\n`£8fΎxρ?μΓα#ΓzΆ₯΅¬Ι-€· ŒbΓBΐ“§ν /nu†>½Ώž[›»>%šV,ΞΕA$“ΤΧΑ|oyk5΅ΧŠυ™mζFŽHΪιΘu#zhΩΎ~ϚŽ>i^"Τ΅}N ›Σ6bƒΛ‘%xΗU'ψ3ψ|ψA£λ^*Φoξ――„ΎΧDp"μΩ8‰χ ΰ―}ΌγkΪΏeΟω!>·―ύ*–Ύ`🈡#φ‚{/S»΄³ΏρJGu 2•IΧνxΓΤaˆόhμˆή΅ρΧ„ob±—Z>Φοό=«Α©iS΄Pœ‚:0ξ¬;ƒάVm Οψ†Oψ‚γVžΦήΦY‚ξŽΒ’ϊ’O95‰IZΎΠ5/ί ]*Ωζ~77DŒz±μ)6αηΔ:έΆ›f>y[ζ|dF½Ψϋ_YιV0išm΅’ν‚ή5°ηήΉίx6ΟΒ:iD"kω€σξλώΚϊ(ύzύ:¬Χ<εΜΛJΓ³FiΉ£5ΝCyoε€Άσ Η*”aμjLњπύcO›KΤ&΄Έ2fˆͺuμ~&Π`Χ-6Ά#ΉAϋΉqΣΨϋW“κšmή—pa½…£nΗ³P{Φ±•Θh›@ΥGΥ"½H"γΞNœŽ£ή‘Υ5 RφK»Ω “Hy=€τ°ͺtU΄RUΝ/M»Υ.6P΄όG QκOjv‘§ΝͺjΪ@>g<Ά8Qܚφ»;xμν"·€b8”"aY^Π`Πνv$Ήυ’γ―°τ³šΚNε$:ŒΣsFjF:ŠLfh€€Ν(€Ν&hΩ£4άζ€4f›š\ΠζŠLњ.h¦ζ—4 Z3IšJvh¦ζŒΠΎ”f›š3Ν;4SsFhΩ’“4™ QIš3@…Ν€Ν&hμΡM£4μњLf£4άњ:ŠLfΝά恋E74f€E&i3@‡QIšLΠ1Ω’›FhΩ’›š3@ΝΪ3@‡QM₯ΝŠLΡ@ š)3Fhh¦ζŠu™€Ν:ŒΣsFhΩ£4άњuάњvh€Ν BΡIšLΠ¨€Ν bΡMΝ fŠnis@… u¦ζ–€MΝ.h΄f›š3@Ν€Ν&hΩ£4™£4΄f“4™ QIš3@…Ν¦Ρš:₯74f€š3MΟ4f€FiΉ₯ΝŠnis@Ε£4™£4\њnh c¨Ν74Ή Νάњvh¦ζ—4Z3MΝ c«”ψ™αŸψJκ@τΗ‘―?²·\Η?y‚ώgτΕ/†λ4š†ͺšž3,<Ÿάz7θkΑε‚ηLΤ;¨d†β&’‘v²‘μk²„’NΗٚ=¬VZeΌ(ͺ‘F€ΠsŸοm"ΎΙr-šεq8Θ‘Ζ Œ£8οάJp­Ή ϋτΞ ΧψγέGΗ7Ά^Γ΅΅°""$…Ξ2I=Iΐό«Ž’˜ E%€Z)( ’’ŠZ)( ’’ŠZ)( ’’ŠZ)( ΰο…›^ρ$w—ŸμϋΉ#‡~ͺžός}‡½fψΐΊŸŠQΡίMχ—N8χ ?ˆώž΅τžƒ€YθZ\:~›Šή!Η«μOrk9ΞΪ"’4sFiΉ₯Ν`XΉ’“4f š)Ή’ŸšΤQEzEP_C~ŚΚYψVδ`ΏΪ;Π|ΟŽΏέg8žΥσΝt_|M?ƒ|k£ψ‚ΩK΅Œαή0pdŒ‚™νΉ φΝ~™W-ρ ǚ€4˜υ]<1ΜΖ8cŽ&‘εp3΄ΐΰu$zέΡυ+]cI³Τ΄ωDΦwp¬πΈώ%aZΓρο€ό;γΛ{_Ψ};w2BΛ+FΡ’0pTƒ‚:ƒΗOA@3ͺ~Υώ…Ψiš­tΐiή8Aχΰ·ΏιψaΓ\Τ“•oώΣ^Ρ€όψw₯ΆmΌ)§Ή§­Χ=σ- VΗό+Π›αΏόΑΔΠ‹i_΅Žƒ)ΪήΤνF9ϋ4ΡΟƒφΆ{Χ¦xwβ_ΓΏˆΡ&ώŸw,μΚ4νJη¦H0Δ†νž τ8_|ψ{‘ϋG†l­dΖΨjWίαOβ xΏehΪ9Ό«­*F (δƒŒŽγ$c$’ρχμΏαέfδέxVϊ]Vl½»!žώθ,βG`{w„t8<3α}+D΅‘ε†ΒΩ-ΦIYφ€7LυΗAΠq^Oϋ4ΨόG­um?β\.lQ,ΎΩ2Λ.ρΑL`c©ΗMΌf½Ί€4‰ O,αĊYŽΤ“ΨWζ'‹υ5ΦόY­κ©·ΧΣέ Œ<ŒίΦΎβύ¦|uƒΎάΫC)]SXW³Άϋ]T$ΊΗ,0E| @~Ρ/ΌI―XθϊL^uυδ’(“8=ΙμΙ'°½ βwΐίxHε[vΦtΧQώ—c7–άe]q•η€z9Ιΐβ|βέ[Α>!ƒZΠ&Hobyut?yH=Ž1‘ƒθE}oΰoΪwš΅ΌQx’ ϋ!Y‚™ΰ5u CM½Iτ‹»«KΌ€’ZΘΡΎrΑSž ~ WθοΒ‹fσαΗ‡ξ%’W*Χ Hΐ–i.9φ$Ÿ`j~.ό/πφ–ΣYλšRBw„[ŽIΖΔ^ $ςp9Ξ{ΧΚ?>/\όMΤΰ†Φέμ΄ &fΆ‚B<ΙρζIŽ3Ž'“œΠΨί5Oό#πδ£Κš4ΨνgE9‘<·Sψ©η5πGΔjήρ%Ξ“¬ΫΚ†7a Α–;”‡BzŽ:"»ίυ†—SΫMκ:Ιέ%§™΄Ζߌž=οθ+κ‹?Œ ΌUbŸnΥτέ₯™|R…N9αΖ0GpqΫE|Ϋϋ)ψ.[ψ•a­½΄λ€i[η{‚„#Ι΄ͺ nη'$ πΎυλΆΖΉ Ρ45uϋUέοڊη‘hΛΘΗ΄ƒœΊzσŽ—Εί΄€Ό3€Ρ(‘ΖH}ΤP{Τ’{Πί?δ‘ψCώΑθΏ:'²Ή‚κβΪh%K‹feš2§1•8lϊ`Χ՟³—ΗiΎ΄πΗ‹.†™q`-]Y’š<–°ΞΦ#œ Žx»βΗΕΟ‡«ΰO[iϊΕ₯ξ§ͺiσΪFΆqοwy"(₯Ψ 2ΉΙ펣»ϋ.Ι πΟύ½ιT΅ς^“'%ecjι`―{ύŸΎ,ψ#Γ 4=#[Χα³ΤmLβh^I]ΣΘ㐀«Αολ_:iΪΟΗ;mnK•RxoγrΎ1œmη¦hλ―ΪΓώH–―]­τrΧΓΎΦn|;β7X°8Ί±ΈKˆω ¬;‡Ψšϊ·φ‰ψ§ΰΏ|)Ττ½^‚ςώY`d…c‘I "“Λ(|„‘»¬ŒˆΜ±η d(Θ>ƒ$©ϊγέ ΫβοΒ†ΕΦν;x/¬ε‘C›εqψಟ©ͺu»o†ίξΣO—μο ’izp ήSbγ Κ¨f€žCΘ~ΖΪΖ₯πβςΖϊ9MžŸvc³™‡XndΎΦ$ΐΕy§νŸβγ¨x·OπΌ|./΄LA΄@>€&ΣΫ;Ο |εEPEPEPEPEPEPEPEPEPEPEP_J~Ζίσ7۟ώΧ―šλι?ΨγώfϋsΪυ_•Ο₯sFi΄fΈΝQšn}(Ν:ŒΣh QMΝκ«©iφz«[j6Πάΐέc•―=ύκΕ 6ΥώθnΟc5έƒαV όŸΦ±?αG¦όoΆίO±σωο―d£5\ςξ+#Ν΄ƒΊ£«ίΝw|ΓψY„hηυ―AΣtϋM2Υm΄ϋhm­Χ’D‘G׎ώυc4RroqΪΓ³E6ŒΩ’›FhΤf›FhΥ έ΄p˜’I’=UΧ"€’€9Kοι³±ki&Ά'°;—υηυ¬ψW‹»ώBgžGe]έŸ3 ₯4Θ5Μ“\‘؝«ωZιν- ΄…a΅…!ŒtT\ “4PΫ`:ŒΣsE FiΉ’€E74f€š3M£4ξhΝ6ŠvhΝ74P¨¦Ρšu¦Ρšvh¦Ρ@Ν¦ζŒΠ¨Ν6ŒΠ¨¦Ρšvh¦ΡšvhΝ6ŒΠ³FiΉ£4κ3M£4κ3M’€E74v f€i΄f€š3M£4μњmμΡM’€Fi΄P³E6ŒΠ¨Ν74P³E74g€š)Ή’€š)΄f€E6ŠuάΡ@Ν¦ζŒΠ¨Ν6Šu¦ζŠuάΡ@ΝάΡ@Ν¦Ρ@ΝΡFhΩ’›FhΩ’›FhΩ’›FhΤf›š(Ω£šnh fŒΣhΝ;4Sh QMΝμњnh Qšm fŠnh fŠnh Qšnh Qšnh fŒΣsFhΩ’›š(Ω’›š(Ω’›FhΤf›ΪŠp4f›š(Ω£4άΡ@Ν¦Ρ@¬xoHρA5{YΓ―Ρ‡"΅h£`<«Qψ+₯Jε¬5+»`†EY@ϊt5 ;ώ¦ό’ν•μΤUσΛΈ¬…SώIφΚ?αGΤΓ’_ύ²½›4fi ² ρ$ϋlε|i—x‰Ψ©Ρ/umZαmμ,β2Ν#v°Ιθδ’δΧ)ρ+β―…Ύ[Ÿν›Ρ. FSOΆ!ηlŒ‚W?(χlLΧΕ>+λ_uRΧLΦz4L~Ν§£εSύ§\`““Ψ±'$ύ@+„’Š(’Š(’Šϊƒφ_ψ₯ΰοxPΣ|O¬}†φ]NK„μ³K˜ΜQ(9D#ͺ·ΟγόC₯ψ«βΖ»¬θ7_kΣn|*o-£έΆΡΎV™Hδv―?’€ (’€ (’€ (’€ (’€ (’€ ϊφaψ…ΰOiΪ΄~&’ζΫUΏ”+ά΅±–©ΪƒfζΞβΩωprΎœ|υE}ΝγΪ'ΐΪ‡)πέΠΥυ §Θ΅‚Ž0Η‘ve υΖO·9―Š|A«ήkϊεώ―©Ιζ^ήΜσΚέ·1Ξμ@;gΡ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@}%ϋΜίnϋ^Ύm―€c―ω›ΏνΟkΦu~Tw>“Ν€Ν3AhΝ%Ή£4™£4Ή’“4f€4f’“4κ3MΝ.hsFi(Ν-™£4Ή£4””μњLP³Fi3I@£4™£4Ή£4™’€4f“4f€Œf’€š3Iš3@ š3MΝ-.hΝ&h Ν€Ν&hΩ£4™£4Ή£4””μΡHM΄f“4”μњJ3@ š3MΝ.hsFi3Išu€ΝΉ£4”PζŠJ3λ@ š3Iš(hΝ&hΝ.hΝ74Ή Ν€Ν½¨Ν74ΌΠζŒΣsKš\њLњ\њLњ\ϋQšJ3@ š)3E.hΝ% Ν€Ν £4™’€4SsFhΩ£4™’€4RfŒΠњLΡ@ š3M₯Ν.hΝ6—4Ή’›Kš\њLњ\њJ3@ š)3FhsFi΄Ή Ν€Ν&hΩ£4”f€4f’ŒΠζŒΣsKš\њLΡ@ š3M₯&€ŠJ3@ š3M₯ Ν€Ν&hΩ£4™£4Ή’›š\ΠζŒQ@ š3IE-€Ο­ Ν”f€4f“4™ fŒfŒΠζŽΤ”™ fŒsIšvhΝ&hΝ.hΝ&hΝ.hΟ΅&h Ν€Ν £4”PζŒfŒΠζŠLњ\њJLΠ¨Ν74Ή Ν€£4΄RfŒΠζŒRP³Fi3I@Ν€Ν%:ŒfŒΠζŒfŠ\њLњZ3IšJvhΝ&hΝ.hΝ74΄Ή£4™’€4f“4™ fŒfŒΠζŒRP³E!4PζεQ^ˆQEQEQE‘’kZ¦…z·z.£w§έ’ΫLΡ·Σ τφ―OΡΏh―ˆΊl+š­½ς©7v¨ΝBΚ?‰Ο½yοώΤ~<–%D΅Πa`Έ.–²O―2ŸΓΘx›γΔΒ`ΊρΕ¬ηΛ±UΆΟ±dˆν‚q^mE9ٝٝ‹3’NI4Ϊ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ΎύŽζn·?ύ­_7Χ±ηόΝίφι΅«:Ώ*;ŸHf“4fΈΝQšnhΝ;4ShΝ-.iΉ u¦ζŒΠ©3Iš3@’™š3@’™š3@ΝΜњ~hΝ34f€GγLΝ ΡLΝ SsFhω’™š3@ΝΜўhτ™¦ζŒΠθΝ34f€š3LΝ њfhΝ>ŠfhΝ?4S3FhτS3Fhτf™š3@Ν¦f“4&hΝ34f€E34f€šZfis@£4άњvh¦ζŒΠ¨¦Ρ@’›š3@£4άњvh¦ζŠu¦Ρšuάњu¦ζŒΠ¨¦ζŒΠ¨¦ζŒΠζ–›š3@Ν¦ζŠu%&hΝ;4SA£4μΡMΝ Ν-74f€E6ŒΠ¨Ν74f€Fi΄P³E74PΏ)Ή£4κ)Ή£4΄Ή¦ζŒΠ¨Ν74f€E7<њ\ΣsFhΩ£4άΡ@Νάњvh¦Ρ@£4άњuάњuάњvhΝ74f€š3MΝ fŠnhΝ:“4™£4κ)Ή£4μњnhΝ:Šnh QM£4κ)Ή£4μњnhΝ:ŠmμΡMΝ QMΝ fŠnhΝ:ŠnhΝ:“4™£4κ3MΝ fŠm ₯Ν74@£4άњu&i3FhΤSsE:ŠnhΝ;4SsE;4f›FhΤ~4Ϊ3@’›š3@€€Ν fŠnhΝ;4SsFy Rf“4f€FiΉ£4μњm Qšnh QM£4μΡMΝ QMΝωΑEW bQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEτμ{3oύΊνjωΒΎŽύζm·Oύ­YΥψQάϊ?4f›š+ŒΠvh¦Ρ@ΝάΡ@£4ΜΡ@Ν¦Q@Ν&i΄w fŒΣhΝ:Šmρ@ΝΜњ~hΝ34f€š3LΝ ζŒΣ3Fhω£4Μњ~hΝ34f€š)™£4όΡMΝ&hω’™š3@Ν¦Fhω’™š3@£4Μњ~h¦fŒΠςh¦fŒΠσE34f€š)™£4ϊ)™₯Ν:ŒΣh Qšnh ξ£4Κ(ω£4Κ(τSA’€FiΉ’€š3M’€(Ν6ŒΠ³E74f€š3M£4κ3MΝμњmμњm fŒΣh Qšm QM₯ Ν¦Ρ@ΝΪ(Ω£4ήτP³E74P¨Ν6ŒΠ¨Ν6ŠvhΝ74P³Fi΄f€š3MΝμњm fŒΣsE:ŒΣihhΝ6Šu¦Π(Ω£4Ϊ(ΤShΝ;4f›FhΤdΣh Qšmκ3M£4κ)΄P¨¦ΠζŠm fŒΣh fŒΣh fŠmκ)΄f€š3M’€š6ŠvhΝ74f€FiΉ’€š)Ή£4μњmμњmμњnh fŠmμΡMΝκ3II@Ν¦Ρ@£4Ϊ;Π³Fi΄f€E6Švh¦ζŠvhΝ6ŒΠ³Fi΄P³FiΉ£4μњmμњnhΝ;4Sh fŠJJvh¦Ρ@Ν¦Š(Ω’›E:ŒΣsE;4SsE;&ŠmωΙEW bQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEτoμ3oύΊνjωΚΎŒύζl·Oύ­YΥψγΉτvi)3FkŒΤ\њni3@έFiΉ£4Ή£4™€Ν;4fšM&i€μњnhΝ;4f›š3@Ν¦ΡšvhΝ34Ή fŒΣsFhΩ£4Μњ~hΝ34dΠσFi™£4όњfhΝ?4f™š2hω£4ΜΠ ?4f™š3@Ν¦fŒΠσFi™£4όњfhΟόњfhΝ?4f™š3@Ν¦f—4μњnhΝ;4f›š3@Ν¦ζŒΠ£u74f€š)™£4ϊ3MΝ€³FiΉ’€š3MΝ ζ“4ΠihsKšnhΝ;4MΝμњm Ν.iΉ£4μњnhΝ.isMΝ £4™£4Ή₯Ν74f€šLfŒΠ³FiΉ’€4f“4f€E74Pζ–›š(Ω€Ν%μњm f“4”f€šLfŒΠ³FiΉ£4μњnhΝ:ŒΣsE;4™€£4Ή£4€ΡšvhΝ74f€š3MΝΉ₯Ν6ŒΠ³FiΉβŒΠ³Fi΄PζŒfŒΠ³IšLњ\ζ›E.isMΝμΠ 74f€š3MΝ QM£4μf“4f€—4Ϊ3@ Kšnh Ν€£4μњnhΝ83M’€šLfŒΠ³FiΉ£4μf“4f€šJLњ\њLњvhΝ74f€4Ή¦ζŒΠ³IšJ3@ šZnhΝ:“4”f€Fi΄Pζ—4Ϊ(Ω£4άΡ@ š\ΣsFhsKšnhΝ;4f›š3@ΝάњvhΝ6Š\њLΠ .isMΝ fŒΣsFhΩ€Ν%μњnhΟμњnh fŠmωΟEW bQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEτ_μ…3gύΊνjωΎŠύ‘?ζl·Oύ­YΥψXγΉτfi ¦ζŒΧ!¨κ)Ή€&€š3MΝμΡMΝ&hΤf›šLΠσFi™€Ν>ŒΣ3Fhω£5hΝIš3QζŒΠσFi™£4όњfhΝ?>τgή™šLΠ™χ£4Μf€$Ν¨ς(Ν?4f™š2(ω£4Μњ~hΝ34f€š3LΝ&hΟ½Gš\ΠσFj<њ“4gή™š3@Νχ¦fŒΠσFi™£4όњfhΝ?4ΉhΝH ¦Fhω£4Μζ€š)™₯Ν;4Ή¦fŒΠ!ΤΉ¦ζ“4 ~ii™£4­ΣsFhΩ₯Ν2ŒΠ覃FhΤSsFhΤSsFhΤShΝ:ŠnhΝ:ŠnhΝ:ŠnhΝ:Šmκ)΄f€FiΉ£4κ)Ή£4μΡMΝ QMΝ QMΝκ)΄f€E74f€E74f€E74f€E6ŠuάњuάњuΪ3@’›š3@’›š3@’›š3@’›š3@’›š(ΤSsFhΩ’“4f€ŠnhΝ:ŠnhΝ:ŠnhΝ:ŒΣsFhΩ’›š\ΠΡMΝ Qυ¦ζŒΠ¨¦ζŠuάΡ@’›š3@’›š3@’›š(ΤSsFhΤSsFhΤSsFhΤSsE:Šmκ)Ή£4μΡMΝ QšnhΝ:ŠnhΝ:ŠnhΝ:Šmκ)Ή£4κ)Ή£4κ)Ή£4κ)Ή’€E6ŒΠ¨¦ζŒΠ¨¦ζŠuάњuάњuάњuάњuάΡ@tQEw˜…Q@Q@wG―΅›ψμ΄«YnŸξΗΙΗ©τηŠφ_ ό&Σ7πΈh˜4ˆ¨U%έ&Ζ%Oέ`Η·;׈׼Ν­Ÿωώ― Š( Ίψ+Sρœχqi2Z£[*³ύ‘Κ‚ cϊW1^έϋ0ΘO^1θM@'"δdleIΤx“ΐϊ§‡Ό=¦λ7Z5₯ψC‰ΨΈά›ΖA=λ°Έψβ‰'‘ΦηIΓ1#3?―ϋ•Ρόx³“Nψkα{)Κ™­ž(\‘Θ,°qν‘@E{πΗBΣ<=kͺψY“N7`­β!Yr2Κ±'ΘŠΗψ‹πκ G·ΧΌ=¨KC˜ζ= #‚ γ Αβ€<ފφ‹/…ž_ hϊώ³άXΪάAΧΚγ,ΉΪœuΟׁ­κ_ό<‘ΫkΎ#hΌ5°Ι<²³`γnΖIΗ#σ  ’½_Ηί τ}?Αιβ_ j’ίiκTH%e|‚Ϋw)r‚?–*§ƒώιoαaβ_κ’ιΊLΆˆ~ςNzτ=pp'< σ:+Σ•Ο|dπΦ»¨|HΦ.¬4]NκΪO'd°ΪHθΨ…ΑGα]Γ­2Jψ#γ5K+«)™oGqFΕ~Μ£8`2>Τ«ΰcα5Iτέ3ΒvΠΝ ;4ϊuΊ ‘•N ’s–σχ‹ν!°ρf΅gj»-νοg†5τU‘€―CύšδzΏ°lŸϊ6*η|mαO\ψΟ_žί@Υ₯†]BαD³‘•ΤΘΔ@Αw @›Z?σύ^^}gu§ώ̏km5­ΜxίΡ”uΝξFAδpAόkΐ(’Š(―nύ˜δ'―ΧΏτ&―«Ϊ^―©i-#iZ…ε“Hsm3FX™ΪFhυί‰uΡu0Φ¦vΐrzύkΦώ4Jςό)π|²³I#y Μη%‰€’Iο^IbKIδ“W―uNϊΞKέFςβΦ yPΝ;:G΅IΐΐγŠχŠ^½ψ’hΧ… Wq€l1Pν½2@Θ ‚3ιT|YkWΐΔπώ―4Oͺ^Θ6B­»oοCœ{:τΙ―Ρ΅ύ_Dίύ‘©]Ω‡9e†VUcκ@ΰΥmGPΌΤξΞ£w=έΑ2O!vΗ¦M{7ΕαFψ0dΰ›oύτjŒα™΄ξO2€π!λΗn΅}JξΖ+½Bς{81εA,μΡǁ΅IΐΐγŠWԟL]5υ ΖΣ”εmLμb9α3Ž€ž”λΪ?πΝzΟ΄ηFΗ]_†5;έ_α’|-c₯κZ…ˆH'³½\€Tqȏ“Θ&ΎvVΤ£Σ_NPΌ]=ΞZΥfaη%3ƒΘ»Q€κΪ†pg―lζ# ‘#Πγ¨ tρ΅ηŠ,>_ΆΉgαΝ*+£δ›(ca#nΖ •r₯ΈΞ;λ_>Φ†±­jzΤΛ.­sy"Œ)žBϋGΆz~Ÿ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@} ϋ%ΜΥnŸϋZΎz― dΣ#WύΊνjΞ―ΒΗΟ‘sHN)Ή€ΝršΝ!4i €³Išni ¦‰€Ν34™ “Iša4έΤόf˜M!j~i7Te©7P›¨-Qn€έ@ξ£uCΊΤ.κ7T;¨έL ·Rn¨wQΊ€&έFκ‡u¨mΤn¨wQΊ€&έFκƒu.κ›uͺΤn  ·QΊ έFκŸuͺ Τn  χQΊ έKΊ€&έIΊ’έFκ›uͺΤn  ·QΊ‘έFκ›uͺΤn  ·Rξ¨7Rξ  ·Rξ¨7Rξ€Ϋ©wT;¨έ@†₯ΝAΊ”5MΊ—5jpj—4μΤ!©CPΐƒP†§f€%Ν.j iΐΠ€ƒQζ—4&isQƒKš“4Ή¨Α₯ΝšPi”Rϊ) Ρš:”ni(όΣA’Ž’›š(μΡM£4κ)Ή£4κJJ(μΡMΝvhΝ74P¨¦ζŒΠ1Ω’›FhΤf›š3@Ν%&hΝ:ŒΣsE:ŒΣhΝ:Šmκ)Ή’’›FhΤSsFhΩ£4Ϊ(μњnhΝ;4SsFhΉ₯¦ζŒΠ1ΤSsE:ŒΣsE.iiΉ£4κ)Ή£4μњnhΝ:ŠnhΝ:ŒΣsFhΤf›š(μњm fŠm c³FiΉ£4Ή₯¦ζŒΠ¨¦ζŒΠ¨Ν74P³E6ŒΠ!ΤSsFhΩ€Ν% c¨¦Ρšu¦Ρ@‡QMΝ QMΝ Z\ΣhΝFi΄f€š)΄f€FiΉ’Ž’›š3@Ν¦ζŒΠ!iiΉ£4 vh¦Ρ@ΝάΡ@’›Fhκ)΄P1ΤSsFhκ3MΝμњm c³FiΉ£4κLfŒΠ!ΤSsFhκ)΄f€š)΄P#σ֊(σ ’Š(­/λ7~Φ­uM9•n­Ψ²o ‚τ ‘Y΄P­Βψρ?όψhΏχζ_ώ9YϊΖOkZ=ή›4lέFb‘ΰ‰Γν#ΞG#Ž•ζ΄Pοƒ|Q¨xGXώΌ“1ŒΔΙ2–GRA €AκλΪ»ίψ_'Ÿ ώόΛΗ+Ιh Ζuh²iwΡXAk++IφhάΑYώΐQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEτμžq OύΊνjωφΎύ”ζi·_ύ­YΥψXγΉτi ¦“Išε4ši4i  M&šM4šqjBi„ €έL-M-@-M-L-M-L SKTe© P…©7T[©7PΫ©7T;©7PΫ¨έPn£uMΊΥκMτ>κ7T¨ί@ξ£uAΎΤ>κ7U}Τn  θέUχΡΎ€,n£uWέFϊ`XέFκ―ΊΤ€±ΎΥ_}ιc}ͺΎϊ7RΖκ7T¨έ@ο£uAΎτcuͺΎκ7PΤ»ͺΎκPΤ>κ]Υ_u.κ±Ί€Υκ]Τcu(jƒu(jœ5(j€585OΊœ  J€'œ @œN’””vj iΐΠ€Σ³QN€$Ν(54Ή  £4Κ\Π³J 74f€š3M£4€xh’Šο2 (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ χΩOώfϋuΪΥΰοί²‘Ηό%φλ΅ͺ*|,qάχό␚Bi€Χ! €ΣI€&˜M8ši4i₯¨ΔΣ SKSI¦‹SKSKS PΛSKS S P…©₯ͺ2τΤΐ”΅4΅DZšZ€&/IΊ‘/IΎ€&έIΊ‘ίIΎ€'ίIΎ ίIΎ€,o€ίPo£}OΊΥϊMτΐ±Ύυ_}ιc}κΎϊ7ЍτnͺΫιwЍτ›ͺ τo  ¨έUχΡΎ€,oχ£}WίFϊ±ΎΥ_}θΖκ7Τθί@7ΡΊ«ο£}XKΊ«ο₯ί@7†ͺϋιCΠ€Τ‘ͺΎϊPτd585VN @SƒUpΤΰΤ€°œ  N @†§¨CS  Α§P†§@N‘ž %œ D 8“4 Τ`Ӂ  ₯ΝF ;4όΡMŒΠ1ΰΡLΝ.hκPi™£4€~h¦ζ—4 ZZnhΝ4f“4f€ŒfŒΠ1sFi3FhΉ£4™£4Ή’“4f˜ΕΝ€Ν€!hΝ&hΝ0ŒfŒΩ€Ν&h Ν™£4Ή₯¦ζŒΠ1h€Ν BњLњ\њLfŽ£4™£4΄RfŒΠ!hΝ&h Ν™£4΄RfŒΠζŒfŒΠњLњ`-€Ν Ν™£4€\ΡIš3@€Ν&hΝ.h€Ν¦ΡIš3HΝ™£4Ή’Ρš.h€Ν Ν€Ν΄RfŒΠ!sE&hΝ0ŠLњ@-™£4Ή£4™£4΄RfŒΠ©3Iš3@ š)3FhΉ£4™£4Ή£4™£4\њLњ-€Ν Ν™£4\ΡIš3@ š\ΣsFhsFi(Ν-€Ν RRfŒΠ1h€Ν BζŒfŒΠζŠnis@ΕΝ™£4΄RfŒΠ!sFi(ΝŠLњ-€Ν¦ζŠLΡHΟΚ(’»Μ‚Š( Š( ŠτΟ‡ o|QhΊž₯9Σ΄’r¬W2JR πϋGς5ΧΟΑοΚΦΣmΎΈο0igΙλςsν@ E{υΏ†~ψΐ­Ύ…zl/œˆ’Ί;7%Θo’υηπςˆ^ΤΌ¨ξ³qc!ύΝβ!Ub9ΪέxΝr4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEοΏ²±‘£ώέφ΅x{ίμ±3?ύΊνjŠŸ w=τši4„ΣICAI¦HM4š`ΣI€&˜M)4ΒΤ…ͺ6jqjD#Y˜φQ“[ώπλj*.nΛGmό uπάZYΫΩΖ#΅…"_φG_©οI°<Γϋ7P#"Ζθh[ό)§KΤηΒοώό·ψW¬QG0Jt½Kώ|/?οΛ…4ιz—ύο?οΛ…zεs!:V₯@ϋΟϋπίαM:V§@ϋΟϋπία^ΑEΑcǎ•©Π:σώό7ψRdκτΌΏ ώμTQΜσώό7ψW°QG0Xς₯j_τΌΏ ώα₯j_τΌΏ-ώλ”QΜ<”iz—ύξοΛ…8izόψ]ί– υŠ(ζ Sύ›¨“ctύqoπͺμ6+"²0κ`Χ―Tvvχ‘μΊ…%_φ‡O‘νG0Rž­[~#πλiκn- Imό@υOρΟ†¦€ΤπjΤπhpiΰΤ©ΰΠΐӁ¨A§ƒH A₯£œ H (5ΔΧ^Χϋ1Ά΅ΐ[ύž=«κ»ŽOώƒωΠ/Žž8šσU—ΓZLΎN—eϋ™ΔGi2§ύ”#υΪΌ†―k¦S­κδœάIζΩ·ώ΅F€X«RCGjϊ αVΏΔ/ κρF뫨aή—ΞιœΟχ•η©ΘχΟΟ•θ³™ *ΣΛ,Θ›~2»O_^q@&―a.—ͺήX\­Ά™αnΙRFyϊU:μώ1m…—μۏ9zzμ\ώΉ2€ (’€ ΦπΟ‡υ/j‰§θφζk‚7p¨½Ω‰θ9¬šφŸΩ»Q±†λ[Σ₯mυ Č۹#,vBηΈά;ώ‘¨όρE₯“O Ί}܊Ή0C+>Γr€1^_$oͺΙ"¬¬0AAν‘ψ+β'ƒ5K[G»V$?˜’Vs( ςΡΆ2έπ 9λ…𷇡OˆΎ3ΊK‰š{ΫƒQ<ό£1 ŠνΌYΰ? k~;Όψ%‡YΏ*ΠΪBθ…@EPAΙ;sΫ―Nτσ…ΠψσΓ2ψKΔΧ:T‰•xεΡ†AΗcΫκ+ž Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ½λφZ™Ÿώέφ­x-{ΗμΉ37ύΊνZŠŸ w=θši4„ΣIS@&˜MΤdΠ“Q“A5RΥ{@±ώΥa€ηΛϋύΡΧό?Μ-]wΓ€ =τ„|Κ¨£θICΆETEDUF…-T (’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’’»ΈKXYOΚΏ™φ  h€SΈ:ihUΡ‘ΐea‚q^]―Ψfj²Ϋ|Ώ½Ίz‡α^₯\GΔT =Œ€|Μ€ϋ?ΔӈŽYZž¦«©©Ձ`x5šzš@N <„rš˜p54ΰhPiA¨Α§H ₯£š~h¦ζ—4μњnhΝ+άψrΘiZε»κZF6 !^κα—ύ’F=qΕuSZ|ρr—K§K!ω£V{p τR6ψΰ•τΒ―Ό5©x·Δ¨φ’<;98++ŒŒd36Π£ΆΤώx>Cs§'φ•όcr―1ΟlΒοΦ₯πΗΕλjך?Šlm­τ«γεΐXξU²“λύαŒΜxV·¨Ν«κχΊ…Ιc5ΤΝ+dη9Ηα©W’|WψsqΰϋΓwd}fύά‡“ ?ΐΠχϊםΠEP^—πŸΒ‹τνZΪβκXuψΤ΅ͺ™0˜Η€2pέyθGζ•-΄σ[N“ΫK$3Fw$‘±VSκι@Dό-π?―_1ΡX:Muηΰν(2JσƒΫŒΤόC€?ΕAg$+€WμΟό2:}όzξ%›ίβ—ώ-ρ‘fmou½F{b6΄opΔ0τnyόkY‘ƒ!*ΐδpA §txΌtΊδ‘Ια iΠC»λ !Έ8ΪMάϋγςCαΖ‘¦xΗΗΎ*Τuθμu «w δJI`]CrGΚ:δ|ίJς»ΏxŠςΔΩέλzŒΦ€a£{†!‡‘η‘υ¬έ:ώσL»[­:κ{[…ϋ²Βε~"€>©ψdϊΣI¨ [Úo‡νAQo΄AB άN qΞZσοΩΙΪ-'Εξ‡k’Dΐϊ²Χ”IβΟ½ι»:ζ¨.ŠμσVιΥΆη;rL󊧧λžš³¨ήZ,λD΄bNΏ{ž§―© —α±m£|CΣ.υT‹ΔΏπR‘‰ϊ‘“θMw>;ψSβ-cΗΧWΪw“&Ÿ{0—ν-(H8ΞW98νŒρŠρ*ά³ρoˆl¬E¦·¨ΓjՍ.ƒž€=ΒޏΒ4554ԝ Ό’ͺν*Ζ'ω[“σc―z‹ΕΜα’ΰδΘNΘu툫Μ-/μοξκx.Τ–Y’«‚x$0ηΉόισjWΣj#PšφζKπκβεεc(eΖΣ»9ΘΐΑΟ Gύ£?δ §ύyG‘=ymZΤ΅έNγν•εΝδϋBω—΄Πd’qUh’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(―wύ—Ώζf·_ύ«^^νϋ/ΜΛnίϋV’§ΒΗΟv&šMΣ SA ¦1 š j641¨ΨΣc]ŸΓS“©Ϋ?ύšΈv5Ϋ|29ώΆ_ϋ='°ΕQP0’Š(’Š(’Š(’Š(’Š(¦ PΚc 7ΈAMΊ™mΰy_’ŒΦ3Ο¨άI!ΙdΙόΕK•šCJκηCEU(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š+˜ρΡ–λΙSςEΧάΧLμK€dΧ7šŠξδΙ&OΣ9¬ͺ½,‹‚κuφΰˆ#¨QόͺJΐ’΅ +‰ψ”qύm?φZν«‡ψ˜ptίϋk²S[ˆγ•ͺE5]MH¦¬ jE5]MH¦€'ž B¦€ƒO’œ J 8ˆp4&iΩ¨Α§gŠ@΄κ3M£4κ3MΝ fŒΣsE:ŒΣsFhΤf›š3@£4άњvhΝ74f€š)Ή£4μњnhΝ:ŒΣsFhΩ’›š(Ω£4άњu¦ζŒΠ³E74P³E74P³E74P¨Ν74f€E74f€š3M£4μњnhΝ:Šm QMΝ fŠnhΝ;4f›š3@£4άњvh¦ζŒΠ³E6ŒΠ¨¦ζŒΠ³E6ŒΠ³FiΉ£4κ)Ή£4μΡMΝ fŠnhΝ;4f›š3@ΝάњvhΝ74f€FiΉ£4μΡMΟ­μΡMΝ fŒΣsFhΩ’›FhΩ’›š3@ΝάњvhΝ74f€š3MΝ QMΝπ=Q]ΖAEPEPEPEP Ψ|QΥ!πEη†ο­αΏŠXZή)ζcΊ$#kΓιΗ\^}EQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEWΊώΜ?σ2Ϋ·ώΥ― ―tύ˜ζe·oύ«QSαcŽηΉ“Q±§Q±SAΤliXΤli€Œj&4¬j64Φ5ά|/9ώΣΆ_ϋ=pŒkΉψZsύ©lΏφzΐw”QEf0’Š(’Šd²$H^F £©'ϊ* ;¨ξў”ˆΖO΅OBw’Š(’Š(Δ³l΄H‡YŸ λβ’πΔ_$Σδ(ώgϊTZτrά\ΉQϋ¨#Ÿrύ_•jθπω|KŒ1γY%z—.φ‰vŠ(­H (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ ­-δ)pnέ+m^qυͺZή₯φdς ?ΎaΙώθ§α»vyήισΐ'Ή=Ο½CŸ½ΚŠQμθ¨’Š²Jښ»ΨΜ‘]†ΠΏ—€ινo©ΎξV4ϊ’?ύu»FsRβ›ΈΣ² (’¨A\/Δσƒ¦Ϋ_ύ’»ͺΰώ)uν―ώΙN;‰œRš‘MWSR©­XSR)ͺκjU4†N¦€ SR)€ΐΣΑ¨§ƒ@N£œ H 8Œp ζ—4Μ搗4ΐy₯ KLΝ;4΄f›š3@’“4™ fŒΣis@ E&i(Τf“4f€—4άP³E&i3@£4Ϊ3@’“4™ f–›šLΠ³E6—4Ή£4”f€ŒfŒΠΡIš(hΝ&i3@’›KšZ)΄f€Fi(Ν.h¦ζŒΠ³Fi΄f€E6Švh¦ζ–€4Rf“4μњLf€š\ΣsE.hΝ&i3@Νάζ€4f’Š\њnhΝ:ŠnhΝ;4Rf’€š3MΝ.hsE6—4Ή’›FhΤSsFhΩ£4™£4Ή’›K@ E&i3@Νάζ€ŒΣsE;4RfŒΠΡM₯Ν.h€Ν f“4Ϊ\ΠΡMΝμΡMΝ.hhΝ74Ή Rf›š(Τf“4PζŠLњ\ΡIš3@ E% ΝάΡ@’“4”κ)Ή₯ Ν€Ν&hΤf›š(Ω’›š(ΤSh ‚θ’Šξ2 (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ χ/Ω“ώfOϋvΪ΅α΅ξ?³7ό̟φν΅j*|,qάχj64γQ±cA€ΤliΜj&4Φ5s‰1 c]ίΒ£!Oϋe³ΧΖ»Ο…u_ϋe³–ΐ@’Š+2‚Š)“ΙεDΟ΅›Œ“@ί^Gg™)η’¨κMrσMq©έ*žXœ*ŽŠ?Οz}όww7Κ²¨38αΞΡύ+ ττ²‹ϋ·ήoθ+j;t/H’Ε•ΊΪΫ$IΡG'Τχ55VΫQEQE5£VVV« λNQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@UΤnΦΞΩ€<±αWΤΥͺŽH•Ψ9U. ν'΅'δδmΰšώψ«gy9v#₯uΦπ€¬qŒ*Œ ‡O³K8Š―ΜνΛ±κMZ©„9}J”QEY!EPEP\ΕSƒ₯Ϋ_ύ’»κσŠηΩ_φΧd§ΔΞML¦«)©”Φ‚'SR©ͺκjU4:š‘MB¦€SHdΚiΰΤ@ΣΑ€ σN’ž H 8T`Ӂ ζ˜ -6+‘„ψT?π—ύ²_΅oQ³gε}sžhΟh‹αφнΏφi8„ώέΏφ­EO…Ž;žάΖ£cN&£c\ΖƒXΤLiμj&4Δ1Dƞƒc@ c]οΒcŸν_ϋe³ΧŸ±α'][ώΩμτ₯°#Π蒊̠’Š(( Ž9d‘Wηs–cΤΤ΄Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@V^₯«ΕjΖ8‡™(κ3ΐϊm-Α+š”UM.I¦΅άcsΐŒΥn„ο¨yχŞΊWύ΅Ω+ΠkΟ>-œ'ώΪμ•QάLΰΤΤΚj²š™Mh"š‘M@¦₯S@©©Τ*jE4†L H B¦ž J ‡'΅Vψ‘#ˆΏλώoύ ΧIπWΒ©βGTυ-COςa_šΞM…Γ ·Ž:P?ƒΌβ˜5‰-nm`ώΜΚ$$ξΘoΊ@#ψ qυξΏ³•±ŸOρ}²6 ‚(Α=²%_Nψaΰ½UζτΏΛ>»ΫJ˜ΛΈ\rτc@%Ez7€Ύ&³γ[ΓΪμΣΫIa Ήkr>fͺ:ƒΑ ŸΚ§ρο€4_ θθk©w―›„­¨6#gͺύξ8δΰ{P™Q^>ψ'GώΟ°ρ7‰n±zͺPZ‘ε‚NΖγ9$gΪΉOxϋ β>™αΫ›—–ΞώhDs  ώ[ΎΣΗ 0 ώ‡½p4W·x“α/†ό?m{q¨ψ‰ΰ_%šΞdWUΟ9σ€?kšΦ<§·Γ+_θWS°Ϊn‘”©ςωΪψΐ†ΗαΝy΅θΪ/4σπΚχΕzεΥԐΔT yΪΉΘ'—Θγ°ΝyΝQEQEQEQEQEQEQEQEQEQEQEνί³Q‘ώέΏφ­x{oμΧ3ύ»νZŠŸΦηΆ1¨ΨӚ£c\ΖƒΤliΜj64Δ1BΖ€cPΉ ΨΧ ό"λ«ΫύžΌρΝzΒΞ­lφzRΨθ΄QEfPQEQEQEQAιY7ΊΗp–ςۜœ”ucJζ΅R}nξLμ+d%ͺj7ϋΉ'Ηv.@¨φ©μ‡Ιάλ:ΡPYΒπBI^VξΝSΦ„…Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@dfŠ(’£ΉG’&HίΛ-ΖμdŠΘΦ΅_/tΝϋΎΓψ}‡½gιs^J$”b<Ÿο{ ³Ž%Όa†[d8,O.{βΊ£XΡQU ΕEΙήEΆ’ΠpŠ(­ˆ σΏ‹½tŸϋm²W’W|^λ€Ϋoύ’œw85*MJ†΅a J¦ SR©€κjE5Τͺhe4πj%4πi ˜p54αH ζœ*1N€$—4ΐiA f”nhόњnh ζŒΣsFhΩ£4άζ€4f›š(Ω£4™€Ν;4f›FhΩ’›E;4f›E:ŒΣsFhΩ£4Ϊ3@£4άњu¦ΡšvhΝ6ŒΠ¨Ν74f€E6ŒΠ³FiΉ£4μњnhΝ;4f›FhΩ’›E:ŒΣsFhΤf’“4μњnhΝ;4f›š3@Ν¦ζŒΠ³FiΉ£4μњmμΡM£4μњnhΝ;4f›FhΩ£4άњvhΝ74f€š3MΝ fŒΣsE:ŒΣh fŒΣh QšnhΝ;4f›š3@Ν¦ΡšvhΝ6ŒΠ³FiΉ£4μњLf€š3M₯Ν.hΝ74P³FiΉ’€Fi΄P³E6ŒΠ³FiΉ’€š)Ή£4μΡMΝμњnh fŠnhΝ;4SsE:ŒΣsFhΩ£4άњvhΝ74P³FiΉ’€E6ŒΠ³E74΄Ή£4άњvh¦ζŠψVŠ(Σ ’Š(σΰgό•=ώΫθ‰+ƒσΰgό•=ώΫθ‰(ψη%O[Άϊ":ο?ζΦΏΟόWρΟώJž·l?τDuήΝ­Ÿωώ ΰgό•=ώΫθ‰(ψη%O[Άϊ":>ΙSΡ?νΏώˆ’΅Ύ2xk]Τ>$kV.§um'“²Xm$tlB€ΰƒΘ#π ›ώmkόΟυx={ύυΦŸϋ2=­ύ΄Φ·1γ|SFQΧ7Ή‘Αρ― Š( Š( tψˆΗώ…Ή<΅°ΘOGÏΕ_5― XΟ:ͺ»8V8ά +)>Δ©R{W\λΞŸ…Ξ£y5ŒXςν䝚4ΐΐΒ“€MW²ΌΉ°ΉK›‰­ξΛ ”eϊΝ{ίΒj~ΈΥυο¬-ΤΗ°Κ―‘Έ1c΄‘ό8©ΝAπFζ wNρΆŸ¬3߳Ȉ{$—8τΜWk#Φ΅˜Φ=WU½»‰NBM32ƒλŒγ>υFΒφλNΊK› ™­ξΛ ”aτ#šϊ?ΰ‡΅oάjΣkk op8’9ξ N[Žƒ‘ι\ημμν›γC΅Ρb`}Χ“ΙβίIvn›]ΥΙ]žbέ:ΆάηnAιžqT΄ύcSΣVuΣ΅ΛEŸύh‚vŒIΧο`σΤυυ4D’I$’O$šτΩΧώJ―9šΧ—Υ­;Q½Σ.>Ρ¦ή\ΩΟ΄―™o+FΨ=FAλή0ψAβ][ΕZΆ‘hΦgΊΊ’hχΜAΪΜHΘΫ[t;Ώ ψΟΔΊV’b7PA-·/Νσ ‘γΏπ™xŸώ†=k₯βͺ΄^#Φ὞ς-gRKΉΐΞ·N$€³“λ@Ιϋ8Ζ%ΆρteΜaΜ*\DΌΤ ΎψƒAρεΎ£©ˆ"°±.Βt”7•*0 s“8―°Υυ-9'M?PΌ΅IΖ&X'duϋΨ<υ=}MY“ΔΪμšwφ|šΖ Φ[vyαΚmι·ιν€=Ηαξ©m¬όvρUν‹+Ϋ΅™DuθΫ${€Χ‹κȚ‡―#ΎŸΛŽγSt–b~κ΄€ό¬½3SΏ§i΄»λ«)™v3ΫΚΡ±\ƒ‚TŽ2εU₯‘ε•δ•ΩδrY™ŽKΤ“άΠΣZ‰qα½oI±πoƒτ—³*­6§sv‹ζω‰bCΞI9Ο±~+ΙgπGϋπθσ^)'‰υΩ4Α§>±¨5ˆ]ΎAΈm›»ŒτφιP]뚡εδwz₯τχvδf–αΩγ δmbr9ηŠτΪ2Gˆ(ŒΔͺYΖzrΗϊΥΩ[ŠK­GΒzσ,u8£CΣ~ά:ώ) ŠςGP½Τξ>Ρ©^\]Ο€ΎeΔ­#`t$œW€|Τ΄ΛͺkšεμQέΕŠΦάδ»q–#ާGΤЏš΄cIπ~–vΩι±#Κ ά >αrΰuγΥ{[Τ5^σQΌmΧR΄―θ =°ιTh’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(―lύ›zxώέΏφ­x{_μάδb·oύ«QSαάφ¦5q5ζ4Ζ£cOcP±¦!Œj&4φ5š`FΖ½ ΰ]_ώΨμυηnkΠώυΥνώΟS-‘EVeQ@Q@Q@ͺZb]KΎβYXˆUϊ)4žΰŠ–ϊ}¬δ…3κFOλVρE°Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@’¨jΡ³[’Σ΄q‘ζojMΩ\ώ±ΆR0u?ν·ώΙ^^qρ‡‘mΏφJ¨ξ&yκ™MWSS!­ ,)©PΤ jU4†N¦€SP©©€&SR)¨TΤ€ 4ρQƒOŠx4ΰi‚œ <QL—4ϊ¦ζ”@:ŒΣsFhLf“4f€ŒΣsΕ.hhΝ&hΝ.hΝ%€4f“4f€4f›š\ΠњLΡ@ š)3FhsFi3E.hΝ&hΝ.hΝ&hΝ.hΝ&hΝ.hΝ% Ν€Ν Ν€Ν Ν€£4Ή’“4f€4f“4f€4f’ŒΠΡIš3@ š)Ή₯Ν-€Ν Ν€Ν Ν€Ν ’“4f€4f“4f€ŒQšZ3Iš3@ š3Iš3@ š3Iš3@ š3Iš3@ š3IE.hΝ&hΝ-€Ν Ν€Ν ’“4f€4RfŒΠζ—4άњ\ΡIšLρ@Ν™£4Ή£4™’€4fQš\њLf€š)3FhsFi(Ν-€Ν Ν€£4Ή£4™£4Ή£4™£4Ή£4™’€4f“4f€4f“4f€4f“4PζŒfŒΠњLњ\њLΡ@ š)3FhhΝ&i3@’“4PΓQEv™Q@ixwY»πφ΅kͺiΜ«unΕ“xΘ9G‘ŠΝ’€4ΌE¬έψ‡ZΊΥ5VΊΈ`Ο°` ΠiΒe«Β·™φ^ύψΩσύύϋsž›Ήι\έ₯αέfοΓΪΥ©§2­Υ»Mγ δA„+?α|xŸώ|4_ϋσ/―%’€;|UΧόU’Ι₯ίEa¬¬­'Ω£p_ f”%™α­rΛΔz%«₯Θd΄ΈRT‘‚$Gb"΄θΨŠ( ŠαΎ%|G±πšz_Ψέ]}΄HSΘ*6μۜδοΚΈ―ψhώ€ΊŸύυV©Ι«€+€{uβ?πΡ:'ύu?ϋκ?ώ*ψhώ€ΊŸύυOΩO°Ή‘νΥIυ(SŽΔ·ο oAυλ^U£όvΣ5}NήΖΣDΤΌι›h%£ΒŽδσΠjάΧ“K~׌ΔN_x#±νŠσρΨ§…q]_δtΠ£νnΟW’Ό‹_ψέa j&ΗPΡ΅™U[̍“c‚:Œž™Θό+;ώ'D .§}GΕWl"κEJ;3ϋΜφκ+Δα’tOϊκχΤόUπΡ:'ύu?ϋκ?ώ*―ΩO°Ή‘νΤWˆΓDθŸτΤο¨ψͺ?α’tOϊκχΤόUΚ}ƒ™έEx‡ό4N‰@]OώϊŠ―cΡoΣUΡμu‘£ŽξQΊ¨e χζ¦PqάiάΉETŒ(’Š+Ν~2υΡν·ώΙ^•^iρ›mΏφJ¨ξ&y•M@•2Φ„“‘©”Υu©”Πκk‘π/όzwϋηA5Ξ-t>‘³N|θ&…Ί°ρ.“β ŸΙ>–fŽl‚`ͺ0£ά1¬―kΊŸˆξ­­ofŠ©…CŒeA5ŸΰI`ρL3ίJO›ΉYNβ8$ύxόkFΥμ/3xψ[@‚t±ΉΥ€ƒ``'Ά1ΗКηυ]Ωλ‘鋉R<§ΏΆ9Ο·5κw^$šhΆY₯σ<νΰlηλ‘Z:ξ―iŽtΝΞ»mΓ$―ΩK9>ٝ'ΥXw)ΛαmΡ’χVdΏp02‚}±όΘ©~%FBi™€‘F;Ÿ’£ρ/…5Kqkε½Όε[Μ.Ξδu=;UŸˆ2­­Φƒ+|λ³φ€(i΅dτR¬^Σ,-‘:φ ΠΟ(α€τ9Η―JΛρ‡Ž›wjΆΣ¬ΦχDˆ'O§=k{Ζ%ΦΉqk₯Έ…⠍ΰc’sΟΧτ¬kο¦Ÿ©ivχ·ΚνpΚ² ΰ ΰuτμ )G₯†™£ζ‡o<6Wz”ΖϊP0rzv?©¬y|=4~$M$Hσ•—ÌηΙνf°Φ-­τ½Ρ-χN °ωΞs\ΦWˆβOY­œρΑqε)G“§ρqψτ¦β» 2½Ζ‘ω—κrE{εŒδΟδ?ŸηW~[XͺΌλ6ν@«+Ǟw•kG Ϊ”—6Ϊφ—DS‹•# ξ;Ž9λ\ΟΓΆŽ=~κ5|ƒ'ψ°ΓϊQd€ƒ‘•β{{+mD‹ “8|΄„‘ςΆOααŠ€Χώb²ΌC§\iΪ”‹t yŒΞ„09\žkSαίόŒώΈ·σ γΨΦΤτ-~}Fζ[kΒ°<ŒΘΏhaž8¬] GώΦΧ/-5εσ!VάκΩ%•‚υ5±ͺh:όϊ•ΜΆΧe`y‘~ΠÞ8¨όm=ŸŠo Ί`Σ¬y9%”υόj­Α}Γ7Ϊ ”Ί£όΰ"‘€}:rΚ΅Ρ$ƒΕQi·ΊIYb8$m$ωV§ό"š‡ό$Ύ~S쾝ηoΖμτ뚳uuΟΔk! ‘ˆυΪΔ:9W`ΉŽϊ Ίρlϊj\HȘw–O™±€OΤδβ§½ΡtV‚μXjN·6Ω ·Δgΐτ«2Ηw'Δ―°O 3¨χΉΓ‹‘Χ­[ΐu=>ϋϋ{MŠΥαRVpAϐzŒ`P’Εs“πί‡Ζ₯·—“ύžΚ. ρ“ŽΌž€zΥωό3a{e,Ϊλ\Iω£r >έ XΠjώ ΈΣ-Vι;IΖ~mΓσιV<%₯άh {}ͺ•‚0˜ΫΈ6psž?O­ +MΩΟxg@ώΦΟq/‘gί~δγ$sΐΐκk«πΆ™₯[κ\ι7ΝqˆΜnŒA#$τ•αfMWڞ¬W.ΜαOcπΘΕXπN{₯ίOq|0јΥ-Θ9γιϊӊΪΘLηlτy5ŸލεΔ’»I!Ϊ7Φ΄βπώ‰¨4–ϊV₯+^ '>VΗΰ3ψ³ΰλ¨γΧυ›W*²Ο#χwΓ6GλZ6C]N$°νQύψ\ƒτΓf’а\σyγx&’)Wl‘±V„pj<՝VvΈΤ¦s3ΘĘσ΄σΤgœULΦEΝάζΕΝ€’€4f“4SsFi)(Ω£4Ϊ3HQšLњ\њLΡ@ Fi΄f€š\Σ( fŒQš`.h€Ν% FiΉ’˜Ν€Ν&iμњJ3@ š3M’˜Ν-74”€vhΝ% Ν¦ΡšuάΠζ—4Μњu€€ fŒΣii€Ή£4άisL₯Ν04f’’Ν”™ QIšJvhΝ%%;4f›š)€μњLRΩ£4άζ˜ š)3Iš@;4f’ŒΠζŠm.hsFi(Ν.hΝ74f˜Ν€€ fŒΣsFiκ3Iš)€Ή£4”f š3IE.hΝ6Š`;4SsKš@.hΝ&hΝ.h€€ fŒΣsE?4™¦ΣsFi3Fi΄ShΝ0š3M₯Ν.h¦ζŠψ‚Š(Γ ’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(―gύ?ζa·ύ«^1^Νϋ:ΜΑnϋV’§Β5ΉμQ±§΅FΖΉΛΖ’z{‰0#cQ1©Τ-@ˆΨΧ€|λ¬ΫύžΌΥ«~ ΜgώΨμτ₯°Ρι΄QEdPQEQEQEygƟ‰©ΰϋ?μν%’]vα23ΘΆCόl=}βxΰΈΕΙΩ φ6ώ"όJΡ|—rΖοSa˜μ‘a»‘cό#υ=―šΨζΊ”cM]‘vΟ#ΖpφΆ΄ί x‡Tιϊ§p‡ψ£ΆrΏž1_bx[ΐžπΒΖt*έ.cν22cοΌς>ƒΪΊ| ‡_²)ρΗΓίΫF^_ κ‘Gχm™ΏvξζΞO.ςΪky?Ή4eς5χώ*₯§Ωjvm©ZAwnz9γ§π4*ύΠr hΪΎ£’^ ½"φβΚγ¦ψ\©#Πϊc^νπογΖωb±ρ’*n!WP…pύtAόΧςο[~9ψ€ji%Ο†$ώΛΌΗ1-nΝ—πΘφ―œόG j~ΤίOΦ­$ΆΉNpά‡^Μ€pAΑδUϋ•΅‰χm΅ΔWVρΟm"K Š`zGZ–ΎEψAρ:λΑ—©c~\h37ΟV·'«§υ^ZϊΞζΛXnmeI­ζA$r!Θe# b+žppe§rj(’ aEPEP^?ϋHψ³ϋ#Βι’ZΘVσTΘ“ΓϋίχΡΐϊn―\Έš;x$šwXαK»±ΐU$“ι_όFρ4Ύ.ρ}ώͺε„ή]Ί1ϋ‘/ =½OΉ5­(έά™;#Τf?›}FλΓ7nLW9Έ΅ΙαdQσ¨ϊ¨ΟόϊΧΡυπ&•>—©ΪίΩΎΛ›iVhΫΡ”δWά~Χ­ΌMαΛ ^̏.ζ0Μ ηcτdόψUVΕΠΨ’Š+Ού€|3­x†γΓηDΣ.―„ qζSv̘ρŸε^/ ΧΖτ-κ_χδΧΫV±ͺβ­b\n|O ΧΖτ-κ_χδΡ ΧΖτ-κ_χδΧΫU{wΨ\§ΙžπΗ‹<3msqmαMF]Na±d–#…:“ξN?Aξ+Τ£ ±CœΆ'ΤΧ¬κ'$uς›ως~΅σΩ½œγ+jξzX6ωZ<7Ηκκ¦{-Nά.₯§ά(…kγ/ϊυ/ϋςkλ[Λgα Ϊζ6Šxl`ŽDa‚¬#PAΉ­Š*'QΜiX(’ŠΜ ’Š(―3ψΟΧGΆίϋ%zeyŸΖŽΊ7ύΆΩ*£Έ™η R‘¨ΤΛZN•*š J¦“©«ΣΛo*Λo#Ε*ςŒU‡ΠЬ¦€Z@Zžβk©Œ·2Ι4§«ΘŘώ&TKOS@λZœVώDwχK %8Πz §œœšˆx4\ υ[τΆϋ:^܈1,HvγΣ”Λ‹Λ›₯EΉΈšeŒaŽX/Σ=: ©N‹zΛSΎ²B–—sΒ‡’¨δΚ‘–i'•€šG’Fδ³’IόjiEBM[P’…οnZ%ΖΘqΗJ†{»‹™D—3Λ,€`<ŽXυ5[4 Ρp4&Υυ ΰςf½ΈxˆΑV~Ύ΅R)^)H‘Τδ2œψΤy’•ΐ³wwqxκχSΛ3€dbΔΖ’ΪζkY<Λi€†LctlTγκ* њΡώΩΤθ#{ΫόkcΑZ¬VΪΥΕΞ§rG™ _2BX±Κχϊ ε³Fi©4ξ5n΅{Α=Μvχ· n1UY z Ο†y •e‚GŽEθθΔψŠŠŠWwΉžK=ζ•§Θ>ab[#§=j{­Vώκ*ζςycώλΉ ύ}jŽhΝh.%·”Io#Ε θΘΔψŠšσQΌ½]έM2Ž@w$Β©ζŒΠ°Ν$ !‘γ‘z2όEZ}_PyD­}uζ€ήkdNΎΥC4f‹!•ΪS!v2ΈΉ<ηΧ>΅n}_PΈƒΙžφβHZBAϊϊΥ Ρš.³E6ŒΠ1Ω£4άњvhΝ74P³Fi΄f€FiΉ£4μњnhΝ;4f›š3@Ν¦ΡšvhΝ74P³FiΉ£4κLfŒΠ³E74f€FiΉ£4κ3MΝμњnhΝ;4f›š3@’›š3@Ν¦ζŒΠ³FiΉ£4μњnhΝ;4f›š3@ š\ΣsFhΩ£4άњvhΝ74f€š3M’€š)Ή£4μњnh fŠnhΝ;4f›FhΩ£4άњvi3IFhΩ’›š3@Ν¦ζŠvh¦ΡšvhΝ74f€š3MΝ fŒΣsFhΤf›š(Τf›š3@Ν¦ζŒΠ³Fi΄P³E74f€š3MΝ fŒΣsFhΩ£4άΡ@Ν¦ζŒΠ³Fi΄f€š)Ή£4Ή₯Ν74f€E74f€š)Ή£4μΡM’€>#’Š+°Θ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š+Ωgoω˜?νίj׍W²~Ξσ0ΫΏώΥ¨©πn{©δΤm\εŒj…ͺF5`FΥš‘ͺ4«Ύ uΦνώΤ―4jτ―‚½uŸϋc΅)Ka£Σ¨’ŠΘ ’Š(’Š(ρ‰νό!αkΝ^δhΖΘbž’ŸΊΏNηΨ_κϊή―©άκ„Ν=έΓ™$vξOς€μ+Χ?iΏ=Š-΄(Y…Ύ’AžWύn?ή5ΘόπˆρŒνν:Τ}’θΑPxOψΐϊgΊ©₯σ39jμzWΐ_…Ρ<ώ&ρΊΙΌ±Άdc΄¬;²?Jϊ ˆͺŠU€-sΚNN촬QEHŠ( Ή―x7LρžŒφ:œad0\¨ωαP}=GCϊΧKE4μξ€ψCΕ~ΎπΖ»s€κ‘νΈ„πΓΊΛμGωΝ{/μΧγ‡ŠιΌ)¨Ι˜dέ%‰oαn­Ќ°χΦ»Ϊ#ΑλψM΅‹X‹jZX2ezΌΖ>χΰ}kε» Ήτϋϋ{ΛG1ά[Θ²ΖΓ³)Θ?₯u&ͺDΟαgίΤVW…uˆόAαΝ;V…B₯δ .Πs΄‘ΚηΨδ~«\XΠ(’Š(’£Έš;x$šwXβK»±ΐU$šς/ΪGſُC΅ ΝS"@:¬όίχΡω~›«ζ}MΉΦ5kM:Ε7έ]J°Ζ€ΰn'ϋJΩψβy|]βϋνUΛωΫ-ΡΏ‚%αF;zŸrkΥ?f/ ωΧw^'ΌC² ΫZ^ σΈϊώή•ΦΏw?‰žUρ Β³ψ7Ε:LξfBΙ ΫqζFέη}Α―Qύ˜όZm΅+― ήH|«œάZό2σ―β£?πλ]Ÿνα/νΏ .±k5φ•—m½Zχ,ϊυ―˜t«ϋ/S΅Ώ³sΝ΄«,l;2œŠο 3οΊ+ΒυΏ‰Ό7a«Ϊ`Gub³ε·FSτ ΒΆ+‘«Q@Q@΅/ωάΧ&ώFΌ t―YΎRφS¨κcaϊW™%Œ₯KzΩ‚ˆΰ—ρ©ξtQEb0’Š(’Š(’Š(’Š(―2ψΣΧFΆίϋN½6ΌΗγW]ώΫν:¨ξ&yΊΤ©P-L¦΅$MJ¦ SS)€2e5"š…jU4*š‰iΰPiΒ£œ(QJ 0p4 x₯˜)A€©A¦ζ@’›š3@£4άњvhΝ74f€š)Ή’€š)Ή£4μњnhΝ:ŒΣsFhΩ£4άњvhΝ74 vhΝ74P³E74P¨¦ζŒΠ³E74f€E74f€š3MΝ fŒΣsFhΤf›š3@’›š3@ΝάΡ@ΝάΡ@’›š3@’›š(Ω£4Ϊ(ΤSsE:ŒΣsFhΩ’›š3@’›š3@Νάњvh¦ζŒΠ¨¦ζŒΠ¨Ν74f€š3MΝ fŠnhΝ:ŒΣsFhΤf›FhΩ’›š(Ω’›š3@ΝΪ3@’›š3@Ν¦ζŒΠ³FiΉ£4κ3M£4κ3MΝ fŠnhΝ;4f›š3@Ν¦ζŒΠ³Fi’ŒΠ³Fi΄f€E6ŒΠ¨Ν74f€E74f€FiΉ£4μњnhΝ;4SsFhΩ’›š3@£4άњu¦ΡšuΪ3@’›š3@’›E|OEWaQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW±ώΟσ0ΫΏώΥ――cύžΏζ?nϋR’Φ簚9©\εŒcQ5=ͺ&4ΐͺ'5#TM@ˆΨΧ₯|λ¬Ϋύ©^fΥιŸϊλ_φΗjR–ΓG§ΡE‘AEPGΤγߊ‘⠚ίAΤ¦O½΄>‘  ‡ΌW©Ύ³βmWQ‘‹›©%œαK£π…}ϋ0θΡΪx.λU#ύ#PΉ+»ώ™Ης}―—G"ΎΡψ1jΆŸ ό<‹όVζSυffώ΅Υ[HΨΞ;­Q\¦EPEPEPwG<C2ŠE(κz2‘‚+αi‡Eρ&©¦βζHF{…bόF }ε_|} ψ­­Ζ7ω.~¦'υ­θ=Z"G²~Μz—ΪόqdΞKXή:¨=‘ΐa―_―e ˜]x–ό…mίωWΡU€Κ[QYŒ+Ηi/dψb=Φ@/5<‰pyH_ϋθα}Ζκυ뉣··–yάGJ]άτU$ŸΒΎ%ψƒβcβήκ—"Z»ωp Ήhα^c#žηž€Φ΄£w~ΔΙΨΓtωυ]NΦΒΡTά\Θ±¦γ€ =IμR}+λίήΪhZ~ h‹›K}΄Ξ9|Ÿ˜κI'>υγ ƎπΞt}>ιv ²ήάͺεۏ”`Ÿγ^‰dώ]μέdVύkΗΗζSφžΚ Ι}πκhςσ=OVš$žŠdWΑVF ΧΔί<.ώρφ—τmήm³z&ϋΏˆεOΊšϋrΌφπ‘Φό&ΊΕ€e―t¬»m/ ϋγώΓ}zΧ±FVv8dq_³'‹~Λ©\ψfςP!ΊΜφ™ν(:ώ*3>΅τ| ₯j:V₯kc!ŠκΪE–7™NE}ΗΰύvίΔή°ΥνΨξ’S9(έOΠ‚? ͺΡ³Έ’͊(’°,(’Š Q‹L‚=,Ψ(>IR€χ9ου«ΤTΈ©n†›[|XŒEρ#Δ―έK’£π½›φSΏ_I WŽ|^’›βOϊϋoι^Ηϋ)Θ_―€Π+²jΤμgˆχ:(’ΉK (5ͺλ bΆΓΛέΊ…IΙGV4h]ήAjΉš@3ΠIό*->ό^Όž\l#OγcΤύ+š΄ΆŸQΈ'$’~y΅u––ιkΕωGSλQ9kΠm$MEV„…Q@yΖΎΊ7ύΆΪuιΥζ:θΏφΫiΥGq3ΝV₯Z…MJ¦΅$ J† Z™i ™MH¦‘Z•MJ¦·4 jΊ²‰--[Ι?ςΦC± υό+¨ψ{αη†=SUz7Ν-Џο0ομ+Σ8Uμύ+HΣΎ¬–Ο,O‡:™\½Υ˜o@ΜφZ£¨x'Z³BΛ w*9&ΙόŽ όzlή!Ρα“Λ“R΅Ё 8όͺύ΅Δ7Q m¦ŽhΟFƒΜU{8±]žΚΘμ₯XF’½‹Ε~ΆΦνΩΡV;ε$£Œϋ7¨ώUγχΙm<Ξ…%Š²žΔVR‹‰Iά@iA¦ŠHΗζ”e(4 vhΝ&kΣΌ1α&σA²ΈΊ³4‰Ή˜ΘΓ<ŸCN1ζΨMΨσLΦ―‡4Kr풁„q έ$Œ2SνSxΚίNΧ₯·³Λ„"Ή'’=λGαξ΅m¦]\Azβ(ξντgƒωΣKή³ θ πdϊ]‹]Αp.cŒfA³k(υœŠδσ^©βίιΡhΧ0[άΓq<ρ˜Υb`ΨΘΑ$Žœςš&’z Ν¦Ρš’‡fŒΣhΝ;4f›EuΎπlϊ­’έΟp-’υcfζaλΤ`VWˆτ;νb„‘Θ ŽE λΗcώ5ήxCΔz|š5΅½ΕΜVσΐ‚6YX(  λΕs_΅»]NβΪήΙΔ±ΑΈ΄ƒ‘'Λυ­cΛtJnη%š3MΝ¬ΚšžΒΦkλΘ­­Χt²ΆΥΦ«f΅<3¨¦—­ΪέΚ  Ž A?­ q<§[BΡ_$—gΛ)…'Π6₯pς+G##©WRTƒΤφYόI€Ehn>ί2>Ϋz׏j?kΏΉΉΫ·Ξ‘€Ϋι“œUΝ%°“dY£4Ϊ* FiΉ’€FiΉ’€š3M’€š3MΝ껦iwΊœ…,mžR:‘©Iωϊπ―ΥlfΣu ­.ο#ldt#±QYN£Nεlњm©(vhΝ6ŒΠ³Fi΄f€šLfŠvh¦ζŠu¦ζŠvk¦πΟ„ηΦ­ΝΛΜ-νςU[nβΔuΐγzεσ^•ΰ?X¦άρΫΝ yŒ8$œ‚xΟ5PI½DΞOΔήΈΠ€ŒΌ‚ky8YcŸB;Vk·ψ‰ΩήΑ”‰>Ι<Η‘T`=ϊšΐπu”‡ˆ-­ξγσ `ε—$tRGO|Q$Ή¬=51σFkΣΌEαΣC½žήΜ$±ΖY[Μsƒψšςό”\wξvΊO'»±IξΕ»H»–1βιžGε\Φ΅¦O€_½­Π€ά¬½Oq^₯£ψŸLΌ°ŽY.ΰ‚P£ΜŽG TχΖz₯yŽux5m`=‘έ H#Œn9$Ÿ§5rŒRΠI»œώhΝ74f³(vh¦ΡšvhΝ74P³FiΉ’€š–ΦΊΊŠ@2JαŽIΐ¨3Z>‘ƒL―˜τ!B­N΅›³ύ+˜πΞ’š^·kw(&4$6:€Aώ΅κ“ψ“HŠΠά}Ύ\d*0.}Άυ­ ’Φ€ΆΟ‘Z9$]I Šnj]Bηνwχ7%vω4›}2sŠτo xgIΌΠlξ.¬ΓΝ"nf20Ο'ΠΤF<ΞΘmΨσLΦ―‡ti΅ΛΉ ‚XγdMδΎqŒΫλSxΚίNΧ₯·³Λ„"Ή'’=λ[αwό†nΏλάθKMGή³τ!Τόw§ΨOw%Τ ‘.⫝̸ŸΉJφoΘ΅¨Χ#^/šsŠ‹ΠIάvh¦Ρš‚‡fŒΣh fŒΣhΝ;4ShΝ;4f›š3@Ν&i(Ν;4f›E;4f›š(Ω£4άΡ@Ν¦ζŒΠζŠJ(βͺ(’ΊΜ‚Š( ―ιš>§ͺ—^yzSο}š“oΧh8ͺυΐx"‹α†”ρ’«ΜΣ<„ΌήkOΰ ~σwό!Ύ'‘sZΐψš?α ρ?ύ šΧώΛΔΧΪ4PΕίπ†ψŸώ…Νkeβh„7Δτ.k_ψ/_hΡ@ΏƒόJŠYό;¬*’M” |Φ€†Α΅}έ_$|k‚+‰ϊβ@ŠˆZ' βh‘˜ώ$“ψΠEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP^Εϋ=Μώέφ₯xν{μω1ϋwΪ•ψF·=ͺ6§5FՁcZ’cOj‰FΥTQ51΅zgΑ.ΊΧύ±Ϊ•ζ-^›πG΅l?φ₯LΆ=FŠ(¬Š (’€ ««[Ν.ςΤuž‹ώϊR?­Z£ι@ŸEJ¬0Γ‚+쏁wίnψ[‘±9h‘ΰ>Ϋ$e ςίčτkZ{Œ*\³Ηωζ2γ¬+ΪΏe­|K¦jš¬<Θ$pŒςQ°¬>€…?π*λͺ― £8ξ{½ +Π(’Š(’Š(’Ž}(―>8_%Ε-vHΞV9RΕ#T?ͺšϊϋ[Τ`Ρτ{έJτνΆ΅…¦rxαFqυ=+α Nφ]KR»ΎΈ#ΞΉ•ζ|y˜“ϊšή‚έ‘3ήΏeG β;ΒΖ0DΈ‘ ϊ ΌΗφuΡίKψoo4ΙΆKωžλž»NDΟγ^YΤw“)lQQέO΅Ό³ά:Η J]ݎ¨$ϋb gώ>-ώΘπΌz¬˜ΌΥ2$ΪΨ)žο£ςύ7W̚uœΪ…τ–ΛΊiœ"s[ŸΌM/‹Ό_«9"o.έΖΘ—„\r}Ι«ΰή‡ζM6³:±ζ(3ύοβoΐqψš½e… ζχύEN¬ΤOHΠtΈ4m&ήΒΤ~ξ%Αl`³wcξMwZ.†/|;+ς>ψ˜φΫΗδywN΄{λΨm£λ#`œtΟε^§o ApΔ0ˆ‘@φσΈ ήr©S_σg£ˆ©μŒG―έ¦ΝMΕ*‡Τ«)θAΰƒO’½γΟ>#ψ™αwπ‡Œo΄Ό³gΝΆbsΊϋΏˆεOΈ5ι³'‹¦₯uα«ΙŠο3Ϊξ?ςΤ™GΥFΰ'Φ»_Ϊ7ΒΫ^]^Φ0ot¬ΘΨ^^χΗαΓ{ή΅σ—s₯jV·φ2­₯YcqΩ”δWZύδ φgίtV?„5ΫψoOΥν8Žκ εΈέ~±\XΠ(’Š(4PhβŸ‹ίςS|I_mύ+Ψe?ωλυτŸϊxηΕοω)Ύ$―Άώ•μ²Ÿό€uϊϊOύΊͺ|qάχ:(’ΉMbσ’)½ ^΅‡η\U‘ΆS€ ω›ίΪΊ*\T·v#††0‘(U©(’¨AEPEP^_ρ·‹mφz…yΖήΊ/ύΆΪuQάLσ5©’ J•MjI:š•M@΅*2Φ·‡,?΅5»+<²Θcϋ½[τ²Ίί†;OŒ¬·uΫ&ίΖλΣZ±έ,qͺF‘Q@UQΠΪΌŸβ‰gΌΤfΣmdd³Ά>ӏ1‡\ϋΖ+Φ«ηKΒΖφs'ί26~Ή­j;+ #A­=X»Ρ―βΝΘηηB~W„VP4ρX^ΕBiΧqίΨAwϊΉ8Οlφ―8ψ₯§¬½μjΈR―Žμ½"?*κΎ>³έΣ/¦σY6dΩβσΞ>›N₯o-crβΓπϋN’άέ]‚ΚΒ«Ϊ|>FΏœά\ΘΆj، oqΙ=9ν]έ§όzΓώβ*ηΌ[βΈ΄&H#‹Ο»q»i8T§ό(qŠWavDώΡΩ6―ΪUΏΌ$ηυΗψ£ΒW*˜_νyΑla“κ==λ Π||.οc·Τ­#Yc'ŸP{{ΧqӎνθόkΣ¬g76Vσ•Ϊe_™Εν°3\πž±¨5άσά$ŒΒΗάWα[jΪ΅ύ¬ςΜ‰o₯1“σcœŠκ|Mγ4mZK4³IBͺΆβδuτ¬―†r™υ½NR6™~=2Ω€ω\¬ φβXιš5Υδ7-$J W==λ3Α~΅ΧmξdΉšhΜNΘη#άWuγωuχώ„+αOόxίΧEώT8d‚ϊκ^EςNžRΟ&$iH*‹ƒΟsœ~u«kΰM&(€›Οϋ±}ΏΉjqid·“)`˜V' ?Hρτ—:ŒP^ΪG2°@θΗ+ž9λM¨'¨jΘόGΰe‚Ωξ4v•ΚςΠ?ΜHdJ±’x n’jHΣ0Ɋ6Β―±=Ο»ΊβΌOγVΣ5'³²·IZ.$y Ζ}8Ζ:°»e‹ΟιRΖΒέ§‚L|€6ΰΈ?γ^yι75ρΆΊœnG^Ž=EzΗ…΅ΔΧtσ8Κ•d‰œ€}G΅`όT[J³ΈΗΞ“lΩ”Ÿύ”R”SW@›½Šπe–©’Ϋ^Mqr’J *…p0Δz{V7Œτ+} ζΪ;ieJ…‰“`ϋ τΘ©§ΊίϊOβ±Εύ‡ύsoηJQ\·υ5Ώα^ιίσυwω―ψQ χNŸ«ΏΝΒ²αbέΟ„χ٧š½ώ΅ \άΪEokΡKŸoozk‘θƒTfΒ½ΣΏηκοσ_πNλC‚²J`.‹Όγw*¦;Χ¬_]Αck%ΝΤ‚8cf5ε–ZΥΌoz¨cI']ͺO8ŸΚ‰Ε+lια^ιίσυwω―ψWα[[’Κy$HΥY·&3Α’½’Ό·αηό³Χ9?˜’QI LΨΏπ¬vs=€χR\>Z1\νž*m3ΐQB§PšYζ#‡j§z즑!…ενDRΜ}λ^y'ΔY~Φ|»Νz3δ}z mF;‚»/jώ΅{vm.Y#œtI*ήΩκ+Ξn"’ήy!™JKe=ˆ―w²ΉŽςΞ˜I1ʁΧ>„WšxώΓ‹ Žο:wbΕ ©œU33Γ^»ΧΊ ͺœ4Μ3Ο Νv±xJXΐ’[§~νΌΘbΊ}>+ (mmΧlQ(QοουGΔΎ8}τ––$ΟΪς9;CwJ|±ŠΤ.ήΕk―‡θ·›{™Ρ›Ζυ γŸj±qΰ >8$quvJ©a’½‡―ψKΕ‘λ’5΄ρ.ΥwUΗ|{ϋWE{sΧ6ώTΤbΥΠΟΝšnj{¦φά?έσ?LΦžΩαύ=tΝΦΥTTύάςOη\ΧΔ?K`©§Ω9I₯]ς:υUθχ<“]­xΔΗΕ—Ί˜ϊlύzήnΡΠ…«9βrrzšžΞξ{+„žΦWŠUθΚqU³FkCΧ-mAΤfcΩG\}OςƒΔΊδˆšU2HηlqƒΗϊ Q‚JμθŒ+ο‡φ/ϋΔρKΫy ΏΘ‚Γαύ³ΪFogΈKŽwͺ2νΞ{q«XόD”έ(½³Œ[“‚b'r^zώ•θQH’Ζ’FΑ‘ΐeaΠƒΠΥ%l ΄xχŠτh4mb+Ky$txΥΙ|g$‘Ψ{Wa χNŸ«ΏΝΒ°~$ΘΡm\BjυQŠmƒg§xζv½žEΆYbEΖφPx$τϊV€ώdˆ¬Fβ'Η ?‘ͺώ*ρ™΅²³·IdŒ1œœFpφ­ λι―Y<ž_•4MΆD#ž„~Ώ•4‘{»ž[βηD½ς.0ΚΓtr/GΠϋWCα? Ωλ:@»Έžα».Œqυ½ρ6έeπϊM΄o†U!»€x#ω~U'Γ_ωWώΊΏτ©PJV θs'π½“6œM;‹™|ΆήG#¦½vΊ†l4I^k6I˜mί)θ0aόM˜ΫdLγΜψυΖΣW<'βΙ5έFKW΄HBDdάž„ tχ¦ΉT¬Ψθυ+DΏ°žΦVeIT‘+ΤW›xΛΒφΊŸ φΣO#<ΎYŒ`žΓΪ½XΌ:~—sv¨Β…φ“ŒΧ–ψ›ΕRkΆq[½’ΒO3p}ΩΰŒtχ§RέB7:=?ΐ–:}΄οstX•Θp ϊVSxkOΕƒI–βΰFρςΉ-׏@kΠτ?ωιυοώ‚+Ξ<}q%§Œβ‰"HέOΈζ”’’Έ&ΩΏ/ΓΫ-ό««―3nβΈΟlρ^k*4Rξ;λ.‘ϋ’ qνžΥετ°ψ‚IPb+‘ζχΊ7λΟγJ€RW@˜ίx}5닏΄<‘Α ™1’Δπ9φ·uΏιš^•sxΧWGΚL¨%yn€tυΕnό?°ϋ‡!v’δ™›θ~οθόkβmλHΦZTΙ+ ύ”~yό…©Fμ/vr~πυήΉ3yŽ8y˜p=‡©φΣΐšLQ9žwξYφΐ ί,"Σ4θ- lk‚Ό{ŸΔΧβOλΏΪ3A₯ZΟΌLPH-ΛΗSΘ#”ωTV‘vΛχώΣεŒύŽi­δν“½Χυ―=Φt»­"τΫ^&ͺ°ε\zƒ^‘ΰΝoRΏ–Km^ΦD‘WzLb(žAνžjOˆ– wαι'ΫϋλR$Sνœ0όΉό(”SW@›Lς\֏‡όTgύ|Η‘ ΜΝhψpΕC¦ΧΜϊ¬Vεε^βC§_2θF½ΒΌ;Δ‡ώ*OώΎdЍmWbbgζŒΣkcΒzhΥ΅Ϋ{y0‚^OχG8όxb•τ(ΣπΟƒξuh–ζεώΝhyRFYΗ°τχΒ/hΘ€:O!ώσHAύ1]1) D©/Π(ηϊ‡Δ6[¦[ 4hΰ<€ε½π:Vό±ŠΤ›ΆYΥ~ΫΌlΪeΓΗ'd”ξSψυ­yυυ€φ7R[έΖΡΜ‡M{…όA½jξˆbž2‘“œg‘Έ¬‰ZZ\ι"ύχφΔGR„だώu2‚jθθΞΓΊΦΉtc·ΒDŸλ%n‹ώ'Ϊ»ϋOιP ™ξΉ/΄~VGƒΎϋo†ΰ s%Ή0·αΣτ"°>*Ωσc|£Φ?ͺμΥrŠεΊ%=LOxv=z[“q$‘Α ŽS,~£ΠΊ—ψ{§ν;.ξ·cŒ•Ζ*π ‡Ψ|70Δ—ΜߏOΠ θUΥσ΅ΑΑΑθj£mA³ΐ¦‘™βaъ°τ"»o ψ6ΫTΡβΌ»šxήRvͺ γΈφ5—γέ9­ΌNώR|·x‘ξΗ‚??η^©§Z­–Ÿml!SλΦ’Υάmžq«ψbΒΛ]Σ4θ.ά“ζ+•^ƒ}*ά…{§ΟΥίζΏαXrί}ΏβL.§1Η8‰>‹ΗσΙόkΣκ£ξ&Ωζ~π΅–­oq=ά“ώζsD`ηzτ˜"ŽcŠ (UQΠΠW”θ^+“BŽκέ-`σ΄›‹γ:{W©ΨΞnl­η+΄ΛΎ=23N­ ™ƒ­ψFΟWΤξyξΨ! γξ+›ψqƒΔΊŒJIXβeυαΐ­xΖMV{4³IBͺΆγ!F}+α¬ήˆοε#H™ρι—“·2°υ±ήk–o¨i7V‘2«Μ›An‚Ήλ?ι‘FΏi’yδΗΜwm\ϋΟλ]MεΔv–“\LqH]ˆτ5ΐ/ΔY~Χ–±μΉθοΗΧ₯TΉSΤJύ ZΟ€a04šL, dE)7°=Ώσ§VG(ΰ«)Α¨5ο°J“Γ±œ£¨e> ŒŠς?ˆΛmβ{ŠeU“ԎOζ EH€Š‹9άњnh¬ŠFiΉ£4κ3MΝ-.h¦ζŒΠ³FiΉ£4μњm fŒΣhΝ;4f›š(ΤSsFhΩ’›š(ρuQ]faEP_Yό ’Y’Ϋύ%|™_Yό ’Y’Ϋύ%w”Tw%ΌM3mŠ5.Ηΐ$Χ ΑŸτ›d ιΌ'β8|I₯%ΌBΆWΨΆςβ˜ω†;Υ»^πΣβ?†΄;Mu5+Ιck½Z{Έ€Ϋ1°\ιώρΎ…βΉξ!Ρ.ži`Pξ&LqžEt΅ςgΗ?ω*zίύ°ΡΧΦuςgΗ?ω*zίύ°ΡΠEPV,lξu Θ­l`’βζS΅"K3`*½{‡μυ§ΪYhΪ‰ξ#Mh­yώTήψχ9>ήτ‡cπ;Ε’Y¦Σmd#")fbΓΨνR?S\W‹Ό%¬xNρ`ΦmΌ±&|©PξŽLuΪ‘Α©5Ώψ‡XΥ$ΎΈΥo#±dHfdH‡` 1ωΧAβ‰— π$Z―b·W¨ΑΎής|Γiΰ…ΗήΖA9η4η”WΆi_tkΏ θϊΥζ·5ŒΫΗqvσ2P˜) c’9$ցπβΓZρΆΠjΒ? imσ_–W2 Ήΐaςπ2IνΗζ4W°7Γ― xJΎ—ΐεΥεύšξk{•Η™ΑΰeŒγƒΘΟW=πΫΑ:ˆlu W_Υ†“cĞYcq’yΞΘμrNprΛLΏΎ†yl¬b€n•ቝcœ±އ―‘―Kρ'Γίάx6λĞΥξomm ΕpΌΰc8ωT‚r+Π>ιƒαξ lu‘―mκ’Ϋ±ˆεGmάέs@4Q^¦ψΫΔ_.΄o j&}Yύΐl&ΥΟLdξ$ΗOjιν~x]ΉŸIπί‰ξ€Φ’V#Ν£r:γδξ±υζ€%‹PΤ5½LXiV ΊR„yΖN3œ;ΰϊVφ»πσΓ·ήΎΧό ¬\ήEcΈΟΚυ l|ͺAηs@KEzJψOΤ~·‰τK«©o­ΗϊU΄…JίΏŒx0ΙιLπo4ύCΐš―‰όAuumimΈ@°•R£ά¬B|Π?ό ׿𯏋~Υmφ-Ϋ|Ÿ›ΜYεϊc―=iΪ—€΅ Zx¦[‹V΅Έ+ˆUŽυ p§¦NGoΟψ“`?υΧnλ›Φό)―Αν+]ž‘!šQ‹7“0!bΐ•\px 4₯“Ι―]³ψyαmΓΊMχυ‹Ϋ[QCB–ΛςFζ;[ #'Ο|f³τΟψfΓβKizΆΏ Ζ’±  š Wη“zγ ½1Ζ <ΤtΫν2U‹R²Ή΄‘—r₯ΔM#ΤRΎƒύ’tέkq¨]jM·Ί-΅˜#‘—“Œg€[Ώjως€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ φΩχώcφο΅+ΗλΧgοωΫΏώΤ¨ŸΒ5ΉλνQ΅9FՁcΤmOcQ51ͺ©’jb#zτο‚σΆϋRΌΑzwΑΊΧύ°Ϊ•2Ψhυ*(’²((’Š(’Šωχφ π³°ψžΦ1…μccϊέ―π/ˆξ<'β‹^Ψnς[G=#<2ώ#§Ύjϋk[Σ-u&οMΤ#ΪάΖc‘}qθGP{_ψϋΒ—Ύ ρΖ™| ;ΰ˜&Œž{ϊŽΗ5ΣJJK•™Ιu>ΧΡ΅;MgJ΅Τtι„Φ—1‰#qά_C؎ΖWΘ>&Νΰ»³c©oŸBςκΌ΅»γQάzŽύG=~υMVΒέ:β+›Y—rKeXV3ƒ‹-;–¨’Ё…ZϊϊήΖ%Τ«φΟSτλΥόS=Ζθ¬A‚.›Œ‡ωζΉ«β©Πψž½iΡ•G‘λZž›oC|λ!<—“Φ―?Όš7Έsh%ŽxW|‘UΙ,ؒO$“\Ύ»βλM?V²νΚΟ}q§©[XΪ!yηpŠ=3άϋ§ΨWΪ.Š4­­”‹[p"F7·R~§’k•ύ›<·Ο}βB3δ(6ΆΌγ,Gος;ΰMι^ο­ιφΪΞXΰIC>8Β€z{σ\9₯ΧχSΡ~πŒ,Υ=__ΘΝπ>ŸεΑ%μŠCIςGŸξχ?Ÿς™ I IJa@μ)υt(ͺ4Τ'Ο' ’Š+bMMΕ*‡ΑVV5ρ7Δί ?„!ΊΝΕ©fι 2ͺŒΐO­}%_iwχ:^§kc'—um*Λz2œŠϋ‹ΑϊυΏ‰Ό5a«ΩŸέάΖ—ϋΡ”ύψUVΕΠΩ’Š+ΒƒE€>)ψ½%7ğυφί½φSΏ_I WŽ|^’›βOϊϋoι^Ηϋ)Θ_―€Π+ͺ§ΐgΟs’Š+”Π(’Š(’Š(’Š(’Š+ΛΎ7uΡνΏώΣ―Q―-ψίΧEΆϋNͺ;‰žf•*Τ jU5©$λR©¨¦SHdΛ[Τ—β Ζ8HεΟ’žτ&±V€S@N)  ©AλΗ>!ψzm3VšφΛXάΉ}ΐpŒz©τη₯o|8ρ|R[E€κr„š0ήF8;)>£·―στ9%FI]`« ‚+v”Ρ8ŠΏ€iΧZ­κZΩΖ^F<žΚ=Iμ+Ψζπ~ƒ,Ύci±λς3(όΕjΨiφš|^]΄P!κqŸ―­B₯ά|Γt›τέ6ΪΞ#”…ηΤχ?‰ζΌχβ½ϊΛibŒ’¦GΗbέδ3ψΧgβΪθ6eεe{¦Ί„XϊŸAο^){u-νά·7 ΊiX³sN£Θ"ΊŸ@ZΗ¬?ξ/ς―$ψ‘ψͺα€ΞΩ τΪσ½nΣώ=aq•RΦτKjŽϊ-Ε>γ©Γ/ΠΥJ<ΚΒNdž,ΡΗ–‘Ψ*Τ“Ύƒ@B€Η$O­`hΎ΄›‘qrK:ύΧ™·mϊ­oTƒHΣ₯»Ήa…*η—nΐR„yV έΟ$ρ³«x«Q+ΣxˆP zξ‰ kϊχAα7Wss,ςœΙ+—cξNM{g„oχΓ–FΑŠD±Ύ;2ŒšnνŽ[sρώF™Ώλš*ψS!+οϊβ?τ*λ΅Ο iΪΝΘΈΊ€ΐ-c zδε~ ‹\Υ#_Ί‰΄gΠ5­Nα}―Ζς*κξύVψρΏ‹ό«{Ης*jξύVΒψπΏ‹όͺŸΖ…Π½ρ;ώE±]ΣωςΫ3ώ—ύt_η^₯ρ?ώE₯ιόye™LƒώΊ/σ¨©ρ +ΔƒΫΤΧͺM%½…›<… Ά…~@§ΫΓΌ ±ΔƒjͺŒ*Ž·£[λ0€W0‰Nν‘ΎΠO©υ§ς­έΟ-ρw‰%Χ.Ά¦θμ£?»Χύ£οόͺ·„?δfΣλ°―B„ FτΉΏŸύj冝•ρΞΣ”²!ŽO+šΝΕ§vUΡκ•εŸ?δn›ώΉΙόΕzy_ΓΏωηrθB{’VΗ’ψ‡ώ@Ÿύ{K πͺχOΘΏ©Χ¬Ώϊ― ΝM]Κ‰νή‘cNBΉΚ°ψγD’L_,’{0σ]?ƒΏδXΣλβ©Ζ·i^γBj©|"[ž‘^β[9¬uΛΘƒYԟβRr zO‚όM­g½ΔuΧk+υ˜ώ!λο]ε•­κ…ΌΆ†p: 6>™§%Ξ΄v<»α΅€Σψ‰.[Ι·V.έΉRύJυ;ίψσŸώΉ·ς¦ΔΆ–"x–„ˆγ@qΖNφλοψςΈmό©Ζ<ͺΐέΟ 1Αάњζ4=λFΎ]GJ΅»B›'›Έόk’ψ Iv‹©Ω£<±ΩQFI^Μ>ŸΛιX>ρ2ι2›;ζΕ”­σΝ½~†½Z7Y^6 Œ2NA΅Π­4g³>|§Α ·$PFHη ͺ2I―l½πξ“{)’ζςX €ύqŒΤϊv“a¦δΨΪE ‚Κ>b>½j=“+˜ητΏιγG†Fχ˜,ς#A=‡cŽ•›…gαi ™$σŒŸ$€e~BΘυ'Σ΅vΊ£m₯Ω½Νδ#^ƒ»@;šρ­S]ΉΎΧ†©’#†‰z„ rωυ4εΛ ]žήΰ”`§ GΎ~•)^9T¬ˆΕX Ž΅ξz«o¬iΡέ[0Γ :wFξ gk>υk“q2IΝχžΫ»κ"œγΜ΄μp γ‘όO&vG—8νŒ2+Υ5&TΣ™ώβΔδύ0jΆ‹’ΩhΠ4v1mέΛ»³}Msί΅ΨμτζΣ‘pnΰNωϊτϊf„Ή#¨·eί‡R¬žΆU#1»«}wόˆ¬ŠΆsKmeu–ŠΚψώΨΑύ?•sώρhχoovH³œ‚[―–ήΏO_Β½e+ˆC!IbqΑ2°ώ΄+J6ў4²*F₯Ž’M{Ά‹o%¦eo7ϊΘ‘DnsΘ4[ιΊ}€†k{;X_©t‰TΗf cž$–Œ«„zΣ„9DέΟ0ψ•#M·ύpOύ «Τ«Λ>%ΘΣm\Bjυ:QέƒΨρOŸψͺ5ϊλύu_ zjΏφΛgSΖς4κ?υΧϊ κ~tΥν—ώΟYΗγ)μnόF‘VγύτΠ…GπΣώE•Ού*Oˆς*\ΎŸϊ¨ΎΘ°ΏυΩ₯iφΙθfόXm;ύχώB²~ΘΓq^­‘₯jόYm7ύχώBΉο‡7‘Ϊψš5•‚‰γhA>§ΜT?Œ₯±ι.‘gR-^%šχϋ¨#ΊΆ–ήuέͺQ—Τσ/ψjΗD±‚{#6ι%ΪC° ΗU"ή’‹=C.Ÿ^ρθ"ΌΛβWόŒν\“ϊΧ¦θςΣλή?ύW˜|L‘ΏλŠZu>ŽηGπ»Sσ¬gΣ€ožζGώιλωη[4ΠΞ΅gl±ήΕ2σθŒ@oθ ς jΩ:ε­Ι8‹vΙ?ά<Λ―α^βFG"ˆ{Ρ³£$1* (vWŽΟ©GΖΡ^9ύΡ»nΈϊ τOκ_ΩήΈ*q,ΉOΗ―ιšρpr2 MGΠ"‘«›Έρ¦oq,2Ι2Ιaε85kΒzάZή—›‡ΪcfNα½~‡­Sρƒ¬5{“sΊK{†ϋΝor=kFΫWˆ½D_θ¬p²NO^"5Ÿ―xΗH½Ρ―m ’S,±2¨12ElxoΒΦz,Lσ\8Ϋζ>8€v{βcι–φ© vΦΪ2°mκ 2―©#Χ§>υ-Ι+±«\σΌΦ†ΟόT:gύ|Ε‘ ΜΝhψlΕE₯ΧΤ_ϊ¬ελ^β_ω΅?ϊω“B5ξu™6€Ο3Λ.Ÿnς;f)Ι'©‰Η˜„μxvk―ψ\κ φ4Ύ(θ3Αλέ|?θZ|s$[t PvŽ+'NπV‘ct³„–fS•0*ΠŸΖΊZ!ΖέΟ)ψ‘#υξΏϊW#]oΕωγ―uКΉ Κ)lw? /Ό­JζɏΛ:oQώυ‰ό«Έρ6”5)ν2‹£τΑ?–kΗtγ§k6—yΐŠ@[ύή‡τ&½ά@ δυ₯=U‰–δ2ΌVVn턆Ι8μ €3αΖ°χ·:œ·ο$ά¨ϊœ0ΠkCβ=Ψό:π©Δ—L#ξυ?ˍyΧ„5μίΩΞΗ—ςίύΦγτλψQ)ZHΠυ}kGMGPξN3i1vΟuΖτ Ώ­ZΧ/F€]έ“ΜQ’Ώοt*νq?=.ήΝOΝ<›˜²Ώύr?*Ή{©±-N'Β$·Š4βI$Μ 5ν•β>‘ŸMΒ½Ί’–Γ‘σύΡI›ύσόλέ4_ωXΧΌϊ― Ί™Ώί?Ξ½―ΒW‰{αΛ #`ΕbXί™F *[°‘η?δi›ώΉ§ς«Ώ Ώδ5u^ηBZμυί iΪΥΚά] ’`‘KFΨΘΉΉ†h"ρ.£ηjDΚ3θQΚΤξΠνβΓϊΛ€vz—1Ι#mPψΪTžΫ†1ξ1ήΌŠŠυΝoΰv½©"θσΪ\Ψ3’Ι±•{κ=FsνOψƒΰ x+ΐΦφ—l·^*˜εeŽFω‰\γ` Œ“ψγΟlΌ_β;_³Zkš”0΄"άΈ =<~‘us=έΓΟw4“Ξη-$¬Y˜ϋ“Ι lψŸ#§ΐ―’± f |@Ζ§ψ©,ώΧt[1fϊ°‘a†ιs‘‘TnΖWΣ"ΌRλWΤμa²»Τ/'³ƒTΞΝxTœ 8ͺφ—3ΩάΗqi4°OΚI•e> ŽE}-£άψΪΞΣQ½Τ4 θ[Δ[ΝxΞ$LrsνΕr <=¦_ψCZρφE΅­€Ξ°ΩK‚‹ΐ mx΅Ν*ΗIœΫΞc³΄`HφpXdΰ’πΕr?#ϋ„|]¦@ιφ©Σj«}θΩAϊfΌŠOλr­Ι¬j,·cάΎ&ΖgζγŽ{UM7Q½Σ.EΖ›wqipHQ±ι‘@Νπ9ž9Φ|;,vΪ”πΗ±K€έ΄pr―œ{W_£Εγ₯Χ$ŽOψ[N‚ΨΏXI ΑΖΠ²nηί•|Υ{y}|χ··Sά]Ή¦–BΞHO<?*»ρwˆ―,Mή·¨ΝjF7ΈbzyZOίK©x―U»ν$–IΫsΪgΚr8ά™η―[ύ›£ΡΌVθpΚ" ŽΗl•α5MΦ5=.9“MΤo,ly‹o;FΖΰΟSΧΦ€55/ψ›S΅{kέnϊHaγσ6†‡ΘϊΧ¦~Μί{ΔυΚύ©^!W΄Ν_RΌίμ½BςΛΝIφyΪ=ΰgΪFzŸΞ€=cΰ―†΄» λZΜΊdΞ±lμYNA^2πxω‰#'ϋΌwϊΕυy>x‘΅½ΓFΩܘlν#ςπžIω˜dςH>+ζ­#WΤtkƒ>“}sg+ 3A!BΓΠ㨩δρ.Ή#]Φu"n—lωΊήΓsΘΑ#Φ€;ΩΔKcβ9΄+ά=†¬…67 HΗΰFAό+[γ΅ύƒ’hώ Ρ²–Π žaœœdνϊ“Ήΰkψ!u ιυΞ³βψmšΦ"ΆΡΈ%™Ψ°ΐμ2?ΰUΖx―Z›Δ^"ΏΥnrζRαIϋ«ΡWπΒ€=dΙ°ϊλ·tx£ώMΗB©‘=xχφΎ₯ύ—ύ›ύ‘yύœύ—Οo+9έχ3ŽΌτλDΊΎ₯6›Ÿ.‘xφœ₯³NΖ%>ɜ§΅} α©<[§ψoB΄»Σ4ΟθΧ’¬ΏΝ xwo`τν‚kΟ>/ι:7‡~$X%#·…–+‹ˆcϋ±6σœΩ{ϋΧ€ψŸ\-Ύ—«ίZΐr|Έ¦e\ž€ ΰzΜΉžk©δžζY&šCΉδ‘‹3ROZχ?Ϊ3ΓΧχ²Zψ‚Υ#“L΅΅XζH2€Ιςœwxι^ZRkΪΌšWφdš₯σιΨμΝ;π@ۜ` fΠEPEPEPEPEPEPEPEPEP^Ώϋ?Μ{ώέφ₯yzχΐωΫΏώΤ¨ŸΒ5ΉλŒj6§΅FՁc£j{TM@ cQ5=ͺ&¦"65ιΏζ7l?φ₯y{W¨|λ­Ϋύ©S-†S’Š+"‚Š( Š( Ήˆ> ΣΌk‘΅Ž »&L΅΅Κš=Η¨8ώ ΤQM6Π xΣΒZ―ƒυf±Υΰ+’LS―1ΜΏήSύ:Žυ/ƒ υάs^γo€7vο%Ο„nΦζϋ%ː{+τoΗS]ͺ€­"ZΨιό+ρχD½Xβρ €ϊlψω₯ŒyΡλΗΜ>˜?Zοlόα}JtοιFR>UšΰFAχ ƒ_kΎΦt zΦ—wdOC4d+}‘ό eStbφ&¬όE₯Aήκ>'琜*Epψ}ξpڟό?bΆσνR‰n₯³ψτύkΑiπΕ$¬PΖςHΗ ˆ }€―:Y5K™Άt,d²;|HΤuhtΕώΟ·=X6eoψoΓσ&—ΟGˆΉŸp*W;‹g·ΎkΠΌ+πwΕΊτ¦±:]3η_e ϊ'ή?υο~h>)r¨oυUηνw 2‡ΐ½λΙχΪtθα£ΛMΚS¨ο&p_>=΄°kή,ƒ©m`Β{<ƒΧΈ^έύ+ί¨’³”œΨ%`’ŠŽζx­mεžβEŽ”»»P2Iφ€gώ^,ώΘπΜz€…o5<ω˜ώήΎ@ΥσF¦άk΅žd»ξn₯X£δγ'Ψ*Ψψ‹βi|[βϋύUχ]φ[£Ήπ£ςδϋ“^―ϋ1xLΙuwβ‹΄!aΝ΅¦GˆωΨ} oJλ_»žμχ_ hΆήπύŽ“d†Φ €ηψ˜ϋ’I?ZΥ’ŠδΉ QEQES&&‰γ•Uγu*ΚΓ ƒΤO’€>$ψ›αwπ‡Œ―΄Ν­φ]ήm«°ϋΡ7+Ο|r§έMzWμΙβΓk©άψfνΟ“u™νrxYω”}Tgώ}kΆύ£|$5― bΦ=ΧΪV]ˆκΠΎ?θΦΎ^ο§Σ5+[λ7)sm"Λz2œŠλOΪ@ΝθΟΏ(¬oλφώ'πέ†―fWΛΉŒ3(9Ψγ†_ΐ‚? ΩV­‘ Ph βŸ‹ίςS|I_mύ+Ψe?ωλυτŸϊxηΕω)Ύ#―Άώ•μ_²™‰½_I WUO€Ξ;žιEW) QEQEQEQEW–όpλ’Ϋύ§^₯^YρΗ‰mφTw<ΕMJ¦‘Z•kRI–₯SP­H΄2Τͺj©U5Τθž6Φt΄X–eΉ…z%ΐ-μzώ΅ΚƒO&ΦΐzTζΫσιq–υ?-΅CQψ‰ͺά‘KXΰ΄ψ”noΜρϊW¦œ*œδE›‹‰fieyec–wl“ψΣ¨Α§ ŸEZΗ€?ξ/ς―<ρŠυΕ—πΐΙ-·ξΟ•(Θ"ηr+΄΅Φ4Αk:˜!A}>΅δώ=ž+ήΛ‰,M³Œ‘{ŠήnΛB»/Δ‹ΦŒˆ¬mΡύY‹ˊδυ}^χWΈσoζiϋ«ΡWθ+:–±ror‡f΅t-~D”΅”ƒcrΡ8Κ7ΤQYRNΓ;ΟψXχώV•―™ύμΆ?,ZητOέθΧ—6ΡΐςN0ΒE$uΟ"±3E7&ΕcͺΥ|m¨κz|ΦsΑh±J0Łλž2Η©ψ{Δχš SGi»¬¬ΌΥbF=0E`ΡG3½ΒΗI―xΊ[±·PΫ${Γζ5`r3κΗΦΉψ€1Ȏ£%H#>Υ›oq―ό,][ώ}μ?ο‡β«”Τ.ήϊϊ{©‚‰&rμ€ τͺΤ™¦δήβ7Ό;βkΝ)’Ξ+wYX3yͺΗτΑ&ΏβΛνrΙ-βΆHΦA 1+ξO­s΄QΜν`:'ΖΊŽ—§Cgo £E!K«9$σ†΅G\ρή³wmquπ}ѐ9η$Φ&h£™ΪΐvΏπ±uoωφ°ΎŠ£ώ.­>φχΓρUΕQOž]ΒΘναbκίσοc|?X—> ΊΈΧγΥή8Κ!Bœ tΞZΕΝœ› ―ό,][ώ}μ?ο‡β«ŸΡu«#RkΫd‰₯e*D€•δ籕Fhζl,uχΎ=Υ.μηΆ’ !Ρ΄lU ƒ›ήΉ,ΣsFhm½ΐλ4ΟjZ}„AfΡΒ»TΊ1${α«?TΥn|M«Z}³μπ1Ϋd(Ίœ“λXy₯ΝΟ`=FΓαε€#uΥδςΚ:ΐ@κZζ―V·zz+„©*ŒŒ~•²ŠkέΪάΰ| ₯κ—ΏφΆgΔhV39;˜ž8 Ζ:λόOvΆ:όξ@ΔL«ξΔ`~€Tϊ†©c§Ζ^φξ@Γ7'θ:šςΏψ€λ’­½¨d±Œδnλ!υ?ΠPΪ‚°·9|њm¬ šΧΡΌG©θ-ΑςΏη“όΙωvό+4f„μ Aρ"αTyϊtNέΚHT~ ΤW―€B-lΰ„Ÿβf/ε\&hΝW<»ŠΘ½©κwšœώuυΓΜύ·θ: §šJJ‘—τ­VσJΈσ¬fhœπGPΓЎυΧΫ|HΊTζΒΥ$)ϊk‚€¦€ΦΒ±Ϊκ_u+ˆΚZC¨?Δ>vBxύ+šY&•€™ΪIε™ŽI?Z‹4PΫ{Œμό'ΰθυ«½šχdeŠ˜γL°#Ԟž½;֏ˆ4-OΓΛΎžτΪνΔ¨X†ώρQΖ?ΥΞx?Δ’θ7l4–RŸήF:ƒύαοόλΦ4­oOΥ"W²ΊΙκ„αΗΤkH¨΅ζKΉε‘Ÿλς-«=μ‘±ΓoΚΖ?ήθ+Χtϋe³°ΆΆS•†5Œ\ f₯–XβBΊ’Ž₯Žqή*ρ΅₯ΌiR­ΕΫ y‹ΚGοžηιV’†­‹sρύςάψͺΰΔC,bάuύI{ώ.­>φχΓρUΖ;3³3’ΜΗ$ž€ΣsXs;έbζ§}&£=άκ‹$­Ή‚ϊf΄<;β;½νcŽσφξσTœmΞ1‚=MaњWwΈΞ›ZρŽ‘¬iοgs ͺDδcVƒžμi4/ίθΆΦWŒ1lΘ¬NOΡ…sY’Ÿ3½ΕcwΔ^%ΌΧ£o#·A %|₯#9υΙ>•ЬURA‚;S(€έχ±Σ|}ͺΪΒ±N°έγt€‡?Rτͺ>&ρMΞ½ PΝ0Εo2NqަΉΜΡO™ΪΑc°΄ρφ©kk ΌvφE"EE,œŽ~jΑΧuiυ›σwt‘$₯Bβ0@ΐϊ“YΉ£497ΈXvk­²ρξ«ki ΊΕi"ā:1b᫐’’ml3oΔ^#½ΧŒlXQaΞՈ 8δδŸJΖΝ74Pέχέ…υΟr·S<3/ρ/ς>’»?ˆΧ± [»(faόHΕ3όλƒΝ¦€ΦΒ;{ˆzŒρ²Z[ΓlOρςμ>™γτ>ζβk©ήk‰Y\坎I¨3FhroqŽΝOctφw°]DΙ ‹"†θH9ͺΤf―ό,][ώ}¬?ο‡β¨…‹«Ο½‡ύπόUqTUsΛΈ¬ŽΧώ.­>Φ?χΓρU•β^λΆρCw²,oΌ•Ξ1ܚηθΝ'&ΒΖ‰ίθ±›j1ΛFά£}EuόHœ'ο΄ΨύRR£ςΑ―>Ν‘I­‚Η_«xσT½£·ΩΖx&<—ΎτΉ2Δ’I$žy¦fŒΠΫ{­‘k·Ϊ$εμ€οΔό£}GυΥΒɟΛΐΣ’σ=|ӏΛΦΌώŠšΨ,tιγ]UuS~Ζ,Δ±2ˆ ΰœπ9Νό΅ _N’ΞζEŠB 1« ρ–>•ΜQš9˜Xz³#BUΘ ΰƒ]n™γέV!ΐŠν@α€?ζ:ΧE ΅°΅Δ-FxŠZΫΓlOωvLρϊUkκΆv‘Ϋ¬v²„η•X³sœ“ΊΉ*)σΎαcWΔΥΖΉx—WqΔ’,b0" Or}k34ΪZ–ξ1k­΄ρφ«kk ›¬H3£ sσuC4SM­„mx‡Δ7šσΒΧ‹  ±=O$ϊ ΗΝ6Œnγ;(Ύ!jΡΔ‰δΩ>Υs#dϋŸš°ΌA­έk—‰qx±«"lUŒ džδϊΦUά›άE½6φM>ώ ΈUH[r‡‚}ρ]Wό,][ώ}μο‡β«Š£4)5°X’G/#9κΗ'§‘kχϊ$¬ΦRŒrΡ8Κ7ΤQYRNΓ;³ρΚΗΨ­|Οοe±ωgϊΧ;’x‚λGΤ'»ΆŽ–e*ΒE$rsΖτ¬lњnMŠΗY©xγRΤ,'΄š 5ŽeΪŁΫ-\iΉ£4›oq}—uKK8-’‚ΘΗ k–FΙ`gζφ¬={XΈΦοΎΥt‘$b0@ΐΟ©>΅™FiΉ7 ‡fŠnh€1Τf›E;4f›š3@ΝάњvhΝ74΄Ή£4ΪZ\њm Qšm fŒΣh fŠmρ­Q]faEP_Hόρ¦ƒmΰkM/PΤν,nμΪ@Λu*Δ4Œΰ©lχ±ψWΝΤPΪ?π™xcώ†=’⨄ΛΓτ1θΏψ_Q@hΒeαϊτ_ό‹Š£ώ/ ΠΗ’ΰt_όU|]E} ώ3πΊ©cβ=g‹ΨΙό―–>(k6Ύ ρζ­©iμZΦWEˆΖΰˆ©Ÿ‘۟ƹj(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(―]ψ1οϋa΅+Θ«Χ>ΜwώΨνJ‰ό#[žΆj6§΅FΖ°,cTmOj‰¨Ζ¨š€cQ9¦m^‘π7ώcφΓjW—5z‡ΐΞΊίύ°Ϊ•2ΨhυZ(’²((’Š(’Š(’Š(’ŠkΖ’!WUe=A°oόαA·^hT―Χq΅Lώ`WAE4Ϊ“ƒαΗƒ pΡψoLΘηζ€7σΝt6e†ž»l,mmWV1ϊVθ‘ΆχQE†QE_R±ΆΤ¬'²Ύ‰f΅ Itu=Aφ«P ΗΑτ.iχΕtΊF™e£ιρXιvΡΪΪE‘F0«’IύI«”Sm½Ε`’Š) (’Š(’Š(’ŠdΡ$Ρx€ΛΌ?χωjŽ·α]WD΄[›ψQa,r8lλ₯{εgx‡M]_E»²|fT!IμΓ•?˜³¦Ί ηΟ ΣΑ¦Θ―ŠUΠ•e=A¨±(ΧΠ΄KνnYcΣγW1¨f,Α@ΝmΒ―ΟοκΧoπΗLϋ‡αΧ^7š}vτQωsψΧ]Zƚjμ–ΟŸυ&οF»[kδU™8 ΑΈ$ŽίJμ4‡3Ψ€·w«o;.|‘νΎΔδsU~)Hbρ]ΌŠ)nŒφfχOρ^yb·ϊ \΄rΘ”ϊ`υό)F1»LgλuΖ“¨Kgv–3Τta؏j§[ž7ΥαΦuω.-AςDhΔ`°2k 5›ίA‹šΡΠ4Ή5N;(dHέΑ!Ÿ8ΰf³k©ψk#m·ϋ’θ&ˆ«»/έ|=Ύ·΅švΌΆ+ ΙΐΟ₯qUοϊΟόοΏλ„Ÿϊ ―Ÿ³U8¨μ ŽΝΪ3P3₯πΧ….uϋIn-ξ!‰c,‡ΞIΐ=Ύ΄x—Β—:œWΚ²Iε€™ΞpO₯v δ y_ϋ*Ρρkώ@vŸυς?τ­yW-ΙΎ§3£x"σUΣ ½ŠκέPHV#OjΜρ7‡ηπόπGq4r™T°)ž0}λΤ|"Žώλθm\ΕίωiυΙΏ)Fα}N ŒΣh¬ŠE74f€E74P³E6ŒΠ¨¦ζŒΠ³E74f€š)΄f€š#₯6ŒΠ¨Ν74f€š3M£4μњnhΝ;4SsFhΤf›š(Τf›š3@ΝΪ3@’›š3@$š)Ή£4μΡM£4μΣ£S$ˆƒ«*<ΤΆ§ύ&χΧωΠo ήώm& γ΅;6Συ ‹IYαr…—‘Ε}^βσ>§]ΫωΦ³ŠKBS(Y[I{w ΄e`Š Η&Ί?ψ@υίωαύύ‘αwHόE¦ΌŒ¨‹:ΜpΟ­{oφ?φŸχωΖ”"žγlςŸψ@υίωαύύΏπλΏσΒϋϊ+Φ­ο-nX­΅Μ30"9? –GXўFTE,Η ΏgnΟ„]ž0ίΡYϊΧ†υ-Ω'Ώ7}€«†ηJφoν];ών?οςqŸ―mntKU·Ή‚V‘ˆ[¦PI\i³Μκώ‡₯\k:ŠYΪ½†βΝΡTu&³«€π³y·,FbgΖvr?N?ZΝZϊŒΨΥΎάZX<φ—‚ζHΧsDcΪHqΙΙφ½³Wρ^“c§Ι4w\I΄ωqDα‹ΩΗAυ―ΝT[E74f c¨Ν74f€š)Ή£4κ)΄P³E74f€E74P³Fi΄f€FiΉ’€š)΄f€FiΉ’€E74f€š)Ή’€E74P³E6ŒΠ¨¦ζŒΠ¨Ν6Šuάњu¦ζŒΠ¨Ν74P¨Ν74P¨¦ζŒΠ³FiΉ’€š3MΝ fŒΣsFhΤSsFhΩ’›FhΩ£4άΡ@’›š3@’›š3@’›š(γŠ(’ΊΜŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ½oΰ'MwώΨνJςJυ―€ΏσΆϋR’Φη­ŒΣ1«Ζ5FΤφ5STmOj‰¨6―RψΧ\ΆϋRΌ±«ΤΎυΧ?ν‡ώΤ₯-†V’Š+‚Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š*+‹˜­γί3…_η@ΡX8Ά‡θΞzώ΅¬ανΓέWnv¨ΖJ’nΘn6,ΡEB (’€ F`ŠYˆu$Τ·qΪBd”ύr}«˜žζηTΈXωΓ•AοΧ¨”ΤtΞ γKΔΑ”dT•€ omKΘQŒϊϋΤ΅kΜAEPEPEPEPEPEP^UρΣώ`ŸφίiΧͺΧ•|tλ‘Ϋύ§U ΔΟ.Z•MB΅*Φ€“-H΅Τ‹@-_яόM¬ΏλΊθB³”ΥύώBΦ_υέ?τ!@MS!•&BΡ0e ΘHυRA˜4ϊβΌ«oΧόE₯Jί4w’Ο?έ.CΟρ†μAΕ|PΏ³ΌFΧ ΌhτίΡ‡ηƒψΦ…`ϊ¦―ies4I—©?€Ι―^ψ—€ixfY#\Οh|εΗ\Ό?.\ΏΑν/ΜΉ»Υ$_–1δΖOχ,Ξ²qχ¬Uτ=B(R8ΐXΡB¨)-¦K‹x§ˆξŽE§Τ‘X?Υ²Ό3rΘؚάGυn§π­/ Θ»₯Χ¬_ϊ­o­‰<ΛβΟόŒΡΧ²θM] 4Ω ΝέζYA8+ά}+ψ΅#<_υμŸϊW­YΗ€ξ/ς¬NNεt<'ΕzlZ>½sc»Ηά3γ'*o­jψOΑ·Zβ ™ŸμΦYαΘΛ?ϋ£ϊ:³β}<κΏd²Ι +ΔŽ‘DjOθ zΤG)(4Pͺͺ0(Α6Α³’α抱νctνύγ τi Fρ½υΓΌ ^9qΈeHΦ³5ΪϊH4»hζHΨ©–F8b:ΰήυΉΰοCβ$/Ωο#ŠnΘeυ§ηTΉod-M½gώ@χίυΒOύΧΟΘ­#ͺ"–v8PI>•τ΅ {ϊα'ώ‚kΝ~ιiu©Ο2†[P`Ž7ΆyόύiM]€4\Π>™aY΅™ή"άωc#κΗωΞΆ₯ψ{’Ό{PέFίήόΕtΊΆ‘•§ΝytΔEΙ©=€χ5ηmρ2γν9]:/#?tΉέ―O›QŽŒZ³°π†‚ώΆ»Ά3 £yΌΔl`γh#׊Εψ· +Oϊωϊ WW’j–ϊΖ›ε‘>[πTυR:ƒ\§ΕΟωZΧΘΠZœ­Λ -͟Θ‘§ΊίϊW!ρ{ώBύroη]Γω4οχ[Cjγώ/u8I‰ΈόiKΰάζ<7 ^kΧF;P$Y+}Τν^‹cπσH†0.ž{™;’ΫΰψšίπΦ—£[Z"€κ»€?ήsԞΐW%βολ±jRΪθΦ“Η Gi˜[—.{㠌RQQWa{—/ώιSF~Ι-Ε΄ŽνλψƒΟλ^w­θ—€jJ|–9GΡΧ<‘ον^‡ΰŸjχ·†ΟZ΄”eK$ζœŽΗŒV—τδΤ<3vJƒ-Ί™Πϊmλϊf‡ΥΠ\ΘO‡[’²ήήaA^Gύσ^β}/ϋ[Έ²Vf(ΝΤ©ŠυjΪ΄f9’δ?ό§ιŠε>.ΨνΉ±ΏQΓ©…ΟΈδ3ωQ([ OS#ΐޏΔj’κIb†ͺ¦=“Jžm>a-Ψ$2#/$γŸaΧƒBQ»l5&ohE6ˆfSύα)Νr~)πšu΄—zd―qc/GG_™ x»Δwz΄ 7]ΔξΔ°ŒžyŒzζ½d€AdΥIFKAjπž™³Aepξ‘Θ–Lg…'Ώ»‹ο‡vΩ\IΕγΚ‘³"ό§sΐιX^·ŸΪέF)gAτ€―\₯¦΅gθ"6κϊ΅Τ’V1Α€Ψ’kρ>”šgˆ§Σ¬όΩUJέΛ1eS^—―xηM―Τ$·3Ζpώ^©τΙοτ¬ί, ρV£―ω,± D…°?ρκbτAvSΠ>ω‘$ΪΜΌF|ˆˆΘϊ·ψ~uΌώΠ™6ˆ§Sύα)ΟλΕiψ«TŸIΜΦv―srμ4T,υ8νΗς―?ΆρO‹bΉKm4Ρ瘚ΣP3M¨ΗK¬_xm6έξτΩZζέ]|κ=xλϊW4²*F₯ˆUP2I=«θ{)Εݜ3μxόΤ±Ζr:λ^s₯ιPiš E†šμ \γπΙόͺeΠ-h?β¬ΊΜΞ‘Ÿ&#€ΎΔχό?ZΥΈψ’KXΦβώςIŸηšθ΅qvtΛ‘¦•›•»έψρωםiz=@Ιβ/₯± ω™vΣΨ«tλοŒU5ιajΜxjηΓΣ¦ησ­e8ŽP1Ο‘sωγŞ7ΆΦ΄Ήlb°uW ¬― ʐsœψuο\5e+_Bεˆ '€z‡ΎΰIυ™ž"Γ"°ΌOςύkπΥε­†Ήiw~ŽπBΫΚ ηu#Ύ z…Ϗ4q¦Ο5¬ΕξQ2Ί2–=ΉΖ?Z¨%»qηΐZΜy3ύο4湟ό?{KgΉ%’tA–†@7γ؎ΏLU;Ζ^%ΉΤΓ›₯-ΝΊ@0G¦@Θϊζ½z­(Λajπέ„z¦·ie3:G3Y:Ž γς―A“αƜ±±K«ΒΐW“ωW;¦Ϋ-§Ε¨·NT€H­zν(E5¨6yξ‡πξn’kHΣ0Ɋ"_b{Ÿ₯[ΤΎι²ΐί`–kyρςξmΚOΏzΟΥΎ#Ό:Œ‘XYΕ%ΌlW|Œrψξ1ΠWq κqkTΠ)U©κ€ωΣJ/D-O Τμn4Λωm.ΣdΡ0ΞAξφ«ΎΠo5λ³’…DζI[ξ jκΎ/Ϋ*]ιΧJ 4ˆρ±υΪAϊίšRhϊ΅²¨•)Η%Ο_πό*=λϊV_τ¨£i–ζy;ΑΰψΤ‡Γ»@]2βXεB$€2ΆLγ#υ«ή0ρ”Zβήqv@f°¨LϋϋU xύuψμυtε;RDo—w`A隿s`Το+Β<^β¨Τλ»:χzπoΘΡͺΧvώtUΨ"dζ—4άњΐ£ΌψG!›ίϊχΩ…wώ+‘kT―i?τ^π‹ώC7Ώυο³ τΘ³ͺΧ΄Ÿϊ ­απχ"Gy O›r»_ΘڎΘ5-jtλk ™κμ΄Q3€Jΰ τcΐήΆρΧiu,шUHςΘη$ϊƒι^΅­Θώ½δΠMyχΑψϋΤάOζhq\Ιτ-κaK_ψ–άNχ”5—hδœ π*υΓ­.(€»šββ^δ0Eόμ.ξ"΄΅–βαΒC—f=€―7Ίψ™7ΪOΩl#ϋ8ο\Qq#ύšΛ8’ώ»Gυώu.΅αΥ„ωtΘAH.d(QχPςΨϊaΏ*υΘ+KeH$1&Ttt¦0»ΤmœΌΡ#Œ+₯Δ­ύ攃ϊb³΅‡6²DΟ₯άI£’Κ}³Τ~΅•©ψ«Εή3YYά[[ƒς ΅άHχ$~•Ωx3X½Υ¬e«ΫέB@$ΖP8=Ώ5K•ι`Υ3i=…ά–Χq˜ζŒα”Χ‘θώΣοt›+©.Υη…$`₯p ρΕ;βޜ†ΣQEĊώK‘άHόˆ?uώ‘oJ―XΏτJ0W³ΞώΩ“X–(ξ$OŒ/οξΔdΠ~5kSπ&‘flχ\ށ4λ%”ςΐγψ}@vφ·g‘Ϊ ‹η`αYΟ η^+ρ΄ΎœZ[Ο±Μ²£±ßJŒA]›ΗαΆ›Ž//?5 ςλ˜^ΪζX%’'(ΓάϊK»Kύ:Ϊξ?»4jψτΘι^GρMx|_"B™7›dŒεΈ?ψπ?)ΕZθ4Ό!ΰ«}cF[ΫΩξ"2;γGδzζ¬ψ‡ΐVΆ5Υέ•ΕΜ“B»φΉ\:τ™―@Σ-OΣm­#ΖΘc Ÿ\MNDwvΌR/Τ2‘WΘ¬+Ÿ:W¨Z|8±kXZβκνf( Jΰ69Zδt}Ώα8‹L°άΩξ‹σ~ ~΅μΧ· ig=Μ§#}ΝD"Ί³Ε5m /‰δ46ΰ© —#9ΖNp8ϊWm€ό9²Š%mNβYζ¨?©ϊρ\ί‚ΌGc¦κ—χΊ¨”ά]‰Ι%³Ξy8ό«€ρ?-’ΣPθS€·26 2ε\ֈςξΑάΏ?€49ͺ%ΔGϋΙ)'υΝpΎ-πΖ‚’β9>ΡdN7γ ‡°aύk‘π'ˆ΅νKWHoUξlέX΄¦ ’>  ΙγρΫ_Ά[Νώέ€!αp3λŽηŠU%thςxzΫΔέ₯Τ³F!U#ΛΗ9'ΤJθ5Ÿ‡Γe2k‰n™ΥUd+΄y' ΤγοSq?™―Mf ₯˜€ d“Ϊ”"œA½NΟᡊΒ>Ωyrσc“ΥQωƒ^y—qy¬=…„m,‚FQτ©=«oΎ#ip\4vπ\\*œyŠƒτΟ5gαޟztڞΜM}#8,9Tάp?―εCŒ[² ²Ž“πζΚ(•΅;‰'—ΊΖv ώ§τ«·τIPˆ–βμΙ&žiώ7Χu-7ΚΆΡν%–y{J".gΩΰυώ΅αίx‰ucΥm.'Ά‘‚³b₯2zπ⟺¬-N{Ε~»Π—wΪ,ΨΰJ£O£Ս₯ΨάjwΡZZ&ω€8ƒΤŸa^ϋ¨ZEe=­ΒξŠd(Γλίλ^}π¦Υ`Τυ„”΄ΑΆ!μ2ΫΏP*\5Ν+αޟ *ueΉ˜ύ퍱ΣΏλRί|;’Š+¬Μ(’Š*H‘–\ωQ»γΥ&£ΓΓ‘μȘX±>ό‘]ωv c*ΊmΩ%q₯s˜7g₯¬χμΣ†zzYάί¦ τ(b«°Η^΄²:Qϋl1^ zXέϋbίαNF€ziχŸχεΏΒ½fͺμ1W<²šqϋL›ž4t}LNyΤω ώD‚ `Šϊ«Η|}CβνA#P£(Ψ₯ŸΤšσρXXъiάΉΟΡEΔ0’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(―Zψ 1ίϋa΅+ΙkΦ~ΜsώΨνJ‰ό#[ž°ΥS1«ΖQ΅<ΤmLCΤMR5DΤυ?]uΟϋa΅+ΚΪ½OΰOόΗ?ν‡ώΤ₯-†W’Š+‚Š( Š*‡ˆ.f²Π΅«Uίq ΄’FΈΞYT?1@zǎ<3£_΅–§­ΨΫέ.7D|ɟοcξώ8­­sK΄ΡΏ΅ξ/ν“LΪ­φ―0πΔwtΑ$ΖΌΛΰW†τ]OαςjZ•…₯ύώ£,Νu5ΜK+±ήΓ`qΐκs^};΅§ΓŠZ³±΄νJ!j€δG›ŒώΏ©οZς&μMΟ|Σ|wαmNφ+K MšκSΆ8–uάηΠ曨xχΒΊuμΦwΪφŸΤ,RHδ˜VAβz†•yβxsLΠ< >™wο¬K Β»B °``xnsۚκΏi +OƒΒ6אΨZGy.₯’α!U‘ςNX œγ½Šφ θz$~:πΌš|ΧΙΨ8]b’a(Ϊ¬Ω* υ8?•[ΉρN‡k­E€\j–‘κrν lν»ξΰ{Χ™ώКe†™πΕ—M±΅³Y/a.-αXΓΪzΧρf)“β–§©Ϊ‘yτ>ΣP@?Ψ–0F'π’0L/cθOΕ&—ͺΫιΊ†©io¨\mς­δ}Ηjΰ{Eψ£DŠ]J9u;U}5Cή)q˜θ[ΎtρEςxŸβ=§‰­²l?·¬4λWυTŸυΪτ₯£ό\ψ”5μόΈ ’p {BdξŒcΦ‡M%pΉΪΒΙπoύ šgύώoTρΟ†4«ι,υ-rΒΪκ'Ι_ψo]n?’W­Τ΅d0’Š*FPΤξη‚6π³2]†ΖΉ€ŽλP›#|―ܞƒό+ΊΆK” )m™ΙPqŸ­>(£…D‘tVrƒ“ΥθR•Œέ3HŽΨ‰%"IzE5«Ei%’%»…QL’Ίmαi8‡R}*ZΝqχuyzTa!ϋ±ϊ θt­9,£ΙΓLίyΏ ©ν­#†Y%i\’]Ίύ΅X¬γ ;½ΚrΎˆ(’ŠΠ’Š(’Š(’Š(’Š(’Š(’Š(―)ψλΧCΆϋN½ZΌ§γ·όΐνΏώΣͺ†βg–­J΅ Τ«Z’J΅*Τ+R­H¦΄4oω YΧtΠ…g-_ΡΏδ-c]ΣBτνx_φ©ΡΎ$]ήdˆϊU“έ ί§?…{₯|ηβΏωuϊό—C5­M,J>Š!d Œ> ƒTt& MK+\ωjΜΩ=NI</Β±~κίڞ]³=―ξΧξŸΛ‘‡SΌOΣξo'?»‚2ηί₯ZΧQQρgUϋ^ΉŒm˜­ζ}Ή?¦?Zτ ΘΉ₯Χ€_ϊ―žο.dΌΌšζvΜ³9v>δζΎƒπΧό‹šWύzE  Ξν²™ζδg‹ώ½SBjυΛ?ψτƒύΕώUδ_?δh‹ώ½SBjυΫ?ψτƒώΉ―ς§‰‰žy½Wγ+nΗ }ό^‹:³A"ΖvΉRϊWxζςKˆwp¬…αuΟ|"ρ^΅’κvΪƝε›ξΗ#Ίκ}Ε8½Z|χ"4r4r)WRU”ŒGQ]wΒΘ€“ΕJρƒ²8œΉΗ#υ"½[πf‘«έ5ΜΡΛ νΛ΄,qυ ‚3οZZ‰a’[΄Z|;7rξΗ,SR©΄ΖΩ6΅ kϊχ“A5Ζό u:Uϊ o~…xώF»-kώ@Χυο'ώ‚kΘ>kΙ£k%n[m₯Θ»Š…·'σͺ“΄–ΗyρN)dπ±h+Θρό<ζExζkθιcŠζŽEYa‘pTςε[αξ†n|έ—3Ÿ(Kςύ:gυ₯86Βh€OL\3&GQ΅A?˜ΗαQ|]Ÿύ|ύ«ΆΆ‚+[x෍c†1΅QFΔό_ ‘§‘ ΅6­ nlό?‘?NuΏτ6Wβ›*kΊ;?έQ“τά+ͺψ}"v›ώλθm\wΖωιίυΙΏ)|·=JΉ«οhφ7“ZάI:Ν aεΘ€πΏ³£ΗΈϋmΊ„•ORΏηKβ_iϊμhv’ήλ2G›Σ υͺm΅x‡©ψCc…’ΰŸA ͺš―Ž΄K.ς䘼°Ί(1’TZπmŽƒrnVI..q΅]ΐG|_zΙψ ϊU™΅­­›SœŒUΟ,HόΉυ©nI]††gΒ-Ceενƒž%Q*qΑύό«ΈρVŒΊζ˜Ά¬@"d|ϊpίψιjρ κΩzύΩ8D?μžθM}D5VWΌΈŠΒΒk‡b‚2δ@:Wπ·Y{εΤ­[3y¦δ{ξ?7λΞ­όTΤ~ΙαΡl§]ΘμŽOτyη5/μίΩΘΗJήKύηƒψQ)ZHΠυΝcEMCY/Ž3g#3{Œd~Lζjo_fh7Χ`αγŒμ?νυ"΄λΟΎ/j]…‚šg2Έέ^κJ©h›©Βψ_F“^Υγ΄Fؘ/+uSυδΖ½†ΓΓϊ.m½-mΤFΉiζ›©,zWό'»ŠΝ ₯U§„¬dχ`AΗεŸΚ½;_ΣF―£έX™ ^rΰ8ΑϊŠˆ%k™ψγBŠU‚ήg,’8ΟΤΰWO^uα‡rYκpέj7QI.cˆ˜ŽFIθ3^ŠFGJΈί¨™ε^’­s]ξ?“W¨έIδΫM((…±τεΎ’―s]ξ?“W§j_ςΊOό(lΑŸ;;³Ήg%™ŽI=I―WψDΚt΅|\’~…WΘΧ’ζΊο‡τz>¬πέ0K[ ˜τFtŸnHό}«(;2™κšξ΅i’[Η=ω‘bwΨ ξqŸθkώƒ=gΏFΊNΒΧU±{[ΘΔ°H:zz{γWឞ.75νΙ‡9Ω…ΟηΦ­Ÿ7BU#γν L—Fa<ΧβΏEsβ˜5MΨQ6³.2A9z`β½jβΟNƒL\Αn,`O»*‚ͺ {Χ”hθ—Ύ5•nm"]:rRέB«dm'žψ©iω­*…ΐο‘^ε―ψ{NΧQόDΊp²!ΪΚ=3ιυͺΪ„΄­>Φ7’ΰ fmΕ~œ*]7qάί―ρ‡ό:§ύwoη^υ^ γωuOϊψoηN¦Α"ŒΣsFkŽϋαό†―λίfθ>,‘cU―i?τ^{πƒώCWΏυο³ τ/Θ±ͺΧ΄Ÿϊ ­‘πχ<‡ΐ_ς7iΏοŸύΧΉΧ…x ώFύ7ύσ šχZ)μ99ήNΧ7sΞδ—•ΩΞ}IΝtί δl‹ώΉ?ςHžMuŸ Ώδm‹ώΉ?ς¬£ΈήΗ­kςΏ―y?τ^{π{ώ>υ?χωšτ-oώ@Ί‡ύ{Ι šσίƒΏρχ©ΈŸΜΦψ‘=ΗΗ‘I7„΅$„ϋp;ώ€Χ…ζΎ’ AƒΤδώθw&`“Β Ɏ'Β~D~§υ@™‹πv)z€€ ΤqΑaΈŸΛ#σ­Ο‰Ξ«α€έZD υݟδ tZuΆ›h–ΦQ,P§EΜϊšσ?Ššμww1iv-Ϋ|Δtߌψ?j»μξ|"ž™\Ώ©+γr ύ>R’bepŸΠŠν< "–™\Ώ©­[L΄Υ¬ΪΪώ,Dδg‚§ΤΖ›Wƒf|σ^ϋαX€‡Γzds‚$[tΘ#q²΄θΆwK>Ι§*r©3‚ ύόk€ΌΉ†ΞΦ[‹™8c]ΜΗ°₯ςκΑ»œv₯,π΅΄°q‘jW>‡εό롚AO#B)bΙβΌRΧζΉρCk ³Oe^€ώŸΖ½³EΤν΅:+ΛG ŽGu=ΤϋΣ„―phΑ… ΟYοΡ₯?ΠΘ$Ip@κ|“ΕVΥώι·Χo=ΌΪ9d@ ηΨv­Ώ ψvΛA΄’`4§2I& oo§΅ ˜48Ώψ³JΦ4΅²yZc"° »― Θ΅₯Χ¬_ϊ―5ψ‘&—ό6Ίu΅Ί\&ZαβP9μ§gΉό+Ό-"Φ“^‘θ”~&cΞ>-ΞΝ―ΫBIΩΈ {–l!ωWšμΎ,ΘΡύ{'σjβσYΟr‘λ u΄θZ1ΛΪΘ@μ·#υέ[šΆŠ—ϊή“|ΨCg,=r>_Ȍך|-Τ>ΙβQnηέ!ώ9ȏƽ’΅†±%ξaxίQώΜπΝμͺq#―”ŸVγτ?…Vψu¨hx^ά1ΜΆΔΐί‡έύ_βώ£Ί{-9„wη…ΩΏ:©π“Rς5‹‹8K”ά£ύ₯ηωωRζχ¬ΠτtTΕsκγΌ·X±ώΦy?QY_υ±ψi S‰.œF=vŽOςΗγ]uyōCντVjr–±ς?ΪnO颜τ@·)ψΓ#_»–K’Ιe7ν8.Η’λ^£φ=@΄σŒ–―c(Ι?SΙ5Κό»ˆΨ_YεDλ(—ʐθGλ]<>ή!Σ#‚)Δ2Ε'˜₯†TπFηJ*ΡΊΈšŒ4CS†ΖΚIf–RB‘ ΐ'œγΆοΏγΚγώΉ·ςCΑž :ιΎ½ΈI•c*η‚rzžΥΧήΗ•ΗύsoεUΫP<Ϋΰχό}κξ'σ5Ψxςf·πŽ€θH%qθΜ:γΎΗή§ώβ3]gΔoω5ϋg£¦?=ΟΝ{Η‚Ω_ΒΊaNžHˆΰώ΅ΰΉ―NψU―ΗφvΡξ\,ŠΕνσό@ςWλžQMٍVΉβ7DΊK{φ•ddή6ΖX’:ώŸ Až³ί£ZΎ#πύŽΏn±ή«Lωr‘Γ/[Ϊ°tŸ‡š}τw3άKsεΆε”Οlϊ֏šϊ BΛxCV*\:ƒ ―9΄ριž+ΌΤμFψfšBcn£18>‡₯z―‹ΫJΆfΊΥ­­ζΪ€F$PY›(=*ΰ~[ι…ΥΥΆ₯k ·\I™’ χtγƒωϊTΚχJγGo₯xΧEΤst-₯=RγδΗγΣυZ¨2¦9‘qΨ†VΛx―ΑvΊ΅ΌOYM@Ωΐφ :Ÿΐώ›ΓΆΧ+qt&i™NΤjγ=3άητi»Ω‹CŒψ“αΈ4§†ώΑvσ6njtWκ1μ@?’Š+¨Μ(’Š+»πΊgG·?οθFΈJτ_¦ν Τ½‘φ2IrΧ—§κ€Χ΅·idHγRΞδ*Τ“Ϊ½ Χα½οΩΓMyn“c;$bϊΥΝψRX¬υλ ηΐ‰%‰tΟαΦ½ΡX2†R ‘GC]yž6­(ΣΠ/ΣΌ ©Hνφ¦ŠΩTΰΫΛ{€;}qPλΊΡΩLΫd…ŽEιŸB;υzηxςq“ΐγ8 ‘@m]nƒΰ{έgΑΪ§ˆ ΊΆŽΧOgY"}ΫΫj+`c£WWα?†zWό"°ψ‡Ζϊ³ιΆ7hcŒ…b§ξ’H9$r9ϊwΦΪ•‘όρBθ‘Τtۨ渊S‚GξΥJ’1’ ϊ½(ζšν|πΧ^ρu±»±H-μrT\\±Ur:…qλŒ{Χ_HYιΝγΏƒšF›α}R;;‹T‰.#.T3*Θϋy·Μ89β€<“Ζί uΪ‹»δ‚βΛ!MΕ³–T' `@#>ΈΗ½qUκž'‹Ηώ π„ϊ6¨]v*Χ€>@Η”dOͺό<ψso­θSψƒΔΊ‰Σ48Ι λ€`ΰœœ€3ΗBIβ€<֊υν{α–‰α»­gΐZ̚ŠZ‚Α) Δ“Œ γœΝSψwπίOρ_‚ο΅{½J[)ΰγάvωHŠ¨Ε›#<=ΗJςΪ+Ω΅?…ήΏπ…ζ­ΰέr{ω¬ΡžA#++ν+€ ©ΗLηυΝs ώ/Šlο5]Zϋϋ;E΄$<άΔ œΐc$ϊώ@{E{¦ƒπŸΒ"ži΄?]]ΩD6Ί&Ο1Άρ-Ξ±s©ήΛi£ι`™ž1™ο88ΐRO·πηΤW‘ψΗΒώ‹Γ#[πŽΎgU—Λ{;ΗU™Ή(0€γ γƒœρ^y@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@zΗΐωŽΫύ©^O^―π'ώcŸφΓjTΟαάυsQšq4Ζ¬ ΥSΝFΤΖ¨šžΥPm^©π#ώcŸφΓjW•5z―ΐωŽΫύ©J{ ―EV%Q@dyS'“Κ‰ά)m «Τϋ 6ΜΟΒΫ­:ζτxKΕZއ§ή1y,γŒHͺOR„‘·κ9χβ―ΙπΏMO‡—ž±ΉšΌu–{ΗI$2±cΣϋ c·σθ‰6Μ°Ά›z%a…>b=qW"ΥΥξ¬νήήhδΈBΰ8Ζάg¨ό+8βα'e"έ-ΡcF±n‘ebd°$!ΘΑmͺ8ό+β?ƒγρΆ‡›-γΩ¬W)qζ,aΙ*cή­Ή΅(βΥ °(ζIPΈaŒ gό*‚ψˆ<’¬:}δΒ7(Y‘CΔBW¨*r} Ό!|64‰nήΝ|δ—ΜXߗ±«ΝxΨΤ΄¦ή,aσƒžO1]}…ΙΊΆ΄2@I?$ƒ 1^qβ‹CAΎ– ο xb-kΑ€η`H <η΄’χH’³Τ,~[YψAΣ#Υ$?ٚ ΤΜΎHΜΜωHέΐΐ9=*mkαrjW^+u‰­Ϋ_ςD!ʐp>o˜{TΧRΛΓλͺκ~Φl―’Ι`ΊˆG#RΫΐ'ξπGΦ·|wβλoZΨΟym=Βέέ₯šˆq•f rrG-_ΏqhršgΓoιvYiή>Τmν ]‘Εœ`(ΎͺmKα‘/‹oΌA₯ψσL»ΌŠ8₯ς­•²z–ξT•Ύή7³_λz΅Έ7]—Ϋ€—+΅Χjœ/9ΟΜ:ρPxGβ—⏠ίλv1Ξ‹bgΆ|y‹΅K‡ΑϊϊW–α‘‘ΰύUΡEίφΏˆ΅Ώ7g–g‰SΚΖsŒs‘ωU+Ϊj^=_j²­βEkφh,e…Z8ύ[’rynέύͺ8Ύ"θΓΐ6ώ,½ΪΨΟ‘LJΝΉ”(ΰ“΄ž½:Φ·ΕΫxnνΏαΝoE±»pή]ΑˆΙ=7z~΄Z[††ζ₯ΰ >Oθšφ‘διW:q`ιon‘nΈ*ΐcη―°¬/…ϊΆ—u¨Ι’ψϋO†φεξž­PΜ}ΫΣπ­οψφκφϊ=–—¨kΔΡωίe²qHςFζ=†Aλq›ρΕ—‹ΎΫv·V•‹Ί²»M²DNp~œσŠ/$zΓ{νgώλ‰|Sw©€ vί u/#;»ΐΐVΧ…<5i“\jΎ,½Φ 1σ@¨‘²l‚yψΧ]EO3Ψ,QEHŠ( Š( Š( Š( Š( Š( Š( Š( 0$€A#―΅C}pΆΆ²JίΒ8§°¬Ο Κσ5ΫΘΕ™˜:—+4‡m.mQEB (’€ (’€ ςŽέt?ϋo΄λΥλΚ>;υΠνΏώΣͺ†βg–-J΅ Τ‹[L΅"ΤKR- %bf·ΈŠd΄nΣ ζ« zΠ‘ŠšίόϊιΏχνψΊγ5 ·ΏΏΉ»˜*Λ<+±ΙΗ·5HSΕ ·Έ…ΌM}αΉ'k…ΔΰI”‘ΗCΑς:ΡΧόuͺkzkΨάΗk.Ac °'8εΗε\ˆ§Eέ¬$»[ˆΊ΅•½¬Vφ8#XΤ²>HPΟΝν\@§BmlΏˆυ˝~ύnο‘cβ @ΐ$χ'ΦΊ8Ύ%kĈ-΄ό( 3φΧ NΝΜ,hkz€ΪΞ©5ύΖ“K·pŒΌ(dŸJ“EΦ―τ[ƒ.Ÿ;FOήNͺQY`ζ•ϊθPόOΎXΐšΒΩίyY”~\Φ]Ϗ΅‰υ+{¬Β©,; Œ·9<ήΉњf;‹ˆϊ΄φςBφΦdR‡ωΑώυqY¦ζŒm½ΐιtjΊ,K R,φΛ)†BcΤ*έ—βuρˆˆ¬-’Oο33ˏη^{š3B“Ac°ρξ³i5Μ¬`ΈyΘ'ΞRBγ Pΐͺή#ρ}ˆ,£΅Ό†Υ#I€Δ¬@#»9k4fŽg°Xλ΄oκzN›΄m …2#9$󆡙β_]ψ†he½ŽΪ%*’% O|“X™£4s;X,Y²ΌΈ±ΉK‹9žό‡»}?βf‘ aolΰΉ#ψԘΙϊυηω’…&ΆΏΎψ—¨M-€δπ‰rΏNƒτ&ϊςβώεξ/&y¦Όξrj΅‘Ι½ΐvk΄Άψ¬Ao" MΎXΰc'ζλ\NhΝ ΅°~%ρηˆg†[Υ…<₯*«!y9'’yιωV8$GS3Fi7qΚ|JΦUL @ΖLo“W9βrλ^Ώw’5p‚0±‚ŸR}MdζŠnMξ+Ε+Γ*I²H„2²œGq]Ζ—ρ'PΆc½ΆŠμ¨Η™»c―~•ΑfŒΠ›[ΪkΏ5-JΩννγŽΞ'b„³‘ιžί€§[όGΥΰ‚(–ήΑ–5 #δΰcŸšΈœΡš9˜XΫ΅ρ Υ·ˆŸYŽ(>ΤμΜP©Ω–%λ φm<Ϋ7βλ‘Υ/€Τ΅ ο&TYfmμ ϋdš§š3IΆχΩ£4άњC6|7―έx~κYμγήDΨD ‘ŒƒΨJΩΤ~ κ·φ“[Ψ¬s‘Š£‚γζ74fŸ3Z Εν#P—JΤ ½·Tia;”8%OηzΧY 3XŸm?ώύΏ\.hΝ MlσΝhhΌϊ&’·Ά‰ΚͺT A+ƒτ"³3E!­ΧΔ]ZζΦh$·° *b¨ωΑγζ­/ƒρχ©ΈŸΜלf»„·ΆΆ—Z‘»Έ†Θ›L<ž™«‹nJδ΅‘έψξκ{/ ήάΪΘΡOŒ«―P|ΕΣβf‘An¬νη`>ψ% ϊυΤ|@Υ4ϋ_Εo}k,­εαebx½5γͺœšzGc¬xWΤ"ha1ΩΔΓÝηώz~G9¦fŒΦM·ΈΟ{π/όŠZgύrώ¦ΉΟˆ"Τ4 ~Ρ¬d_-νςρH2σίαZή Υ΄θ<-§G5ύ€r,Xdy”Ικ 'βΕέ΅ή―fφ·Ξ‹ Dα€;V~ξ„­ΛŸπ³ο<ΌgΫουήΨόΏϊυΛkώ%Τ΅Φn›)ΚΓΪ€ϊγΏγšΔ£5““{•aΩ­ZΎΡ Ϊ|ν?yz«}EffŠC=ίβ}Η‹6ϋΙ!AωgjίυkΨLV«šž­Kώg§ΰ+ŠΝͺηb²$ggrΞΕ™ŽI'$šλμ>!jΆ66φ‘[ؘΰcRΘω όΥΖfŒM­€Φρ·q―_‹»Δ…%#Δ@€IξO­eζ›š3Kq–,d³»‚ζ°Έ‘Iυ5ΩΒΜΦ?ηΫOΏoΕΧ š3M6Ά‘­j“λ”·Χ{²c! 0gιQι—ΣiΊ„–Δy°ΈuέΠϋcTσFi\λώf±>Ϊύϋώ.Ή Jφ]Fώ{Λ‚<ٜ»mθ3Ψ{ULњm·Έτλλ:ν.l¦hgNŒΏΘϊŠξm~']€!ntψeΎ’πΑ―;Ν‘I­‚Η]«ψοTΤ. eA 2¬’Ξ©n=HΘιΕ[o‰ZΓ)Sk§ΰŒέΏ\6hΝΜ,nxkΔw~’w²Ž3ΞRqŒτΑ΅£­xηRΦ4Ι¬n`³H₯Ζγ0a†Œ±τJŠ9¬³JΘΚΘJ°9i™£4†vΪGΔMVΚ5Šνb½AΡ€ΚΏζ:ώ"―ά|OΊeGΣ`½^BΘ σ¬Ρšv+#OZΦ―υ›.‘;HWξ―EO ͺVσΛm:Mo#G*ΚκpA¨sFjn3ΎΣΎ%κ0DφΦ’ίΛcυΖGθ*Kο‰·²ΒΛgc »‘μζB>ƒWžΡšv+"ΝνεΕυΛά]ΜσLό³ΉΙ¨3MΝ©μΡMΝμњmμњnh QšnhΝ;4f›š3@£4Ϊ3@ΝάњvhΝ74f€š3MΝμΡMΝ fŠnh θ’Šκ3 (’€ τ&|;hίΠΪΌΒ½gΐ‰Ÿ Ωχτ6―O*•ͺΏOΥ ›pΕ^ΰmsΙEΣ―μ'ΉνŸα>ή•ΖΓ]†:τ1*5cΛ"nz§}ŸjΣLsΩW»Jσϋ™₯½Ίyηl»Θz &ΈΈΌ(n₯iJ .ξΥ41W›Nš’ΌΙ”Ε^ρTcΗΊ _ϊ)+θ¨c―ž>. |BΥGύrΡ)\υηΜ‚œ}Q\Ζ‘^έϋ0ΘO^1θM^#W΄½_RZF΅ Λ&ζΪfŒ°3΄ŒΠ£ά|ρ\“ΘκΪv‰Ώ>ΏξΧKπΒΖm/αοΔ+ Ύ}©Ή‚M§#rΒΐΰϊdW‘Βeβϊυ―ό—ŠͺqkΪΌIv‘j·θ—ŒΝr«pΰN[οηζ''9λ@λπ?UCψK¬κsΖΗiw4₯«b8ψͺ_tΨ>"x*ΟΖ:φΊ΄ˆ­ΕΆμƒ–\yI'άϊW‰Ϋκϊ•ΆŸ-…Ύ‘yŒΔ™-㝖7$r ΰτ•?LΧ5m*)#υKλ(δ9u·ΈxΓRŒΠΡZ>§¬|*ΠζπžŸ₯j—vqGo=₯βηiDΪvε€ ΐ<žA¬/ˆ7ž&±ψepΊν―‡tΘοDl`„ΏxT‡*[ŒŸ@:ηŠρ'YΤ΄yΪm*ώκΞVᚠJn‡M_XΤu™ΔΪ­υΝδͺ0­<…φAž”ξž%Ρ>"ό+πάΎh₯Έ±DIm‹„ω‚eη€Ag5sGπΕχ…>ψŽΛTdϋ\ΡOpΡ#e ‘Ζ~\ρλ^€kZž#>“¨]Ω3ύ㬛ΎΈ<ώ5,ž"ΦδŽκ95E£ΊΟΪάΉqœgζΰΟjΚ―j…r/|+€λŸ /ξ~ΨΚ~Πλd„2‘†Π₯H#g?ŸŠΦŽ‘­κš4ŒϊN£wd͍ήD¬Ύ ϊoνmΰζ·Δ¨ηΊ–9"·WHωd·ρ6όœσŽΉγŒ?ٟό ‹DΡ¦‰u; ?y6έΔ;0ύΰΩ¦Ex―­jzΜ«&­¨]^ΊηižRϋ~™ιψTZn£{₯ά‹6ξβΰ yHQ±ι‘Ϊ€=οαyπΫΒή"ΥόVbΆY£PΆήbΉ%C` bΐ dό=$~Οώ+ |ΩΗυΞ:ς-g^Υ΅ΆC«κWw›9Q4₯‚ύΰTVϊΎ₯m§Λao¨^Ec1&KxηeΙ¨8=ε@ΕπŸψD|d3Η”8ΆrQπ¦k?|3ΥΌo#΄Τέ™βέΖπH`Gs‚€vΕxκZl3E§j–‘N1*A;F²Ÿ0ž§―­wΏ /ό>‰}’ψΆή;K™›0κJ™uΑΨAzp}ΐ=Gΰη€Ό¨>«i-νΜ@%½»–ΒεΞ@=H?p?SΔ‘_x†σΓ|ΎS;NΉcΊs–*WΈ8ΙζΆ­5ο|8υIΌ?«Λ­λw‰±ŽπΈnHδςI―Σ΅έ6μ]iχsΪ܌βXd(άυδPΌ|LΣ,υ?†Wξ· A‘k±H«©]ςΰ`ΰAcƒΘΖkηΪΣΦuν[[d:Ύ£wy³ξ ₯,θ³(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(―Wψ1Οϋa΅+Κ+ΥΎΜoώΨνJ™ό#[žͺiN4ΓX1©Oj¨Q5HΥP½Sΰ?]sώΨνJς¦―Uψ1Οϋa΅)Oa£Φ(’ŠΔ ’Š( ΡE`]Θεe^ν³U}z9¦ρ6ž–Σω›mݎjθ»K–ŒΡv«δπ?Ι4=€]Grρƒ<`„|žIaε$Υχ•ώZ*‰4ό¬s Μ.±[Λ―΄Θcb`\ 7‹Μ­|m΅%³Qpΐ‘@Ω>ΌšλΞέξι£αΥ|œΟψš¨ϊ˜ξΞφˆY‰$ξnOηYΌ$“Ί}[έυKε*Ι­$Z°WKTYg²ξ}y·ΗίωψcώΓΆϊ Χ₯ΩΪCgŠΩqƒ “όκ·’iΪδVρκΆ©r–σ-ΔA™†Ι£pG©ϊO–Χ9εǝ~*ΟΰΝ9c}ŽuXBΆ3΄ν“šγ~.θ^'­t)ΌCβ―ν›wΥaD‡μIΧΓΩSό{Χ»kΊ›―ΫEo¬Z₯ΤJ'Dfa‡ΑΰSI―h:fΏλ‰tL'Œ30Ϋ ΰSωΦ‘¬KW<’Oω,Ώ?μτ\Uΐι6—^π•β½5τέZΚ}?U„1α™δXεΗδ? }"|7€VϋRϋ}Ίφ³\MΉ³$xiΗ@:zQ†τˆΌ:t(μbAC΅%Šν$’2Nz’zΣU >:΅·Γo…Ί₯ΦN‘e©3]œeW3’ EΟή»ΏŒ>+Υtm9u=2λΒχΊ9΄Vχ@Ν4²χ΄€9νΝzU·‡t‹mh‘iπd…)φWΣ’G͞η5ƒcπΏΑv7‹uoαϋO9X2™δP}B³ϊQΞ›» 3Žρm–›βY%†ΏwαοœŽ³’ββ?6Α–ŽIγ=Θ8«Ώ uνUόgβk“ιϊ•ΥŒi'φ€J†O»ςΉdόΓά#šξƒόšΞΧ“^O »‡jgάσΦΊ>"Ξϋ…ϊχ¬c¬Ϋ-ιΕQ[QEQEδζmφzΕy?ǏωΫύ§U ΔΟ+Z‘j%©VΆ$•jE¨–€Z@J)λQŠx  <ŒSΕ  8`§@œ 0Rƒ@ΗƒKšh£4ΰisMf€š3IšLΠσKšmμњnhΝ;4f›š3@ š)3FhsFi3FhΩ£4άњZ3Iš3@ š\ΣsFhsKšm Ν™£4Ή₯Ν74f€FiΉ£4΄f“4f€4f“4f€4f“4PζŒfŒΠ!sKšnhΝ4Ή¦ΡšvhΝ74f€šLfŒΠζ—4Ϊ3@Ν&i3E:ŒΣsE:“4”f€4Ή¦Ρš\ζ›š3@Ν¦Ρ@Ν¦Ρš.isM£4 vi3Iš3@ š3Iš3@ š\ΣhΝ.hΝ&h Ν€Ν f“4™’€šLfŒΠ³IšLњvi3Iš(Ω£4Ϊ3@Ν¦ζŒΠ³IšLњZ3Iš3@…Ν.iΉ£4 vi)3FhsFi3FhΩ€Ν&h f“4™£4΄f“4f€š)Ή£4μRfŒΠζŒfŒΠζŒfŒΠζŒQš\њLњvi3Iš(Ω£4άњvhΝ74f€4f“4P³E74PΘΤQEu…Q@z€u­:= [›Έmζ„°"g XA?Zσ +js!5sίbΦ΄qΧUΣΗύΌ§ψΥΈ΅έuΥταoIώ5σ½Ό±²—ArŸJEβ uΦtΟό όjδ^#Π]oKφχψΧΛτV2δO³>ͺOψu³kΊVΟq“ωfΎxψ‰ͺΫk^3ΤομX΅΄ŒͺŒF7E\ώ;s\ε‹waΛ¨QE‹ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ υ_σΆϋRΌͺ½WΰgόΖν‡ώΤ©žΓ[ž¨M0ši¬ j6§΅FΤƨڞΥPf½[ΰ?όΗ?ν‡ώΤ―)jυo€σΆϋR”φ=bŠ(¬J (’€ (’€ (¨.‘΅MΣ8QΫΤύOEsχzρ9[Xπ?ΌαYΛ%νό»CΙ!=ΐΠVn’ΩjR‹;ΡT4½yG¨ΟAοίυ―J·π_†μaιΆδt-1.OβΖ©A±\ωτx5ξΪ―Γνϊ#δΫIHβHŒΐOδΎ,πΝη†―DW8’ήLωS¨αΗ§±φ’PhiάΔ”S;5m g¦:ρY^†γ_°‡Q`Ά*‰2p1θO`OμΐΟ£5μtΫΒΟ4vΦΦΧ1²ˆ H±ΘΚρΤc'π―Ν7];Ν¦ΡšFiΉ£4κ3^ΫαmA—Β¬ΦΦ³G,§™Τݏ›-Τ`ηιŠρ[‘άΚ°1hƒŒ{x5N6ΖfŠnhΝHΝ¦ζŒΠ¨Ν6ŒΠ³FiΉα…μυ˜―.υX ΦθDQ.ζ\·Rx# ΗηM+»ΑfŒΧͺψοΑZeŸ‡f»- 3ېν‰·'CԞ™Οα^Qš%Α;ŽΝιΏ 4;Q/$Ώ²·ΈuŸj΄ˆ΄qTl΄Λψ―5‹ZBlΑlBPlΊΟO­>] œhΝz/Ε­*ΓM‡L6p[™@ήRέ€ΈΝqΎ΅†ϋΔZ}΅o‚Y•]rFGΤsIΖΞΐfQšχoψ@ό7@Ρδ⨄Γτ χώOώ*―Ω±\πœΡšχoψ@ό7@Ρδ⫟‡ΓΊM·ΔU°ŽΖ#fl|Σ„Έέ»ω‰₯μΪ žSš+Όψ³¦Ωi·ZjΨZΓn°ηu₯«; u¦ζŠ@;4f›š3@Ν­ΰϋ85ΨZήGζ[ΚψuΙ=Η5μπψoώ£ώΙΕUF[v<'4f½Ϋώ? Π4ίω?ψͺ?απίύGύ“ŠͺφlW<'4f½[Oπξ“Δ[›±‰¬ΦΓΝI—·/?15ƒρcN³Σu+°΅†έ^XF‘A;ͺ\,;œ>hΝ75·ΰ»{+ΏΨA©ϋ+Ήάΰ1ΑΪΤΰT­@ΖΝκ΄­&ΧBŠhmννΔ‘cς!qά:ϊ~5δΩ§%g`C¨¦Ρš@:ŠnhΝ;4ShΝ:ŒΣhΝ:ŠnhΝ;4SsFhΤf›š3@Ν¦ΡšvhΝ74f€š3M£4μњnh fŒΣsFhΩ£4άњvhΝ74f€E74f€E6ŒΠ³E74P³FiΉ’€š)Ή£4μΡMΝ fŒΣhΝ:ŒΣsFhΩ’›š(Ω£4άњvhΝ74f€š3MΝκ3MΝμΡMΝ fŒΣsFhΩ£4άΡ@’›FhΩ£4Ϊ3@Ν¦ζŒΠ¨Ν74f€š3MΝμњnhΝ;4f›E:Šnh QMΝςUQ]DQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@z§ΐίωΫύ©^W^©π;ώcφΓjTΟa­ΟR4ΣJi¦°(i¦58Σ 1ͺ6©£j`FΥκίζ9l?φ₯yKW«|˜ηύ°Ϊ•3ΨhυŠ(’±((’Š(’Š*–‘lΣ―ξb€Θxσ$PvΚΡCWΧB†<4μeoN‚΅£#]±ͺͺϊŠu”Tvm…QLAEPEŠ(ͺ³κ°dI2dvŸ¨Ύ½n€…ŽVχΐΦ₯Ι-ΨlΨ’©iχλz[dR(^¬ΐbΣNϋ «QLŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š+3UΉΊ …Q#df €έ•Α+šJ‘)iQGv8¬ι΅ΛDϋ›δ?μ―ψΧ>‘έίΘHJίή=kΨθAH{¦ ώΒτόMeΟ)|(ΎT·4¬/>Ψ…7EΆ9ϊUΊDUE  ΐ₯­W™ (’Š`δ?ζmφzΕy?ǏωΫύ§U ΔΟ)Z‘j5©Ά$‘jE¨Φž΄€‘kwΑzHΦόKcc &'}cϋŠ201ψΦηΰσͺψΦέZύqŸδ 5Έ3Φƒ°φκ£s¦ir€|΅™•Ύ₯F?‘― SzΨHθό'β›^ΖΡJοfXyΆδεXwΖzzφΏXAβo Κ‘ βhDφνίv2§ϊ} ―œ…}#ΰΔx<%€¬ί+ d'=†3ό©Γ]ž?ΰοMβ[)ξ"ΌŽžYVBΩΰώ΅―aπΓPžκuΈ»Žήή7(’l,cΈ\Ž>¦Ίƒ,―€κlƒ nΙΫh¬ίˆή6Τl΅©4Ν&QnζHf#8θ#ί9’ΡJμ5*k οmmž]:ρ/FLF?-Σ’ ό«Ÿπ‡…₯ρ‘sjΣύ‘­€2Œ’9ΑΘζ»Ώ†>/ΌΦngΣ΅FΜ‘ω±Ν΄) 8γΈύk+βεη…όVo4YE³_ΐS±X3Aκ;R΄wAΗ£6’‰α·-ίj}”Ϋ#·=WnOσ―ρƒ&Ρυ=*ΚKΘεkω<΅`„ω”dϊύκυΩ/nƒZψIώ”, ϋπ>—»8ιΦΌrΟ_Τ΅ίθgTΈσΜ7q„ωq—\τΠUNΐ‹ώ.π]懀‹ΫEnQcTΪxΟ¦M?@ψ}q¬hΦϊ„wρF³BΙ#_jνΎ.Ȟυέ?­_ψo"N™ώλθmG*ζ°_CˆΡ~]]Z€Ϊ•ΰ΄v,{Ψ}NF·5Ÿ―|<ΤτϋˆΙ…τS8Œ2.€xsοš‹SρώΈΪΔ³[]yVλ! ΐWh<ΖOωι^Δu4ν2Ÿ(΅ϋNΜ±»’‹Ψ5<ξΫαS΅Έ7:ͺ€δr©εκHΟι\Šό3{α»”K’²C&|Ή“£c±τ>Υ§¦xϋ\:άά] y@x6»Iθ8ΘϊΧ |X…eπlξέa–7_νΏΙ+E­SŒΠΌy©θ]Εͺ,0ά.σΦΗγΟ=+#Αή—ΔΠάΙάpT†BΩΞΒ½kΐς&iυΗϊšρΔ:¦ˆ’¦™t`YH.+dŽA‘€¬m ͺλώ‚pί£ώ5SWψqq¦ιwW―¨C"Α¨Œ‚p:u£αάή#ΥWϋGWΏ°ς"‹ΚE2Ÿ\…ΞλόιόPρlvφσhΆ%^yWmΓυ©ώ©ύ>½£k†§žψoΓΧώ Ί1XF6.<Ι_„O©ώ‚»΅ψRΎWΝ«7­ψΠ«­πŽ›ύ‘αxμβVΉx<β ΖωsΙό‡ΠW.‰γι/MΧφY3«s„Ϋzcπ£•%°\δόWαK:΅ΞΙ­\νIγιŸB;ηs_Bλ2κžžΫS‰>ΤΦΔ²©ΘGβ+ηœΤΞ6ΨiŽ$2O χν&ό)ΰ΄σ€Ϊ,£ϋΞy#σ8ό«ΙΎi_ΪΎ*ΆΉ†Ϋύ"OO— όρϊΧ§|J΄Υ5 ,t‹fœΝ 3Κ0«Θ‘Τγς§dΨ™oΑϊšψΒ±Ιw‡‘Υ Έ§‘όΑρ― Φ¬KΥμeΞθ$)“άv?ˆΑ―Rψ]₯kZ,χΆϊ“Γk2‡V.€cƒά±Ύ2ι^Mύ¦©ό“―•!ή^‡ρϊ 9k‚άΩψ/ KϊψΩEgXΙhŸκϊ*΄> ΘώΎ?φQYφςZgϊΏώŠ£’€?γίIz_δ΅εjΕH*H#‘κγίHz_δ΅εY©ŸΔ5±7ΪgžίFΎπKπž”ΜI&Ι5σΎkθΘ£€ΧΊΣ§Έ™ΰ s>γϋιzxΧeπ’F“ΕΔ»3³8Ι9ξ+‡cσ­vΏ?δm?υξΝjcΈΩΫxχΒΧ~%Τ΄ρnρΓo?™+σ‚HΐΉβΉλο…—Ϋ³YjQΟ(ςδ‹fγμrksβ—‰/tH,ντΩ<©n73K€J¨Η>Ήύ*?…ž$ΏΦEν₯/žπ…t€A{V•ΚΔλcΘ –Φζ[{„1Νt=AEuήπ‘­@·72 +W£:ξg‘xγάΦί‰τX5ŠΦV(ς"Y₯ΑCdΐ?ν<_΅.˜–ώ1Ε+<…‚”Lt_εR‘½ΗsŒ½ψTβl΅5y@αe‹h?ˆ'•yΦ§as₯ίKi}ŠxΞ Ÿζq^­α=/Ζ:n­j7?i±s‰V[0κ3Θ9ͺŸl#ϋ-† ¨‘Μ ΓΈ ?CωΠβ­t žV¬Uƒ) Ž„TŸiŸώ{I}‡4™¬Ζ}α’OƒτΦ$’lΠδΈ+ηΟ΄Ο=€Ύ}αωtΟϊςOύWΟ₯N‚G}πyΪO\bΗμmΙ9ώ4³Η^»ρ.³fΠΙΡBCΚάσž€wCΰΧό7υθϊWQρKΔΧΪ7Ψν4Ω<™& ο(ΐ?5n]C©¨ό,ΉŠέžΓPK‰TdFρy{±Ιύk‡Σ4Ή―5ΘtΉ‘;Λε6ρχΎEz―ΒΟίkp^Α©IηKnU–B$6x8τΗλXšά Ζ @šρH@υΖ?₯'h.bψΟΒzŸ εΦ .ƒJ! ΄δpOsνV­~]\θqj1^ΖήmΈb’Η+Έ/^½«¨ψΝ"Ν§ύ~/ώ€υxnaƒ΄Ω˜ec±Θϊ 4ωUμ8 7αmΜΆ‘ου·™†|΄ΜΫυ9₯s~-πχ†ΚI3,φŽv¬Θ1σzΨΥ…ψƒ― L]5Θ0οΙ·Ϊ6mώοLώ=kΤΌ}]ψ/Q,!*δt ‚)Z-hž%‘θχΊέθΆΣα2?VcΒ υcΨWvŸ f0ευhΔΈϋ’Wσέύ+¦ψ[¦ΕcαX.GŸvL²7¨Ι >˜ώfΌϋ[ψ¬έjr½…Ρ΅΅V"(ΡTρ؜ƒ“ϊQd•ΨμΎκ2Όλsu 7Ϊ€)a ΖwΗΣπNλFΉΔiγν+)…vŒn>ΎΒ½«ΐZτž!ΠVζαUn#Ε&ήΘB?Zδ<7,ό[ΥDδs*EŸοδδ›ŠΑqΆ_ εkpךšΗ1r8·?RF*η<[ΰ»Δ.ζ̐¦T*Oχ‡o­z4 wUΊ‚}Q0Η`Αζ΄6OΜΰžG_JδόUβ/ΩιJΦtψ£IcςžwΜΈξΉοD’—@LσμњLf²μњm.hsFi)3@Ν¦ζ–€Šmμњnh QšnhΝ:ŒfŒΠζŒΣsE;4f“4f€4f“4”μњnis@ š3IšLΠ³FiΉ£4μњnhΝ;4ShΝ;4f›E;4f“4™ fŒΣhΝ;4f“4f€4f›FhΩ’›š(Ω£4Ϊ3@Ν€Ν&hΩ£4άњvhΝ74Ή ΝΪ3@Ν™€Ν:ŒΣsKš\њnhΝ;4f’“4μњnis@ š3IFhsE&i3@Ν™’€>M’Š+¨€’Š(©a·š|ω1I&:μRqωTUΫψiBθΠ,XŸsΈιAZœŠη%ύŸy>—χνΏΒμϋΟωτΈΏmώθ@ I<*ΘΣοHΘ³ΈΗύroπ‘΄·9Ύ΄ΧCΝ?³ο?ηγώύ·ψQύŸy>—χνΏΒ½/ϋ:χώ|ξοΣ…E=ΌπcΟ†HσΣz‘ŸΞ’iυ­ΎΗœ ΐ2m.gό*ΏN΅ιUΓx…Bk7!@ ώ%A¦mJ³›³FmQAΈQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW©ό˜Χύ°Ϊ•ε•κζ5l?φ₯LφάυM4γL5CM4Ӎ0Π 1©ζ˜i―Vψ1Οϋa΅+ʍz―ΐωŽΫύ©S=†X’Š+‚‚B‚II4R7N(ŒΊ΅šΛ`ίξ‚j³kφγξΗ+{ΰλM»§»Ÿ|’Δ‹Ψ"œ/‡βώ9άύγY7S‘vˆ£_€Ÿšφ Φ­¬λs Λ`§¦εΕVΆ­ ˆχ°ξόώ*υ\TΎΡ.έŠ(ͺQEQEV6· H0Ώj‘DOΈ>ΌVΝšΊ°Σ±ΚA’έΙχΥbνπ­+m lΟ#J}ΐ­š*8‘󱱒ƁB¨θΰS¨’΄$(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*풜―œφτ Σς©¨ U  (€ RΡEQEQEδ?ζmφzΕy?ΗωΫύ§U ΔΟ*ZzΣŸ019ΛΑ Κ?αΨϋŠτ[?‹–Ζ1φΝ.d~ώTόρZ^2άZ’‡„ΎήΘξ5.(#`ίgVc±#€?:μ>$ψ‚-@–ή&Q{t†(uU<φΐιο\ž­ρfg‰“JΣ–'#‰'}Ψ€ρ―8Τoξ΅+Ι.―§yηs–v?§°φ‘Ι%dξzηΑ/ωjυσ²ŠΙψ•ΰύJ}r]OL·{˜n.‘Œ²0tκAΖ:Φψ# +ϊωΩE7Vψ‰.‡β]FΒςΠ\ΫE ²6ΦPT0zϋSΣ•\:ψWαKν.ξ}OSˆΐΝŠ(›οrA,Gn˜όMsί5ξόMΌ.ZΒρΩΙ$Λm_Φώ*M=³E€YycΞ•ƒϊ.1Ÿ―ε^m4²M+Λ3³ΘμY™ŽKԚ–Υ¬CΪΔΧώŠ|3Ο¦„NqΛEόλΖ΄Ν#P:_φW[_³yΏhcnμmόqšˆ4―pg bΣmλ’1^γρKώD‹χ£Ρ‹^žTρɌμ`ΨυΑηΕ_·΄9τομΟ#Ν*|Ο΄oΖ›G§­i& τΘ—₯ΧκkΛ~ψTx‚υ.ΟόKν˜oPy‘Ί…φ§ό‹ϊğμΧOώΚσΌ„Ωζ}§nο|l5›ΰŸΒ1gqΨ>ΥηHw³ctΥ6ž©βϋ­NΛJ[XI-ΛΕhΤ…}~ΎƒόŸΌπΆΏ S]]ιχ4’HΔ$žk³…·P_ό›μ*¦­ρ?ϋGJΌ²ώΘςώΡ ΕΏν9ΫΈœlη­q}A\ο|/ύ³ΰλw²œGqφ$Έ1ΚΑχΑϊWžέκ_mo ³ύ΅ί8 ͺΊ7Έ`ΈΕsρ=‡.YμΩ^#Μ…ωWξ+ΠβΕ™‡/¦\ Ί$?ώ΅Ι­XXŸU³ρmŸ‡žϊγΔQ#€&Iαxγξ†δφιΦΌ{5ΤxΏΖ·ή#_ ’ΪΨ†Θ…%mΗΏι\j$ΣΨhφŸƒϊWΩ4/δ\Kx/ϋ‹?]ί₯CͺόNΆ±ΤmcΣήu†C˜&6 ‰Δαk₯%•–Ž!ςας’ssΈ9υ―8,I$œ“άΥ9YZ"·sΦň23€Κsηώ&Ίίιι―ψNζ81#4bxξ@ΘΗΤqψΧΟ5θ^ψ•&“£ZΨM§}₯ ]‚_΄lΚ灍§ ΐό(SΎ’»Α_ωίΧΟώΚ+>ΓώKTWΡ5αΟΕ‘6  wEupgTϋF<°‡ξσYΦώ,ς|jώ ϋνğ³ω½2›~φίΗ₯ΚΘ,vΏγίHz_δ΅ε5ΥxγΖπ”GfΏaϋ/ΩΛωΫχnΗϋ#+“ΝLήƒC³_DxώE 'ώ½ΦΎuΝz.…ρ/ϋ+G΄±ώΙσ~ϏΪvξΗ|l8§“ΤLσΧϋΗλ]·ΑωOύ{?σZαΙΙ&Άό―Β9«›ο³}§χmΟ3g\sœJQvcgeρ·ώ?4―ϊη'σZΰŸό„υ/ϊβΏϊs~7ρWό%ZIφ?²ω ˏ7~μγΨc₯'‚|QΕΥΜίcϋWœ1ζμΫƒŸCUuΝqt;_jQι_4›«† ·Tv=c"ηπΞ 꿝5%v‚Ζ–wγ½SRŽήYξν!Οο&šΡT οΥFO΅Rψ—·c­Ά­¬Go#™#AFF7ϋXλ[7Ÿΰ±i’™HΰΝ  ΞJσmsWΌΦυΌΤ$ί+pαTzΨRm[F₯FiΉ£5˜Ο’ό1"n™^QθΎvΝz—ρ3μ:5΅‡φO™δΐ°ωŸiΖμ g+Ξ³W6¬$ŽϋΰΟό7υζϊUΏςΣΏλƒθUΚx3Δ_πj²^ύ›ν;α1lσ6c%NsƒιSxΫΔπ“έΫOφO²ω(So›Ώ99ΟAEΧ-ƒ©Υό[ύΘΏ›Tή#’½₯}"ώ΅Θψ#Επ‹ΛvcϋWΪŒy»6γ>Η=iϊ—‹ΎΫβϋ]wμ[<ΏΈσs»ώ-Όuτ¦š²AmNϋγGό‹6ŸυψΏϊΦξ“"§ύƒWEW–ψΣΗπ“iΩgύ—Λ˜KΏΟߜ+ chώχιWν>$ύŸΓρiŸΩ[Ό»aoζύ§ΒνΞ6ώ™§Μ―p±ηω― ό_">£^§ωWΟY―BΦ>$hθwwφW—ηEεyŸhΞ8덿֦ +άΦ|&ΦbΎπκΨζΛ*TH#σΗαο\Φ·πΗP:”­₯MnΦ’1e1V@{qλU<ΰ½Fϊ bΛUŽΠΖ#,ΰ‚F ~)n~ ψ’ΖW²»‚έnν%ΰ!στ₯UΥ—0z™ΰν|;’₯“Ν”±’W±ΗOl? ςλ½σΔ>Φa°ž%†c)i‚zŒΞq^ΰΤΏ°ήλ\y εΤΝ1pUpνχszρλέzβΧΖWΊ›(W7227Ud$π}Aεk Gc¨ψƒΕžΏ[;°š”&xOΞ1Θ ;ƒΗ95Ϊx™#ΤΌy%όIk39ω18]ΓρΉ;?Šφζά}³M”L>S‚€ώ<ΦΉ―ψφλ_Ά6vπ K6 ΊξάϏSΗΤs$· nh¦ζŒΦ#š)Ή£4κ3MΝ QšnhΝ:ŒΣsFhΩ£4άњvhΝ74f€š3MΝ QšnhΝ;4f›š3@Ν¦ζŒΠ³FiΉ£4μΡMΝ QšnhΝ:ŒΣsFhΩ£4άњuάњvhΝ74f€š3MΝ fŒΣsFhΩ’›š(ΤSsFhΩ£4άњu¦ζŒΠ³E74f€š3MΝ QMΝ fŠnhΝ;4SsFhΩ’›š3@Ν¦ζŒΠ¨¦ζŒΠ³FiΉ£4μњnhΝ;4SsE|£EWQEP]Η†δ oЍpυάxoώ@Άπ/ύΠsβ~¦π†ΦνCFXώ!IίWαω[ΐΏτ]νyψύz=ˆ++Ε ‰pHδ#ώϊ«Y~'ΟόB…/z™ΓβG\?‰?δ5qΠEwΓψ“ώCWπύW°zΨoˆΜ’Š)Α]„Ό«x―H»ΏΡ沓μΔ«Ϋ΄Œ%Ξ206γžάϊΧ!]‡ΒίΏ„ nuΝP:n‡#Μ ψκA<:g'ŠΪΥΎhZw©ψZ—Q{@L–ςΜΨΐΒ©γ#šρκι<α+―λιΦ7A,p4ε¦Ξ £ΟΜ+oα‡ΓγβδΌΏΤ/>Α£Yρ,όeŽ2@'€Α$τΘό=kαO†<)§ψ†ηRπŽ»& έ­§†VVe,ΚC *ρςΗ>΄σ~§hϊ~₯ug#+=Ό― 2τ%IΚ«W’hž ŸΖuψDβΦΒΦκi.nΞΐdlξp"k‘Άψwΰ―%Υ—ƒ|Is6―n…φ\‘πq‘ς/㠜qΦ€υbΦu 683ΒΎε γςcωW›šΉ‘κshΪ½‘mΜ°>ν§€Γ‘κ2?M]XgΤ4UT΅ΦtΘ/¬d £>κ{©χz°((’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š+ΖΎ8^¬ΊΞŸf§&YΫΨΉ~J?:υ}oT΅Ρ΄Ω――€ C>μ{(χ5σnΉ©Ν¬κχZ…ΟNϋ°:(θ}αW­ΔΚBž)’œ΅©#Ε§ς―3Ν&i3IΆχΩ’›š3HfŒΣsFhΤf“4™ fŠnh fŒf“4μњnh QšnhΝ;4f›š3@£4άњu¦ζŒΠ³Fi΄f€š))3@Ν¦ζŒΠ³FiΉ£4μњnis@ š3MΝ fŠm Qšnis@ š3MΝ QIšLΠ³E74Ή Ν¦ζ—4΄f›š\ΠζŠnhΝ:ŒΣsFhΤf›š3@£4άњvhΝ74f€FiΉ£4μњnhΝ:Šnis@ š3MΝ QMΝ QšnhΝ;4f›FhΩ’›š(εZ(’ΊH (’€ ξ<7 [ψώ„k‡γΓς·θFƒŸπ?†?δ9mΠMw΅ηΪ ρΫjΦςΜΫc‚}2ώ΅Ώ­x†8Ε§ΈyOY1ΏOS\XŠrD’θy5bε-вόO ;Ÿψώ„+–Σ5«›;‚Ξν4lrκΗ9χυ·κΆw:,‹ Α€—nΈδ}:V~ΒTηΊ“μάdŽBΈΘjγώ Šξ+‡ρ'ό†?ΰ?ϊ―Hτ°ί™ER;‚Š( tψˆΗώ…Ή<΅°ΘOGÏΕ_5― XΟ:ͺ»8V8ά +)>Δ©R{W\λΞŸ…Ξ£y5ŒXςν䝚4ΐΐΒ“€MW²ΌΉ°ΉK›‰­ξΛ ”eϊΝ{ίΒj~ΈΥυο¬-ΤΗ°Κ―‘Έ1c΄‘ό8©ΝAπFζ wNρΆŸ¬3߳Ȉ{$—8τΜWk#Φ΅˜Φ=WU½»‰NBM32ƒλŒγ>υFΒφλNΊK› ™­ξΛ ”aτ#šϊ?ΰ‡΅oάjΣkk op8’9ξ N[Žƒ‘ι\ημμν›γC΅Ρb`}Χ“ΙβίIvn›]ΥΙ]žbέ:ΆάηnAιžqT΄ύcSΣVuΣ΅ΛEŸύh‚vŒIΧο`σΤυυ4D’I$’O$šτΩΧώJ―9šΧ—Υ­;Q½Σ.>Ρ¦ή\ΩΟ΄―™o+FΨ=FAξ)πΔ οjwZnρYMpςBƒP‘6‘b@ΐιΗj­π?K½ΡΎ*kΆ«‰/’²c3‡/ΉšH›;^΅εŸπ™xŸώ†=k₯β«²ψ)β›M3Ζzާβ}M”ΟfΡ›‹†iίz`Ι {ΒC‰~ψΓ³Eo©»ΌŠ§€U‚ΰύ2₯O Η­jόπ·α}vϋPΧ;`φζή8VUrωebί)#oךωφΚξζΖε.,&·ΈNVX\£/ЎEjKβΟKv—RkΊ‘ΈE(² § ͺq<Ÿ\P³|Υ-γρwτ†hRϊκκI-Δ£+&֐}qqιšέΠΏα:Kλ¦ΊΠ|+£C1ϋaŒ•lzm“ wΙΖ?JωœάΞnΝўSr_Μ3o;χη;·uΞyΝjκ>+ρ₯gφKύkPΈΆ<䝘7מτΟ…Χ&»Χ|S¬xvηHήf–βΑ‹…ΈbΜΚcΞ6‚KIοΘ­Ώ‰šež§πΚγ]Φτ4-v)cU+ΎB\ ά,pyΝx>¨^i—Ks§]Oip£Hd(ΐzdUg^Υ΅ΆC«κ7w›>ΰšRΑ~€π(2Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ½GΰόΖΏνώΤ―.―Qψ%1―ϋc΅*g°Φη¨SM-!¬ i¦œi¦€i†ži†˜ 4ΓO4Σ@^ρF‘α«£%‹†…Θσ`~QΐϋŠυέβ^ƒ¨"‹ΉΒsΥ&}˜qωβΌΣMKŠcΉτΪψŸA`Φ΄Μ{έ ώ΄ΒM ΠoKΐΈΖΎb"šE/f>Ÿ„ŸA ή—qπ“θτπ.?ρ―—ˆ¦‘G³cκ?ψIτϊiψψΒQ ΠsKΐΈΖΎ["Š=š ŸRΒQ ΠsJΐΈΖψJ4ϊi_ψψΧΛ€"f‚ηΥπ”xώƒΊWώΗώ4ΒSαϊι_ψψΧΚΨ£{4>©„§ΓτΏπ2?ρ£ώŸΠwJΐΘΖΎUΕ£Ω ΉυWό%> ξ•‘π”ψώƒΊWώGώ5ς¦(ΕΝΟͺα)πύt―ό όh„§ΓτΏπ2?ρ―•1F(φh.}W O‡θ;₯ΰdγGό%> ξ•‘|§Š1G³AΜ}Y O‡θ;₯ΰdγGό%> ξ•‘|©ŠLQμΠsVΒSαϊι_ψψΡ O‡θ;₯ΰdγ_)βŒQμΠsVΒSαϊι_ψψΡ O‡θ;₯ΰdγ_)βŒQμΠsVΒSαϊι_ψψΡ O‡θ;₯ΰdγ_)βŒQμΠsVΒSαϊι_ψψΡ O‡θ;₯ΰdγ_*bŒQμΠsUΒSαϊι_ψψΡ O‡θ;₯ΰdγ_)βŒQμΠ\ϊ³ώŸΠwJΐΘƏψJ|?Aέ+#ωSbf‚ηΥπ”ψώƒΊWώGώ4ΒSαϊι_ψψΧʘ₯ΕΝ1υWό%> ξ•‘π”ψώƒΊWώGώ5ς)qG³AsκŸψJƒA½/γ?α&Πθ7₯ΰ\γ_/Nf>Ÿoθ* :Φ™k€?ΦΉύoβ^ƒ§£ IώqΡ!\ϋ±γςΝxαG" ›ή*ρF£β[‘%σ…… ς N?ΔϋšΔ‚œ*Δ8S…4S…[’Š+€€’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(―Pψ'1Ÿϋc΅(’¦{ nzu%V οHh’€Hh’˜i¦Š(¦›E””Q@ €’ŠJCE)΄Q@!’Šc (’„’Š)€”QE-%PJ(’%S QE Z(¦RφQH₯’Š`%(’Š)h’€ Rh’ŠZQE΄΄Q@Ε§ ( ₯¨’€)Š(iΤQ@’Š)’E΄½¨’€N’ŠJZ( ₯νEv₯’ŠQ@Q@Q@’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(QEQEŠ( Š( °’Š(’Š(QEQEQEQE蒊(’Š(’Š;ΡEPh’€ (’€ΤQEQEQEQEQE/jCEP(’€ (’€ (’€ PEPEPEPEPEPEPEPEPEPEPEP@’Š(’Š(Q@Q@…PEP@’Š(’ŠΩ endstream endobj 189 0 obj 103635 endobj 185 0 obj << /Font << /Font2 12 0 R /Font5 28 0 R >> /Pattern << >> /XObject << /Image24 188 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 190 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 191 0 R /Resources 192 0 R /Annots 194 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 191 0 obj << /Filter /FlateDecode /Length 193 0 R >> stream xœ΅TKNά@΅³£2™A€§?UύY‚R‚)’%ΕˆΟŒβkpͺ\‚eVYδ©²ΗŸLHhpΛξξ§zΥο•\Qd|h¨‰ησ%T •Φ&ωHλ›{>$Σœ§ΰu^φ«) ,JΨΨΘw'pΓ$LχΛο‹™†ω3XyCDg˜C9’vΙΑjώ*ͺ\νΒWΥ€ΙΤLυΰ΄&D2 1€Ar’“` Fΐ+’£λc{¬£R[uϋU-m»‘½Š„&RΖ%£C« –0ρΒ³ξ:Δ DλΘ&”β ΞQ¬`zt{soψ <Š«Ώ}Mό’U‘hL+.ΰŒ³‡μgώe΅\γμG~œύ~χ˜½ΟGΩ―ό8ίΛwςQ~z:3(>ΓΗb›%!EΕFα?u'P\ Ω *>η*E—¬¬}aO-±Κ¨μ!nŸj¨λ‘A m3ιΙnέύΦτΆ•Εr‹Eqj#€/;ύ΄œΝ/-Ααm§Λ/ο“³*E„@άΊ₯M—]‡•ΜDΜΊΨ.xExƒδ­όgΡABš&Ρ!y―΄y*¬—Δχ’ΘψZ,ξ endstream endobj 193 0 obj 443 endobj 194 0 obj [ ] endobj 195 0 obj << /Subtype /Image /Interpolate true /Width 702 /Height 78 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 197 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐNΎ"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊ§²€ό•ASΩΗ~?Κ¨DQEQEQEQE:8ήRDhΞ@Ι 3Ε6Ί}ώ%~Τ5Δχg쐞ψώ"?Οjζ(Β71™1ŒΗύi΅Σψ‡ώ%žΣ4‘Δ²΅Ξ=ΟέόφΜPE*©f :“Šν/†…€jqι7p•Užι€!`@™Οΐβ¨­§‹­iμ΄Η«HD,N7£τ«“xWU†K‡qάθQκE 0諚V™wͺNb²‹{(άЏRMK«h·ΊRΖχQ―•'ά‘2ŸΔPu«₯hϊœ{xΡ`o™#…ϊ υ¨.τ«»MI,nbς$`δΰτΕQ’»|?φ/·ω§{†˜γΎ+˜—OΉMD؈χάξΩ΅μŸcL ΄VΥ†u;+WΈ–dύ`Ž@Ε> V- (­}?ΓΊύ¬W6ρ§‘!#{8P0qΞh"ŠΉ«i—ZUΟ‘{Η#p δ0υ΄ π­5²J°(.»’6aκ  :*h-gžνmb‰šα›`9τ­™ό%«B$-ecBξV@Bγ’½`QZZ—s¨ΞZΥ!$«2ΚαAη§=zTή,YWZ”Oi€W1BA^x  z+WJΠ/΅;vΈ#Xmσ%p ŸAšŠχHΌ²Τ"²ΉŒ$,6ΆNΟLP}ΨΛΰι°ΰ(‘}ΏΝ;ΨΜ6”Ηρ\βiWO«fͺ‘Ίέ·†3Œυ¦+ro κ°ΪIpπ.#‚κ=H¬ψt뉴Ωο£UkxX,‡w+œcNiNŠ·q.=ςͺύš Μ[žΐwλU(’4’*F₯ˆUP2I=«°τ3e’5έζ‹=νλΟε¬ Ήv&3»ޘm‘o-Ζ²πA`Φ²»[Q’Tΰzώ[ΏπΎ©cjχB†8ω“c†)υ”Uύ+HΌΥDίaŒHb°άδΰu©΅]K·IξcC ‘γpΐCŠΚ’ŠTu¦h(ίX}Γ^m6M,’™V 7sΖ°υ] αρ<šU‰σ aεξ8ΰμL J+ro κ°ΪIpπ.#‚κ=HͺV—wͺάl’ήΚ71'GΉ4€₯Eijϊ%φ’±΅ά`G'έ‘2“ι‘V`πΎ§=²OQ²Ι•Μ™O   J*φ«₯]imΊ ‰Wr28e#κ*τΥ¦ΆIVΧrFμ=@4‡E]Σ΄»Bνν UYΛ#Ζ^όΧG―ψFh¦FΣ%„B¬α¦έΞq“L>ŠθΌ9₯.§’κώ\[Δ1Nq·,sνΣΦ¨jΪφ•Rέ"dαdƒ)>™€Μ’΅t½S§·vω’8PO ΟZ©as§ή[ΈŒs p{ηΈ=ΕU’―]iwVΊ¨Σ₯UE• ‘–Ζ9όE2M>ε5#aεξΊεμSœ·Φ€*Q[·~Υ-­ε™£‰ΔCt‹™GΈ¬*(’ΆΰπΎ§=²OQ²Ι•Μ™O   J*φ«₯]imΊ ‰Wr28e#κ*τΥ¦ΆIVΧrFμ=@4‡E]Σ΄»Bνν UYΛ#Ζ^όΧG―ψFh¦FΣ%„B¬α¦έΞq“L>ŠΏ₯iš¨›μ1‰ @€<œ΅6« _ιvι=Μhas΄•¬ςή-ͺDΖΰΏ–#Ζμγ »wα]RΪήYš8œD7H±Θ”{ŠΒ Š( Š( Š( §²€ό•ASΩΗ~?Κ€ ’Š(’Š(’Š(§EK"G,ξB¨Ι¦Υύ ς?U‚ξβ&™";‚)ΖOoΘσ@ή4‘mžΛH„ƒŒ@>;Θά“όΏ3T<-`5-rΪ‰O™&zm^N~½?Ο½Ή{ΛΙ%9’W.Wτ}U4ΫE&7W1ωI&p‹σώ”ΐΔZΤυ›«¬επŸξŽθ+:Š)θHYPž5ΤxΞΒβοΖRE d΅Ο—εžΗε9τβΉZΪ·ρF±ohΆΡ^°FΥΚ© zFicΒφ―eγK[iŠ™"‘•ΆœŒ…5V=ZηLΧ―n‘Ψς;Ȍ$†σœYφ—·—«w…n–@c“ΤσΧ­C#΄’3ΉΛ±,O©4ΥψHΓξ»ηG,«ˆΛ€M‡+“Πώu ύε»xU­μl.γ΄7ΔΣ8e Ž@8τ¬-7PΊΣn<λš1‚F#ά Mͺλ7ϊΑ}9‘Sξ¨P ~€6€Ά²±Π4ΖΥώιnI1H8>όΡγΐ?βNU$Aφ5ΒΘrΐvή²¬ςήmHYiš‹ΞΠΊN@ΐΤ·ΖΦ½χ‰5kλVΆΉ»-pΐ"©o©²(—Pv΄άHHυΑ?γ\ΥY’ϊβKlήLΫDΕ‘6Ž λΟZ@X»Υ%Ύ‹O‚θGεΪ Šΐ•γ―>ΥΨx‚{(<[½•τΧ ΖИ€[c?ϊυηΥ³mβ}bήΥmβΌa«•RTzFi­ ά,Ÿόιb6ν$’~νϊ«<|Տ iڍΖΉ%μRΖ†ΦUfp@vλ‘λίσ2&έr$¬™pZNIςk°]VΒΖήξ_ν«­RβKv‚4xέBξΗ?7ΠP=5|AώiΞ6'ώ‚+3JΦ΅ %d]>γΚ[δVΞ:u¬^ψŸW½΅’ήζο|2 2ωH2> Pλ+ΨWΓΦֺޝrφFh.!lδδsΑοU|W`,€²hngšΪxCΔ'?4kύΪ­¦xƒRΣ 0Ωά•‡9ΨΚν‘ΕUΤu ­JγΟ½™₯—Ιΐΐτp(nιYΌdTρ³ΣƒUΌ#M‡ϋΝ š©₯뚎—%…ΣDŒrWhaŸ\j$ΤξΣSώΠY±yΈΏ™΄u>ΨΗι@#ΥtΝzφκ#ΌˆΒ@H`O9ΑgΑW ύ‘6ŸrΡ―γ0·³ ώŸ`Hν$ŒξrμKκM]КΩ5‹I/eς­γ;Ά ιΞ8η’1@>(C€ι~ŠσFn.1ݏ~?₯rυ^Ώ:ž―uvsΆGωsΩGτ¨RQΩ]«©Θ`pAυΆmFψx ΕεϜoŠ™<ΦάFΓΖsœW#VZϊα΄υ±2’¬žhM£οcΟ^”Ήΰiž[Is#I+ωέ‰$μ=Ο΅OαΉMCY7AΒ‹YDεΊnχχλ\΄2Ι©,.Ι"ΚΚpA­KjΧφ¦ήζρšχ”*ο©š`^π³²h~"*H?gQŸEdCͺO‘q¦€†ήgƒΉHΗN}…Ek}qkΔ0IΆ;… (Ϊΰ>½? ­@,λκ)(ΤRΌρ^Ήβ)Υ4Λ)n#ΨVyT–ΞΠGεXΎ»šϋΖ–—7/Ύi$bΗώkP½ΈΤ.ήζςO2gΖζΪp08RY]ΝcuΝ«μš3•lŽ1ΠΣF=ZηLΧ―n‘Ψς;Ȍ$†σœWό<$ ψmΑ3Bυ+“ŸΣ5ΝHν$ŒξrμKκMXΣu½2γΞ±™‘“$`‚=<έE‘~Λη―‹wϋΌγυύkfΨ‘}‘ΰΜ%Ώτ\v«¬_κ₯ ύΓJξψ XΏWΦ|4#;εLc?^΄««m„gΓ%ώξgΟΣx­ίOe‹cw²ΎšτΪ€+` `c§^Έiοn'΄ΆΆ–MΠ[ξς—mάryκyυ­oλφ«oγΤm\ͺ’£Π3@uωLϊΥδ­ @Ο!&6κ§Έ5­γ΅oν6Ϊv›8πqΑλ\Ϋ1v,Δ³’ORkZjΠΩ}‘/μϋ6mdVωqŒdŒΠο»'„όDPqό J!bί§ rψmΟo”VΧZ\ZΕ&Ψ.6ω«΄Ψ9υ… }pΊ{X‰1jy₯6Ž[ΞzΠWpφ ΰνήΫάM2άΈP­»ΎGΧυ¬ί]ύ’m4΅€φΛ ͺg9g@x5Ÿ₯뺎—GerR69(T0Οͺ·χ·χ-qy+K3ucώx ·^Ά™ώ"ۍŠΙ,.€ €Ή?‘ͺψςβ{MΔιpεcΕ€A–j•Ώ‰υ‹{Amλ•vUKθ3Yp\Νor·Κι:Άΰΰσšλ ΆΣυ‰5Σ…ώ¨,o$Š_(}Tž½kŒ­«ΟkvΟΧgΛq‡ Š₯‡Ή±h―@Ά$_hx?σ oύןΥυΦ/ΥΰuŸ FΞΕωSΗOΧ­jκΫαπΙ»™στή+wΔΩAβΨέμ―¦½6„Ε ΨιΧ{Ϋ‰ν-­₯“tϋΌ₯ΐwžzž}kFΫΔϊΕ½ͺΫΕxΒ5W*€¨τŒΠ]~S>΅y+BΠ3ΘIΊ©ξ kxν[ϋFΝΆ¦Ξ<pzΧ6Μ]‹1,Δδ“ΤšΦ‡Δš΄6_dKΖϋ>Ν›YΎ\c#4{ΒΞΙ‘ψˆ© ύF~Ή‘©ύ«"@ϋ/šsŸLΦ…—‰΅{Xν­nφCΒ―–‡ϊ‘šƒUΦυ U#[ϋ5c$¨Ψ«‚~€Pο‹£ΏoƒhΞcΆ#θ:vΖsYΆ’κVή,˜ΎΣ©G+pwέ=³M·ρF±ojΆρ^°FΥΚ© zFk.™αΊ[˜₯u[psλ@lΪ~±& ΪpΏΣ΅δ‘Kεͺ“Χ­qπΔσJ‘D₯δrTI=«^σΕΕέ³Α5ΩςάaΒ’©aξ@¬›iδΆΈŽx€±°ea؊uν€φW άM«ΥZ‘«:ύΞ₯tΧ7’y“0œΐφZQ@Q@OeIψ*‚§²€ό•AEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE&O ΝεΏ’a}§nμgυΕ2Š{Ε"F’σα―‰-4Ιοd΅‰–/$I(i}vnqΧΪ°ό7αέOΔ—­m€Ϋω‹ΎFf ˆ=I< ֏ΔχώρΆ³¨YωRΝ,ΣΕ"Ξ ++9Ξ@#ΠWIπΌΪψΌ\ΫΟpΈ„Ν³•£Ιθ}>φ}³@w‰ό#«xm!—Q… ΄ΗΟ ‡¦GCυ«>π.Ήβ 5ομ!‰mClWšP‚Fτ\υηJθ5½NΖO†’ΩθΪ.§˜Χ‹"\έH‹'p§ιιοVu}3PΦώxMtKyn£‚I–x BΜΉΑ ΐΉj˜?‰<7©xnKXυh–)."σU@τ>†±«Ύ4EqπΌ7­Ύκ=5VΞrγƒϊζΌΦokώΥt-2ΒQ‰ήυAŒ«†## Ψβ°k[W·Χ"Σ¬V[ρdΙώ‰φ‚Ϋ6γψ3ΐΗNΨ tΝTΥRGΣ4λ»΅Œ€ζYΒ“λRjΦtλcq¨iWΦΠ’hΣ’+kΐκ­ou»Ζψ{ζ_έ‘“χΌ~V?­]ρr¨Ρ\Ο­λώ†ζ\7=~f#Šα)T`£©8€§ΑώΎ?χ‡σ Π|0ρ7›,fΪά:”Τ8ευλΧ₯s:n‹{¨ki€ΑΫζvΛνΓ(9Σ‘―JρΌ:ƒ|hΪ$”ζKs €ί†wfͺΨ•?Ϋf1φΉ:zωmŸΦΉcV\·}9wποΔVΊlΧ’ZΖV/$K*΄Š½rT{sŽΎΥαΟκ^"Όkm*ίΝt]ΞΕ‚ͺRMiΕβKνΖ:Ά‘iεK4²Ν‚`YX3œδ=lx%f“αό£±έ‘B}γγ»τέVε8ΖοΛρρ/„υo$2jP'‘1ΔsDαя¦Gz½iπϋ_»°Šξή&€\D‚eήθ}ΤqωΦ€I4n~ΦQ΅56Αϋ£;}Ύχλ]VšHΥ<'‚δ]ύΤJ¬ϋ<·Δ~Ώπτ–λ¨,En̊H€¬;ς=+^Σα׈ξ¬cΉKHΤȞdpI2¬Ύ‘Iώx«~#)7€ŒΨ1ζλv}<ΥΝv>1»­~#A$ΊN―uͺ©‰νšή`ΐW3YΩ%ΎΏƒΚ΄?ίλZœΦ‰]D¬Ξ³Έnsί'₯w1ψkq ΤRh‘[ΗjΆͺ‰.FLœξ#'§JβόipnόWͺNφ―hςNΜΠ>7!ξ;ζΊ?Œ1ΉΧtΙ1FΣaΓcƒχ»ΥIΝΚ6vΈψΓ©―xSΔ~Mšάjq˜Ω‰ΑMΜwsœ$Φ/‰|#«xv'Τ"ŒΫLp“C t'Σ#½oψ.G‹αǍZ6*ΕmΧ#Π±~DΣm]€ψ/zK,z²„ψ~E<~gσ£šJo΅όΎπn±―Z5έ”1₯’ΆΑ4ςΥ›Πg­fλ5ώ©?R·h.†0€‚=#‚=λΡnεΡγψcαfΥl―n­˜’Κ$›Ξwdu<γρ¬?ˆzΪξτϊmε„vφȈnΘ/$`ό§ΖˆT”₯ε―ΰ;¨xzώΓΔI’\€bύή8Β‡rψΫΟβ*)τKψ΅ζΡΌŸ3Pω>Zrή™ιψΧ‘ψΒΒζo–.Ι,φ³#ΑEΩΈηΠm5‘{yymρ†ςλGΆ7ΧQ^HVώ<~[¨VτΈu/‡^ °²žεβ·™mΧ|© κξ€u$…qυκ––:/‰§Φ[D]cCΦ£†IηF˜›Ÿ™υδϊγιΪΌΒΪkΛ¨­­cig•‚"(Ιf<*ιMΚκ[zή±Έψcko¦¨Χ ΰœΘŠε[ςΒΈ_K½ΡοžΟS·{{””~Έ=½z.—~–_ΕΖ ­]ZΜBŽκ9φΞαEVΥ¬\-­ΞSΖΆZ‡žΦξ,YHΟΞΗ©4ΆΎΧlα-£S"οHžUY}B“όλcβ]šιΧ>³˜†K{U‰‰ξ±ŸΘVߊ΄ΫoE$šn§q©[΄€―€0c§\ώ5 r²·˜ωUέΟ4²//>ά"Œ²‰¦™νeU8<γ jeτ₯&u0ZΫη0}8"ΊM ΰήόDΥ‘{wΆmF+ˆκ€H>ωZκΰ*%g8ΫαΦ`?Ω_²‘)§*­?λϊά8Ÿ YΨ[θ^"½Ττψ―₯°h•QœΛ<σΕ.«c€κήŸ\μMžΦuŠX„…ΡΑΗ#=ω*ή /ψ’κKxn‚yΕ:ξGΛΘόsSψςφKΟhΧ:\pΫhσρ5Ό$γ<v돦})]σό@Σ”ζt? κΊΥ«\ΪE[ΩζΝ EfτλYΪΎ—y€_=¦£ C:ŒΰςμA]έԚZ|=πγjV—wΐΚ?Ρ€χ½‘Χ?ΗρΥπΊΈΡŒš}՜pΫ*/ΪH/$`π\g'/!8€ˆaπΏ-¬-΄cΞΑXΪUœώ’š%γλΝ€½ѐΞδO=;W’λΊV«sρFΓP΅ŠW±- ₯ŒƱ€7 έ9ωΈχǟjΰ Ÿ΄?σ₯ Ή=ϊ’‘©γ+έ;A-―tΫ qe[›w ‘Χv?ΞkAΡ/΅Ϋ¦·Σ’Θ»έ™‚ͺRMtς·ό+ §>eΗoϊhjΏ‚oζ±ΆΥ„šd·ϊ\Ρ*^ΙSσƒ‘ψΣM¨;oW(λΎΤτKhξnγνΆ‰‘:ηΠγ₯t^π,·Ί=νΝδp³Kj$³"|mr27xνΦ«kzfŸ/„« άjΩ-ΐŽK;¦ωwcο.8=½Jg€UŸGρR ,ηO8dž΅.Rp½Ζ’LΑΧ΄+έ XRΚέ(,Ύ\ϊ}+f?‡ΪϋΉ_"8Κξ™Fώ3…υL‚:‚>΅ά|L»šΫΖsΔη}½Ό/{Οσ«nWI2R[œή j†«>› !oa Z))ωzκj-H»Φo₯’)”#;om‘Tu$ž•z?ܟΗ―J‘€ώj»€@… € “ΤgΏzνόEi†΄½T΄u'YeŠΠ©ιΞG·'ς₯9-;E=Nΐϊ*xƒΕš~—+Ši˜ΛΧj©cΐΤψ‰βy5KΧl£ŠΧC°”₯΅ΌhΚεw“άž?Ɵπre‡β6’\ΰ7˜€ϋ˜ΨΦΉzΪK=nώήe+$SΊ0#Φ€Γ]wνSΓαMf8ξt[ζh‘YFθdnŒ­Χ9ώuΗλϊsiεώžνΈΫNρnώπώ"΄ώΪIyγ8A,·qΚp3…F @iΏgKλ’Dr†ξEΧ€9ϊ(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ žΛώ>“ρώUOeIψ*‚Š( Š( Š( i•ޏ¨Γ§KδέΒIφ†ΖA‚θMS’€$ΉšK›‰g™·K+vΖ2IΙ'Υυ­:ΚΗR»3[YŒD₯TcŒH'sXΤPEPNˆ…• θ&›EzWŒ>#κ+β+ζπΞ¨ίΩ³*m&ΑΨ½r9Αiϊ­ξŸͺ¦₯ipΛ|Œ\Lΐ9άs’wSΦ©QQ Q‚²@>βgΈžI¦mHΕΨγ$δΥν [ΤtΓu€έ=΄Δm%@!‡‘ ώ5ESI«06|Eβ}cΔMφ½λN±ςˆ"―Ύ>τ±ψ£XŽ[Iσilm!>R|±‚½9γΉζ±h₯ΙZΐ]»Υo/4λ‰·ΪΩoι΅FΝη-Θ9#ΎkrΗΗώ&²°[857’μBΡ£2@ΔfΉj(p‹Ρ #Ό²4’3;±,ΜΗ$“Τšθν|uβKm,iΠκoφ1ˆ#DŒBcΙRz{Χ5E7Λtλ=^ϊΟM½Σν§Ωi{·ΟbϋNG$dsιŠV½MM%'Ɵ$Βv‹bςψ9ΖzΖqTh£•v{Γή.Φό? Γ₯ޘΰsΈΔΘΉυΗαYΪΖ«{¬ί½ζ§pχ..Ψ€ΐΒ©QIF)έ-@κlόβk=5l`Υ@‹± EgUτ FkŸ³ΎΊ³ΏŽφΦy#»Fή²ƒσnυΝV’…­V₯ρΔΊŒ–—:‰ςe]²l‰Έτ$kΣο.4λθ/,₯1\ΐαγqΞ:uͺτSŒc…X ZΏΧυ'ΎΥgσXέ΄(t*+NξκΖΞΞy·[Ωξςh7ž@ΙδwͺtS°:Φ·¨krΕ&©pgx—bŠΈ€­+?x‚Ιm`ΤD‹΅ "³(τ Fkœ’§’-ZΓ»-XκV:Š_[LΛvŒ\H@c“Τœη={Υ΅ρ¨£RμγQ―‘yΧێ§¦+*Šn)ŠμΉk©έΪιχvPM²Φοoœ›Aί΄δrFGαN‹WΎ‹H—KIΠ%q#DQOΜ1Θ$dt Q’‹ Ή³‘ψŸWΡ"h΄λ³,wΩUΧ>Έ γπͺ:¦£wͺή=ή‘;O;pY½=τͺ”QΚ“½‡w±ήψrϋK΄ΆΣ₯Ώρ]ώΘ&m=a¨e9 ž˜ΘϊW=sβ+€ρMή³₯ΉΆšY]•V*­Ψ‚ιXtTͺi6ΗΜΞ«ώ‰θ'’ρρ5‘€kΪ–‘y-֟tΠΝ/ϊΒ!ωΟ ŒVeΤ"΄°Ή™³x›VΧ"H΅+³$(w,jŠŠόjž‘ͺίhχiΣn ±΄²€r=<₯E>T•¬{šZζΉ¨λ“G.©qηΙνS±W9ώ*WS»Υ…Ζ‘70@›Ά…ΰtU:(QKa]€λι]OŽ5{[Υτύ.všΒΒΩcW*Λ½ρσaϊΧ-E7iŽϊX’Φβ[[˜-άΗ4Nz«k¨ρ‡Šm> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐtΦ"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ωϊŠ(ͺQEQE=οό}?αόͺ žχώ>ŸπώUQEQEQSΨZΛ}}oinšy$ΰncϊš‚ŠξαˆΥ”4v` NΖεqν»Σ³uφ‡„mVςΥ0ΉΟπBŒ”›θΐτOΓ¨7ƍ-’INd·08Ψέψgvkˆψ’TψοZٌ} τυΐΟλ]7Œ>#κ+β+ζπΞ¨ίΩ³*m&ΑΨ½r9ζςΘσJςΚμς;fc’Δυ&³‘ $œ»‘©hzž™giwe,ΧkΊpγώG½t^žK_xšβΆX₯΄‘‘δV&³βm_YΣ¬¬u+³5΅šν…J¨Η䁒qΖMQ·Τν΄λ»eΫktTΜ›Aέ΄εyΖG>•΄γΜ¬4μzgγ…ό u¨ZΰC©]Cvώd‡ζ§σ¬ϋ©4΄ψ{αΖΤ­.ξ-”£H+ξ?{#―\~5ΔΙj2h±ι/rNŸoXŠ/$υΖz“ή¬h~'ΥτHš-:μΗ Ζ6UuΟ8ό+%I₯o2ωΥΝΟjΗϋWΓΧ&ΒκΙlβŒΖnH/"+¦»mVΔ}¦χDLΔΤ]έΰwlΖTγ­^?ͺj7z­γέκ΄σ·›ΣΠΐJΎή)Φ[S΅Ττ›»Xό¨€ςΣε\Œc©κ(t•Ίš6΅Θ/u―‰ρθς»ŠB";φcΛP8>Ώ-khΧ³x½o΄ίiρ™­νΩΦψEεΙ(ώ#ύ8ιΣΣΟ’ώι5|“Ί]ω†_5NβrO³©xΣ_Τ¬šκύŒ0α#T.= n›Ρ!)#oΐ&ΨxGΔh†i—™cΆΘΙ“ΠϊuΟΆj WP΅½™₯_Ε`n„‹qpα”>0@8τώ΅Λθϊ΅φuφ6εΰ”€ŒG‘ƒV5ίjšο–5;£*GΚ PͺΣφošαΝ₯έYΨ|-ΠΠ1Χr’=H-ζkUΧ.υ;-6ΪδFΒ3N †#ΌsΫ¦*ΌΪάΪ]Ύ$Ϋ¬ΰrρΗ΄|€υ9ΖO_Z§UΫr[=zΦΦcRΠόY6>Ο ›Λv{ bγ?\œΐk˜ψ{zoώ$Eyu6všAžΜUŽαšζν΅νNΫG›J‚ι’ΒbKΕ΅NsŒσŒŽƒ‘ͺσΛmηXv‰«ItΠIΠ’UePz–γΧϊΥ έΛaΰ^ξ܁4Άς&zd0<ϋV>₯γ-wR±k;»βΠ8Γ…TΈχ Ypκwpι—|sm³•δh;ˆθsŒΐΠ©»kδΗku«άλžρύΰe{¨l`…P€$“TΌEΝπσΒΔ₯㍧ΘΓΰ~†Ήx΅;Έ΄ΉτθζŜξ$’=£ζaΠηύjφ‡β_C…αΣo pΉάceW\ϊ€AΑϊSφmmίτdχ6~##Amα«yFΩ’Σc‡ͺŸΘΧeαρu†,¬ξ% ΕΎΉ{ΛΙξe?<\ώ&ΊβUΰ¨γιq©Ι½½|₯ιϊγσj(ΪY8Αgr@ξM0:]ώ%~Τ5Δχg쐞ψώ"?Οjζ+₯ρ€‹lφZD$μbρήFδŸεωšζ¨¦Ϊ=;Hπύ•νεŠί\ή³α]Κͺ*œ‡η\΅tΪάo/ƒό?$jYΞF#±-ΐύ gx‰4ί΄C6’ΨŠhΓΌ9'Κnλ“WΑϊ»6<˜ΖWtͺ7qž+/SΣ.4Ρoφ ͺΣΖ%U―‘­Ο\Kˆν₯Fωα†&Ob9ώtΞ‹;“{φ1 ›ϋ<Όs»΄οό3©ΩZ½Δ°£$λr)υ΄Ό+~Ϊ—Ž"»ΉXΦYC gag>•6Ÿyio6€,΄ΝEηh]' `κ[Šζ΄­2οTœΕeφQΉ‰ €š›WΠοt€ŽK€S œ,‘°e'Σ"΄<;iΡu+λΉξΕ’ΰΆm¦L{۟ηW―³ψ Ν”AφΐTLΫ‰8δŽ:υθ= Β²]iΧSά$l^ά=±†<Œϊ~5ƒ«iW:SΖ—~^\68oεZήRΪvΎͺ cfp^υΞΔ•<ΑςξΟ₯lΑα]Zkd•`P]w$m ΓΤXŽŒŽΘκUΤΰ‚0Aτ―@ρφPxΆ7{+ι―A‘1HΆΖ:υλΧε3λW’΄-<„˜ΫͺžΰΠ ά,νζπζ·q,a¦€Eε±κΉb aΧWα;§²πξ½qΖΞIEά§ζ#‘@"³€ψ2kΓϋHΌ‰;νΪ+SΒ²izŒιg>τ„³Kζ6\¨λz/υu?K4ρŒ·‘‰6Œm§γTό!Χ―y?•PΎΤl&Ά{}*+t‰χH‹!"Q‘Ατθ:ίΆŸH›@ΌΤN‡h$TΩζ·9Η9.ΊM;ώD][ώΎ#ώb€ΓΡΩjώ-…Ι"΄7ξχλΤf―i)€kχriγKs•cΡJΝ‚=A¬ΘΥgτύΣ€ρ;@³.§ΩΩΚΰ£Mψφ=¨a΅ˆ=AΕ%R«„yοό=€Mak4žižV}£οarOτSΣξtΛΆΆ½Λ” υΘ#ΤΪΦέ‡ƒ|>€€ΜHχ Ησ5'Š—Γͺ[χ’ΩΖ»›Τϊώtΐ©oα=Z{u•aE.»’7+°ϊVm†›s{¨‹S$°Ψηn*λΪ; _ΪΪΚ5KΝB9#{Κ1žLghΟσ¨τ±‰γώzΛ ΒΉπΖ©mbχRΐ»#uWz‘Tτ&οV’²Œ1QΉ˜œ*s[~•δΤ΅μ[Μ³™Ÿ=ΞGψšo‡Γ·„Ό@Άΰ™u½vδητΝΪΣΌ+4·(»aREmΐ‘QЎ1œΤΪSišž›©(b†kk7•e1%€λΦ’ *ό;o40Sz yώξήߎiž Rπkˆ€³΅„€(κhš­Θ<+«Ml’¬ 䍀Ψz€k0TσpΞ}+ΎρφPxΆ7{+ι―A‘1HΆΖ:υ臲±ΈΌΏK8S ΕB·Λ‚:ƒωVœήΥa΄’αΰ\F7:Τz‘Wτ‰LV… gΙΊ©Ϊr fG«\ιšυνΤ;Gy„€ΐžs‚(Š(€Oα]ηyξ―μ'–ή;v–$ΑQ3vΥΣofώχ·ο:zϊZΣπυΩ²ΦTέNV10αιψW;%εΕΤΠ›Ϋ‰§Uoωjε°3ΟZ`jAα=^ke™-Τo]ʌΰ;₯eΩX\^_₯”)‹†b»Xγuς³^ŽνΎ"[΄aΘ2Bc#¦Μ ώz’΄*~&6ΜcνΣΧiΟλ@SxWU†K‡qάθQκEaΦΔz΅Ξ™―^έC±δw‘H η8"±ιWX›¦ψoIΉŸKŠξ[Ÿ3{4Œ§εlvϊΧ']œΊ„6ΠΜΦχ›όμyΓ;pύ©™β>Ξ];PΣ£x`ΌF&lμ# νΝ*x?WfΗ“8Κξ•Fξ3ΕgλZ½Ζ­,M2ΗQ.Θ’‰p¨=…lxββX|Gm*7Ο 12{Οσ xY\›ο±ˆ\έoΩεγή•§α}RΖΥξ&… qσ&Η SκhψRύ΅/Ewr±€²†8A„qŸaG„ε5 dέ -e–ι»ίί­cιzξ§ng΅Xό‘'–Yά.ου·ώΤ,,Ϊζζ$TGΨΰ8,§Ά@υ­-0γΑ͏ϊ 'ώ‚+OXζΫΖ9žΆϊsZ^©ΐΣΫΖ‹;|Ι('Πg­WΉξνu±Έ‹ΛΈf ƒ“€sΣυΣά=‚ψ;E7ΆχB ƒχ.+nο‘υύk/ΕΧFε΄πlηΆΫ„O<ε{Ρ—ΑΣaΐQ"ϋšw±˜m)Ž;β³ό5₯£x²-?Q$QΌ:†Θ$!#‘R]+7€lŠ‚Bή6p:pj?ΘΧgτύΠ7žΤνν%ΊxˏζuWz‘Ϊ¨iZeή©9ŠΚ-μ£s@ =I5»ΰι^MKXήΕΌΛ9™σά䉩<$a„w]σ£–UΔe&Γ•Ιθ:ΓΥ΄[έ)c{¨ΧΚ“ξHŒOβ* › νμ­nεP!ΉέεrNΣƒΕnίή[·…ZήΖΒξ;CpM3†PΨδJMf6“ΑΊ‘©dC21‰nθhϊΒ{(νžα@[ˆΔ±ΰη*kRίΒz¬πG*Η™r#Κ0ϊTώ3FŠΩRΕ)κ?Ξ+Jiν5=N fΚώΗV!#YanΒΨ=9τ .x€‚gŠd)"1VSΤL«Ίέ³ΩκΧVςΚfxδ ΘO-ξj• 54½ χS·3Ϊ¬~P“Λ,ξ ŒχϊŠ[κmss*#μpSΫ zΦ–˜qΰζΗύ“A§¬smγΟ[ύ ˜Φ— _κp4φρ’ΐί2G τλUξt»»]Eln"ςξ‚€Δ`δΰτΗ½tχ`ΎΡMν½ΔΠƒ ύΛ… Ϋ»δ}ZΛρuΡΉm<9ν„vαΟ9g^Ζ€4eπtΨpHΎίζμfJcŽψq4«§ΥΏ³UPέnΫ€ΓΖzΦ½³xΘ¨$-γg§«x+ώF›χ›A4Mα]VI.Δcs p]G©WCξuΛZ€/δ•fY\(<τη―Jš=ZηLΧ―n‘Ψς;Ȍ$†σœXΰΠ@,YWZ”Oi€W1BA^x¦ι>Τ5H{hΡ`o™#…ϊZ½ρψI§88؟ϊ§λk#x7@0‚`Pψι»wΗ¨ SΣξtΛ£o{ŽP3ŒδκzΤ·πž«<Κ±Δ¦E܈ς€Μ>•[\MMΕuRIςG’2ΆqΟη]ΣΪjz€Ν•ύެBF²Βέ…°zsι@\ρIΟΘRDb¬§¨"™Wu»g³Υ­ε”ΜρΘAž[άΤwVV°A5ΜS Ρ³R΅Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ήΗΣώΚ ©ογιεPPEPEPJΈά7gnyΕ%«β-Uu[Θή(Μ6πΔ±E9ΪC‘^C§κ°]άDΣ$GpE8Ινωj…5νΛή^Mq)Μ’Ήsψš†Š(­=+]Τt¨Ϊ;’‘±ΙB‘†}yVebώφβώε/%ifn¬ίηŠ]BϊγPœMy'™ PΉΪ§J­E>^RX]’D9VS‚ j_x“VΎ΅kk›²Ρ7 *–ϊ+"н₯jΧΊS»XΞcή0κ@`ίPjKύwRΏ·h.ξL³*U@Θΰc ¬Ϊ(֝¨]i·}”Ν ΈΖFG‘ƒOΥu[ΝVT’ώo5Ρv©Ϊ«ψT¨  ›oλφ«oγΤm\ͺ’£Π3XμΕΨ³ΜNI=I€’€ ³υΕ½₯Ν¬Rm‚γoš»Aέƒ‘ΟQψUj(ΘΎΈ{X‰?ΡZO4¦Ρχ±Œη―J,/4ωΜΦ’yr+ πzυͺΤPVcΎΈŽΖ[4“°gM£’:sΦ«Q@4ϋۍ>ν.lδςηLνm γ#ƒΗzI$“ΤΡEQEYžϊβ{;{YdέΎο)v·''ž§ρ’ξϊζν-ΦβMΒέqpΥZŠΫ>*ΦLhŸmo—m‹ΈγΤγ&¨ΕͺήΕͺF9±xIc&ΥκFΗJ₯EY²ΏΉ²’Y-dΨς‘ΞΠr§¨ζŸ₯κwz\ζkŒNF‚=Αβ©Ρ@Z†»©j<7—&H™Γ•*£01ΗͺΨ^άιχ"{9š)@ΖεττχͺτP†«­j²ΖΊ…Ηš#$―Θ«Œυθ₯YΆρ>±ojΆρ^0FΥΚ©*=#5EX΄ΌΈ΄ΌKΈ$+p€°rž§Ÿ­C#΄’3ΉΛ±,O©4Ϊ(’Š(͝υŚNΆlYγ1H6ƒΉOQΟJ­E³‰υˆ-΄W"Q΄eT=#5iyqix—VςΈRX9ŽO^ΏZ―E:Gi$gs—bXŸRi΄Q@Yžϊβ{;{YdέΎο)v·''ž§ρͺΤPVu λBq5δždBηh*΅ψe’ RX]’D;•”ΰƒZ—ώ$Υ―νM½Νγ4'ο(U]ίR5‘EYŠώζ+3h’bάΘ&Ϋ΄}ρΐ9ΖjY΅kΩ–ρdŸpΌ*Σό‹σ•9Έό*₯₯뺎—GerR69(T0Οͺ·χ·χ-qy+K3ucώxͺτPŽ—j:\l–M1Ι]‘†}pA¨βΥobΥ£ΨΌ$±“jυ#ŒcΏ₯R’€,Ω_άΩI,–²lyPΖηh9SΤsK¦κZmǝc3C&0HΑ{ƒΑͺ΄P†«¬ίκ»τζEOΊ‘Bψ ~•κ:TmΙŽ69(T0Ο―#ŠΜ’€'Ύ»ΈΎΉ{‹ΉZY›«5jΓβ½j$½;Tm‘Y€ϊ‘šΓ’€,4―$¬^G%™‰Ι$χ¦ΡEYŠώζ+3h’bάΘ&Ϋ΄}ρΐ9ΖjY΅kΩ–ρdŸpΌ*Σό‹σ•9Έό*₯₯뺎—GerR69(T0Οͺ·χ·χ-qy+K3ucώxͺτPŽ—j:\l–M1Ι]‘†}pA¨“S»MOϋAfΕζβώfΡΤϋc₯S’€#΄’3ΉΛ±,O©5JΦ΅ %d]>γΚ[δVΞ:u³¨  ›ίκχΆ²[άέο†A†_)GΤ ‡JΧ΅-*6ŽΚδ€lrP¨aŸ^G™EXΏ½ΈΤ.ZβςV–Vΰ±ώC΅!ρ^΅ ^ͺ6‚Θ¬ΐ}HΝaΡ@–GšW’V/#’ΜΔδ’{ΥΛνVφϊΪήήκs$6γΗnέ£EQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEO{Oψ*‚§½§ό?•A@Q@Q@Tφ²ί_[Ϊ[€fžE‰8˜ΰ~¦€ ’»†ψ_β5e ˜C±Ή\F{nτΟϊZδυ6λGΤξ4ϋψό»˜c¨9τΖ S’Šιό?§Ϊάψ?Δ—sΒ―ql ς\η)Ήˆ8₯'Κ4sWOŸjίnu ›ΕΤ"^r`8όΝUΠΌ)ͺλVΝsiilh–i+Až΄ΉΦ­‡+0¨«ϊΎ‘{£κΛP„Ε? ‚„ΤVό+Οy’!·„:ύΥ3(2pΛλΦ‡8­[VΞFŠ΅o§έάjKa ׌ζ?+;‡P}+ΉΠ|seq¨ΆΉk °%Œ¬Œ’ (ΪFpr3D¦£Έ(ΆyεΧxλJžςΛKΏΡ Ί’yΆ–•ŸAιX>"‚;ojp@!ŠκTEC ZΪΑm.gΡ[Ί…u]jΥm"-ƒlσf"³z υ¬ν_KΌ/žΣQ…‘Fpyv ަ€›΅ΒΟr’+;@Y˜ΰ2I₯’7ŠFŽUd‘ VV Ž Šτ}XόπϊΫEšΦ©3Cm,Š[Ζ€‚@=Ι_Τ~<Ο…΄ηρ&Ώ3ήΚpw\\ΚHΙ<π $Niˆη(―l·΄ŽΧϋ.τm!mηcφ$‘;ˆΛapΔε$gΠW-βΏˆ`[ΛX#†A?Ω緊Pκηk/$¨8?)θiΨ<’Άnm¦ΆΈh'’e8*G4«§}O·Ώ€ ’hχΖάeKθi=Ω‹EwzΖ•¦ΓaβΧ†ΥK;ˆR ύΨ,Ÿ­p•1—0£.aβ) FQ˜Α}§ϊf™]ŠβQαmD_–iGΫnG}ΝΒƒτ€ͺώΦ.-#Έ†e„O‰Ws©τ”ΥΔ¦­vs΄V–·’ήhΟή,x™7ΖρΈuaί‘ZVή Φξ-tΆE2.τ‰εU‘—Τ)4ωγkά|ρJχ9Ί+GIΡο5Kι,νΥxΤ³,¬ Ο|ž•ΥψŸΐΣΓ‡ω•νqσ+Ϊζ-Ψψ#DΤL±jvφ7ΠΊΊ,W(φΞΉ+œ›™rЇyωW’σΠ{RR»°)&ΪDtWMkΰrβΡ'KxΧΜ]ιΚͺμ=ώ΅ƒ •ΜΧλe.n™ό±0wgφ¦€žΜ“Ω•θ’χΑZΝ₯¬ΣΌPΘ°ιV)U™|ŠOYZ_jwqίΒ²Ζ–rH “Γ `:\κΧBηVΊ9Κ+£ρ •₯Ώ†|;qo €χ 1™Α9r¬Ολ\ε4ξRwW (’˜ΒŠΠΠt‹½wT‹OΣΥZζPΕC6Ρΐ$στ·πΔ:LΊ„φ±ωPιcYU€qœ²Žœ~5.q‹³`r”VΟ‡|5©ψˆ]dΒ³5ΈRκ\)ω‰ϊUŸψ7XπύœWwπΖΦ²’Xd‘½:w£ž7εΎ s΄WIαΟλ^ ΄k»#[PΫ³HY½zΥjZ~»‘{oδήΚꈬà ΈαH=1žτsΖφΎ dΡ]›|6ρ ²†ŽΠ0ΔμnžΫ½3Ϋκ=iώπκΒΖ‡EΧ­VO/ΜYacHŒr?RκΒΝ§{ΔΡ]n©ΰvΛNΈΤΦ?³Γ—’4”4‘/\²φγρ©Ύx>_ίΫάΞ‘I₯€ζ)ΤΝ±Ο˞^γ₯¬\Euώ/πEώ‡φΫΆλ§€εc 8g [ ‘Χ¦+kΒ?εΏΠοξήk1-ΪδdρΤu€λAGšΰy΅³β/ ίψ~{x΅#|ΰ”ς₯88η:Φπψaβo6XΝ΅Έt(3¨2pΛλΧ―J§V ]°8Š*KˆdΆΈ’ Ρ£š6(θΓH8 Τu`WOαύ>ΦηΑώ$»ž{‹a’η9MΜAΕiφ­πζηP0©Ό]@B%η!6ΜΤs‘ςœΕ»‘xSUΦ­šζ(Ψ6Ρ,V>ƒ=jŽ―€^θϊ²Τ!1OΑ †‘u\Ι»\,χ(Q]wό+Οy’!·„:ύΥ3(2pΛλΦΉ»}>ξγR[`vΌg1ωXΑά:ƒιIN/f 4U’½Aπ=Ν•Ζ’Ϊε¬2ΐ–2²2H$£iΑΘ8ΝexλJžςΛKΏΡ Ί’yΆ–•ŸAιSν­kaςΎ§#EhxŠνΌA©Α†+©QtU@wCπ«­Z΅Ν€Q₯°mžlVoAž΅|Ι+±YήΖsWο4‹η΄ΤahgQœAˆ#‚+‘αφΎξWȁN2»¦QΏŒα}i9ΕjΨY³’’Ίι1Ογ{m7WΆά Θ²Βόr¨Ηœ{ŠšγΔ:2ΖΎ΄eC}‘ΈχιIΟ[%pΆ—g#EihZ%ώ»tΦϊlc¨άδͺ£Τ“SλώΤτ‰οαQ Ό$±Έt'Σ#½W2½―¨YΪζ5Πi>ΥυK/-"‹μ²–G”(\η§5C^Ρo΄+Ρm©CεΘWrr¬=A)&νp³άΟEg`¨ 3I4²FρHΡΚ¬’!*ΚΓΤ^ Λƒ>Cβh£“ZΥ&hm₯‘C xԐHΉ+ϊΗΞ%ΊΉšβαΛΝ3™ρ19'σ¦":(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€'½§ό?•ASήΗΣώΚ  Š( Š( ΅Ό#n‰_ΠθΕ¬š–Ξζ[;Έ.­ŸdπΊΙ`¬AΑγ¨ ]ρ;0όu‚δ3q\—Ζoω):Ώύ±Ρ)XW^%Υ’ΎŽ{½ι}2ά\-ω‘ΰqτSZΥo5­JmCS›Ο»›δΪ«œ£…t€%Τ΄=OL³΄»Ώ²– k΅έ Ž8qŒ#ήΊ―_I¦ψKΕp€O$_g!e]ΚrΜ9sšΟ‰΅}gN²±ΤΜΦΦkΆ*£c’IΗ5JΧS»΅°»²‚m–Χ{|δΪύ§#’2? ™Η™Xqvw;mSWŸZψeqqsΌNΊŠΖμ\l§―5Άzv™α]υΉ5KΥ» ,6πJ~™ώ#»ωΧ ΊΪι/¦,Ψ±y|σΡΛγΞ3ΠtΝii~.Φτ»gezRέNQYφ} Ÿ³iYw+™u7ώ&σΌ6V9cΙ0²œΊŒπϊ՟Ο(ψ½g‡a²{d_`vδ~§σ'UΦ΅ ZHQΉiήΩ2€@ΞyΐηκhΌΦoο5…Υ.gί|¬Ž%Ψ£q΄ΰ qΪ…M€―ζGy‘μ_Œχ@ΰ,Ϋ~»^©|=Šω5›•bΖa>α-3Ζ}ώυq²j—²j§R7 /Œžoš )έλΗ±sγŸ\†κ«FΡ2ˆ^1Χή‡N[.Θ‘[ΐΔι8IOηQxΊ)#ρN±ζ#.nεnF8.H5•‰$LΙ"ΚΚpA­λkΪ†Ÿ%•εω–Ϊ@ΤΔ€z…ΟoZΆŸ5Ρ7V±ΣέI₯§Γί6₯iwql £ύ@_qϋΩzγρ¬Oή›ΖAΣξ¬Φ+Qi Όˆ>ι¬ΝΔϊΎ‰E§]˜αcΈΖΚΉυΑ…QΥ5½Vρξυ ΪyΫ‚Νιθΰ₯Li΅+”εtvώ$FΉψ=αKˆΑ)mq<2c₯ˆΟεϊΦ/€%΅:…ݍϋ˜ΰΎ€ΑΌ0]§!‡'§#;Αή.m ΪλNΏ²‹RΡΘ3ZHqσqσ)μxι\ν쐛ϋ‰,Q‘ΆiČrU3ΐ'Ύ+bWΊl%½πϊMkͺΗ(fPYΟ-Ι;ψτ;²:ŠΝρsYΩiΧΖΉŽοVΉ΄S‘•Ef!€* n3Ξ+΄ρ~Ώimφ{}Ru‹ᢏbFGαYSί\άLΟ3Λ+³ΉΙ'ܚλν|D‚ΩςΥn5qΆήvτkΧηΦΉ}RζYξDςΘΝ3ΕΙη5Wν{τ1c–94€{\LΒ@ΘD„Λ˜ϋϊΦΏƒ4Α«xŽέΖ`VσeΟM‹ΙΟΧ§γX•Πx{\΄4νB1k;ή]Εδ™VP‘Tžqςœq^ͺe{hL―m ž*ΤΞ±―ή^g1»β?d/θ+Ί³$j>Α?ςύמyšwόϊέΰJρΊΤO”’ΪEaνΰ6Ρ:?–21·ύW=zžje €‘2…HΉ„CΒOΉ›ΩτσΊoάιφώ8ίNΤ5ch@Wΐ 1Σα.uH.l­-&Šν­νwy)η ΫΈεΉδδϊΦ­§omlΦΦoDH»WtΡ³(τ bΝ'MώdΊoσόLoΜn|A3[΅³<ΜΝυSά|ΦίΔ€oνkΪv›°qΑλ\ϋΟ`ξΞφχŒΜrIΊRIΏu·oγΈ4°Η-οΩvφ4Ρ7ˌc&,τχͺqz[‘N-Zέ Όν‡ΠΖ#hΓ§ :vΖμζ²,fΥνΧ«E3"\ηpωxιž•jΧΖΧΆΆKk ΧΒ%]«™£fQθŚƷΤ-νοξοε[x”].μϊηΛ₯΄¬Ε΄¬Ξ²ήΣKΧ€ΥK]KIΥ'–TgΜmύε'―_\W²DI‰Ω %N2=+«Ώρ΅ευ£Ϋ\Ixbmp’Δ₯‡‘",Χ+1ŒΘL(ιev GβώTα·"Φβ4²:";³"gj“ΉλJ½‘躎»tφΪM«άΈdeR3ΟΉŸ]—‚ΌGiαΟψ…‘άk‘-½° Β―;›wnΉόY‘Η:”vVϋΚpyΝ%PkπoώJ›ώμΏϊ-«gαΤWΡx£Ε-z²*-ΐΊ.8έΈ}ϊŸΞΉ†š­ž‹γ++νJo&Φ1 gΪ[F€ κEŸŽ5ϋν:]6]IήΕ²€lP̝ldŒ{ύkš€%)4Άi~ k|<‘β🍚6*ίbA‘θwƒόλ™΅ρεΏ†―45XZΚκU™‹]XχNp3΄gŠ­§κχΪ}ν­œώ\¨#v)ή£8##©ιŠ£Z¨jΫκ ψͺ9εψaΰσh¬ΦŠg„B.}ώύiψ€JΊοΓ΄ΌΘ½X-ΌΠίx|λΧυύkŠπχ‹υΟ@πiWν wΩΧ> 08ό*ζ·©^k ͺέ]Ό·θλ"Κΰ₯NFLLb³T₯-=Δ¬³|oɐΔ=ύλB/ω8yάΫQ^YsβRκ;θηΊά—³-ΕΐςΤoqΠπ8ϊ ”x£X":θΌ‰©3ωIύݟw~ο*}„¬Χ“ύ?ΘGUπΚβYΌAβa+–iΧ/ ?ΔwOζ:Βψdqγέ?σίϊΗ΅‹ύ*ββ{ ό©n"hdmŠΫ‘±‘Θ8θ:UKiεΆΈŽ{y9£`θκpTŽ„VΎΝϋήc4ΌY‘ψŸW#)ϋdΏxcψΝtί ‘€ΠΌd‘©gm4α@Ι=k[ρžΏ­ιbΥ5qmΈ6ΓkΘθrΦ³΄MgPΠο~Χ₯]=΄ϋv–PG‘ ώ48ΚPε{N%+<{0κ=λΥόo ί4Ά‰%9’άΒ@γ`#wαΩ―;ΦόE©λχ–σλ7_hxFΥo-S œΩψΓβ>’Ύ"Ύo κύ›2¦a€1Χ#‘Q57%eΡώ€s?JŸλ[1΄žΈύk7RΠυ=2ΞξώΚX-Χt28αΖ3όzΟ–GšW–Wg‘Ψ³3–'©5―¬ψ›WΦtλ+JμΝmf»aRͺ1Ζ9 dœq“[ΕrΕ :?_I¦ψKΕp€O$_g!e]ΚrΜ9Mͺjσλ_ ..b·‰ΧQXΐ‚=‹€τυζΈ›]NξΦΒξΚ Ά[]νσ“h;φœŽHΘό(]Nνt—ΣlXΌΎyhερŒηθ:f³tξοζ_6–:ωlτν3ΒΊ3λrj—«vXmΰ”,0ύ3όGwσ§|L ηxl¬rΖ ’ae9uΰ1υ¬ /ΕΪή—b,μ―J[©Κ+"ΎΟ‘ β¨κΊΦ‘«Iκ7-;ΐ»#fPΟ8ύM% s]ƒ’΅ŽΫΕ³Κ>/YαΨlžΩΨΉ©όκmbόgΊ™fΫυΨϊυΑήk7χšΒκ—3οΎVGμQ‚ΈΪp8ΐνL“T½“U:‘Έa|dσ|ΥNο^8£Ω;[ΚΑΝ­ΞΛαμWΙ¨x”ά¬ƒ3 χωiž3οχ«œπ1ΕϊFN?SωΥ›ŸψŠδ0—P%Z6‰”D€zρŽΎυΞE#Ε"I2H„2²œGB*”^·κ&Φ–5|]‘ψ§Xσ—7r·#$μ.€Σαο‡R΄»ΈΆQώ @―Έύ쎽qψΧ1γ-{PΣδ²ΌΏ2ΫHΊ˜ΟPΉνλPh~'ΥτHš-:μΗ Ζ6UuΟ8ό)8I₯δ4fŸοMγi ιχVk¨Ž?΄^DtΥί‰—s[xΒΞxœο··…γΟb9ώuΘꚍޫxχz„ν<νΑfττp—UΤξυk‘q¨MηL&ν‘xΤ-o!9nuήΤζΦ~'Ϊίά€I4ήaeŒΌB̓ιTu/O2έ[#EUpρο[L0# η­sΪV£u₯_Ηya/•svΎΠΨΘ πA ͺΕέ™ŽXœ“G³\ΧmΧΒ+,žρZY‚nH‡!~ρMΗ?¦κ#YSα,i ¨Ϊ‚˜7wFqνχΏZετ}^FΊϋF™rπJF@θAΰΤϊοˆuMu£:₯ΫL±ύΔΪGΰχ€ΰωΌ―qσ+Ϊ³°ψ[‘ bε$z[ΜΦ­­έj–:u­Ε²Β3L ξ*qχŽyΖ₯W›S»›K·Σ€›uœ^8φ”ž§8ΙλλTκ£nKw= ĈΧ?Ό)q%-'†Ls΄³±όΏZσΪκΌβζΠ­΄λϋ(΅-μƒ5€‡72žΗω•Ξ_Ό_\=œm«HΖ(ΨδͺgεϊŠ±QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE=οό}?αόͺ žχώ>ŸπώUQEQE₯*±+t€©ζ[ψσ (’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Šžχώ>ŸπώUO{Oψ*‚€ (’€ (’€ žoψυ·:‚§›ώ=mΰ_Ξ€ ’Š(’Š(’Š(ξ?…~'w+δZ©Ϊ7N£Μγ8__ε\%zWΖϋ‹?iΧ0Ήσ-m`’,τίΞ€81€_Ά±ύ”-%:™δω|Ϋ½?ϊύ;ΧA­|;ρ‘¦Λ{qo Β38‚evˆ΄τΝo|7Φ_^ψ»§¨€άά$„,jB†cŒ“Ψυ₯’jš]•φΌΊO‡uΙo^ήXοD³+ͺƒΤ°ϊZ`yΧ…ό3©ψžρντ˜UΜkΊGv ˆ=Ν^ΧΌ ­θZd—ϊ„0­ͺJ"’†ήHΘ+Ž’Ί/†πOΰOΨi€Ά£,p•EϋΞ€œλΖGγV/΄νGLψ πκ±K©+ΗͺU‘Aδdξ?yu‘‘躎»tφΪM«άΈdeR3ΟΉAΤ£²·ήSƒΞi”QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEO{Oψ*‚§½§ό?•A@Q@Q@O7όzΫΐΏASΝΆπ/η@QEQEQEV†Ή¬ίλ—‚οTŸΟΈ#±WεYτPΆ—3YέEsk+ΓχΔt=ύ¨QΉ2¨–ΪžaEoάxnβOέhzv$•%uŒ»Κ¨'“λS^ψ#\³Σ$ΎšΩ<Έ†ιdγrW΅¬~=ΞjŠλ<αi5ΫΨ.&HŸNIΌΉ”Λ΅ΰuξ*?ψBχGϋ]Ω ˜¬af ΑKaxλΣr»\=€yΉo©ΛΡ[Ϊ„υMjΝνR$΅VΩζΝ @[Πg­RΧtkνπ[jPωrή€ΚΛκ₯gkN-Ϊϊ”`†YεXΰε‘Ί*)bI,RC+G24r)Γ+ }―Eψ]u.α_j;cΤ-­β1NT€–Θγ°ό«Οοο'ΏΌšξςS-ΔΜ^Gn¬OzEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE=οό}?αόͺ žχώ>ŸπώUQEQE<ίρλoώuO7όzΫΐΏAEPEPEPΰ_ϋΓωΧ¬xήAΎ4imJs%Ή„ΖΐFοΓ;³^M *ΠMzGŒ>#κ+β+ζπΞ¨ίΩ³*m&ΑΨ½r9…XΙΙrτ{§γΫlΖ>Χ'O_-³ϊΧ-‰/΄κΪ…§•,Λ4r e`Ξsτ‰§κ·Ί~ͺš•₯Γ-ς1q3ηqΞIά=OZ«q3άO$Σ6ι$bμqŒ’riͺZ롬{ΰ•šO‡>2ŽΔvD χŒ{ŽοΣu$ΡόΉϋXeFΤΤΫξ6Œνφϋί­r·¨θ7†λIΊ{iˆΪJ€CBAόjLjΌO¬x‰£ώΧ½iΦ>Q„Uχΐgή“§.o+άQΣI§„πOό‹― γόKρ<O­ΧώZηγρF±Ά’%ζΨΪB|€ωb#zsΗsΝSΉΥ―nl,,§Ÿu΅Ž³¦Ε7[2r@λšQ£$ΣώΊ˜‹γ[™—γu†ΩywˆΎΚvδγΗσ?β0Η:Ψι,k>ϋ^Τ―΅΄Υξ|ΝEeΨ£ ˜ΪvŽ0;U]JϊγRΎžςφO6ζfί#ν'θ8ͺ§MΖΧθ¬iρ†7:ξ™ F(Ϊl8lp~χzΙψdqγέ?σίϊm―ŽΌIm₯:MώΖ#1h‘ˆLc*OOzη­§–Ϊβ9νδh捃£©ΑR:Da%—‹"’?κβDe?l—ο ·ΔΡάΏΒ_ •ΪάK7™‘Έ»mΟώ=\ξ·γ=[ΣώΕͺjβΫpm†(Χ‘Πδ(?­oΛ€ψ?Γ–Ϊ ωPΆσΦκ?+*>W;†α¦JvŽš§ϊ|T¦Ÿα$»Θ»]1<ΐίxtλϊΧ#o‘κw:<ϊ¬RΎŸm’p>U<ˆ¨υ­Zϋ[Ώ{ΝRα.XΉ€ p­Ωψ›W³Π.t[{²šmΓn’-ͺsžΈ8ΘŒZ֜\b“WαOόZϋ²θΆ—ΒΎ&»Φ.υ»K‹{(γK ά40„bA“ιΝyΎ“©]ι7ρήiςω71δ+ν Œ‚Кvͺήι³\Ke7—%ΔM ‡jΘΨΘδqΠt­γ;Ξ—3lι|!a ψkYΥ/ξoΕ„e"’ΪΝφ™³ύφFοηZš£YIπ²VΣmνν~ή₯εΓvŒ•8ιύs\n…―κZ’6™rbŒ:• ­υb₯ΥώkρηόŽ:Ώύ|5OόCœ6ΡκN#‹IE-ΠFHγ½a_έΟy5ΥΫω—1wl“τQ)'°S„’Υϊ+wΔΨ€k½UF1Ά— ‚έωΥ―aαύ’§\BeŽΫ#&OCιΧ>Ω¬7ƞ Σlγ΅³Τ] Œa£GΪ=`N+;JΦu &υτϋ—‚vΞζΩυƒO™^βφrδε:WP΄=™₯jX‘"ά\8eWΖιύiš³°ψW‘ bε$zΰΆ?™¬{Δz¦»εNθΚ‘ςˆ*ƒλ€5RmRςm.ίN’mΦp9xγΪ>V=Nq“ΧΦ“Υ7§­Λ—ΊυΞ₯‘ox"ιγˍΤΕr>ρΟ8ΗlWaβ«+™>.Ϊ΄p»,³ΫΘ„ ¨LŸΓΌήΊK_x†ΦΑlαΤ\B«±IE,£Π1‘KΈεφ|¨ΡY_γ\εH#Θ~Q°ͺήŽς?xέ¬Š«i8Έ.8ݐyχλϊΧ?ΰ-RΫLρu­ώ§1HWΜ2HAc’Œ;džM7PρŽ·ya&Ÿ-ϋ΅›eHΪ‘™{ΨΙJKs7NWε]ΏŸπώUQEQE<ίρλoώuO7όzΫΐΏAEPEPEPσΗ­Ώό ωΤ<ίρλoώuQEQEQEt ΆGΥZφΰ£XΖnϋŽƒσηπ¬[λ—ΌΌžζSσΚεΟβk‘—ώ%^ Ž>—œ›ΫΧΚ^Ÿ?:撍₯‘#Œw!TδΣ₯ΡβWα]CQάͺ’©Ηψ~uΛWM­Ζςψ?ΓςF₯‘<δbB[ϊ­β« [k‹9ττ1Ϋή@³,dηa=ͺAΰνc{‘†0ΛΠToγ™›]:,‹πφ_8­x [Ώέη―λ\Ε T³IΕvχθš~³‡&š'-²9.ZBscΔW *Π0&»-~Ϊgψ‰HΨ‰%…ԁΑP'τ4ΐΑ›F™όC>—g‡‘deMΗ'ŸΐT—>Υ-¬^κHdcs¨pY©Ή₯°o‰•9l£jƒΒipšΎ΄n€-¦σ‹tΞ{ώ΄ΞiZeή©9ŠΚ-μ£s@ =I5.­’ήιKέFΎTŸrD`Κ[ž0Β;ωΡΛ*β2ιaΚδτ?Cynήk{ Έν ΐq4ΞCc=(†΅+ΫX.aŽ?"`J»H8ηρͺσι—~― ₯ό[Ίδg!”ž ϊV¦Άμ<ατν&bGΈn?™©όBΕεπΛΉΛ΅¬Y'©δP‘αΛβ;WŠΊpŽF™8:ώyZεόC`ΔΧ6Z|`XγN{ έΦυ›«ήι‘μϋ<χ1³αχ2ΟCSZeߌξmΉυςθΞίψgS²΅{‰aFHΦδ SκKαMυ[¨₯‘Q¬ΦM’ƒ&ΦςήmHYiš‹ΞΠΊN@ΐΤ·‹αω΄ϊλύ $Χ|=u¦ύ’r"«!TΔ‘›ρΗZ‹Oπξ£kΝΌiδHHήΞ sš«­£&±|H>{υνΨΤ‡€τ€ν7=pOψΠ6­¦]iW>Eμ{ΐƒΓΤίώΚΎΣ|=~'±²–7ŒϋΓ«‘_i$׍’Hά2ηӊ΅α‹Ή-!Τ7ΨΙwa$anB pr?±ͺXΩΙαΓ€Νy¨˜#ΫNxݎ£ΤΜΡE:-Ύjoϋ»†~”€ΪƒΒΊ΄ΦΙ*ΐ ΊξHΪ@‡¨±‘Τ«©Α`ƒι^β μ ρlnφWΣ^ƒBblŒ tλΧ―ΚgΦ―%hZy 1·U=Α¦ ½€iWz΄ν”aŠΜΔΰ(χ5Υ…Υ¬MsΗΓtlΓ†ΠxZ9.|;―ΫZΧN±«Υ”? ώt—¨ψPΣ­ζκ4XC„ bFAνYUΧ\ΪέZ|?1ή#ΖΖπ2£Œ]ΎΉΝsV7Z„Ζ+(iξ*£ υ  ΤPARCΰƒE .iZtϊΓAk³xRη{…ΘOΦΊMΒ3E26ž‘,"g 0ΞξsŒšγλ₯ρΪ·φ›m;Mœx8ΰυ¦>•₯έκ·(·²ΜIΐQξMK«θ—ΪJΖΧqŸvD`ΚO¦EjψxHώρΫ‚f",…κW'?¦hE‘~Λη―‹wϋΌγυύh˜’Š)½oα=Vx#•c‰L‹Ήε˜}+:ΟK»»ΤώΑxΊΛŽq‚:*ꦞΣSΤν Φl―μub5–οό-ƒΣŸJ­αΈΗⷚc+£ΘΎc[δ<Ÿz`sš~Ÿq,ΡΫ*–Š6•²qςŽΏΞ₯΄kέV9žΖ!'”T0άωΊuϊVΧ„-ε‚ϋYi‘‘a³•\‘χO~†›α••Ό/β!bε"αzγ-ŸΣ4•«θWΪTQKuωRp²#\ϊdTΦ>Τ―m`Ή‚8ό‰³‡iώ5z λπφ4x<¬ύqϊώ΄νaeoθEƒΛ»3ΈγϊΠ©§\ιwfήφ?.P3Χ PkN κσ[,Ιn£zξTgΨ}*狁Xτsώ΄Z'˜=ZΉ―Gvί-Ϊ0δ!1‘Σf½@•…ΕεϊYB˜Έf+΅Ž0GP*›ΒΊ¬6’\< ˆΖη@ຏR+VΠ©ψ˜Ϋ1΄?O]§?­cG«\ιšυνΤ;Gy„€ΐžs‚( h/ͺέE,Šf²l”6±γ<½Ε3]πυΦ›φ‰ΘˆZ¬…S†lΗj?ΘΝ§Χ_θj¦ΆŒšΕπe ωοΤ΄h•S’Ϋ榻ΈgιH ¨<+«Ml’¬ 䍀Ψz€k:ΓNΈΎΎp…[ƒ‘²C·‘Τsή»oOe‹cw²ΎšτΪ€+` `c§^Ή]A.όO+ZΑ$R\e#ώ%|0+Ωι—rέGaM²–˜Θv„Η\“ψώTΝ+L»Υ'1YE½”nbHG©&»–›D»K…§ŠDώς† £Ÿ¦Gιμk#ΒFψGuί:9e\F]"l9\ž‡σ  =[E½–7Ί|©>δˆΑ”ώ"­Aα}N{dž(£e’1*/˜72ŸAW/ο-ΫΒ­ocaw‘Έ&™Γ(lrΗ₯lΫ/΄<ω„·ώ‚hŽΥ4›­1α[˜•w##†SψŠΦ7Ίc ½•Fώ3Η―Z]gώE Ϋύ V·ˆγΊ?¬Κ+ςρΘώθΖ ζ€9}:β :ζeΏΣΦ菓ˑŠμ σ―ψΞΪΪΪϊΜΩ@°G5’JQI<’ήΏ…VρnΣβMGn1ηž½κΡŒϊS…% „@68=Ζ€1τ­2οTœΕeφQΉ‰ €š›WΠοt€ŽK€S œ,‘°e'Σ"΄<=iΡu+λΉξΕ’ΰΆm¦L{۟ηW―³ψ Ν”AφΐTLΫ‰8δŽ:υθOπξ£kΝΌiδHHήΞ sš©«i—ZUΟ‘{Η#p δ0υΆuaΰ=);MΔ„\ώ5‘¨j“ίΪΩ[ΞmͺΡ€9#ŽΌϋP…Ώ„υYΰŽUŽ%2.δG”aτ¬Iβ’ ž)€ˆΕYOPEv“Oi©κvk6Wφ:± Λ wώΑιΟ₯rΊέ³ΩκΧVςΚfxδ ΘO-ξh•fκΒκΦ&ΉγŠaΊ6aΓ ­HŠ( Š( Š( Š( Š( Š( Š(  ογιεPTχΏρτ‡ς¨(’Š(’Š(©ζ[ψσ¨*yΏγΦίώόθ (’€ (’€ (’€'›ώ=mΰ_Ξ ©ζ[ψσ¨(’Š(’Š(₯\n³·<β’ŠΥρͺΊ­δofxbX’Œœν‘Π―!ΣυX.ξ"i’#Έ"œdφό5BŠšφεο/&Έ”ζI\ΉόMCEVž•―jZTmΙŽ69(T0Ο―#ŠΜ’€,^^ά_]›‹ΙZYXŒ³WM―xΆμjΧGG½?c.ίݎΠ7 Ž•ΘΡLwgvwbΜΗ$“’MkCβMZ/²%γ}ŸfΝ¬Šί.1Œ‘šΘ’Q@^&ΥμmcΆ΅»Ω c ΎZwκFj S[Τ5Eoξ<Ρ%~E\ΐ Ξ’€.\κww:ˆΏš]Χa•ƒν•Ζ8…Awq-έΜ— Ύis6Ιό**(^jΠΩ}‘/μϋ6mdVωqŒdŒΥ-7Q»Σ.<λš1‚F#ΠƒΑͺ΄PύWXΏΥJϋ†”'έ\πBŠ(­«kZ h―XD£jεT°€‘šΕ’€6|% ˆ­ξο₯+ο.δ9*Gnzšm߈υK›6³’νšΨρ Ύ„γ&²(  Zn‘u¦άyΦ342cŒGΈ<›UΦoυ]‚ϊs"§έP‘@όgΡ@gΎΈžΞήΦY7Ao»Κ] mΙΙη©όin5«ƒkηK»μΘ/”  t9όj­fζϊβζψήO&λ’Α‹ν‘ӁΗj'ΏΊžόήΙ3}¨°o1p§#ΏZŠΧΎρ&­}jΦΧ7e’nU-υ VTR<2€‘1I†Vή›Ejj> Τυ+_³ήέaΘm»r=ΐΝT’ϊβKlήLΫDΕ‘6Ž λΟZ­E*±V §Šή„Η]ŸοόƒXPΛ½Nςκό^Ο;‘ŒH )ιΣrϋΔΊ΅υ«[άέ–‰†**ξϊ+ŠΉ₯κwš\Ν-Œν°Γ`χŠ›UΧ5 U;Ϋ‚ρ‘Κ P \Y΄PEPΝ·‰υ‹{U·Šρ„j6UIQθ ¬vbμY‰f'$ž€Q@―΅[Ϋλk{{©ΜΫŒFΈ»uόiΪF—α₯Τ$ΣΤ)ύτjΜsιΝgΡ@FΉ©Yμ·ΣκIqηΙ<ͺWψqŽyτ¬=/S»§i¬f1HΛ°œ‘τ5NŠWfwfrK1Ι'Ή€’Š+^jΠΩ}‘/μϋ6mdVωqŒdŒΦEkMΤnτˏ:Ζf†L`‘‚τ πj]WXΏΥJϋ†”'έ\πBŠ(’Šά‡ΕzΤ0,Izv¨Ϊ "³υ#5.f_iΏΪ7oσ3σnΞsšŠŠΧΏρ&«jmξΛB~ς…Uέυΐζ¬h²iΊ6¬‹;Ey)ˆΑ€NJ±'œcσ¬ (GUΦ΅ Uc[λƒ"§έP‘@>Έ­kIc ιι—E.‘σDΙ³#²3‘ƒψW1E0,κΧ:Λ\^JΚxάxγΠ΄ ρ>± ΆŠυΔJ6Œͺ’ $f±¨€‹KΛ‹KΔΊ·­Β’ΑΘ rzυϊΤ2;I#;œ»Δϊ“M’€ ©$LRD!•Αw­-GΔž₯kφ{Ϋ£,9 ·bŽGΈ¬Ί(’Š(fΫΔϊΕ½ͺΫΕxΒ5W*€¨τŒΥ FκΒμέZΛΆΰ‚7• yλΤ}κ­rΗR»±žYmf+$ͺUΛΑλr 7NΤnτۏ>Κf†L`‘ŒθAΰΥZ(CUΦoυ]‚ϊs"§έP‘@ό"λκπ:Ο†‚#gbό©Œc§λΦ¨Q@e½žkk[i€έΆο)v·qΙη©όk₯ΧΌ[v5k££ήŸ±ΘoξΗh†GJδh¦»³»;±fc’IΙ&΅μΌM«ΨΫ$Χ¬± Β©ElNA¬z)LΦ/΄Ιd{)ΜfOΎ ‚κϋύwRΏ·h.ξL³*U@Θΰc ¬Ϊ(Μ—ΧXΓfςfΪ&,‰΄pO^zΥj(  Θ|W­CΔ—§j ²+0R3X²ΘσJςJΕδrY˜œ’OzmzϋU½ΎΆ··ΊœΙ ΈΔk€1Ϋ·_Ζ¨ΡEQEQEQEQEQEQEQEO{Oψ*‚§½§ό?•A@Q@Q@O7όzΫΐΏASΝΆπ/η@QEQEQE<ίρλoώuO7όzΫΐΏA@Q@Q@Q@λž:ΏπΟ…Ό@ϊbψ>Κθ,hώa“;†z`Χm§Ιβί5Ύ…c ›\e’Άσ>D Ή#qϊ@4W_¨ό:ρŸ£Λ¨ΟmŠί,i(i#\g,ΏOΖ±ό5αΝOΔ—m€Αζ².ι˜* υ$τ  Š+’ρGƒ΅ E ϊŒQ΅΄ΗjO ΠŸLφTαC «)θAξ84—Evv ‚Τ7ΐlΘ]ί{ιZχŸ |Ii¦O{%¬L°)y"ICH«λ΄{sŽΎΤΖΡ]‚Ό9¨k·­.€’Νγ’Hξd $zƒ΄ζ¬όP[„ρlΛy¦Ϊi³“0Z°dιΑΘ“τ NŠιό3ΰmoΔVMyc QΪ+lO Efτ΅•βPπφ’Φ:¬ΐά92φ Ž’€3hΪΗᏈο, ΈXm’3§™2Ξ«#Θγόk½΅žΖξk[Έš+ˆ\€ˆέU‡Q@Ρ[Ϊ„υ] L°ΏΤbD·½Pc*αˆΘΘv8¬(’»/xB[½.ξβε"f’ΨIjDΐa#pΖ³«V4•δΝ)•Wh£’΄5λH’4Όξ»7O₯jGΰ­iΫo“’2»₯QΏŒρλC­M%'%f FΪQwG7E_²//5_μΨ’Εΰ,₯νΑPIώTΝ7MΉΤeš;UVhbi_-Œ*υώuNq]IP“θS’―iUζ―pa°„ΘΚ71$QκI©u HXής5ςdα%ƒ£~"—΄‚—%υ³—/5΄3(’вŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  ογιεPTχΏρτ‡ς¨(’Š(’Š(©ζ[ψσ¨*yΏγΦίώόθ (’€ (’€ (’€'›ώ=mΰ_Ξ ©ζ[ψσ¨(’Š(’Š(’Š(ΪΎ'xΣWΡγɚβ&†VΨ­Ή‚ÐqΠt«>ρF―αΉ%m"μΒ²ΰH…C«γΤiίλ-§Kπbv,οmlΏ΄TΖ·n“–Sύί뚑⸀ψAΰσ »[‰%σ6ŒΕ›nρκεuŸkϊՌ–zž ΣΪΘβCtΖ@φTϊ?ŽόG€ZΪΫXj&;keeŽ#ŽNxΙηΧ§j`oό\&ŸαΌΘ½]1<Πίx:ώ9¨η†IώΩω(yzΉgΪ3΄yl21ωΧkϊξ χΊ­Λ\\° Ή€ pψwΕšί‡#–=ύν£”ξtΨ€ϊၠ ‚‘β%€œώ\ΎXaό[τΝtz&©₯Ω_kΛ€ψw\–υνεŽτK2Ί¨=K―υ―6Τ|Cͺκ:κχwŽΪŠ•+:*‘zch΅uˆ%Υ΄Χ°ΎΤK[Θ6Θ$C τ$hkΑΙyπΛΖ–ΦΚdœ}žMŠ2v†Ι?’š-ΰ’Χΰ}λ\!Œ\κŠΡnή6―#ώω?•qήΧ΅?^›­"ιν¦#k =9¬ψ›ΕzΟ‰Z?ν‹Ζ™"9HΒ„E>Έsξh­ρLW2|π…]­Δ³y›FFβν·?ψυ?βpd‡Α ©―[ώΠ¨\ξύZ‡ώΉtxjΫΓϊQ΅σ–κ#Wk>TΓπι\FΉ¬_λΊƒ^κ·-qrΐ.βΐ€>”μή3Όm>$ΫΙ6‘¬]jΰΔΦ―m0ΰ€«ιœηρ¬\ΏŽ’ά=¬–o#ΞΝ˜άεœƒŽωΝrΆ?|Qc§­”£y(»ΌhΞƒΠ1¬='ZΤ4Xjv-π,|ζPδ–wrhΊψYq4ή&ρH–Fq>rςόMΈr3ωΣ|}6—π»\Ώ΅ Om¨ΫJ™ιΘyφIΦυ "κβγOΈςfΈ‰‘•Ά+nF °δt)°kφϊ5Φ• ϋl.]d–-Šw2γ8Θθ:τkέzοğ ΌQ©j%™οmΣd@„U]€ 'ί―sVo%ΡcψYαWΥμoμΑ”’H$›ŽwgΉω±ψטΑ¬_Α£\ι1O·OΈ‘e–-Šw0Ζq‘Πt5£αΟkΎΰ―ŒvμwΧ> 08ό(k➠oΫCK½°XlΔq›Β Λπž?΅cQεψ'£˜Ρœ&§&ν£8αϊΧ­jχΪέϋήκ—/qrΰ큀:{ ΠπχŒ5οΫɏ¨=Ό.Ϋ™ #}@`qψRKα +ρFCΏώΉ΅G‰οό;γmgP³ς₯šY§ŠEœVVsœ€G ¬ˆόCͺGβ%Φ5BζO?Λ_ΌF ۍ½₯g\Ν%ΝΔ³ΜΫ₯•‹»c$δž(ͺŽqYΎƒ5ίόqF>>Ή`¬TA8γξΧ7αΟλ~Šhτ[ί³$ΜAε#䎟yM]Υ>!x£UΣη±ΏΤόΫYΧl‰φx—pϊ…€7|_ςό*πcY«5’™„Ϋ@“v>σΖpxŠ4ΡΣďΈ›eϋ*±]λ Žsώχ5†όi―xrέντ«γ»Ζ'EuΤ? ΛΦ΅{ύnύ―u[—ΉΉ`vΐΐ€μ(ΥnτίxƒM΄ρ^‘¬i%eŽm_Œηεlv' 8υ―4ρŽŸ6—β}JΚζιξε†R¦w$³χηΎ1[6ΏόWmfΆΡκ„ͺ.Υw…ΤΌFOγ\ΥΔΧw2ά\ΘΟ+wc’Δυ&€4u{}r-:Α΅eΏLŸθŸh-³n?ƒ<ŒtνŠΙ­gΔϊΎ΅§YXκWfkk1ˆ”ͺŒq€I$γŽk€ κ|₯τΏͺ‚ΜlŽκzΧ-VτΝFοKΉϋE„ν ΈΫ‘ƒ‘θAΰΦu ηΉ₯)¨M6T Ž£ΧxώζX(Φ5CmwxΝ ϋΚ¨«»κ@沩BM΅ Y€½,iNΌRΌχMΏ[› 0 ψ‡ΟŠYWΪε2zNΉ¨5Ϋvπƒ[XiΧ±Ω›λ<ξCγOλ\ώ—©^iw>}„ν ΈΑ#θAΰΤϊΖΉ¨λXΤ. ‹έ@‘T~PθKΪst½χ}»½Ÿ/[[eωΠτ]G]Ί{m&ΥξgD22© η܊ κQΩ[ο)Αη5Ψψ+ΔvžποˆYΖ±yΫΫΌ*σΉ·vλŸΐW]g(QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE=οό}?αόͺ žχώ>ŸπώUQEQE<ίρλoώuO7όzΫΐΏAEPEPEP²:˜!P~eΞ:ŠŽ½*k«[‹I]A,FvΘ…Oδh(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€'½§ό?•ASήΗΣώΚ  Š( Š( §›ώ=mΰ_Ξ ©ζ[ψσ (’Š(’Š(’Š ‚:Šτύ{U»Χ>Γ}­H.―Tς’˜¨ «°œΧτ―0―PπΎ€|;π–ηQŽΦΫPkLBΠ]©’π™έ·=xλξ=(Λ諚ΕωΤυ)οΪΪΤΚAςm£Ωΰς―n•6₯‘κZe•έύ«Αox»ΰv#χƒδ 瑝fΡEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE=οό}?αόͺ žχώ>ŸπώUQEQE<ίρλoώuK#©‚ζ\ησ ¨’Š(’Š(’Š23Σ½v~&ρfsαΈ΄ιo§ιβ΄Je—Μyό;wμ+Œ’€Fš5•ŠFX`3žN+¬ψβXΡ<»kH~μCŽύΟςv€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€'½§ό?•ASήΗΣώΚ  Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  ογιεPQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEΩ endstream endobj 197 0 obj 8805 endobj 198 0 obj 29480 endobj 192 0 obj << /Font << /Font2 12 0 R >> /Pattern << >> /XObject << /Image25 195 0 R /Image26 196 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 199 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 200 0 R /Resources 201 0 R /Annots 203 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 200 0 obj << /Filter /FlateDecode /Length 202 0 R >> stream xœ΅XΛn#EνξE€Τ7€f“ŒB₯ή‰  b$€–fA@²€I„œ2Œ+ώ€Η†oˆζ"Α†E”ΰέΜ* Δpn΅έέΆ;ž$nwΗvχνκ{«Ξ=uκVΘδ‚Ρω~ua„Εο·§μŒ .„Œ.XaR‹Ε{4’ŸS¦υN€ΧG͍ΦΊ±…ϊ>aΩS9cŽ~< vό"(ϊψ`΄D E BG͞ί+Τ {ς}‰σ¬I¦Hι„[协­=|žbX§’δΦΥΆQΛ&£ΕΑ…†΅~Ήmlέ„σΗnAš¨Έ΅ΣάΙθƒηHLΗ[ΘΣΑg§Γγο•g?K][‰ˆθŒDc)΅q©ΧJ‘<Œ΅mΤ²)έΤVΏΫΨj<(¨3Ύ5W‰l³ϊE·΅υ*2ΉχΡͺ0#dτʚˆ " ™H”Ά*κϋG%\”ΟΩΑ§ΟžΎPΜ’!•Oζ‰NYŝaeΕβς;φΫΝώΪcyvσύμ:»Μ-ώΛΛbάzc™ΏSŒχΨΧ¬όœ}RφΩ/m"Xo£_κέξ+ horUj₯ΆXE]ΡQ»Š.3Σ¨1yνL¦Ω{εξIk‚Υ 2 ±16mfŸE€4SBΚ-!%A=η”±ΐŒ»6PΕοΕω ¬ϋz·>%cΞ1ργέόΑΣS‚δƒlζΑ<θPK•΄.ΦπÍ ˜E\JAρS恙•Z΅Œ£Ζ% Ϊ[ν( υϋέΦΆ$ΉA'"f’w–Έ™ϊγp*–Ϊ»^ΗYΖ%ίʏŽθο“εeqQ\δYΎM†­|˜½*Ξ³Χ€kζΓόŒSw²Ij„Ÿ!ήΌ@³ω6ξ0Wp²O€«8xƒ<» ξΘpήγΥΖΝ"\‡YdτŒΝ·ΦΚ’γšΥclJξΙhζΨtƒ΅ε€Έχτ•ά[+΄e"qΨΉ9όGOsΈΛ;Mδcβΰ~{&― ©V  ­cΈaTη˜ˆ5LσG ϊ%βηΏ`\’ΉΔΣΓΫ }U?Œ€Ϊ† Lw?ΦEΙs&… ! 'χqn˜φ”ΌNοΩ7΄4Ί7XœΗλ"…ΩΜ£Œζ†‘@‘.!dƒβœ΄hέA)/ΉρΦtΖ+k&κuζg`UyLŠ—·γθͺNθΰxTΚωξ―;ΖT{B<%ό†>+”»ή°τ[>WφC·Ώ€ΏaIͺW,pᐖόμ=,ύΧXΛφ‰ΘΩϊY‘ €|¨εΡυΚσ…R©ΰύRE0/hXΛΏ@%0Iš7β]₯Η„b³ΎOPcWWΧxž$ςθˆ²§ b˜Π&7Ε?λcξπH{ӁK£Ϊ B ξέμΎ;‘―kΦ΄wI•UΓid#1y—ΰφξ›ζ“T‘ ’/JBžΑΓί“~πΧ> >> ] endobj 204 0 obj << /Subtype /Image /Interpolate true /Width 698 /Height 1026 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 205 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐΊ"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ρ (’¨AEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE₯ hzŽΏ~ΆzU³O18αPz±<υ  Ϊ+Ρtο‡zuΑΌŠγΕΪxΊ³·{›„΅…8Σ‰`@8ΘΰsY:§’Σ₯ΤtKλ=oO‹™^ΝΏyυxΟ#υ BŠ( Š( ŠQΙΐ­=oAΥ41lu[9mΎΣ–-γοθ}AδP]Q@Q@oJΣυmB>5ΤΔ„Œ7`yζF»DWxe’μτ )¬ίψΓ:—fρG¦bΆΙ– X@?0ωΉ 2RΎk Qψ-α˜|U¨Ν§Ψ,±u2l|/έnΕ»vKΔώ1π…πώγΒή ’{ΓtHšβT sΜI ’@ΐΐΖ(ƒO‡ή+yβ…4;²ς‘‘8+Η$η¨λYZG‡υmbϊ[=/OΈΊΈ‹‰5ΞΞqΙθ?χ~.Φ<3₯xrλμ­u4²*‚Δ LAΐωιYϊN£sαΏ€XѝSRΌžk•\Ν1Byξ€€`UJ@QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEθ,Ήo ψrΗΓ:y0άέ@—z€«ΓHΞ2±ύΥ»ηλŸ?―`ψ‹βΣa¬ΫLžπνν­ν€70\έΨω’:•·s‚1μ1@ƒυΘ4OνΏ΄E$ŸnΣ'±M˜ω]φΰœφβ³τ fχAΥ!ΏΣf1OόwVΑτ¨]'Τn§·΅ώόοΌgdIœ“χTgπ­ox›ϋΦX?±4=G{οσ/ν<η^ΐ9t  ίτϋH―μu}*!Ÿ¬[‹€ˆt‰ϊHƒθrθΏoMƍαf΄΄²Ί’\½΅€^\q¬¬ €Ή8αI>δםPEPkαiτoi ―]<†΄μΛecœ¬y²0?q&‰γ?νs¦xΥεΎοd22ZHε€~ƒΥGθ:ƒGHπΔΉΡn$—[΄άχ6^,πρzΰuLΡπ—†ΌG~ρDΛoiω—Wrρ:’}zΰwόΝ0(λ–1iΊ΅Ν₯½δ°ΔΨKˆNREΖAŸ>ωͺ\O‹VΉF–y΄υlE$ΐqŽIί8φΕP€EPM%ΌΡ͍±°dt8*GB­z,zŽaŽηΔ—‹€λjκαbϊτσΧ·Ώ‘θ<Ϊ»―x6Ε΄Έ―όW©dΕ}ϋ½=HΛHΗ€Œ;F=xΞzŽ2™γlωlaΠlώ[[EΠίΥΟ韩<ΕiψCΎπφ©-†₯ΙS•aΚΘ½™Opk2€ (’€ (’€5uίκΊχΩΏ΅οdΊϋ2yqomϊO“ΙΕeWUγ―ΒWύ›Ϋ{±ΒbύΡΞώžΓcΞ2yV€ (’€ (»Nρ·Ψ¬-ναπΕΗ’<Ϋ‹ ς>;±έΙχ FŠνα`Τ₯αόφTΒΐ©KΒψ-μ¨ˆ’΄όA«lί‹―μύ>ΓΚ±‡ΚŒσŒžyλμ+2€ (’€ (’€;xχϋ_αφ•αμί'μ.φŸ?vύͺΓξmϋή§₯pτQ@·ΔΒiŸΩίbϋn™σόΟ3vή~θΗέχλW>όH“ΓZLϊ6©§EͺθΣL g¨zΰχ―=’€=7Ε_&ρ.—oα θπιZtς,bάn”–W€‚έ}}k«ψΉώψYΰύ:yRΦh›j8%Y#l}‰Χ…C,Κ’Βν¨Α‘Πΰ©‚cSκ…ξ₯0›QΌΈ»” žV‘±ι’hΦbψΏ¦ίEk?‰<)k¨jΆ yW!”dŽsΚ’ΌσήΉ›ο‰ΪΝώ‘ρ,i2BžJ[Jy]Τϊη9Ο=+‚’€=¦O4χϊ_…-mυ»„Ϋ-Σ:σξHPΜ8dt7αΔ+Ο kχϊŒΦλ~Ί†MΚ3l,Ϋ‹n’{w"Šέρ¦­§λzτ·ΊF••jκ [ΖF2-€τ¬*( Ÿ$&ί1ΩΆ«ΈηΠ{S( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( »_λ:^­ ΗαίΘπE°ΤQwbz£₯ όΏ,qTP°xΑρΫάiχφ·š=Ν­Όφ·*Κς>έ δ‚:ΌZην<9€xVA}βλλ[»˜Žθ΄›9#‚V*ϋwύŸΡ@^"Φn΅ύfηRΎ`f™³΅~κ(ΰ(φ³h’€ (’€-i—χZ]ό7Ά<0Άδ‘O Qν]7‹|ss―X%•½₯Ύ›m#yΧqΫ ™»»{{~§ŒqτPEPEPύςίOΥ­ο,’ϊ[s[»mW㌟LΰγΎ1Rx\Ύρ©-ώ₯.ω_…QΒΖ½•G`+2Šθ πΥΔ« ·£iδ;PI¦Ι–=bΨήΈνwH½ΠυIτύJΜGv#±Έ>΄ŸEPEPEm_ψ_[ΣώΗφέ2ζΆ8K}λ1Ž0ζ(ρ?†5 άΓΉfm€™<ΘώupΓΏ*Hβ€1h’Š(’Š(’Š(’Š(’Š(­m+ΓΊΎ­eqw¦ιχ6Φωσdr'?…dΠEPEPEPEPEa-&{7ΊTύΒ0BΩ}1@θ«ίΩ:†3φ+ϋΰΥY’’)4oŽͺΓ€#’Š(’Š(’Š(’Š(’¬\ΪMm2L›Veޜƒ‘λUθ’₯‚ g/δΖΟ±w6ќZp΄œΪ―)ΎΞnώΩ (’Š(’Š(’Š(’Š(’Š(©c‚Y"’Tš8ρ½€αsλQPEPEPEPEPEPEPEPEPEPEPEPEPEP]ˆ<;φ mOMΈϋv“p…Αϋ£α5ΟVο…ΌA&‰<±ΛΊΣnFΛ«Gϋ²/¨τaΨΠžποΫμnu=Jγμ:MΈ ΞW&Gμˆ?ˆΧ=[Ύ)ρšάρGBΧMΆ-mξΖΎ§ΥsXTWΰOω'ώ7·ύΥΐWΰOω'ώ7·ύΤΐΐ’ΛΗΎ&²΄ŠΪίTq K΅E=2ΚMrτP£ψGΔΊŸ‹uΨt?MφŸyˆθπF ‘0e*^1^Ÿπ›ώJ•mτSטPΐυ/|/·ΤΌ7 Š5Q₯in3@ΜΉΖβ[€ ιΑΝCρဇγρ‡υUΤτv 3Ή82πFxνƒϊvή.ΣόOπ/ßπFχ?eHX Λ3lŒ£$†νν\£ΰŸθίŸSΤ΅9l¬23₯Ι,ŠNηe>ξOήΑ€‘|i¦Σ| Jπ»ά’‰ᐐœq\§Ζ_ jrxΛCΣ†§y«ή^E²#pv|Δ`ܜW_ρƒώ=ΎΧδ_Ι*ξ`΄ψέΰΉ.™V3±‚Η3ULjrCα'†,g·Σ5―ˆ΅ΙΤm… (άzaO'žœŒΦ“π±ΗΔgπΞ³u"EφfΉŠζΜPpqάκ+Σΰr0{yj€8?ό3ŸΔž&Φ-θΫiZeΛΑ%ΛY°ΔLΰdϊWEsπEΥ΄Λ©|β5Τ/-ΎόNΘΚΗ2ΈΫœpyΥx§α߈ΪFŸ"¦§&£y΄nΑωΧja•ašΕύŸΌ5­hΊξ­«Z\ΨY₯Ή€­ΒήϋΘΟPžzs@ψΓΏ$ŠUΥ€ ¬0Aςzγ>ό9·ρ‹qkΪͺιΊD$ΰWsc«xQž;δΧ’|/ΈŠσßmˆ0Mys$dt*P‘ϊΕψ}α] Ηαšψ’χC“Δς?f@_h/N1’pMaxΛᅍŸ…Δ^Φ?΄τψΉ>3·8%Xppz‚_ώιwž ΅Ϋmμck§Ÿo—~οNs΄ žύϊW}}3ά|Φe}=^ΪR–H1΅ΌF δτ_Ζ¬Gμν‘€H[ƒοΦ€9ίό-±ό&Zj ρVͺt½>AΊ ©ΫœfnOAŽι<(ΕΏg XHUœ φωΑ«~%o<[π3Γ‘ψu~Σ%²@d†6εφ!Fδ78φ  Gα“oα-_\³Χ$½‚dΈ΄xv”tTΞϊξ 8ύ+Ελθ θ:—‡Ύψ‚ΧXFŠβH.fXX‚bR˜‘?|α@/N΅cMž+kθfž/649)λιϊΦ»kΠίoW΅ŜΖΡπινL~·5?τ_iΦ½bnϊ~‡τͺχσ­ͺ@–Πω1°Ζ½ρž§σ§ψ¦a&±$iώ(τΐЏ‹/ξν΅4K{™£O)NΥry¨υg’λΓ—£ύ$JUŒ\π«ώ!Φ4ύJ(’Hš?-Xξ\“ΙοYώ/σ. ­μr3Ω̟ =χηΠΠ"Ό:M¬Οͺݘ<αΉ#EάΨυ5_Uş‘, νgϋ’ΐΦφΉu ii9ΣbΊ†HWl¬OμΦ~―q;ιΆqΆž––ζMρέz玽σ@Ηήθz~Ÿ>ΫλχEoΈͺ™lw'ρ¬Ν_Lk "1Θ'‚aΊ)}κρ­΄ΓUYv1Π q‘ΫόϊΣοΏΠ΄‘‰C+)κvyόθΡμ¬Φ5ΥoŒW7yq¦νŸZ©}£ΝoΌn²­Ζ<©F¬x²ήa­I&ΦhζΪc`2ΐoRŽβ+m Φ?ψ@\) Ιύ?J…΄}5n ›jL.Η1αzg―X©nοxΆΐ‚εόΌ©ΘΞqΦΊTš-GPϋ«₯νΊ'kM ƒκ}½ωͺz-’[ψ’efέ žχ-μ8k‘>‘ⱡ*ΒΉθ$ύ9ό©WFΣ€Έ6‘jDήtδ-ιšO ά |BςJ@’pψ?νΖ³#ΣnδΏ6‹ yΰΰƒΖ=σιο@Ύ…νξυHexν€R=ΑM`“ώ¦Ÿνy~~Ο'?/N΅sΓ°΄z€Rcz[:ΆFAȚυχ²Šl:M¬Οͺݘ<αΉ#EάΨυ5_Uş‘, νgϋ’ΐΦφΉu ii9ΣbΊ†HWl¬OμΦ~―q;ιΆqΆž––ζMρέz玽σ@ΌΡ4λ ―.χPd ‚Š©“SιΞj₯Ξ™ †­7wμΞ‘T\δvγλRxΛώC²ΊΏΚ€ρωtrηΩ(OGh/€u•ώΥςƒί” uΝsu»γ(άkR9VΨΚΈlpx¬*»€ιςjW^R0Es»tUυ­[mM½ΈYj,ςσLnΚΣ<,<Ψυ+T O4Gžύxύi<5§]· <F±]™HŽ”ηίήFfZΪ» &aΨ?>*c€YέA+i7<±.ζ‰Σiaκ*ωFΉ²ρΌ΄βθΎΡΥ—wXΥ?E"jMrΰ€ΖΖG#qΣόϊP!š7ό‹ΪΟΡ?™¨¬΄Ϋ?°­ή‘z"G8Hγ˜ύ}*}$ƒ kD °γρ5 †ΛM¬ξ$²7“\Ϋ™ˆTφ e_LŽή «IόϋY²ˆΑv5n]ΚΦ iο/š8ζX(L±$dώг―3?†l™ν’Ϋ3dDƒ 6?Ζͺx£ύ^–?ιΥhWYΦΘΫΙo7Ÿop3ƒτύjΫθφ6kjwζ+—Ψ‰Έ'Φ€ΈuBΠ€“OΠ53ΕRkMRKΑJ2)`xP2ΆΉ€™ £ ΌΣ0bH遌ωΦEtž)…ντΝΦ$nz—Šζ蒊)QEQEQEQEQEQEQEQEQEQEQEWGΰ νΠ]XΗ¨iΧΘ©qlςχm9Rr9ό뜒€;ψKό)BGώU₯βh„ΏΒŸτ$εZ_ώ&Έ )θQxχIΣ·Ο xV; Gc$W/$ή^α‚BpkΟh’'…SΦ»ύ%ζπ¬χ:η|g’©EH†$*Ÿ™ŽΠ­|³EoΕβJΓΕΪΦ‹s-”χΙ/ΛƒΓ1m¬AZΤρΔΟkΦ/g{©΅uΫ$pF±οδ γΫ82ŠίΠ|]h:mέ†“}φ{KΌωΡωHϋ²6žYIzU― xχΔ^·{}"ψ₯«Ζd@}FG…rΤP]ρΕwϊ}ν•ζσZήdL 0 ·*0BχΕΪεχ‡`Π―ΌΝ* Ύ\R »z|ΑwΎ΅EoΪxΏ\΄πδΪ ½φΝ&mΫΰςη''ζ+»υ―OψWc ώ?πŒxΞγJ֘ζ{;ƒDBB0ΙΘΗΜΦΌFŠϊ3Εϊ­·„ώkn­βΦ΅νSx%Hέ—PŸt΅UW۟­|ηEQE{EΊ†ΛQŠβtgHς@\g8βͺM#M3ΘyΨ±ϊšebφς{Ω„·O½Β…Ξγπ₯ϋuΗΨ~ΗζfΫvν…AΑφ=EV’€4,5‹λό»iΚΗΧiτΝEu}q}p’]Κd`xΟ}T’€:wZΊ΄Υζ7 ΔΚ§ 3ŽΥΞέάΝw1–ζF’CάΤ4SNΣ\Τm ΓpDc€Ccιš₯5ΜΣ\ε•Ϊlηy<ƒPΡH sβ-PΓεύ€γέ΄nόρQXί₯ΆŸΧ (~ΐgœύk6ŠUbŒI AEj·ˆuF‡Λ7GΖBίž+&бky=«H`“i‘J9ΐ9―ZάβΘΪoG/ΏfήυΟZ―EhXkΦωvΣ•ιš†φϊζφa-Τ­#Ž™ΰ ͺ΄Pχ—S^ΞfΉ}ς8§–κξ{₯ˆNϋΔH8 ;qUθ  !«άΙ0]·Ϊ-Qƒې;nΖjΧφ¦—@TΏηό+Š`l[½•ξͺ†3ύ–>VVέσφ9γύjΫ·[ΘncŸUΥ`kXNΰ«&wžάcšγ(  ―2js^Z»Dο#8#МΰΤ—ΪΥύμ^UΕΑ1žͺ (?\Vu€± άπΫΝOΆ)±½pq¬Ψk7Φ1yVσ‘P¬‘€ϊf³¨  —šεδB+™Œˆx΅ΥάχB!;ο Dΰ (νΕW’€,Iw<Ά°ΫHω†"J.λ]χ‹ouˆΪΨ¨Θ‘φ”=ψηΚQL ΟάDΙei Βv·BPrŽ3ΟαXtQHŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ŠέΏπμ°θΊΕœιye 9pmδώγδ{ώ#8TQEQ^­¦jמψyαˍ 㢹Ԟιξfς•ΩφHFX1Imγ›­L΅‹ΚκZDγdŠ"Dx½ σ `yUθα bž6*™ΰ6•) {œσTA£άx’(ΌEiywbcέZ+3ξΗ Ξ:τ jŠΡΌ±y―/δΣ,ξ͌S0RΡ’c]Ηhr:b ½°Ό°1‹λK‹c"ξA4l›‡¨ΘδPZ*λi:ŠYύ­¬.ΦΧσŒ,οcΧx?Γ~­ΰ/jχboΆiΚ¦ ―…δδw бggu}7•em5Δ½vB…Οδ)·v·s˜o – —¬r‘V h«V:uξ ΜΆw7%~π†&|}p(‚₯Z„3YMdΫ‘Et-τkoό9g{gd!Bc»VWίΞH Ξ:uχb€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€;†Ϊ?Ϋύ—ΚώΜΩ΄¨ς{ξχΖqώΔ?ΩίΫWΨΎoφ~σεyqώιžqŒΥΛK6k£Ωΐ–vQ€ΣˆΫ&βOοΉώC·ΰ1…@Q@«Ι4πOύΏθα\ΕvΪf“yβŸ‡ž·Π’;›5ξ’ζ5Q“|”αˆγό+Π+&"⩁ΘWO€Ι4ρ·ύΈθγV?α\x―ώ_ω1SκzMη…ΎxŽί]Hνu'΅Kh|Υv}’c…'ŒP”ΧKπίHƒ^ρΖ‘§]‚mε›2/χ•T±Žά~5ΞΔΚ‚RDyˆ wΕwšΞ₯αΏ ψΛEΤό <χpΫ*Ι8›p έ ‚ΐ•'<`fώ)ψ―ι~5ΈΆL6ϊ>pm’ΕbP²*§'ΑιŒqR|3Υ¬΅ί©©iΊφt7ΚΝpΐ>ΞHΐO?RjMFίᯈ5¦ρΖ»5’Jβ{8ΐw3πX όηκy™αoxrΛβίφΔ0&‘ €Oabcό UA9'ςβ€:?‡z“θώψ‹¨ΕrΛmred]ΰΆG±Αό+αΕνηΔˆ–³x²q}Ÿo%ΒΖΡ"©ΑR` ©‘xŸG΅π—,§»Ωs©ΚZΡ<§>`Λw¨λŠζ~x ψGΕvΪ›Fe·ΑŠt^­uΗΈ Β€:Έ~3λΓΔour#ŸFve:nΕUςΟnΑ9Η~*πΝ­ηΓΏ‰7:}―Ψνf*ρΫξέ僓΄n)±iί ­΅VΧ[’βΘ±‘4Ÿ³Άwό§»žƒΗR+7Gρn†žρΥN“T`ll6#hΞ@ qŽ€Puαν[Ύθ‹ΰ©4ϋ=CQŒ]^^\²‡ €UW*Aΰ㞘υ9ͺ?tΝFοα\·^.}>}{N<››gΙ2©xπ8ΰζ4kΓ>.πf™ x²ϊM+Pς–—«τd?Βp8ΰΞ>θη΅ex?ι~‹Mπμ’κΪΑ“tš‰άŠ‹Ζ@θ88ηœΠ[ρ ΔwΏν4_ ψQ’Λm’\άά՞gbG9uRIΗ θ+Žρ?Œ’ρ…ށ-ʐkξ±ά]£ \ ŒeqΗLυγ&Ί[SΒ?΄-όIͺΎ‹ΨΒ –_+rΞƒίυ g‚OZη|i¨ψNτK @ 'VΉΤ^2―9{dާ§~:PίΪώJ4Ώυλς5ζuάόdΧtοxΦKύγν6†ΠI±“F\5QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEWk€Mcβ­2ίEΤLVš΅Ίyv˜Ϊ²ΡIύυλΙκW:uμΆ—±476ΧFκωο@¨’Šμ΄YέhVϊΆ»G€Ϋ];₯°ϋ3Nμ8c…#*σxOΏ·|3βHυ]B42 F³{v‘G]₯'Ϊ§ΥΏδšx'ώίΏτpvΦβkK˜ξ-€h¦ƒ#©ΑR;Σœthέ‘Τ«©ΑR0Aτ¦Χ§ΒΗρ_ύς^/ώ&₯Υu;Ÿ|>ρήΉε\^i’[=½ΐ‰QΤHϋr qσ€<Š*ή“§άjΊ­…’y—72£_r{ϋR₯Zτϋ­WP‚ΗO…§»ΆΗυcψΧ¨έ|=π~Ÿzš&₯βΧ‹Δ.αaΜ !+qψ°?LΥ]SΑ αŠ>Ρ¬u+¨εΉH¦k” t{<Ή7Ÿ”p2(Ν5 +:φ[Kθ^ ˜›l‘ΈΑSθj½{§Œ<'α ΏίΗ―ψ–[mVώ}ΡΫΑV-Ψ ˆ#'ƒŽ:ώ5ΙιΏ Ώβθ7…5K©/-₯Kˆ@Χnε89Η‘ϊσz½€iϊΝΓΑ₯ΪKu2FedŒd…ύ9© θ0κ^:·Π€šD‚KΓld\n3ιž+ώθ©£|\ρm#J–φ3B&?<}qυ ’½rΧαηƒοo›B³ρlβ%paύΓH:¨8ηπbkΜ56ηGΥn΄ϋδΩsm!ΗlŽγΨυJŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ΧH†ΗΒΊeΎ΅¨ˆυk„σ,,σΉc₯“ϊλΣ“Τ/nuΩnοei%mΞνԟσΪ«Q@Q@«Ι4πOύΏθα\Εih>1³΅Π­τwCVΆ΅w{cφ–’ήrΓ*A<ΥίψKό)BGώU₯βi]>“$ΣΖίφ㣍W„ΏΒŸτ$εZ_ώ&©kή1³ΊΠ4 CIΆΊt{“φ–₯Ψr£,<Π$2Ojοό§έψSβo‡ˆν%±>WΟ\gz²©Ύˆϊw7hδWF*κAuWCͺxŠϋΕΊΥƒψ«Rs …¦X—χQη– ΈΙξ{*@t7π7‰'ψ…©A›uqφΛ·–Φ61•v$ύη=1]ηQ£ψνΰ΄vάΛmn₯½H–^jWΡ|U$k‡ρO Ί€·ά)™Έά$χ‡α\/ŏC7Δ  ^+eΫEW*©tflŒδσcӊκό4κΏ΄–¦€,Σ“Τωyώ†ΈŸ YάΩόcΣξήXꄁ"Θήyκ+•“Δ€ž!:αΌuΥLžoΪ;Ίgψc§«ψοΔΆ­¦κw—¨ΧΪό{Κ° *sœ‘ŒΔb€'ψ΄Μ>%kΜ ά.x9ιΐ―dΤ&HΏhν,Hpdӊ/ΉΫ!ώ•σΖ―©]κϊ•Εώ£/w;o’M‘w Β―jή)Φumn^ϊωίR„(ŽtUŒΣ‘ τέψ7ΒΪΚ|eC.sVΧO$­AέΠηŒ}k­πB—ψύβεS΅΄ΐCΎ*σkΏŠή1ΊŽέVΫδ²Έ)cs[εηι±mΙ¨ΛΖ)-Όsu©–±ρy]KHœl‘DH£‘P>aTuoω&ž ·ού+˜¦@ώπ‘v)γb©žiR’ΉΟ5CΔΆ³Ρ%Υ΄=j-^ΞήEŽγ4nνbr γ?ύ|gWO€Ι4ρ·ύΈθγ@qW­4}Jφ=žyqΰΙ κ?1U`ζxρ›σέσσσӎyφ―’ğξFŸqg“α.UsΘ›XΉωIΈΗ֐:E²Ξ°E36Ρ©,O¦=jδZ.«7εi—―δ’²νΞΒ;7~5μή4³·΅ύ Ό;%΄h†λȞMΛ2ηςQTΎ%|LΧτO]ΨhrΕiee /%XLΔbδŒςIθGη@YαXμdρ„zΔΨ4‘fŠά#@=}9§xΎ=>ίΗ£Aso§¬˜Š+DŠ03y랼γλΪύ₯œΏόβ EΏφΕs,jψ9ϊΓ?Jσ‹_ςR5ϊω?ΘP#EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPνˆ₯›@΅ΡμΰK;(ΐiΔm“q'χά!ΫπΒ’Š(’Šυm3IΌρOΓΟ[θIΝΚχIsš¨ΙΎ@ΚpΔqŠƒώNJθ“ρUζSΣα\x―ώ_ω1SκzMη…ΎxŽί]Hνu'΅Kh|Υv}’c…'ŒW”Ρ@4kΑ§k7₯<ΑmΣ-υ­DEw«\'™agΛν,ŸΠ^œž‘{s¨ήΛw{+Mq+nwn€žΤΐ­ERΡυoω&ž ·ού+΅Έšζ;‹i)£`ΘκpTŽυΡjίςM<oίϊ8W1LΏώ?Šθ+’ρρ5.«©άψ«αχˆ.υΟ*βσL’ΩνξJŽ’GΨΛ•Œž•ΕΧO€Ι4ρ·ύΈθγ@tˆ:’)gc€ d“θ+Υα…τ­-όmβIlυk”φ{h·AιΌν?ΣΏ¦kΟ<3q §‰4«‹’έΕ$„τ ϊWΉ|OΦ-΄Ώ8»π¦·* ρΛώP1ΒF1Œτχ€šλΎΆπ׌΄λ oPfΠο€x΅Cΐnr3ΧƒšΡ? ο?αcΒ?ζΏφnί΄ύ·h_MΩω~Ότ©>/\k‹xkO½πδzAH™,ΰ†q)u}€.Π2Έ _jυ#o7ό!ƒΐΪγώίμ­ΫΈΞά«έ鏗ΧΠ‹hžΣ|Cγkν3JΥΤ7·,»•ΙΞ=Ή5ΠEπχΒΎ ³ΤΑž#Έ»Τμγ2˜n"Ϊ²θvŽ γ<φ¬ο…Συ+ΏOβ ;›―μh|Γ§ΔHy\nΚΰrHیzšτŸ„ϊΌ±ύ—ΰΛ]Κ^μ.d-‘ˆχmδŽzP—ό9π%—ŠτfώχRk°2~πεͺK3}>•·mπΣÚξ–ϊ‡†ρ鎡꺏‹/|9π·Αsθ:„q^)‘%@UςΉ' §>ΥβΤPGβΟkή+(5«ζ–Ξδ…$j}p:Ÿs“T―όCͺ_θΆ:EέΧ™§ΩmβςΤlΟ^@Ιλܚɒ€;]βŠ΄-=l¬υφΘ»cYγY<±θ Η±βΉ½wZΤuνEο΅{Ή.˜½ϋΠ8ΨVuήΩ|Zρ¦œ-#ΤΓ…VYaGχˆηρΝqZ…νΞ£{5έτςOs3o’IK―EQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEVν‡e‡@΅Φ,ηKΛ)YΜkƒo'χ#ίρΒ Š( Šυm3VΌπ·ΓΟ\hO΅Ξ€χOs7”Ο²@ͺ2ΐρŠKoέje¬|^WR'$Q#ΕθθT˜SΚ¨―@ψH»ρ±TΟ΄©Iά皑β[Yθ’κΪ΅―go"Ηqˆˆ· v±9ρŸώΎ8κ)T`Oυ‘‰«KpπG¦_<ρ€^5·rΚBF2)E=’‘%1:2Κ„`ƒιZΊ4MTΌ¨4Λβρ.ι[ΎPuΙγ@τU‹;;«ιΌ«+i%ΖvB…Οδ)·v·s˜o – ‡XεBŒ?@ΡWγΡυ9%Ž8τλΦ’DσV%—ϋΐc‘οQΑ¦ί\]5΅½•Μ·+χ’H™œ}@  ”T—Km3ΓqΕ*2H₯YOΈ5fΛJΤ/γg±°»ΉEϋΝ ,ΰ}HJŠΉ¦iχŽ£ΌR΄αHD,Tg=+§ρŸ<-βX΄ω{Λ2b v 1¦XύάδŒώ4ΖQ]χΔΟ ΖRι~²½Ή ŽBZVƒœΰ{W ,o ¨Ι"œ2°ΑЊevΛJΤ/γg±°»ΉEϋΝ ,ΰ}HZ(%–u‚(€y™ΆˆΥIb}1Χ4,ΆσCp`š#œ¦6RLu₯»΅Έ³˜Γw°JJJ…[C@ΡWtJΦΨ\]iχΫœbY eSŸr1Th’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(±ψgύ£ύ±/Ω|―μ͟ρ0ϋGϊ'Ύο|gαšηόCύύ΅wύ‹ζgο>W™Χαž™ηΝ\Ώρ³hΊ=œ ge 8²n$ώϋŸδ;~TQEθϊ·ό“OΫχώŽΜWm¦i7ž)ψyαΛ} #ΉΉΣ^ι.aσU7ΘNŽ1PΒΈρ_ύΏςb/ώ*˜…tϊOό“OۏώŽ5cώNJθ“ρU>§€ήx[αηˆνυԎΪηR{TΆ‡ΝWgΩ!f8RxΕy¦“![?ϊμŸϊ―qψΧγνgΓΎ(MΠ&K!ε$σΚ"ViXδwΐ +Γ΄Ÿω ΩΧdΠ…{οΕ½7ΑΪ׊„Zξ³.©ΫB›Κ.“Δyτa–Π™ψ€πψ‹Γ~ ρƒA:έΐΆΊςΧFV#?š6=΅iόqρΞ΅£ψ–MHž;KW·Vœ¬JΝ1`AΙ ρ΄Εr~>ρnx|?’xs̐ΚΒiƒ+de±Œϊφ’xιY5έ;Δ^5’FΈϋM‘‚4ld䑆Π[¨λ3ό<ψgα¨ό:ίSΦ£7w†5gΫ…;FF?Œψχ9€ΉΤeψƒπ‹UΏΦ)5UhξΒgCŒƒŽ:nγ§Υ ZπΟ‹Ό§h,½}+PςΆ—’=ΚΘ{ΐGtΤ>(Χό9‘x xBκmA―&ήήΊ«œuzqŒςs@_ΔοjώΡό)…2ZΛqa’Νε«;UΪΌƒΗ,>&xγUΡ΄ j:'Ωμou›D»Ό™!ViDΒδƒΐάk…ψ―β/^·πι7^{YΨ,3-“c€8ω€ΟNΥčLΦ|?ΰΫm6ηΟOΣ– •ςΩ|· ƒ ʞFEtίνΧΔ“|<½ΈDŠχZ·Ž;‰#\d“?†φΕwž&ΣΌee}meΰ›­#KΡlΡV8]Χt‡’ΰ©ΗαΧ―~<Ζή(±ΊΠόΊ=Χ™}€[2˜ΨyR ʞ™ι]΅/€όw·­Λ‘jm‹Λvˆ°r2§' σΐ ΠψŸ-΁βο λšsΑg¬j˜o©WF`P7Qίv3ΧU_ϊώ© δZΪΫϋ+uΌΏgڸݜη8Ολ\'ŽoΌ3Ήd|hιmh«ΎyYΏcζΪǁǢI9TτΘ \ρ6γ++λk/έi^‹fбΒ8—N?½{ρ…βύ:(~(x Shν’Τ―€υm˜2SnOΏήΖO`+Z—ΐ~?»[ΏΦεΠ΅6Eε»DX9SŒ€yΰrϊώ·α+ΖZ5η‚με[M5γyfvlέ ž§I'πυΔr(Ά‹n3Πν1ΐγœώ΅σ“X‚x΅{†/Όΰ»­_MρMζ ²#΄θγa»=qŒSŠρ;ΩώΥy<ϋ?6F}‹Ρrs@ΡEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE-΄¦ήζ)”cpΰψ9­ίψ’oλνͺ\ΫΗm#F±ωq±# ߚηh Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Šνt‰¬|U¦[θΊ‰ŠΣV·O.ΒσVAΪ)?‘ώ½y=BΚηN½–φ&†β&ΪθέA=θ΅Q@–ƒΰλ;­ ίVΧuΘτ›k§tΆfiΪ]‡ p€`Ε^oιχφσ―†|I«¨F†AhΦon(λ΄±δϋTϊ·ό“OΫχώŽΞΪάMisΕ΄Ρ°du8*Gz`sŽ²:•u8*F>”ΪτψXώ+ ―ώKΕΔΤΊ§sβ―‡ή »Χ<«‹Ν2Kg·Έ*:‰c.T1ώzP•ΡO†'žhβ‰KI#UΙ8½jγαί„΄[»]'ΔΎ'ž ruRRun™$=ΙΌRΘ¨¬x"ώo·†,η‚ζ0¨Έ³ΜgyΖqΗQλΕvQό<πuΞ¨ϊŸ‹e.PξL€rΉΖ3?yhθ:.£―κΗG΅{«’₯φ)ΤδwΎψe©ˆΣZΏ:uΏ0ŠGγΛ Ιf9η3Ε[π†‡‘ΙρM²πg‰5-―o)šνc«x”ϊΠ•άΑ-­ΜΆχcš'1Ί7U`pAόj*τό=ƒΕ‹βk‹½RX'°Ί+ηI‚€nbΞωφυb/‡Ύρ΅ά> ρ$·Ί΅ͺ ½Δ[ΐtΰ~|υΉ (’½Ώΰ-žŒ4ύqε»Έ]LΪH—PΎX’οŽO΅rZ‚4―xΆ{?jΣ6‡kn../n"Γ(ξΰsΧ =’½/Rπg…/΄-FσΒ>${›­=|ΙaΌQ‘{μ$/?Ÿ§―4 Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ΧH†ΗΒΊeΎ΅¨ˆυk„σ,,σΉc₯“ϊλΣ“Τ/nuΩnοei%mΞνԟσΪ«Q@Q@«Ι4πOύΏθα\Εih>1³΅Π­τwCVΆ΅w{cφ–’ήrΓ*A<ΥίψKό)BGώU₯βi]>“$ΣΖίφ㣍W„ΏΒŸτ$εZ_ώ&©kή1³ΊΠ4 CIΆΊt{“φ–₯Ψr£,<Π'g³έΑ ·ϊωR?˜/ΜN'Οzχ;½fβχX²Π~#x%o―έV1{j2εN9}3Ξƒž+Α«½²ψ΅γM8ZG©‡ 6¬²Β οΟγš@w~ Ρ,<ρΚοIΆΈΜ3Ω0ΆσY‚Ά}@VΗΆ+ΛνΌβ+ŸΆŒΆSAd!ΓΙή_8Θ=λγSΎΈΥRšξgΏi<Σp\οέΨζ»>-ψΚM?μ‡T¦e…„½Τs@G„μ.4Ÿ‡Ÿl.δGΉ·Ϋξ€9οιX?³ό”»?ϊγ7ώ€k°ρ&­a₯κ:u­α[MGώ>’±—ώA#―b*/λz‡‡΅4Τ4{³ή"•Y6+ΰƒΓ?Jφ/‡Φ7:Ÿ…~%ΩX©{™¦tGV??Λψτόkψ’jqψϊ+ι`žΪΒ9MΛΚ…e …9ο’=ͺΧΓmjKO‡ή8Ό«€Μ“ΖΫ‚Ή~N@ϊΧ/―|Mρ^·¦΅…ξ€VΩΧl‹ k΄@Οΰ0 vηŽϋΕ^8kL0Ή΅αAՁsŒΔ~uΛό.ΕZN½{u iώtΆΦδήZά|…β'8ΪH$Ό`~Ός:΅¨θŠ_θχOkt ¨uΑΘ=A cZχ<ρή%ψΏς΅1‡ΜŠ5PP \`―τ IΆό?ρBΦ?α—ΓΊ”/0Έ+ 0ΙΑ࣑ŒZπκμόIρ/Ε!°{+ύ@-€ƒGkqξG8φΞ+Œ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( œˆΞΑQK1θΙ¦Υ½+PΉ΅/¬€ςξ!mΘΨΟ±B2(₯8#f J―R»Ω4+?mΤ΄·±ΊΟόL-$m«¬©ώΟ·jΜρ.³eo§`xtΔ΅X5ΕΛžξAόGΡAθ)ΙΡE€υm3VΌπ·ΓΟ\hO΅Ξ€χOs7”Ο²@ͺ2ΐρŠKoέje¬|^WR'$Q#ΕθθT˜U[ώI§‚νϋG ζ)Π?„|$]ŠxΨͺg€ΪT€ξsΝPρƒ­¬τIumZ‹W³·‘cΈΔ Δ[…;Xœ‚xΟ_ΥΣι?ςMc Τ Ί9©όx―dψαβmbίKΠl‘½uΆΤtΥ{€ΪΏ½''ŒΓ€ρ{«;›AΊ·š"ξC"ά=FzŠsΨέ€0Κφ³¬SœDζ2‡ύ“ίπ―NψλΎ °Z%©jg„τe~Σ<·»ΌΛU΅`Φΰg–9>ΐFΞΞκϊo*ΚΪk‰q‘sω φοψΓ^·ψUα{θu[½@H—Rl_ή ΖαYϊ޳?ΓΟ†~Γ‘-υ=j3wqxcV}ΈS΄dcψΐο€sšρϋ»[‹9Μ7KΓ¬r‘F©α΅ –†ΒξA>|’°±σ1Χoώλ:ŒΏ~j·ϊΪE&³’J­Ψ@¬θqqΗMάtΰΠΤ|S¨x[ΰΗ„ζΡΪ8―.Δ'dΡ¦XΉγ’ε@y5†mπώsu¦j‘x–;―,ΜρΊΔ£#ε9ΰv<ηΪΉ›/PΤΪΒΖκιSοagΫυΐ―UΎΤ.΅_€—χΧς™§ΥχΙ!n?/8VξŠί.Ό-€Eαλ-;Γ:uΌcχ’Ί΄qΓΑˆΟ^y9ΞhΒν­[ϋN[€xΨΚ±Ί0ΪΓ'ƒΠΧUρoΓ–>ρ„šn–%yΈδƒžkΈψαl«ΰ»ωώΜϊ…Μ{.f·ε$d1ςq–l{W?ϋCΙF—ώ½bώF€<Ί( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Η#Η»Λv]Γkm8Θτ>ΤΚ( Š( VΣ4›Οό<πεΎ„‘άάι―t—0ωͺŒ›δ § G¨?α\x―ώ_ω1^aE0=?ώNJθ“ρU>§€ήx[αηˆνυԎΪηR{TΆ‡ΝWgΩ!f8RxΕyMW¬x»WπΏ‹ό§]OͺΛg―iv"fb;ea€pF9οΝy=€φYu_xΧšx—WΉυM*ά@ϋb-ζ¨daH9Ϊ¨Ιβ³~)x›Γš·ƒΌ?₯ψng+`μΎLˆα‘Β’ΔIΖx'­yeλzΏ…όKπΣMΡuέV]/Q|Ζ‹Yz㐨ŽA¦θϊΧ†|]ΰ­;@ρeλιZ†—•΄½ξVCΨώ8ϋ ζΌ¦ŠυkώΠΌ ?…Y›Ίξμ}+;ϋ:σϋKϋ?μύ·—δνω·zb«+20d%X‚5ΪΒ{7φo™φ8Ώα!Ωφν<|ώWΣϋύ·zSΕ,:Άφ†ρn5„έGωanΛ»Ήυ¬:s3;rY‰Ι$δ“M€^ŸρgώJ«lΏτRW˜W§όY’ͺΫ/ύ”Π:&΅¨hwfηJΊ{yŠν$A„A­οψXώ+ ―ώKΕΔΧ!Et ίθ^Χ&Š%Τ/γΈK— rV qœΟψaα{/kΣiw·S[HmΪX<|ΞΈωN}‰?…_ρίό“ΫχώZη|¬`ψ»IΤσ„‚u2φΚψι4Ρό-πψ»YΤν5)¦³ŠΑΖα!lηαoΚ£π?Zρv­€κ—Ϋ[ii+\Oo^Oα^Ÿρ Σαώ¨ήιδyϊΖ΅Ϊl8ωl„}7+ίu/Δ4΄πη…|W―YΘΎo‰|ˆ‘ηψZ?›Pd4€Απž—a«|Ή‚χPώΟΣSidΈ•w2Ζ1ΥυΜλήΠηπ}׈<­M¨Γdΐ\Ε<{X91œτδw«p?gKŒΊ Οζ΅Β²OΓΟˆΛ“gΗα-Sπί‚΄αxuοkb·Ήr[ځ$§ήΖqτΗύ*/ψNΠμτ}gJΥZϋΓΪ„‚?<¦$ΧŽόμ9Εt‘iΎπwτV Ώˆ/υHΌΦ’F>L'ƒ΄π@?6ΖN5sβ΄²Οπw@–}"ΙΉl’]’5+.8γŽΠρ¦ŸαψcαΨξ5{Θμ#Y ŒΛ-;`πΓo₯yχ‚ό§_ψjηΔ~(ΥMΡ’—ΘO*=ςHάtΰρΞ:ύ1[ή4Άžσூ䴆I&“Μ1)`Ÿ{:t5Sΐz§ˆ4άάΝ Ϋλ^Έ˜‡†V Uϊ’Λέzΰp ―x;G΅³΅O λBK½˜@Λ.xΫ8ϋΌ:φγk?βw†-ό#β—μη–x–“|Έέ–ϊWgγ/θ/α7Ζ:N™s‘ΏΫ&³›8qžͺΣ#gŠ>&πŽ˜——-³rJδ.c-Œνγί½kjŸ| κ¦λώ*žήφVύΚ$Y‘ϋ¦C΄€O^έιΌinφŸ>[ˏ2£±κΈŒ^ΥΫβ^ RΖζa}"½»Ga *ΑΗ΅sž=πΧƒυΣ§άΘ³Δθ%‚t‘θqΨρΘn½[γ¨ϋ$^%Y5 5R䃓œ(ηρV―) Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ½ _ι:ŽΙυ Η¨μT–ε/δ‡ΜΪ0 PΞyνίΒ_αOϊ?ς­/Gό%ώ‘#*ρ5ΐQLΖ&Ψ`΅±OΣ¬Q’ήΩ$2mάrΔ±δ’qωW9E€ΩΧόO¬x† u‹ΦΉŽΙ pŠ»@ϋ£““Ε―‰υWG°΅ Σ5…ˆή-Š»€ γŽI¬j(Y|Cͺ/‡A_ρ*i|σ–ΏΧv7vυ¦ιZώ₯₯iϊ•ŽŸsεZκ(#ΊO-[ΜQœ HϋΗ¦:Φ]Χψcβ7‰Ό5b,΄ΫρφA‘MΘ?έΟ#ιœU/ψΟ_ρŠΩλ:‹][,ήz£Fƒ‚3Ζ γ8vŠιό=γ―θ\Ίv›~VΖ@ΐΓ$k"ξ€n˚g„ΌkψOΜ]σΛ†CΉαuŒqŒΰτ<G₯stPCβΏλž+xΞ·zΣG&8•B"PsΝiΨ|NρmސΊmΆ¬βPˆΝ3’ϊ#5ΕΡ@ο„όO©k<-.»|²₯œρΕΊ’@{~¦·όiρ7Δz/‹uΛSŒΨύ‘Ό’cI6dv’|ϊŠς:(Φ§wͺ_My¨\Iqu3ny$9$žέͺ­PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE©αΝ*=gRMy€²!ςZQςΌžΩυ  Ί*Ξ‘es§^Λi{Cqmtn žυZ€ (»α=Ύ£ρGΆΌ‰e€»ΉF¬lΓ#Ώ*(‘’½AΎ$x§qΩ©*.xU·‹ =ΛMΤ‡‡ΡΎΖι~Ξv͘˜yGΡΈγρ  tUΛ½.ώΚšςΖκή'ϋ,,ŠίBG5₯₯Εμβ;yn&<„‰ ±όAEYΎ±»°”G}k=΄„d,Ρ”$} v^(πƟ¦ό8πΞ·l&ϋn Ξ&άω^3Œέ(„’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(₯ΘΗZJΤπ櫍© Φ³ŠξXΠω+)ωRNΞG|zP[βΜΒa ?όŒ|}›oϊί#ώ›~ΈοWŸUBφηQ½–ξφVšβVάξέI=ͺ΅Ϋό’—£ΫoύυΔW]πžϊίNψƒ£άήJ±@Π»Z6Q“Ϋ–FŠμῊwšjΊη†[ˆ°ΓΤ|ԟπcEˆ‹,½qΘΤΗ ΠEπ»EΤ,Ύ6©αe½¨ΞΙφ«ΆΙ‰I\.Aη+œ\φΕikVΉ¨|8Χνόwq¦ήάΪBΧV70:™•Kp£Π:‚Eyχ‚όC j^ —Β>/š[;uŸνw±¦ο)b>­Ο£œM~Σΐ†.νl/$ρ·><™ΐhίߎ~9ΙΕuzŠu |πœΪ;Gεΐx„μΪ4Λ·\6AΗ°ΐΙγ5‡πΔ:_‡―uΉ5‹―³₯ΝƒΑςΩχ9#εkψSZπφ΅πβ/ kzΜϊ$φχ 2L¨Z9άpΨκ>n„Ž‚€:Ώˆz€ί/ŸΕ—Z~‘«XάΖΡOlCVt\6ΑΓ7n˜OǟςE|ώόŸϋ5O­κώ ~κώπώ©-εμ³Η)’H]|φ…Šœ`žέϋαx·Δ:]Γ ι—^f‘dΞn"ςΨlΞqΙ={@}EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEΠΩxwϋKϨiwhΌΆ$έYνΓ’g‡_ο_Jη¨­_θwzφ -­UQΎYŸ„‰VcΨU}b KmNβ:ε­QΆ€Εvο㓏Lζ€)V—‡4{\΄μΚ‰ξ_hfθ I?@ ό+6»‚ςRτϋm’^€,·ƒΌ,ŒUόn»ΑΫ₯JΓ>Ηw5ƒβ \xvX$Y’χLΊ]φΧ±.Aάό,;Šmnh^,Φτ+w·―ήY·(3κ7Β˜κ ρΔϋ‡¨$ΡηζνβΪγΠαzW5ρSNΆΌ}«ΪXΔ±[«£ͺ(ΐ]Ρ«a–\ χ€ Vtλ­Jϊ;{©›dq Ιc^§ΓοέjO‘ZxΊWΧΑ1ŒΑϋ–uPq‚~W~ θV:Oξ-uyεΔVO,QΫ*f6MœΎμzc@mβ―λ~§]΄[o΄‚br98ΖxRzd~uΟΧ₯ψ§F·ρWŽm΄ί λΪ₯ΥΔ²›ƒx¬ΨξΙΗtzzZ1|>π]Φ€ϊ§‹₯}|ΜΉiU'θΤδtW’x#αΛk^%ΧtMZw΄»Σ’f1΄Έ ’>ιΘ9τͺ^#πί‡–λNΣ(’οY·Bβ9βΫΈλ΅°8χυι\ǁ</ˆξ―δΤ.—LτΡΊςζUϋ~QΫ<₯q΄W¨Οΰkz5υׁ5ι΅ Λ2KksFuJπΣƒιΕyuQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEwHΤτB+Ϋ LW‚:PGp}*•Φψ‹Ελ§›-"Β=2ήΰω·‚.³ΙߞΛθ+’’Š+·ψ/%/GΆίϊ%눭/kΉiͺY…3Ϋ>ΰ­Ρ~ ‘ψΠκ+ oψYΨ³ψ!w“·U•F}†ή)?α/π§ύ ωV—‰¦kόh’—¬Ϋύ•e|cαd`Ιΰ…άFνVVχyGΔzΕΖΏ]ꗁDχ/ΈͺτP ~θΏ Ξ>xχάOδj―μσsΏΔ “²«Οi,Qn=_*Ψό•«ˆΣ|CͺiΊEώ™euεXί€.bςΤοΗNHΘό¬Ϋy₯Άž9­δx¦ƒ#‘ΑR:iνvzΗ—β€Σ-~Ω&­Γk+΅Θ}Ε0έKΰ«ΛΛΪ κγS±[ Ζ‰ΔΆΛ(”!ͺύαΑΞ3ψΧ wΖ_`ϋ7φ’ησΌ„σ1υΗλŒΧ+’ψ‡UΡuƒͺι׏ wfwU‘ŽοΌNΰA'Φ€=ΰΕΜυ•^uΉŠ-Η«ο ΙZ΄μυ/ΕI¦Zό/²MZ)†Φ WkϋŠ`3ΊΌcν—ϋν«3₯Χ™ζω¨vωΞF:sι]Ώό-ί}ƒμίΪ‹œcΞςΜΗΧ3@ƒoo/Ύ"xςηR²[ ΦΣ±%ΊΚ$²ͺΌ8=3ψטό#Ή‚ΣβF…-Σ*ΕηΛt ΚΚΏ©‘£x›XΡ/n4λ׎{ΨΪ;‰VF‘IΙΙ`y'ΏZΗ‚8"€=ΫΕΪ΄6^1ΌΣ§ψkg}w,μcŸ’nC;;ηžx9«ΊEφ₯}ρηN:Φ—™wœρy1Ξ&  9 Έzη§΅y½‡ΕŸYiβ=LHͺ6¬’ΒŽκ1ύβ9όs\υŠ΅«ΎΉo'φ«ξέq"¬„δ`πΐŽœtγ΅nψMό.+““«ŸϋhkΣt΄7Ύ8ψ£€ΪΘ©©^Ϊ•Άΰ’ƒΟΥΦΌ"ΣU½΄Φ#ΥmζΩ~“yλ.Υ8|η8#{cbOjΟβΧ>Ϋ"κ¬ώaΈŒ;±Ž€ΣΆ1@^πOˆu½^[)`Έ€1‘η ǎűΑη₯zGΒY#O‡^,²M:ί[Ό·Ί=‰l‰ΣεύΖ#ŽH΅Δjί<]ͺi­cq©…Χd†•Ζ9Λ‘ψbΉ}[Τ΄ υ½Ρξδ΅ΉτΑΘτ πG± gπw‰n€–ϊλΓ μν€·…„‰Δ?.y\²€zgΥΰυΪx‹βoŠuύ=μou–² ²$¬~`τ$slβΈΊ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Ÿo+ΨφQ“@ ’­Oawn»§Άš5υd UZm5Έ“O`’Š) (’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š }π»C΄}KM±Ήπυμ’κΆMw6³kΗmjΓ D@…σΥ—Žr>v†)'™"…I]‚ͺ(Ιbz+θΝβκΣJŠΪ9εˆyk±€œ888 ŠκΓAΞκ.ΜεΕMBΞJθΨ†ΞΜxkΔz‘±ΈΧ€ΣFΑ§YΌΔώτ9ΖΰΧ„|KΣcυKHννΚήhεmεŒ,Π™fŽB:²Ÿ—ž˜―hΆ™l]ŸK†=>Y9™νsLη«Ή’p?*ςΏ‹πΜχ–w{‘ biz€ωέ΄ϊσΦΆΔBJ.s# 4βδ‘σ<ξE₯κ¬ Σ¬ωςŠΒΔIŽ»xηπͺuξz§‰υ |π”Ϊ;€7—βϋA@Μ‰–$.x!*σΟDρs§_ Ο±›;‘w< MΏώωΖj;Λ;›Μ7Άσ[ΜJL…C^ηβ/j°ό*Πxg^Υ'Υ ά–ν2 RΛϋΟOχύhΛlt½CPWk «₯OΌa…ŸoΧψnΪΡ|OeoΪέ½§œx"Sζ‘θ\ηkΩtVψuαm"/YiήΣ­γΌ•Τ}£Ž† FzσΙΞsW¦Ά‘Y•μa^‚­^Φ>†f ₯˜€ d“ΪΌ{β^«φΝyΰ€[x£EaΘY’Ζƒωpk”–βiWl³HλθΜH©/οu >φgžmͺ›ίΐύ+Jψ§Ur₯‘ž ©>fυ+W ψ·Δ:]Γ ι—^f‘dΞn"ςΨlΞqΙ={^}Erg{kϊeΧΒh\ξΤν.₯’x|Ά΄„Δm<0θ{Ρ«λϊeΗΑν C†ηv©m|σK–Γj&μm?xt=λ‚’€=³ΔWώ ρόv‘©ψšηH–ΦέcšΑ’,£ΙAŒdη¨ΟqLρŒ|-&Ώπύτ‹·]7Gb³oŠMΠ ςΒ珘αOLΧ‹Q@Η’ψΟAΆρχu)οφΩj6Ο¬žL‡ΜcŒ Θό@Cα΅§ψΗ6š†―qφ{8γ‘ZMŒψ%('―΅qtPmαψDυκσx²ξx΄Ω ²@Ρ+|μ_#8Ž2@Η_Θιό7ρ&ag―hZŝέί†o>y%Š=Οoƒ€νŽŸΓΟb+Ν«©π/uOsφH Ί³ΊP·· ” ώG“ως {ΒπU‡‰fƒΒ·ϊδΆμς\άΗ±aˆς”rI»Wœ|4ρ>“e₯κήρJΈΡu0΍wd'²œσ‚£Š±{ρRH΄»«? ψLЍ•škeωΘΗbΗλŠσZφM'Pπ_Γ€ΎΤt=b]s[–ŠΩDER έΨτμ3Ξ}†kΗ‹1f$±9$υ&’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(ηDπ}•Ύ•―βλΉ­-g­¬νΐ7 ύξxUχ=}ΈΝί΄ψ#ύWό"χ{:yΪζ}vύΪ`yΝήλž·ŸC—]π”χ7zt$‹‹{„ΔΠq’r8`3Ξ:{σŽ Q@V°πφ¬|’-{QώΣ“μz›—’μτxΟ*ϋΜA:~‡'Ε^!ώΥςl¬!ϋkΕ½²θmκΗϊύI`kΙ½§fGφ=ΝΒGh:4Σό"ί |;Ζ―y„k!±™`%§lmγτ -6δό›PώΥ½ΒΛϋG’NGΝλžώ•΅γKiο> ψ.KHd"i<Γ– χΊγ§CPΓ&ι?ύ…σZ―eΰ IΠ,5k“i²ίψ-mβ.αqœ°Α=Ζxγ¦sPψχαφŸαΏΪkš~¬ΪŠ]έ¬PΊ€’dvΧwΛƒ[4]G^ΈΠ΅έΦ{ύ.{γO³#IεIδ™ ?")œVχΗR~Ηΰў?²ΧΑkKSΈŠΧα―Γ;›’κδ'²¬„ŸΠPlŸΌ/αψm ρ·‰%³ΥnPIφ{h‹ˆιΈν?™Η|tΝej__LρΞ‹£Οx.4½UΤΫήΒΞ‡γ‘‘‘κ9|rΡ5Cρζρm§Έ΅ΎXΪΪHΠΈ`WhΗ|ƒΗΎ{Χiv¦OπŸFΏ\jΘ$‘ ω’S΄?ΛώhŠρ―‚ό'αh5YόCq6Ή-oh‘δŸ”HΑH―=E&Ÿΰ- KΠlu/k’ι―~»ννmβ/&Μg-Α#·n=sX_Ξ~$kωŸθ+Χ~$λvV±hΊ‘πu¦ΏasfžUγvw χN:‚=r}(Ιώ ψ)|5Ž£¦_.₯‘ί‚mξ@Αϋ­οώŠβλΦ>&κz”ώΡν¦π€:”χ>}ΎΙΑ9Ϊω_/wnΟψΧ“ΠEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP{‘ψήή}- Ε°\έιМΫά[Ύ&ƒŒƒΓž3ΣߌYϋ7‚?ΦΒQw³―‘ύžώgΣwέ―9’˜Ξ·γ +}*}#Β6“ZZΞ6άή\n.ϋΌp«μ:ϋsžŠ)· ψ§YΠ,―ν4›Φ·‚υvN‘Tδr2 2=~•Ψό(ΣΪβΒϊm ΕCGρ `±ΫLBE4`gœηw~άc§9―3’€>€Υ/oό9αΛγ_ZκZΆ₯fΦv––ςΨ0$>π$γ°δ׊―ˆuEπγh"λώ%M/ž`ςΧοϊξΖξέ3Y4POαοx‡@εΣ΄ΫςΆ2#Ywu#p8ώ\Φrψ‡T_6‚.ΏβTωζ-~μnνΣ5“E{o„4½\xZΕόγhQsyexκžKž»T†Ϋύzζ¨όYΤa³πN—α۝f=c[†φςxίxS΅Ζ νχΐΠtδPΆ»βS^K%ΥΎΠΆq ZΔΎP3Σ½ή!Υ/΄K"κλΜΣ¬‰h!ςΤl'9ω€Ικz“Y4Pk‘|Nρ^‰¦-…–₯›t]±‰’Y cΡI‘Θ¬)|K¬MβυΙ―€“UΔ‰;€ΫHι€F0=1ŠΗ’€.jΪ•ή―©\_κ2ωΧsΆω$Ϊqϊό+‘π·Δ/xbΧμΊ]ϊ'$A2 Iξ3Θό+’’€6|Oβm_Δχ‹s­ή=Λ *‹€ͺƒύ• Ζ’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’ŠνtŸ…Ύ2ΥτΫ}BΓEi-.I΅ΔIΉOC†`p~•%χXΪKsq‘Ώ•ξm—HΨφUrOΰ+κί‡kŸ‡Ύ°]―ώŠZΤΎR6•YQ›?(`OιJΰ| E}ρΣα₯¬±έψ›Γ(Q‘ZkΫo-‘H΄‹0{‘ί―^Ώ>Σ’Ί―‡žΈρ޲φΙ2ΫYΫ§›urΓ"4φχ?ОΥΩ „ΏhώΜϋ~―ζ³ϋ@ŸέξΞ3Σχۏzς:+¨ψ‡αό―}ŠIEΕ΄¨%ΆΈD?ΤwλΦ,N₯qjn`Σο%ΆQ“*BΜ€}@ΕQ’¦΅΅ΈΌ˜Ci³Κy cψ tEν^εl.ΪΩ3ΎQ \uΙΖR’ΆΌ! Oβ]zΣNƒΜEš@’L±@~"§ρW…o΄\ižMΝΒ€ήL3 vQ9dsŸ &€9κ*σi’Γ<­§ή 8•Μ-Ά3ώΡǍvZΆ•α»­Β6Z=ާiλΓηΪƒ)“{¨Κϊ·#Ž˜ ?’»xN]?Ζ:ΎŸ Ψ_\YYΊ¨d₯+”VδοX~±Pρ6•atCqypv³…?Cƒ@tW²x“Hψ_ανnλKΤ#Χ~Υn@-ƒ/*`ύ―8ρ‘πωΥSώ1x4(nXίζdηπΖΪΒ’―6“©-ŸΪΫO»˜Οœa`˜{ͺh#ͺ"–v8 I>”Ϊ*νφ—¨X"=ύέ²9Β΄Π²ϊdWOαΟ^k^Υ΅₯yβ6j­ΏΩ™Θ?έ9 4ΕΡRO Άσ;™ –xmζ’±ζHˆJ¦}OA@QWo4­BΖ$–φΖξή'α^XY} ΥX£y€XαF’F8UQ’O° Q^πΓΑK­x½4ΟYί[@φΟ2†V‰˜‚½2:sOψ?ΰΫoj·7έ΅Λι6Άν62‰˜6†{τ9ΰPžQ]7δίZOμ]ηE· Π\–ήΝ“σ|Δΰc= s4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEχWΓ₯‹yαϋZθ•­ΦZΖψr?βέψ[ώΑVΏϊ%ky–€g)ρqΰΨ2λE5|=_s|GρoΌO`»―ύΥπΝ4&zΟΓνρ|ρΔΆρτ̈όγχxύ Χ“WiπΗΖ1ψSRΊP·7Z=ό~Mά#“·œ0ρ’1ά]AΠΎ­ΐΤˆοMžνaςΫϋ™Ϋœvώ½ιΜx.ϋΕ3πξ›β ‹λ‹&oݭČΓΛUάU7tR+¨ρ_Ε}{LρΥΆŽπΫi:|ζΪ;! luC΄δγ#8μF+ΔΏ$½ρξ—­iΆΖ +lvΆΝ˜ΗήΞ:ΐ ήΥ­~ψ‡VΟ―άX$οζάιώCo.yl8ΙΞqž§‘@m¦“ggρΏEΤ΄θVu]:K¦Fr§'γλšη<;ρ'\Ήψ£–BΊ,—mfΆK …DΙUΑΖsΠυυͺΪΔ]*σβνΆ΅xνc’ZZ΅₯Ύθو]§ͺ‚rI?†+„πφ«eiρ&ΣUΈ›e‚j>{K΅Žy9ΐιΫ ΣDΈŸΓŸξtΝ"Soes¨₯‰TaΫyžΥwVΧυMC㝎—yvΨYκ«δDU@NΐΙόkΦ|OeΕΧρ‹›ΎIΤ…*]3€Ψ9ΖzΧMj^Oˆ:GŠτΝrI„χλ5ά/!@ε±·=GNzρ@Ύ1xηZoλ>Άž;}!Κh#‰yœ333’I:r΅Ώ‡΄9aH™ηbΊ–lq…ΟτόHΣώMγmNM{YΥνυ6dσ’‚ QNΕΖΓΫλŸψgανVψΦϊt“_h–›˜ΎΤ 4€aΐv=» εΎ(jΆZߎυ]GK›Ο³Η&Φ]؍Aα€=AνLψqβƒα[jm–ίkE'[BχC}I6Ι`²© γνΙ zž~•ΙψZ-Γ?΅ϋ2φΦ‘’Ɲ,€’‘Β6ΡΨ}β°#½eΗ£|/]HλβŸOήdaƒg?s goτο\η†―Ό7ŠuUΦtΙmt[₯)fΒGv΄= œŽ{ΰγ΅w~/ižΦ!ρ5­Ÿˆt‹”ββ=Έ·ΑαΐPΠτΐΗZƒα·‰΅ˆώxžT½q&–ˆΆgjώθz9όsLΣυ ψ ΓΪΔ_ˆ5ιο‘h’΄‘g#'°λΟ9>•Νό,ρ‰k’ψƒΓή$Ή’ΞΣTE rˆ[c ƒœκLps@©¨]jΊ„χΪ„¦k©Ϋ|’γλΕzχΑMDiρ–’aIΪΧdΙŒ©eV+ŸΗΗψwOπT^/Τ­΅έVytH£o²άƌ<Φγ#ŒφΑ#σν> Λ₯Ϋψ'ΖΝ¨,²θϋΥ%γη1ΓμιΦ―"‚ξ »ρή ϊb—B»π'Γωn5­/Y›\ΤΪ&[8<’Ύ^ξ2ΗΤπqœ Βψyβν-lυέΖΖ—¬7œΣΖ™1Kœξΐυ GEw<}¬ψ‹Δ“ιΊόΙ{ˆZxf1ͺΌd@ΰƒϊVGΐ=wRZφŸφ¦ϋŒ“ΑΡ„rs»8ΟηWΌ }πϋΐΌ“Ηβ5 ›„1ωg}¦s”’@ό»wβ~x‡Kπόž :½ΧΩΕΥƒCξΩχ9νςƒΖ€9 \Τ|AφέbεnΆσBό£ ΰή³h’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€;}#ⷍτ}2ΫOΣ΅ηŠΞΩqFΦΠΙ±GA–Bp>΅lόfψ€ζa?ψoΖλΟh ΧWψ§γ]_MΈ°ΤuΧ–α r’ΫCε=FUΑϊΧEQEQEQEQEQEQEQEQEQEWM xΆ}Βϊή‹΄REͺ#11θ;υfŠ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’΅|7¬>‰©‹•†+ˆ™LSC*‚²Fz―·Φ€2¨§ΔΪΊΩ·αζiτiŽO/jάoCΦ'– Š( Υ>xΕΡ]t|« ƒφ¨zίtοψU~2 ?ώMCΕΣSΓΎ(₯Όs΅ˆΙ_μ‰Ž§ZΓΎΕ|sΉ€Θ_쉆O§Z`π»Ζ(Œν£αTdŸ΅CΣώϋ*Š)Q]—ΓΟ½νΥνβιϊ=‚oΉΊqΣ©ΐνœ ϋ~5ΪxoᧄߍxΝΨ|=π[ψͺ[Λ‹«ΔΣτ‹σ.άp£“Ϋ8ι]ό>πφ½₯^Νΰ=~mBϊΝ ’Z\ΔQ€Qέrώ‡œ(Λ(’½+Β>uo·ˆυmbM:nZ9Ψ¨eϋ£,IzσZ+Χ%ψiα˝*-LρAMΒκiβύδd`ͺΙ$‚;Ž΅“βοθΦώ_xKX“QΣγ”Ap³&ΧF8φδŽξ yΝιΊ€4=/@±ΤόwK¦΅ϊο·΅‚"mΖrά:Žάdsž+β‚Γ–Φ:¦•~Ίž…ώ’δ έv°υΐ?‘ΰb€8ͺ½&“‘«%€«§K'’—|Œόό ϊπ*τh:W‡μ5/k“i²ίϋ{X",αqœ°Α=Ζxγ¦s[Ÿτ{}ΰ‘kc|—φMͺ‰ ΈAθΙ)£8ό? ρJ(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ Υπގϊή¦-–h­βU2Ν4¬ΗκήJΚ’€:ŸkφνfΊ'‡• Ρ‘9f<=Σ}ύ½XZŠ(’Š(΅Ox8"†π6ζΏ΅ζ>½)ίπ‘ψ7ώ„Oό¬MώΤψ£γEEΦ0ͺ0Ωaι|P|bθΘΪΖU†ϋ,=?οŠ`β/`ΎΪΔ`7φΌΗΧ₯qTQH[ψwi.»π‡Εš&–wjž|wp Ψp>»}~΅£ϋ=ψgY²ρ]Φ£}csgk³BLρ΄eΩ™HΟBkψOcow©]΄~$} YHΗΨ›!RV=C1κ8/|ηœb½SI»Φ|/=ΖΉγΩ]Η–Άvςƒζ9Η!@\œ SΘ 'αύ΄ΪΗΑΟi:V_SΞb_Όρό‡Χξ7‡zO€:eυ§‹n΅[¨e΅Σ¬νeϋD©E>\žόψWœhή₯αύAo΄{Ή-nTmάΈ B{ίρ/ďxŠΙ¬υ GŽ0ρCΖκ@Ιϊg.‘¨κš†·e§Nt¨ζmςͺό±δδτΘϊGμιqοͺζ΅ΑΩψ§Y³πεΞƒmzΙ₯άΆω!ΪΌτΘ݌€p2νυ¨—Δ:’ψq΄u¦—Ο0ykχύwcwn™ οE“yΧμ.ŸΚι:~­E{w~f†8tO˜ηΏϋ1\‡…Ύ!x“ΓfΣKΏΕ§%a•Š€χ\τώU‘β?κΎ$½zΥμ—S΅K`*@£~€=#㾟w¨ήhZ֟—MƟq<@²«dœqΣ!†=p})ή1Σ/4Ÿ€ΆΤ#x§:—›εΈΓ"²ΜΐΨΰηυΖψ_β'‰|5eφ=2ύglSF$OχsΘϊtͺZŒυX}XΤζΫΟϋNƍ$ΑΘΖ Ξ=¨ž’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(H‘’_υjMIφ9ηŸκ+Z$Ζ¨½§SμsΟ?ΤQφ9ηŸκ+bŠΗϋσΟυ}ŽωηϊŠΨ’€1ώΗ?όσύEcŸώyώ’Ά(  ±Ο<QGΨηž¨­Š(μsΟ?ΤQφ9ηŸκ+bŠΗϋσΟυ}ŽωηϊŠΨ’€1ώΗ?όσύEcŸώyώ’Ά(  ±Ο<QGΨηž¨­Š(μsΟ?ΤQφ9ηŸκ+bŠΗϋσΟυ}ŽωηϊŠΨ©ΎΝ>ΝώD»:ξΨqωΣQoa6–ζΨηž¨£μsΟ?ΤVΕ¬3μsΟ?ΤQφ9ηŸκ+bŠΗϋσΟυ}ŽωηϊŠΨ’€1ώΗ?όσύEcŸώyώ’Ά(  ±Ο<QGΨηž¨­Š(μsΟ?ΤQφ9ηŸκ+bŠΗϋσΟυ}ŽωηϊŠΨ’€1ώΗ?όσύEcŸώyώ’Ά(  ±Ο<QGΨηž¨­Š(μsΟ?ΤQφ9ηŸκ+bŠΗϋσΟυ}ŽωηϊŠΨ’€1ώΗ?όσύEcŸώyώ’Ά(  ±Ο<QGΨηž¨­Š(μsΟ?ΤQφ9ηŸκ+bŠΗϋσΟυ}ŽωηϊŠΨ’€1ώΗ?όσύEcŸώyώ’Ά(  ±Ο<QGΨηž¨­Š(μsΟ?ΤQφ9ηŸκ+bŠΗϋσΟυ}ŽωηϊŠΨ’€1ώΗ?όσύEcŸώyώ’Ά(  ±Ο<QGΨηž¨­Š(μsΟ?ΤQφ9ηŸκ+bŠΗϋσΟυ}ŽωηϊŠΨ’€1ώΗ?όσύEcŸώyώ’Ά(  ±Ο<QGΨηž¨­Š(μsΟ?ΤQφ9ηŸκ+bŠΗϋσΟυ}ŽωηϊŠΨ’€1ώΗ?όσύEcŸώyώ’Ά(  ±Ο<QGΨηž¨­Š(μsΟ?ΤQφ9ηŸκ+bŠΓ–"X€Tu½* #dn„V QE (’€: (’˜Q@Q@Q@Q@Q@Q@Q@Q@Q@ί€­"ŠΑ5Yό={―΄w±ΪGk`€HςZg8$…ΐ= @―e„wO„πhΏjύΙO8&αζcΗ_ΌΛαΛ]iϊ2H-΄ΞΖT*ΫX‘ΐ Η888υΕt{γσώΦmβ:8Δ=W9*=3ΟΦ½PŸ*”LςλT‡;ŒΦ©Hα<{kΆͺΑαλέ€½’Φ[[τG ‚³!ΐ![$u*y"ΈJυ?ˆΝu£<Žςά̌%rΜY‚ sΞF}3^Y\΅γΛ.VξΞΜ<ΉγΜ••Ια΄Έš%†ήY"έΉι“ΪŸuayh#7V—‰>η™.ο¦G5ιί oΫKπ'‹/’Ž9%·Ω",ƒ+Έ΄‘μp πGŒ5-cΒ~%»Φ<‹λ%κΩε‰~W*ψΰ8+ϊΦAγχz}νœi%ݝΔΏέibe τ$sQΪΫOw0ŠΦ g”ς4,Ηπκώρ£βίψΎίΔ%ίΩ-DπΉU•°η° Œ~5Oα”ž&>Ό·πΎ—mΛ'ΟͺΚΐmΖ>\6saŸZσkΛ;«)w–Σ[Ή ,eδk’ρ}ž‘ˆό9§κ0Ν4Μ³£fG8Ζάυοӎ˜―Gρ½¦£7Β›Ζρ5͍φ§gpΦδ ²ΑΓ™―ΘεπγώΈE²ΠΗ€κ2™DZ}ۘŽ$Ϋ ‡ίŽ*zŠώ k:_Δ)l¬dŽ-:ήαQ­ΔK‰s‚ΕŽ3’IθkšψΡc—.ώ́hfUˆΑ?Ž3ψΠ WKԝμn– ,† IιƒŒWYπwJ΅Υ|gΫ£Γk άωl2ΘοΛgπ­}βv΅βϋtΊh€fb]ͺŒΐ g#―^hΝn šΪf†ζ)!•~ςH₯Xw䝴Λυ΄ϋSXέ lgΞ16Μ½ŒW―I€Ϊκίυ1|‚X-aK“ †+ `;Œ°?…aiίυ»ΔΣΩ£E聆HΩΟα\•QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEΟΧA\ύ Š(€EPAE6'F½§S’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(Όψ}ͺGδMgs!οRŽμNα΄Ή=ΐ^§N•ΫW‰Gq4vσA°Ν·Ν@x}§#?Bi¦Y ν.Ϋ}3]”±|‘εkc†ΆΪK™=Ξλβ&’’ήΪΦ0Θŝ ₯Jdw;ΉzŠΰͺVΈ™­bΆiXΫΔΜΡΖz)nΈϊγόζ’z•Is3ͺ•%J*)Η„uέ;Oπ'Š4뻏.ςυTAΖ;πyρ"™ΰ}oOΣ<+βλ;λ*ζώΩ#·MŒΫΨ 22οΈ*ŠΜΠν| ­ιϊ_‡|YkqεO}f"·]ŒΫΫkŒdήqZώΥ΄=_ΐQψgXΥfΡζ‚v•eT%%qΓc¨ωΊtζtP©jϊ§…4Ο‡§‡΄=J[«Ή&ŽBο9ƒ‘$`Χ·z]_ΕZ5Η‰|w ζλ}:ΦιΌ§YΟΙιΫ5ε”PIβύJΣPρΝφ‘g/™g%Θ‘$ΪFWŽpFJΫψ«θ~!ψ…mv.έτvX£žhγe` ΨΣΫσŠο¬57Γ?ηΒ)q¦"1`–0ω‚δdσ‚>ž•½¦ΒŠ-―τχΤfΎ’ε|9’*‘ΚXœŽ€œγ'§zσ=W»Π΅X5:@—œŒŒ‚ΑwWs Aα― πΖ‘¬ΐζμ/;±Χ¦Z»βoΒ1ρ³PΤJ`ΔqL‹Τ‘…3p@?…$6,υtΧ[™νO>=9`;ƒƒ½:g±ΐχ―5Υu SQΈΎΎΙs;—v=ΟψUJΩρ†Άώ"ρξ¨θc°Ψ„ύԐŽkŠ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(~·₯qlνΠ Α‘€QE€(’Š’)€‹ύ[R}²ωιϊ ―EXϋdσΣτ}²ωιϊ ―EXϋdσΣτ}²ωιϊ ―EXϋdσΣτ}²ωιϊ ―EXϋdσΣτ}²ωιϊ ―EXϋdσΣτ}²ωιϊ ―EXϋdσΣτ}²ωιϊ ―EXϋdσΣτ}²ωιϊ ―EXϋdσΣτ}²ωιϊ ―EXϋdσΣτ}²ωιϊ ―W΄]=΅MN 4q”Ÿ˜ŒΰIύTbη%ξΔΪJμ‡ν“ΟOΠQφΙη§θ+et;Έδ]#V[Λ€]ΒDXΈ$ς}«cω›6Άόνێs銺”§Nάέ{4!Fj[}²ωιϊ >Ω?ότύlΆƒih‘―ͺ₯Σγ₯*Lx>Υ™­iν₯κsΩ»‰ D|ΐc €GθiΞ…Jqζ’όWβ·_1F€dμˆ~Ω?ότύlŸώz~‚­θϊ©­%ΛιV3έ­²†˜ΔΉΨqŸΘώU™X–XϋdσΣτ}²ωιϊ ·§hZ¦₯aw}cc<φ–ŠZy‘r±€2r~ƒ5™@>Ω?ότύlŸώz~‚«Υϋ­P΄Σ-u›9’±Ί$C3.LuΗε@}²ωιϊ >Ω?ότύW’€,}²ωιϊ >Ω?ότύW²γαηŠ-΄TΥn4§ŠΡΚί";Θ ςgw$ŒgšζώΩ?ότύlŸώz~‚΄u k:v·‘y§Λ₯0S Ο»¦0H= gjW:uμΆ—ΠΌ16Ω#q‚§ΠΠφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^бφΙη§θ(ϋdσΣτ^Š’Y€—ύcQΡEQEQEQEQEQEQEQEQEQEQEQEΏΰ_ω¬ΰϊVoψώF«ψώ€ΥΡ„ώ<=Wζg[ψrτd:•uέ֞μ.¬Κ:ͺπ[;Ί^+Kϋ~ΧmϋώήW»oɟωιοvΕVπό[ψo^šd• ±VSΘ>a«Ϋφ?΄ΎΖ?Άρ·§ξσ=qλ]tœiӍ₯fΥέυκΥך±Œ―);«Γ-όŒν{JΊ°‚λPv7W…έ•Ή+½O―57ŽΏδjΎ€θ Oρ\xoAšwg•ΝΙfcΙ>`¦xλώF«οψώ€΅γΒ|›^ο‹eSmΙ_ΟσG§~Νχιφή*ΊΊ!`‰-šF=ζLŸΒΌϋβ—‡ΏαρΆ‘eν΅vσνρΣΛ~@C•ό+€ψS"Δ_ϊπωK]¦€Αρ/Aπ~«rκΧ:DfΤ7—αŸ\ŸχΫWžtz•†ώκšK¨]Jmζώε{©xΘώoόΧ‘ψ#ΑΪV§‘έλΎ%ΦΣNνίΛΩgo§${pIη·5ίiΎ!„šϋβ•ϊ>λa€Ι Ώ§–© }yoΖ°<'£h:7Γh|U©hskΧ“ά<"ΔG†[ΛΤƒΤPW‹Ό €ΫψI|Kα=^MGLID3,Ι΅γb@τΘγΑ­―Ω\κ_όgaΟu4‘Ζƒ%Ν[šνΫ_ό ΦξG‡­τy.b0ΫΒ›|Εσ#ωΟ99ΗjΦπηŠμ|%πλΑ:·™Αx ΰσn€ΆXzφΟΆ~”δώ8π†›α[;+Τ&Όρ<‘Lφπb‡=³Œ“Πί―Vλό?πΎ₯ΏΌI-ž­rώΟmα=7§ϊwτΝTρ—‡Β4ΝNζw»Ρnο#»ŠρΫ~δήƒ7r~γ»―‰ϊΕΆ—β§~΄ΥΦεQ‘Ύ9c?Κ8CΘΖ1ž€τΑ\xOπߎ,¬όE©;hχQ‰μο-βά&δaHηρφ#žk±ψζϊlšςD5έF-\uK ! [;σŒnοΧ¨Ο|MΎΥ.5/[jž‹DŠίfŠ;&P˜ψΐnέΈΑυφ¦|o’Ήϋ–Ξ€/κϊ}Ζ™ρηBΆΊΤ΅)>δΨ9γ€+3_π₯Χ‹ώ1kφ6,Η)–βαΖV$dύ}tž5“ŠΡ?ήΆώ΅±αi’?>$Y xη‹tV²6Ρ8U!ŸCΉAϊΠmπϋΒZρΉ°π—Š$ΊΦ‘VeŽβ-±ΝŽ‘NΰŸ^•εWΙo<Ξ…%Š:žͺAΑ½ΏΒž šoτ†6j–Α›™δ˜Ž ³ œγρ―ρ,ς]x‹UΈžo,·rΘπ† #bδ•uΗLΠmQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@^Ρuυ8/†"~RqAτ5FЍΙΒJQέ €Υ™»u¬Ω2ζΟNŘΉ)ζ1€ΘS‘ΤqΝaQEUJ²¨Σ—O$Ώ!F*;ΆΊΝ˜Σ-¬υ,^ bώ[ Ϊ<9=<Υ kPmSSžρΠFe#ε8?AThͺyΞ<ι§EΣEλa(E;£SJΧυ-&ΓQ²Σξ|›mF1yjήbŒΰd‚Gή=1Φ§ΠΌS­h6w֚EϋΫ[ήΩΠ*Άα‚8$§ς0!X”V%šš>½©hφΊ…Ύ›sδΓ¨BmξWb·˜„G γ©δ`֟„Όs―ψQ-χe»Άζ‚D„ϊΰτ?LW1EuzχΔkΆ7vZž€e³Ίei!ς”‚8ȁΠΦUˆuKύΗH»Ίσ4ϋ"MΌ^Z™λΘ={“Y4Pδή*Φgπάz χ¦]*2!xъr0δnιΗJΩΠ>'ψ«BΣΦΚΟQl‹Ά5ž5“Λ€‘œ{+Š’€55}{SΦ5a©κw’\^‚‘ρςγ  ΐbx‡TΧ5qͺj·^}π ΎZ―έιΒ€?JΙ’€7o|[­ίxŠ vκχ~«SώR »z|‘vώ•ψ‡V6ΉφΩUi<Γqwtθ†1Y4Pw¨|Xρ…φœlδΤΔhΛ±δ†%GaŒ}ΰ8ό1\%PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEFu{¦·³Ωζ*;Ξ2υP„¦ΤbΔΪJμ‘E\Υtλ.ρ­Τ ςœ‚₯_ΎπΞ‘e¦λ…‰a ¬Fο˜d€8όjΥ ™(Ώw"y㦻˜”UΝ/NŸRšH­ΆξHΜ‡qΗ―σͺu-%'³*κφ +Ρ>ψkBΦτί_ψnΎ— s£ΎΦΪC–γΏέ΅₯ψoαΟ‹.†› j΅†©"·‘φ•€Ξύ2:TŒς+Ρ~x*ΣTρΦ«‘ψeΕ„³ˆ_iή’*πqΣ“ϊUέ 矈1ώ4ε΄UΛτ·—VΈJYZΥηeΆWr…Ύ@}ρŠυ‰ ¬Ό7ΰ‹]JΒI$ΏΆhγΤ2ωPYG vωˆό yΣό4ΡmGŸΎ#έϋq’sƒι]8:‘§^3›Ρ3*ΡrƒHνυ6?\ι—Š£ΜΠάφTŸκ?ρκwŠ/ϋΑϊŒΡγ`”"ŸP²ŸΉ=3Ε3iπκ1Η~Τν"ψς˜ηžœφτιUΧ^ΫαwΡώ͝Η>w™ώΨo»oZυ:‹„¬υ’wυ΅—ωœͺ„ξ»&­ιΤΥπn›wmrΧ3DDrάr#c\Φ£§]iΖyŒΚ›ΤΞ=ύ+OÞ&ΉΡRH‚‰ `JΖΗ[Τ{zŠΘΏΌžώκK‹© Κη$Ÿδ=«Ο«:.„cσ/ψ:!©Άφ=[ΰm¬Wήρέ­ΝZA5œq½Δƒ++(,y΅³ΰŸθ’_.³k€‚ε,a ·Ύφ9νκN+†ψwβ 3HπŸlυŸ&ηQ³X­SΛfσ,ƒχ‡\u¦|"ρtΧε‹Uoψ’ίΖa»R₯€8m z‘F5ΔnuŸ5C|Wρ§2˜Εέ₯Δ»z•S,x€β±Ώ²ΎΠΑ―ί‘ΖκO‡Ο†Ό+ρX˜κŸρ#’ΦHm|‰ !™)]»²#$vχ¨αψeC₯χώIΔPoƒZZΧΔx a€°°fΊ,γ¨SςgίqSψυ] Gρ­―xΧΔzlΆϊF΄Œ!‘€F•ω€InΥkΞ4/h^πWŠ`Ρu7›YΏΈk{VHŽ-ΑΪ―»T³c9ΙΚh^5Χ4έfΖφ][Qž(&Y'ΉvWPyR Η#"€6ΎΪΛeρ{K΅Έ]³Α,ρHΎŒ±HόΕs4‘Η^―ωτcW’MβO [όp³ρ–‘&Ein%ς$\†'B6νάrvžϋΤΝFΗα…ή³w©]ψ£QŸνΌνVŽœ³+’9Ε7Vo7φwΡΝγ1tԊΫsΖdγιί―Oρ[Ηβ-_]π]ΙPχZdw–dφ•Iώ‘Πρ/‰^4·ρ XιZ%«YhpΫo\τάGn:rzŸZΩρώlOΕ-+ΔZΑΊ·΄†%r#dέ‚ΑΧ εXΖ€,|+€ψSΓ%ρ…τE.-ΨΪ#‚šHΟοƒUOΪ–ρFŠX’N$χωδ©Ύ3ψΣGΦν,4― JNYdΌΈ+Fgbz0ψ˜žί7΅bό`ΧτίλΊ]ƏsφˆaΣb·‘ΌΆMΙ`=G=(~.Ψψ"ηΔΦοβWS΄ΏϋacΆŒ2”άΨ?pσœχ―ρ·†­­ΧΒwΧ·&VΊM₯[<ςŽ1^›γ»Ώ‡~1Φ"ΤnόWsm"[¬#²”ŒNyOφ«„Φ4ΟZk:2iΊύέώ,Δ_ΉΆhΪpW*3[¦qŠΣύŸδ₯ΩΧΏτ]‚|y«k?eΠ/ ‘ά5ŲوT$hˆδcŒž'šζό1«xGΓΕξ—}*ψ~8]DFο‡)‚ ΈŒχΕbx ]Σ΄―аkχVœ³ά9›c6$NΠ δ°νή€;xσY½ψή•ΰώΓiη΄K1 …Ž4WΫƒŒΞxλψdό:Σtύ/Ε^9Φd΅Y“ΓΒvΆ„€TΟƒυ0lΧ/α{MΣώ-΅wsει‚ςβ_;c•ƒν;@Ο;‡jΡπ—4έ'Η^$}AMΗ‡υ©'Žbηc;m§œaŽG^}¨ ψ_ρ3_ΦΌsk§λ“Eyizν΅ JΎCYJΰgΆ9Νy—Ώδ{ρύ„τkW§xX|9πoˆ`Φ!ρΪƒ’Dω ‹pΓŸ ’@$tzwUβϋΘ5kWΆoζ[\ήΟ4O‚7#HΔGu  Š(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€:ΠμνB¦§«%΅ΙPΝΐmΟ ;Σ²τ_ϊ䛍XρLΒίΖ74i*£FJ:‚¬6/Ήύkύ¬5μo/ν]8xϊφτβΉ}€¬›‘μ}^›“Œ`Ίύϋ™«‘ΩέM3VK›₯–&£έŽHχ~Ίo L.6‘†oχSAQ§(¨μΣu‚Ζ Q[ˆ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Šθf–S²ν'ρψΧJ…W'QΪφ²άW[>ΉXuaίκn”ΐΰϋτύxόjή³ Ρ΄τβGq+I!έSωΰΝΡ,VφΰΛ5δ6ρΔΚΞ>χω}ψ£Δš€Τ΅ifŒ“α#t‰Ιόk9CŸ­²Υϊ­Ώ?ΐ/‘wO΅²΅ΠF₯sjΧ’<…n!SΞ*ύΜ¦έΙφ(­#2ΕEΖα‘ΟΏZΉν7V½ΣC IΚ+• OΠΣυ›ϋΈ₯ŠβΰΌrYJŽέ1Η…)αͺJ§3ξžοnΦΨ.¬_ρ_ϊ½'ώΌǎ‰^‹ό…cέήOv!o 8 :(ΊΌžι Iδή° Ž1€0ΎœV”θJ<—ϋ7όA½ΝώAΊύq gΏδa›ύΤΠEe\^ά\EsIΉ ]±Œ΄R^έΟ}pΣέ>ωX[tϊQJ„‘(·Σ›ρwξW’Š+¬’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Šθ4Oψ‡[„M¦i72ΒίvFΎŒΔψP?Etίƒ|C’BfΤτ›˜‘_½"€θΏVR@όkŸ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ηΐzMΎ™wβmnΈ΅΅Aijίvβr3󲣓λψ`·\ρ©­Ξ_έΘΙό0©Ϋ@£Wξδ–ψ_ΙϋŸhΊσ±ύύγnΰ5…|=ύ«η^ίΝφ=Χ›‹–ΠՏυϊΐΦψtuH¦“PώΡ’ΗC΅ζκIθάΟ0§†cΣΫ?LβόDtΙμΰρ7‡"0iΧ34Ϋ‘0δ`‡8νψΰIβ―jω6VύF΅βήΩτ6υcύ~€Λi$·ΕwάϋE―“Ÿοο;± 9’ŠιΎι0kž:ΡτϋΕέo,Ϋ€_ο*©b>‡n?@c&•¨=™ΌK Ά΄Q“8…Šλ»«ώ±†ι°ψŠΖψΩJκCl$‘@*:‘ŸOCŠτ|WΧ΄οέΫι­ :E„νlΆ>Jμ‘•98ΘΞ;8‡ΗlρΣΑM„ŒΫ[P1ζˁ@›ΰ»oό@½Σt%ΌΣt€Ν²[‹vs¬ $η9ΕaiΪ\±”lœkΫ<9«έψGΰυՐ‰―­υ9 ŽGPΑ₯€=ρœ}jŸΑγwβοk>"֚-GTΣνWμώxTC!έ΄œ mλŽ3šςK­'Q΄·Yξμ.ΰΈK *Ÿ‘#JΎŸπέ·eΥ¦‹ΖWΊ.‘‘]«€φαΧδmFGA‚z{ΧΞ>#³Nρ©eέ΅Τ°‘Ξrͺδ Ξ’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(½ψw«i“ΩΟαŸΚ`ΣfYΰΉ"aΑΙ=3ΫρΘΪψŠ5H¦OώΞ’ΗC΅βΦ8ΖθάΟBΓ†cΧΫ?\ωEt'ŒΌC’B!Σ5k˜‘_»θΏE`@ό)―‘ψwTΦηXμ-$dώ)˜m©cΐ§xσV±·Σ-<3’N·Ά²ξξ—ξάNF>_φTp= œmoΖ^!Φα0κz΅Μ°·ήHDoͺ¨ώ5ΟΠβeA)"<Δ ;β»ΝjΓΎρŽ‹¨ψiοά+Κ²†ωŸ‘QJœ8ΟΐU>ςγNΎ·Ό³Εs‰#qό,A€k· ΅ v]kSώΨ΅ΤYΌΛ$ΐW|½Α㌞Ώ0ό+C↧k§|eπ¦£~ίfΆ‚ΞήI~RήXσ%'€3Η°ώβOΡτ½F`C]Ζ€·=pΞ€.ψ{ΔZVρ βκΧ^B]5ά0Ÿ-Ÿ{™[εSΕrΏu­?Γώ9΄Τ5{³ΩΗŠlgΑ(@αA=}«ži.'’iέ€–F.ξΗ%‰9$ΤtιώρvŠ’ψ—Bρσ kΌ«mΨΫϊζ©ό-ρU§†υ;Ϋ}b›FΤΰ6Χj£$œ6;υ zβh [Ά>hΝ.£uάkPo'O29$pŒsυΫ^StρΙs3Α“ 9dqmŠO'“Ž™¨¨ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ŠΪπί†5Όι’Yύ₯ Θ<ΤM ηxŒτ5» ―Ζ_τΙ¨ψΊβ(ίώ_ŒΏθ“Pρu…βO kx[³ϋ3N Œy¨ϋ€Ζ~ι8κ(Š( Š( Š( Š( Š( Š( Š*Φ—§έjΊ„:|-=άνΆ8Χ«Ζ€*ΡW5m6οHΤg°Τ h.ΰ;dˆ%N3ێ„U:(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’ŠΪπޟ£ίΌγ[Χ?²1·ΩγΜ'9)γ~u»ηƒθ{Κ<ίγX^Τ4{œλzφΊΈ5ϋ[Ϋωdg'εηΚ·α#πoύŸωX›ό( Ě~`π \ώΧWΘίd{,Œ`|ǜσωV-vπ‘ψ7ώ„Oό¬Mώ…βMCGΏx‰‘d*$_΅½Η˜N0~aΖ9όθ­ι:}Ζ«©ΪΨY'™ss Š5χ'Ώ΅U’'΅wώΣξό)ρ7ΓΗΔv’Ψ‰+η3½YTίD};ΠέΧΓίιχ©’j^-xΌBΰ.ΐ’Β±Η‹τΝ`xϋΐMαiZ—$·—7ΆρΏΟυŒμ€ »ςη5?ό βIώ!jPE¦έ\}²νε†uŒe]‰ΏA€yΟLW‘xΖx΄^kΩbΨΗvθYšeώϊ"€9YΎx7KΎFΧ<[$Zλb‡0Ζη cŒ~d~ ΖΎΌπ—ˆ&(«D=zt# ΦΟΔ λƒβ©llnn'»»y (…„ŠμJ~„ι]_Ζ]dθΎ6πγB–χ:†—c›ΞџŸ•€#λγ΅ΪψΏΒ6šW„|?β *ζk‹]EJΝζcχRχF=Ïψ iέό]Υξmfτͺʌ„­£γηλZΏ ’>0ψy―x=œ Έol‹Η# {dγτΛήψBΧOψegβ;Ϋ™ώϊγΛΆ·m( ω~ŠOβ+_Oπ…₯θ6:—Ž΅ΙtΧΏ]φφΆρ“f3–ΰ‘Ϋ·Ή£γ¦‘Χl<;`qc’Z₯Ί¨ώωŸΠ(ϊζ½βN·ek‹©Zkφ6iε^1'gpŸtγ¨#Χ'€<·ΖΎM }*οNΏ†…©°X.”`ƒŸΊΓ¦qόx·αη„<),ρλ$ΊIή"φ–ιηn8/…8²;tλι'υ=J ψjΪo C ιO~“ΫμœŸ›+εΰΞνΩΚύ‘ό\i}­bώF€"Π| ’Aα;OxΟYŸOΆ½bΆ°ΫΕ½Ψ ςx=qž;σŠ—ώλ}+Η>:ΌfΣυ9­ξαeYα眯γԏPG£ λ:ށΰm2ίĞ·Χ<7rwZ`Ο'=@lrΗ€zŠΧΉπΆ‘¦x»ΐšξ‰kq§E©]ϋ ‚wFx9䎼Œϊb€8MwΓ†³ρVϋBΆΊ–φνξ ΅ΥΟ'hPKΆ@? >x.}M΄oΚΪψ>XΜΉ2ͺ0NxΖοnΌVο…!ƒφˆΧγ•Υ$ΈIb„ŸοαΑMy‰αMy<{i§=•ΘΎŠρ °α@|™7άžτ­ΰΟ†jώ'Χt-^w΄ΌΣ‘, dfΘΪI#ξAυΑ­]7αΧ…5αu§xwΕ2]λΆθ_kΓΆ)뷎F{‚zζ»»KΨ.ώ+xε­H>N’"wSΥΥF.Ÿ…ywΐGΔΛ ±MŸϋΰΠžΛE+Η"•t%XΔu¦VˆδaΥ?λκ_ύ ΦuQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEmxoΔϊΗ†žwΡ/>ΜΣ€$>R>ΰ3Ό:šέ…©γ/ϊ δ¬?όEqPΧ‰0„ιβΪΚ;A2«•,Δƒά|ΨΟ΅yύέΩόXρ¦œ,γΥw*«,£ΘϋΔsυ95Εήέά_]Λuy4“άJ۞I,ΗԚ‚Š+SΓΊφ₯αΝD_θΧFΪθ!MαΎSΤa₯eΡ@5 ˍBϊβςςS-Μς4’9κΜNI—ΒίΌIα‹_²ιwθœ‘Θ$U'ΈΟ#π8JŠάρŠ΅Ÿj1^κχΟ<πŸέ ±σŸ•@ΐνυΗ5[Δ:ξ£β-Hίλ7?i»*Ι±SΠa@™EuΎψ…β? ΩύKΎΣ$¬2 uBNI\τζͺj>3ΧυzΧYΌΤ^KϋV ”]±η„ΖίӞυΞΡ@ΪΕύφ³&­srηQy¦tρЍΈ§jλ%ψ΅γ)t²WhΖΣ*Β‚B?ήΗκ9ŠΨΡςή#ΐy‘dρ"€(ΡVc°»–άO¬ο?–$XΙRίέΞ1Ÿj[ν:χO(/μξmKŒ¨š&MΓΫ#š«EMkm=άΛ ¬2M+tHΤ³ΐU‰tJ)&ItϋΔxSΜ‘ZϋΜ1ΐΰς}(bΞΞκϊo*ΚΪk‰zμ‰ ŸΘSnνn,ζ0έΑ,Ž©*aψ†ŠλΌ{o AŽ|=c¨Ϊ4–ΫMβ°ήά`zχδqΣΜΪY]^vΣά˜E}£Τγ   τSαŠI₯H‘F’G!Ud±=κΘΣ/ΜσB,ŒΠιcς›rVΰ}hn}6ϊήΥ.g²ΉŠέώμ―*7Π‘ƒK6— šέΝcu«t™α`‡ώŒP:+»Γ{|!—ΔdMύ€·ίgΙ·ŽήΌΧ @Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Ϊ7ό‹:ύ»θf \„Τ>Η0/mz<‰άτ?PiήQu¦κΪ|l‚ζαch•›ΆΆHχ©¬ό9ZέΓq’—‰Γ¨iS<όΥΝ6―$­Z„fγNPMΫ{kΥώ…άΏP‚ΆΦCɍ}ΗSυ&gώEώή?τ1V/<;]έΝq%’‡•Λ°YS'·ΝPψ‘E›€ις2›u‘₯UlνάΩ‘ή”ΌRώ΄ ρšIM5}―§Uϊύtί t˜5Οhϊ}βξ·–m/χ•T±C·s‘2 ”‘FβHρ]ζ΅αί xΗEΤ|4χ‹nεYC|ΟΠ¨Θ%NgŠκ<“{Ε_υν;Ζ·vϊkC‘a;[-’»$D%NN23ŽΗŽ+wβ&“kβ>°™1g=„Lю>EiŸoΣ ŠΙΧn>jμΊΦ§ύ±k¨³y—:I€ω{ƒΗ=~aψTί5Ιt?ŠžΦ-β[m> $φ2KΉ=Έ$P/όWΧ΄Οέ[hο Ά“§Ξm£²¦ΗT;NN23ŽΔ`b΅|I€ΩΩόhπŽ₯§B°Cͺ˜nš5Ιδγά`ύsT5k_†Ύ!՟Δ3λχ ;ω·:Ϋ˞[2sœg©δVN§γ«cβƏ¬ΎλMOxβ‹r’V%$–*Ήη$π;b€6αΈΥ-Ύ7xŠ]C‡WΎΑ<ΦΪ-ςΟ“ΐόyμ+½πΆŸβΛ¦Υ,\gΉΑΕyφγ}/xΗν7³Α₯λ‰εΕ¨@Œ/”€ΐcpϋΗ·P+CΑw~π.­stΊπߌm―GIόΨ/νγ-φyNΑκG\δŒWaαCα[oψΪΟΒOwvL•ξonSnβcpˆO˜τοή€1΅ f‡Ÿ ό7‡BA©λQ›«‹Γ³γ vŒŒΐη5Ιx―Η­βΏ ZYkV+.³k&SRRͺY9Κ• οΨυΦφ­ψgΕή ΣΌ?βΛΧ΅ 3+iz#ά¬‡±τΰAΖvƒšΚρΔώ ΣΌ7o’ψX JΝίqͺIVΗχW {tγΎhWγ―όzψ7ώΑkό–°> k£BρνƒJΐZή‘͞˜|cΫψf΅όw―ψsΔZƒbkιΒΦ8/ή8œ4wpτ<Œώ5Θxή= ίΔ³―„§š]1B˜έσΨη€qžζ€=/Α~‹Cψ»OxΎ^™‘$—ŠΔaB°&?ΙI?U§|Φ_VρŒu{Δν$£~FέΩ τΖj|Iρ8 ΄ϋΟ,C«x‚b˜Ž‘,~‡8ϊ=yΒι~ΈΧ›WΊϋ:άΨ41-Ÿs“ΐωAΗγ@ΟΒ_κΎ.Υυ;ğgΎ²ϋ]€- …BŽΈPδ|έσΠT λϊg‡> /Pattern << >> /XObject << /Image27 204 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 206 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 207 0 R /Resources 208 0 R /Annots 210 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 207 0 obj << /Filter /FlateDecode /Length 209 0 R >> stream xœ½W;Eξ$Kξί`Λ‘O·hiχϋ‚dNœ„4‘~œΠϊq†ΐ ސΘLDΒ8›τ"ψ›ω"‚ϋωͺΗs3»;^Ξ7kOk·gzΊ«ͺΏϊͺΊζHh©΅Oš§<ϊοŠ#‘€R:‡δ•+3VŸ1‰Ί‡Βƒ*ΛηέƒQ>:Ί™‹•ϊ?_‹GPr$n}:r8SβΑΠ`θ“³:€U9)›­xϊΰRͺΕύΕWhG=MΊh* bVYΙμ’ΠΪΊ ‹“œ¦Ασ±yoΜiš±nm7v’”ΪΤ’ΫέhΫκ½—Φ‡d„Ι2ΖμMjαΟΡx—q»Š)’ ’±ήΐ ΨώY υSqλσǏ~4Βc"]IΤχ—έšI‘Α‰ΊρY}Wά»μ·‰Πž ΪegΌζό*ία¬Z|t­Z°?ρV·oχρκ;e'Ν¬)ί©ρ¨Ώ·λmΪκ“•ΙyνΧ,ޝˆϊ{φ?πnr·ŽΙ7 ›lgΫsξ Ν»‘hcΠe¨]׍Ό»£Α€δ­2B;/΅ρ9wsΪί*RV˜Π ½j }ˆͺΥq΅@ϋ»k“t³AΊ‹`ΆƒVT€7ό&hpm"\nΘQ- o‚%.»+Τ*†8 ΈϊͺΐΏ)Ί}>#²ŸωώDΨb XyTΕ„+θfΌΖλΎΓώE_³vB71Ί1»OγΛΪΓ.«!¬Ψ+(>νΠβlΙή™7ή€dœ΄&‡5>\„›ϋHΫCbΚΈό‘L~~9@±’Ÿ¦|―£@o„ΈWύ5HJχ>λlήΟ¦i7Z9I‚σRάώZβv|Τzιχ82‡Τ Ηn‰€m.N@o}|ΛΧc·ΨB!xŒ¨ΐ8άώ ‘[Ž˜SφΘ£#Y†€@ͺΓxl‡ΔΥ††ΰτa$W/ΩuBhŸί¨^³λΓaœ &ei”Žώύl±CDζ|W‘›€„’.[KΓίς)n©fψ3 τ|‚B±MΒ8¨²Ω©ώΈXl2@£$Œ¨Χ¬Ψ^TZ9/ ’<)…J’'TΗ[!ݐtBπ—&h)K $‘7/ΚDœvu?ΨYy³ν«KΪtL›ζ|ό‰ορηOΣξδ€9cσUL ©Αša8ΗB™€ΝΑH§‚—]rΦ«m9k@:9λίΊ¨~g·»*‰Ιg₯ΦΎζž-Iψ²46; ΙX8΄–¨½Q₯ «–RKy…n ρ!ιύπ Žƒƒ7ίWC,ΚC΄3PΣΘ§ΛkΖ#ο‘’,ΜƒΘ\ψ«ŠΪδ;D endstream endobj 209 0 obj 971 endobj 210 0 obj [ ] endobj 208 0 obj << /Font << /Font2 12 0 R /Font3 13 0 R >> /Pattern << >> /XObject << >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 211 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 212 0 R /Resources 213 0 R /Annots 215 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 212 0 obj << /Filter /FlateDecode /Length 214 0 R >> stream xœ΅UΝnΣ@φϊ€”y†’œ%UΩμΞώA€•*!Yκrˆ€&BnK ‡^xž£Δ±/—θ±ηΌΜΪρO"+@[Ό²½σywΏΩofΦs\@lOʎ†ήοOa‚ !ƒυFθbΔ¦Mƒβλ”5Ίbzή(ŒΣ±“Γ†Ÿ38‚3"™Γψiώy60ύB oη΅’ΔΑ•^¨ ΰbz'ͺœμΑjσ“,˜ŠFΛ’Aπ H©΄ε z-#Xcy ΣRΪkζ6XMI•―Τmz…΄•ίΖpe¬Gΐΐ }%pht Ž%Ω…σ.†ΐ£2HnοΟ2Z"»€ρΛσ³―†ΖΛCv²Φi[ Y³μΌ…aς³IrΛvŸιMς˜=J–#† τ†Ž@—φ2ωU[Άq6Hn“%ν±]vΐϊ鏼ƒμ5ΌΘrΞeΪάΘpΩ§ΘυΥ·etΛXαΛPVΩΠ‚ςr*Έ2ΪΥΌωχψkΓj-ARρ‘Sέ›:)@[κd;ƒ­4·±ξn¦m\Έ…K δhƒuŒιUz]δW|μ³CΦK¬Ο2B/Ι—E„3ϊz@ΐ–,Sa-ΛΩ.Mν±AzΕΆ·›Ψ&˜ΥžK₯T—j΅3qT"€ *νoδrιΪ’LϋκK,…ϋ;—¦ds.³ξ»l;Εv’,‘ϊΛΘξ—zχ¨;hβ]ύ Μδή α;½©kο>Ϋ”BσΈpxΰ’F:°eQF)·:ΩΡō­±Ό…Ι`$j.T<Ϋ«Ιm°υ?ω‹νΏD/u@nΜJ%θΠδτΟν˜E Œ_N¦ΡΑσσ•X±ύO}„€ endstream endobj 214 0 obj 641 endobj 215 0 obj [ ] endobj 213 0 obj << /Font << /Font2 12 0 R /Font3 13 0 R >> /Pattern << >> /XObject << /Image27 204 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 216 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 217 0 R /Resources 218 0 R /Annots 220 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 217 0 obj << /Filter /FlateDecode /Length 219 0 R >> stream xœ­S½n1ήݎy€T [ŽνρίH4 AΔIH–(EJNhΈΐ#PžςΌΔ•T)ςt0³Λήή-'~’[Λη™Ή±?ση`”w:ΓiΟλ‹#˜ƒVZ ΙkΧfŒ}N’ε0ψt»½«}tb40rδwOα˜Aζ°{―y3ΫΧpψ–¬Μ˜ΖP¨)i$„“ΓKAΝΰΰ<α1_A2-R;ψXk4iE.‚1θ‚jAlrF‚ΛX³sΖ„.6μbKHΕΤWw°Ϊφެή+τ!Y°€b$oS_~ŠΦ;b#pΩuLQ$H½εkπέοg>"ŸΐξΓΧΗο,xN”/A>X—•Ζͺΰ wšε—π &ΕϋrZC[«Iq±f?.χΛkeζΉ·ΗnŏšK+—·Λi΅(wjΐ_~ρ­ψZξplΚΫnrφY Ο!?‚y›4"zE&ΔίΈLjΘ―μ/…S#˜˜|'‡%μΪC$Z 5C(b ¦ υϋ†Θ·χXς¨-η•±žhΘιηΈP6t… υF§ΒΊάΥiυΉZ°’wY9κ”c_’§Υ§κϋ Ωeq³JLcπ₯>W!ψy~Δκƒ°*‹ΆU«/lήΰfΌΞ½L]/o KΦ§°ρ[!g΄Sr0Θ}rΕΉ<±UNςV―Μ Q9Ρoχ'%γ'ωD8γ endstream endobj 219 0 obj 521 endobj 220 0 obj [ ] endobj 218 0 obj << /Font << /Font2 12 0 R /Font3 13 0 R >> /Pattern << >> /XObject << >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 221 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 720 405 ] /Contents 222 0 R /Resources 223 0 R /Annots 225 0 R /Group << /S /Transparency /CS /DeviceRGB >> >> endobj 222 0 obj << /Filter /FlateDecode /Length 224 0 R >> stream xœ­TΝn1Άs@bnδΞH*pόsA‘–.‰pˆ€&B›–<Γ[π}†>3ήnv³ T©Ί–Χφgησ7c/A TU+ΆŸ°)€TΙG'm^Ργ"j`Ό ^fσ²hι‚₯N ύη0†ct²„ΡγςΫ|*aφ=hͺ!Z£Π‡02Ei’ΣΩ΅\Ναh°,[žTφ” n«BtJX@YgHtbSP°²…Yk\…5Ά ΆrINM¬ΥmzYΪz@­υ":«’ΓEB™€d¨υOA;›°γQwb DmœN–Θ?)pβF»'Η?48\H_„βh= «ΣΒ[(ͺ Ÿα Ψ~Ÿ3φλyοŒδ·ωdΒoυΞΨ/ώzYΕΘο±σ<Α§ΌθύΒG(^Β³β&z…Α]’9Bρ•œ]!κ‚lƒ7:K-ƒBldTN Ι+[Cϋ”ΑΪ΄΅²κ¦7οδK‘£QѐA₯M*rΣ΅Αs^,¦³/:ΒΣ“•DA+δ”sξ"_‰o*ΘΗ\†V† ΄}’;„R΁R^Xι£ΦlζJΗS˜Lψ$…DQBΔ kΠ²…β=΅ΡDη%ΫξΈm…ά‘vΝ«›¦H0Viκ7^$νΖ#₯ΨΞRΆΗΖXΩ;v—υ±²·μ ΫgΟέΓ{œΉΓ^!Φg»yf±DΖl2aύ:ΝΧΥΐ'Χ$­œO«nΠa;uB7+΅NΝnΥͺΫ AV–@όΦOΤ m–:‰H°Ύˆο₯qˊN±ύh›„!φώZ/•ΏUΰh endstream endobj 224 0 obj 617 endobj 225 0 obj [ << /Type /Annot /Subtype /Link /Rect [ 432.0866 294.1449 638.1708 310.9449 ] /Border [ 0 0 0 ] /A << /Type /Action /S /URI /URI (https://prometheus.io/community/) >> >> ] endobj 226 0 obj << /Subtype /Image /Interpolate true /Width 2048 /Height 1079 /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length 227 0 R >> stream ΨΰJFIFΫC   %# , #&')*)-0-(0%()(ΫC   (((((((((((((((((((((((((((((((((((((((((((((((((((ΐ7"Δ Δ΅}!1AQa"q2‘‘#B±ΑRΡπ$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪαβγδεζηθικρςστυφχψωϊΔ Δ΅w!1AQaq"2B‘‘±Α #3RπbrΡ $4α%ρ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š’£€₯¦§¨©ͺ²³΄΅Ά·ΈΉΊΒΓΔΕΖΗΘΙΚΣΤΥΦΧΨΩΪβγδεζηθικςστυφχψωϊΪ ?ϊ¦Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š:V}Φ·₯ZHRλS±…ΗU’αώDrQέ•JnΡW4(ͺΆšηόyή[O\₯VώF­Pš{ Qqvh(£₯g\λΊM³•ΉΥ,baΖΧΈE?©‘ΙGv8ΒS*ζZΟP³½³»·ΈτΚEδjΝ §ͺ‹‹³AE…±I5Z;ϋ9\$wvξ瀫 $ώ΄6(·²,ΡEΔS&š(|ς$iΣs°υ¦AuopH·ž)Hλ±Γcς₯u°ω]―bj)²ΘΖ^WTA՘ΰΖ’‚ςΪαΚΑq ¬pŽγπ’λ`Qm^ΔτQE1ΕΥ½Ύί΄O[ΊopΉόι`ž)Σ|€©œnF 3ψRΊΨ|Χ±%χ0[γνEzopΉόκEeu €2‘AΘ4ξvΈ΄QQOsΎ>Ρ4Qg¦χ ŸΞ†μ 7’%’‘X:†RHΘ δPΙ{kΎ\·0$Ÿέi?•+€ -θ‰θ’Šb *n­βG,ρ$‡’³€OαSQq΄ΦαECέΌ“£Έ‰₯Κ+‚Γx€šςΦΩ=Μ1Ώ]― υ₯t>Y^Φ'’ͺiΨΟν―ύύ_ρ£ϋNΓώmοκ.eά~Ξ}™nŠͺ5+φΫώώ―ψΤΆχ0\nϋ<ΡK·Η Κš’bp’Υ’Z(¦Θλ3Θʈ£%˜ΰ dŽ’’‚ζ €MΌΡΚΖ Κ₯’χMhŠ( AEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPLšT†–V )fbxu4ϊγ~-_=—ƒ§HΙ pλG‘δ*Ξ­Og7Πί EΧ«K«±ΑψƒΔΪnjυ“¦h>jZUλύη=‡΅mιίαςΤ΅)LΔr P©λϊUο‚ΪTvϊΪ‹(σ$*ŽB―^½Έ0ψUZ>ΦΎ­ώ΅ŽΜe„›Γ`ύΨΗO6Ο$ΎψOs€Ί>ͺ7ƒU(GΈe υ;X–ΗOŠ'•™ Œ)’FΙ €ΥŠε~'^½‚οΪ3‡˜AφcƒϊfΊUxXΚp] b±ŒιΡ«+λm»žwβ/jώ2Χ²τ#"Zn*‹ή;»JάΣώۈTκ”Ν1κ P~'9©Ύι©•y¨²:i<₯nαGoΟω τΚζΓa£^>ΪΆ­ψόΒx9ύW ξΖ:yΆxξ½πΪϋG‰―ό=},Οάcϋ²γύ’:ύ8‡α‡Œ€Φ•΄έMΎ‰rŽx2¨λŸq^ƒ^ πίΕHζΆ#3€‘GkπΓρΙόιU¦°sJzE»4V»ΝiN…}f•βϊιΠφgώ@χίυΒOύΧΜΊ|Χ70ίΫ‚ T†ν»¨‘―¦΅ŸωίΧ ?τ^α'ϋ_ΒΎ"tЈηκ»²?,Τf0s©μ\†¬iP«)νx§σΠχm*ϊ-KMΆ½·?Ίž1"ϋdt«Uη?΅o΄θ“ι6d΅}Θχ―šτ9εH!’Y³@+Ρ‘UU¦¦x8Μ3Γb%G³ΣΣ‘εuFΈΌ±Ρ-rΞ?}"SζP| ž«\“B5KΒρΏ‰Ό]¬λS ΕrJ3Ψ•!δ?J»π3ώBš―ύrOύΧ“NN¦*5^Ν»z#ιλΒ42κ˜eΌToκέΞΧβ―όˆZ§ύ²Ρ©^;ΰ}Eτ?ιΧre`”νcΨ‘%IόΗι^ΕρWώD-SώΩθΤ―/»~ΥπΗNΤ£_ήΪ\HŽGtfώ‡™«Η){u(οΔΛ&”>€ιΤΪsqϋβ|θhoαξ±ύ΅α[9έ³›Αsψœ~F»―‚?ς)άΧλθ ^F™βUI}€ΩυŸ$pŒ6ƒKηkΏΜΙψλχt―«Jτ? Θ·₯Χ΄ϊ―<ψλχt―«Jτ? Θ·₯Χ΄ϊΚ?οU=εβδ[C՚•ε~ξ•υι^―^QρΧξι_Wώ•y‡ϋΌΏ¦Yϋμ>“=Βς-i?υιώ€+Δ>(«7Ž―Β[xpW·ψ_ώE­'ώ½"Πyn°ͺ"G‘¦X„†:<Τaν™<ύž*΄ϋFOρG]π·ΕۚGΩ.ί7φ +y‘;7Χ±λΧo^β+―xΚ+ΫM”Ύ1ِύθΟΣό {N“¨[κΊtΆoΊ—rϊcξ+lg$ιTψ’rfΈXBKGψsΥy>¨ς?ŠςPτοχaΠλΩλΖ>(ΙCΣΏέ‡C―g©Β―©yŸϋΆό/τ<[ΐΏςV/λ­Οώ„k±ρwΓψ|G«›χΏ’(©°F§γ\wδ¬_Χ[ŸύΧ΄Φx:P«IΖjκμί5ΔΥΓba:NΟ‘1⏆ΠθΊΦ šŒ’΄*ΓηΧ5ŸΰOΕβ}2kΉ/žάΗ/—΅c žΟ_zυ‰ς%jξζ+ ΰό‹wυςτYΛ IbU;ic’že‰y|λ9ϋΚV½–Ϊι m-oaš]BI£FΛFb0τλ\Ά…<Ύρό–—,E€ε9=2~Vό?Ζ½ΞΌϋ⇆££§n™Ί³ϋΨ΄}#ΟηZβ0‘₯iEYΗS›™ΟUΠΕΚρš·§cΠAAδσŒΪωŽΪΥΏy6lu۞ρ<ώαŒ!—ΑΣI©Iϋν11!'—Oα?^ί_­rΎ°›Εώ2ΈΦ΅%έ/ζ•ν»ψθ?₯ŠώΪ§Oyώ ¨°X/ͺV©[½Ϊ_‹ιώqθ_΄ ψv$‘qw>%˜χΙθ?]EW}8*qPŽΘρkΦ•z’©=ΨQEfAEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP^}ρ2ή…ΗDΈ\ώ Χ Φ'4†Χ<7yef]Ρgϋγ‘ώa‰ƒ)Ev;0UL*Kd̟„²¬Ύ ΅ ŒΖξ§λœZμkΔώxž= φ}+Vc? γ\0ή€ώ•νQΊHγee= œƒYΰͺΖ₯–λC£7ΓNŽ*M­$καώ1ΖΟΰΗ+œ$θΗιΘώ΅Ϋ;€c.Κ£άβ³ΌM₯΅ ^ιμ@3FB“Ω‡*0+jπs§(¨εΑUTq©-“G1πjU„R7G;†όyκΌGα—ˆG†΅‹­+XΜΜϋIoωe(γŸcΣ?JφΘέd@ρ²²žASk E:)uZyΞT±R“ΪZ§κ:Ό7βϋGΔ8γ‹ζ`!L\υλΨuέfΛC°’οP˜"(ΘQχœϊά׏ψ"ΦγΕΎ>}Zε12ύ’CΨχτ€5–=©ςюνY,]i‹ž‘Š7Ψφ]gώ@χίυΒOύΧ™| ε΅|ϊG³W¦λ?ςΎθ&ΌΛΰWήΥνŸώΝW[ύζŸΜΗ "όG¬33O#ΑZςXΞώXτΉωOΰqωνώ-kLπ΄FΨΈ½o%G}½Xώ\~"°ώ6ι%­lυh—ζ‰Ό™τ<©όλ”›PΈρ׈τK7 Ά8Φ'Ο·.ί§ι\s›‘Ο‡]Ύg«JŒqΎΗ=’½οϋwcΠ|£+αό:ββς'σΤ§hόΏ™gΰgό…5_ϊδŸϊ―TΤcX΄k¨ΠaέΤ@Χ•ό ¦«\“B5Όιͺu¨ΑtΉΕJ³Δa1Ue»kσ;_ŠΏς!jŸφΛF₯e|7±SψjφR²v•9ν“Α­_ŠΏς!jŸφΛF₯Vψ?"LυΦOύ ΄’OgόΏ©…98εnKuSτG%π‚ϊM3ΔZ†‰tv—$=€BA–*»ρ§Si€Στ[rK» ]GsΡGκk;β]ΌžρŞΉhΈYŠΚ@ΰ^~#™£ΒψΏβDϊ΄ͺίeΆ>r«vǏ―ΒΈω€’πoo–η­Ι TY£ψyoo-,u>,ΣGψY-Š˜’@ήνΈgυ¨ώΘ§s_― %kόP‘#Qϊ/ώ„+#ΰόŠw?υϊϊWW*Ž.))ζ)Ήε•'-άΘΙψλχt―«Jτ? Θ·₯Χ΄ϊ3γnŸ$ϊ%₯δjJΫJCγ°n‡σ­j|.Χ­΅?[Zyͺ/-WΛxΙωˆJtڎ.iυJΑ^.¦WJQΧ•»ωyGΗ_»₯}_ϊW«’Δ;šρŠZ’x‡Δ֚n”EΗ“ϋ Pδ4Œz§­Vc$¨Έυfy9K§7oξ=oΒς-i?υιώ€+Λ΅ω-pΧxΏτ^Ή§[ =>ΪΨˆbXΑυΐϊW‘κςZΰρθ§­ kΝ•IJ΅vΊΖG€xΛ@‹ΔZ$Φo…˜|πΉώ?Υζί ΅ιt=j]UΜI$…?ό³—¦>‡ό+ΩkΚώ0ψd•]zΕτΒάγ³ώ?*xΚn b)ξ·σBΚλΒ¬^ΏΓ-Ό™™ρGώJ›ώμ?ϊ―g―œοuΉ5έoEžΰ΄D"†F?ΔCυόˆ―£*p3U'RKfΡyΝ)Q₯BœχI―ΘρoΙXΏ·?ϊ―i―π/ό•‹ϊλs‘φš¬ΏψrυfyοραώϊœΗΔΏω΅?χσ…πGώE»Ώϊω?ϊ­ί‰ς%jξζ+ ΰό‹wυςτDί#θ:_ς*Ÿψ—θz%6DYchδPΘΐ«ΠƒN’»ΟωΗΖz$ϊˆξtθYό‰πρΨή„πΠ‚? χ?θiαύήΘ`͍σ0ώ'=Υζ_Ώδ|Σλή/ύυνζ`¨Ζ5ͺ[¦ΗΡfΨͺ•0”ŸΔόΪ² (’½3ηBŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( /Ζ?μ!ΌΈυmY5`ΔSωp?ZυαΐŠ+J8xQΏ/S ^:-―im6²±ΘxΗΐšˆΨά+KόcΞEΘoχ‡zβΣΐ>-ΣσŸ©ΗεΙΩF>„q^ΗEEL*’ζ΅Ÿ‘Ά6ΔΠ‡³M8φjη‘Z|0Υ―ξVM{T_,uΖG#ΠΐύkΣt=ΛC°[M:!C’z–>€χ5‘EU-:.ρZχ3Εf5ρIF£ΡtZ" ψZζΒζ 4±²zAΘ|7π•ο…ΝρΎšή_?nί$±Ζ3Χ zΧmEi*Q”ΤήθΖš”ιJŒ~Z#?ΔdzΞ‹y§Λ€'Œ¨'ψ[ͺŸΐΰΧ!ποΐ³ψoPΈ½Τf·šfΛ‹Ι$…όΔδx­wτTΚ„'5Q­QTρ•iQ•Ώv[ήΔn,!RI '¦HΕq_|}α‹ΛΩ―gΆ•gEU–$`省]έεF2š›έOR)ю΅ώF'4™΅ί ^iΦ―sM³kHHQ‡VηϊT^Ρ.€WaΰΏΩψrAu,ΏkΏΖ…vͺΊ?­vTVtπT©Λ›wζo_6ΔVƒ§t“ήΚΧ ΰ―Όqρ-y'΅«"9B[~€xΖ?Zοh­κR[)tw90ψš˜w'Oͺ·Ι…2x’xdŠe©VSΠƒΤSθ­tνͺ<Ύ_C-ŝݠ²IĈͼ(9ΗέΗλ^ΉE…<(ί“©ΩŠΗVΕςϋW{αΏ_ι~6ΊΦgΈ΅ki^fTBΫώrHΞF?Zτ (ͺ₯J4•’g‰ΕTΔΙJ¦ιXΗρv—6³αλΛ g%™@V£žψ³~xrλΓZLφ·²Α,’Ld"HΖξ₯uTPθΕΤU:‚ΕT‡_ w (’΅9Ο?ρΟ‚―όAβ[MFβΦ8a‰–V`Δ«±8ΐ>΅θQYB”a)InΊؚ•‘ sΪ;QZœαEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP^sρΔֈ<7mαϋ¨­n5=AlΪI#nΗ±5θΥδ΄ςZΝΰ›ˆ-ήζh΅˜δHα₯a‚{“Ηγ@ ρ.£ρ'Α:{λ7ΧΊN·₯ېn"ŽŠ€‘ωϊώιΊn»c{£ιΪ‰™ †ύPΒ%` ,2άυό«ΛΌWwγΏι2hVΎώΒ²Ί!n.―.C6ΐA :{ρUώ8θηLπGƒt}>wŒΓ©CoΓ†Λq»λή€=r sKΈΤ[OƒQ΄’ωA&”λΕ7Sρ₯Μ"Τ΅;;YOD–eSω\έΏ„τ/h7Ί¦“¦Γύ£eg,ŸiaΊYBNζ<ςEqΌ£ψ‡Αιβ/ZE«jš€’Ι$·CyPzt'ρ cΆΈ†κšΪT–&WF β*…Ηˆ4{ko΄\j–QΑΌΗζ4ΚαΤg=Ey§Βθ›Γ_όQα+I$m%![λhΩ²!Ι¨φωΗεX?ό€λη̖»j—λ§5΄ΟσG0ΜΑ}NεηΪ€=»ϋcMϋΫ~ίkφ?ωνζΟΟ8₯υm?U€Σ/mΡN †@ψό«ΓΌΰ*o‹ή)Ρ."3hZv˘,‰„<ˆ§%{γqΆμτ›/ ||Σν48ΞΟRΣ€i ‹„,Ή γώ(Φ5-NΗK„M©^Akΰ4σ£NΤμu;s>ŸyosκρHΔW€jšΖ›ͺό]ρΎ*Σ5^ΟKΫmgionΣGη,Κ;œgO₯^πl°Eρfάψ[DΥtέPΆhο­ξ-Z8w€pΐύ}hΡtˆΊM׌5}K«8­μ#…ΛN‘Ϋ;”vγŠΔρ΅qΗ? ΪΕ~ι₯O¦Λ4‘‰1ό²Η±θ9φΑžπυΧΕοX\hφRYZ₯±‚ˆ( Ϊ;f›ρ+ΓφΊΟΖίθΞ¦;§•hβ;v†BSθ@Η€=‡OΧτFα °Τμξ&Šefό­ ζŽšYδHγQ–w8{šρoŒ^ΡΌ/’ιZΧ‡l!Σoν/‘U’Ψl,€ΰ†ΗZ_¨“^π…|—’ι7,אY©i'Uώ$P¬iΊώ‘ͺLΠιڝΤ«Υ"™Xΐ·5ν¬7PΫMq\MŸ.6`ρΧ½|εγ)τrΊeο<-­i:έ•Κ2Λžρ«ΗΡ•½{~Ύ΅έxΚF›βΓΉ$]πLΜΈθHPͺ^ή[X[™οgŠήp^F £ρ4——ΦΆVΖβςζ ω’8UόΝyΟν@ψ]{Ÿωνσ¬ί‹Z-ύΩπ¦ͺΊTšή§Χšr7. Œ6;γΣΫή€=7LρͺHcΣu;;©πΓ2±ό­:σ‡·_u­j;ΏιΦΦν²°0<^LΙ‘†ωz>΅ιτΜx(jbmkϋSZ΄Υνδ,mΣ'·Έτφ«Χ)ΠmϊΟΐ81΄κ?Lךό+ΆΉΌΣ~%ZΨΜ`»›R»ŽGπ9ήΏAgΒmα O‡@ψ‰αqa©ξ(χΧ0οŽα²~a ι@CΕ"KΙ«£ «)Θ"›sq ¬5Μ©H2ΞμΔΤDvΪ]¬:`ŒX€j°ˆΞWf8ΑτΕywΕxOˆώ!ψGΒ—2:ι7eΥΤjΕ|Πƒ!IΈΗγ@_όSj 5λŸλ΅άIi8.™™θxΰ‘]Ξ…>|;§Os'&Φ7wsί`$“^Aρηΐ:πφοTΡ¬!ΣξlΪ-Ζάl£:©V―$Β“γ­%·ƒ|€fδZj~XΊΐ™$‰2€]Γς \°ρ¨]kVΚβΰΛ8ζVoΘΊ—Φ²^½š\ΒΧQζ„8ޣԎ΅σ—Γςθp·ƒ|)išε›£ΪάΕ§ΌgƒΞζο]G‰ηΠ‘yok θσHΞΌ·β>-ψ­α― ΖwYX©ίΠγξƒώŽΉ-WZΣu_‹Ϊϋψ§KΤu{,‹[;K{vš8Θΰ³(υ ž}}¨θ 7R±Υ σ΄ΫΈ.’Ξ7ΒαΗι\ΓνJφοβΔ K›©₯Ά΅–άA±+Cηhνœ γόqΏΕλFπ¦‹ͺιš‘₯δ3Ϊ΄Q,ЬΚΐ@?ίψ/‘ρCβ„ΐdΖΦο\$†€=#TΧt%•u=JΡ› šUR3W,ξνοmΦ{9βžθρ°`^5πwΒΊ_‹΄›οψ’Ϊ=SQΏ»”)Ή„Q©ΐP:sψb¬ψ>Ρ<ρ―Pπή”]tkϋ~–ε²°ΎpBϊ ƒϊP¨άkšU΄SKq¨ΪG/εΘΟ*€ύΣΟ_j›MΤ¬΅8<ν:ξ ¨³πΈqϊW‰|;πŽ—β/ˆ>7ΉΧ-Φφ mAΦ+yNc IΛ•ξpόκόš]·Ύ7θqh -tέnέ{Dϋ›Χψ€νό?‘υ ]Τυ;..₯yokΰ4σ₯Σu+-R?N»‚κ›αpγτ―Ÿυ-oMΥΎ.x†_ιzŽ―g¦7Ω,ν-νΪhβ#†fΉ ž}}«Oΐ—Ϋό_Ά>Ρu]3AΤ-έnαžΥ’‰dTfVπ>θ{V©¬iΊJ«jwΦΦŠέ Οη^}―λ²ΝρsΑπιΊ‰“MΉΆ™a—1ΘGBqΑ¬OθV>:ρΗ‹΅―š‚Ωέύ† †R%^§oOOΧΦ«\ψ^ΓΓ?|8ΊDBήΚξΪIEΊŸ’7ƒmωxυΝ{s>ρˆ ώ³i}iζ§Ω­bϋφ£!ώΌ~UΣW•|1’‰ρ#ώΎ’ΠZ€= γΔ=΅¨ΉΈΤμ£·,PHΣ(RΓ¨ΞzŠ΅§ίΩκ6β}>κ˜OβpΓσαΌ€k–ZΦ«Ϊ₯ϋ&₯5½ΌSόΡΔ£ H^™%ΏJΫπ6oᯍ^"Ρ΄…0isYEt-ωΞ3ωώtλsK<³:Η ³1ΐԚβόρIρ κbK›K_³_5€§@\8Τ’? μ/μνυ 9­/aIν¦]²E Κ°τ"Ό_ΰW…΄+ϋ?ά^ι6sΟk­ΝρcUT@ tZάπ|pρ­ξ ΡιpiΡH#–LF„…Ιη]ώ—­iz©a¦j·ezˆeGε^7¨ψjΟΔί΄F©oͺ!šΚ₯’αd;ή£'8«;Π΄ίόAπχ†­cӞχP[9άmY#, ‚:tc@Λ}ymanΣήάEo υy\*ΔΥ}+YΣuefονnΒ}ο&Pψό«Δ~%κ֚‡Ζ(4ΟYίκ.™h&V‘|Ι3¨μ2? ;ΥUΊ²‡β‡5ψwX•εϋ> dρC$lF 8Ιηι@CΥ-SVΣτ¨„šν΅’43ωΥΪρoθΆ^;ψ‡βέSΔ°­τZuΟΨ­-¦ζ8€ΞNή‡8­zφ›©XκpyΪuάQtί ΗιI>«§ΫΙ:O{oΐ‘εW€τ'Ό‡W­όρ‡Βςxu>Λc―y–χ6qœG•Ϋσνχ‡εοUο|9gβ_ΪW·ΥTΝc ”2½Ήl,€"€w9Ε{—¬ιšΆομΛϋ[½Ώ{Ι”>?*±{ymcnΣήΟ―W‘‚¨όMx·Δ­ Γΐž&πŸˆ<1zsI|Ά—0ΐ6€±·\―N™ˆͺŸ5{kο‹Ά:N»k’iφ’v²΄ˆΙζΘά†eG#ςχ l΅­3Vt»ϋ[½Ÿ{Ι”>?*–}FΚ €Š{Έ#–4σ]@ ―χ΅xΧv0ψχΓzό9¬iLnήωM“Ε‘1$cdσ[~)πύ·‰hX,uΟbΊRΟ4!ˆ…c…lu γΪ€=sLΧ΄RV‹MΤ¬ξ€^« ΚΔ~Φ•x—Ε? ι>Υό!¬ψrΚ-:λϋM-Ÿμγ`‘‚ϋΈόkΫhGρ£sρ{ZΠe•›m`“ƁC–PN]εxV₯‰dψλ―M§Γv4ψόΣz€©L―LwΞ(ΦΌm¨\i^Υ―μΨ-Ν½»ΙqP|;Υ.u―θΊ– κχW6Λ$Œ'ΪΌΫΖΦΧΒZ±Υ/|<Φ"έόε†7Wγ#­WΧ5»­ φj%°‘’žβΪq"œ œ~ƒzθρ.ˆoΎΖ5k΅ηo•ημϊc5‘wuogw4pŐ»δ`£$ΰ šωκίΑ‡Α¦[xG^ώ[έίgΈ”ΝŒ‡-ώχn˜­o^κ—Ÿ³}ΌΊ²Ο€²ΒŒfR―•”NyΟJφ¦Χ4₯Τ“OmFΠ_9ΒΫω«Όρžiu]kLviκΆ›Ύο(LώuΛψαώ…’Ωiχ¦Κ;`"Λ%όί4­!œžzWxS^Ρ5­w_Φό]‘jzέΜΧMΈŽΝ§ŠαG`qςhι;;»{ΫužΞx§…ΎλΖΑ”ώ"¦―ψ/4–ώ=Χμt­;S±πΜπ}ͺή+Έ5ŠPΚ zgqγΪ½’βhνΰ’iέcŠ5,ξΗ@κMeέx—C΄Ές.΅{¦Ξ6<κεš{˜Υ^hΕΊσ!a΄/\ηΌKν £ΌΆΌ/w«,¬ΒK‹['“,z•ύ{)Ώ.¦ΉύœuυžGq΅μH_¨P‡υ `Ίρj`:₯”F|ƒΜ£~zcžjΖ₯ͺXip‰΅Λ{XFš@€ώuεό’άψ3JΦu›DΤu+„YVkŸŸΚP~E@zcΚjzή›ͺό\ρΎ)υ^ΛLaigionΣG30Ισλν@@iΊ•–©§]ΑuqΎ?J·^ ΰ[ˆνώ/Ϋ hΊ™ κξ—pΟjΡD²*3+xόkέnδ·•#mŽΚB·‘Η€3/ΌM‘Ψ\ύžχW±‚ωη$κ­ωf΄νξ!Έf·–9aaθΐ©όkηΗ xHέi<0EΤ·ίΪσCηE8cΖ[ψk¨ψ³{i |#΄³πd‘A§ίΞΆρIn(ΙfΓ{Ÿλ@˜ώο\σι\]¦­w«~͚Ώφ„­5Ε ’ΠΘΗ%Β8Αόˆ…{%׈΄k[”·ΉΥl’ΐ*2‚AιΖj]K[τΕC¨κ6–ΑΖWΝ•WpφΙ―0πΧΓ?έ|.·—Q±KNσO^KσJ²2nnΑrφŸπ7ΑΪGˆ<©β;TΥ.ζf…λ2yQ/W=;Π΅ZάCuMm*M Œ«£θEQΤΌA£ι“¬:ާgm1θ’Μͺ"kΛΎ\·‡τZ[³5Ά‘{)ΆF9Ψ6d/Σ"ΈŸ‡χήΈΠeΏρO†΅}oWΤ$’YL˜ά@ޘ§|ϊPΣΛΡ,ΊΙ «)Θ#ΨΣ«Ι>I{ Ύ½§Io¨C€[έΣ–φ6GXXœ/>Ψ—γ>³s ό6Φo¬\₯ΘD‰u]ξ©‘τ h~hvχŸdŸW°Žη8ςšu Ÿ¦jυνυ΅•›]]OP*ξήξόλΟΌ5π―Β­ΰλ[{έ2›«›uyάfVv,·'ŠΑψGzί„uψŠ$ΤΰΡ/€‚p»ψ€λθAΗΦ€)|4klΦ΅ήΫj2έ3C¦Ϋ\**Ζ§;vu#ώνΊυΆe-έμΙ ΌJYΨy7μη i-ΰ?Xm:Ψκ‰,‘nΆ0W―Π‘ψΧ€xΗN³Τό5¨Α¨[Es…ά$‹‘Έ) ύA  o‡ώ<ΣόW£[]I5­­μςH‹iηψW qא3X>ρEγ?gSΩekx‰Ϊ%ΒF1Πg₯QύŸΌ7’ΛΰM+W“L΄mMfœ‹£σ$`9ϊqXήπŽ›βO‹>7ΈΦΰvΦ· Go!ΜeΨrΔw >¦€=―LΥ,5HŒšmν½­ ΐό©u-NΗK„M©]Αkΰ4­yι~ψχ Α DΆVz”Ώi·‹ˆΨ¨|~ zη5moNΥ~/λςx§LΤu{,‹[;K{vš8Θα™”zO>ΎΤοϊn₯cͺAηi·p]Eœo…Ï­Χƒx"β+‹ΦαMUΣ4=BKΘg΅h’YY•€<€~5ξΣΙεA$˜ΞΕ-   Z·₯ι;΅5KBέͺgσ3βφ»…zΆ₯ κ#rωa.-eΞ˜ ΰc\—ΒO iή5McΕ^+uKΛ›ι!‰.>dŠ5Ζ_\“ψο[4-3ΓυΫMΞ+Kft”ΗΐάdLŸΠP_’ψ—JƒE"Τ΅kHοe΄…™eC±( '&ΊEthΓ«)B2υ―.π—Γ/ Iΰ#¨ι‘]_]Y$³\ΝσIΉ“<7lg”Ÿυ’ψS7φέΧϊœΧο,Ν q‚~‡ήΏ‰τ$ΊΟ¬X,δγΛ3sω֍Υέ½₯³\έO6λŒΘμŒœ~€Wk’ό;Ίπž§o xZφp-δ1_CbψWαόΖδ€{η₯YΤ―'½ύ”|λ™ID1&ζ9$-¨ύ dΌρ&‰gp]κΦ0ΜΐGA9φΝi5Δ+lnTήdά6…υΟ₯y—…>xjٝGM†ξφξΡe–κaΊRΜΉΘn£γιXίξfŸΰ.½ς<‚Νom£f9;Iυ T»ρ&‹g/u«XΒ“Ρ—@p{Žy­kˆn I­₯I‘q•t`ΐώ"Όwΰ―€tGαkz|:…εβ6^δoςΠ1UUΟAž=i~ά7†τ߈VΜνi€]JφΘ͝ƒa;G·κZˆt}6ΰA¨j–VΣ‰,Κ­ωIβ+œx[TΉ΄”dYΛ$rFέφ"Ύ{π ο†'Π$ΌρG†u}oWΏw’βομ/*œ“€ΨιήΊ…2κx#ΖϊmΕ½ό:UͺNtαy#ˆ™Ž~ƒŽΔšνώ κ7ί τ«έJιζ™•Μ“Lω'z“] >*Π'Ήϋ<:ΞσηZά)9ϊfΌ—@Ρυ={φl·°Ρ ϋc‚Β0Ϋ|Υe“>ΰεKαk―‡w²Yhϊη†’Πυ¨ΆŠξ…œc•“ΎHο@εUμο­/Ze΄Ή†f…Μrά6ΖŽ:°Σ΅y†§ΒΏόee;¬ο­†¬™ΰ ήΜ“@₯£g=μΆpέA%ΤC2B  χGZs_Z-ϊΩ5Μ"ρ“ΜXKε}qΧωΏΐσήι~9Π‘ßφ·Ρk@φwΆ·«#Z\E2ΖΕΖαΆ°κ;ΦtΎ*Π"Ί6k:z܏,ά.sτΝyΒΛK½Gΐž9΄Σ&ςon/γ‚@q΅Θ φη½axROizu·‡Ό}αuυEύΫάέCΉ'oο‰{PΠfh–8Θ‚nήXmΗk;Oρ¨ά›{ RΚζqΦ8¦VoΘς―ŽΪ„6–Π-…Ηφ5μίΎŽΘy @Ώ"γAKΖςθRi6Σx'Βšή•ΩJ’[ΟžρδΘcߊϊZΈίψχNΡ|]€hrMlZμHg‘¦ φp c>δ“ωWM’άKw£Ψ\\‘Žy ŽIŒb ‘ŽάאψλÚ4Ό1Ϊm«Η}ά«F™†yoS@Γiiyiφ«[˜fΆηχ¨ΰ―yͺVΎ%ΠξξώΛk«ΨKsœyi:–ΟΣ5ζ,’³²π·„4D]3NΥυ†ql6…†@ϊη>υ₯㏆Α7ίΩZl6ΆP4ΦχPό²+ ΘΛu9Η9 P€wXўF Š2Xœ+”ψS«άkŸ΄kϋΦ/rπν‘Ορ8ΟγŠε>:Νs}/†<5Δ–φϊΕθŠεγ8cΖ@όθΏΆρ>…ux-m΅‹ nIΪ"IΤ±>˜Ν]Τ΅;..₯yokθΣHΞΉέ;αΗ„tιlε³Πν#žΡΦH₯Ϋ— ½ n§ρΓΪ=§~*ψ²οΔ‘‹Λ]γ΅΄΄—˜Χvμ±_ψλν@»¦j–¬F]6ςήξ1Υ‘8•-Ζ§cm$±ά^[Δρ'™"Ό€_Sθ+Θ|M£Ϊxβ…/ό7²ΆΥek;ΛHΈϊa‚φ<ώƒή‘ΧΌ;iβ_Ϊν5Dil"Σy!έ…”‚B†ΖN υύ;[υ4‘τύFεcsͺΫGΎΛ/hχΧfΦΟS²žδuŠ9•›ςΌSβ/ƒ4Ν?βW„μtHŽ™i¬n·ΌŠΥŒk$jA#ΤqZ_Ό'’ψcNΠ΅XC§^Ϊκ0 ’άl.€ΰ†υ dΈ½΅·š(gΈŠ)eΙDwΆN>•RΗ_/ξšΪΛS³ΈΈSƒs+7δ y_Ζ­1uΟψN–I#ŠκYSmm„ ΐΩ\Ζ³~:x;Fπί‡tSΓVqιWρ_ǚΧδm¬­œ‘Τδ~΄μ­β-o…“jΆ"μœy&uݟLf^ήΪΨB&½ΈŠή"Bο‘ΒŒžƒ&Ό›β'Γ―i ΅νtθ“P³ΆσΦπ­i bέNMfόT»–ΰ/‡nξ΄Σ‹)‰ΞIPM{“²’3»U$τͺ§bΪyΎ[Έ 3‰Μ}zT^# x{T'€-eΠ x&·q^ο£(Ωo|G’ΨΜ‘^jΦ0JΰY'PH=;՝EΪ]ιμ’…Ϊ1\2!ΪpηΤ΅η^ψi᫟Ψ6­¦Ε{}yl²Ou7Ν!f\πΗ¦;c±ΎΟ;|ρ%€ς΄«do ˆ±ΞGœ}2Oη@›ΰ|<1eύ«©Ϋκ—›Nϋ»Έόž†₯›Ε e›XΣγ8ςΪu Ÿ¦kΖSYΊΡfk4ω WW;mRE8(C’?Gγ]ί†ΎψJΫΓφq]ιΧ— Ό·;‘’sυτ κφώΖ:φκ"ώόŽ~f υ½/V.4ΝBΦμ§ήΚ•rξόnΪm·‹`[ΙΠ–΅³HΪWnίqz­yΐΌ`ψ·ΰϋŸ θ·Ί*άHπN²Ϋ˜u#wΏ_ε@‘ͺ|AΣtΩψvI­‚InσOpσ!aχPφΙΑύ+ŠϊΦk!yΜ/hAa0q³Ήι^/¬ψgEΈύ‘,lην$΅ΈΣ^ybhΑW“/σάρ֝ρΎk]-ό%αx-§‡BΈ™δΈ΅°CΉγBΕQκXτ [Σ|A£κw ©ΩάΜ½R)•›ς΄λζŸO£5Χ|+­ι:ν”θρMžρ‚½Γzώ5τv3άiφΣJ…$’%vR1΄ έCQ²Σ’σ5 Έ-£ώτ~΅—¬iΊ²³i—φΧj½L2Ηε\_Δ»&§§Γβ«a¨κQ+5½€q4Ο†ΖIEw½pšΦ™ΖΟΏ‡4{Νήφήhξ!š Λ…$Ώ€ s›R±‚Y’šξδ…<Ι€’ϊŸAPišφ“ͺΘΡιΊ•₯Σ―U†Ub?kΘuΏΫx›φˆžΛQάφiiq4ˆY‚[FζΥ?ďi^ρ7ƒ5oΩΕ§\I¨­¬’άlY‡p>Ÿ­{ν塌 =μρ[Β½^V βkΚώ7x©‚lξΌ3¬!ν(cy,ην*ωƒΣPψΞΝ<]ρ―Kπφ¨Lš5‡Ϋ^Ϋ$,²~χ¨αZηhhΪ.₯jš-”V.o£‚XΰR@CHι‘΄σο@@ΤWwPYΐΣ]Ν0―ήy(‰©kΗ<{j<_ρ—FπΎ’ξt[[#{, Ψ>[ƒκ0υ PόA£κ²΄Zf§gw"ςR•ˆό₯Υ5έ'Ie]OR΄΄fθ&•PŸΜΦv—ΰίhgP4{KK¨βdB˜;{ΌΧΰί†τΏιWώ*ρ=€Zž‘u Qp7¬(¨< φ{;»{ΫužΞx§…Ίh‘\[ΆΣ‡`;Οα^aρEMCΗ~Ρmd{;iDπ ν+ ΉG§ΚΓΔΠΌ5πϋΕ?Ψze½›>“pŽρ―ΜΰDΨΙκh7ΗWΊ›πBζιυuΉΥ#7_Ϊ6ΰeHφβΊΝ'Δz]Ύ•¦E¨κΆ‘ήIo+,κ’£±5εϊŸόšΜυεώxKαw†.|dš–›έεΥ²ΌΧrs)fΘnΨΟJτ©ξ!‚Ω&•#W{H́λŸJ[y⹁&·‘%‰ΖUΠδ0υΌΒχΧr| ρΆ—{;\6“φ‹Xδn»Aωζ½SαWό“ŸΧ’PγkrΪάά›λo"Ψ•šO0b2;ΨΧ3πϋΗϊw‹4¨ξd–ΦκYδ‰-LΐΉˆSŽΌŽkŠψ[§Ω꺏­΅ xmΞ«3δ]ΚH@Aό Kϋ=xoEŸΑVZ¬Ϊe£κQέM²ε£Χ@ΑφκΪ¦―§i(―©ί[Z+t3H?Ma}k¨[­Ε…Μ70’Dα”ώ"Ύx΄Φ΄}WβŠ5hΪ–΅φk¦³΄†+Vž(Q œfΆώΞ֟/‘πώ—ͺiώΎΆ24VνqΜ rΉΰw{Mާc5Μ6Wp\KlΫ&Hά1½†­Χ?α―iΤuKέ*Ž}JO6rΙ<Πdšθ(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(―<ψ± jzή£ΰι4»VΈK^+›‚G—#-Ιό+Πθ ΌϋラkΦή]&ΥΧUŠβ`FΘΒ°-Ι’½ІφΪ;Λ9ν§‘š6Ηͺ‘ƒόλΘό-ŒΎZΟ‘[h ―ιI+=•Δ$lͺΗ;\1υ潊ŠσΏ†^ΥνukΔώ(G«κ…T[ΔΫ„‹žη§εNψ- κ~ΡuΘu‹VΆ–γWžζ%,­Ί6TΈ'ΠώUθTPŸx_BΤ¬ώ.xΓWΉ΅hτλΨ­ΦήbΚD…c@x#’_AΤ§ψΡ‘kQZ³ivφ2Ε,ϋ— Δ63žγ΅z δΪΖƒβ_ xϋPρ/„μV°ΥU~Ϋcζpγ£)={ώfΊo xƒΕΎSπ³i:hBZiξœ·`WgEy%ύ‰Ό'ρ7ZΧ΄ υ­;XŽ βU&EpO΅_Τ4Mbγ„ό@tηŠΖ 9ε‹©ςde“δ<δςΐd W¦Q@ƝQρ„b³Ρνšζδ^C!@ΚΏ*ΆIδŠ‡β‡…5]NγDΧΌ2Ρ sG“|qΚp²‘ϋɟλ^‡Ey΅·‹ΌsrπΐΎ{y‹$³]§–ƒΉ94ŠžΦnuŸxΓVΙy}€HϋνYΒ™‘φπ γŒΞ½Šπ―‰vώ<ψαΗ²‡Γ'MΆ…ΦSΧΞΓ€œ2O&½ĚΏ‰44Σ†αγ«Ϊω!gΞ©$l`x"»(Θl4]Δτ_x}%xqΌWΰmCL >ΨΡ‰`9ϋ³/ΜΈ>δcθMuTP—όπΞ³§_[ρl-nω’¬ΚΕbEΐδΤ!UυΔ~ρφ‘βo Ψ&­cͺ*ύ²ΗΜκγψ”ž―βkΦ( 7ΒΎ ρ>―«μΥ<.ΪFš#$Λ5Β³—γ(νΦ³ΌαύFΗβŽου FŽΓRx>Ν!e"PͺαΈ#¨λŠτ:(Ητ |8ΊΤtν7D:ώƒ=Γ\Z΄3*I nͺΑ±‘ΣόšΧπ‡5ˏκ^0ρd1Z_\D-­l£pήDC±#©^“E|ωΰΛΟι>;ρ΅ώ₯―dΪ‹Εqj²ˆδVκO‚F+ͺπήƒβ?όH‡ΕΎ)°U₯„&+"αί'?3cκOει]G<)uαέ_Δ·w3Γ*j—¦ζ1rŠ{χΖ€<ŸXΠΌIαj>$π₯‚jΪ~ͺͺo,|ΐŽ?‰IλλψšιΌ)―ψŸWΥΚjžm#M“ζΝp­#?Gn΅ΩQ@D4ΟψΖZΥm蚼‚v†9U$‚^ύzƒŸειPΩθώ0Φ~*h~&Φ΄€²±Š)!ι2»[¨9δ±cΣ=+Ψθ ΌχΐZ§¦ψΣΗ·Φ­‘qΫHYO˜NΘλή½ Šΰ~ θZ–α½FΫW΅kiεΤ§²ΆQΆΰπO‘€±Π΅(ώ4jzΣΪ°Σ%Σ£…'άΈ.:Œg?₯wτP^;α _ψ\ΦtθΌ9&©₯κƒ]Εy Θ»7ΰΐžΐ φ*(Οt­S‡γV΅­ΛjΛ₯Οa1ΟΉpΞδc9μ{S~)hž³β?\閍<~ͺ—LG—d%Ή#=LΧ’Q@_γ― kΪŽm|gα"ΌΊ}šςΕά!š>Ψ'Ώς©‘ψŸΕڞ―iΟƒδΣlK€\\\‘Ϊ1ό*9'5ήQ@yEΞ‘β_xΫVΦ<9¦ gHΥΘ’βΥ%T–)Gρ.zŽΌ{ϋW«Ρ@U£θ^#ρ_Δ x¦Εt« - ΩX™δ.έ]ˆγΣςΝλRkΦΏ΅›ί ZE}5½”&kGp†XΚ(Β“ΐ ΰΧΌΧ§xRκΧβ~­βgžkyiΊD3½J€ =±ΕqךOŠ~!x·DŸ^Ρ›DΠt©…ΙŠYUδž@AΗΈιšΥρχ†uΫOΨxΛΒEw{&ΪκΚFΫηΗμOπιΤP’x£Εϊ–­iΗƒ€Σ¬‹€\\\‘Ψ1ό rNj5Πu/ψ^-}•Ώ²Ώ²>ΝφΛ3x;qœτφ―A’€<χラλΆή]&ΥZΧUŠβ`FΘΒ°-Ι’Ά5ύKΔΆή2Ρm4­.+ p~ΫrΗζˆσӞ;v9ͺŠ+Ο΄]R·ψΝkSZ²ι—zCϋ— α”‘Œη±ν^ƒEaxξΚγRπv±ge–ζ{gHΠ71xCώ[oটαE~Ι¨Εj˜ Cε^Fqωqλ^™EyN•βoˆ:^Ÿ¨ψ2MBφύ€́Η'‚{Υο‰š^½β…‚ΤiΛύ΅,Ι%¬R‰ 1  τŠ( hμmγq‡XΥHτ W’Ψi^)ψu―jΓ@Ρ·<=¨NnR(₯T–ݏQΟQΫπμ4P/ΰέcΔ:ΌΧo―hΨφΚΘ8’G<η pJ½γM&M{š—ž\·P4hΩΖ ι[TPŽxRλΗzG…ν<5gανnνβϋ:κ :yώšIοŽζ§πW„5#ΰψt »Sύ₯2έ€({ΉHRp3οψΧQ@ΧΓM:οHπ‡a¨Β`»·ΆT–2A*ΓΆGΖk‰<%γνGаMZΓUU7–>`GWΔ€υυόMzΕΖψSΔ'Υυ}š§†HΣDd™fΈVv~0Žέk―œΘ°HaP…%θN8§Ρ@Y¨ψΖ:†u¦ί|=iε•<΅ΜmgŒœžŸ­TΆψ[yqπf? ίάƚšHn’`IH€άH_¦ S^½Ey4šχΔi΄6…ΥZ/%΅s“ΣLg>ψ«~ΌΎ ^xgNS{©I 3m y’³nl―₯z…‘Y\[xΒΖxΚ]Η§G Η‘Γˆΐ#=:ΦΑMPπΓϋ=?XΆkkΔ’BΡ– @'ŽA"»ͺ(Ξ~ψfϊηΖρk6­ Ά©zΝ ,§ΜŒ©ΖΏ­dΠ’πωΧτx€v³Έ·™Q‘Xηk}I?{%ΰύG[ΤμζŸΔBιRoΔPyΒF+ެGΣόo G⏠κ:<Ο°]G΅_ϋ¬Tώ`Vεδš^±ρEΠ£Ρ_Β’ϊϊή?&A.BΰpΐœτνήΊ†Ήπ§…. Ώ™n5kι$ΉΊtϋ»Ϋ°=IκŠΰώ hz‡Όk§λ6Νkx’ΘΝ`Δxδ+΅Ώ·ϋ]ΕΎvωΡ΄yτΘΕOEyΒ΄ρ_„’ƒΒڏ‡[ξd)©E:l³ΙΟS[Ÿτ-KLρ§/oνZ[ϋ΅’ΪBΚ|ΕΘόkΠ( <ρ.©έόbπΆ³ojΟ¦ΪZΛσξPˆl g'¨θ++YΠ|Gα?j&π‚jΦ:’―Ϋ,|ΐŽ?‰Iΰϊώ&½bŠγ|+βκϊΎΝSΒν€i’2L³\+9~0Žέk±u¬¬2€`ŠZ(Ζ4=?Ζ ΅RΛIΡ?·΄ »–Ί€Ε2€³u ό½λcΖ–ώ%ρ‡Β}^ΪγB6z΄ς(†ΘN¬Ε‘Ιlΰ½Ζ{W§Ρ@š΄ΦώΣνfB³ΗgN™θΑ#σ―+Σ<­]|Φ|?qΩ5)ξεž$waΌ2δ‚F+Ωθ ϋOŽu_  ΫψM4—k_²Kw,θbTΫ΄μPrIΞ£“Β:αύœΟ‡ƒmlQφ]λŸψωΧ8ϋΌυ―e’€2ό?m5―…τΫYΠ€ρYΗ¦z0@όλΟ| αcNψQβ-&φΙ’Τ.€»ha.€ΈuΒς9ϊΧ«Q@ŸΒ.σEψ{’ιڜήςŠΙ •;ΨυŽ„V/|1}o«xδjφ­ ¦©vL,YO™R μ₯TSμp*XΌaγΙcHΐoί€’ν χ9Ξq^›E"d¨άlr­y§Δύ\_xsΕ°”šp’)­7„fVξ όJτΚ(Μ|c‘λ^:𦟨EdΪ'ˆ΄ΫΏ΅YΓpκί2ž2FG8πͺξ§ρΔΊΊ~\χiδ\ίKr!αŠ€rr3τΝzν‘α/xkO`bιkqώ#άώuΜό[πˆτύ:σA‘#Φ΄«umζ}Χ#ψOδ+½’€<λEρ_―/μmoΌ֊ͺέ\΅γLόΜ “ŒΰVv₯’xΒ=ΤόCα=u}7WU7–BEIEθΚO^§σ―V’€<¦ΗFρ'ŒΌu₯λΎ%ΣF₯išΦΝ₯W’I«1c§Υ­m‘jIρο[kV[ιkΟΉp\6vγ9ύ+Π( <ρށ©κ_Ό©YZ΄ΆVΚΧ2†P# pNOαS|dΠυ{ΓvVΪE³\Οό32† „VδςEw΄PžψΣAΤυψ'P³΅ilμ$‘d  F ΰpNOαIρΓAΤόEα;;MΥP†fEe\ “Ι’½Šζ~#iΧz―€5­?O„Νy=«G`Ή½2xWΔ> Τ5Ο‚z^€`Υ­m-ȍΨq,h2ΉzŒΧ¨Q@I¨κίΌC Ν’ &›us‚βώk„1(# PI$g™¦YxS[ΰή{ΓBΚ-·I/œg8ιο^½EeψVΪk/ ivΧHcžhΡАv°PβΌϋαΟ†5+αηŠ4νBΙ‘½»šν ˆΊ’αΣ Θ8δϊΧͺΡ@S₯ψ χSψ†58ώΕ©,{3εΘ―ΉrA#§ΠΣt|BΣ4Ψ4ΛΏΛΘD·It‹€pϊW¬Q@Mβύ#Δ_Δ»Oi:(Φak!m-ΊΘͺπ°'•ΟωλTo΄―x—β…uνGF[ :Ζ䏳yΚςDΈΙ‘ΞqΟL τ―g’€<―Ηϊ?ˆ4‰O‹ό?¦kE «Z\Z¬[ζ{τ©|m λΎ*4iΦcMρ.—+MΓ†Κ“‚…‡…ρ―O’€<Ξ/ψξuŽπΓtpI―DΎ§ δŠτΚ( !Χ΄ψsβ½οŠτϋvΞώΩadIUd€QΖοχ{zše‘βύkβ—‡ΌK¬ιQΨιφλ,BέfWh£aœη’ΔŽqŠφ(Ο¬tJ?Ž:†Έφ¬4©tl——MρΈΞzΫ΅;βΖ…©krψXιv­p,υDΈŸ £d`·$~•ίΡ@gρΓϊν§΄ΟψVΩ/ €Ϊ]Y3„2Ε’FxΟ'τWβE—ŽΌ}₯Ϊ"xlιΦ–—)1·’αY›¦G8A=ϋΧ»Q@y—Δo k‘xΏKρ„‘ŽλP΄„Ϋ\Y»σ’Ι<ΐ?1ύ+Σh /ΒΎ!ρ6±ͺ5 I€Ψ˜Όςά+όa@Ίσ\ž…aβΏ‡zŽŸ₯hmθ3ΞΣژfT’Η•`ΨΘ―`’€<Σΐ>Χ.‘ΰέzΚΞ3-ΝΕ„πΔ€ΉΪ6sΗ$ŠΩ’€<žχΒΪΜΏ!πςY7φΐΆHΝΎυΘa $g8ιοLΣυ_ˆ>πυΎŠΎ]Bξ„ίΕp‚6`3)9wϊW­Ρ@iΰί‡“ιί u] SSΥ£™%!$uΐηΎ8?dxbΗώπν·‡WΒbβζΩL0ί}₯%rpǜρι^ΕEyΑ k‹β+?D#žξυδY‚$V@ sΦ¨|-‡ΕžΫα›ο½Ε€»vMJ)—`ŽI œZυϊ(Θδ#ζ€>¬u+=_O†ϋMΈŽζaΉ$Œδδ|gρKΓΌ6z…ΫKx>τ6λΌ§ϋ݁φΰƒκ>ψ)¬κ—JρΣέY¬ƒψDjcΠ°?Ο½rί³Ώ„tίλο‰ MEβ”K½ZGΛ30<1ϊΠ―ψ3β―†Ό[©&Ÿ¦Ο:_8%"–"»°2pzt»Κηt―xwFΦ_VΡτ‹K+φ„ΓΊΨ»I fΉ†χερެΎ.‹nŒy¬`ά6μ+Ιυώtι±±j[›ύSV.»5ύΎ“q.kέϊεC$›ΞFrέΈΙ €NΧΆ«rΦΝsΈTσ FAΌ'χ±Χτϋ[ˆ.ΰYνfŽx[;dƒ)ΑΗ{ΧΝ—Ύ!ρ)Όρ‰ίH΅£D.3φsΐ*ŸήΙ+]ή•­λώψXκZ%€+§E [ͺάnσ·™›ε99όhΟ]’ΌŽγβ7Š,τ[ήxjπά»²άfuˆΘΖ0r1υθΦΊ–žΊΧl•gŽ;Cu'Ζ܌ΠεδΪ?Žόeβ]. KÞΆ{=ƒ{ά\lσdxGμFO₯oxΏΖχš9Ρtέ;Kϋ_ˆ΅E –ŒϋV.2ۏ ης .wtWhž7ΥνΌ[kαίipXέ^‘kK‹ywΗ!ωNz?Ξk+Δ?5ϋ]cΔΆΪN‰ksm‘”yεyŠ’‡=±Χƒωη­Q^cᯈZ½ˆ48uM"M7\‰δ±u”Ό˜Q‘Όc#š΅ͺψΧXΎρ-ξ‰ΰΝ* ι,p.ξeΩl„c© .z%FΣD³,M" Xd!aΈ\WΰΟέλW:‘©ιλaβ9w=ΆύΙ"ŸΊΚή™Ηζ+Οu«‹z“ijκ‹e †Ί&7Lœ’ΨΰϋP=yRd–VΫjY &ͺθΪ­–΅§E¦N³ΪK’(88¬ˆgΦ.<%©Ώˆ,ν­.ό™@ŽήS"νΨpr@η­yGÏψ¦Λα΅ΌšƒΟ`e–yΆ΄Έ$°Ež΄Ο|’Ή+_ιοπϊ?\ŠΡ‘σ<δξΞ6SΈbΉY|uγ;}ώŸ [†ΞhΕΗϊBΓΧy\zs@\υz+ƒρŸΣGπ†―iP%δΜP¨‘ŠνWV9γΈΫŒVŸΔOΛαM θ-’α€ΊŽίk±PgŠκhCβ‹ίΒΪnžΦΆbσPΤ'[khKνRνΣ'°¨Ό=©xΥ΅›{hΊ|v†έqkpXΔB’HΗ΄ΫFΕ\W*’ύαυ«΄ AEy-Ώˆό[γVƒΑχ–zV‹§LmΝδΠω―;ƒƒ΄1Ης«ώ ρf·kγiΌγ?³Ι~Π™μο ]‹p£’ φ8ώ‚OK’Όq†΄t?x§Aψ…cα―έΪjPjPΌ–·PΕε0e*@φ R¬7\‚YΤtΨ‘%²Ϊέ0­ŸCZΥΙψkZΌΎρˆτϋ†Cmdc€Έ#9ΞO~•€#Ν>ίζg9rΚ+ΏωeεΪΏβΟMi§Kkl-n^ςH³ςτT λΑ$ύ+gΔΪώ­€G£θΆ>Mοˆ/FΣ#.cο>??Κ΄xi)r]\ΝbbγΝgcΈ’Ή]ΗΕ–ϊŒ/«jΦwVg>liΦqƒυͺ²œy]“Ή΄%ΜՎsÞ)YΡυ @ΪΙYΙ"2½›`Ο_JKŸΓƒ$ρ VΣ4*›Δ2|Œ~`΅Μό4ν|βˆˆEqq"δgΉjϊ•Ζ―πZζϊτ«\K,Uvυ€tΉPŠ©kiΜ‘Θ«KΩήϊΩ³Π΄ϋ‘ycorhš5}ΉΞ23V+Ξ4eρ₯χ‡ν/,nμ,⩆ΥβάΞ qΉ»fΆ|5γυέjΧρyΨο[˜ΧϋΚ;g׏Ʊβο­΄6…tμ₯¦—:κ+Ξ΄ϋ―kšgφŝ協2$mβΛΫ-οWνΌ[>‘πχPΥαEƒP΄GIŒ…‘zώ<<–Ν=mθ Ρ­/κvΤWŸxnχΕΎ$·±Τ’βΧOΣΙ\ΖΡnyΤ˜ϋg½Ϋx–ηPΫ€_ΩYX„;ΕΎBέϊρŠ™Qε—+’ksG™EΖx?[Υ_ΔZ–―<3έZΖ³GΩ•e:.*χM^Ɛ¬€νfžζύGs6t™υYuM>o³‘–KU·Β•œ7^•ΔKϋνSαΌz”ΡAi4*χΛ>β =‡ZΈαο(efμL±MΩέ+žŽŽ²"ΊΚΓ Žβ–ΉŸZλΫΐϊ¦£mshΠ/—pμe8ΙοΕtՌγΚμΝ‘.ev¬s1ρα9-“Q†ϊSp―Ω­Ϊ\cqΣ­rιρ―Γ;κΝ2 ΄bΝ‹(χιδΤ^IΰΥπΠ>6ϋ?Κ:‚c⍍§„αΧ¬μ.ζ‚KΥ²ςζS#;°GNkΠλΘiy³”.vj6=pκrόNΆΠ§ρΤ4¨Ό¨MΑΎΟœ +Ώΰ=θΡψ¦?κ·χXς₯·‡Λωw/Qλšτκ#WΠμ5ŒΔ. I‚»†qšΏ^+ΰΈώ"jΎ Σ/4½GMΣ,β΅UΆ΅’ίΜi•Ff=3ŽΥΫό-ρUΧ‹Ό&χ—qG£m<–“ͺύΟ1δ{|Β€;:+Λ΅;?‰ρΨ]j\ΡγšiVΖ+]Κΐvο<ζYψήοTψ3wβ›tŽ F;9dΐU‘3Ξn3ŠτZ+Θ<9yρ#ΖΆΦl΅=3I†Xσ -mζ4Ψώ&' '=+kΐ5ΤƒXŽΥ­VWeς™χƒŽΈsΕΊύΏ†t+Vξζ†e ]ΜrqΈ―ΩΟώIm‡ύv—B­Ο‹zνο†ό ¨jz["έΓ³at 9`€:ΛIΦζΦΠ2¬¨ žEK^iρΖ:•oα‹.[;K½dͺ5νΨύΤ?(=:d“Εiψ{LρΝ–΅nΪΎΏ§jZQέη(΅ςδm#ŽΈλΪ€;Šε|γρ»βM5-£] bεχyΌ°Θγξώ΅ΥWΟ~ “Δσ|IρώŸαY--|έE€žςε ˆΒ»€{“»τ ‘(―0πη‰ΌG’ψςΫΒΎ2–Φχνρ4–WΠGεο* *ΛΣ ?δΦv­γ]|JΦ<'αΤ΅g ‘\LŸ-¬`|μΨϋΔ–Pz'‹όKmα}:+ΛΘ.gŽI’°&ζŽ>ΥΈ§ ZςΟjώ)πw‚lεΤ5K[νV]F8šu· ΎS6νυλΝi|Lρ~§€]hΪ†‘†]{Wr±4Γ)Όδ{JθΌ{β5π—„ου··7+k³1Ϊ[sͺuf΅τΫ‘{§Zέ…Ψ'‰%ۜγp­x?Ζ8όs€ό?Ώ‹^Τ,5}2ν£ŽWŠ)νΨH¬§Ž ’»]·‹όU}αΏx^ίFŽΥuA¬nR< Λίqο@•ExŸŽ΅ˆ\Σx’Ξζήϊε-€?bQδ–=@ξ+£ρ§Š5έ΄ ιOm}βO άH›cE\–¨φjτš+Θ΅-Ζ^Τ΄»_Ωk%υΐ΅‘ΰ€Dπ; ©γ¨ΰώU―ρ ΕΊΔ>&|+α%·ώΧΏˆά=ΔλΉ ‡$nΗsς·εο@Ÿ|^ž πϊj’Z5Ψk„ƒΛWΩχ9Ξ₯uUσ‡Ηόe¦ψ^ΟΔ—ΦZ­„χhλs >SΖκΚ@ΰ‚ ό«θρ€+άήΫ[Oo ΔρΗ-Γ…°\’―bΌ;β„%—βΟ…!ΆΥm!΄Ν` ˆ8]ΕΖ~bxϊWUβΏλ^πlMͺMo¬x‚ξγμφ‚Ό΅vnƒo·λ‘@Eyͺ~(hZ4šεΖ©₯ίύ<ιτΤΆΪX+υ$ ώUθžΧ ρ7†μ5{U+ΤaφͺzψΠΏ½ΆΣνšβϊxΰHδlIΐͺž'ΥF…αέKUhŒΛenσ˜ΑΖν œg·JςΪIuoψGlšΦς΄ΦΉ‰$„ΖK΄›ŽΣ»?tzVΟ‰l|IgπγΕπ’κ֚€m:_+Θ·ςΆ|œϊΠmαm\kώΣυU„Β·q De³·=³Z•αbψ«ψKŸGΤtέ&Β[Ε$kΞψ˜ž€ŸJμΎψή}sΒΊ₯ηˆ"ŽΪχHšH/ tμ]Ε€νΖxφ ϊŠρύVρŽ΄ω5ΝPΣ΄m1έ–ΞήX­*©#,Η§ Ž+¬ψ[βλi7i©ΐΆϊΆpΦ—hŸwxξΎΖ€:mwT·Ρ4‹½Jτ°ΆΆŒΙ!Q“θ+7Α^-όe₯=ώ‹#Ό)!‰„‹΅ƒOΖ©όY’mβϊτjσƒΏρIψ«KΣΙΩaβMΪφzyλοRwΖ€=ŸΔΪε—†τ;­[TΗinrIΙ;’H¨|#βKθ‘jΊIΪHΜͺd]§*pxό+Ο>0ξρ?‰΄BI·ΛjWψ="Œυ<}H«Ώ³ΞψUVΎNΠώuΖάτΞφΗα@ŸLžXΰ†I¦uH£Rξμp’My†­kρ6ΫM»ΤΞ»£¬#L,c΅Κ°PNέǜΰVwŠΌE«ψ―ΰLšζŸ=½›k ΏŒ‘bκ FT=³Ο―€=zΦβ»hξ-€Ya‘C#©Θ`{Š–ΌΣα-—‰ΰΠ4›CX³ŸH6@Εj–Ϋ]xrέρ\ΧƒΌSγο[έΑ€\Xιιeq$sjC»yΙڊ½8\dϋŠυ=CΔΦΦ>*Σ4-ξZζύD•1¨Q“Έφι[΅ηwΊώ³¦όDπ‡‡ξ.aš;«)ρΔ@%Dε‡χA#8¨n|a¨ψ_β!ΌW4_Ψz-§^l"aΦ7?¦~ž΄ιTWψĺό|I©jVμxFݍ½¨1χN:Έoξϊ½kΡ(’Ό/ΐ^(ψ…γύ Ά›ua¦₯³²M},Μ­Τ*―@κk¦ρwŠόAΏ€x;ΓfΪ]~{q5έμɘαP9m£ΉΑ?ˆυ N’Ό‡UρŒ~ίiΧ+Ύ²Φ4+©„O·cΠρΤ…nόHρv©§jϊO‡<+ 2λš™,―8ΚCκΔ}ό¨Πh―ΧυŸψ+m[_Ώ±Χ4S*Ηv"·<Ž:ŒρωV§Εκž‡Γ3ψu"ΈώΈςό§λC(Ϊ3Ϋ’(Σ(―ρ^ΉρΐΆVϊφ΅¦κzq™RζΞ<³oξ·_ΔΤϊ΅χΔ•πΜΎ)ŠϋL·!ϋXώΟΈˆ±»Ο;Άύ(Ψ+˜ρχ‹Β6W/hΧ"ζι-‚‡Ϋ·qλ―ψ;Y!πΎ™«ςΝά )Oξ“Τ~uηΏ΄Α΅πŽ™py‡QŠMΏήΖN(Φ¨―&Υ⍞.Ίo4’aν€­Ή$ δώ₯€Θγ©­‹ί‰πό.‡Ε‘[ο’uTŠΫ=fc·oΣ9όz rΏ|^ž πςj’Z5Ϊ΅ΒAε«μϋΐσœJβ5+―‰š?‡Ο‰.΅-.α"Aq>–ΆψΫRυΘKγ~·oβ?‚ϊV―h Γww[ͺœ8 ύ#π n(βwŒo΄tΓΦράkΪ΄ž\^R%Λ°όCι\χˆ5/ˆ>±MoVΤl5½67QwoΈ‰’Rz©qο@ΏEyΞ©γΛoψJ(fό;ΫŸ Ȑε;½ΑVΕ?ˆϊ·‡|kge€„m:Ρ"›SΚ!^@ g·υ c’ΌβOŠ―τέCšg‡εŒ^k€dή<…qφΞεηλ^€:PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP^ ϋYΘAο Χ½Φ^½αν#ΔΕ·§[_$D² ΣpR{ŠρΏŒ?ςo^v?ϊ&Έϋ†φϊΑm3Δz,u{ui§ IσΣ<ρκ0η_Jju&.ϋOΆΈΣα #·‘2‹΄ap=‡gNΣl΄έ=,l-b‚ΝU… νŠσ/†ώ'‹βOΓ[ύ"wH΅hνšuθW ‡ΏΈ>ΥεŸΌiΓMkWΡΌWoqk7°BΖ)#9 Žγ5τ†α=DΌ{½#I΄³ΉpU€†0€ƒΤRkήΠ<@αυ&ξ@0HΑaψυ   όRπ犼BtBΣ™š‘€€9ΓgŸJ_όMΠό[β+νMŽρ.mC6ω£$ pJIλκnθΠ|?#I£i6–r0ΪΟ`1™§θώΡ4mBζϋKΣ-­nξsζΛ`ΆNOλ@Σͺjγ>!^kΝU‡Mϋ"<σΌ°y»ΡW8ŒtΞncjΜΏ³·Ώ³šφžΪe)$n2¬cAHωžΫEρϊ?…΄ŸνXxŠν΅ ΫόΡ²Εάη‘ΘγΪ½+βΕ₯gπnώ jφ+λΥuέ4qyjFώܞ‚½4M1.μξ–Ζqg†ή@œΔ„`ͺϊ ζ~2ιwΊΗΓύBΛLΆ’ζιΚm‰IΓ Π9ψΏDΉψ ήEΤ/5Ռv±Ϋ+ …R»Ω9ό«vφk³[]Y£pέAΩΠΦΆ•ΰoΖφz„Ί%˜Τ’4-!ˆd8'Σ9šςΦ ΫYmβI­εRŒ†¨4 ζ~"§Γ…Ξ3ψ‘“\Ÿ.’Ρ>4xkTΤΫΚΣη΅’ΤNό$rγ'Άrγ^£cioag ­œ) ΄*8ΠaUG@WΦ4?Z³6Ί΅œvδηdͺgΦ€<·Η—Φή ψ­ΰktΊžΚvΉΈhX0DʞHφSωŠΟa/ŒυΖύZυψ_DπρθΊm΅£H0Νa˜{ž΅?φ•ΏQ°[ξΤ@ggϊπ3ή½Oη@Xς{^.~cώ}‡ώ“ŠΙπށ£Ώ<[§ψ›RΎΣ―žωξmό»Ζ·Y’rH# y―o]KS§cnœ»m>OυpΎœqPkώΡΌΤ&K{W²–,‡jξΙγ?ˆϋAπζαψέ4m:ήΜ?ίς“Ύ§½M¬hΪn΅n Υ¬mο!!f@ΐP•ε΅χ‡u)lξ"ž?³Κ7Fα†v2+‰ψLψ-[iΟώ…]ή—‘ιšNŸ%Ž›comg!%α0­‘ƒ‘τ©l4»?N}•¬PY*!EΒ€zŒP„G§άκ?²ύ²Y£;Δο3*ςJ¬ξMnιžπ§αΈ―dρ%ϊΩΛσR]U€PǦ€ρŽAλzf™e₯ιιc§ZΕof™Ϋ k…$ž=Ι5?ΓΟ OvneΠ, Ε·επO:P+Ε}7O°ψG‘.„ο.‘gι!%ΏvwΩτˏΦψίβm&ϋÚ5­μ3\ίA*¬N„;Ž:@όkΦ'Σl§ΣNšΦ±dςΜΝΎ˜¬[OψZŠ ΕQ™\(rα@μSψ¦ψwXll|Mx–eά5¬¦_-„€ =ρ\>•©xcβ6‡’XxžOιΧϋ–X&a$ άX~…zΎ· ιzνͺ[κφ0]Β‡*²vŸQιUt h>•₯Ρτ»kYX`Θ‰σcΣ4ΌΏx}jνRA–Z»@€xΗΑ}JΟΒ·Ύ#πΆ·qυ½σΝžΑDўŒ€υΰψΣ‘Ί‡ΕΏ΄ φŒΒβΓC²tΈΉ”.ΑΐP{œΏθkυ θ^!dmkK΅ΌtW–0X―Z·£hϊv‰kφm"Κ 83 PMžmπΔψ[ŸŽ9σaϊIγ―ω-ΏλΧώ€kΡ¬΄>ΖώςφΞΞnο7’α₯#¦γί©’λIΣξ΅;MBζo­'eΛGΈ`ΰφΝ^ΑςQ|cώτ?ϋ5wΥVΫO΄Ά»ΈΊ··Ž;‹Œy²(Γ>:gσ­!5Ιw_©œΰε(ΎΟτ8Ÿƒΰ}‡]=΄€ώB‘ρΔλ’όBπξ΅xΣΒ=Ό’γ"2ΐŒŸϋλ?LΧy§ιΦzrΚΆ6Ρ@²Ή‘ΔkΜz“οO½΄·Ύ·h/ Žx[ͺHΉ΅φλΪΉΫGώV2φΩ(_Uώw*Ϋλš]ΜπΓo¨ZΛ,ΩςΡ%·ΰj4ΝoNΥ.―-¬.–iνdΚOβ9ιΪ«ιžΡ4»‘sa¦ΫAp2ŠΌŒϊU» &ΓOΉΊΈ²΅Š[|ΣϿζk9{=msXϋM/cΟΎΘ‰βϊνu Uu’ υΗjŠτ«M*ΒΞΦ{k[Hb‚rΖHΥp·\ύi‘§/ϋ8YΓφ cΘΫςc9ιυ­ή&.\ΦκŸά`°νFΧθΧήsήρNŽ<#g<Χ°Cδ@XΩ€d*9λšδΌ/¦]κΏόS418mJi&·NμΟS‘^ƒwαMςΰOs₯ZI(ώ#­˜£HbXβEHΠaUF‚§ΫΖpZΆžΎCφ2•”ή‰[O3ΘΌ€xSSπύ»έj0^F»'‰―=¬:ρž•Ώ}§hΪoΓ]y<=7i"HμβO0ΐŸΐWKα=PΉ7šU¬³1ΙrœŸ­^M*Β=5΄τ΄…l™J˜αH=F*§‰Ri¦χ½‰†ΕZΛk\‘ΰPƒ4< ‘Ε Šαμž/xŸ^ΔΊΌφ±Ω\4PY₯Η’»?1Η^―P΅·ŠΦΪ+{hΦ8bPˆŠ0€V^§αTΉϋF‘¦ΫO?χέ9?_ZŠu£IΎΏz4)8Ε.Ÿ‰ΐ|<ώΟ…¬ μ–Λj;1mΨtΙυ―@·ΥτύoϋJΗO»Yn-ΑŠe„‚;Ž ΅k₯XZ\ νm!†a’³9Ϋτ€°l4ϋ›«‹+X‘šε·Lκ0\ϋώf•Z±¨ω΅½•Ώΰ…*R¦ΉtέHΰΎkznq£jsGg¨Z\>ψζ`„‚zŒυοW>*^Ϊκ’k)βΈ‡νQ.ψΨ0Θ~Fk¨Υ|5£jΣ ΅:Ϊyzodησ©°΄ΏμΕΣΎΑoφ`Β Ÿ.sœβ­Φ§ν[;ήδͺ3φn•Υ­anF<=(>Κτ ςϋ-VϋGψ'os¦1IŒΞ†@9E2ΆH―_hΡ’12»JφΗ₯TƒJ°ƒN:|6₯‘œœž>¦’•hΑY«κŸζUJR›ΊvΡ―Θςοiώ²π•ΕΓkž‘,$BMΫ9‘Θ봃©φ‘ͺ£Iπ6 ŠX‹Xρ†k΄²π…c#½¦•iΊ•bt<ZPΩ[CdΆqAΪͺμωBϊb΅x•₯μ署Γ=oeum ­[ΣΓΠ\-μ(mD’ΰμU_˜‘νVΌ9―ιž$ΣPΡ.–κ͘ +/#¨ΑІΛΒϊ%‰Έ6še΄_hC»Sο)κ§Ψ՝ FΣτ=lt‹H­-U‹γ=MrΟ•ΚρΨι‡2₯Ή‘^Kΰίω8/ל?Κ:υͺ‘o£ιΦΪ΅Ξ§œ1κ*k…\<€cžύεPYζί΄Š‡πU‚°N₯ χΧ‘x»ώE]cώ½%Π XΦ4?Y·H5[8nαG*J»€aΠύjέΔ1άA$3’ΙŠUΡ†CΤπKίω5˜λŠθΪτj j>4―ΙdβέΈp„£%O―5Π·‡t†ΠƌΪu±€ΐ΅)ϋΌg=>΄ΝoΓ.Ήk Ά­¦[]CΔK"g`φτ %]ΌρAΠό1―Λ«hϊ‹2M§Ι(˜Ϊ¨0aΠΏ―r¬=ΒZ‡δ2hΪM₯œŒ0^8ΐb>½kr€ΐϋ _ϊ―$π&«}’ό ρΞ‘₯τΘ5{¦FΖvό± Ψφ―w΄Ά†ΞΦ+kXΦ("PˆŠ0G ©¦θšf™iqkaco½Δ,±’μbGr@β0ΨxMΌΊζΏβ[έ[SžΧΜ1ύ½²Σ2ηΛXΑΰξ8ΕYπwό›«^—_Φ½CNπ'…τνD_YhVέ©ά²,C*}G₯iΓ ιPhςι0Ψ[¦›(e{eL#κχ  …€/Γ―0>Ɵʼϋαoό‹_λϊοEšφK+K{H­lαHmβP‘Ζƒ  vͺXθz]Œ7‘YΨΫΓγ3ά*&¬Γ·h‹ύŸ@ t|¦_ύΥ“πφqρ β¬ pKθJJ+Τ4­6ΛH±ŽΛLΆŠΦ<μŠ%ΒNNΦ™c€ιφΧ·–vΓuzΚΧ2’α₯#8,{γ'σ ž>xwΒ—·ϊWŠ/―tνvΚκD’½hΣ<2ŒγΨύ=λΤΌαοιOα[ΣwtπωwMφ£9>΅kήπφΏ8›X,ξ¦cΖ7~uoDπώ“‘ΪΙm€iφΦpIχ$ λλ@7μη$ΆΓώ»K‘UΪώI^­υCάιUŽb–zU¬V–¨IX’]ͺ λΕ.«¦Ωjφ2YκvΡ]ZɍρJΉVΗ<ŠεuΨ|-©xwIΌ[%κΠ₯Γ„bBŒ•>ΌΧ€Hή ψ“ θ^ΧεΥ΄}D²Νa$‚cj pΑ‡@:ώ½k[πΖ‹[Co«ι–ΧpΒ1Θ™Ψ=½)š„τ»>₯ZYΘΓγŒ#λΦ€6λΒώψ‡N>+xώΟRΈŠΥοέ’’VΪ¬Uί+“ίζΟα^ιX7žπυμwQέhΦR­ΤΖy·DωV>τηZζ£m⟎>·Ρ&K¨τ˜εžξxŽεL©ΒδqΧρ«ήώnj›"ΞŸΔW xsGπτ/‹§[Y#ςήR`·Τχ«ϊNŸmͺ\κ0ZCύΚ„šu\;Π@{ϋBΘ₯§ΨNίBͺ.SΓόβC)₯"Ιk4δ|±3 }=}z–­₯Xjφι©i Τ(βEIWp :­?SΣ¬΅K'΄ΤmaΉ΅q†ŠU §π 'ύ ΌY£KπβσN΄Ύ·»»Ύx„i‡!VErΗχŸRΩ~hw3#­ΜΤΫ\«φg*σŽΐvϊW{eΰ/ ΩAs Άƒ`‘\ΙWΚzη8>Υΐό^Άk_xfmZΖζοΑVΡšΪΪ2κ’ ΰΊŽ«Έϊ©₯Ε‘kš“/‰ώ"ΩkFΞE–ήΡJB­ θXg$Τtλ$ψ‰αmW_7 αω­gΈΚ˜ηiά: OΆk;Η~ ρ‡§όα‰υ‰π°< ˆδ|ň«ΩΕPFN:d΅{¨ι\Ν·€Ό+me-€: ‚ΫΚC:y@ξ δgι]5y/ΕK¨tߊ_οο€X,Υ¦s…Rvc'΅7㌩6—αίιεo­4]R;‰ό†ς‚ ιτzfΉ’iΊυŸΩu‹(/-σΈ$ΛΈκ=)š>₯hΪciΪe„φ,IhU~V'G|Π/γxv^ίΓ©Ϊά,φΜ°E†yY†BυΞO>œζ€ψ-₯\h tk[Δhζ1™Yͺοbΐ~΅‘iΰ Z_ ΛmOŽδΑΔCƒκ+§ +ύ£_C6Φ1Γ} Ή8<Φχ΅};Vψgβi4Λλ{΄:l͘d ΑCƒΕuχφvΪ…€Ά·ΠGqm(ΪρΘ»•‡Έ¬m/Αžνom¬4{H-οSΛΈS‰WŸ”ϋrh—Βe πΫΓΑ@μ‹ΐ―?ψqa.§αο‰Ά6ίλξ/ξ#Œz±Nη^Νcgoag ₯”)΄+Ά8ΠaTzPizFŸ₯5ΙΣ¬αΆ72¦1<Η=XϋΠΟί |?ΰΝSΓ1Α­κ7–Υ£ΌwVΟ~Π`†8!r8Ζ?Χό6Πό1£ΫjΒ7_jŠYΏ$ϋGϋΐ:gךΏ­xΓ:έΩΊΥ4[+›“ΦFŒn?Sή΅tm#OΡlΕ“g₯Έ9ςαP£>΄ƒρgώI·ˆλΡ«ΞΌ[cqΑΟψ—N_τύΦΞι}ΣΛ@ΐϋtΟΆkΪ―μνυ 9­/aIν¦]²Fγ*ΓЊϋ2Λϋ$ie‹ϋ8Cφ³νω<ΌmۏLq@[π©ŸΔ“ψ§ΖΧ<Ϊ­­ϊ€:~'ϊV/5[ύφq»Τ4ž/!iΚ63³χ€ό5νšv™e¦ιΙaak½š« k…υγρ¨τέMΣ4Γ§XYA‰έ˜O›―ταςiή…~ΪΞ΅β[Ν[TžΤΈS~Δ΄ΜΌ"Ζ1Ζ1VΌ-Νϋ/_$JYΎΛpp8Iύz†ΰO ιΊ€½±Π¬!Ί"EˆeO·₯lišU†•§-†i ΅’δc\ Ο^=σ@―ΒέkMΎπ‹₯υΌ· f’YπTrλΕa~ΞjƒuRκχϋπ•Ϊi> πΎ‘¦hφ–·Œ ™cLΏiιM†lφϊU€6Ό†VH—h.z·ΤΰPœψ³ώKΗƒ?ληA5—ρdΛρΔ–žΡV2-›νz…λ.αl (χ9Η£ή½j}&ΒγTΆΤ§΄…ο픬3²εΠ zf—’ιΊTχSiΦP[MtώdοΰΘή¬{υ  ΰΎΈa³ŸΑΪ¬Ii­h§Λ1¨Ϊ&‹ƒ$dϊf½ Aπ‡‡τ šmH³΄™† ‘ΖcλZš…¦§i%‘mΝ³Œ4r¨e? -ψιβm2ϋΑhz]Τϊž«,PΫΑ ί Xγ γσ" ψ“fl>ZJ2πί$mžy+Π΄OψoCΊϋN“£YZάv‘#‡Πφ­=GI°Τ¦΅–ώ‰-_́€\˜ΫΤzσοΪ7ώImχύv‹BŸΕ# ΅0:eΏώŠ5΅¬iVΝ‹YꢐέΪ±’•w)#§<φ°Ofφ“DlθchΨ|₯HΖ1ιŠδ~ Ι0πχύ{ζk—ύ₯d0ψ;N”'˜SP‰‚{8―TΣ¬mtΫ(lμ ŽήΦΫQŒ*@)šŽ™e©ύ¬W Vh„‹ŽΌ†β€9|Cπx&οU‹T΅–9-˜Εqζ;•8M½sž=»Χ–j~ΏOΩ·JI ™žΪιu "\‡ς‹6 ωό+ٟΐ^}Gνν ιζλvύώHλλŽ•CBͺPŒmΗτΕxž™α†š¦…ιΧnΌ‘ƒ"Λͺ²νγΐž>•Ζm?Kώι6ž3J[Ȟέχοά­½³žωάkΡζψsΰωΝ̞ΣΪRwε λŽ•³¨θN₯¦E§_ιφΣΨDTΗ (»F° 2ψΈΨ?όβ«΄μ»g{[‰@Θ‹p8'πbΰ5wγG‹4‰~ήXX^Α{{©…‚Ϊw3’G8«Σ/m-ο­dΆΌ‚9νδxδPΚΓάV&‘ΰ θχΏkΣtK{r$H†GΣ€<λβ~‹s£|%πΝμk ύ’\η‘Pͺί†qUό£/Žό3γΝjt?ρ>‘β΅.9XγVο α^Ο¨Y[j6SYίAΕ¬Λ²H€V„St½:ΟJ±ŽΛMΆŠΪ<„Š%ΒNxΰ―.|eρM»½G αΝ$[6ξžq%½OηIƒ₯Α\k0ΨšΒ–ΰ/ΞΐOΠΚ€4蒊(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š*6… Ο#ιRQ@y οGžυ-δ^B{Ρδ'½KEr/!=θςή₯’€Ήžτy οRΡ@\‹ΘOz<„χ©h .Eδ'½B{Τ΄P"ςޏ!=κZ( ‘y οGžυ-ΘΌ„χ£ΘOz–Šδ^B{Ρδ'½KEq‰‘ΘϋΣ蒁Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@0@#ފ(©'άE_ Ε:Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š( :Ρ^ϋRίήXι:Y]ά[Γd)Ÿ—Ύ {•Τ׊ώΜώ!ΊΎ5mTžio,§ίϋη,α[‚ <πA―<ψβ½FσΗχvΊUνΤ6Ίd+ω² Ω‰Αυ`?*ϊΆŠΰώκρΨό 5]ZyZ8m ³JΑ€lr{“\Λ~О>X΄Φ,γΞ&ί7η†hΨ¨C\ψƒ ιΎ _‹Ώ6Βo’ά’’d‚Bc±ΰυιŠς†_T}’ΫΕΟ{swsr’ΨΑEn0NGjϊ†!T– Ι'΅qzĝ@ρT:ͺσΑq,>žΘ<”\1ω›9tφτ¬‹‰>ρΎβK 8υ!gke#Ο?–©Ί2;>lηΖ@ E΄»ΆΌŒΙgq ρƒ΄΄Nι‘SW‰όΤΌ1αοψƒRππΧ/mmζWΉYβΝϋΏΒ‘±€9<滏όJποŠ4GQ³š[x4ρΊαn”#"γ;° γ¨ϊŠν(Βίt/Zκ—V6ڜvšm»\άO4*UA$ 1$ΰŒv­?‡Ύ<|wiw>Ž—Qύ•ΒH—Ήδ‚Fzκ₯}‹š¬eZ–ηξ­cλ:Ξ›’[€ϊ½υ½”.ΫUηp ŸNh)~kz5½^wρq†β[¨5;Ά-θ·αωKy{€2άcqΝzm—‹4_μ‹ «jΑ–γχK0•BI 0₯Πι|ΧώυkzΉνΕώΦ―ZΣJΥμξW¬qΘ ?O_Β΄5}VΓGΆ[RξHΔaεm ±θ>ΌP>kz5½\Ιρ·†Ώ΅Ζ™ύ³gφβΫ<―3ήž™φ«ΊˆτƏ­j6ΦjsΝ|ϊ¦€ΠΩσ_ϋΤy―ύκΛΡu½3[΅7:Eυ½άΰΌNί²—Ηžk€Ά]{O39 /œ:Ž£4‡SζΏχ¨σ_ϋΥ‹ ψGρœθڍ½η’q'”ΩΫ隫«ψΧΓz=οΩ5=fΚήδuδ_―§γ@htžkz5½YΣjΪ|:Sjrή@Ίz sp\l λšσ½β™?u«+ύ[M‹F‚46“οΜcχ†ξτ‡ͺω―ύκ<ΧώυyοΕ}zH>έκώΎΪXFΠάΐΩΘ,A­=7Ζώa°ΉΦμΏ΄ž(ΓFΫʎΎ{Pšή£ΝοUk»¨,ν€Έ»š8`Œny$`ͺ£άΦ&γOk7¦ΣLΦlξn{F’ Ÿ§―α@htžkz5½YχZ₯₯ύ­•Νά1]έdA 6L œτ—š­…•ν₯₯έά0έ]’°DμJGP£ΏQ@XΡσ_ϋΤy―ύκΘΧΌA€θ$ΪΝύ½œnp¦WΖο οQψΔΪ7ˆD‡EΤmο<Ό6JύE‘·ζΏχ¨σ_ϋΥ“­λϊV„°Ά±¨[Y,ĈΜΞqqŸ¨«ΖβjnL‹δσ<Μρ·Ξ}1@X±ζΏχ¨σ_ϋΥΚΗγί Λ7•Ώ§³μ2q0ΖΡΤηπ­=ΔV½k%ΑܝρΆBŸzC_ΝοQζΏχ«‘?ό".ώΜ|A§ωΉΖ<ьϊg₯njšΖ₯iβϋQ½‚Ϊ̐8 ΟN}θ /5½Gšή―*π‡ΕM2χUρ Zή­¦ΫΪΫ^μ\Έ_6,œ6sΟAΝzZέΫ΅ˆΌ!΅1ω’\ό₯1ΩτΗ4…―5½GšήZσǞ³†ή[vΕ#Έ]Ρ0˜gŽΩ«wivzTzΥύ΄:|YnΐF Πƒο@hjy―ύκ<Χώυqž»ΧZέΜ^"ΆΦ­eΉέ@Ϋ…²Β]ΦtΡ¬ (ήΐ5"ž`Ά.7•υΗ₯iω―ύκ<Χώυfέku§m§\^Αυΐ&ΖχΈ~€°5½Gšή¦VΉγhW+m«jφv·εΌƒp€v ‹ΝοQζΏχͺžŸ}k¨ΪGuaqΕ΄ƒ)$LX{Yχή'Πμ$ΌKΝR΄ Σ«ΘŒ7LzCsΝοQζΏχ«@ρ&β&›FΤ-ξ㄁!ΎζzgΣ‘ͺ γΟ =ΤΦλ―iώl —pΰΌτβ€Πκ„Ξ\Υ”mΚ¬»»{ϋH¬¦Iν₯]ΡΙΚ°υ΄mΥ Ρ%’Šςό;³·ΡρΞ‰βǚ.iRξ™mn#1ΚƒΧiντ žŠεΏΥ­τύΧφ―rΫ`–κΥ£ŽSΨ¨ίΠ‘22{Q\F°4Cρ[@777Λ­‹YΎΝ δ²m;‹{γ?₯;ğ΄U“Lq}} ,66ζS?ή<ωΠkQάάCkΟu,pΒƒ-$ŒT{“ΐ¬Oψ³Mρe€σι_iQˆεKˆ&FΖqϏLΦGΖ―ω%ž"―ύ™h³†Xη‰%…ΦHœWCΓΤτϊς/ |TπލαMΞVΎΉ{{8’w΅΅igstγΫ5ι Σ5nΒεn4αMζF3Β‚O£(VŒŒγ#>•ηW_|+ ­¬Π=υγ\GζˆmmΛΌk’2γ8^3W-Žˆg)qύΏύ– oυΛΟϋΩ"€;š‚KΛhξ£Ά’⹐H™ΐv©©SΕτ jK§]Ιsu¨•άm¬α2ΊSΨ~uΒ7Š4Ώ|gπΦ‘3²Ηk~xτθW⿈Ϊ†΅§έ=ΝΦ£·{[YBet­ŽβkGΑώ/<]i,ϊ<ξΝ l–P€‘ŸFS@AφΫ_Άύν0}―n#ΜφϊνλzγόIρ;ΓΪ¬ϊdy{}ϊΨ¬ 2˜Ώή=q^Χ΄|}MCI˜ΛnΪ>ΣΉJ²°nUδ@ΩEAu”χw„0#HεT±ΐ8“τδψΕms―kΛ¨Ε©=˜ΉT²H¬ΩŒhμt$σƒ@ΝEs/ρΞ‡αD·ώΦΈ“ν0ΫC’WΚ?™ΕTπ―Δ}̏φu³έZjn[kΨLNγΥ{Ξ€;*(―Τ>-Αkρ:[[φΡ­ν8νη>`1 dg₯zέΕε΅΄°Εqq RLvΔ’8S!τPzŸ₯O^1ρK^±›Xψq­Θοo`n₯˜΄θP’ν_Ό"Ί;oŒ>šφ8%{ϋX₯p‘έ\Z΄pΉ?νƒά@‰ERΥυ[K›QΤc·²…w<¬x·ΦΈ;β†//ΰΆc¨Z₯Γ†ζζΥ£†Bza»gίθtP r yoΕK»ˆ> ό>Š ‰£Ž[β²"9ΖW‚Zυ"@κh=+Η~2A.₯ρ ΐϊOΫo-­od—μΣ4dŒ§₯fόCπΥχÝ|GαΏκ₯­ζA%­εΑ–9Tœc€=°€~΅η|k{‘x_L49Χ5—ŽHΩs±˜ ρλΘάΦvŸπ.m–xƒY½Υd€–;¦DF=”zP«QXΎΠαΡ“OώΠΌΤ»0šνχΎAŸ@(ρ/‰tί ύ€κ΄K{pΆΡ°\€νΣqμ=θjŠγΌ5ρDρ&ΌΪ^Ž·³¬βλμε``½pΗ―εU5ߊΎuI΄υ7Ϊ…Τ-Ή”D}π?*ο(¬? ψ«Hρ]ƒ]θ—BdFΫ"2•xΫΡ”ς+ΔΏ|= j¦ΘΧ—Ϊ„λ ±€ΚΡ½Π¦hΆ’ΉψΓFρm΄²θΧ ο Ϋ42‘I"?ν)¬MOβ―†tλ»ϋIfΊ’φΞslφΠΐ^GaΧhGΏέΡ\ŸΕ― \ι·m{4*=¬Π0ŸqθrXύ3V|-ρ'@ρ&t»V»΅Τ —H/ 14€rJϊρΟ­v”Q\‡ŠΎ θΎΤ†Ÿv·ΧεžE₯³HΑOCžzλκ {Λk™fŠήβd„ν•#pΖ3θΐt?ZΒπo4Ept™e[³AΖ€7¨¬;Ο颞*²πτ+jwq΄Θˆ™UAžXφθkΔ?|;’κ“iμoo ^Ά6ζQϋǁ@Υ“αiž'“PΡφμJœ‚¬Œ:«Θ5­@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@x'νe }ώ»Ώώƒ^χ^uραυϏ¬΄θ-/‘΄6²3“*έ‘ŽΤεΛ¨Ηπγγ;ί\“™ͺΨyΞ{nhχ~{ΧTις]ό'ρGŠοW7Zž₯#pΛ6=‹?ΰ"½·β·ΒΙ΅ΗόFπΤώ,πα`ΊKd–hΪge'tjrT{δΚ‚–ΗΟ6z"Γΰ6M"νžF»Τˆ²c$Γͺ€1–^ή•θτύ2ώΧΐΆΦΦ’ΧO»Τ2aωx A^ΔΧ iήko^x‚Y£hšΙ,­ U?ΊPAoΟΈv-©]x:Ξ9ΪήI΅«*Œ”;FϊΔ_τ«? κΪ5¬V—ΦΊ„Q‘B—BySŽ£ŠΉϋG§™ΰtΙ΅FGn§ΐώ!Φuέ.ηΖZΝ­εŽ™ š-ΰΩζΘ:3ώUΏρ7Β“xΓΓπιΦχ1ΫΩλsψLήΫψ?LΦF‘$-εεΰJw ‚§ΑώuλPxMΧβˆež)-n¬ΜΫ•9ΰŒ’z`βΉΛψ£ΒΟsmΰέrΡ4‰€2₯΅τC =v‘Ϊ€.ό$πζ«£ψQΣ|Eg V―t[[y’eH۝Ήξ¬?ι:tŸιQEφ¨υ"²MIε¬μ«›°;Ν'Š<7βΝ^ΦΘiή΄›Ϋ)V[{«{Υά›{c Χ x£ΐρkώΣ4ι.ZήNXΪΪς1Μr"Ÿ‘ΗO§₯fE’|CžH!½ρ6Ÿͺ2™$·΅Δ²¨<Œž}±@¬Tρήαkό?.0wMŸΓQόL#ώΓΑž~Ρ)Πkβ7„.όFΪUφ~Ά:Ύ™7›»”ϊ‚? Γ_x‚ΕϊˆuύrΪζζΒL΄1BQv οœδŸj‹βf¬Βu€x›OcΧlν-ŒX;CeŽρž3σϋζ΅ΎxCΦ5­BήΫC}\Š0. –ŒΙž9Ehx«LρtΊΒ^xcZ΄·ΆςDoguτ, ;Αƒ‚^ΥWΑ~Τt_x‡Δš”wϊΕΤbδΗ²8Πv’όKπV™γ84ψυkωl–Υέ£1²ΔŸΌ=«{Um|%yoH¬]p##5Κό\π׎m΄Θμοβ³6’;±‘IέΈO₯uν§»xtιΎ`ήm~ΟΏgfάΠΟΆΊŸ'€ΎJΦ°™n5m³>Α™ΜΩ {Œ? ο<35–‡γ߈­*$eΌ0άȈΈP<ΌΆϊΠ·ψwu†Ό#¦ψKθ—’κGΨq(ή́ιΦ΄‡ΔΪη‹―.ν5λt·ςΠΡ€…IΟ―9ΰώΡs¬ψFετ?‡št:ΉŽ[‹„Κ~p»΅Χ|TΥ~h«¨’](σS€Γ +…λθ•iΰ?¦‚|9/‰­WCbVŽί˜»»·σΟαΗ‡%πŸƒμtiηK‰-Μ„Θ€€wHΝΠ½@#‡ψM€ιΧ'ρςOcm"E«:Ζ―!ζΰz τŸ"ΗαIB’Ϊȁ€ΣΕqΧ>ΧτίκΊ―„uΛk8υ9<λ‹{«1wχ ΗσΦκΞβο@’ΚβT7RΫ€•W \ ιžΤ σOΎџαύυυ„ww›Ω䝐‘ˆ 3Π`tυ&½=t«ΣbΣώΙ ²‰U@Q@θ0}+/ΐ: ž𝆑<ι<–ΚTΘ€€Ω$τ?ZŸΕϊνΕ¬KαΛλK;€ωvΉ„Θ γ υ #ΰμQΑβE,q&¨ΑUFθXψέakˆRεl΅.E{K€9rOϊ’;ƒιΧͺ^πOt;ύJκΟΔFύFγν­ε»γž+{[πm׈|c§j:έμRθϊzο‚Α€ΣqσΏcΦχ4ζΎ"x†γTρf±r·>!–SΓ·oΨΠt@§¦Ο9―RΏΤltεFΤ/-­UΞΟ* cν“Νr’ψ2k?'ˆτ¨­αvj6¬€¬ώŒ1ΡΏΓάΥO‹ώΉρݎ­μ6†ΦGrdBΫ²ντ g{©,+,.²FΛΉYCc^AπSI±Χ‘ρ6΅¬ΫCy¨O©Λ΄θj*©ΣοΘW©xsOm'AΣτωd{h"κ0ŒΧώρ…­κw~ Φ­m,υ'σe΅ΊƒxΌΏησΕVψ3ӞܟΝ’x^m;ΗzζΎχ1ΌZŒQΖ±;“orh⍕§‡>xŠοC΄†ΞβζŽWΰ@Ησ¬OψCBƒΰsω6p,ιιr·Fσ&ΠΕ·{’:τίΨYκšύ–¦@²šYXœm\rsνΦΌ3Εz]ή™πήκΦoYίxv(±i ! ³r=ΐœ¨88‡΅g¬ό(’qαοϊτZν­Υ δ>ZKcΰ-ήα&KHχ+ $gߚtMwY]ψZ},[]y·!IrqςœuοΑΰζ€{…sΏδžx£ώΑw_ϊ%«’+3Δϊkk>Υ΄ΘδXžφkev ] δύ3A'7πOώIo‡Ώλίf5Θθϊ}½ην/β)n"IΦΒ)cά3΅ŠDΉ5θήΠ€πΟ„tΝy’y-#Ψ 7$πΦ³4―OeρCYρS]DΠ_Ϊ%ΊΐξB‘Iιόσ sβΔIώ\’…œκ^Qp9*qΗ–ώN/L°LŸΜΧOγ? Mβ {Γ7πάΗ i7‚εΡ”“ γι›qα9₯ψ›iβu‚&΅0m;‰=σ€9=CΓή+πg‹uΒPZjϊ~¨βk« NΙU†~γ~'σιΖk―ψ{γΩ]Ιkk-•ν¬Ύ]έ¬Λ‡ύύz}«/PΡώ Ηͺ]>“βM9¬%΄qέΪnhAμΖqοWώψ1Ό*š•ΝνϋjΆ§7ŸwpWj–η…‡&€+όo’Uβ/ϊΰΏϊ1jχΒΝ*ΣJπ‹œ){d•Θ³0Ι'Χ­\ρφƒ'‰ό©θΠLIwE‘Α!pΐς―ψzΑ΄­ O°‘ďmB]Ff€<ΏΰŒ1έx³Ηšβ‡Υ’bfnYζΐƒΠSόg v?<q`;«Θ¦Žδ(ǘO-λιZϊί€΅KOέx‹Α:΄Zmεκβξήβ/2χ±ΨχϊηΦ§π—om|Q/‰ΌUͺ.©­ό˜|ΈφEw =}ύΟ­a|7†;Ο‹ώ>ΌΎQ%υ΄Γ q“d»υΐ£βεΌVŸό¨ΩͺΗ©KxΠ3(ΓIː}@ΙόλoΕΏΒMα U4½^Hό«„–=πά/ϋCׁωT~π₯/‹!ρ/Œυhυ=BΩ6ZC^\0{λΟZΖΉ°‚σφ“ξ#I>Ο€,ˆg Έ€SPό^Σ-/~(|>[ˆQΔ·,²d}υRκ+Ά_ Μ>'ΏŠ~ӐΦΟΘΪwd19ΟLS|[αυΟxcXŠκ8£%i6RL™Ηφι@χν_π‡iσl_2 JάΖΨε~lq^&ΙκT*εώ$ψ^ohiφχ1ΫΊ]Eq½ΤBγŠκb]‘’žv€(ΛΌG'α/ϊπΉΠZ‘Υ<=βΏxΏWρ„a΄Υlu6Y.μ&;%qΏωτι]^§α9―>$hή&[˜Φ y`hJΞ\zw¬νOGρόz΅Τš?ˆτγa3–Ž+»]Ν=Ογ@_|ecβλ[Σoi-ύ€ž]ε€Λ‡Ξzžύ>Υ[γWό’ΟΧΏώΜ΅'ΓΟ?…ΫT½ΏΏmCXΥ%]άmΪ€Œΰ*φ1­Oθrx—Β:ž Ι—qyk#‚Bς }(3αFŸgoπΫD†’1Mj― 0μΓ-ŸZΰΎ†ώ%X[gμΧ7@Ξ@Μm?!Zφ^ρ¦£¦αΟ[&›³hϋMΆι!ΘωΆ7¦rFzWMα_ΑαΏ^hV·[‹΄”Οu ζI]pXώŸ•sΏ³†•iiπΚΖφ(P\ήΙ3Λ&>cΆF@3ι…–ςrWίφϊ1+ψmαΉ|#ΰ½?DΈΈK‰m|Μʊ@m3τ?οb«Aα9γψ₯qβ£u‚M;μB §p;•·g¦>Zδώ ΓΧ‰|s©ά¨mHκFΝΛ,c8ΠŸΛΪ£ρ%•­Ών᫈{‹ ΫF7X>ύΏ ΤΥ|­iώ,½ΧΌ¬Γ§I¨φΛ[˜|Θ€aΡ€υλωŸZ‹Fψs«Εγ­?ΕZΦΌΊ…όhι:ω[)EŒ€|ǞΉ  MGS|lΥoo,5(΅‹ThEšω’ΐr½pHλZtνKSψ™xΎγNΈτλ›U΄† ΆIH*w•νχZη­¬΅Ώ|CΦ΅ο jcAs1₯+ζΌΑIδ‘΄aΦΌaαˆZ‰―k–ϊνžΕ0-Φ9!ΗΎP8Ιοž†€9Ώ†·~+>"ρv‘ θΊn£u& Ι<Χw\‰Œα@τ=«°πG‡|UΔλολZmŽ›kwiεK¬αΓΘ1†#ΧƒW5‡ϊ½‡Šouk1ι³ίswkq™ ύμv=λ]ƒτΟZήά\ψ§\·ΎG@±ΫΫ[ˆ3ž[=I Gφw†9΄-gS™AΤ΅~ΠνΛpxͺΊ}΅Ÿν-yφTTσ΄Ο6EQΌγ?žόkROψ‡BΧυ+οkvΦVšŒžtφwPyˆ²¬ΈιRψGαΦ££ψρΌO©kCQΉžΥ£Ήέd'ψqΐP€=¨λΛ>ΘΩρ ώΒνύkΤλΜ§π?‰4Ÿꚯ„5«KkmRA-Ν½άfΉR?Νπά1_ώΠΎ%—PQ%ŝ’ E~v)* Ο4ΗoΰέNΨ*j‰ͺΕ r(ω™XςΉτ­ίxοPρŸ‰<;©3Δ0Gε<ψ§_G_σΫͺιΎΦ5/Ψλž8Φ!Τ$Σω΄΄Ά‡ΛŠ6ώρ©λP€Χ”ΫΙΘάΨgJυjσΟψ#VΌρ}§‰ό+ͺΓaͺE ·•n"ί‰ισΠP7Ζϋu/|?΄Ή@πΛ uaFΰώU±ρκΦψM­f$ύΚΔΡρχ˜ƒN «:Η„5]nοΒΊ–‘jך<Ν5ΙHˆY‰ξŽέ;ΦΟΔ?Λβ―κZ,₯Ό·jͺ$pH\:· }(ΘΎ.Ow7€>[F‹:]5»I―΅$qm }γ[2Σ~ ψ£Γ3h·>Πΰΐρήs ŽΥΪλή΄ΧόaαέFR%³†Šκ!ƒ± PγυγΠΦψ•²YiβέΑrlΓM·ργ>τέψVΪςΟΓ:MΆ¦AΎ†Φ(η!· α@n{σšσΏ‹_ςQΎΨ@5―T·GŽή4–C$Š 3‘ΗšδΌeαυψcTŠκ8c.|χ”“ γι€8–χΧό“xΆWΞΣˆΞS§­ckZV¬Ÿ4=βf΅>©’έ~ςΥ’U†œEόδ{Χ¨x―Βλ~5πΖ·ΤqE€<Œρ2’dݎ‡·J±ρ'ΒψΟΓo§΄‚ €q-΅Ζ9ŠAΠρΝq_₯Nρ·ΓύJσ §Α}΅ΨύΤ$Œ1ϊuό+ΧΗ##₯rZ§„‰|‡βΩRκθFέ@6Ÿ1x.z_©[Nπ—Δ]Υl4ΏYOcΫ^Zο‘°ΟΗ4κΥδ΄U’_ιž³›>]Ζ«-Fΰ:τ Ϊjv:,kΊ€Τu,dΉˆΓe‰(…bόCπœή*(‚κ;°_ΗvΫԝαH8ο@·vριΎΈ‡L!X-ΨCcp§Wϋ:[[―È/#Uk«Ήε{‰Hω·‘ΙϊW¨0 €0Θ<kΛ πˆό5|| ―[Zi·²™šΞς1bsΤ‘ν@<5zoν β;m1B[ΟcσĜ(…==O_ψ/μΩOαSSΊυk›ω>Σ#˜ž?‰5Υό=π8πΔϊ†₯¨_>₯κ-ΊζνΧπ‡ψJΗΈπΉ’xƒQΤό ¬ΫXC¨Ώ›qeu™ςyeΗN¦€2Μ)§~p.š’5½Σ―8€H$zεV£ψIcΏΎ#ήΙ΄π^γb2T3HN?ο‘]_< .‡¬jφΉ¨SΔΓcάlΪ‘¦~κÁω ŸΑ>ŸΓΎ'ρf©5ΤSG­\¬ρ’)0 œ_ΏϊP Ϊ]€Ÿ΄―šπFYt‘p2ΏςΣvέί\T#HΎ+ό:ΈBΜχ2FΞ%~^?ργωΧX<'0ψ ή*ϋL~AΣş‘΄ξΞμξΟLSΩZΛρWβ%䨏w ΜqΖΔrŠΕΛcκU*θ< πϊοÞ/ΏΧ―u†Τ/­‚Nς&Φi7d‘Žΰf/ΓmoNρ>±β/ψ‚;MJϊvo-αί D@ω\z‚3‘@xώ8μΎ5ψκΝB]έ αΈ)ΑxΐΟζhψ{wŸy +Ϊό αΨΌ)αM;F…ƒ›xy σ$',ί‰'πΕqcαˆ|9«_\x]·³°½Λ%ά>dhηΊϊPό$πψ΄Ox—PΧ,­lm΅6I’ήΪ`θ g·½FΉ i~$΅²Τ?α"Χ#ΎΌΈ„Í-ψ#ί’>”ί‡Z.·‘h“ZψW}ZνD™Ιb¨q…Ιη¨'Ϋ4ΤΡEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEΩz⫘_Συ«TP4μTς_ϋΏ­gκš –«5œΪ…’O%œžt Ηύ[ϊŒΫ’€ΉSΙξώ΄y/ύίΦ­Ρ@\©δΏχZ<—ώολVθ .Tς_ϋΏ­Kwυ«tP*y/ύί֏%»ϊΥΊ( •<—ώολG’έύjέʞKwυ£Ιξώ΅nŠεO%»ϊΡδΏχZ·Er§’έύhς_ϋΏ­[’€ΉSΙξώ΄y/ύίΦ­Ρ@\©δΏχZ<—ώολVθ .Tς_ϋΏ­Kwυ«tP*y/ύί֏%»ϊΥΊ( •<—ώολG’έύjέʞKwυ£Ιξώ΅nŠεO%»ϊΡδΏχZ·Er§’έύhς_ϋΏ­[’€ΉSΙξώ΄y/ύίΦ­Ρ@\©δΏχZ<—ώολVθ .QšΧΞ…β–0ρΊ•e=<\₯ŸΓ Yί-έΎh³«nRrΐ\Šξh .UΉ<Œ~5ej€)h ΈQE(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Šΰυo†:Uή³uͺiΧڞ‘wvΫξ …ΑdcΤ‘λVΌ/ποEπώͺuU7Wϊ©EέμΖYŽ ιΕvTPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE‡γ/ιήΡ%ΤυiaS΅UFYΨτP(rŠωρ~”ΡΡFFq‘ŸJ(’‚@$οEP##‘EP=hΘΞ3ΝQEQA “@Wœx3Wρέߎ΅;_ιΫθ(Θ•P‡εΑΟ9sϊP£Ρ\‘γ*ΛΗ6>5υ+€ή₯FU8c†>ΈSϊWU@Q@PHHQA žQHΔ(Λ©₯ Šσ/WράΏξμotΘcπ²—Ξr |­»9$χ―F Š8 βΉίψ»NπfŒ5[Μ14‚%HΖY‰τΡQUτΫΈυ :ΦςΒ+ˆ’d Χ όκv`ΏxΫšZ(―9ψ}«ψξϋΕ:¬+Σ!΅£έφwTάrw zΠ£QE‚8 ΠEΘ j(’Ό£γοuŸιΊLϊ ρDχ2ΊH^ ωdu W’³ό;u-χ‡τΛ»‚ ΣΪΕ+0 2xϊšδ>*όK²π6ρ5«ήκW#tVκΫFΠqΉ›π ώŠπ'γWˆU²ΆΥ|<ήJ±Δλ½ άxΖεΑύ*ΕΏλώρώ…₯iSŝΪΔeG‰Xm<žœP³ΡE"°oΊAϊPΡE `I‚GQι@ Ex―ˆώ λφ?,|5oqešxΜ*X†?7Zφͺ(’Š(€V 2€ν^/π‹βΏβok:^­<2YΫ,†5HUHΓΰr=¨Ϊh FA{Q@) 2€κ( Š23ŒσιEPHN( Š  f™;‚F^ͺ€Κ€ExΟΐkή3ΌΦcΧ§†UΆŽ6Λ‰S‹g§^‚½˜zP’3 =Ν-Ηϊ³UhEŸ=}=}ΉYΌ_€E6ΉΝ :4bKΖΨp€‚@ΉΐιZϊ]τ:žm{mΏΘΈŒH›ΧiΑ¨‘§η―£Qη―£Uj( |υτj<υτj­EbϞΎGžΎU¨ ,YσΧΡ¨σΧΡͺ΅‹>zϊ5zϊ5V¬―νύ;ώ?μ/8iω?hςΆŸΉœg4‘½η―£Qη―£V'ˆυTΠτύRhΪXν!i™ςΐ‚ κΡλΊ Ž© mwq Uς φ4‘·η―£Qη―£Uj( |υτj<υτj­EbϞΎGžΎU¨ ,\Iϊu§U8Έ‘~΅r5`’Š(QEQEyŒώ"ek©αiskZϋ ΝoΪ‘/«Ά8 @’ΌγMρ?WQ΄‹WπuΈ΅ž@-΅ήL χ`}*όT‡Βl4BΝ³ηŠ9$½σbάΜ9\tGzτΪ*9e lσ&B<3\ίΓ―Ώ‹|.š΄φΙhL²ΖQ_pŒδι@Eε—u=kUΉ²π‡ΫWŽΩΆM{<žT!½­tΧΌU}«Ieβ_ &Δ]nαΈσ#c6γh³’Ό–Ηβ/‹5GV‡@π₯΅εΎŸtφ­#^l$ƒθW»Oκž#Ԛθx—C‡JΚ1άyΎfsžΓγσ šŠΗρ^Ώkα½KϋΐΞ „DNΗ q|Gγ…nG…’00 #ϋOο1ωV°£)e·­Œ§Z1|―KέΘψΫ]Ώ΄].κΥEΌχQG"8 ΄7QυΉNT™AΖ*O©Qš“q]Š(¨,(’ΉO‡:ΥξΉ€έΟ¨:Ό‘έΓOD[h D]£οqχ½ΙλŸzγ>;ψ’λΒ2ι-δ^]ΞΆ±H£<†faο…?‰―3πχƏθz4V₯α‰ο-PB²±xΙ 07.Σ“ψŠμΌk₯k?ώ[Ο5€ΆΦ’_΅Ηjvξ]£w<«Ηζq|,Υ'ψ{ «ksQ‘ϋpBNν½sΏ9ݎk―πΏŒoόQπΕ#SζΏΣνή#9?3©\©'Ήκ3\”_όImπόψ)Ό9sφΕ„Ω‹­Έ'LlΫΧg5ΩxgΑš‡†>x™55B•­ΐΛ  ;χΗ½p_|«|Bπδ—zεΔ6c2Ϊۜ²™άN3ξ9λQό-ΌAγΖΉπ¬Ϊύέ‹d ς ;ΉΘP£Ύ3Ξ3ާ―Sύ›­§·ψuͺ%Δ2DζβBΠ©? υ{φd³ΉΆρO‰šβήh•£\¨?9ιšΝψ6£α‹z…dΌ’[5i’tΙΨΜ‡‡±#ωΦwŒ±ρχT4]F{)u VΥ€G#lf5-ϊ ρ[ή³ΊOΪ[Vν¦X χHP…(x/TψvϊFΉ½uqrηΜ›%]d<ς:υŸγύΤ<7$ΣIΑo–D$ίΏq[Ώ΅=­ΕΟ‡τ1m³ΉbDh['΅eώК¬ϊΓκ[Ϊ9/Qn!Η/·υΗΕ8ύž]Γ°μΈΞμσΡ{Χ1ρKΓZž±πKΑςiφ²Ν6ŸgnσB«σ…0('x#‘\ΧΌKβO‡Kα ά‚[‹‘Έζ4ηξ0xΝtίf•Ώg»HεΔ“α‹Ž½r_ | ͺόFπυΔwΊνΝΆ™`εmαϋκdnIΖΞk°ψwisμιβ($·™fi'Δl„1α;VημΏm=·‚υΈ†HXήŠTŸ”zΠ=ϋ2κϊ”:ώ»α»Ϋ™&Ά΅ŒΘˆΜXFΚαnzžžΥGΰδ³Mρ·Δ1δ₯Θ1;~qΞ*Χΐ ;˜>,xͺIνζŽ6Š}¬θ@?Ώ^„Τ¬ξ‘ψί―K-΄ΡΔVγΘ@?8ο@^£ΰι/~9Kα›½^ξi%›~4€˜|Μυό>•Υ|bψw/„<₯ήiχχWFΚvIζc΄νs•$Ω†?ΰB’ψ˜Ί―ƒΎ:ΒRΊ\Χ–lΙ4;AΫ ςDl»€8 ητ―bΠοαg|;Τ£¦I§Gz$·ΘňΗέ|;ΰτν@gρ?Ηίmψ# ˆ'"ϋVΫ›[ζ/υ‡ώϊΪ?λΌ«h? ό’Ωψ£Rϋ%ώ xβD‘Λ3c”`m…x€Ό={|AΣ<7xY ±Ή1?…[/?•}eβθ({gΦμδΫ)H²Δm}yχΖOι^$ψA©ήψzν0Ηs m"+¦xγζטhήΥό[πΦoίλs·Ψ"u³Ά|° QœρžkΤ>0xOOπΒ-NΗΓΆ r\C!Ž<Ή'xζŸπκΪhgϋˆ^cmr62έϋP˜ό5πηˆ>)hΧZ—ˆβ΄ Ϋζάν’υσŒρ]'μΓ«jkšΞuq$–°¦τ˜‘†ΑΫιšΩύ•­n-|?‹˜%„΅$BΉω=λφ{²ΊƒβWˆž{y’FI6³Ζ@?Όχ  >*hΎΌρ•τώ#ρδρd–Q+ά9^2wǝϋ:λχVž?ΉπύΆ£5ξ‹,rƒηnWκ§ξ’:υ«™π©›ΐώ2ΤΧΕ›[ΊmΡΖ$Lόϋ³ΌdΫ½k€ψ?§j–ΝΖ§€ΎšΗ4¦jF2 cΑPί M)ύ¦υHΜP\Oς–8ιιXή4ΝχΗνOIΠυμ§Ώ‘-ZDr6ΖbB 'Šέπ­ώΣ€νm0€Ο9;O½(w_πΥγμΣyy>fΓ·ώ=ˆλ€9_xPψIγΝM/VžarC'*XoΓ# ς?ΖΊ?Ϊ‹MœM₯jςjAsϋ΄³cϋΈp –Qκ{ΥΟΪjΞζηŞk{y₯U²Q ϋΑΧ΅ϋIθz†©ΰέζΒΪK…³“3,k’ͺSΗΦ€6~ |:Γ[λkͺά\›ΫΙ†EΒΗΈγžέ+Μ|q‘x.mUŸYψƒ<χM#˜bD{Ÿ+ΡKŒŽ:c5Ϊ|>ρΆ«γ ^x^-{ ˜4g‚;η bΰyη©―-ψyzή—SΣυ?I«k‘tYςΫ‘‚ ‘Œσ‘@χμ»β-BκσWΠξ―%Ί²·ˆMoζ1>_Ν΄…Ο ƒŠ‘ϋ<Ο,ŸόF²Jμ‘eΐf$¬©fέ/QΣ|{βυ;)m%[b¬¬˜PήbδΣς€ύŸ,ξ­ώ&ψŠIν¦‰eΓ:ο=MrΪFŸ¬ψŸβΧ‰<=§jΧ6·——&νΡΟϊ€‘Ž?2=κή•c¨ό/ψΟa£Ωκ3Mi<‘*%ϋ2τΘ9‡α Μ_|M4ΆΣ$Lo6»! s:γ™ρRΞκ_Ϊ,Ρ[Lπ³eΥ QΙο@ώΠ>-ΈΌρΜ>mJM7F€GφΙqΙp– Λ€`zΧΪΟΰOiχΎρ-Ζ£lΔ}¦)"xΓ ς¬ϋWwργΒ:•Žνό_§ιŸΪv.#k˜JoΓό%@ηΨϋT:oŒtm_Q°²Σ>B³Ν*$${–0X ΐχοzώ©―xΗIπ–—rπZΞ‘3’ΆΡ#ΙΣv:€βΉ/‹―Ό €i‘kΛ}¦Ο!ύΣ‚R…κ{ŒώUΩ|}πφ­€ψΫKρnfσΫΖ±†ςΣw–ρž±ηΨΧ3ρ[Ş!ψƒ‘ΨN<5uc¦ZK†qΊMς°νςŽ0cΧ­}5ΰοωt?ϊρƒE­yOν ΰM_]ŸOΧό?\άYG²KtεΘ Έ2ŽψΙβ½_Β*Ια=\ae Œ|΅―<ψ₯ρ Δ^ ρ, e’hiBΆΖ|œ€γπλ@ί>6¦‘o’ψΎΠYί3–ΰ )~€2žTζΉΪώJΧ…Ώέ‡GηυwΦ~-xσNΊΣΌ8Ϊg•±f˜Π6K»2@ιήΊ_67RόRπ³Co4¨‰gD$ K܊οΎ:Xιš†•a―β£ ΐ²"cφ„ΗO,±ΰγ&Ύ{½ΎΣΌβ}:χΐ^$ΊΎƒ3ήΑεH nR+Όύ’τF/ιΪΔΆίi>\cb‚Tνl²:fΉOˆς]ψ4έSIπsθΪ< φt1Β7K!δ“€ α}?h?hΏꖐ躏<–Ο¨EηLΡ6Φ`NA€NsRψ_ΰDϊ6«€κGΔ3 ΰ•%ΉHMΐrUXΰτϊU_ΪΒZ₯ύ¦ƒ―ιςΞΦp¦XΧ,€a•±θJ³α―ŒΎ Χ5MKΒΞ“ΝqWW;(Bΐ;Ϊ6ρ“Ι8 Cβn§o’ώΠΦϊ•ι+mi%Ό8 ―xn WγgηΤu+‰-|=§°Qo›p!Ξ9oώ΅Cρ'@:ίνmkwiq&Ÿq-Όr²©ΪW?5;Rυ_ƒ£ΎΡνnό={ΙHΤΆcΟΜ‡ύ₯κpG½}/mVΆΡ[Ϋ’Η HF¨~σΕΝ_Xρ—Ε8<§ήΙkb$XYˆVb»™˜½ΠWΡΊ}ά7φ6χvΜZ ΠH„‚ dpzWΞτmsΒ_‘ρŽ•c%Υ«Θ³†E,‘€ΪΘΨι‘όθ½ψuπ…Όβ„ΤβΦηΉΆ2΄)ΉΟœ9λίβ> πεŠώ!k:EŽ‘%…ΌΟ1Ί’>­sςϋδγŠφο‡Ÿ5x¦ψG$Στυ‰ήi™π@ωFv€2kŠψgsΕ?Ι=΄ΡΖΛ.Π€yκh#Βqj Ύ6ΩψvΫQ–βΒζhα‘ "H8%zΈτχ―Bψν¦hzξœuヘl‘°’ΙY€2σςΈ{υ#ΉOYέ?ν'£N–Σ4"βΤ™£Χ₯bόW°ΌΡ~26³«θσκΊT’$©RT ΉΑθ{ΔπΞ­oα?‰ΪT~ Χnu &ζhc”Ί4AΓΆΦVSŒγ¨5ΩώΣwχšŒό;q§άIΔPω‘²žŒqυ_[]C[ψ…αn >‹₯KsVΡET”ν€9ωΊγ οŠκ?iΫ+›Ÿθ om4Κ ”Œ°?΅sΎκΎ Ρ΄οIάάκ“\*Nω!γ‘”°!³“€Wuρ7XΊΥg/SΈ‘ΎΥ?ΩΪGS‚[8&ΆiΛy~Ϋ₯ΌRJΪ±©c’zW1βϋK—ύštXήfœ3BX|Η·Zε4ίjώ/ψc'Š΅-ryΞΦO±ΪΏΜΎT:ρ„~¦»Oώ3Ύ‹αoˆ΅€ΊώΖVxLŒXν Έ.OlŠθ~[Νμθ`x€YΏ³―‡–T†ΙiqΕq³φ6§ΰ/ιWqKoφίάƒ"ΖθΘΟ4ηMƑ㠍KRρ‹nlο™±n‚%χΟ…QΐW§ώΞ,Τ/ΣYΠoο$ΌΆ΅„Λm$ŒXͺηA<γ‘΅pή•ώή_ι~0πHΥCIΊ9 2‘ΗΚΨ ©β½α₯m&³{iαtQq:‘έ(9Θ'8ΐθ(‚ύ”½η‰‘X©h"ŽάΏ5θŸΎj~ Υ5{­GXϋr^w$wΆ‹·βk‚ύ–m¬όJσΪΝς"* ξ Ώ5ήό#ψ­xΛTΥ­΅}XEj$Ь0IΖΖέΤχγΠΠ₯ά«?ZηΌSi¨ήi-‘ͺeά† φ)dŽ£ 1] Ηϊ³υ―0ψί₯Εqΰλ½C}ψ»΅eΌv²²†g!Fΰ½@Ξ [6Φzυί„ZψkγΔϊ¨΄x  ΐΙBq>QΐΗZτ―Oβo|<‡ΘΧφψ^Ε2ύž4ΔXGŒczσΦΉ?α΅Όž2πζŠςjKmφΫΦΈ )3ΡNβ:WQρΒΐh tλ;4ΖήςˆΚεݎN2O'šƒΔΧ5πV—kβ[έϋN"}Άΐΐ‰«vBF:gωΧgρ?[ΊΣ~κZΎp`ΉX’’B‚@gAΠ‚:σψΈψηΓ6ήΠτΝ@k’F—Ο"Ϋν9mΝΣGjμΎ.X΄?5KuyLVπΔ‘W$ν‘OΒ€24-+Η~ ¬΅™ΌQύŸ$±€‘Ω€ Ι·οœrO_Ζ­ψΣZΧoόm§xCΓΧΛ§ΚφίjΌ½‡e\‘…ŒρϊŠξ<,₯<3€«€ZD#ωy׍ή όS°ρ\–—EşΨξ^Λ΄, Γ;`ΘΠ2Ζ…ͺλώψ‰eαj‡V²Τ y-.dRDd•luΉ-c_ρ‹iΎ,ΦνΜxφ©Sƞϋ dψJWԈΩ.’»Γϊd½}θkΗ~-½ŽΗΑϊΛ[ΫκχΆώ`Ϊ€ΌRm;NAΗ΅]ψ·κZΏ‡›JΉ6ζλTŽήb[teX•δA²>2Ωά/…ό;ͺiΊ{˜΄«Θ.žΦ$ζ8ΖΐΝόEρbψΒγΓ ’iϊƒXΑ¨Η$ΧΫ²δ ―‰=:P]ρƒΔΊŽ{αν6ΓPM& NgIυPD*»}xέΤϊVΏƒ4­bνψ΄λΊSΖFΧD$?!—·ZočsBΣ–ΞΛΕMΕυ…ΠfσRίΞH™qχ±ΘΞx#Έ/‡VΆ2|Qϋ_μον|:-˜]™‘’'αΪŸOΦ€=Φ?υ‹υ«7¬I+ύΘΤ±ϊš­ϊΕϊΥ™γY‘’'εJŸ‘ $x‡‚τ ŸŠ±ίψ‹Ε¦’–MrπΩYZΞcHΡO\zϋυβΆ|u©xcβE‚―΅ CN6Ώl±–α‹Iδe =ϊΥ‘ΰmyώKΓ~*±Ύ‹tσΨήΫΐ€¨Η§ΛΠρŸΔζ΅ώΓβŸ‰:nln,tΕ΅ϋŠ\.אdδvιϊϋPIΟxOAΤcqŸZ₯π£]Ό΄ƒTπGˆ_ώ&ϊDl v–φψωY}pότ¬O^Kaϋ9λ7δ‰Wν`qŒΘGυ‹γW…ο'‚ΫŞuν'ζ!3ΓόKο€OΖG₯AπoHώΨψ5&›¨Δπ‹ΗΉGVR ξsΞ tΏ΄λ}7αž€–¨«ηΫ-Μ„ugqΈ“οΞ? ν+ΓΌγ Gα½§ό#5uΆ΄f[;ϋXΌΤxσ;sΖ9μ@Εzƒό{§x³PΈΆμ΅4Žήn.mόΈΫœ`dη?…yWΓΟ7†u_ۍXΤόέZY<Λs"―l:+Ψ<βsβ{k™N‘©ιžK…Ϋ} ŒΎFrΉκ+‘ψ!ΠάxΟΊHχλ22οR7 Ezsž?πλx›ΓΟe ’+…q,Lέ7Ηۚΐ΅ρΝφ‹$Vž4Σ&³bB Ψ†θœϊδŸjκΌO―'‡ν"Ήšκζ&}φtάΙξG₯q~)ρ§ˆ΄++Gυ Λ»΅ςΥ^ίjΖOρ}+Ά„e8¨Κ7~ΗiFrŒ­.έΛδI΄-"X^7Τ!ee9σ[Ύ/³΅ΌΣb†±6—jŒ ΌsˆwŒ}Mr~/Σ.¬| α»U₯Έ·Ί·Y6 Ψ#­'ΔKoθϊ†³i=ή‡ ${Υ$Ιδ―~ί•T šŠ‹Ϋ˜™ΞΞM­μd­ζ›‘x·BΧ'Ό‚κΰAunΣ™‚@έιžJίρmΕώ½γk YήKef}’κHNΧqιŸNŸakΧ‘k>!πΜΊ&,e΅όjn>ΟεbΓ€:ΰΦΆΌZ—žρΥ·‰‘³šοO–³έF]=ρψΘΦΝ{Ρoβ³ίΏC$ύΩ/³u·n§CαΟYθΖζΞσPpP«G4吟\zםxSΕ€θSιzR¬Ϊέυό‰ΒdΉ«ΡτXk·e°·ΎΘBν$°”EφΙο\„όΉαmQž&ΆΥEγ΄ΚTε Ξ“²—Φ<ΏRκ+Έϋ?Πτo h’ιεn₯»Ύ˜οžiΆ[Πg Ή\6ƒβλ¨ό%©άjΆ7ͺi·Ÿm ΰ©οœVχ‚υοψIΌ3e«ύŽ[/΄©>DΏy0Δz Ž2:We%7ΟΉΩIΕΑrμmΡE™ QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE…Άβ ·)h’€hέ»w­-PEPEPEPH.pΟ\ Z(’Š(’Š(C 0z^ρboΕ ”^…Ν· UIN˜#wNυθ4P”όψouα!{«λξ’λw£iΓnς“9#=ΛτυκΤQ@Q@Q@T ‘Πβ–Š(’Š(’Š(UF@«»vο\sKEQEQEŠŠΉΪ gΠRΡ@=(€ΤQ@0@#ΠΡE"ͺ¨Β€ ΄Q@ ± Š(€TU$ͺŸAKEQEΑδQE"¨Q…aKER2†`χ₯’€ (’€ (’€ (’€•X|ΚΤRŽ:QEBη ςqKE2e-­T«Τ…TυP ŠUΙ|IπΝ׊΄k[;)‘†HβΈ&\ΰ…9#€yλbu*6/χWς w3сΐέ€ ΗZ}]ΨΏέ_ʍ‹ύΥό¨b•!Œ‘WΆ/χWς£bu*˜’ͺ ; Z»±ΊΏ•ϋ«ωPΕ*k*ΈΓ¨aθFjώΕώκώTl_ξ―ε@s@` Z»±ΊΏ•ϋ«ωPΕ**ξΕώκώTl_ξ―ε@s©»vν«»ΧΥύ‹ύΥό¨ΨΏέ_Κ€ζ(Πͺa@ΠUν‹ύΥό¨ΨΏέ_Κ€ζ(²†`τ4Šͺƒ @1Wφ/χWς£bu*˜« “ ΗAVθƒP&ξ#(a†zZ( AEPEP**ύΥθ)h’€ (’€”0ΓG‘₯Pa@ΠQEQEŠ‘~θθ)h ‚#"Š(Š(  ξ€>”΄Q@=((μ(’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (¨§Ή‚άq4qΣ{Οη@ΡH¬C)HΘ#‘7Vσ»,Ε#/PŽ •MEPEPEPEPEPESUΤ¬΄>kνNζ+[H†^Y[j―8­[’±βρ>‹/‡δΧ"Τ`“IK=ΚΚ psŽ 4hΪƏ.«¦κΝ§DXI?*ͺTdη8θ lQY~ρ“β+i.4MB ΨcmŽΡ6vŸB;V₯QEQHΜK1’hh¬xΏAρΥΕΆ‰©Ew=ΈΜ¨Qœw½M€x£CΦoξl΄½RΦκξΨβX’|•η>”±EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP^ϋYΘ?@²!^^ ϋXΒηGΠ¦˜ΦwR} _ώ΅{…ΏδL?μώ‹ΰί³A γί³ν­{„όI€·Γ}3Pkϋd·‹OŒJZAς2Ζ)χŠρΟΩ}M׊ΌQy°ύ™ ‰θ7Ή ΐιυŸPΗ¬\Ωx{Γ—z΄Vδ‡˜K³88$(Fγάγι]·ƒΎ!Ωkώ½Χοlξ4›["Λ?Ϊ 2v‘ΙκAΙ―ρΓψϊσΕΥVγNω₯f‰Τ²ΗœΓξΈΣ₯XΧΌowγ:Δ²ΪΕowiu ]}v€ŠXΨνΞ3@Χ΄ifŸNπ₯νΞ•ašm„R>›Ώ*τK麟€nόS₯£Οom3ΐΔ#«―T=pyx_Γ-Ηz߁žΫΓZή›#ς =ΫcprG¨'Ϋ?v_όA‘j.uΉ­dΤτk„Δ+'’η2χ°pUΊύ+Η =΄_u·Ύ·76«-Α’ΫKΕΘΟo­gψGώMwYϊO‘бπ‹ώMσΔ?οάθ΅  Ÿ:Ά‡ƒΌA} hΣΨΗjΖYR[―9₯*…‡Ν΄cŽ•B?ΪΚ}7u§‡o'ΤΛ‘φT›*cζ.τ²ΏgΏω&^4qτKRώΙΦp2λχo΄ΰΗb2Bςp(Π>όW°ρέάφ e.©Δžg’ς Τ­ΘΟ ΟšΜρ7Ζx,όCq’ψoB»Χo-ΙYLo±A_Ό‰Ηp? γKΪKSŠ ’θm^έ&©i2κž ψΝΕα[8όC)󍴨cœ꧃@ƒΰߍ“ψ£Δ6ΊU·….–I$T™ηxK]†Αΐό+Ψ/?γχωWŒόπ.»₯ψ—Vρ7‰ [;‹ΠϋmΛΎζ$ƒ=+Ω―?γχωPΟ²όŽ>'_ϋR·> _ψnηΗΊμz&ƒ>Ÿvͺϋζ’μΚ€oΑ »F9ζ°eω|O\Ώφ₯Eϋ9ΙNρ'ϋ’θΚκ5P¦­siαΟέjπΫ’u›`ldΗΉό«l|ZŠo‡W~$]Q‚Hζ6«Ώ{·9Οχr@ιΌΫ^π‰< yyβo‡ϊͺΟ₯a₯&RV<ηkΊκ?₯wρ΄ž7ψEβ9νa·½΅†X¦ΙL‡ΆyΘφ  αOΕ½cO76ϊŽŸ¨kur›fσŽ Œ}Σ랒½;β'Ζ ? λ£DΣτ©υ}Pc̍$Ψ¨HΘΓqΞ1ψΧ/ϋ(IΠuεg@ΛqOA΄σSόSψe¨κή+›ΔΎ Τ’]Z2¦kq(YΒ€ ‘Πγκ>|R>,»Ώ΄Ίπυφ›sgΈ“soM£Œd… žΓKπ»β|^<Τυ;4₯²k1½]₯σqΟۚεώόEΥ΅―ήxoΕ0DΪ”11ϋP@Ϋ IŽ η¨τ5λ:$Ί$’] M=δϋ²²ύ­ΏΦ€5h’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š+#Ε^Σ|S£M¦kωΆ`πpΘΓ£)μEkΡ@ 'μη§w―ή-Ή9ΨbRqιœΧͺψ3ΑšO„4'Σ4˜ΩR\™es—‘ˆΖI’ŠπΛ―ΩϊέηŸμώ$ΎŠΦf,Ρy`χθyΑ―DπŸΓέÞΉΠ’„έZέ‚.š~LΩηΣΫ+―’€<>οφ}°[Ή[JΧομν€λΠΨ™ΘΟγ]Ζ…πξΛFπχ…­οnΝζK‡°fΰ+Έ’€8†^ƒΐzEΝ…΅μ·‹<ήqy)c₯vQ@y­|/΅Υ>#[ψΉυ)γžΕΈŒ;sžqOψ£πΞΧβϊ|·ZŒΦfΝ]@Ž0Ϋ·Χ'ύšτ (‘ψ“ΰ˜ό<ΆπΡZίΝx.™X™.άjξh 4³ψqmαίj^5Šώββΰ€σ}Ζ’Κx9― Π4½'β/ˆ5½cΔ>!ΣΌ9<“o3,{ς9#s۟|ΧΨΒjΏ Ό©ή½ΥƏM#n)Κ>ΈP‡ό7σΌ=ρšΓGπΆ»&―₯ΘΫn"|§]€ΆGC· +κ™SΜ‰ΠœR3υ¬? x?AπΒΏφ›«ΈΓH]‡¦γΞ+z€<αΏΓ;_κΪ•υΆ£5Ϋ^ΦI# ζΟ4Οό0΅πwˆυ ^ίRžεοΖ.[wPkΠθ  “φ{ΆV’;__Εh瘊‘θyΑ―Jπo4 ψf}ΝX.w—”ό–]§>œvΥΡ@ σ¦&©ηΫλw‘Ϋ 7ˆΌ°HΞ3ŸΦΆŠIό+ε/…Ίζ³gρK“NΉΉyξQ']δωΚOͻ׌žhνΚ(’€2ξ|C€[C,³κ6ΡΗ†',γ‡νϊΤϊ^«a«Bι·pά’œg_Jσθ~«βο]jVρ]y["ŠU ͺX’[iγ<Κ\Ψ[xsβž‘ύ“[A©Βι4 &WœΰtνωWd¨SMΑ7t―ε΅ΞHΧ›Jm+7oΖΗsq­iΆΖδ\_[Δm°&ήΰlΟLύjM?T±Τ,εΤRڌζPp£y5ηZ¦·ρcΔ?Ϊ)ηΫ[€1ωŠ ρΝ^ψŸ Vz>‘’ιΡGegz±Κ° EΫԌSΚ—°‡4`žΟπΈύΌωe6΄W_ŽͺίΕz ΕΨΆ‡V΄y‰ΐQ δϊΠ֝ύνΆŸlΧ³€)»œž•Λx“ΑzxVξή :Φ†xζHΒΈe\‚[©ιΞk‘Υ΅ υ?±Ovεζ ±=X,˜ςˆΠ…K87kΫο V;©₯{\τyόO’[ήύ’mRΡ.3‚†AΑτ=…?Rρ¦L±_κ6ΠJΐŒγ8=+•»πvΓιΨ[›‘gζ›“2y›s»w^΄Ο‡>nόks¨ΩAyux…€štψθ'‘€J:*<Χz;©UΛ–ΛUsΎΆž+˜kyX\nWCΓΨΦUηŠ4;+³kuͺZGp Aτ>•ηήΤn4†#{i5•ΔΡΐ{¦v‘$Υ Ά†"‚γΑZό³¦ι.ώΖ\ΘOρ+γ8τΕZΒ$ε}Rv!β›QΆ«ž«―kvz>.‘q•γš&£ η‰5ΝKSπνώΉ)Έ0ΖcΆσ£…Gπΰ‚Ζ?Ι­ο%Τ>8Ώk=Q΄k¨w˜§‘AŽœ`gž*g…P‹ΧTΌ­ώeCε%¦ωάτ[+ϋ[ο;μwΝ乎M‡;Xuޏ·Ϊh}‡νύ³g™δηζΫλJβώtρ'ύ…%ώtΒAψΤ1ΫMώ¦³tœ£}•Νfα[wc«ΥΉR-CΓ«sα JƒάEd6±=pνΟς₯ νM= udΰΦ§€}ίμFπO΅d2†v’sιŠΝ»ρN‡h±RΥͺ2ωΘ=ώ•ΑxWƒϊκ1m±GvˆψG—œ~d֟Γ ix:ΞζσOΆΊΈΊRΞσΖγ$3ΠqΪT!O™Ν½ˆyΤεPKUsΌΆ»·Ί΅[›iγ–έ†α"0*GΦ³nΟν ?+±*9π!ωP¨A΅$ύΫ_Ο@uδ“‹ZήήZ•β-#V˜Ε§jχˆάγιF©β-JœC¨j6ΠLFv;όΓκ;TΩ:^‹Νώ¦Ϊ[Ο σC‘ ㏠―)πUε³Ψ\ήκ^Τ5»ΛɝδΊϋ'œ„g’’ιE:©y+Ωz\*V•;EΪοΤφ«[˜nν{YRh\e] ώ5΅¨Α€i7š…ΡΔΡ4―τ5Δ|)ŽφΪοZ·}:ώΓK2 m"Ί—nμδ ύ3φ‚Έ{o…Z±Œd1FHτiΖ΅?g7Ν©OΪAI’ΧΒέSXΤό7sβOήm·ΎvΈΆΆ*ͺ–ΆΰœrNG9$ρŠθξ|S‘[y>~«hžr‡LΘ9‘ϊU Fή;O†“ΫŠ-0’θ#¬†ΎΡξ<kq}§Ϋ\ά]£3Ι*`2@žGt«§NŽso{hDκOŸ’ ₯Ξϋ_l-βžοQ΅Š)†θΨΘ>qκ=j֟i©[ ‹ ˆ!'γlŒϊWšό'πζ›sc¨\j±^ΌW/mΪH#E=<I«-γΣ|kβΝ:Ρ|»4xέ"uI όAWR„#Μ’έβE:σ—+’GCα&’8΅7ΊΦ“SUΉrΛύΓτ«w>'Ρ- ‚iυ;UŽq˜ΞόοΖEqΏδ βΟϊόΈώF«ό$πΆ™sᘡFΫ‰˜…7 $¨<UR””¦φkoBaVmF0[§ΉθRjϊ|RΌRή@’$^{+8ϋΗΪ“JΦ4ύZ9dΣnβΈHŽΧd<^uθΦϊΟΕψlξ6kb―$@ΰ8Rp§Ϋ8ό«Gβ„Ph^ –ΫFΆ‚Ε/&Hdς#=s¦*}„ŒSΦVων攀֑ΉΣΒ[ }«μΪφ~nq0c?^•­uu₯«άάΚ‘ΐƒsHΗ\Χ8ώπϊθ-§6Ϋ-Ύ–<έΨϋΫϊζΈύ2ξ{Ÿƒ:΄W.dkQ-ΊΉη*§ŠJ9λχKοVpilίάz%Lj΄‹{¨-¦ΤmΦβ}Ύ\{ςΝ»§υΘxgΔ¦Ÿρ#UπΏtΧi2έ6vESεwŒν?₯^ψ}α]*ίΓΪmνŜ7:„Ρ₯ΓάL‘ά1'¦8ιι\χΕ Z|Rψy}ΔΟtφĎ₯X`ώ1¬ͺΖ—,zR”₯iu=^Šl#‰ά‚B‚ΨN+Μίγ–ŽΚ|?βbTγ"Η²¬N γ½ΔΦΏ uΩ­₯’”C΅γb¬3cθ;ΒΌγβƒΙ} |<πι‘β²Υ€‰nJœnDDωIχݟ·ώ$|=πΟό+νSμZEœφ6―qπB© dRά°9Η9 ϊηVΣνu;]:βξο0ΒΝ†NΰiΊΎ·¦hζάj—ΠZ‡ςβσ_nφτ˜―ρ£{uπΧαχη/%φ™v‹<έ7•Ι>ϋ?οTŸmgρο/m΄ηfΆπφ’ΧhιΠΜϋXΔ|šχ}[T±ΡμšσTΊŠΦΥHY[ ιΝ[FŠΚr€dQ^β­dxίDψq₯FwkL³έ(δm‹‡ώ‘ψWoβ/‰Ϊ~ƒ¬άι“hΪυΔ–δ)–ΪΣ|m•ƒžzΠψίβ>αŸθΊKOhΟu9[Ζy?γΦ<}γŽ„“ίήΊH|Q‘Ο¦ FRΡμL’{₯ψΕzόώ&ρmՌqέύŸLΆ΅»ΐNpAνΟsšήψ΅έ玴™τΏ#LKΨέtλ€ "ά*Tδ ώT|πώuuβζΊ4ωšίV’8L–ΘΖ5r8Β€2υνkGρOΔ[+Sρ\–^Σ­Qaϋ-ΨAq!ΖI~wcϊWα­5΄ŸΫYZψK«΄μ&™<›εnAσIοΧ―Ύ+—πΟ†τ9~5ψͺΞMM{Hm`hΰkT(„’«Œτ­ eTύ£εTPͺΊ& Ι@…―xFπϊ#λZ•­Έ%p }SOΠ΅ύ'_ζΡu {ΨΠαΜO§άv―"ψs’XψίΗ~0Χ|Ko Φ·bΪ …‘ Οπž:Ζ½FΠτ­f]N΅±I˜<‹oXŽ3Εr_ξ&΄ψSMk,Μ’―a™γKβΊ xY ρθΫ’C#g1}Oτ¨hω$ZχύsŸΏδMψa;/ύΠͺkzξ• Ϋ¬ΪΞ‘mg)™Βξ>ΓΏαTτxwWIŸMΦlg‘–LJDXƒΘΦΈŠΊ£΄Ώ.„Υγό;’]kž5Z>›0·Υ6CζZ£yKƒΒδp>•μϋFέΈqŒcŒP„xΫΔz_Š>%Η£_x§μ>΅³σ^K; ‚i‰Ζγ ΧͺiFπ‡…-ΌέX1Fθξο ΘωΈΟ―:²πή†ίομ[FΣM’ι+ ·6©ε†ά>`ΈΖ}θΥ΄Λ_|w‡BΥaGΡ΄]3νY‘ˆ™‰A½1σ= τνŚΏ+E£jΦ—r¨ΙŽ7ω±λƒΞ*υή«ai{ ₯Υά0ά̌ρΖξe^Xa^Gρ«Γϊo…μτψvΚίMΤlo#_τHΦ!*1ΑRΒ™ρƒIO|Mπ.™q$‘ΫέΗ0›Λb₯£3.}ΐ#ρ TΠόO’λΧθΪ•΅μ–ΰD-»nzsΣ±­Y₯ŽžY€HβA–w8 =I5›‘xsFΠ—Eμμw¨W0B¨ΞMΔrέO_ZΖ:†¦ψrφ5Όπζ₯ΰυΠώίΪΪ¬[αΤNž°ͺ`Œ>ώ€{δΦ—ΔΙ₯½ύό;$ς3Λ ³ δδ“·'Φ€=VοΗ>³Τ Ξ»aΆΦŒΚ>SθO@kfQ³°Σήϊφζ(lΠi° ‡5Β^|:πΔξ-NdΣ-“;\˜TΜdNύψݜϋΧ.₯Όύ•Yά»‹v$ηεIʏРυ}KΖώΣ.–Ϊϋ\±†r،€FFqΣρ­λiαΊ·Ž{iRhd’HΨ2°υu―9πΓΟ ΒΏΣVϋG²»ΊΌ³I.'‰^Fw@Ηy'ŒΥΛxUΊΡ~xŽKY\Ι¦Ιu»’ Λ9 PΤόsα2ψΩίλ–0ά©ΓFe©τ8ιψΦμ7vσΩ­ά3Ε%³'˜²£R½rγζΏ Όα·π5ώ“ewžβββ%‘ΩœdᏠ}>½kαJΙ£]xΒρΚςiΪt²5°cŸ-X7ΛόΏΠ―iZ•–­d—zmΜWVΞHYbl©Η^iΆš­…έύΥ•­ά2έΪγΟ‰[-zdv φx’[¦ΧI?τ*₯πΰƒρ‹β<ΐ?τ*ξ.Όgα»K6ΊΈΦ¬c€JΠ–2ΎΈΚγFGηW΄MsKΧmΖoy œ…Γm>ώ•γ<%€jΧ~&Υ5{{ι#Τ€‚ΉŒH‘χ$)γ'#ŸjΩπΆiᏺΆ›£Α₯…Ξ’·/oځÁŽSωΠ€λή#ΡΌ>ˆΪΦ₯keΏξ d›θ:š~ƒβ 'ΔI6‹¨[ήΗΜ/’€τΘκ;Χ“|=ΠτψλΕϊη‰-£ΤσμVΠ\(xγUο΄ρΨc>υόM‚ΟΑ_ ΅ϋ Y[ι²ά¬mcŒΆ88 ŽηΗ~ΆΤ Œϊφž—JΫ Γε>„τmκ…¦c%νυΔPZF4ΞΨP ΐ9όE|υ’&ˆžƒK›α޽u,ΆΓΜΎiiBΌΘ²c#“‘ƒ΄ΘΦ#ύ™υK[έΫέΫ―”©u#ωbTΫΓsŒP¬^xγΓW«iuιρ\ƘqžFOAψՍkΕΊ†ρ¦­«ΩΪΌŠδe===λΣ~xq>>“i-δšqξή Σy› d?QƒοT~x?DΤώΫjšΦm©ήή4ˆήF&dΖ¨»³΄Ώ  _ΣοmuHξ¬."ΈΆe%‰ƒ+¨¬}_ƞΡο~Η©λVVχC¬O άΏ\tόkΜώέ·‡ό'ρ=ήF}v-’v„V ~‚Ή_‡—zjψ\Λͺ|=ΦuϋΫζygΤŸη‰I'ξ9ιή€>ŽΦ§O7λqYΜήz°)³ݟLsX—ή9πŌ6ςέλ–1₯Βοˆ™AήΎΈ½λΛώE«Ω|7ρέ†₯§jVt0ά>ŸτLŒ±Όr£pθ0Ιυ«< \ό;²Τu-*Ξώξχyi.‘YJ¨r‘Fΰp8νλ@¦šζ”ϊAΥWP΅:h]ΖδJ<°>΅Ηx↍β8fw–v—Fρννΰ2| ΖΦΑξsX tΛ8―Όαφ·Šm&ΪψyvΣ(t”œmƒΦ£Π|C€x‚'“EΤm―QΚ|•ϊŽ’Ό7Ε²jυA«ψ{Pρ–‘EmgmnfXΙUbμΈΗ%'Ϋ­hfοώΦ‹©xwΑΊΦ§Μ­’²X΄0Έ αˆhΑΑΝ{εb^x·@³‚βk­^Κ(νε0JZP6Θ9+_jΫ― ψcα]/]ψ‘γ«νfΞΥ΄Ύ)S¨tVfbΝ΄ρœ*Π°θ>"5ψžMQΆ½TϋώS‚Wκ:Š]{Δ:FI­j6ΦJsΝp }S^hšM—‡>>ιΡθΆΡY[κl†x P‘–SΧhΰtΙΆ« χΕ_k>ΤόJΆR KX ΅7ہԕΑ=³ο@ρ₯kϊN―§Ι}¦jΧV‘gΜ’'&N}8皱₯jVZ½Š^i—1]ZΉ!e‰²§υβ ‚μ|\:?„υ ΓΪ…£E{Ε›E pΪ;cκ}j/ λοΰo|B%­Ξ‘u!΄ΙηχΌ!ΩΓ~4νϊF΅¦k"s₯_Av .O)χloCO³Υ¬/oξμ­.αšξЁ>Ι,Φ>‰‘ —αǁt=#ΓϊUμš}½Φ±$Iu-τθ$˜ΚΓq!Ο#“Ϊ€:M{Ε‡Κ.΅ͺZΩ»ŒͺJψb=qΧwIΥ,u‹%»ξα»Άc$.gΣλν_;ψ_X·ΎρW‰υoΑΊ§‰^υΰŠH¬ΎΡ―@ €ΥΣ|#‹P΄ψ•­5‡΅}ΓW° VΪξΩ’&~ξF~no₯n| »ΈΊ_}¦yfςυyU7±m£'ž‚»[ΖΎ/ž₯­XΫέƒH2Ώ_OΖΌ·αΖ₯6ΰΟ‰Z·ϊϋ[λΉcγ8`ηŠη>άιqψE?΄ώλZνέξιgΤžgσIcΚΉώ#½}% Δ3Ϋ₯Δ2Η$»ΦE`TP}+œŸΗώ‚ομψƒNgip ―Jβ~ ά]hž ΧSΕ·Ίf‘gpοnΊŒL…-ΘΞߘr==k χPπ†§αBίΓ/ξ¬^6ί¦œgη7ΜpyλšχI.­γ΄7ROΫσ Μΰ \gvzc띢ψƒα+›±mˆ4φ˜ y }‰βΌΗBΡ5OώΞZnŸ(kΕl’HψͺJHŒŸ§Nά ±αέsΑOuc‘x·ΑφΎΥβ*±}’ΝUΗB²žHκx>¦€=SΤμ΄«&»Τα΅Ά^²ΚαWσ5CAρV…β‘4]RΦςDdώ`=qΧδ5!wρoEο΄‹νkJ²΄ϋQΣν"2dbί1QΤλλYϊ΄·ψΓΓz§„Όhw6χJ·NΊsC°’ ΈιžM{–½βmΓα΅©ΪΩ—εVW˜zΦ‘xFΧΥΫFΤ­ovrβ+υEy_Ž΄›Ν β5NJ―Ό4z…mθk‘ΚΨ‹·Κ–ΦΏ]ŽJX{%Μήχ·MΞK@Ρο­ͺ߁·²+‡GΔσ»ιηKπ¦e}—s {]wΑΟ¨β·(¬Ήί//Ν977ΘαΌαkˆ|9išΤ>Rί\ΚΓk«Œ Α<Υ xΟΓk₯Ε₯[jΦ°ε`ΈYΔgo`A>υθτVΏX“o™&™ŸΥK•΅cŸŽΧTΦ<+uk­Η­νΚ:l‰·*Σ'ωΦG?α%Σb΄Ρ΅]&³ΆB‚ρ'*>οΛΦ»z*=―Ίγegψμ΅R»ΊόNOαξ}£ΫꫨB"iοdš<8l©< $Z5ςόM›W0μφ°ς›Ηίά§Ξ{ΥΦΡMΦ““—pTb’£ΨσΙ4ox_^Ώ½πέ΄Ž~ώl–― FύA?ηۊθΌ5yβ+Ϋ™Ÿ\Σ-΄ϋP£ΛE—ΜrήψγΠΡD«s«I+χκ(Ρδ~λvνΠσ¨4ψ[YΥ[EΣ`ΤτϋωΝΒƒ0£sΧ9=)|7 x…<|uέn86ΟlCyN Δs\ž9ιΝz%o&žŠνY²V)­]“½Ž2λVρ΅εΔ+αΫ[Ψ7°†TΉTsΖΰ{γιS|<πύζ‰i6₯δΗs}9Έh ϋηψEu΄T:׏*I\₯Fζm»uλνMφΔ>ΓqFΣ"Έ] ±+Ά΅­n‚φ²I»ο~§›ιš‰n|¦ψƒY‚ŒG"g{XΦ+•Zχ8/κgΕίγ{=―y%‹ZΙ@+2§=9ηžΔVτϋ/Β:uμb;˜b*θ6Iκ8οSh΄ ‹ωt›cno₯σ§Q#/κœ/ΰlSη|œ/qr.n~»―Γ½"χGΣo’Τ"I-δ’  *OƒQψsFΎ²ρ·ˆυ ˜BZ^y~Kοv<‘ψΧ]ES­&δ˜•F)Ev8―hZ†›¦x‚Θr]άΝ$#zΚΐΰπxόkCαΦ—w£xNΛQˆEsmΚ62}GΡNu₯;§Τ!F0³]GϋϋώqΥό‘ύŸφ/'Μή>ώzc9ύ+OΖZ~$Π.4η-› γ;\t?JΫ’“«+©-ΠΥ(ΩΕμΟ<ϋO³²Ξ•hn6y_Ϊ?iqΣ~ήΉ8«xRk†χZ†./$‰²r|Œry=?νhͺx‡₯’Zά…Akvή–3Ό9m-–§[\Ω‘·HέrP"Όγ]?π’|uΡ, ;­΄κᗐ$a…R{A―X¬ Ú^…=όϊmΉŽ{ιLχΌŒν#žδ±'πιX·wsd¬¬kΡE†Η|^ΡoόEποW΄ˆDχΧ/.2κ™Ϋ*1εˆ€k±’€<ϋƞ Όρ‚τk{I’Σ\„S[;¨‘T€ŽΗ}…sϊΨψ—β½ό?s‘Ψiάή‘φ΅ώ-¨yτώUμ4P¬ψ*ήO…·²ΥlΌ˜ ρ™ζV?π0 cόπ~₯αέQΔUΤ%r—WύΪ.ΤRGLώuιTP‹|1ψu¬θ?οuXΐ,’hτΖσU²BίtŽ <⽦Š(Ξ>-ψg[ΤοΌ;ψb8nuα₯ϋ,J­·‘Μ&σ>fε8ۜφ<γθP]ψoΕΎ ρ–«¬x.ΞΫVυgάYK(γ~y1ΙΑχΖ8Νw~ Ύρ.‘ou7Š΄«m-·o S \rX‚GZι( ;βώ‰β/‡zΆ•€B'ΎΈςΌΈΛͺgl¨Η– t±~!x[WΦ<5α M>ΨK>Ÿ}k5Κ™v"! rN₯z]ΕψΏVρž™¬£x@΄Υτ¦ˆnΰE*Ι“ž½±ŽΖ°όαίήόDΈρˆτϋMύΪΗi’G|‘σ;Oει^‘EyŽ—γ?ψΛ]—DΡmυ#WΈΝΚΔΠ·9ΞOΏ§aΝzς(₯ΖŽG‘₯’€8+Ojqόf½Χήά *M1mΦo1rd 6η?Ž*§|)­§‹l|aΰο"]RͽŜν±nbτ Π:xη( !ΎΡΣ΅;zxξυ^fžυ“ξ ηε½O5ήQ@-α}?‬gΠ4 ΛX°Y™­/ιcΪ€“Ÿσή΅ΎxGΔZ‹|O¨ψ“Ι‘΅!‚x\wΛg Θ―S’€<ΰο‡5OiϊμZΕΈξ΅9n"E}ѐΈ?)8θx4ψ<=©―Ζ»5ΈώΙ}$Z‰ΌΕΙ“x8ۜτqŠοh "½πο‹ΌγSWπeΆ­₯κ¬$Έ±–QG'χ$zŸ^½;ΧA†½γo k:o4Λ}!n€Kd‚Q+(Ζw1Ξ=+½’€<ƒCΊψ›αm6ψvΛZŠΥD6χ©x±ξAΒξƒΐΗ\V‹τΏx“α6‘§ήΩΫ ~κ0>Ο€ >`8 Η­zƒrΎsFηφyƒfαχόΌc=:ΦWΑνPπηΓέ3KΥα^ΒΣŒ:Ύ7Jμ9RGB+³’€<λαΧ„ο΄γγhuΛaΆ­©Ο4@H­ζBωη‚qΑθy¬ ΛβΓψ$Ρ΄½ΧΔ:2;5€ίiI“¬ ώŸ{%ΕΪ―Š5―k°ψ‹O΄΄Τ+kkyC­3Œξ'Ύ*o„Ϊ5χ‡ώι^­†φέdF63#0δW]Ep^πξ₯€ψ§Ζ—zŒ+]Jι$Άa"Άυ8#―zζό ¦xΧΐϊ•ή‹‰m©h—7νp—Λr¨cG#q*NN鎹δΧ°Ρ@s¨kί,uKΫxΌ%e©Y™Ÿμ·^¬Y'nπέρŒτ©ώxWRπν―w­-΄š₯ΡΉk[S˜ΰέ³τώŠδΎ+hΧΪ€υM7J„My: “z’sώ?π―«ψ/Γ}…¨’κΚ{g Š»BΈδœ{W¦Ρ@}ρΓz–΅γίXΫ,֚mαšι‹¨ΨΉ^pNONΩͺ>(π–±£ψζΧΕ~ f’ΰωZ‡˜±¬ΙύπXŸλzτϊ(ΛΌYαι~6>1πT0\έ]B°ίισΈO4!³Œΰύ»ΦΏ…υκzΤ#Zπεž“₯*±•ΝΠ–F8ΰ(ΧEwTP^πΟÚ¦‡β/έjVβ(5ρ=³ ·§ΝΞ8κ:β½ŠΰυojWt]r(i–ΦRΓ,»Τrxs“ωV.·αΟψ_Ζ·ώ#πU΅Ά₯k©φέ>igxώ%'ΧΠΧ«Q@W„5_κzΉ>!Πlτ-c8ΰK+Ώn‡uμ+ŒψƒπΫTΧ>(YκP©Π―<ƒ©Ÿ1FLG‘Rrr‘G½’ŠςŽ>Φ•ΧQ@iπίΑ·Ά:W‹΄ZˆνυkΩΩTH­Ύgε'όΦ7‡­>!xΡ΄M?F΄ρ“7Ω.ΚΒκ€η ωχ―d’€<SΡόG㇝β{=7TΊΟ“2DCžrq\ν”ο|7…ίBΣτ˜DMHά«¨nV59ΙδW±Q@_ΰύ+ΕήψS§ΩiΊu€ΊνΌΜZΟ2νhΛ1 08Ο#½dx£OρΗΔ+k=/Sπ͎‹kΒM-δ—k+ӟFΙ―g’€<Ϋβƒυ‡Χ4ŸxAαmoN‡μοηjάΕΟμy>zρShΊοΔ-CV³†ϋΒΆ:e˜>Υ<—bC³Ύΐ_Ξ½ŠΰόE­xλLΧ'M+Γ6šΎ”Ψ0Θ·b)ŽCgίΪ³~ψ[^΅ρOˆάx¦γHΉo[ΓθΈao1ρ‚v’:ζΊΊ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ŠF`ŠYˆU$ž‚²τί躝ܖΊv­cusފ՘~Π­Q@ΚήψϋB΄7 $σ4πΜa0$E˜c8œυ«Ύρ^•β‘4ωœ\EΛΑ*uΈ?΄tj%Μβμf«AΎTΥΝΪ+›Τόk’i—7Άχ—“Ϊ2«Ζ–bΓ (x«Z‰΄λΝ υvi-lΝr»ΑΗJ)₯vUƒvΉ΅Eqp|Iπό“ͺ»έΓ «q-»,gρνψŠθ΅½nΛF[RΌύmω£³ž˜Ε£R-&·VM§±₯EqΧ?ό=шΝpρ΅1ώχψTΊŸτ ŒbiŠ€Ξmb2*Ο'₯WΥκ+·§όΘλ(ͺZF©g«ιΡ_iσ¬Φ ‡tκ= swŸ΄ k™"Y.gHΫkΟγSώχΓ51₯96’ΥUa›{ΞxΕ6Zo…ΫU‚S2L„[΄HX3HΟ γΎ+?ΐή3·Φ­,-fϋKjOι\ΐU Ξ₯5BnvΡ Φ‚’…υ:θ. Έ mζŽP§kl`Ψ>‡κZς_ψ§LπύΎ±λΚχj2”†ΛΉλΠ}kΠ|9βm3Δ))Σfc$\IˆQΣκ U\<ι·¦Ι₯^5Χ^ΖΝΞxƒΖZF‡v-.dškΜn0[Ζdu§°«Ύρβg›M˜·–vΙ©WCθA¨t¦£ΜΦ†Š¬ΉSΤΦ’³tMnΟYϋ_ΨYΫμ³4n\aΗ\RrΛώ’ξ·y>~έΏ.ί­O$ΥΆTυ4θ¦O*Α ’ɝˆ₯›€f©θZ΅Ή₯Ε¨X35΄₯‚–]§‚Aγκ G+΅ϊu{u/ΡYΆZݝξ­§@ΞnlΆωΐΘΘΑοX748.$Š1{t±ΆΧ–ήάΊ)ϊχό*γFrvH‰U„UΫ; +>ΫY°ΈΡ—UYΒX”/ζH₯0¨<Χ;ďΛr‘™.£…Ϋj\Ι,Dύ{r(ΚφO@•XFΧ{•™k–:%€7ς†iVe†ζΓƒΝfιώ55kϋ6Ι&›χΛ| “σ₯ ”δΉ’Πn€εoS₯’ΈΫˆΪSΘ‘}Άζ8ΫkMΉhΑϊχό+¨ονυ;o,ݞήe܌ΚT‘τ<Ρ:S‚Ό•‚5a7h»–¨―>ψΟβ ½+Γφšnε5mfεl *pΘ§ο8ϊp?ΰB·RοOπ^ƒ₯Yκ7R˜ώ[q<¬\³ΰ’ΜΗρζ’1rvE9(«³€’Έθ~#xzKΔ€Νq;lK‰ e‰³R:β&grρ4·’6ǚKF‡έ»ώ­~―Vφεf_X₯kσ#―’Ή\i·ž»ΈΉΉi²ΒΝoχΆžβύ±¦θ~ζ–iMœ‰ 0Θΐ–;”m-ψu5*›kMοbDž»ΤW5§xΣIΤ΅Εμ Δς±aη$GΚΚ‚OΝψT4hΪyžE•αςcˆ΄…—―žζŸ°©{r±{jvΏ2:Κ+οΔϊ]–‡oͺήΜΦφΣ¨hΦD;Ϋ# m9¬ν+Ηϊ£{¦ϋ‹Y₯8ˆ]Bc@z~t•6έh'fΞ²ŠΛΦυλ [4Τe1}­ΜqΆ>\SΨV kΊW­υ O–ϊ3$-‹΄FŒFVΘ=qIR›2Z Τ‚—+z•η_§‚3ίθ΅…Q@ –D†6’WTFY˜ΰξjΆŸ©ΨjJηNΎ΅»pζ VM§ίŠρOΪΕއαΙ%»6’ωSŽ8œ*BƒŒ9Α'<⻟^x/CπΕζΏ€[.¦9 <“DΡ³ΘSΙκqŽΉ φŠσ‹/ŒžΈ»Ž)dΏ΄†FΫΥΝ«$,ήνυ W[βŸiΎΡΖ©ͺΚΛf]#οεΊtν@TWcρ+Γϊ‡Š#Π΄ζ»»Έwhόψ &ΐAΐτΝv”T1έΫKs-ΌW½Δ@"W“=2:Šα΅Ÿ‹>υI¬·w³@Ϋfk+s*D{‚ΓΣΫ5Ο|/Υ,΅―‹~2Τ4»…Έ³žήέ£‘r29μyΨΠ°Q\'ΓwΠ­ΣΔ³iΧ’Ζš„vΧ„€Bηψqή©Mρ—ΒΙ3ˆWTΉΆVΪn ³f‹?^ ό¨(¬‰|I€ΓαΔΧ/)β εR™SΣ‚3“ιŒΧ%₯|_πΞ§ͺAelš§οδΕ;Y°ΙιƒΧσθ”V%‡Š4Ϋj^·y£§’Ι:”!@`Αοχ…;Yρ.£κΪV›zς-Φ§!Šά* SΪ€6hGş΄ _₯…δ—7ƒ.²ΩΒe/©Ηρ57„|u’ψ©.ΜΧ1=’†ž;¨#œΰ’xμ{φ ’Šσ‹ŒžŽgX§wnŒU­μΩ’ΘλΙΑ?€§|KΤ<7«x/HΏΥoοΰξ/!’ή[Tew|1PT€@ΐ=G₯z-•β-{LπΞ”ΧϊΥΪΫZ¦sd–=€’~•Ιι|/¨κΪ;ήΨ΄νΆ/mŒqΘ{܁ψβ€=ŠΔρOŠ4Ώ Εe.±3Cάλo…Θ {±μ=λ““γ/„£»΄·ΒΨΆΑ{φGς {=ρ@Ecλή%t-ϋ[SΌH¬H$Άότ $šζ4oŠώΥ5K[‡UΆšιΔp5Ε“*Θǁ‚3©ΕwτQ\—‹~ θ^ΏKχ»šύH-νmΪFΪsƒΣzλhgΑΎ7Ρ|^·IšQqo:ήxΜrGŸP₯gjί<1₯I έάίi³ŸμΝn–‘ίωκ1ί₯vτW3τ_ψD“Δw“Ia¦Άpn“kη8ΖΡ’IΗV™ρƒΒ·ΧΡ[I%υ™ΆΕ5ε³G‡ΩΉΗγŠτJ+Ε'Σ|3œΪ«Θ©u:ΫΔcBΩvιψVŽ©}™¦άί]–φρ΄²!@Ιβ€-Q\ΥύtkoEβye˜i2*ΊΏ–waŽΛ\ώ₯ρ‹Βv7RD%½Ή†3ΆK›kfxPχω»ώ E’©iΊ­Ž₯₯E©XέG5Œ©ζ,ΐαJϊσΣρOŒ~[ζ…'½–έcήGjΝŸχΊγά P}kymwζ}’ζόΆΨώS†Ϊή‡΅O^Iϋ>MΔ^/šY"“W‘ΡΤδ0<‚+ΡόRν†ug™m%*ΚpAΨy©ExWϟψOΥ¦ρ/ˆ-οξ±xο_‚@ΰšθ~xŸRhόU€ψŽμήΏ‡§)φΌe€ŒnΞ}HΨ:υJ+Ξ~1xN+;9αšςνTΊΓon^DPΕrΓ’ςzήρ_Žt/ ZΫK«άΊKr†Ϊ8ΛΝ'ΡGσ8ΣΡ\g…>$ψ{ΔΊ‡φ}¬·Ί–ΪςΈυ^ΗιœΥΟψλAπΞ€–ZΥΩΆ•ΰk…&2ΐ¨8ΐΗ%³Πh§’ΈβΧ…u[Φ΅k›‹ Ά4Š/‘0‡U$ΗOΖ’·ψΑα9΅(m Χ±G3„Šκ[VH]L1ηρ#θtVv½­ιΪ—.£«έΗmgΙ‘²sθ“μ+‘Πώ,ψcVΥ °^ΩΝpvΐχ–ζ$”φΊsοŠοκ+«˜- iζŠWοI+…Qυ&ΌΓβ§ΔΈό3―hΪ]™Έ›΄{Φ[vaδγ•RGΜΗ ρœbͺόPρ=‡Š~kΧzb],Q:DΒβΞTπnEzκ2Ί+£V‚=ikΛl~.x[LΣl-$šςγΘ·&žήΩ€Š6 »γΫ5θš^­cͺiQjVQΝc*y‹08χΟOΖ€/Q^suρ—ΒVχoΛ}=Όo±ο!΅fO›©ό³Xρ>•₯xaόA=Η™₯ͺ,žl#~εb#zŠΪ’«ΨήΓ}§[ί[’mη‰fBFΦ} dθ~-5λU΅Έ)ck#Η,“.Ν₯>χα@ΤW›Œήσ2UkLΰ]­“˜Ύzγπ―EΆš;›x§„“¨IR€‚28<Ζ€$’±/ΌQ¦Ωx«Oπτο Τ―’iaP„©U NOoΊiή+ρŸαm+ϋGVyΫΜX³;˜ΰq@4W;βοhήΆ‚]^wpq Fd’Sμ£ϊΦ…>#hž%Υ³m#Τm―Š—X­Z<¨κsΘ‰ ʊγυ›[ύBβΤβΰX[Vίsp8φ« ψ‹‘ψΎυν΄eΎbŠY€–Ω‘1‘»¦yι@•ηϊΟΕΟ izŒΦb[ΛׁΆΟ%³IGΈ-ΐό³]†ƒ¬ιϊώ—£€\₯͜Γ)"δ~Aφ<Π… νΤ66s]]?—(d‘πNΥ$ΰWžΒεπ ™wΆ€–₯Ά‹·²qηΧτ H’±mτπFΫξ VxTχω»ύFhΡhͺvš₯ή”š•½ΤO`ρω«>p»1œη΅pΏπΉ<"o%žυ­•Ά5κΪΉ€γοuΗΎ1@ύ­ε΅β»Z\C8F(Ζ' ΅‡PqΠΤυε?³ά‰.β"exίV™•”δOW©Ο,pBςΜλH 3±ΐP:’hτWšάόhπ”WO-¨έB‡k\ΫΪ3D? όuΎ!ρfαέ=SWΌφ²€c ΎBF@ ŒηΫwΕnΡ\…ρcΓΎ₯ ‰’ςΒβsˆEυΉ‰e>Ήž+‘ρG‹4 ›ν«ƒn—’γT2wΓ»EyξŸρ{Β—Ί€V^}έΏœώ\7ΝRžΨcΣρΕ6ㄬ―ZžςXό·»ŠΩš9ΗήουΠ’QXΊο‰τ½ΓΏΫ—““¦„KξΘrŸ§"ΉKΏŒžΆΌ15Νδ–κv΅δvΠι»ΏΤ(Ρh\ψ―αm&ΰΓφ‹›ζU νc™#d·Χ5Ριώ%΅ vΖηΟΣDm)‘Tδκ0yΘτ  š+;Ú͟ˆt[]WMgkK•-uΪHɏ«hΎ&Σ΅SV°±yγL—ΙΈ „ήΗΏJΪ’ΌςŒŽΩ$†{Λ©Y™~ΟolΟ"ν8$Ž€gΤσ]ƒ|e£xΒΦi΄[–v€…š€‘ΣrŸ‘η₯t4Wšψ_TπΦ‰}γFΦχR Ύ'PI#i<Ή70Ϋ$g#ςνXίώ/Ϊκ‰4zΒ_5ΥΕσ₯ΈŠΠ²€eΎE,8ΘΟ4μtV/„όM¦ψ«M{έ"I(εh]dBŒŽ½A₯0x§Lo7†£yTHΓͺ‘*ŠznnΗ§β€7hͺΊ¦‘i₯iσίj3₯½€^I\ΰ(ΐΕρ“ΓLƒΛΥ–έΫ tΦ/ε7ΈοϊP€QXz—Š4Ν;YΡτ»—”]κ»ΎΜdƒ΄r{u7ŠΌAaα}mWVi"‘Š&γΙΐβ€5¨Δ>/<=§iχΪ€Ο­τ© O³ RΓw ΐ<Χ2ί<"·’žρmΛl†Υ„ηϋέqοŒP£QXΎ$ρ>—ανϋgP™Ώ³ώ\IοΘn„c΅rΊ‡Ζ Y_< =δΠΖΫξfx½ίκθ”UK]NΚλKMFήκ),?4NδΫλšΰgψΟα(ξ]MB{dm­y£4#ρκGΠP€ΡYΫϊkxr]v •ŸLŽέξLΡ|ΩERNβΉŸ‹ή‰¬ή[ΛΙ.U\%΅Ήsn›ϋ§Zτ*+ΖeψΕiΔ‹«GϋiΠΰ΄Ψ-»O»–Ζ7ΑΗα^Ή₯_Γͺi–·ΦΒAΔk* «`ŒŒƒΠΠͺ(?βψÞΤ. $^J’ήΨ/S#π1ϊŸΒ€; +ΘΎ^κzV‘­xCΔW2OfRξ%bΕ£‘A Ψ?3]ο‰|a£xjφΚΫZΊϋ1»Ρ»)Ψ.γ“Ϋ§¦€: +Ξμώ0ψRγQ†ΥδΎΆIŸdW¬‘9=0zΔ κ|Oβ+Γ1YK¬\y0έΜ ŽLeCO'°ΐλ@tWœ7Ζo­ΨζΏ[fm‚υ­@}σΧψφηQ³ΆΣ_Pžζ(μV?4Ξ[δ Œη>”jŠσeψΡα&Έ _Q[BΫEλYΈƒσλΒ»sĚfαΉ5Ϋ©χιˆ‹'›ίΉX€Η^’€6(ͺφ7°ίiΦχΦδ›yβY‘ƒ΅†GCXΪOŒ4W@½Φm$”ΨΩ΄‰+4d0)χ°;ΠCEyΥίΖ/ Co-νι’5•–ΦٜΔΘίΨlζΊο xKρN”šŽ‰r.-˜ν'YuVh^Šΰ|CρcΓ.§%ƒKw}uΫ*Ω@eŸBx–k~ΟΕΪ5Ο…‡ˆšδΫιEKn£+‚AHΞr1Η^ΤΏEyζ›ρ·ڌ¦[ΫU‚CqslΡΓ!=0έ³οŠιΌSβ½'Βιc&³9‚+Ι„Ι·*ŒεaŽτ»Eyε―Ζ O©Ghn.αŽGΕu5³$21τcόȍOγ„τϋΗ…/'Š7Ω%Υ½³<(sƒσwό3@‡ETƒR²ŸKMJ˜šΑβσ„ϋΎM˜ΞμϊbΈ&ψΝαwεω·ΖΧ~ΟΆ‹Vς3ώχ\{β€="ŠΔρŠ4­CM_PœύΩeˆoCΗozεoώ1ψNΞνβσo§‚6ΨχpZ³ΐ§ΏΝίκ E’ΈίψηNΠΌϊέ¬Νp·±΄1³‡b€‚p>QκN+/α—Δ{?Ψiv7?lm]νCΟ+Ϋ2DX.X†ιŠτj+Ξ―>0ψ^ ™b·ώΎŠ&(χ–Œρ)~n3υίBΥ¬υΝ*ίQΣdi-']Θ̌„σŽŒλ@¨¬Ώλϊw†τ·Τ5yšU`ΉXΩΙcΠ œšε΄_ŠήΥuk};7ΦsάΆΨ ε³F²žΑOψβ€;Ϊ+Δ>-Ρό=¨YZjχ?g{΅‘£v ₯˜±νΐͺρώβ»λ»}%ovΫGζ΄σ@c—8Κ“Ιό¨­’Όκγ„ν/ee½ΉŠ&Ω-Υ½«<({ε»ώΧy¦jš₯„Ί|ιqi:‡ŽT9 Y’ͺjΪ…Ύ•¦]j¬RΪΪ6–F8P2k‚ΏψΟα+H-₯Y―n|θΦV[{rζ=7σ€}²MzEŸ¦kZ~§’C«ΩέFϊt±ω«9;T/rsΣ9ΟLW'Ζ_₯ο’.ξž ϋ βΫ9€γοc§Έ E’Ήˆ9ΣΌ%αΏνηyγch!Bλ!ΐΑ,8‘Ι5πŸΗ βm"ΦΪσνo«€m̏lc$τSΠγ ~θVwˆ5½;ΓΪTڎ±t–Φ‘}ηlœžΐΙ'ΠW ?Ɵ Ϋ2}ͺΫY‚9?ΥI%‘ /ϋΌδΠ¦Q\νnjtk? Η―κΙe§Θ2ΏhŒ¬„ηlλ“Ž•αΦυhtθήςΞκ~ –ζ!7²žŸž(»’ΉίxΟDπΞ‘ei­]g»I7e%A““ΫΫΤΧ=aρΒ·z”6%υ¨‚C=Ν«G„τΑνψ@‡EgλšΞŸ ιrκ:½ΤvΦq ΄“ψ9'ΨW£ό\πΎ§©Αcζ^Ω½Γm‚K»fŽ9IθvΟΎ(Π(¬x·Gπέζm¬\›vΏσ<§+ς €ά{}αYώψ£x³SΉ³ΡυΌ”σ<ι`)qς“Ιλι@u2y£·…εžDŠ$™έ‚ͺROJσΛΏŒ~·šEŒκW0ΖJ½Δ6Nc\uΙ8ύhxοT²ΦΎλΊ†™p·sι΄r/B6Ÿ^Eu’κ6QY-δ·–Ιhΐ₯P„˜l㚴##‘^ γŸω6ώ½ν?˜―Z΅ρFšFW¨ήzτμ*|Qπή…ͺI§I%έντ_λb±€ΚbxπφΞhΉ’°Ό%β½Ε–Os’]yΛΫ,l₯6τe<ŠΒΤΎ*x_OŽοΟΊ˜ΟorΦ†ή8KJξ ΅{ŽG=(Ί’Ή³γM/ Cβ;ι€±Σe]Λφ”+'RΪ2rqΠV>ρ[ΓZΦ«œygq9Δl·1,§Ρ[¦~Έ ς‘Ό»Ά²€Νyq Ό ΰΙ+„P~¦²ΌYβ#ΒzzήkwbέΆF€yΡTrkΖ~2όDΠΌQπξςΖΙνο|θ`»€ΔΞ‘Ή+Ψώtτ^”ΩdH£i%uDQ–f8{š!RŸξŠποΪΕ62άθώiόΆ«j)NF1…nΉΐΟA@Ο§κš~€ιΧΦ·aΘ™dΫυΑβWšψkXπ7†΄EΦt‹ 4ΛMBε,™šFgΫΈ7AΙζΆ4/ˆϊ½β/μ}!ξdωΏV ;zαΟ_ΛΩQ\'ˆ~*xkEΥ%ӚKΛλΈN&Ks/”}π3μ+‘π§Š4iζσD»Ζ§lŠT«Ζތ§hjŠσϋο‹~΄ gΊšζ ‡ΆkhmΩ₯,ΈΙϋΌυ$T°όXπŒΊ;jPpO(Ϋ[Οίύί/?^žτέΡ\‡ƒώ!θ>+ΏšΗO’βψ—yΆΊ„Δε}GcωΧ_@Q@Q@Q@Q@Q@Q@Q@Q@Q@Ελ]FσαΎΉŒήΌ#j§ήe ξWp―“ώιΪΌ4…αn!ΉF…#Λ@~mޜg­}ΑLHc‹$h¬z @’Š(ΝώΪΫΏ‹<]rΚ­r—A#•RXρυ#τ©ΌAvŸ|=-ͺ…šκ}ΌnQœώ{V†4VηĞ$Τ4E-.βΌ1˜―4ΊšYώ@Σ±bIώ蔁ώ…tΧ>ρ^£`4½K]ΆώΞ ,’E%‘bzV·‰<(—ή ]LtΆŽ0ŠŒΰœσŽηωΥSœ)rΕΚώςdΤ„ͺs5{­ {§[Cπζk5‰<•°ϋΈκvg?\σP|,³‚ια"LN…δγοO_ZίΌ°yτlΤ;ۘC™ΫŒΤ>δΡ|=e§M"Λ%Ίl.£Φ.₯ιΈί[άΩS΅Dνǚxrilώx³μ€©ŽζdL!AΗαWΌώ&‡ΒVvϊw‡τΩ¬d‡;Ϊδ =KZκΌ'α_μ#T°Τ+˜―§’F ƒY…όQ FΦz΅jΪvI‰.βάΡƒΨ]R­ s%mο­ϋy±₯8ς·}­₯ΏR¦“£κZ'Γ=~ΧV‰"cζΙhαΒ‘QΖGΎk«ψ}"F‰^©όͺ[M&ςoΟ§λ·ίlΈ]d™ »=++Αϊ'ˆt6‚ΖηR΄Ή c_(‰qΨgΪ°œΥHΚν^χυτ6„9FΙΪΦ‡2~YB²ψ‚σb™ΪώDߎ@ρϊΤΦQ¬/|₯%Σw8Ξδζ·Όαω΄užhε77Op» zGαω—Η’kΖhό—΄ϋ7•ƒ»9>˜βͺUbκMίFΏΘQ₯%N Ϊ¦y‚ξuνŸήιZU₯μοvRYgŸc¦3…ίη΅t~Ρυθόsu¬jZ}΅½Μ$H&Ζ0qVuκVZυΞ­α]F;9.ωΈ·7FηΧόϋΦΏ‡,ΌA ΤΣkϊ½Κ2…H ‹b‘υΟSWV²’r΅Vλς"•šŒ―£ς·ω˜_ ?ζdυ—ωΤ{ΥΎ5JιΨ>Η―υ©δπΆΉ₯λ…ί†u;h`Ύ6X.bάΟV₯ποƒ/΄ίn_jbςi`eœ•Α.Oπށ@b“”/)σn†£;F»2œΊVΏα-sSΤt+huM:ϊS<ΦΔν• $§ρ>ΏJΩΣόWύ©αϋ‹νL’{Ψ₯Λe#™[<δΰΤsιώ3Šξ±k|–μΡύ’ ΄jOŽΈχΝ_πo‡mtΧMw}y)žβb0 μ*'(8σNΝι΅υυ.’•£t΅ήΪz¬΅]gP³Τ£Υ΄?μΨ–ΩΚΏΪ›Ž:c«|’§½7ώjμ€A"20Κ° jΰ,<)β]Oi kV©¦Ι!‘βΟzγ·τ©Œ£8J:GTϊωϊ•(ΚRΦZ5ΣΛΠ<%Άoˆž2\ε[ΛCχ@5KOΔ·’ΨXG«θ(ΜααωfO\ŽηšΪπƒ§πυώ«pځΉkΤ_ή8ωχΔ“Q6“γw·’Ρυ½9βu(g6ΌΗαΖ ΥΞ.M&œtήύ’„”Si©k΅Ί³βV±­ΰ:ηI΄ΌΊD*~N~SιΘΕM¬[x³UπόΊSψsLŽέγΨ…nGξύΥΠ'‚¬α _Ι$ΌοβNνί™¬λmΖφ–ΛgΏbΠ Ϊ“ΙoΊP½½‰ϊζœjA+A­ή ₯NmήIκ–ΦύNΗΦ7vŸ τ SjŽξ(€· €sτΕzte΄Oφ|¬VώQ‹1ΑόλΕή»ΧΌ;§XΤ76σΗ4“ΘΏλ ©Π’k¨ΉG’ΪXβ“Λ‘ͺΈΪqΑ¬*Υζ„UϊΆmNŸ,Ϋ·D5Σψ>Ω5¬ΦκΪ LΜ²Ϋό²Ζ€’r;υλΧ‘jVšΆ“o{§œΫJΉAŒc±ν\€ΊG§΅’ΚmoN0Θ₯³βB§ƒΣŒγΪΊo hΠψCΆΣmέ€HAΛ·V$δšͺξ23kšύAJ.Ι>_3Ξ~#βOŒίcœ~εLΞΉώΰ΅±ρ†Ί΅πύΌ£1Λ©FŒ=A‘ρΣNΈ†ΧCρU‚3άh7bi{ΒΨή}πU ΧIiΛγ-7@ΏΣ.’ΡάE|¬rw ηλ,<Τ*)3LD\ιΈ’·Ε«XWαες¬H>YŒΏ:Ž?kBΚΒΪ/‡‘Ϋ,Iδ<\pIL“ωΥΏhxƒΓWšd€RO·ΰ0Α»}*άvžM<Ίο[aώΩ ·5J’φJ7Φχό‰tί΄r·K~g[±o Xημ?τ|EO3αf„™Ζαl3υJι!π•ΔΫΓ†ζ#9Œ§ƒ·–ΟN΄xR}[Βzn“ΜQΛjaέ#†ΨΈ8ˆΦ‚šwϋMόŒΈZίe#₯Σμmτλ8mlβX‘‰Bͺ¨μ+€ψG§Ϋ›j ΅ΙΤ$„9*£ž=>υzEsΎ πόήƒRŽy£”έ^=Κ”m =ψhT΅9¦υv:'NσƒKEsΔρ%ίΕO[]¨kXνžXΡΊ2{~¬|dΆ‚O\ά:―Ϊ-䍑|r p?kWΖ>ώέ—6—Mg©ΩΎϋ{…Η±Εc]xO\ΧηΆOκΆςιπ8ΫΪDSΝ#ϋΔΦτηΒnVεισύLjBVœoΝΧεϊ?‡ϋNΟΐΡ^εΔ¨%Ο|ͺf½Fc‚$ŠXγA…UW;β―Ι¬^θs[Λ)§\yΜ¬Μ8ΰcι[š₯υΎ™§\ί^Θ"Ά·ŒΙ#žΐ Ζ­E(E.—όΝ©Sqœ›ςό1πξώ7ό@ŠυmάγϋεŸΤšτίκZn%Ξ‹₯j^+([o7Κά δξΑι\ΐΫ;«Θυίj΄rλ·m,*έD Ώ‡aμ+Τλœάσ?ψLόyDπΰΙψŠοτK›«Ν&ΦγQ³ϋ܈[mϋόΆτ݁š»Ey/ΖΟωΎΨe?τ8©><΄κ^Σsύ™s©€ πΔmΪύτΥΤxχΒ%ΦΌ+{os)£ί-άŠΰ“ ‡ώZΏγ ZψΛ@:}̏© šήβ?½ ƒ£̏ƀ ψ™¦Ψέ|;Φνξa‹Θ†ΞGŒmFU%qιΘγή$žβσφ`Ρρ™€σcŒ3u*²:―ώ:vš‡‚πn‘αύ;ΔΠΗ¨Ζ—:₯ά—PMδξ ƒΤŒV5χ†~#κΊ\ϊN₯βM#μWbšxν•ΠŒ0τν@΅+/ΪόΠ|5ΦνΌbΪ+'ΩQ…ΪΌcΣ[β‚δρ%Ž…k§MœZeδWYN6'π¨8‹Ε:kλ>Τ΄Ψ€X亁αWnŠHΖMyœΊρΑŸ %ΪA©YEΥ³Κ»ΊŒήߝ^<ͺiΪΟ’όBΠ–ΒξβQ΅ύΉίo+žΣΘξzφ­eπΗ‰4ΟθZW‡u«{=CNEI$xwΕ8 ARΘζ²δπGŠ|IͺιSψΧY°’ΗNnRΦΖžc©ΘάΗ·κζ·Ύ<ΌΤsŠΖπLš£|wΥ[³³²Ύ—MF–+I7‘δ`“λŠ³πΗI΄Έψ±γΝJxRK˜.„q3 μ’GΉβΆόπφCρ΄ή#Τ΅“©]]ΫΉgM€ΙŸα€‘B€=Ώ Ψπw….4ψ›Sšζ)cΥΡ’ :δ>1’ήόBψ{¦ί ι“]Hοϋ²8)Œώ©—γ>ewπΟZ[ΈγΫdDΈΐŒcΣΣρ«<Œt˜`iήϊQ=₯άcζ‰Ητ=Η°τKSπ7ŒόOm™βΟYΆŒ¬ «eInώρ<σΕrž3ΉΈΊψEπζ{Φf™­w3H“τ½β<‹€Ό@ς*ΩJI€š©γΏYψŸΑΙ‘@a[bhю"dQLq\¦§ΰψJ}#Δ~)³ώΜ)΅ΎΙoΆIΘ齈ιœghžρόšν‡ύ{Γ‘ΧψwE°ΆπuŽ”–Ρ}‹μ‰G΄aΑAœϊ“\Ά§πώξοαΏ„φΊŠ$C9S°•lτλ^e ·²‚ ˜γT$wΐΕ|ύα{˘?eΝ^HΌΕ2F8!ZESϊ^ΏπϋK°·ψ€YA Mi%’\rδ“λœΦ_<4O‡Sψ[Yš+Θη2‰ @*ώ™ξ+KπOŽτm;ϋLρUšθ«”ŠY-·\E짦hΏμεVΆ>)‚άƒ Z«’cϋ `W₯ψ·ώE]gώΌζΠ s Ό/¬υ[WΌ[ΈξnΜΡ6ΰ˜ΐέολŠλu«FΤ4{λ4`qΔτ”Œώ΄០4Ÿˆz‡€τΤΡuύ+NG˜ Ξ£'=W½ zƒΰ»_x#\†+‰o/ΰ–k»Ήxi_aνΨp=Νm|<πόήπ†Ÿ£άΝςΫ) $`…9$ρšΩΥmšχKΌ΅F ΣΒρ=e#?­yŸμί€ΪZ|9·ΎŽϋUδ²4²cζ 1P3ιΕA‘A‘ϋCkςj*$šΖΑ>Θ―Θ@J‚ΐzσϊΧkπΣΓSxGΑΦZ5ΤράKrdŒ§sου¬―ψοRρ§‰|3© /_·O(»¦ψ§OξΈ=½(γδ[Λα-VέV=R-V(b‘F•³•Ο§›γ+5>KΈΦDŽIΆ0Θ,ΉΗδyό+NΓΐzζ―βk gΗZ½½χφyέkgiΘ•ΌsΤτό«sSπ€χŸτŸ%ΜKoem$ sξJβΏh=6ΦφχΑbx”™55Ž9(ΨΘϊq[_ν-αTj*!@ 14@ l!ΐγӊΨψ‡αάψzKk˜ eςέΈΌ p1ή|Hπδή,π}φm~!xΛA]6ηΒΪM±IH§ŽυKDTφηΈβ»ίxxfΗO–ινoμv=΅ά]c‘F3τ¬X΄/‰Οv³ψ«KHWc³f_Δc?…dόPKˆ΅…±ήσt—гsŸœ,{Ήϊ溏ŸςK5’θBόKπdώ,Στζ°ΎZΆ›8ΈΆ—rξΗ |ψU _Βή(ρ'€u=ΔZžœϊ…Λ―•42’(ΗήΞA ƒΑz5•€τ½:+xΎΞl£.Ρ‰ AΈŸ\’Oγ^7αϋ™μfΏ}‘˜4sΛΰς₯U?‘5οΪe«YιV–ŒΑšR"Γ‘!@Οι\‚|4_xwX–+Θn䙀1‚Χ=9ξ(ŒπΉρΊψΟL°π~‹.•-¨U-z˜¬ΏxSΦ³υλ>ύ5έ3_#ž9χD‰ p±΄‘2=χWM₯x;Ηή΅ώΜπο‰l%P‘Ύ·έ$+ι‘ΦΊαα›­Sΐ—Šu&Τ.n£užν#Tδ±*B—ŒqΪ€-ψE€π&ŠΩω³`9ΆK^kπ—G‹Δί ΅ύ-₯1Η{{r‚@3·$`β―Xψ#Η°hρψ|ψΝ4TΘσ£ΆHcA=8γ=G­lψ7ΐΪ—…Ό ‘ιΪ²C{$ςKov©»ΛΉrxζ€9‹x›αΖ•›γ=CΓφΚ°&₯aΞΔθ7‘λϊ~5μ6p_ΨΫέΩΈ’ΪxΦXœtea#^cͺψKΗώ"Σ$5οιI¦Ν…νmH–EΞqΟ§΅zN§A€iZm aoi Aγ“΅T“λΕy‹xύ‘όOO°M ΛSώΡΞ«πωœ½„λσfΆΎ"ψ&λΔWϊN±‘κCNΧ4Ά& ]7#)κ¬?ΟS\§‰ώx»Ζ6±ΒKβK3%»‡Ά·Ά€€ δe›Ή8ιιšίψ‰α=gQΥtOxZ{Q¬ijΚ°].c™Xr3Ψώ]zŠwƒό~ϊ‡ˆ“@ρ>&β#4aŽθηP2v7^ΔγΫ©­Oιž-–ξΦγšΝ₯€qΗ²[k¨7€‡ϋΩκγY:‚5›ZψŸΖZ­½εν”M₯½œF8£ά$η“Γ­u=sXΤaπ7†#ΏKY|‰υ ›Β8ΛcλψV/ΒWΎ…ΉγeΤν­­.Ϊ(^h-_tjΔ/ χ'9>δ֍—<]α­GS_λΦiWχ ra»·ήΡ;’?!νΐβ¬xcΑς|=Ύρ'‰υ NMM%²3ΞΜΏ½ysιƒŽjε~x‹ώ[ίxR―΅ΤΌyΎΡaœ%έΘ Gέ?_ZΩπ6•«ψ{αΏ‹΅ »f±ΉΏ’βφ \όΠ©^3θϊΥ‰ΰ?x»\†ΕρZ ·pχ_e‹ƒΔd– τ“ΐώΏ/ŽuΏxΆξΫWϋ=§ž.βˆ&A* 0PGτΟΜό%Έρ—€μW@πΎ‘ycqΎFΉ–π+ΞKœ—½Ώ μΎ ψk\πάZςλvΩCwvn-να˜H‘œ¨Η@8…RΣΌβο Ksoΰ―Z.4†D΄Ώ„Ώ’O]€ŸjξΌcXιςj±κW²H\•}§›₯ΉŠ[§š&ΗΜπ‘½ρΧxG΅ρ‰y₯κ ZΪκ3γ¨χγ­Sπf™c§ψKL΄±†%Άϋ2pa²2IυΙ5ΐψΚ΅Žή²ΤTIg¬³Γς­ τφΐ?…;KπΔM ΕtΕv ¦Eς@χ6‘₯‰=Η?Žk’ρ߁ίΔΆΪ]ΥΆ’φ^ Σ{{δQχΈΞαθHι@΄5•€ί ―ξζD[›'Š[iqσ#ωŠΌpHsβœΪϊΓHuίφ‹ΈόΰάξΚ)9ϊΦΝο€ΌSβ«›(Όq―ZM€ΪΚ%6Ά0όφ “ώ}«€ρΏ„eρ†¦΄žx΄›±pΘΚ~eW(œύ£lνΟΒιΟ’ƒΘš#6sŽ? θ5έ&ΚίαφŸΌbΦ=)€M£g?\σŸZ±ρCΒσψΓΒ=­ΔVςΚθΒI*0sΪ΅υm-ο|-w₯$вMhΦΑΘΰ›sτ ρ#³ώΛ6EŽH†άδQ^‹β "ΚΣΰξ‘aΌbή%Κ¨QŒ¬DƒυΘΝgκ//>Aΰτ½·[¨57NΓ΅ΓtλΪ»-gJ’ΒWΊBH©,φOj$#€JΟ€9}΅ΏΒ$€)›€’IŽίΎK°ηΧ€s? TGπΏΖF17w‰ŽŠ1½+ΐΎπn›£\MςΪΖΘ ![,OϊΦo€Ό'‡΄mgOΏΈŠα5 Ή§Μ`Œ$Ήο@|9ψWαόΟΠΪ°>H’ψχβ;FrΏΪEsξ ϊŠMΐΎ8πέ›θώρ=”z/˜Ζ=Άω V9!ONδύkoᇀ%πMΦ΄Ν¨Ψ―]Ασ2Μ[ά’M`ώΝϊ}Ό>ΤοR%ϋLχς«ΙŽp§g—ΒQ₯―νγ-ΤGιρJΚ£±ςŽργωΧ]πΗΒ—πόΪ}ΥΔWχ2N0@ŽqΝE₯xBβΟβ–³β—Ή‰­―­Ω`οR‘9'¦>CωΠ3π[ώG/‰φoύJ“φr‘*χώΒ31]€ό!qα½wΕwχ1LšΕρ»PcœΰηΏΝX>π?Š|)­\ΗανfΗώλ›Ώ΄=½Μ%€Œ– G|q@ϊ ιΰ_‹ϊξ—p|­#Z€κVδτYΰ~Ώ%«?m%Υnv±vΛožΠ‘ΐΗΆF?ΰKφ“±†ϋNπτVΞΙΛ{δZΟΜΘγ{γξ~ž΅κ~‘ΠΌ?§ιvγZ@±|Oβrh‡ό6Ύ.πŽ‘’΄ζάάͺμ—ΪΚΑ”‘άd מΩψΏΔ>³΅Σ|‘Η6‘ΘT±ω£`.τ?Ϗ₯zoЬ΅;ύh4-DiΊ‰*Ρ\Γ…Α‚Εyώ­ΰίψ¦Δi^(ΧτΕ]Τά +b²ΜΘ<@ιŠoΔ)RoŠ e‰ƒG!ΈenΔ„UΟΪ.EO…š€c‚ςΔ«ξwύ+OΗΎ}zΛF}όιڞŒα¬ηeάΓώ+•ρWßxΣL{ψ’ΘyXkx-`)|Œ³χΣτϋ{xƒZ’˜φ ŒηΧ5GHπ.•§ψώVVšΕβd•Ϋ†vnK{σ\―‚Ό{¦iAόUf4p¦(¦–ά›ˆ£?Β{t=»cŠη>ζ…ΏμabΦ†ϊ;cœΎSτό…vίτ›K†šTφπ’Νv†iŸ3Δr ΡΌk’ό9Τ<1₯ΚwέΪΟάΚ9y$B»ΫΉz Υπ‡/†Ό!¦hχ$ΪE±€@B·$ρŸ­pΪOόœ†Ή`˜φJυŠσŸx'Z“Ζ±x«Β:₯½ž Π {ˆ£ίŠ:tό?!Wυ Ε—σψ^huθνžΚU}IaRδdn{‚20}h·― ψ΅ͺίλ?΄mF₯ΦcΡΤ.­c w$mˆ8ΐΗoβ5ξG§kŒπƒηπώ§β WSΉŠοRΥ|Ζ’0@HΖv§?SŸΓ€<»Δ>#Χ,~!ψΕšΧ…§ΠmP‹ ©ZδL²FηŒαWrOzι>0ΨAͺ|Dψ}it«%Ό—L]O!€!°}Ž+Ώρ†γρo„οτycyΣχR0ΘG*kš„UΈ»π=Υώ£m,ϊ+;lΞΪχΐΟz>?ZΑ'Β­T΄I˜<§ˆχuzqΕs? MGΒ^·ΉγΉΤmcα“ωΧ€|Fπτή*πv‘£[Oά… $€•`yΗ²|a૝wLπ΅¬7pΔΪEδ23‚D‚1‚;š³ρNΒΤό.ρΏ‘† 4 B«• vΑΌΏΗW7 πΑρoo"ζβΪ’;Η‡8>ΩUό«ΪΌ_₯Ix[V‘‘b’ςΦHάd)e#'σ¬4π-½ίΓK λ V8#4C]NC{ƒ@:†‘¦Ια9τΗ‚/μί²”Ω΄m ―υ― ηžoΩ{XI‹4p\΄P’sϋ±2ζZ»‰<γιτoμ ΌUeύ‘°Bg[sφ–‹¦άτΞ8Ολ]zψJΐ ღžΠKŒo,NKžΫ·s@ό"ΐxElόΏΩ°Ϋ%―-ψjλ'Αo:«OxAυ­kxφ ?ŸΩ¦Š‘ωtvίι,ch'§g¨υ­x|>Υ|7φΘ₯k¦›Κ— 07{ŽτΏ4Ϋk…Ϊ3A+άΖΣLΨεΨ±λλΖα\ηΓrtΫ―ŠQΨ(E·ΎαG B± τoh’ψoΒ^q*M-€^[H€…c’xΟΦ³|α)΄oΕ—7O±xnQ’œπsυ {φv±΄‹αΥ½μJww,’\LFY›q&³ΏhƜi^±΄†9"ΉΤΡZ;R9Η°&¬Ω|?ρ_…/.ΣΐΪύ€EΜ†Qg{ρξŸJθ΅\x›ΐ‘θή*Τ~Σͺ+Eτ„Ω&βTͺŒpπ /ƚwΔx^mγΒZ4Έ_.HοT˜ŠAQψcρͺŸτ˟ψC~ιzΞ Θ½†ήγζέ“³žυΣA |OŠΩl‡Šτ³ ‚ι­7M·ρ'Θ­Ÿψ6σΔΆώDΎ‰eξ㹚ITζ]£θIζ€3>=Xڏ„ϊŒkj–ώYˆΖΜ0•ͺt›+„2ιρΫΖ-†ί&Ρ‚|¬ηλžsλZΌ;7Šό!}£ΫOάI*0Aντ­ ΄·“Β²iBE5‘΅ίŽ2Sn~”αWχ—0ώΛBaζΊΐδ|†s‘ŸC€?θ`ΗW^ EƒΑΪ!Σ%΄&/G*W†Η―zμ|=ΰ(mώ§„5Ήκ#Η$‘K– ΉξΤV™αOˆΊ’ιzG‰τΩtθ†Ψ$»Άέ,kΨ{ώ9 OΗZ>© ~ΞΊ^Ίͺ·ΦΧ*€…σX¨Θφ"½–]ΒΣΑ’ιΫD,c³h|­ΌŸ½sή7π^©β‡1h:¬RκA£yo%jΘT’NΥι]ΕΤ&k9‘ρ”φΘΕx―„ŸφcΤwvΨέ(φ5zΓ8λα^o&vK¦ΖŽΈ)Š―α//α«ψSSΉIΔ±K’Β|τΟΦ³όαox~Ω4‹vΒm^(`"tΘ!9ιςœζτ„ρoΒkl€αΧό-Ό’k_’β%'$²χϊ~΅κήΦ¬bH8‘Ξ y‡ΕΫοέiΪ,ώ Πτν6Τah^+―6UlτθzGďήxŽσGΥt=A4ύkJvh$‘7£ΖCΓυ5ΜψƒαϊόX–³x—ΔV=€Ι$φΠ„`ε‹w,G€#ψΟ¦ΫλΌcx‘ν¦Ήa"Œ ‚AϊγΩόT‘τί†zσικ!hνSΛΪ:qψRx³ΒWߌ<1¬CsQi2΄’Fΐ–ΪΊJΚ FΒβΚρ–σΖc‘Ou#€<[ΐ2ψΪΫΐZe–•αηK–Ψοxœ0Ιf§<Χ[π?ΓzΟ…Ό+q§kΡ$Oφ–’Q U q‘οYzW‚|qαh[Nπ·‰,_G L_Ϋ—xA9ΐ#·ιν^αK-ZΓHXΌA©.₯¨gyΦ1ΰτP δh DΨ|3Ώ†#‰οδŽΞ1κY²Gύς­Uotm?ΐŸοαŠΔ‚ΐωΞTn’G$Ÿ©ύ+kβOƒn|asαυK¨b±°ΌWΈ$ˌ=·uυ«?±: )ϊW/sΰψ›μ–ž8ρ$:E»‡{{(<ΆΈ#¦σώ~”Κψ–K•ψαM"bβηUšήΤβIoδη^υcnΆΆVφθX£TzŠβώ$ψ*ηΔV:7φΤ6ΊMΐšΫΜLΗ€1΄τΣxf-^&5ρΕ­Ζ£Ή‹½²Lg€φ  φ†Σ.Όm}–πι—iw420Q"1ΟSΟOzΐρ¦³sρ/JΡτΓڜn’Ή{«Έ|¨νΡzα»υν[?η}di ³ˆ}»X”H“»νHDgq'Χ‘β¨kšWΔo ψvγT6ΆΉŠΒ1 šΞ<:¨ϋ»ΆηυΝAρ΅΅ρ·4ϋ+XoΘi%Kk‡Ω.Π7oλPόAΡΎ!ψΟJ·³ΈπΞ•g$,Ρ\C|₯ЎßσŠκotOψZ>Π5Y%m3XT[»kˆΏε”ΰ'Κ‹}βd­ Ύ(γ·FdΠY6EzŒ}±@_lRψ•πβΣRE;1™!Šΰ‘τΘ­ΏΪΪψ[~Νξβhˆ‘ά•΅βŸάk>7πΞΉΜQΓ€³΄‘°;ŸpνVΎ%xjoψ>σG΅ž;yg*D’Taντ 7ψΫ-εΘπ œGv'ΉGϋ<Ο²9€v«Cšw4Ώˆ>0πγi7>-€tx§ŽυKBTƒςώwή6πEΏŠό1k¦ά\=½έ¦ΗΆΊ‹οE"Œd{V Δο--eρV–°ά­¦feόF3οŠζώ+iM}|)Σ5•ο#ΕpΉΞβ;ΉοΘ―`Υ―μ|;‘\_\…‚ΖΞ"μz(μι\ηŒ<u―x—Αϊœwq"θ“<³SΊ]Ϋ:c§ά?t^&Ρ ρ€έ1Xnβ1³(Ι_CψσΛx§Δz3άψΑΆ0h·Εϊθ)•ρlQΖζόΕΏfpΐ†πœ€9ƒLπ?Ž Ρcπμή)³CHό6 l\ω=6<8Ο_zΦΠ~O€ό/Υ<&·‘<—"uŠb>vξχ­q9“aΡλήΣωŠθ>2A&Š<5γ[4-.:-ΐ^―ΰ0ώŸjψ‡αύή©π–ΗΒ1ήΫ₯ΥΌp‘”μ;1ž:σ]GŒ­τω<«A­8M?μn³ΏχT/Qξ:|Pžk―ŽΎ0θξ&4kq©LΓ•wlΙψf½†Ό‡φkΠd°π|Ί½ΰcu©8*ΟΙςmAτλ^½@=πϋO·›γŽοe^h4Œ‘»€Ι•&§€Y\ώΡϊt“[ΖΕtΦΈΑ^ Œ¨cξ3ϊ μ|-α+ΖΎ&Φ幊HugFŽ5rmζ7….$ψoβs·ŠΕ­L8;Ι'9ΟLP+ρ†$Η‘Bάh4{ΐδ―Θpj][ώNGE°θΙk£ρΟ„ΉΤ0ώκφcq)ε‰`ψηρ―WvΔͺyΐΌΑ|β jϊ…Ο€΅‹KK ω ΨήΒ]#ry)ŽƒΫωΠ=τίΪ3S·Σ•c‚οJσξcAΏr᏿ψΥƒEœΎ9ρΦ«4)%άwώDNΓ&5;‰Η׏ʺοx"_κ޳¬κSΧυ ξvνUQΡPv?!ιSψ ΒwΤ|GsqsΛͺ^}₯ {Π ρΦKι|kΰ{+HoCΝ,Ιk;μŽYnΠΗσ¨<£όBρž‘ Χ…τ«V†eš+ˆ―TΌdvΧ’|Fπ\>1Σ­Ρn€±ΤlεΪ]Ηχ’qύ+Ÿ‡Cψ*Ηouβ­.(T€χΩƒ+ŽύF?A@šμ ¨|vπuŽ΄₯Ά˜f±Κ΄ΐ1'σQ|Š·ϋNY[Mπμ]K}¦ήζ1γ‘“‚?*ι~"ψOέιΊΆ‘~tέ{MbmξvξVSό,;ρ>΅Κx³αnj|i₯›xŽΗ0ΦπΫ@R2έΩϋž:P°Γώ₯?έε?δ`ψaq²Χ« ΪŠΎƒΗxΒ7&ΤΌ5sos ₯^‹©‚KŽ8οΕs_΄uΊέψKJ·“;&Υ!±θr+Ѝ€z?†€‡I·Ž!mlήLh  …γυ¬o‰>Έρn™§ΫZάEnΦΧ±]3H .r;ΧZιŠςΟΩΖΦΨ|ΈΤu=NψκZφ’ΐάέΪGaώ€9€Ϊ}ΏφουMΟφ›ΒG* “€}Ιύ)ήlΏα‘|KqφxόΘ­#‘>Qς» ~:ϋšλώxFγΒ²kνssΪ7ΝvžX#`=Ž{ԚW…'²ψ¬ψξbh/­γ…aξR½Ιι@Ÿ‹bHh/Ν„’kIΦFο―Φ½jΈέwΒ7—Δoψ’;˜’ίM†Hήs– §zμ¨’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(#BΠmτkFky$vΎ›Ξ7cνZτQNRrwbŒTUQE†QEQEQEQEU{;ΫkΡ!΄ž9„lQΚ6v°κ X¦Υ·ο°QE€(’Š(’Š(’Š(’Š(’Š(’Š(’ŠlΡG4OΘ²Fΰ«# †¨"’±³ΆΣνc΅±·†ΪΪ1„Š‹ί€8=QEQEQEQETΦvΧφ―m}o ΝΌƒΘ[κ§’€ QΑ q@‹Q¨TD ΨSθ’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ eΔ1άA$3’Ι ŠQΡ†C) J}ζρ|&°²σ"Ρ΅έK²v,mmoPgΣΊOx/GπŒwΩQHΧ$ξfrςΚ}Ψύk€’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ I|lΉ+FGQKEpΎψk¦izόzΥνφ₯«κP‚°Λ9—Κμηόσ]ΥPEPEP;γ_ ΩψΆΪΒ ιf‰lξ–ν xε”Οnk’’ŠΑρΏ†-|_αωt›ωeŠ \΄XݐsήΆαŒE qHE 3μ)τPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP5γ_ι^/†ΨjBhξ-_}½Ν»μ’#μ\λ|&Σο5Χu½{WΆF -ξο£$tΘ―G’€"΅·†Ϊ+{hΦ("PˆŠ0€T΄Q@Q@Q@Q@Q@q^.ψ{gβ½Sν§ͺ›"6ŸΑX―r΅ΪΡ@YΫCgi ΅¬kΌ(#Ž5  `RΡEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEqχ?4¨n.-£†ςβφš³Γwlc,νΝ_πΧ‹tύzζkXV{kΨF^ήα68Έkα”PxΒ\)ΉJΉ#€±γκGθ*_„‡βΟ†δ·O,,Δu(3Œώ΅Ϋ*Tω4΅΅οςΉΕ΅9UFτ½­σ±―ͺψλIΣ/ο,§σΪξΩ‘1¦ζ”°ΘΪ^΅vΫΔΦ‡Γςkρ\iφΘHeΉM―ΑΗO~ΥΜxn~.xžζD ,Δ#$}έΘ3ΚŸρηƒΓπΝrj(&ώ΄{*nq¦–ι6ώW΅¨‘*₯Χγb|GΣ€In,5;{ -Τ–δFsΠηΊw_³ΡτCͺΞZ[O”†‹ΑΊωΡβ›{i|/©EpˆmΕ³πG qω`W—ά<²|€ΚIΓνRΊ% QN•:Άi[TΎπZ”›ΎύΗaqρKˆ΄‹i¨I`§iΌH•ιΦ₯Όψ¦FΟφ{έF(ΐ2Kk tN3ΛtιWo¬α‡αδΦͺ‹δžWn8ϋ•_αlΓΰ=-QF]ΈκI9ΝKT”ω^ŽΫ:ΌΚ7Z«μmθzΝ–·₯G¨XKΊέ³’ά#¨>˜jˆΪjΌΝkg¨έΪBΕdΊ‚Ρ:œϊW'αη’ίαw‹ΕΆFΫ™”ΩHPLΦ§ƒ£ρbψNΒ=2ίD6/S{Ύβ]Ψ}kG‡„9›ΪφήΔ,DεΚ—kνs§ρŠ­νΌ$ΪΎœ&ΊIˆš-΄ΰςή€cœΥ/xͺ]ZΓN·Ί³ΤMΛB —R@Dn@δ†ιΝfiϊ ‡Ύλφš“@]όΩcX•U*8δωŸαχό‰'ύz§ς¨œiΖ›²Ύ»ό‹„ͺJ’»Ά›ΌQi’±lΦχwwrjΈ‚Ϊ"ν·=O₯wήρM‡ˆβ+a47VλmηMŽΎψkα΄j|Cry―"Η8ρϊΤ–¨±όj»(/¦e±ίζOπ«­NsVΥ+ίξ3£)ΒwΡ»οŒμ4½HιρAu|«Ήα΄ŒΉAοιW<3β[Ε1³2G< ΆX&]‡άWœψψ…υ_άhρi―3ޝƒŽΈ§ZιΌ7 kΠψΦγ[ΥΕ„i=Ώ•"Z»Μ1‚A‚•JΰšΎ©wλθU:Υ&ΣΆφύN›@ΧmuΏΆύ‘dd­ίxΗΜ:γڐλΦ£ΔΓCΫ'ΪΜ~qςνϊΧ1π£―‰GqͺK‘ψΤBE…T䦝΅½_κ*©Ξ=•ΛU₯Ιwv5υ/Y[jW6vwڌφη}’"β3θO­kψ{Z‡\΄yΰ‚ζ ±’β2ŒΠΧ)q λώΥυ GΓ Λ[Ω σYLvΆγ’v·γZ:_Šo5έζ}OUΆ”C-₯ΛμΨΩηš'J.)Σς֚T’•§η₯Ώ&uΥΖάψώΞ'˜Γ¦j·BΕdš;c°c―5gOΦ5Λk{ΫΏiΦΆvvπ™CA6ςHν₯gιšΧŠuϋ5½Στύ:ΣO”Ί‘‹²ϊL)ZξI5κ9Υ½”]Ÿ‘ΡZψ†ΒοΓ’kV²4–QΔσ6Μ‚HΗ― Mš%“O²Τo—hi Ό„~ΔϊΧ9ΰOΒ/Ž0οιώ«΅uΏ νγƒΐšYB™ΘΨξKkI§K™΅{; ΅*ς€νus[AρŽΉ€Ά‘`μΠ¦C« 22A΅ΟΕρLΉO³Τ/e —Šή͏›3Š‘πόξόm ±­ΫmQΠpίαSό·Ž/Q@’k‰ ·sƒό¨•*pζm^Φ·Νjԟ*NΧ½ώLι<1βKΫΛ%‰‘^Ω,RΧCξ+;WρƟc©Ι§Ϋ[ήj7‘¬Ž"ϋ>¦³<0ΎWΔˆ†7G `zΰΡπu#:6©9έΙ \Œ`~Ώ­)R„y₯k₯m=G³•£}uΧΠθΌ3β}?Δ"e³2GqΔ°L»]>’§5Ϋ]VQ΄·Y–2ωR–ϋW%p‰Ζ›o²­>žZΰ(Ζ⠟|ω ›α*ρˆ=~ۜ~t§F*.K²ˆαVNJ/»_έkφΆή$³ΡdY>ΧuJ„—=OόΦn­γ+LΥτΩΦα― ˆγŒ±°―±u·VψΟαυ•³“?””Νή9~5λΊ‚πΪFΘObR1ό8Ρ‚W—ςίρ±2­6νζ·αswDρ­Ž₯ͺ›5΅ε…λ‚ΡΗuBγΪ―xŸΔϊw‡#ˆί»΄ΣE KΉίθ+ρϊ…ρƒ€PŸlΩ»Ύ8ͺϋηγc ΐ[ιϋνΓ €Ωΐ΅ ”%iΫK7oAΊ³γ}n•ύN‡ΓΎ,‹ZΎ6ƒMΤlδΨd怏―γUuiφΧσΪYΪίj2[œLm!.±ŸBk₯ΤέγΣnήυ« •Η+Κ~/†·θι-“;;Nμ$-œΰ}(§NœΣ¬•΄ΈTœΰΤ/vﭏLπφΉe―ιλy§HZ<νea†CθGjΣ/ΐ^Υ΄WY»Υ~Ζ‹|λ*ΗlΔͺ·; zŠν+ž΄c΅toJR”’³ (’³4 (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€ (’€<‹Γζ‘β^ι:€šuμ7¦=Ϋ7€ˆyΓ/ΤuΓΓ~’ΓZ›YΦ5Τ΅IbΘSbΖΎŠ2kgFΠν4‰οζ΄σ7ήΛηK½³σ{zV₯uVΔΚM¨μsRΓΖ)9n`i^6)Φ5΄‰ ±+f6mλžsτoĚ%―ˆ4™l/AςΨ†V_ΌŒ:0χ­J+RNJWΥ~†ΚœT\m£ύNoλWΆ‹§κ>&’m,`4inGQΨΆkgΔ^‡Sπ˜Π¬εp(EFΩΏhSž™όλ£’­Χ›iίmHT “Vά£waηθ’iώfέπ|ΝΉΗˌβ‘πΖ”tM ΟN3yζέ6y›vξό2qZ”V|ξά½ 9ωΊœί…Ό-‹¦j67­δW³Ι+ƒΡ΅€zœύkΧΑšΞίΓώ#kkΔ¬ΐ$1ηΠζ»Κ+EˆΫΎζn„,•Ά1¬tiF.›ͺίK¨<ΚΛ$Μ‘I ΨΨ¬― ψkWΠeŠέ΅Αs€ΒŽέ Γz Ων]u>ΦVkΉ^Κ7O±αE~†ηνjΉ{ŒμΫ·qιΤηλD~)γY5΄δ=―ΩΌ9vμϋtΕoΡC«&ά―Έ*QI+lqš§ƒ.·>­αέUτΛ«υθcί‡Χ5©αΝ'V±Ήš}cZm@Ί…XΔB4OqΙζ·θ¦λNQε’όΔ¨Ζ/™_#‰Ήπv£k«ήήψw[:zήΆω‘x|Εέέ‡#Ÿα6“βa­KͺKwpπ”›Ν—r~π9ΰcνΦ»:*Ύ±RΦΏ—A}^½Ž>γ@ρ*ήNΦ>'Ωm+³*MjΖ ΞΟjΣπ—‡cπυ­Βύ’K««™ ΧΘ0]Ο|v­Ϊ*eZR/ODTiF/›υ+κ6qj—˜gCcЊ⬼­[Y0xšA€΄F°&ΟξξΟZοh₯ ²‚² ŒέΩΚhžM'ΒΊ¦‰ήθο<ΰ’ωŒ:νŒσΓ5―α(θz –šfσΝΊlσ6νέΙ=2qΦ΅(’Ug;σ=υŒ-ΚΆΠη4 &γ]”έ ΄ζ2γΛΫεδ:σΧΪ§πf‚|7‘¦œn>VG3fΟΌsŒdΦεJ¬€šoΠ#J1i₯·κ`ι~6>'Υ΅΄οΚ‹εlΖΝΎωης¬«―]ΪκΧWώΥΫMk£ΊxZ!$lή d`ΧgE5ZiήώBt`Υ­ζs>π’θχΧZνδš†«sΔ—.άE…SΤό!|ΊυΦ­αύ`ισέ€'βσΘγ=F vTQνηΜεpφ0εε±Δi>–ΣΕzνή―-εδjβc$xσ2₯F9ω@ΟNkZΓΓ†Χƚ–½φ Βς‹Θςρ³hQΩηξϊw†Š%^rέτ·Θ#BΩuΏΜΑρ‡Ξ―ͺθΧ’ηΙώΟΞΩ³w™ΣŒδcυͺΎ-π’kw–Ί…δš~«mΔW1άzήΊŠ)F΄γk=‡*P•ξ·9Ώθϊε₯ρŸYΧ~ίΒ‹ ΐsκy沏‚o΄Λλ™Ό-­6Γ—{i"σ1ξΌρ]ΝJΌΣmuςVϋ„θA€Ÿζοχ˜Z&“©ZXέΗ¨λ^άϝ²ωa\cεόjΏΓνPπί‡ώΓ«jςκΧ>k?Ϊ$ ‹Ι'Χ]-œ€δξΝ#dQEHŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Ό«γߍ΅ιΪTڏq+$žl{ψ5κ΅ΰŸ΅—ότϊξϊ f7ΔŠϊV™o¬κ:,3ι2D³ω‹eςΨ (Δ¨ΑkΦώψςΟǚ$—VΡύžςέ‚\Ϋ“„Ž=ΑΑΗΠΥ,oπγDY˜N“pέ ω+œΧ„ώΛΕ—ΗΪϊZ“φhΗΫ"UΩϊ Dψ^§­ι–sΟ9ξ‘ς'5σμζ ψ›β0§Γ.§οEpb ψΖϊ/‰z5ύθ•Ϋ|±ΜQχ̊xŸ¨ ³,o­5 qqauΜ€ΘOβ8¬«ΟxjΚθΫ^xƒI‚ΰ仍XpOδwχΪ…ώκΧξζxηT2Θ{;AΰBδ ΚψEπ‡BρG‘Φ5Ή.žξρδΨb“hŒ+όNA<ϊΠΡ unφ’ε'‰­Κξ‡υΟLVU§‹Ό9yx--5ν*{’p"Žξ6b}šπΪ&Sαo ψošCɝεΆό`|Ψλ’I>υGβ/ΒM+Γ? bΧl..?΄ν–ΛεdήΚ§Ά =…}#}i§Z΅Ξ‘u­Ίΰ4³HFx'ŠKMBΚςΔ^Ϊ]ΫΟfA"x€ rwŽ0*ωϋ\Φξ΅οΩƒνWξ\$ΡΐΞΗ%‚L'ίΓα ύŸcf8Φτ“–€=/LΦtΝUdm3Q³ΌXώω·d υΑ8¨SΔz$–3^¦±§5œ-ΆIΦε !τ-œ^ϋ+Θ/ΔίπύΧπcΑǚ•υνύΕΎ‘fςΗεδlͺγ<sνο@Z wI:RκΪv_Ω­ΚέΤDyΗήΞ:ƒPi~(Π5iό/[Σo&žp]#·δkΑώ>x2ϋHπΗ†ν48ξt=5$IοbA ΐzδŒφόiŸGÝcΔΪLφΆ—šVΏlΫ㢚c$38cԎ psλ@CjΊΎ€@&Υoν,’'ξ&XΑόIΝ#Zυ˜ΪM#R³ΎEα΄Λ \+ε/λvΊΟΖ;ΦρLwχšEœΟ΅³}ͺ0Œά“Kα›ϋ]7βΞ—{ΰ»ZΗJšXβ’΄ηζ8aΑ9^‡“@^WΝΏ|qί|J_hzόzU‚”ˆΞ³ˆΡXŒ³;Ž˜τΝ}!* #tlν`TγΠΧΙ‡‚΄h~:Ϋψ]"—ϋ&IUY §v {ΝΧ­} πΚΪχHπ£Ι―x’kt­"ήωαγXψ?Cί½mιώ,πφ£wφ]?]ξnη”7Hμ~€k珑xoΑ#Λm€ω~s)rΫΩ€*7ΰ`œ{Σ~.|-|ΰΛ-gFžι/a’4•šLο'ψ‡χN}(ιKR±ΰκwΆΦp–Ϊ$Έ•cR}2OZ­uβ-{h.uk¦ΉΑ‚7Έ@ƒΠ¨Ο9φ―Ÿώ$λW> ύžό7¨_±{§ΊT‘ΟW($]ίS€k[αΒ»MSKΡόW­j“_1I‘XlUC… “ΣΪ€=Ί=oJ“Rm>=NɯԐm–u2‚:ΉΝŽ·₯i³Η£©ΩZM')σͺ3vΰΝ|σαΟω:ϊωŸA₯ύ₯ˆ?|83Θ‰xΆ”τEφ―¦ιχΑ}¨Z[O7G4ʍ'8ωA<ώMΌSαυΤMƒkš`½i€έ&όϊmΞsν^ϋUο:‡DlUΜ/΄ƒ‚ρX~ιΎπ>«ΨΝpΪ„³"\ΌεΆ@μA­}'©ψ—BVίSΦtΫ9Ϋ€sά€ljό—vΡY΅ά·₯ͺσ38ΧwL{ΧΜW,ΰ£xΎφζκ}vH–ι₯y YΒ…ΑdŽ}kΈψ+§/‹ώ έhšœσ i&’θί2(*Γτ4μ:f₯cͺΪ‹2ςήςܜ `H€ύGΖόXρ>₯α8΄=BΝ’{ί$ΫΣ8»ƒΫ½iό9π]Ÿt7Σl.'ΈY&3<“c%ˆ€: UΎ0θΫu«e]G >©σ hΧΔί·…Ό©κΠϋLq„· 2 ŒB―ρœώŸπwΕw~,π™ΉΥB§o;Ϋά*ά0ιΗn yΥώ|{€ό2Πχy†ρΦβόz¬kηλ΅Ώ1[zn ž ψ§γ 9—geύ«xΠ|ΐ}y?πθ|βOΔ?§s4šVƒu˜kHι0Ι?ΓΐχηΓ?Ό?β}E¬4™^ηΛi1%¬‘£ε€θαˆ€›DΧn|Aͺ‚±j³Ε—sPIθ+Ρν.­ο!ZOρ†SψŠπƒ~Ξwbp?Zυψ‚ΑΌ93U΄{θ,guX.Ȍ#bΘ"¨|Τ.υO†z%ζ£q-Νά©!yemΜΨ•ΐΙϊ\η~xfΛΐ:‹i– k}efςΗu!*„œœσ?ZΪψ $—ΓξK£ž€;Φ!T– Ι'΅s)ρ ‹xg\ώΛΥm^ϊ I]D ΌpA[γευΠΡtmΚv€λιm,Šp|Ύ€ξqUόuπ»ΓV^ΤI°KKλ;V’;¨ΙJ―;ŽyΘΞ~΄{Β—ΪΦ§πBΖςΫWŠίY–ά‘}zΩP|2ΔϋqωWy¦Μφϊ€Ί₯άJ°!šεHXέΆŒ°=0zΧ‹Ο& ?λΥτ€UΏθϊž§πΫΐ³ΩYM©iΦQ[Ν§ΔΨ3Ηε¦>ΈΑΎ³Ϊ€=rΗ\u LvΜƒψaώ@Υ›ΫΫ[LΧ·0ΫΔ:ΌΞ3^[ΰ6ψm­kV³hΊt:vΉhw-΄Ρ˜fCLα±νšΜ‹JƒβΖ/Cβ Σι:€6φeˆBδ ±ωΟι@Ώe«iΧπΌΦ7φ—1 ΛΌ3+ͺrfήxaYmεIbnUΡƒ)ϊ\n‘α Γ~ρ$ڝ “άXΚ$ςσ‚6?Eπ;ώIn…\ώ„h΅‚ξήβYc‚x₯’ΆEG‘τ tͺwZφgsφ{½VΒ ηœ—­ωšσ…‰,ή3ψ©΄ž\Ο}Ά7ώλ(π5ΗψB ψ~ 4_‰ώ’ΫWyŸv£t†H§Ιΰωƒ§ςοšϊ0άB-όσ4b nσ ΈυΟJ§eιΣl΅K ‰GπEpŽί5ζΏΌ6χτ{oZ›έΞα&–ΚήOψψƒΰό‘ΗψT^†šή―gύŸ₯E₯λΦ¬-n#0Κ¬?5wŠ5oψO_:­™ΡΎΘ1aǜ$ΟίυΕmj•Ž›“PΌΆ΅ŒπyUόI―6‡ώN2γώΐ«‘šΖπ^‰eρΖή,ΥόOΫ’ΣοZΒΪRLqͺžΈυ8μΆW–·Π‰¬aΈ„τx\:ώb›.‘gL²έΫ£@”4€Αθ[ž?ρι΄Θ~όeΠ`πώλ}'^γžΝOξΓ―ρΫͺώ΅Oώ›?ώО)·ΥCMa½ΌΟmΈ„•Ό˜Βξ¨ jΣυ]?R tλλ[°½|‰•ρωΉ^+β]NπgΕ_]xnέlP™νnaˆ’)r?ΠW΅AθhΘ~ kχZ§Δ;ΒΆ^!ώΖΣE‘ΊΊΊ‚UW-–7œωΧ‘xnΡ4’^kSj1 Θ/o%•<›¦1ήΌžσΑޏp鍀ڛ 4Ÿ΄<~V»όί^]ρ^™oβ?Šϊ/ƒ' ‡tέ8]›HΨͺΙƒ΅Tϋ υ­?WΣu"ΓNΤ-.ΚύαΚψϊΰΥ‰n`†X’–hIsε£0ρΧ½x·ΕΟ iž lΌUα8KΏΣξcWη ,lΐΓΏ8ύi~4ΫΛψ“α½ΌΙjΧΟ:΄‘œ2«,%€?LŠυθu.y'ŽJΚGKL©:“K π>΅r ’Έ…e·‘%‰†UΡƒ)ϊ^{β/hψ{β‡Ρ4θ­₯}*xήQ’Ξg©=jΑ_ω%Ύ―s‘΅v][ά4«ρJΡ²pJCŽ•V}oJ··[‰υ+( bUdyΤ)#¨œfΌίΰιΞ·ρτ?ϊ W/π'ΐϊ?ˆt-GRρ¨ΏΩ}-½ΌS1)Œ1*;XώTξj6QΪ ©/-ΦΤΛc*„Ύ³Š[ ϋ=B6Βκ ¨³πΘ~bΌ+αοτΛίψ«GΤVK½HΈΝ₯ŒLHΟΞqίŠΪπΞ—mα_WZ^ІΫL½Μοl€μ`ψΜΠ²U νgLΣά%ώ£glη’Ν:‘?™«υγZΝίΓ |A©I&›&·©Ν!7 mo%ΐVθ@#ε:@Όo-…‘ΊϋD_f ΈΛΌmΗzW1ΰiΎ(°’ΰMmm'Ϊ€·Žw8S€ΐuζΌΰΝ΅Ž«αθ³ΫΛ.‰λy·jADΖΰ€vΑΤΏ<% έψ`jw:]΄š„:„Β9Ω~e ί.>”ν5ZξώΞΛoΫ.ννχtσd ŸΜ՚ςθΦ^,—UΧuΨVφIn^8RL•@mNš’r“ΡT¨βΤb΅fΚκw2|VŠΞ+·{ΣόΑΎPΆzΦζœ5ψI΅/΄jΣXm_&Ω1ζDp2[υόλ†Πtx4OŒ/kgΉmM“INΐq=³šΤπΘ'β§‹@8&(°}>EА½ίε]<ΞzswχΏ™υς;KSO΅”Eu}k ‡ψ$™TώDΥ¨δI9ζ ¬ΣHIfoZ₯0ΗΖ{`: ,θF£ΩΒM¨7’fžqIΙ-Z;™ξ!· g–8ƒ »Ιτ€ΉΈ‚Φ#%ΜΡΓκ0Qωšα>2Θ/D°œ_ϊ T¬g„ƒJΤο4ω΅M ή6Y­’δ£δόϋ{ρΚ: J-½οψ uά\’[[ρ;λ=BΞχ?c»·ΈΗ_*@ΘΣn΅; IwwΦ°9θ²JͺOΰMrώ ½ΌkοC WŠ…”uTΧe—‘꺌;d–[‹†xυC$n€ρΘϋΏη₯TpιΙ­tιmI•v’žšυθ{RΗ4aβut=NAόi&š(4$jH» τ¬ο [ivΊDI‘y`b] mrryWγYeπhhΙ.c*AΖkSS¨‘ݚΣ…7>ΘμίR±KŸ³½ν²Ο<ΜͺςΞjΜ²Η m$©Œ–c€?βζψs‘Ύ„φνo›ΣMγ121χ‰ϊΦ¦₯>§πFϊK·/4Q4%‰Ι!Xc&΅Ta;8>©}ζn΄£u5ΡΏΈτΉu(eŽ)o-I1±U³Σ<Σξο-lΣ}εΜ0'χ₯p£υ3ΐήΣWHΣυ+ψ~Χ©Θ‹1žRISŽτŠΚπΦ›oγψƒPΧc1Yܝˆ ‘œzρϊš=Œ.υ;ΐm;-5{Α=*Ϊζ ¨Δ–³E4gψ£pΓσΩ/-£2‰.!S@Ξΐ}}+Ξ₯²Β?4ˆτ€a°ΥU£šΨ”0άγυͺΗD·Χ~/k_«IgΊJρnΒΘΐ(Pή½I¦°ρήϊZ„λΛkk{~=6Ϊϊκ#%­ΤF½Z9ψŠmΆ‘eu+Gkwo4‹χ–9ˆϊ€kΛυ ΨΫ|A΄ν<=¦Ÿ¨BΖκXͺΘηgΗŸαΝOڎ‰nΆS}Ή!+ :’2κ?kRz­4όΕνζ“mlυΧς=>Y(ΛΚꈼ–c€?‚ΟP³½,,ξνξ υς€ Θך|NΤ’—ΖN“© —3q<6κY₯npGσ5“©^iVϊΖ‘{α 3P³ΊIΥ'_³2$‘4C Νήοξρ\²k’ϋΟJΤξήκ?οΑ"ΈόΑ―ΣtΛˆ_|M ›­7C+mkfδμ‘b;ςώ#›β­&Χαηď _ψj?²ZκχBΒξ2|· TnΗ¨έŸΒ€=‹QΥ,4Τ ¨ίZΪ)θg•PΜCͺισΪ=Τ7Φ²[ ΛJ’©@=Θ8―ρ΅œ7ΔλύgΖΊ Ξ±αλ˜Q-cS*ΪΤ>ΩΟΒΪ€΅_j’ψfΦΚ{ ΠΏh3Œ¨%ASΚγ&€4ΌγΝ;Śk\‰mν€7RA 0ήΰ+c―>•Σκ•Ž›}BςΪΥ§•PΜ׎~ΟΠξό%―s¦[Ι©A}'—pΛσ6γι\Τη‡υx–ΖΊ~£ͺ k¦³³‚+fš(‘ ρМPΡ–—Vχ,Φ“Ε<-ΡβpΚPκŸ¦νώΠΎ΅΅έχ|ω•3τΙ―ψS}§Ε BΟΓvz•―…―-ΜήEΤ Ε2’Ήιίσφ§ό*πφŸροΔ>(ρT ¨ΜχΟkSRPΟ£ψPT5«©Ύ8ΫXA~ςiRi-0…$ΜlΫ†ŒϋΧ€Χ‡ψcΓ–Ύύ‘ΟM –/₯ΌΡDX‘HΚz σψΧΈP—|/ρ ςλ~:ώΫΤΙ΅³ΤΜP›™p±.[žΰW€ΩίΪ^ΑηΩέAqότŠ@λωŠπ‡ΣXŽδΗγ[)₯ZψγN‹c‘)·΅ΫyR{@IYΐ~υ b΅Ί‚ξ-€ρO8†˜¦›»av-MΔ?j+ΈCΌoΗήΈ―+ψVγΒΎ5ρGƒηm–ΘΪ69ιε7ήι•ύiΏ aoxγΕ^5Έ…ζϋŽ{"cq†Ρ}P¦x’ξ[jw–δ ­ν₯• •IΚΈŸάxίZΠνu;mGK :–Xδ€Ž„ŽHϊW_γ?ωυΟϊρŸ@5›π·ώDώΉ·ώ†ΥΥ‘EΚΙ»υτ9¦œͺ¨έΪί©WΓ^,Ό}u΄Ω₯ž¨|OΜsjΪa¨ΒXΈΏΆώΝϋ?6œy»ς~o₯rŸΆ―ΌΠΗѝΑ#ά§_Μώ΅eδ³―ύ‚Ηώ„Υnš’ηŠ΅Σv„)΄ω$οf—ήvWš•‘ςςΪܞ‚YU3ωšš ⸌Io,rΖz20aωŠςkΨl΄oλψΣJšξΦξbφΧΫ ‰}”ΣΒΊ[ˍ+Bπ©αO%ae.Θp3ψqΕD°ι%k»Ϋ^…Ζ»mίK_Τλ.5]>Ϊo*βώΦ)Έσ*·δMZ2Ζ"σ ¨άOυΝp^π&‹7‡­n5KE½½ΊŒM4’X³sΕWρ₯ͺίx“Γ^Fh4–BςΖ‡• τβ—±ƒŸ,^ΧΎƒΪΝGšK{[ζw–Ίδ…-/m§qΥc•Xΐžiβ„ šXγ.v¨fqτ΅η~?𖙀ψrM[Cl/τς²Η$$Γ Mρ•Ϋ_ΫxιΖkΈέΎ₯iΖ„gg£ΏΰΌ‘u%ͺ·βμzD²$1΄’Ί’(Ιf8ρ¦=ΥΊB³<ρ,M\9ιƒX?δFΦλώbΈΏξ?4M‡ ώƒθqSJ‡΄IίwaΥ­μΫVΩ\τσ¨Y‹±jnνΕΙι˜7ŸΓ9¦\κš}¬’+«λXd?Α$Κ§ς&°ό;ΰύ3M† ±—UΫ½δ%œ»Oλ\’ά]ΩψοG]Λ;0Τ%S$rxω‡J¨Q„ΫεmΫοdΞ΄αnd•ώγΩc‘%@ρΊΊC)Θ5UuKΉϋ:ίZ›ŒγΚοΛ9ΗW–ήψp‰α§Xνn$G$-œ+e˜ƒψψΧ1|ž„u­¬΄Qu$1έ}•Γωƒœ“υͺ§…η\ΪΪφΫσLO+εφΎ‘ν”Vξ―Ό'¦Ο¨M$ή0IŒ‘ψVνrΞ<²q}˜Λš*K¨QE%Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@xοναgΔΪf…§ΛzπΜν Œ”χ"½ŠŠω¨ΨόaΦ4 1§ιΡΐ–€‘–T.²O sŒf½[ΰΓΨό’Μ’Κ·ΩVΈ•GΚΞΤ_a“υ&»ϊ(Α> x?Δ:ŽυλνSLšΦήxdXerΈf2:Ξρ‘ρ;WΡn΄=sΑΆz‹H†5»0 ˞7Œ6ΠΓ¨ {WΡ”P…ψ3α>€Ώ u½Wt‚Q‘n"LδBΙ‚ΉΗ©ϋζό) gΑ:lš—‘₯Ε°‘š'’1 Œž₯`1žy­}1ExοΔ‡ϊߍ~θw"ΩDUb‘ˆωΧ#€sψW ͺiόS ZxWQDV0”V€S _»½·Αΰvτνζ:Γg[Β6S+]ͺ žεΌύ’½ΖŠσ―Š―τFΖoipκz{DΛs‘†ω³ΑΰƒΣίΥεώπGŠΌMρ?Oρ§ Ϋψ~ΦΪβ+‰%Ψcnΰd’ΝŒΕ}+E|ύγίψŸAψˆή/π]Ί_ \Κφδ†# ₯ISΟzθΌ#­όFΦ|M`Ί·†μ΄!uΓ¬Xfι–cίΠ­zύW„κ^Χ₯ύ‘muΨτΙ›HY‘ΞFΠxυΟZχj(Κ><|<Όρ…₯Ž£’0ώΥ°ά’2Ϋ|Τ<π{0#©―;Χ4ϊž;±±Πu*;[Kv]σ²„@ΐg;Ž+ιΊ(ΕΎ)xώ?„š/†ό9k.‘5”θ[fo•Λ7'»7λ^π»O»Ύθ–:Œ-άm’6ΖTδρΕu4PΞή?π_‹τŠ2x³ΒVBύ%“ΟP퀌2ΊδuθkΕ^ψβwOΧυ½(4Ο"'Ωΰ xΤƒΠ“Ι=I―©θ ύ‘<%ψ]ΠgΡ4Ω―"•£#εωξkoγΗ‡uoxN±Ρ¬€»»Žζ7xЌ€<ŸR+Υ¨ -Τ|=ͺΛϋ?&…”‡VEφlΫƒ)#;Λψm£x―Βί5k{M= ρ–I-‘”+ΌœŒγ=Ε{5Δό#ΉρUΧ…ΪOΖSQσΨGΉǁ‚ΑxΞsψWi",‘²H‘‘V‘Ex‡Α‡ϊ―‡|o«άκΠJΆ6bKm9ά‚Ιά> ΞώΠ> Υό@4{[Ι5μfKIΔdδΘΌ“žΓζπ*φ*(žO [ΙΰUπδŸ$ΘZ’?‡εΖ>kΟ<'©xΣΐΊL~Ώπ½Ζ³‘)kyg*α£Ι 0>ŸΚ½’Šβ/εΧ¬~­^§Ex—…­όIπχXΧν£π₯Ζ³υΫάA}o*‚ΐ’@rzuόσZί ΄_ΩψλΕ:׈l£ŠMBή7ˆFϋ£ “ˆσκ2kΥθ *ΤόUβMGNΉΣu‡WSΟ"²`ʏ=3“Ξ*§ΒύBηΰ²xjϊxβΥVV»„ΚDϋ‰ ŸLψšφ:(Λ4xήΚ;=Kΐχ—Z”j§†tJG³Ϋ5£ρÚ―Œ< bΡEžΏi4wΡCΏ*²(9Mέψ'ρΕzδ:ΞΉγψjλD‹Β3X^ά@ΠΟu<Λε(# ·’yλ]gΑν.χEψq£iϊ₯»Ϋ^B’ "|es#‘Σ؊쨠βχ…oΞ©φ\ΩσΓc:s]Ϊ—ˆ<1α? Ε§ψvMTΗgW‘G(I!eΐ<wτςŠρ«;[ρ§ŽΌ=ͺ Ύ›)š{Λ‡Q,ϐκ>Ύ΅k^ΡόEαˆ·ή(πΞ™ύ―§κ‘ͺήY£„‘7.~™όMzέΖθZ¦―βΛZΣXπμϊ5¬’iε 7 ~uΕx7Pρ§ƒ4ό8ώ›QšΩ™-ξαD.€δΟ#­{=δ_™`)ϊΧ‰|G­θΧZ]χΓ›©ne£Δ²£@ έ»;ϊΧ­Q@e Αβ_ό>Πμ­΄ƒ­άΖX]EΑZ%<€πq±5‹sΗ~'πυΚxV] tϋ₯ΈšώεΠHΚ:ΖςAχ―h’€<φ-Q&ΦM«f6”° Ž6—άNίZΖώΞρ€|e­j.‘&΅‘jς}’H`uY`—Ήη¨<‘Ο­Ρ@S θΎ ρWΔ[_x–Γϋ&ΓNˆΗcdξBΗ«6>Ήόυ­hz•·Ζ―jσΪHšmέ¬ η]•#ό*τZ(Ξώ#hš–§γoήXΪ<ΦΦ7¦K™~^Oε^‰Eηsθš‹|s·Φ–ΡΞ–ΊOn8Ϊ$άηo―qPόBπώ΅mβύ/Ζ>·KΫΛXΝ½Υ“0Sπ&‹¨ι›˜*-+)~Gα½?ZπΏ€ξ~ΟiΪ™‘¦ŽΠUςυη©|S’κσαΝ£ίB-ξε’,c’1κ+k›ρφ…qβ lν4L’fLγΥR¬U9w½Θ©FԜcΪΦ9ϋkΕγHm0x~FԌ~H½YΔxΗ™ύqλSΏ…tί…—:-²}’υα$ͺ’ 5ގ’§λ [•%­ΛφΏ3oKή‚KmO‚t),p"²žΔ•Η _Β^&Το΄­=υ-/R:H£`$ŠN€σΤdŸΞ½ ŠˆΥqoK§ΉR€€–Άhΰ΄­3VΧόco―kVgO΅±BΆΆΜΑ˜Œnl}OιVτm.φ‰zή£-»­”φΘ‘Κq†#nGθk²’©Χnϊik PJΪλ{œ†·¦^Oρ BΏ†kH!‘e”c OJoč.χSEο1‚ώ9dۏ•GS]£Y§ΨΤ—s‰ρΆ‡©niΎ#Π&Ύ³S–μqζ‘Οϊς?jžΗĚνεέΌ?π‹άΫ£8Λ4ͺr1ΦΊϊ(φ׊Œ£{²΄œ’νs…ρ–©gβέ/_μ[PŽš F°{ŒΤ^4ΆΤόG’hrΑ₯Ο Ι¨$²@δnD†O>β»ϊ*£]WmP₯A>e}—β‹ynό;¨ΫΫ‘’i eEI#₯rψRγVψaa£Ξ>Ν HΚψ]{W{ED+J (τw*t£6Ϋνcƒ³ρ7‰ννRΪχΒΧ¨™b•Drό^Ω«~6uxFίΚ‚8΅HdŽιa-s•Οβk±’«Ϋ%%(Ε&…μ[‹Œ€ΪgœkZŠ5ύγKƒΓΩK,Efši^œ…υ'§γZZφΗ‡ό€Ηo₯5Υτ?,ΦΖ@¬,I¦zWkE7]8ς¨«^ύD¨5.g'{[‘ζ#‹Vρ‹XΫΗαΉ4χŠu‘―.YA@:…Η'5ΧίκΝΏŠ4λ]=&€‹3έξF玾÷9‚ŠR­t—.ŠˆγFΝ»κνψ„Zeΰψ‘6€`o°››Œnέ³Ež³α/κwznœϊž•¨ΏœΡΔΐIΟ=A―A’…]υWV°Ρλ{œ“¦jϊχŒ‘Χ΅«OμϋK8ΚZΪ³rOVl}•wΤQQR£›],]:j υΉηΏ τ]GKρ'.5 W‚έDΝnνŒHœς*-kCΤ§ψιαύj+IK·Σd†[¨ηΝΐ=ˆ~uθτVf‡”jϊ6Ώαˆwώ&πζœΪΎ›ͺ’‹Λ4p²G ysΤqŸΔϋS-τΏxλΗZ6±ιO£hΊ;yπ[Μα₯š^‘Ž:@ό½λΦ¨ ^ρ_ˆtέbκΜψ6οRΣσˆn-eR$ώ%=9¬Ÿ…~Τν|Aβ]sQΣSEΆΥv¬:z0b˜ΞXγ€ΔΧ©Q@7π΅ž‘’άLG|Œ £ ΖyφB³ρ7ΓMgY΄Στ΅Νϊδέ[΅΄Š― α`}°? φj(Θ<)₯xͺσγρ6½₯ύŠΞ{Š8Φ@ώ@ΘΪ¬Όy …aΉ/<Κ?‹nƒν’*λn>:x&£»Ί‘AΑ•-Ψ―ψšο|7―iή$£Τtkqhδ€ΰΘκ=λŽπ— iή΄³Τ4k;ΫΆ‰MΕΔρξvr9ΓuQž˜Εt3ιψkΑsΨx*Φξ-βci Ωu-œΰ’r@%axγΔIαO ίλrΫ΅ΚZ&%m₯·:―_ψxw‰΅Ώ‹ώΣF·«κVbΩYwΫ,pΆΠO€ΉΗγŸzιόaβƒγΩΟQΦ$‰ažT%~θuΗ±λψΠπηΕρxΫΓ‹«Chφˆehό·pηεοuαί5ψ΄VΦΦΜΑO–ŒdU8.μΰΰΐP€ή|N·΅ψ›ƒŽ™+M#ͺ}«ΝFSwέΗυ―C―“΄+­fοφ„_ΔΦρΫκιp±Ξ±Œ+‡Τ`ΧΆ|MoˆO¨ΩΫψ¬α³’2άHͺZ7‘/‘‚z-σΟ‡>"xΣß-<7γk‹{ψξ]z’»ψVV@3Ο ΦΏΖ?‰ZΧ‚Όy¦[ΩΘ²if–{cζO˜‚7‘Πt o¨ξgŽΪΪYη`‘D…ݏ`I―.ψO¨|AΥ΅ϋ«οΔmti­K[[ωH\²ννΏξξκ{ΧEρuυΔπ=ψπκ[4­ ƒ9ϋ°ν;Š΅@Ην §΅όιžΤ/mΡ°f$g λξE{m»΄°G#ΖΡ³(bΥIΎOψmβΙ΅ _ΓOjΊbέ@52!f'!w~ξξ˜ΣΕ|]β/άψcαΰŠ³;£ΞQYœ‘Γ\ͺ3@Ex'‚>&x£HρΜ~ψ‚‘Ι,Ξ#[€ŠŒŒίtό +)ϊf“βgΕ/ψSβ„ϊm–Λ­=aΛ³1.ZGN>`7˜Ž3@ωEy―ΒIό{wu¨άxμ­δD6°ωq C“ŸΊ3ΣI­οŠΪΝχ‡ό«jzT’ΫtS” ‚\‡#‘ ²Šω§JρΗΕOψYυȎίO ..–χά0ωށ)^~<ΰw Ύ$_x·ΒΛj4Φ4ΨŸΈYUΆτ#‘€=nŠςΩσƚοŒ-΅‡ρΪά΅»Ζ#+G€AΟέ=+?ΒΎ>ρ Η+ί]^#ιΛp«’€€ͺJόΐg·­uvί­ηψ›/ƒF™(š7)φ―4m8MίwΦ½ΎNρφ«aϋBκrxzΩ.uWΈ1[£ύέΝ?A“ψWKeρ'ΗρΕΆ™γφ†βι—vΨΡ|΅cθΘ@ξhΡόyρBίΒ>,Στ9΄Ιn^ρQ„Λ(P»œ―Ls¬|Eψ—cΰ}WL±Ό°»Ί{ΡΈ48ΨοΤϋW’ώΠ_ςX<9\­τsWSροΖΗ‡|Eρ ρΌήρΊΓ. 7cURX Ψ;p€œsš§Δ/ĝoΓΊ1‚ρšκK[8žN†ΘœzœPΡΥOTΥ,t˜}JξXYΒ+ΚαAc۞όωϋMψ‡γΟ xώΓEρΜΡ]Αtρ«*5Ϊpθzƒž•Gφž½Χ›]ΣμοιŒ–B3–vΐŸίœΖ€>šFWEd « ‚;ŠZς j~<πη†5[ΖMoyekb²ΩΕ@K] cΑxcΖMu=Q‘Sp«ŒΗ=(ψJ4ΟψKO†Μ’.©δ} !B“Τ7Cή™γι>Σβ½Χ&x‘–AlBδΆ θ>•Β|TΨΏόβ5ωciŽpίμΏέΟ°%ͺΕM4xηβ.α}Ημφz|χsό.ΚV3ψ6ΣψP±Asφ‘έDα ‘ŠύŠ‘*ΙπŸ‰΄ίXΟw£Ό’[Γ;[³|ξάΝ}*H{Ι4€°σό…zΥγΪΆ§ρ;ΓΊ)ρ&₯q£έZB’k28J˜γώ @χ?z‡΅k}wC²Υ,σδ]D%PέF{§JΙρg‹#πξ±αϋ -vΥξέ]\(Œ€9#υšΌsγύεΝ†³ΰk«qsuτ†(IΐvΒ?:w‰5‰ΫΔ:΅Ξ}a©Έ±††4$•ΊηœrM{ …¨_κZ‡„£Ώπ²Z΅υΜ1Νn.σεαπrΨτRMyί‰uŸˆ>΄ƒZΦυ 'SΣ<τŽζή+sXγ*έ{χΝ{ 纏‹5-/↏¦]΄GAΦ-w[˜d˜T·~ΗώNψ₯β­OG½πώαΓφΎ«v#Dή1χ›ŽsμhΠ(―2ρŠ|G«ψΞ x(ΩΑ%”BKνBι7ˆΙθͺ½3ψώ”x_Ε^"Όnžρ±΄Ήžκ>ΚϊΥ6,€g*Γ׏AϊΠ¦ΡEpšυ§Δ+έZθhϊž¦ι¨p^,’ r4έΡ\'ΒΏκ^ MgOρP&―€\ύžv€a$8`;t5Τx¦φm7Γ:½υ±Q=΅œΣFXdnT$d}EiΡ^/ΰύwβGŽ<=o©i—:N—‚›ε„»\Έ<œrv«α·Œ―υλ]jΓ\·ŠΫ^ΡίΛΉX³±ςΦϊν4ίQ\GΒj)π€—ϊ³FΧ w, Ζ›FΥ#Stoκ΅νf‹ϋ>ΞΦ)b0ۘ δχλ@~ρd~%ΌΦνβ΅{s₯έ›FfpήaΔ8βΊjωϋΐΧ*ŸΕΎ5Σ|$,mΤžiοΤΈLœ*ͺŽόΞk΄π§‹d“zœƒϊb½GΓΛ©¦‹jΊτ–ςja~φκV2rq€}±@4Wρ?Ζ—Ύ}3JΠ-#ΌΧ΅I<»hδΞΔΩ€κ?ϊτΟ XόE·Φ-dΧ΅"λNb|ψb·Ϊθ1Ζ ώŠβ•“­ψ‡Η~Ί—Š.4νkD’UŠδΫΓε=Ύγ€GL φ +Ν>+ψλPπΏό"χ,Iw£3+Ε·&UΪ₯BžΩέZώ ·ρΉΤοΕwΪwΨε+ek Lq€XŒœ χ ŠΘρn»mαŸ_λΉ0ΪΗΏhκΗ’¨ϊ’γ^m‘ρCPΠG‰m4x-Ϊ?΄Η₯΄$–Ώ\‘ξ(Ψ(―"Φ>&_ ψcΕzjG•=ΧΩυHdMΖ<ΉΆ?\Šλώ(x―ώ?^κφΜ†δ¨KmΓ »t8ψP]Eyn½γ/iš†4+X-|e¬FόΕΫf*=ο’}ͺ΅ίˆόgΰm[Koέiϊ¨N-ŒΦΠωoo!ϋΎ™*υΊ+Μ>"ψΟΔ7Ž4MΓΆφΧM©[ΎΨζLπĎv’Eex‹Δ>=π–—‰/4½WGžα`-ΰ1΄;»©γ°=s@½wwof¨ΧSG Θβ5.ΨάΗ υ5xŸΗ―ψHZπ²YήΩG§Λ¨GφT1’Βp8w=δΰZήρOˆΌUΰάίkwn£¨ΛrΫΌq4qDŒΏ zuζϊ]ŸΔ•Έ²Ί“^Π―μ₯ticΨ2FJ2γ"΄ρN‡©§ΗqΌŒΚtΨΐƒƒΕlΧ›ψ#ΗΏΒCβtD^‘έa@°ΨSΐ¬λ⏉τθ΅«;ΝI΄œyYIφ)Ϋq žGΈό(Έρ‹#ΡόU θhςΎ¬Ξ«(p{FyζΊjρ‹χΊ¦›γ\[ΫΓ{¬τX—+“2…ϊ…άsΧ§zΉβMoβ'‚¬S]Χ.΄}GKY‘n­ „£D¬ΨΚ·^€s@ΕEEi:έZCqvJ‹"ηΠŒΧ ή(ΤτΓΪ›Dt­BΧΞΣΨ&Φ£ζR{τ'θEwτWŸ|AρV©eβί ψsΓ­½Τf/p&.ϋΗ@Ηπ¬έOΕ^(ρ/Œu-ΐζΚΞΫLΒέκHdωΟEQΣ±μzv S’ΌΓ@ρ_‰4OZψ_ΖβΞΰί‘{-BΩ6 ꬽ3ψή΅­£x—P»ψ­θ4_Ωφv±K †άΐg'½w4WρΕ–ƒβŸΨiν·ΥoZ ιΈ•:ίxΧ{@ζ>-ρwˆoόm'„Ό’]ΫΔ%Ό½Ή]Λ@ λ‚=zΧEΰ»OZKvž,Τ΄λψΆ―Ωήή-·sέ:v ²Šσ=JίβƒGu{§‘Z¬[ž;4·/½G@Xη’= K₯ψξσVψ?{βh’ŠίS·‚]ιΘ²‘#€{=θΡθ―πΦ«ρ'Ζ^΄ΥτΛ½'J£X ½ΓŽr·αGŠο;Τξt_jϊ•‰QsmnF]r2=EΥ.u―hΊ•ρSuuj’ΘQp7“@ΤWšxOǍ΋γ}CRDΈ-δρΑI΄² ΘΤϋΦ_‡/>#ψ£C·Χ΄ΝwAЁ½,…ΎεQύΦnN}y _’Έ_ψΏPπ·‡τ¨£Ά‚σΔΊ‹Ηk +‘˜Έγ9Ϊ υόk˜Χ5ψ>΅ƒ[ρΦ—ͺθώb%άπωocŒ«qœ9ώ΄μ5 ΧvπO 3MM1"$fΑrNz[;ˆξν Ή€ζ)‘dCκΘ―ψŠ€ψΓαΈm5>λ3iΰΒΕb\ ή`ώ&>ΤξTWžx§ΕzΏ|ΖΈΦΊ½q?‘l–θcGfι‘ΧΏ―¨ά|SΡ4™5Ϋ»½φ8WΝ›LŽ₯S© έrΉόhΧ+ ΕΎ'²π½½œΪ„w2%ΥΒΫ§‘ς»Ÿj›Β:νΏ‰Ό7a¬Y‚!Ί~rTηό+šψ·β;οXθ²iήNλF+y<ΨΓό€σCο@εΑ|Lρφ…y€θž΅Šλ_Υ\¬ 6vD£«°{ώGΉΝo[ψΰKxu]iΊΦζ*έGo—$ŸΌ€c?ŽhΡψ…β»­2_Ύ’Π=Ύ­©A $a³•ε}Z‘ρ'ƚώƒγ EΠ-­ξΫRΒΕ(Ηο2@bÝ£©€Π¨Q^=―λž?π9²Υ:ΉπuένΥ€–³E$—+·,±•7qOύ“Τ kMŽMβθ½rΛΓz5–‹6‘i§[Γ¦Μ¬’[’α\ƒŸ\Š_xwHπεΌ°hvΩC+ouˆ3c Ÿ~ .~8ψzf;‘ΗύuZΗψSβ/‡΅Ψ§σ¦ψΑ~ρ%ΒO­iVΧS Ϊ$a†Η¦E|€πxvίβΖ‰ƒεΈŸJK»uLIσxάF@γ ιΪ»ŸΪO‹ήG•–Aξ<Ϊχ?ψB<4?³ρ’ُμφέk΅1僑Žω­M¬xOBΦu+}CTΣ-ξo`Η•3ƒΉ0r1Ο­nV/δOΦλΚoύΦΥEuoέ΄Άχ$†U(θz2‘‚(ΑΏd―ωx“ώ»A ½rήΥνώ|kΧO‰°ZNgŒLΎά:>$1Ηsν_GψwΓ:7†γ4-> $œ†DΜGLώf™β/ h~$ ύ·¦[^2 +HΏ2ώ#šωΛWΤαψ‹ρίLŸΓΛ$Ά‘ΌCΝΨW),δ@λΦ΄όtͺ΄ζ˜<Ϋcƒώΰ―|πο…τO#‰¦ΫYοϋΝόΝυ=i—~Πυθυ«2ήMV2₯nH;ΖсߡnWρΫώIV½\ΣF-w΅ΑόtV…zκ¨,Liΐώ5  ψAρ?CπΏΓ­CJΥDΏG–Hb,&ά£ `ƒΧ΅Oϋ5ι7w:o‹o6ς-΄yθΞCΜ~uΡ|πNβ†ΦrλΪDάLδRΊg½ŸJΣl΄‹μ΄Λh­mcϋ±ΔΈ€>`ύŸόs’ψ/ϋrΝ%‘›cF|—}ΜΉp ΰς:ρIπƒS]kγσjH¬‰tΧ2¨n lWΠ:ŸΓί jš‹_ίhv’έ3ng+Ηԁ֯YψKA²ΦWV΄­aΤUv ΡpBνۏNœPΝΊζ½mα―Ϊ:χUΏ m »ύιUάULawcΫ4Ο‹~#²ψ‰ρD·πΉ’ι%ΊIε²οf|τ R+ιόαˍJοPŸG΄–ςνJΟ+¦γ œύGαψoΓ׍w£ιΦΧ$ζ*ε€==(ΒΎ?ί‹Ύ\ηیΫf«_΄όŽ^GF χ=gΒZ΅©A¨jΊ]½Υμζpw(#ϊš]{šˆ.mξ52 ΙνΖ"yΚ ηΖ€<φšΆΈ±ρ–ƒ¬‹Ϊˆ”GΛΉ;OΤτύ/γ/„΅K½2ΞΒζζkλιR”ΖΜqσ1qμMwZΖ“a¬Ω5ž«i έ³uŽUΘλVποš=όwΊv‰kΤgrI‚JŸQž”ΥΧΕvz¦όAΤ΄Νwao«ψ£¦ψ³ML%Ϊ—γ§š£kυOΏ5ξΎπ_‡|99ŸEm­g#i‘W-Lš»βi>#΅ŽΫ\°†φίΜD”d+`Œΐšρ―Ω{BwΆΥόOx€Λw)‚n€—óψς-#Γϊ›γGEρύΕέ„0»F·©?0<Α;Xr+μ­#L²Ρτθl4»hν¬αGc Ή$ŸΤ“YΎ#π†βFWΦ΄»kΉ`Hλ†κ9 ψg |;ΗΦCΒΪΖ‘©[£ΞΉB" ’£?{ΆkΑ@ΪsVΘΞ.Θύkή<9ΰΟxrf›E­­fa΄Θ‹–Η¦MIkα-Σ^“ZΆνγΥdfgΉξ%Ίž½θΑh_ω*ήvύVkt»πΤεO”£v8Θ*q^Ϋ¬ψOBΦυ/΅]2ήκξ yRΘW#\ΧtM7_±6zŜ7–Δ†Ω*δκ= pϊOΔ―κή»UΈ{Θ,¬Kθ>Ξ*p€|ΐΙμkΐό{cΰ›(cΦΌβ9μH Ωμ‘^3κ¬@+ςkιν#ΐ~ »‡OΡνbŽν<©Ζ σ9ΑΟj‘ΒΟΕp&OΪn Hό³@Ο‡Ύ'E ό-Πu©ΛD†8Αyv“σ:cšτέTΆΦτ‹MJΑ™­n£ΖX`ΰϊŠ©―ψ_EΧτψlum: ‹X1FW8ΗιΕiΨΪAcg ­œI Ό*8Π`( γΎ’Ϊ§ΓmI’Ο³ΫuACΟιŸΚ°>Ο7‰uOψΒρ Ι{$vΡƒΩQF@όkΦξ­β»Άšήζ5’ Η"7FR0Aό*‰£ιϊ‚Ωi‘ZZ),"Œ`dυ4σ-nlόsͺxή2-5έZΪυp>]§qqψ‡ώkΡΏh})επ›Α―m§]E,« "©#Σλ^‹uαύ*λ[ΆΦ.,a“SΆ]‘\0ωsΐόΝiKMG*+Ζγk+ ‚= ΄πgΓέSD[ίψJošΒXχ7«…cΑΊ{ƒ^§α;OΌ5§Ωh²tΨβC—ίΉ ηΏZΓ“αƒθά7‡μόΒw‚~™ΕuφπEmp[Ζ±Γ„DQ€ t€<Ώγ †ρ—Γ°Γ#ϋEψόΆ~:Ι'ρύrOύ•ΦjZ6©έY\ίΪG<φNd·wλ€~B€Υ΄Ϋ=_NšΓR·K›9€Dύ?ˆγ~4Χυ='ΐ?μ4ϋφνu8­`ΊΏSƒ yqŒƒΫ‚N}«›ψΙ£xcDπ΄kiίjšΝΔ±μjγ*YΩs€8ΐ'Ή―Ώπφ“¨h±ι7ΆO§DЉUBŒ.=0+&Ηαο„μm.-­΄;5Šΰm”Ιaœγ=q(™ψΕ€ΝuπφΗV°ρ0ΡLWΠ°λ…wιΟαY/“Ηo4ψŠΟΕ·χΊjj!.,gŠδΫ€œ`©n„ϊ}κkΉπχ‚<§x²ΒζΛZžσYˆ3AΊˆ™°?/\Wsβ θώ#aΦτϋ{ΔO»ζ.JύQTΌ;ΰ ψrθάθΪM΅­Ξ6ωͺ lzdΠDΔ…%FHZπ?oι—ϊ׍όWyo4sΊΆŸΩ£·Eυ\ώΎΥο΅Κ_ό;πώ¦Ϊ…ή…g%Σ6φrΈάή€t4ηΏ³£YΎ·γ¦ΪF±7Py-#fOήΰ’y5κ><‘Δ_φΈΡMW4ΝMξn§Σ¬αΆ–λoœΡ7ν.~€š§γ [Α!NpυΙ¨ΟΏghηαΝ₯ŒχφΆχV&A,rΘ¨ΫKέ‚y=}ͺ/„²ΒAγoλφY:mΣ₯΅Ό˜ΐ”¨l‘ϊίT…žπξΏπΟΓΧޏoqt±8σHly―ΑΗZυM+M³lc³Σm’Ά΅ŒacpyOΐ-oM°π©§jΆΦ—–zŒζXη•c!N0ܞGαP|7Φν|AρΏΕχΪ|‚[3oQH½.‘κ2₯z³ΰ kZƒ^κZ-€χNrςΑc©¦ψ{Hο ֝§ΫΫ\–ρ.ߐtZς„^ ΣlS’lr=‰\ƒοYžž6Ρο5Οψ²ς’gaΩγΆUπΞƒyφ½'F΄·ΉΔ‘rΛτ'₯yχΔ«6²½ψYe0ΰ»XŸΏ*±ƒό«Ω«?TΡtνVβΚ}B;‰¬€σmΩϊΖή£ς‘@'Η.ηVψc¬ΫΨΖNŠ“l^K*8fπώΑx+ΒΎΧ|+ex|G©BώJ­Δ/ͺω~S†OAžžΥοΘ_ό4π}ύλ]]h6m3ΜB• }ΐβ€3-ό‘]|-½Π<98ΊΣVG‚c(”3Τ0γο σ κ³όAΤ<α»Υv&ι΅%p~c mŒυΘ Ÿ©―‘τΫ ]2Κ+=>ννbH£UKKπޏ₯jWš†§Αo{xΕ§•BNNhΗώ6iΦ‰ρ7ΒϊŽΏ-ΥΎ…4Om-ΥΌ†6…ώl|Γ δgΫ5­7Γο΄{ŸέNTh]Y\;ηεΪ;Ÿ₯z«¦ΩjΦOi©ΪΕulz9T05ΞiŸ ό#¦^₯έ–‡iΔmΉν>£&€9Ÿ’Žή\d-ŒΨΟγKϋHΙ:OϊƒωšτKOΈΥν΅Iν#}BΩ E9ϋΘ§¨kz6Ω M^;»`βO.N›‡C@cρΞT΅ΐχ— ²Ϊ R3$‡’ό½Οΰ*ο%·_…χZeί‚<@χ—Wkh0™dV<”ΎΎγ­{5η‰τ‹?ΩθEukΔ2CΫr€I;€ΐαOSYϊΓ hw‰w¦hΆά‘ΚΛ·s)φΟJ©cα+“ρBΕ:ƒΐπ‹E΅±X–Oο³d`Γυ4ΪWΝ_€ΊποŒόWαύ5 v· 07»ν~}ΞοϋκΎ•¬»ι:†«g©ήΨC5ύŸϊ‰Ψ|Ρύ(Θ>#ΐŸ u kΆ(ΖήΡτ©φΌ<³΄ŸΗŸψ _πΖ–ϊoμχ¨I8IΎ΅žςRG%Ÿ'ŸΓκzφ‡¦x‚ΔYλ6q^Z‡ε†pSSK¦ΩΛ₯6KxΪΔΕδ˜qςμΖ6ύ1@ηΒ% πΛΓAFΨ£?₯q γσβ‡ύ†nΏ›Χ«iΦ6ΪmŒV0¬° Hγ^Š£ [OΠτΝ9―ΪΖΞ(ZώVšθ―ό΅vΞXϋœšρNΈΥ?eϋ«k5g›kΘFK”1π½αηK€°ΘςȎ§!†Μ‚δkSφ‚’E―ΫΏώ”G]„Ϊ—5ޝs-”->ž6Ϊ>9„c_ʟYμ΅­6m?UΆK«9±ζDu°Α‡κό(?ΘΏ¦Χ¬_ϊγ:θ^$Σ—:†ƒr·KŽι‘Έn™φΝzL$ΗJ8Τ*¨θΌΟ⯎¬αΣ΅o i0\ίx†β?²-΄vξU|Ε1b6‘΅»Ογ@~LΎ2ρώΏγ@¬lγE°°ή1…ΐ,Ο­CπλQΆπΗΔ―θzΤΙi=υΒήZ<ΜfL€ΗŒς8ϊϊWyπΧΓCΒ~ Σt¦ φˆγί9^†FεΎΈ<~{Δ~Ρ ΔNWΜ^WθzŠƒΓΎΠ<;ΒhΪe½ͺά ²νή={rhΘ΄» QπψΕž/Τ/ε€Κρ D’£‘Δk<ρŠo€?³nΎW;quŒυν^£iπλΒVzΏ·Π¬’ε[zΆά…> t­{ιϊ=Ζ•„)§\2Ϋ¨ω\·ήΟΦ€1Ύ>ψpτ45ΝόŸΨjOύW₯iΦ6ΪmŒV¬°(Hγ^Š£°¨4­OθιΆ‘Ϋ›©Lσlώ7=XϋΠGΔΛy.Ύψ‚(Fη6r| Jη~ψ·B·ψW£MuͺΩΐΆv‚)ΦIUY+Χ)»–ΒPeΦFξ8=σŽ=kΧξ¬ν¬ήζ₯ΆuΨΡ:‚€zbΉH>x2 ‘qf$pΘ$τΞ(©ν‘³Σmm­I6πΔ©'$¨ύ+Λώ#έA§|bπ%έτ©ˈ̲¨€Iΰuλ ‘T*€v¬Οψ{Jρ˜΅ΦμaΌ…NεYέ> φ 6ψωϋΝ@Χ¬ΘΊ΅58ζŸΙ`ΰ.G'ΰΖΊxίΓπψχSMJΦhgΆa $Š^FeΐPΉΞyδvη5Ρhή΄m ιzm”0Ψ6νΠc*Ωλzζ±­~xBΦό^A Y-ΐmΐμΘΤΕSψ#₯άi 4KkΔd˜£ΜQΊ¨wgςaX_΄ό‚ό5ax?z° x§ΕMzΣŚξ‡α­ .5]]>ΣώŽκ„l1,@pNFxkβ”«αο‹> ρ=ψe‘d³–\ecfWŸOΏŸΐΥοŽ^$ίΐ7m₯έ½εφ¨V h ‘dg$Ž@§ΏΈ―JΤ΄ϋMRΚKMFή+›i9WršΑΡ<α}τ^iz-€ εd ’ΏLτ >ψdϊm‡Β›ΏΦ[jvp·ΥBό«GΖΪΐ€Œ’ܟό‡-z>«£iΪ΄–rjV‘ά=œΒβάΏό³taοEΞ‹§\λ6š΄φ‘Ύ£h¬N~τa¨'σ φ…’o7ύ}ΫθΑ^‡a6υΝ•A¬ι6έ‰³ΥmcΊ΅,c“¦AΘ?]EŠͺ0ͺ0  %ψ…wρ§Αž£*A`bž™ΞY•€ΙνΙGφˆρF–ώ²-/mξon/"Η ‡ΨŠrY±Σ g―>•λkΦ_dΦ,‘Ό·Ξΰ’p}G₯cY|<𝝜φΆϊšΓ9S +’ΫX0η―Pα@Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’ΌΗγ=ν՞©ΰU΄Ήž›[†9DR₯†U±Τ{τΧuδ`¨£%˜ΰUl5; CΨ/mnΆ?‘*Ύίγ΄?ЬXiΎϋM£ήFΪ‚EŒΓΑΐ8Γsž‚»ί…φžώΞΈΤ<¦΅”S‘ ₯γtfٜpίονh¬(|S¦IβΩό7ζJš¬P‰φ„ζ’Σώ&ψrCΎΥ!–πCdTMZHK}Π9Ο·γŠν¨―"ψcρnΣ[‚ ]`έRξργˆGlΖ5Vl ,8ΰMzž­—¦άί]oς-γ2>ΕάvŽΈjŠΙ|C§jΎ]΄Ÿ:kΒΣωŒ1…\ξΘνŒΚ«x7ΕΊOŒ4ΗΎΡ%y I mζ!Fθh~ŠζτίθΊ…Ž±{ Γ­¦•+Eu3ΖB«(ΙΖ:γΪΉΘώ3xEkθ`vΪ·RΪ:ş2?*τz+Δώ'ό3¦A¨jӘν&™!Iw ͜;pyNογ/„-―ZΉΌ’}w«4 ½ά{@EpŸ|yiα―Ά₯e7›syϋ GtcσŒƒήποββ¨m,β7gR[T’v’Ω‘ `nΑ<Mw4VόKgαOΟ©_™6Œ€klε€ 8t<œ γ>όP³ρŽ™a¨5Σλs†σ[0‹#'οtι@£Eq~+ψ—αΟ κ?Ωχ“Οq¨ [YΒetνcτΞkOΑώ1Ρ|]m,Ί%טΡK ˆRHΟΊŸη€:( Xψ―α­6ώζΡϊώKVΫpΦVΝ*D{εΊqνšοhGΑŸt?άΛ‹φΗςΤ³<–μ‰τάxΟ=+7ZψΉα]'QšΙηΊΊ’Ϋ3ΪΫ΄‰τ-ΣςΝzΚλ9Ρ¬||GΑΉ±tΜ- lεΫ€29λœc½rŸ Ύ([x‹N΄ύQξ_^Έ2‡eΆaΓ9_˜qχόhΥh’ΌχTψ½α]>φ{o2ώε b“=½£²!$ΣΪ€= ŠΙΣ|Ά8*U‘ΏΊΐς l““ΐ Šσ½Sㄬ/ε΅K‹»Γ m–[Kv’4#―ΝΠώ­λθ1ψIΌKΩΉ₯ Ι•κ9#9ι@5ά7ΦP]Ϋ8x&A"7ͺ‘kCρΆ‡¬ιΊ–£ivRΓO‘£žβeΨ€ŽΈ'¨@-ηΏΌq}iΌŠ_b]Kjλ p>cΘδ λόIβM7Γ–6χš€Ε-η™-ΡΥw ΝΣ§n:ΠΕηw|)εΜK{r–ΚΝ$π[3E…88nQΕw>₯k¬iVš„že₯ΤK,MŒeHΘΘμ}¨εη^-ρ?†όGΰA=νμ6|‹oyqo ­Έp‡ψΉ?Zλ ΤtέΒΆχΧ7žV›Ί7Ÿ9ηf ξIτ  š+Ο4ΏŒΤ5(,ΦβξίΟ}ΟqlΡΕ!=0Η¦}ρ]<Ύ(Σ"ρd’ISžΜz~8 A’Όκλγ'ƒ­―Œ yrπ‡ςΪν- 8ϋΨδ{€EuΊ‰4Ν @:Υτηϋ8l"X†ό‡ )νΘ  ŠdσEo Νq"E ³»Uδמί|dπ}₯α„έ]Mœ=Μ6Μρ){ΏαšΉρBφΫRψI­ήXOΕ¬Φ{γ–3•`Hδν‘–9βIa‘$‰Ζεt9 =Aiυη~ρN™€xcΐϊEό’Ew©XΔΆηaΨΜp[ ?β+³ρ³eανηTΥ$1Z[η`2zγw4£EU―‘Υ4Ϋ[λ`⠈ΦTσkm## τͺψ“N›Ε7GκPB.v‘NhfŠΕρ‰΄ίάιjRH’j3ύžά"ΛρΧΣ­gψΓΗΊ„ξ!΅Τη–Kι—zZΫDe”―AυΖhͺ’Ή_xσEρlσΫιfν.`PςCqnΡ²Œγ9<~΅CΔΏΌ5αύNM>βk›«ΈΧGg—ΚxτJξh¬― xƒMρ.•££\­Ε«’3‚ ‘Τ0<ƒZ€€2xQ^w©όbπ•όΆ©=έη’Ϋešέ€›ΏΤf» 'Δf―’kι—isa°Ώ˜™ΰ’κ±  J++Βϊύ‡‰τX5]%έμζ, œ«<pj=7ΔΊv£β SF΅y φ›΄ά)Bά=ψ4³EpZΕŸ X[<’]Ξς¬ς[ύž(KJYντΟsŠμ4]F_I΄Τ-VU‚ζ1*,«΅€>£±  ΄V^—Ωjz…ύ³?Ϊl_dΚθWΤzŽ*+ι—#›CŠf:„)½“oΈΟ―"―ΩΛUmˆφ‘ξlΡYwν”ύΎŒξζϊxΜͺͺ€€£<“Ϋ‘¬­kǚ“|φrΛ4χ¬[hŒž_Ττ§S“²B•XE]³©¨νη†ζ1%Ό±Λ8܌~b¨ιZ½Ž·₯}³LœM3‚=ΑkΝΎxΓHΠ|mm{,―re‘Ό˜#.ΐnκqΐόjαBR‹²Υ5§ήD«Ζ2Wz;λχ·Efx^Σ΅ϋ3s₯ά QNΧR ²B"Ÿ―kΊšχΧζAn„(…ˆΟeΙ.n[jkΟ^kθhQQ[ΟΕ΄w8hd@κ݊‘kŒρ&·‘kήΉ–k»Θl"ΊXZhP†.ΰzŽG5P¦ζμLκ(«ΕGPΤ¬΄,ή_ά,6±¨ΛΏ$ϊqԟjΐΎ hZ•όVi,πK1ΔFβ‹!τόh)Ι9E]Ua”ž§[EeΫkΆ7υΌŽβώή1+£.SŽAοΤTW%Σ-όG‡,Δj uPΌsž υβ—³–Φσω΄Žχς6h¬ΝK\²Σ΅+ †΄ή±XUW9ΗR}iΤΈ΄“}JM=Q\—‚f­t}^γN»ΊΈΆŠξW§*αA`¦1QΟρΓΡΓ ‘Νqpe]ϋ!„³ kΣ§JΥΠ›“QMόŒ•h(§&‘ΨΡYΊ·a―Ψ‹½26,νl‚O‘₯.Ώ¬ΪhZ{^κE·V ̈[ΰg«>IsrΫSNxςσ_CFŠdr€¬¨ΐΖΛΈ7luΝcιΎ)u "γTŠγe„ Uζ•J Lυ‘BOTΚ+vmΡ\\ό;,κ†[˜’c΅g’XΟγΫρΠλšεŽ‹₯FφCφ@ToŒnΞzcR£R-'©*΄$›OcNŠi‘D^gπνέψVE—‰4λίK­A$†Β5gf(CazρR’ή©䖍›4W%7Δ .m­βš{‰gΩ…†"Ϋ7tάz₯u΄εNPψ•…‘ŸΒξGπΜ,2Η#FvΈV©τ>•%y_†όI¦x{ZρSjS2ΌΊƒyqF…έ±θσ5άxoΕZWˆΌΕΣ§o>.^T£¨υΑνξ+JΈyΓ[iάΝxΟKλΨά’ΉΝKƚ&›s}oyrΙ5™U‘6X°Θ λΕYΣ4Ρτ³­Μ“=ΕΔbT·Š"ςm= ΏŸΓ~*Σ|BσG`gB2ρΝ !ω~΄έ)¨σ[BUX9rίSvŠεuŸθzMτ–rΛ<σΕώ΅mβ.#ϊž•΅₯λ6:–5 ΔΦΈ$°Ž Ž ϋPιN+™­ͺΒO•=M +Ίψ‹αϋ{KyΔσJg ΛQp$ŽάƒΦ›c%ΔΏξ͟μm¦Η"ΖΜv‚[Σ¦xͺφIΉ+ν’ΪQw;*+‘Τ>!hVwrΫ«έ\΄-ΆF·€Ί‘τ'ό+ ΡuKMgNŽϋOv{y2²9‚=jeJq\VEΖ¬$ν©zŠβ~(x΄ψoIς읗R˜ƒ1’ͺΉδ“ΣΫzi>!5U…ξγ† ™ΜM*y\υ<₯B|ͺvΡ“ναΜα}QΤQ\ΎͺiZ'ν/–ββM2(ΖΩdR\‚qΘͺ·_<9mrbk™έ᧎hΤύG_Γ4{ Ι΅Ψ{h$œšGeErš―΄ :QΈ’εŠ‡?eŒΘO ’8­νU³Φtψοtι„Φt`1PAθjeJq\ΝhTjBO•=K΄W!¨όDπύδΆζiη1²<—D>ηό3]6™k©ΨΕya2Νm(܎½ΐϋQ*S‚Ό•F€$νrΝŸκφΊ%ΌΎσ|Α?v…ΞO°q~$ψ|Λe―€`‹ΊΩ†I’4g5x«ŠUai;‘βιžΆI΅;/Μ8Ž5RΞηΨ ‘ ψγEΦ―EœΛΫ €W1˜Λύ;§Z)Έσ% :°RεoS¦’±΅Ώiz%δڝǐσ#H¬Κvαzσύ+&Γβ&y¨–β•ΆΖσΒQφΑ’\Κ.ΐλS‹εm\λθͺZΖ«e£X=ζ₯p°[§Vnr}“μ+Gρφ‡ͺjΩΗ,πO/}’‚Cμƈœ—2ZU!Κή§WEVe…Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@yOΗ/ω xώΓΠθB½ZΈίˆ^Ήρ=΅Έ†υοd—U ΰcΏΜόv‡μ5ώ„΅λΖ|EπΟŠn|;-­Δ02ύ.δσͺp1ߊμθΚ>3DΪ·αΏ۩Ο8ΆΌ#Ό{ύ ?GͺμρΖέ.Ν—MπυΈ½“©™πPθ'πίβD6ψ\MY‚Yύ•Λ1μ@Κ‘οœWϋ9θRΨx,κΧΫΪσTq i9o)FΤλμ3τΕCπζ―ώ0xςϊύ—֏0o1FAϋΎ™ΐ&‹VΡXόDπ©b«₯5Ϋ[ΘΙΑ–?—―2:ΩρG΅AβΓβjιΪ¬±ωWPάGΎ…2~Z£Π< «άψΊψίU‚ώφΡ6Z[[FRsΤσΞΞxRΛώN+Qχ#ώu_㴊5ŸFOΞΪΊ°ΐ˜­―x/VΌρ]Ÿ‰ό)©Γc«ΓΩ€K„έΡδ>ΏΚΉύCᯊuύoHΦΌG―ΪOycw‹o E!H”ξ`Όd± rhΨkΚδ“ŽOϋύ «Υ+ΚߟΪ9qΞ4AŸo¨~ΙPψ†;ύͺ?ύ«ψΪE?<?:ΫLΔzΘΦ†ΉΰŸΩxΞϋΔ~ Υm-₯ΤVξΪς2Θε@†>•KIψo―ι>+ΧuΨo―`ή.G±J‹ ΙΞhρ‡|QαŸκ>,π…½« Š.μ&;d@#{γ?ΠΧOΰXx²;τŽΖm;U΅!o-'P·?Δ=ψϊU-gMψƒΉw>…­ι2i³6θνοmΙ0qΠΑ#κjo‡ώ ΌΠ΅_YΧuΤ5½P―Ÿ$QμUF¨ϊcς  ?Ω§ώIuΏύ}M‘W§έΫΗuk5ΌΓtR‘Η¨#ΌΛΑή ρgƒ΅c£κϊtžk―;ɞ"fD',ͺGr8Ο?…z•|Νi¬έh Oγ™tΙμ/!΄ΈΆί­&οž6ΗΛΗγωΠO‚5+/ό΄ΤυΘ^βMBC3Bͺ Ο,€Έ2Ε…ŽIοϋ“^³―θφ6ήΏή!g‹Ζ#Ϊ1€œ~IЍv—φ±ίXάZ͟.xΪ6Η‘―;ψα?ψJk},κϊuΧ†ΰv(­„9;AιΤϋΠOμι wV#ΥξΤ>­>©*M#˜( @φ嚀Ί4ίΪ3L:rˆ΄4ωMβ§°€†#Χ*΅~οΐšφ‡βMCWπ«ii’ήe͍μEβίέ—Žηρ=Έ­xσKΧοΌGβ]Iu=zι<­ρ¦Ψαϋ¨?ω}hΊ ΘŠΫY”€ή‡kΑ~ψͺ/ΪλήΤ΄kϋέFήϊGg°„L³n˜ΧόkΫ|CͺE’hwڜκΟ€-3*υ βΌSΐ^ρ₯ξŸs―x{ΔPhvzΤΝzΆ†1pFγΖY”σŒPρ4­cŸόQywnΦW³Ew}Άyƒχd¨ΗcΗOaX_ .|eeΰ[Hτ/ι—Ά7%½UiΙ'%όΉ»αΞΏ―]ψ£Δ>ρuΕ©-ŒjΖκΒW«θ}=jΆ›ΰ_xFK‹_λΦ'E‘ΛΕk¨D\ΑžΐŽΏŸα@όαΝwΓ~ρ΄:υœVQ\€χΠG2Θ©Ί&ά…­ΩχώImτ’Jήπ揬Β;}eβνR=Jκρ€ πΔ#Xγd ±@§Μr}k—ψ{αx>β -5}:λΓΚξ¨Π‘8VΙΪAσž½θΡ΅ Θtϋ‹Λ§ΩooK#z(&ΌΛJρ—‰η>MΤ/ γсωΧ—hή ρξ“€Ϊx—OD\Ζ“‹rn2~κφΞ;ώ΄•πAœό%ρjHv]]Šr«ϋ•ΘΥΠώΞzu΅§Γ;+ˆ’A5ΫΘςΎ9l1τΐ>ŸΒΎΧt3yΗΫ§α”η*―EίΗ^2q[_ |9?„όa£]Νσ[οέ$YΪrΔρž{Π!πŽ4Άψ‰ρ&ΦΫΗy$j0a&»β…ΕΕ―Γέ~k2DλhϋJυΰώ„ΥoψRηCρw‹uyξ!’fh€‰;£;³ώπι]]ν¬7ΆsZέF²ΫΜ†9Ί2‘‚(Œψ/§YZ|1ΠΕ€I‹›a,͎]Ϋ–Ο―9…qŸt{{―όNπΜJŒς"€cξ£:Άμ~Ÿ•iι~ρ·…mζό%β+£33B/ΰ/-Ύzΰƒό½«­ψsΰΨΌ₯Ο\½ξ‘w)žξιΖ ₯yށγ΄?ƒζrηϋgF•τ΅_β;Ž##π$ΐj—Δ]o όΠ4XΗοnnc{ί›hyζ ŸLΰgΡEv ψPϊŸΔΈυψο!I’Xn¬Θ9’XΑϊwΟ>¦»Ÿψ^ΛΕώΉ5ΙΈd‘>τn:0 5ρ―uΏ άhΰ}9!ς£Ω~ŸΉ |¬£=AΑͺt«λ_‚ž΅ΑΆυ/-ΰ›xuxŽΟΓίμ,ΣNΆρ>“%΄cdwS[˜/Až0OΧ5ΉγŸκ&𕦛ψšςΦκ‰%R›3žΰœΠEƒ§'†Ώ±£ΆŽ;·0Ρ@Jΰώ>υγώ ρDž ψyβέR“v‘αΩd†姘qΠ±ΟΠΧΊ ΪŠ=+ΚΌwπ₯όMγ›]^+Ψ Σ€hN‘lAΜώ[qŒqӎhŸΤtΠ?fΛδΈν—q₯έΑ=KΌŠyό1Kρ–[–π/¬­βY’κζέ^m«)0Œ{kΤ>"xzoψ3PΡlεŠ nUU@vίJ©β[ψ“Α6ΪτΖ9­γΚΉ‹¬r ΐa@l<β― M’OΰΝ*ή εIς R*3θ1ψΤ~:΄Ύπ|6ρ’1{¦Λλάv²ΰς=ƒŒϋΦόΕ(­–ΔxŸHς”mmkΊmΎΌŒQψΧS㟠Ιβ\θrά―Ϋ$Š=·.0<Τ ‡γ¦Hνλ@1βν6jή:ρ=±b4O*ίOqΘέr?,ΐλ¦:€~:ψ‘ΰQ ίki§VaΤ aAχWwπσΑΛα‡y"\Λ/˜ΧR.q#>sמ˜…`ό"ψk?ουK«ΫΘnήΰ­ό°ί»Œpsυ(ΣjΎ₯h—ϊ}Ν€„ͺODHκ―>πή₯¬όFρ…ό··/€ZJ,m­Μ„ΖqΌ…ιœŽΎζ½PŠiμn"΅›Θγ+ΈΞΖ#ƒjρ­&ηΕ 4ΏμνOF‹[π΅Ήr·v\KI.§―^χΥ/Η]VΓ[ψA₯j:C°žϊ‹ ·1ŽΨ#φ­›―όMΎΣg―E°Ο°™EzχŠ΄™uŸκšD2$s]Ϊ=Ί»ηj–R2}«Ν>'θ²θ³α.eIe΅ρ;ǜ7ο—¦~΄θΡ΄Επ†œ-α:|–H6Œ0(2Oη^3ΰΙδΩηΖμΜΠZάΟφO‘°?Oγ]5„<~ž‡GΣΩ ΰ"½[ΓIΡΌ!§i7―Ώe΄Ky]~λm\ΟjςOΩοΓp {_Χ‘w–Ζ ^ΓMfθ#ήYŠϋ}ΠΦ€=Κ’R(Τ*"…P;^_₯ΙΓλ>ϊTΜW©ΧžψΟΑZΕΟ‹mΌQα-N V8>Ν,w1οŠhσ?ΟJΗψγ"ό>ŒŸ΅]ΐ{™ώb­xίΒώ"±ρΊxΛΑβςθΫ k‹ž7¨ξλωtοœV}οΓoλšφx_΅Έ½±ΊIΌQ…"$/,N95Τx—NρΠΧ₯»πΞ³¦>EQφ;Ψ Ψ yη―Z‹ΑΎ<‡Δj6w:LϊWˆμαί5€λ’F8ΪΨυΌΓཌaπΥΕζƒα½?T—2<χ“ή,rHΩδNxώ΅ιώ πf©cβ{οψ£S†ϋWΉˆ[ͺΫG²(£‡sXλΰ/xcWΎŸΐ:͜mδ†g°ΎˆΊFη©R;~_/ΒxFρ'‰―u½6 6ΟRdš;x'Y\Ξ0xΰΧSρZββΧαψ&³,&ŒS‚ΰŸΘš›Αv%³ŽξOjΦϊ„σ2˜’ήBr9Θλι[Χ֐_ΩOiwΛo:δFθΚF ?ΰޝeiπΛC[X£Ϋqj²ΜqχέΉlϊσ‘ψWπ!a­όQμ†έ2ή@Π’ύΤfI7ωΚ΄4ΏψίΒΦ²ι>ρ‰Ρ‹1‡νπšάBςφΦ|?πUΏ„τK‹GΈ{ΫΛΧ2ή\Θ0esΧπ  OΩηώIF•].?τsΥ‡ξ²|hψ‚ΘrΏˆ@κ*=+ΐΎ7π°»Σό'β=4iζib[Θ7ΙγΞή1ύ=†Mk|5ψ{uΰν{YΎΉΥ?΄ ˆZI:»7l'ԁπ H³ϋ‹΅W…τκ³B²2δ’'Σ“^Θ8ι\Γ \ψV e.!œί_ΙvžX?*±ΰχΒ€<ςώhό;ρJKɏ—i©X³ΘیsލBΚ9μ"Εq*O;ΘK"η OΧΨ ΔΒZζƒu'„υ;xμ\ΘΦ—HYQχH?Z~Φš ΦΧ½΄τϋΕμ¦Ήg―[ΪΧΧΧξΐZ6±¦κzυΞ§c ½ζ%Ž₯ͺάη¨~Ϊ[Ηα7ΉDO>Yά;cž8ΊΩλpΑruύBΉ₯?"ΓČc γ'ρO@πo‰<3cεθšΕ‘2όΣESψrα^›γί Ιβml‘™"ΉŽU–9_8džΔΤΆŠίΑk ;+/ٌ.ΰpXη-ωœΡ Dc.»?Kά'‡”€ΧMΧ­¬sΦ&ΏρOνq0’ΧM±RΫ|ƒ9ΎMz r|'7…¬n’ξβ;‹‰άιœs]}sb%+Aέ-Š’δ΅zžeπϋώDΧείώŠZΤψ3g ³ž8ΤKrς<Ž[Κ?EsΓ>Έ|?­iσO Ι}<£.p‘Π(ς­hψΓZeΔ©,°oΛ¦pw;7­mZ¬e(½Ϊό™•RŒ’δΆOσG=πώ5·ρw‹ΰ…BB·(ΑGkΧτΨυ}ςΒP6ΟN{Ησ¬Οh3išώΉ¨K4o‘"Ί*η*Η5ΡV5§zœΡ}Ώ#jP΄9d»ώg‘Ϋψžko…·v2ώΦ΅ι{ˆ’pύσ‘υΎ2αO θ’[½άkvAα˜γwκ[ς©%ΡmυŒ²ύ•‹ZΫ„»ΊAχDΐ`~=ԚοΌYαϋohςXά³Fr9SοFγ‘ΛθkUaNqkg«ω‘ΙR© 'ΊΡ|ΏΜ_ιφsψ^ϊhcΛaqΒΰqLW˜κMqπΡξ gύΡ+ϊ]5Η†ό]¨iγJΤ5ΛA§Ibˆω'‘=+‘ΤΌ/gwα# DZaŽ6•#‘χ泄γJΙΚώςf“„ͺέ₯m5euM)ݎa$Ÿm΅ζΎ’%¨Χ δkQ|5βΫ­=4C]΅fΑ’CϋΉ>άgωΦ†α;‹έh qΟ,r’ΚΪ7gοJ<”γnkκΎνG.z’Ώ-΄~„Ÿ τλk/ι―H²\D%‘ρΛΟ&ΊΚΜπΝ&‘αϋ >gY$Ά…cf^„JΣj²ζ›—™ΡJ<°KΘσŸ‡V–νγ/έ2+\-ΩE$r«’x=©ή"Ž;?‹>žΤšκIΒρΉFpOωνO‹ΑΊή­jzΆ«A Νάμζc-!δί η‘WΌ9αKψόBϊχ‰/£ΌΤByp€KΆ8—ΫυόΟZμ”αΜκs_K[εc’0Ÿ*‡/[ίηsAΣνξώ0ψŽββ5‘­γŒΗΈg’ ՟Œ?½΅Π­$$Yά_’ΟƒŽ2?ΔΦξ‘αιμ|e­k/4m ς’€c;—hŸΚψ³@Άρ&%…Σ4dρʟz7ώ_CQν’ͺΒMθ’ό‹φ2t₯΅mώaβ=>Ξ ^ΪM bΥ`l.ήŒ}+ΜδK›―ƒZF€rΧZlήtlzνY¦+€Έπί‹΅ #π[άΘπˆf΄›‚Tc;ζ―h>-W‡RŒΨΛa­ZBZ[yG<0{ŒΤΊΝ—ŠΖ­-Ζ‹©XύŠ@ΈΆΊ‹;8#žzυ¦ψ_ΓWΆZΝξ³^Ηw¨ά &ΨΡaXΉEΣχΪm-7Ώ£6Q’ŸΈšMλΫΥ?Γ[ŸΑαφ—IΠμοRβWi.%Ή ξΩη ΧCΰXΟ‰¦Υ,β²·ΌlPΕ(uVΓnΖ>’€‹Βzξ{rήΤ­£°Έs!΄ΊŒ²ΖOχHν]‰a­&Ÿzšξ‘ έΔω εG±"ΖΦ•«)s8ΪΟΦδgF“*•ξ½-ώg9π_MΆƒΒ¦υcSss4›άŽphN?ZτŠI8#Η5…ΰ}oxv:βXε‘Ψ²g3ίλ[ǐppk—>z²’}Nšδ§΅ΠσK[ψ ξ–ΦΒ=_CyZlΔvΝ'œŽ―ΤWqα½^Λ[!½ΣAX‘°¬ \Χ6tί’InΊΖ™,M'’ζτf·| §‡4D±YšwήΙ)άμy8νZΦq”nΪrςλκgEJ2²O—Ο§‘Μ|r‘ ΧΤΙ«­ρ_ό‹:―ύzΙ š­γo―‰΄ ΄φ—ΙrΑγ|d3νTtν3ΔshΪ…Ž»{e9–άΓ ‘!$YΏN”£(ΊqΧgωΨn2U%¦λςΉΙκςBa)‘Χ[>™koπή{4…+§1ΐ^­ε“Ÿyͺχ>Ή—αΤ~‹•SΝ μα³υŠζΑεπτΊxu=©€1ι’›sU:©μώΣ‘0€Φλμ₯ωœΟΒ+8"π“€kΊγ{HqχΎb9ό`ψ:i,όγ²ό¦ήςδDψFΡ»―hςθ>²Σn$Ie€0.™ΑΛίλTΌ#α§Ρμυ{{Ω"ž;ϋΉ'ΒgXƒžόSucΝ6έξΧζ(• ­k/ΠγΌ 7‰m|)i—αΛ ‹I”±•ξ”²NKΊ?…ϊ.©’Yj0κΆιl’άy°Δ’P1ψU; x›ΓΖ[o κφ­¦³ŽΘΛ³Ψώ}«¬πε©kbΛ_%νΫΉmρΖTvP1z©©r΅gλqP¦Σ2w^–4¦• …ε•‚F€³1θ―>Π"—Ζž&mzρHΡ¬XΗ§Δέ$aΦB?Οι]t]C_ЎŸ¦]ΗjdyΜωωΠςροΚ²τέ'ΖVΦφ°_θim`~VtΉcΤ’“όόJΌšM>Uψ²£D—ŸYo:ΪΨ«Ϋ«r=X{δšoΖxb‹IΣ5π—Π^Ζ±H>φ$Œώώ΅β― άjZ…ž­€^ -bΤmY ξIϋ¬=:ώužΎΥυZΞοΕΊ…΄φφmζEikTfυlΦ°©hΤrΩmύw2œ%Λ*vέούv(ψΪΦ;ˆ^Šν!WfB8$`β|g†6πL’β• 0―=«cZπόχώ-Ρuhζa±WΝ»€ρή…7ˆό;6m,qHμ¬LγƒνQ ±R₯‹όΚ•&γSMΘγΎ'Iwqβ/ ΫAmήζ2­Ό―±$qŽ €ρmŒ£§|QπΆ…lΡ‹ B9ZpS,J†#·A@εQ@Q@Q@Q@U}BV‚ΒζhρΎ8™Χ> @(7αˆ/ΌQΰ+ [UhΪξg”9v–FQΗΠ μ¨’Š(’²|G―ΨψzΪή}E˜%ΕΔvΡ„%άΰV΅QEQY6ΪύΗ‰nτ8™υ¬ q(ΗΚŽ>΄­EpΎ2ρ6£₯|@π~‘hΡ‹=M¦“$νیέMwTQEQEQEaxη^ xSQΦ#ΆMi(Ύΐ܁Χ}(vЧ’ή6££X^Ι”χ6ρΜΡƒ…”gΎ3W(’Š(’Š(’Š(’Š(’Š(’³τ­ZΧT–φ;Ff6s$$`n=zΦ…6švbM5tQE!…Q@Q@Q@ŽΧš ρBΪ :IƒyΊέΘLVΕ7 JαEƒγ­RηFπ­ύύ‘Qq ‚…†G,OƜ"η%ΤR’Œ\ŸCzŠηοu-YtM2ηL²KΛ‰Μ~r“΄*‘σ0€tζ‰EΗpRL(’Ήoˆέζ‰k₯IbΘβώ;y7.~F?ʜ η%š„y™ΤΡEœu‹A―sΓΉΐΞ:ϊ֍6šάI§°QE†QEQ\ΏΔjοCμη°dKw-Ήw|­œΥBrQ]IœΤ"δΞ’ŠE9P}«Ηϊ­Ξ‰αύBΔ¨Ή„&ΒΛ‘Λͺž>„ΡΉΙEu ΙB.O‘ΠQU4yήλI²Έ—d°$’ š©¬^jvϊŽ›Ÿb—³HVζBΨ1/b?Z[| δ’Ή­EPΈΥ­`Φ-tΗfϋUΚ4ˆγ Χ5~“Mn4ΣΨ(’ŠC (’€ (’€ (’€ (’€ (’€ (’€ (’€ +'ΔΪύ‡tγw¨9 NԍFZFτΉ˜όQβ»ΈΕΕ—…6ΫTMrΨzγV°£9e·ž†S­ΎWΏήw”VO†u;½WO3κdΊlκε 26μγΈ8V΅g(Έ»3HΙI]QHaEPEEw#Ei4‰χ‘‡Τ ηΎk7zχ…αΎΤαέΤ”]£ΰqV ά\ϊ"\’VtΤQEAAEPEPErΊ·yyγis²K%ˆΔΰΛ““ήΊͺΉΑΑΩW&SWAETQEW/y­^Eρ ΗHFO±ΝhΣ0+σnŽ΅ΤUΚ6ΏRc5+Ϋ QEQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@yOΗ/ω xώΓΠθB½ZΌ―γ|nϊ―€v#6έvp3ΈP?ρσΓ±Νβ ]>£©ζϋRŽάΕφέΒ QΊ5ΗΚέσ^·αOΓα½0Ω[^_]‘rώeμήkδφΞΑ|sίPπ6ΔfΫ¬ΔNqσ-z΅y_ŠΌ-ρƒDԚζoμmm>Ε4M!1Η0αHFޞ†ŠwWzύ<-α6κhςύ²υΰrŒ!^ΩŒς>€VχΖ-ΌAΰKψνς/mΪνΨuœροŒΧ#π:K―λzǍ΅8φK2Gcμ‘oΗ±<ώ4—κ?>"λZCκΧΪw‡t@‘ΌVRyo<ž§π=sŒ{ζ˜m΅†<Πmmukλ λNmΪ Ω|Ζ‚AŒ=ΊŽžωνNžϊ_†ŸυΝKT³Ή“ΓΊξΙΥΌFA«ž\ŸΣκ;NOŠ?πϋh–wKανCs5μρΦY0ͺΣλΙ  λ;Λ“ρϋP΄7U£qσ°6zγ¦j/w·VšŸ‚VΦβhDΊ²$‚7+½rΌuγσ࿌0ψ“R΅Ή}φΐZ½Δ1—ς€RzνŠζόβΟψM ³#g‡ŽΚ(7βEܟό'£ψoBΥnmίS»16£w&ω Œ‘Ή·`c―\pοΝr~!ŸDπ…„ZηƒΌww¨jφ!šΦβοΝK₯' 6ΰzηœτ―@ψναΫέFΟEΦ΄ΫΤ€Ρξ„σYηEXm?{§#ΠšΕ‡Η ζ†1„‘―Ÿ φEΡPΈoLνΗλ@Ε€^ GJ³ΌQ΄\D²γΣ#5ηΪύεΚ|tπέͺ\LΆXΜΟrˆΟ$t5θφ‹ΪΒ!ˆCAΆ0»B tΗlW”όQšo όDπΟ‹%³ΈΈ ŽKk¦7˜·ƒΗτ  χ—6^Ά–Ξβ[y£—‰Κœr2;VGΖ½FκΪγΒπ^ίκw†. ϋ«"CξΒν Γ δύyτg⍣ρ‰gkα«Bm:Φφ+‹»Η€Ζƒͺƒ<’Kηπ―Qρ4o +ΩέIgyL«mηEΗXzώ€3ώxKD΅ΏYπΟ‰υ=BΗaV·{ί:"O¨Α† ψ}ys?ΔΏˆΝq4Γ4"$g%S)ΨvGΑ‰₯ή|\²Ύψue{m’ωύ¦ζ'Šέ‰(PέσΫς§αΤnΏώ"3#i‘Α#ƒςP#πίڟŽβ֎·βZ-"ΟQšmνgΨ]σ’Yˆ9ϊτο|9‡†~&λ^›SΊΤ4΅ΆK»Stϋή<γ#?ŸN8όγπώΊ$FRu‹‚7 qςΣlγqϋCκ2mŸΩΨγ―­axwM?|YβΧρ«©G›zΦ–Φ6Χ‰ΤρΧ֏‚8„·Δ6©©_ θΫΫI%Σ4N¬¬eθHKΔwϊΟΕO\κΆZμ€PΙ °!°ο0©lπ~•κΌMΰϋ¨eΠΌ-iq¦O2½₯Τ[$qΐ/œέ»ζ€:ˆW’Ψx\ΉΆ%fŽB€uΟλXtΛ};ᎎπ*ω·hnfp9wf=~ƒπΧW°‹Tμ.ΤάΔΡ>=bΌ[Β(ΏψU xgΖZuλι°HΖΛQΆˆΙ#pxκ3€:‘ρƒF]FΪΞγMΦ-ήβao5©E,N:š‘ρTρΔ=;ΐϊV‘>›fmΝέύΕ»m‘—œ =‡Žοjζ~!ψΟNρΦ₯α{/ A¨έKm©Gq+}•ΥU:gΦΊ?ˆp^ψWβN™γˆ,ηΌΝ±³ΏXsΔ9ΓγΈδί>τ‘γ-σαDV>#πφ±ͺ]X$λυ•μώjΚ­άp0}λ{βv―ͺjώ'ποƒό?&ž5Uk‹›ΈΈu…A8¨Θ§^L֏ΌKΕ;{/ ψBήςX§$ΌΌ’Ž8#SίwS[tϋύŞρž•c-햍mw#.!`Wpπύ0(ƞ½ψq€/‰Ό-―jς½œŠΧVΧ“ω±Ο8<`υ§ρ;_»Υ&πN•g¨O₯ΨkοΎβζΨαp€ nΔξ¬ίψζˆ πΗƒ-/ξο5UžY-Ϊ4·ŒX±?O§^iίRΟLπg†τiΦ)Ρ'‰$1φƒ ˆ}³ο@ώ?πm―‡<_α+/WΦΎΟ«^-½Ν°ΎbϋK\£©ό«¦ρU²Y|iψ{m;$6³F­#nb0δχ>υΞxSΕ|=A{>βK³ϋΈο΅HŒ‚ xΰξ$uμ+ͺρ˜3|oπΡπ˜&;Χ•ΑVΗ4…γŸΑβ‰w~Φ:­ζ£ κπ3Ϋ­γοxd^ ΓΆ:τⳡMwğόE ZkWz~a†[–…Ξπ‘F?»Έž~Ÿ·’_Kρβέ†»§ΩάΕαύX'Œ§# υύ9λZώΗΗ?ΉFm-πΔpx  ~8όa‘xbϊςMCVΎρ]]Θ$’0ά³Σ€8οU΅ί†z‡uΕιΧν"7 ,·;’R£, γ‘ΑκO½t?t ύ[@°Τ4hMΖ£€]­βBΏzEyGΏCψVˆ>-ΨλΈΣ΄-?SŸΔ°›u³ϋ+°Ϊrzq“@½ρ/Po‚vύ€X΅›φ[0T#—%Y€?ξ’lŠ/>ίiΎŸQ΅ρNΈ|G»Hς=ΖθdmΉ*TŽW¨δΥo|<Υ-ΎιšMšyΪΞ›"ί4qςYχ32/©ΏΎυzηβύŽ«αΩlτν3S—Δw΄BΔ[7Λ!9n›G'4…α{‰­ΏeΛ‰ν₯’’;‚―`|φθEzdyΌαωfvyO·fv9,Lk’O­y‡΄KΝWφp›J†'ϋl±άͺΖx%„ΜqϊSό)ρgNΣ|¦ιR隬ž!³ΆKO°%«$ˆ‘F‘ΗΤzPΏ…Ίτφ^ ρŽ«4Χ"ΒφκP$rΔ*vŒφβ³<ΰ‹οθ±x—Ε^"Φ{βe‚ 9όΈαLό  Σ'ΑέσSψoβέ'R ½»ΉΉ·”7π».δj/|G΅π^†Όcc¨Ωj:h1)Krι*ΑR?ύ^τ[γ?„#²Σό «κχnΰ°&[’A‰2GΟ_@=+§ρv¨x#αΞ»'„υ bςϊMŒ^ζo>H“ 9ƒ΄“νΧ΅Tψ½w.ΉΰOψM±»{{kΨož¬`υ+Ϋ―] τ+Ÿ]k0jWVΦ‰:%« w|gπh‰π7†<1βkk[½ΖΊιΥΤ,“©ΎΔ›ΊΆPŒγ― ώ5ξJ6¨''&Ύrρώ§α?Ιi?€τλοψKΪζ7Šk[G‡oΝσ‘βxqμšκϋRˆΌ²,€BŽXŒr έωPc_>h~΅Τ>.x›M›YΧ•-νγ”N—˜™ΛΝ·‘_AΧ‹j:μ>ψΟ¬j:ύ½Ϊiš₯œk ΜP™r‘qΟ―ι@~1i·©γ/‡zf{4Xšξœο‘GξΑb{œgšgΔ ^|=ΠWΔώρ΅-ύ¬Θg[ˏ29Α8 υώ΅·γK”Τώ%ό4Ώ΄YΪ_>Eb„`˜ΘνZΏ΄4Ÿ ΅5Y›||(ΙϋΒ€3>3xΒκΗNπώ™§ί)υ§_>τœxxάAμyλν\/ˆ/4_Akx/ΖχZ•ό Έ²Έ»σVε Γ|Έ^₯v|?ys₯xOΔ6ZjκƒH΅Υ‹F͈…ΟΚG=ηžΥ^|3ΈXc·πœrήΚΑ~ΚΊ*o {·­XψΑͺk/«xώΛ·΅ΊΏwU9;FυQ–'ŸJΪΆπδ ΄=kΔrκΪ­{›4Ÿl›r;ŽF22p:š©ρ."|{πηΙ„¬iu'Κ«€ƒhγΪ»―θΗΔ>Υ΄•`wnρ£±ς“νœPƒθΛ‘ψ‹DώΨρGΔ+»o\ƒ*Η η—±ώُδEwŸ 5 >$ό/ΤtΝrα€–9_O–κΌ5νΊ‘ύ•e,­ˆͺΫ—#~ΥυΐηΪ€8oWZE—†¬Mξ‘aα“ ƒPΊ²βE@PHθωΝhψΒZ j6Ίί…ΌUͺίYΗ»Μ·kί6) Ruΐ#Ξp+ ρ׌τŸ 5΄υ₯ΤΆwŠΐΛΏ›γψ\{ηΠΧ–xxiZ‡Ε½ϋα₯ε΅€ύ«"ΒπΫΑΐΪqΟΆ:γ(θ ςΟθŸ_ΈΊρO―죕TΓ§₯ϊΒ±$/$δσœw―S9ΑΗΎmπN₯αί κšϊ|C.nΌJΧλ,φFΰΘ‡Bd 99ΰG4ΪόΦ$—Sρ>‰±.±¦iς#YέJϋΨ£ΖξψΕsΏ|;©xμkŸΫ~!Υ‘Ρμ΅‘†ήΦ}…ίvIf9Θ€Χ§}‚j—Η~4»Ί€–ι`–+W@…# νΘŒdzΦΏΐ8ή=ΔDe'YΈ##P/‡CPπΗΔύgΒjwz†”-RξΤέ>χ8ΘΟηӎ―]―-΅α’/ŸclώΘA»uυ―LΎY^Καm›lζ6·£cƒωЁœˆt} ϋJκMoΕ·‘NμY! τy5'ÍVζϋΒzΔSέ΅Ω²–X’Έ',ι·*sί½s Ττ L{}cGžo‰zΙiζΙ#“ΐ GΠό(Ά΄ΟΓwnmf–ρΓFF6e†kΣ«ZrRιkmψm))TN=o}[α-ΔΧ> ΅–ζY%Ι(,μXŸœχ5KCσ΅ψΞΖ[»”„€H†91eNJzΖπOŠ­Ό%£Λ’λΦΧ°^ΫLϋUa-ζr0Gώ*οΓIξόeβ{ΫΫImδC"Η Α σmΟΎ1SR›‹«;iΣο[ ŠJœ/―_Ήξeό:π₯½τϊΌ’jœfΧPhΤEq΄89n95±«΅η‹§¬²D…Œ.τΟγW77QΏ/wπؘ¨ͺiyϋߎδφχ>Χ΄™lοξξ΄{ι…Όπ\ΙΏa?ΔnΉό)ή2ώΌψ—§iV…ΕœWVdJΡ7E‹θpΈΝ3UΏ„ϋ_-tx':]”βζζκXΚ)Η;F{ρΖ΄υcρ“Jp§hΣάgJm4ηρr»ώ—I¦£πέΑ±ƒβM'Qπ†§₯λΜ5 ³­Τž`V8ωΐΰg©ό*Oψ~ηΒZTzξ™­jrήΑ*yΏh›zΘ ΑΘτφ­οˆθΝ«xPͺ“@ΣŠ“γ ³ψμ"–>d|ŸβB¬›§~»ωκ₯ͺ[¦ήZ%·MOAC.«6“ +,“Ε ŒνΗ*Xτ?₯yΎ‘q¦ψ{Vn<3β;›Ω$ΊHn-δΉσC£u< V—ΔHΆ_ψ^οU·žη@…Ϊ#Kϋx$~_‘¬Ώj:v4”πΎc±Ά½‰ζΊ[QδœzδώXxY.©ί΅Ύb―;·Ρ«zόŽ£Ζ“Ο©xΧGπϋ^ΟeaœUί‹χ‡SΠ­ξβ3Δd•-±φ€1Ζήΰό©žΧό#₯κθΗS³½ΉΔBκύ '=·dγ΅ω£IJ)μτ_˜¦γ*2ku―θlωσ'Εθ­DύœiΩς˝ΉΟ\zΦZΗ{γΟκφςκ7Vz6˜β³l27#$χθ~œV“£ΒηφΏΩ€gu¬«[ηπ‹΅ŸνKk†u)|ψn!BαNOσ#π_Ιρr«}ϊόΛ“ώo‡™ίξΠνό1αθό?ρC{{uŒ ‹™wμφρWώD[ύΕΠΕixkΔ–^"K‰4τΈBΑKΛΐΔϊf³Ύ)«7€υP ’Qxύ±\πζφρηήθθŸ/±—&Φf/Œξ&Άπ—†MΌDZζΩX£ΘΗN)~#Λ©ψnΣIΌ’Φ[–x‹©ΰ0[Θ‘QψεΌ%α€ͺΔ‹«l€:qWΌ^Œ|}αL:|΅ΡNΛ•ˆΒw|Λό?™‹γ MαMλΪV΅ͺ5Υ¬ˆ‰ηή²†`§Œzžω«ξV]ΓwRŠΪ…ΌŒO¬Mk|[V‡Ίͺ ,ΗΚΰ Λd¬?‰6ΒλΒ^Ρξέ]@μPƒEΉςJ[έώHU’‘Ονeω²d½Ίρφ΄ΡισΛmαΫ1,±9GΉqΨΘZτEP¨FζΊ½‹x^X s‘έŠφΪ1Ÿ,φp?Ολ^‘ΡάAΠΈx€PθΓ‘kŸ•’απτύoζoBχj_ήG’?† »ψ―yc&‘©…k3qζ­Ζ$Ι+ςξΗέη§·Όc-ν™Π<+£^άC%ζQξ™·J#^§>§ΧΪͺx‚ω|5ρA5}F³lΌ4q– ΩqτύjnjΜΧOαθΠKw ™f’%B’nψλΗ?u^R”ΆΆ―cžΡŒf£½υοk”ΌKα‹― i/­θΖ€Χ6„<±άK½%\ΰδcή½DΎž‘g|«΄\D²mτ$r+ΟΌWγ|O’Ι’ψjΪςζϊχΆθJ—#;‰γΫ½C±ώΜΡ¬¬·ς"XΙΘšΒΏ7³^ΣβΏΞΖΤy}£φ ΎW3όcc ξέλi6Θϋ€–)D[Ζ>ιc^} Ν†…βν |7―ά_Αwp-ξmδΈσF€ί­h|GXνόm£ήλΦσ\ψy!*QPΊ,Ή<‘τΫωVn­e«xΓ2xIh4Λ}B Χ"ΨDΕ‡`+zj ϊ¦ŸkØ֚svΡ¦½αK―ψΦΫΓ6w³YYΗΪήΪμ3€όGη\χό5/‡­τ³g©_\iήΔ²Au'™΅σΚqΗq[ή*yό3γΫ5΄Σι—ίeΈh—qAΗΰ?ZΖρο‰ΣΔΆΪtZ-­άΆp^E$χ/E8UκyΝ:<ιΓ“αΆΎΏζMn[O›βΎžŸδt/―ζΤ4_iw/i&’ΔΛ:}εzγΉΏˆΎ}ΒWw:v«¨Λ(·PάΚ$WΖ・ΠόB†κΓVΠΌGkm%ΜV’β8Ζ[cΏ‡5‰ρΕφώ#π₯έ†ƒmypX,—4%V$V Ι=ς,?:φ|›uϋϊόΆ~Wν9χιχtωξzO‡?δ^Σ?λΦ/ύW3㋉‘ρW„£Ši$Ήpκ¬@aΤw›Γ ι€Œkώ€+–ρβ3x·ΑεT._$œ ε£όWσό™ΥWψKεω£_πδ7νmδΏΤ‚έA$εΦ|4|Ÿ•8_jτ½NM+OŽ)&Hσ‡χΉϊšαόkuύ…γέ[»‚gΣ„’D›ΆΣ"»SΆΦ,#½±gh;K!Rqμyͺη*p}-ψκEԚλΓCΤ'ΉΠ~'ZK$ςΆ™«ΔbΨΞJ€«Žƒ νωš_άO©ψίCΠ­&–8γ?l»1±\ θ§ΈύkCβn–ϊ…ε–ί‹»p·pW“ϊf±ώ‰΅›½[Ε©ΆKΙ0ƒό(€?AψΈ΄ιϋn©[ηΣπό‰’|ώΛ£wωuό2"οΗ+Υ­ηΤ.ν4}5ό…ŠΥφΉ&‹ayΰ―išhΏΉΌΡ΅@Ι\Ύφ‰Ζ:Δ~t‘ήŸxΏW}Jήs€joηΗseΒ?p@’;‰f1ΧΣ?]f½–χΧτωW“Ϊ?k΅΄ύ~fN§κ§Γ­?\σ$ŽχN»γΛ;w…8lλkKβ}ύζ‘m€ιz$Ξ·7ŠΧ9ˆ%29¦―ψsΒσΑπζ}*ύqwv’I"uې?+ŸψEΦ§ͺ>‘¨#μΫDΣαά=3“ωV©ΑsN?aΏΗoΔΙ©ΎXKν%ψoψ΅Kqπ’ζ X_݈μΓ)ω·η xξBŸΞ‘ρtZ₯Ά»α+OΤ'·šX$ O fχ=qY6EΟό,X|>Ρ°ν/ŸQ^>]€σΐ·Ε¨Ηβ_„Ψ)*\8ύΪrJ=TŸή΄½8·./ΗSΖήΣcΧ4_S’β SΝK‰·¬ žr1^©\t` qŸUŸΐ·a±ήœžυΨΪΗ΄?ξε\•dηN2–χ‘ΧJ*%νeϊž{β8ΧRψΉ Ωέa­­νήuΊΓώƒς·Δšό:P<φ·wV*ΌEΘΗ+žψ…£κRΣ|I‘Eηίiω@:ΙΞqκy<{[όOΡ ?ιίΪά·$ƒι‘Z8:‘ƒŠΊJΝ©ͺrš“³n隺OŒ¬5MTΤm’cΣ՚T•vΆUI#τWΓ>ΉρŽ˜5ΝwVΤRK¦f‚iv$Kœ {TŸlΫVΣ~~YVΪΟχ#Cΐϊ½ν†₯­θΕΛέΆ˜ΎtSΉΛ΄^„χΖGηYžΡξΌwϊΦ·©ίΓo$Μ–ΦΦ²μTU8ΟO_εZ>Σξ΅mW^ρ‘lφ±κKδAƒ εγοοωVw„υεπ<‰-ξaXfwΆž8‹€¨Ηΰ_δiψ6ξHρ^‘α‹ϋΉobŠ΄ΪΛ)Λ„ΘIοΧτ¬Ο icΖΏΪΧϊΞ§|$ŽιαŽg1¬ :p;֏ƒγ[ρ†£β‰­₯΅²h΅¨˜mgPA-ΒΈ—ΊΡ¦ρ>»>₯e¨\«Ο΅J?ΊdήΑ&ͺ1nRεVW·~€ΚVŒoͺ»΅ϋt:?…φ†K=zκkΛΛ§Ά’[hέζ-.ίO_z_k- |—QCKH#¦βψόNkΒށ}’]ιΪ2Zh˜΅¬©΅ΖAωΊœσο\χ†4I΅Ώƒ’ιΡ ·.ξΡ†γ,―?cρ₯)s9{EeΝ»QΕ8₯μέί,Ύύ Έ!΄a¨^xεuηΞΘΉΒ£γ!vγπ―Dψw­Ν―ψRΦφλh’ŽŒTγ?Έ­Δ>²Σa΄ρ‡γΆΤνΠG*6œ¬\ŒƒŽώυθήšΞηF‚}:Ημ6ε–ˆŽz•½j1MςΩ§ΎOΐΌ*\ΧMmͺΧρ0ώ&kWΊ^—ik₯?—¨ά-΄Rs=ΗΏ5[Nψz–³[]Kkή#«Θίhω_‘ŽΈ?Z“β–—{y¦Ψκ\Fk½2εn–%,<ύέ;βN‘zφΠ-½ϊήΜλƒΘ9V''¦D9ύ’φ^w.|žΥϋ_+Όk¦Ψ]ά[Ν«ψ†ηL΄T+δGp!6sžzšζΌ} ‡N“€kjzEΕ©” eσ<§ ?‡λUu)tν/β>«sγ9n-εEϋ –5^γœΤϊ ΐΤ>(Y_Ϊioa¦½“ΗnZ!šε°:r![F4Ϊz«y[ώΖSN’kG;Γώ;~'ψΌž‚8ώ9\Ε¦£§xφώχΔ~$šΒ”Ηki ώ^ΥΔx9Νu>ΔΟξR£€ŽΛ\Όt―έήι~+Ρ#’?9€Ά½6b`θ{g§]Ϋ{GmφΤR½•φΌ·Ϋ} ο†δ’κΊ„ΧΪV֘’ΪθΆζd$pO|d~΅…πχE½ρf“<šΎ±¨­”΄qE ΫK7RXœη¨Εvώ Τ΄=NkΉ4(Z$ATΟφE„Iœπδγ•πQ<%pJŸΆΙΑμ΅Ÿ*œ’³Συ.0ζp‹wZώΰV»Ό[¬ψz{Ωο- ‰. iΫs('gρ₯XέxϋXΥ―/υ+Ϋ}*smook&Μ‘Ι'qωϋVΎ k[b§i°ŒguZΕΠuuπ­«ιšέ½ΒY\ά΅Υ΅ΜqVά# £Vά‘ρ4Ώΰ†‰%?†οώΝ'MΊ>,ΩΩ\_O{Y»[Ι9Λ„$ό€χΑΊ?išeΞ “λ^#Ή°·ΨΪ₯Π‰IN:šΐυ9΅ΟŠ–ZŠYάΑ`lή;w™6™κΨμ2j’\ιZG΅Ω|ee$σK6λId·3'—Ψ(ηΪ©ΖRš}TzoΉ*QQk£—]Ά4Ύj"jz-Ž©.§€‹qq’IΌ‘AΐΏJ‘€Xκ~%ρo‰΄ι5[»m* Ζi.C“’A=гΰ™λβνκi―ai>žL΄a2ΠΐιœΤψrŒΎ+ρ±e α‚G^d’£δζ’ήΛοΈS\ό±{]ύΗa‘ι‘hϊ\60K4ΡŜ<ΝΉΞI<ŸΖ―Χ%γ―Eα+)΄ϋ›Ών0Λ>œϋυι]my­ΆξΟE$•QE†QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEyΏΔmCΖWο}αί ψ{\ ˆj\€Fο—dާ§Jλ|αθ<-α?G΅;–Ϊ0ρξyfόI5·E# φ4 ; ( €ΐ†ƒΤE@ °₯’€ (’€ h–‘SŽiΤPEP*ͺ.B@1C*Ί•u b3KE"¨P€θ-PPήΑφ›9ΰΡ™cdή½W#5βž2ψy€Ι ―ƒ—WŽ9]βΌ΅»XΔ ž¬ ’?ΚΆΌαΏκ?gρŸŠmm΄ΗΖΪΪΖ<Ζ°γ¦>ΨηΤh † ±’ŠDEA„UQθ)h’€UPaT(λ€1KEŠͺΉΪ dδΰW—xηDρŸρΗΖ™΅Z}–[6”FρςNδ'=sιλλ^₯ExΟ‹γρ·Δm5t6πΔ:,ˆΣέ]έ X όͺ9ώ~’½{M΄K :ΦΞ"Z;x–%-Τ… ώUbŠ`ŒŠDEA„UQθ)h Όοαf…¨iZ·ŒdΤν―u6ψΔ‰ƒΘ―D’€T(@t–Š(€ ‘‹SŽM-RPΕ‚€Η©Η&–Š)6νΫFξ™Η4΄PMdG Ί«Σ#8§Q@"" Β*¨τ΄PR4LμE\υΐΖkψVΝΌo <²Ν%κΪ HγllrI#Œδδχο]R:+Œ:†„f–Š(’Š)«+TPΗ©“N’€ (’€ρ£]ˆι‘œS¨’€”2ΐ{Bͺ’…Pΐb–Š) ©`J‚GBGJZ(’Š(’Š(6νΨ½qKE…A  ₯-PRA :dt₯’ŠP…Q@Q@=(€‚Š(Ου=?ZΡf „ž •Ug©ΰσ^“Ek Ό±qjθΚtΉ€€™Δx?BΥO‰΅λΡΑkqu‰-amΫc–>Ό νθ’¦₯GQέ•N𦬄(¬A*  ΄QPXRPΫ‚ήΈ₯’€”0ΓG½-PHΚ¬0ΐθE-ΐQEŒ‘†=ιh ‘”67qΣ"–Š(’ŠFUb7(89 -PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEOPΥ,4ΧΆMBςήΩξdΐ%)‘ΟE\υ>ΤrŠΜρ»¦ψsJ—QΦn’Ϊ2vδ’z:“μ+/Αž8Ρό`Χk£5Ι6‘Lžl%8lν#>»Oε@=Q@Q@Q@J][O‹U‹L–φέ5“ΜŽΩ€G^~`½HΰώFΠEPEPEPEa­ιΊ†£}aeyΧ–D ˆ”όΡ“Σ4£EPEPEPEPE#°DgnŠ2kEρ†¬xfM~Ϊ䦕rσL»6…κH ‚Š₯o«X\i ͺΓwiΝœ.3„Ωλšεό;ρ7Γ~!Φ“L¦Ήšy7l!„o·€;Z+…?|*Ϊϊiχs\άΌλlKΗζΪpγ―₯wTQEQEQEQEQEQEQXώρ&β/·f;ΏΨΦmΛ·½@υ­Š(’Š(’Š(¬{iΧή$Τ΄+yκz#Ξ₯0pΑοΑ±@Q@Q@V=‰4λιΊĎ5 A]ΰP™ $δφΰΨ’Š(’Š(’Š(’«jz…ž—e%ζ₯u ₯€xί4Ξ$’}ȍMΡάAΠ:ΙŠNCΘ ϊP蒊(’Š(’Š(’›4© O,¬4RΜΔΰ9&€EUΣ5 MRΝ.τω{wΞΧ^‡j›M;1&ž¨(’ŠC (’€ (’€ (’€ (’€ +4kVg^:8vϋp‹Ξ+·ΏZ¦βΦβM=‚ŠΜΊΦμ­΅Ϋ="Wa{vŒρ(^PIΙ€šΣ‘Ε­Α4φ (’ΒŠ( Š( Š( Š( Š( ŠΞΥ5Ν/J*Ί–‘klΜ2Y±Γ­&™ι:£”Σ΅K—%#”όΊΥrJάΦОxήΧΤ’Š*J (’€ (’€ +6-jΞ]v}!ΎΫ bW]Ό=9όkJ›‹[‰4φ (’ΒŠ( Š+;UΦ¬τ»›/–KΙD0αs–>Ύ”rvBm%vhΡE†QEQYΪώ±i‘i―}¨3-Ί€ͺδδœ)€δμ„ΪŠ»4h€V ‘‡B2)i (’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š+Κ~9Θ[ΐφƒBκΥε?Ώδ-ΰϋA‘ ΐύ οu‰΅OΨb 4ρ¨Ζa‘Srqϋ²½TsŒŸZυΟ ]κχΊg›―ιI₯ή* I–Q΄t9RGα\ΗoωxώΓQθK^±@tž1’ΫβZxZϊΝb†ζΫν—AΦγͺ‘Ψ‚τυ£βŒ€π»θφΆVk}¨κ—Ko φŽxάN=H¬Ž–3[ιz_Šl›έ εg8κΡ―Σ₯gxzκ|c}bέΌν'C³E·nΖiW$ώ‘ψPχ‹> έΪx˜xoΒΊ,šΦ΄±ω³ Ž(ύ¦?Ԏ£½3Γ?―dρL~ρ†ŠΪ.«:y–Μ%E0τ ;ρκ ΙψjρΪ|_ρύ₯α };Ε4;Έ/8φ|^x~ |?²΅`Ϊ’^<Δ/,‘|Ή'Π~†€;ύk˜·aνv²¦m yώ,qω₯ρΦφψIΌdLηTYJƒΘ]Κ#ί?₯tΪ·‡ξξ>2hzκ[³Y[ιΓ$ΩW%Ά_γ5ͺ|T»‡ΕzΏ†τ­mGVΆ™c·Ž'ΐ‘vεΙα@γσ―T―$ψu gγOΔ Šƒ"˜”7  gωPώ₯γ›Ώ x)5oi_dΥe”Ýo*Θ9?( δφϊρX²όGρ‡%₯׌Ό&Ϊn‹s"Ηφ¨ξC n›ΤGγιY΄LSSΑR‹³cnΊ€οfρnω\9γΗ±­ wᧉuύ"[Sβ άΨLΊ5pΨ ƒ‘'¨λH²Ζ’FΑ‘ΐeaΠƒ\Ά₯βΖ³ψ…₯xhZ«-νΌ“™χr»sΖ? θ4{?μύ&ΞΜΛηy,^f1»Εy―Šaψωα&”…Yl§D'»`ρ@_ğ·ƒΌ?€–«t^ζ;}…ΆγvyΟαTόsγy΄ #M΄·Τυ­S& q EUΙf?_ΠΧ5ϋIίC„4»Fuσξ5(J&yΪ‘‰lztˆ£Ζž ΄ρu›'Ϋn4ύVΕwΪή[Ÿž<œŽγώ4†5ο\λieβ? ₯³£7Ϋ!ΊYqΨ€IΙό*?κ–7~;ρ­“₯Υ€‘ ξόΧ\‚ή˜¬O ψ‡Ε>ρΕ‡„όa5§όnΦwπvŒαΧθ?ϊζπγώJΔoϊνώ@τΏŠz߈f»²πΏ…^ϊϊgŽwyΦ8cPΔ/ΜΨˏη]ΓΟβ_RΠυ½)τsO₯€Έue8δυ½sXΏ³άHšˆ]@ήϊΝΖγ델₯±ύ’υ,q"2}ω  w><Φυ_jΊg‚΄΅δ0άέ\ά“ΜQGsΑŸ|y―x―Z»΄»Π ±‚ΖC 㛐^'ΑΐΫά:τOA›_πχΔ_ιž ‚ΛT΅’ΰ]\-δžO‘+δ•?0τχᇄοό>ΊΆ£\A6±«Οφ‹oŸ-1œ*η2hΉbB’O§­yu獼tΆΧφώtΣΰάΔOv’fQΤ„λΫ¦>™ΫΖΪηό#^ΤυžΦ‘Xϊn=}²kΟ4Έμ TύkΥo―,ΒέΛ$GNϋ;6FΣΟπ―πό›6Ή^χϊ h|@ΦoŸΰœ ‘θ •w` ΟΒͺΪ&GΚςΩφ«±γ /‡+ ‰-‘ΣΒΫΚ—ρ Ξ\Œη§8λI¬Ι³―ύƒSωŠξtοω%ΠΨ'iPžώΞ—ZΤ^±ΆώΒ†=F–FΤ…ΒngΙκ™έΤc8ν[-ρ_Φο/ό.u]6ΞCέΛp± Xu ύi> $ό†;lωο Ǐο|~΅ΗόπώΏͺψ.&Ρ|lϊdqJι%’Ψ,†&Ο9%Αη―JυOψζΫΔήΎΤa·{{Ϋλwe!ω’‘A8'ΠγƒώΗhί΅XDήπ›ίά &μΌβ8’mΔ Δn%@?kx_ΐ“ψBΣΕχ·zΩΥnuH ΚM°‡k*ΉΟ sήΤίΩγψ[bθ 4³ΞΞGsζό€  ?xξmϋNΡt­*MWΔwΙ½m#p«Η,ΜzΏ–r*Ÿ‡~ j#Ε0x{ƚφ-ύΪ΄‘&Ε6?„žˊγ‘ΧϋeΰqΠGόGβ¨~/x~ΞΓF.°,νioφΕQx ΰ»s…ΖήZυΟ ]jwšDSkΊrιΧμX=ΊΚ²…πw/#ΌλΖ„'Ηί k0ϊαλΦh“ψ‰γkOι°K-Ό·—ΧRyVΆύι[ϊΞ²|7βo^kpλ^ [>αˆ7 vŒb', “ΫZΓψŸ,V<y¨°M=ZTήη ²…Ιϊ•―^$“@7‰Υ-ΒΖf#©E$gπΟτ¬‡QO7„>%ΕiŸ΄=υκǎ»ŠΆ*‡Β/x‡Vπ5ŒΪ'ŽžΒέ7#Z%‚Ώ’Ω9οί₯z6‹ρΣZπ‘β(g°ŠCqg!ΓE*.Jύ}ώ’Ή#β_Še$Η­:Ϋΐψ3ΐΎ;yυ“ͺM¨ΫK4φqΖωΰ3uένΊΡ$_ Ό<ct,Ηά—bhχΓΟΓβύβρ­žΖκV‚ξήCώ©Χ“Ο₯rΠ|IρΏyzή π£jz]€¦&ΊšαaσXuΨ ΧΆqš£ΰδvψ£ΏΙκc5·ϋ=Mm'Βέ6+r’XT;¬žc sŸ΅―ψH>.xΟQ6“ΩI%½ΊIo8ΓΔθ2Ÿ‘S]n»β_¦±wi x8άΫ[œ «‹΄eγ?($\οΓϋ›YΎ8|AšΝ•αB NAeP Mπ~₯γˆφ—ΝΎΏ€yΝ6πZ¬²½Ω˜ŒσŠμΎψΡ|[¦_Ι5”–ŽŸ1‚κΥΞJ0CΟδkΡώ,λ^%ΆςΌ+αWΏΤcfϋH3†…Ϋ’qš­π#?ΫίΑ½kς.£δ€ §χΏ6Φ—μΥ qψφEPMJmΝάΰ(κ:l—ιΦ²_B°]ΌJΣD­Ž@ά χΑΘ©₯,±»"οp œdϊf‘šφΦ ˜­ζΉ†;‰ΥΖΞ?Πu5b€<EρWζψ₯βo³xt\άΕ Q5ƒ_’­²!‰ΪIΞxυ«uΩ4?‰ΎΥ―,f’ε-&έgΖWB‘οσ0­o0};IΊ˜B.bΉYLDτά?ΊΟψΞΧΒZU½Α‚KΫΛΙ6v°ύιœϊ{{Φν ψex{‹›r?οκΧ'ρ‚ ™£4Υx_Δώ ΉŽώϋΕzθZL0yρΚσ«»α”Ž=@n/‰^)Τμ%ΦtΙsαψΛšK…IeEκʝ{vρ§γSΝπΟΔ lΙφbp½Hgταο†ΌKͺx+GΉΡώ Ό6FΩ M9ΙΐΑBwςAβ€:/ήEρ/ΰεόžη{ΘΣlΦD‘X‘ν‘ŠŸΔž-›ΑφΠτύ.MK\½…a‚Ψ8EA,Ηόυζ΄>ψ3ώ} m4j_Ϊηi|Ο'ΚΪHcqτ©<}ΰ«/­›=άφ₯‘2Z^[Ά"qž;ŽψΠO kώ2ΈΦβ²ρ…#²΅‘Xύ ΅‘‘“νΪ»Šς}Δ*πΏ΄Ο xΎ{]VΫQWϋόCl™^Ξ?Ο^¦½]ŽŸAšα5οψΖ=fκΟΓώ7vΦδ΅ά]$I/ωA ŸJΉπγΖ£ΕΦΪ„w62iڝ7‘wjν»a9ΑΠαΏ*γΌ)©xΓβ2^j–zτ:ν 0Cj%•‚ž¬ΜFωΕVψ |qρ Zύ΅[ˆΊ )_›г όVΧ|Q ±x_Βmy{Œ· χ 1ŒόΏ3c$σΕu_Όq7ˆυ OIΥτ·΅½;kvpΰ©θΚGωι\ΧμΡ―‚υIΫT˜κ¦?™«Z΄ˆqΖt¨‰Ύ–€=J«jޱi—rI•fFθΐ)ΰύjΝgjΣE>…¨΄€Š •IF΄ρΕTUΪž†„υΝ:Ε«hτλΡάΕΘ\1z’fΪxΏΔΪ”+{₯ψU€Σ›”i.]‡¨C\ΔΙ#ό€Ζ U3ύί4\W«ψzh'Π¬$΄e0nmWeXƟ4­y­oΠγ₯)Tεν’zXΒρŠμυK=#JΣ ξ­<>{Dd‘/»½εVό;ͺkΧW²[λz ±UMΛ2N秨ΌUαXυ»ΘoμοfΣυktΫΔ\όΌœ0ξ95αmsY·ρ4žρΩηΈX<ψn γzη0υόͺ9a*~βWK]οςθ_4γSίnΟm­ώgY¬ά]Zι—iφΏkΊEΚCΌ&ξ}O σΟ†ΊΟˆξ,€ώΚ6’]ΘeΊ{•2yIΙΕzeΗϊ‰?έ?ΚΈ―ƒΔ L[ɁœΤΣiQ•Υυ_¨κ&κΖΞΪ?Π±ψΊκ=uτ_鍩κ(i‰p‘ΕžΔžτΎρtχηφ.Ώ§7Sd/ή%“΄ŽψΙό++ααή6ρ…΅ΡνξΌΤ ΤΖKl£Ζεn>"ψJ R ΤR™$ΫΤGΤηπ΅φpζφVι{ό―χϋIςϋKυ΅ΎvϋΟD_[Φ|A©%¦αγujΪecFΘΞ}:WQ^u£κ^!ρ•φ£%†₯‘¦ΪΞ`UX’ΉΞO…ήςv²οΠή΄­h«έφ·κoψCΔο­Ν}g}dΦ•“šΫ‡=5™?Œ΅;ύVξΟΒΪ)Τ#΄m“O$«nξO5•ΰxώ x¦'Ύkω(Ρ €XΟŽ:~‘πm‘t 菡Εy œwΞzšήtαMΚI^ΦΣ[kψœπ©9ςΕ»oΫ§ΰexcU“Wψ―4ΧrΩ\ΗcεK„¬cάr9ƒVρ}λkσθώŽ₯ulΈ‘€ gΣ'½fXΛΏοΌ‚€­YώπϊbŸπΌ€Zχ‹­ζΐΌώΠw`x%w6ΣόjκF?iκM7/=δυ2"Υξ΅O‹~MGN“O½·†d’&`ΐζ9*GQ^±!eŠ.搹ΖO₯yΦ·$/ρ«Γ©S"[Κ$ΗcεɌώθυ†%§ΘΆŸ«7Γ&ΉΣwΧτG“ιzχŠ$ρΖΉδθΒy‘#F΅k΅ €1ƒœsž=k­ρ/‹GώΟ²‡O’σ[ΌPR6)Η9oAΟεY~ |Rρj“σˆγώ΄ΙΩm~4Bχd*\iζ;rέ7η=π m5OXνυΧCΉFKy[ΣRΔ>3Τ΄νNΧΕz/φtWm²+ˆε oFΑ8όλΊ γ,‘ Am‘φΉξ£/ρn’ΣωΧsj¬ΆΠ«ύΰ€+žͺ‹„f•―ΐθ€δ§(7{XδόSγ6Π΅λ}54ωo%Έ„΄Kω™σ€ΏNΌΥ&ρ¦―₯jqψ›Aϋ ₯ά‚$ž9Φ@¬zgΡ«"ΏΕύ°­œŒ=#ϊΣΎ1Ν™ξ5HΗ«hFα‰nc9T΄ζ₯³6ΌaβxΌ; ²-Ό—wχo²ήΪ3˞ηθ2?:Β“ΖšΎ=»x«Bϋ Œξ\E2Θ#'ϋΐPψ ‹o‰ώΉ» ZΌ θ$ΙύyZΠψΑ4ψω&+ζJΘ±ΤΆΰxό₯Nχ γ~nΏ;iθœύω)[—§Κϊϊ—ΦΏλέ©Ζ4⠜owϊΨ%)ΙΝ©ZΛτ7­.#»΅†βΊ)P:ŸPFEcψίYmΒχϊ„ct± XΗϋlBΘœώ‘§ΪkW~ ππΠ΅(l]m"2bίΈlͺ^-Ρuۏ‡Ϊ­Ύ§{‘z₯gŒΕΟ•H$`u8²…(ͺ‹™«_o™€κΙΑς§{oς$πo‚΄σ¦Ε©k°‘©έ¨šI.>`»ΉΐŠθ¬|3‘Ωji}cao©Pьp}ΊUo κ~$πΈŠ\†€C2£aƒτBλC·ποΔ/ C§ΟvcΈσ ‹,ΜΰΰqΧλZ>z“”e&žΊzΉ)Ζ2ŒSZkκtή$ρlΦZΔz6‰§>§ͺ²yŒΒ$kώΡ?ύj‡HρΪλ°θώ%Ξ™yp3¬γϊdt5GΓLΆΌMΙyγα-όI΄tϊJβ‹$ϊο…-` ί}΄:…κ©ΖOΣό)ͺpζTνΊ½ώW©>WRϋ;[ηcsΕ~,:N‘m₯ι–O¨κχ ½`F }Xφθ*₯cγBΣY΅ΣΌS€f½ΩΫΙ(’6nΚHΞj‘fVΧγ]ΪΘζΕ~Μ[Ώ ?ο–§|c+5†‘g nšυ<>πχύE§ Ζ›[«ίϊμ©;J₯φ{]ΝΏψžm?W΄4›ΏΥ.ΈBαwcX©γΗβ84K­ Ω/e_1qs…dη$ύΥŽMΞ›γνϋDhεΥnch ¬ά#Ζ$ξΟ?JΡ4-cQρt> ρΩmΝ¬F+{kw/Œη–oΔӌ)Ζ RKUη{œͺJn)½ώV!σ ‡WΟ_°Εό–jή-Ύ}r}'ΓZQΤm†n$iGώξOz©¦ΙcΦ?λΖ?δ΅ΝψCLΥnόCβh,υφΣ.VωΪHΎΞ$2Η Λ*Ή#/z]"»ώ„σΙ{±λ'Ϋυ;Ώ x λWz~‘fΦ½―2Ϋ3nΚyOqΟκ+¦bIb’kŒπƒξτοΆ΅¨k‡PΉh %MΈŒ‘Ζ9 zcΊO$’hZŠ@ •­€\ν8Zͺk‘θ§U'5}kύv8υρΎ««έά/„τΏ΄Κ5Μ²¬jδw$ŸJθΏ΅΅8ό3ύ‘.‹)ΤFΨcΞμuύ~•‰πjh$π-€qσb’A0ΕΙό«?Ί|όΨξC=7MΘmoΑδt:ŠϊW?ρ3NΥl<0$ΥόD׍$ΘΈcV9ΟηŠέρό…<_ρJΦ0Šqœm­φΏo3)NMJ2Ύ–ήέόΟx hrΪYΪZIͺ]œAl‡ή'°¬έ?Ζ…Ά·k¦ψ£HώΝ{Ό‹y’Q"3t‘ŸηX^.ΆΊ—βΆž°κُ5‘X. Aώnr :֝u]F{'Υ»δ£γό΄£άj`ώt‘ mΒ»­Η)Ξӟ6ΟckΖ>)Oύ’ή Y/u+ΖΫ΄gϋ“ΨWρ3^ΦdπΌ–:ώ†Φ&wCΡΚ²! δ©Α88­ύ}’ŒZ·x=«€LέαΈϊσϊŠ“γt§‚™$+ζΌιεƒΤyΗαWAF¦Ήnή·ω‘]Κp¨οkio‘ΤλZ…杀E6Ÿ§K¨ά6ΤXc`ΈΘκIν\ΩρŽ―¦jV0ψ—BVΧ’’h§Y1μΨΝMβνwR΅Τ4]D0Εy¨ƒώ‘0ά±ͺŽp;šδώ$Xj6ϊ8Υ5χΤ%’υ Γδ,``°Α'Œγρ¨‘J2²šZί½ΘΊΥeΈ7§₯ΏΜνΌgγό1¨iΠMlσGv²§-•ΖςMEgβmZ >RρŒtν>|ΨΘ”;ΉΞ‘םγΈ_ˆ Yeσ%8>Ϋ+·Υ,­΅>{;Υm2μpN2½fύœa Η}ώώ…yNv{mχu8Λoxκ+ϋo +ΨΚ’Dι|Β‡qŸOjξ w’ήDςέ”LηiΗLךκV> π ƒ^iZŠκ%Ύ7Ϊ]8ωXυΎ†»ϋ-RΪγO²Ί’Hΰh­ΘΰHΞў¦•xΖΚPJήWόn:•άfέόνψX½EW1QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEβ― Xx–γHšώK”m.νo!°N@lƒ‘ΗlVύΟψ―Βv'›J“P’εMΊ[Έ|–. 6AΘγΆ+ ’ŠβΎ'x―AΡΌ/¬[κW–’ά΅»D,ΌΠdveωFΠr:ƒŸJ₯π/ΒοαŸΪ-ΤF;λΣφ©”ŽWwέSτ\~$ΧMwαήkΫzEœϊ–Tύ’HΓ6T§ž209φ­Κδ|eΰ ΕWp_\5έ–§ΔwΆ2ωRθN#π¨όποGπΞ£.₯—š†«"ν7·σy²θΌ?Ÿ½vTP#γ_ι>-Ή΅»Ί’ξΟQΆŠςΚ_.E™ΑΘ¬k_ƒώŠ{K©ξ΅K­Fήε.…δχδbΌ„$6η°Αχ―G’€ ητ_ Xi$Φ5»i.ZοT*gY]£hψ“]™β= Nρ“6›¬Ϋ-Ν€½TπAμA‚=Epp|£)λή#’Ε+hΧƒΛΗ§ ½>ŠlH±D‘§έ@}s~7πN“γ-ΧSΕ=³o‚ζΩφKφ8?ΚΊj(ΜαLψ~h$•ξ―¨]³![»›ςFΒepΖΗzέρ€μ|O=Μš†§§έΪ!Ž9¬§ςΞίCΑΝuτPα_‡:O‡υs«5Φ£ͺj»6-Φ‘?šΘ;…ΰϊΦ‹α[#^ΦukY.ηUeyΦF¨ΐΪ~$Φύƒα ΨψRΞξΫN’βHξn^ιΜμ‡ld ΗΗ†­-|O{β»΄Λͺ5Ÿ!ά<Ά 2ΞIχ–ŠωΏΑ:7…Όoo{βxmυΫ‰›Ο·K”΄ΰ Όΐκm|,ιίo΄Ώj·šŸ†RΜ½ΓK'›rδckcΟuλŠυSΐ~Υo^σPΠtω\ξy @>§OΦΆ4'OΡνEΆ•eogoœωpFg׎τ&§cm©ιχWΡ,Φ³‘ŽHΫ£)―<Σώ h6’GΊŽ΅w¦ΖϋΧNžλ6ωτ*Θφόσ^™EbψCΓV>ΡΖ™₯™¨‘εR ŽHJΠΥtλM[NΈ±Τ`Iν'R’Fύ΅Ey—Α½ΪXMCZΉΣcmλ§Mw›~ΉΑPGΆ~Ή‡Kπ•¦x&σΒΦέfά¬ˆμΞ¦@ά}8Šζξ|§\xxUεΊp€AΌ:ω»GΎάgπ­Xt¨!Π—IVΫ-ΏΩƒ7mΫ·9Ζ3jΏEbψ?Γ–~πύΎ¦ΌςZΐX«NΑœξbNHwτ[[ψO’ίκσκZ}ξ©£]\Σg\yk!ξHΑηι^‡Esπ^ŸαέϋO΅ΈΎΈΉ3Οu7™#»sœ`qνW|α»? hil“Ιk ;+NΑœ–bΗ$:ŸJΪ’€9xFρŒ«©qΜ7Vο²XΎ‡ΣΨƒYψaa€kΪ”ΪΞΉ©OlwB·—[‘OϊŠΐ΅π­·Œ―|K—ώξ·‘ ,*γΞxυ€ρ?„μ𽏇οu{«).MN΄L%`@lc €0>Ή_RψE’\j·7Ί}ώ±€}©·O …Ο—‡ΉΑό«Ρ¨ OΒ^Ρ<'ͺ]_h©AΐφŸ+Πθ’€8oό4|E΄·š–—ͺlΙqa7–eQΐέΑδ2;}iΏ‚τχΧ|?«Iqzχz$ oi‰B„ΙςδΆrζΊj(Ζ³ρf….•©I˜·[π₯†³β-YΊ’εn΄¦fc`‹uά$ώWAE6DIchδPθΐ†Vzσ[ƒš(Όžm'TΦτˆfmΟmeuΆ<ϋ ze‘α_ΩψgGMΣήααF,^y7»1κI¬―ψΛΕw6—S_κV–ͺR9¬gςΞ$k¬’€8Ÿ |7t`j]jZ¨«±.u 5£φπ1ϊΧmEζΧτI5+«›-KZΣ ΊrσΪYέl‰ΙλΖ3ƒυό«’π‡τoίjW:$rΒ/ΔBHK‰ε‚ή3“Έ“’rk§’€9οxNΓΑΪTϊ~—-̐ΛpΧ,nY·0€8ωE>ΧΒφ6ή0Όρ$r\ϋ«uΆt,<° ‚Ξxυ­κ(C£#taƒXπ₯–‡€ήιφΣ\IΫ»;Hΐ‘ΈcŒt‚Š₯9%dΙpMέ£'Fπύ–• .yμ‚²œ†,’AΐΏ₯s_π¬τ΄w[mGV·΅s“mΖιΣ8שΪ{‘*4δ’kc—Χ<iͺ^Ev—ϊ•Δq,;ν§Ϋ•3ΕXπη„τύ ζk¨žζκφQ΅ξn€ί!™γŠθ(€λMΗ–ϊ Q‚—5΅ δ`πŸk­6‘ay¨Z—Ν{hfΔLέyι]u‘RPΏ+άr§Ϋ™lsΎ#π†]Ηy#άΪ_Ζ6­Ν¬›‡ΤRψoΒ:vƒs-ά-qu}(Ϊχ7Ro“€φΠΡOΫO—’ϊ ΩC›šΪ…q·ίtۍJβςΦσR°7tΡΪΟ±χγ­vTR…ISΦ.Ý8ΟβF‡ό'₯θΣ\ι‰$M4K!l―˟›Χ'<’k?Wπ›©Λos§\Νώ΄ΩΝ°IξF5ΧQT«TRζΎ’t`Χ-΄9­ΑzV‰ͺ%ύ‡Ϊq …·Ύα&I%Ϋ#%ΉυΗŠgˆ<§kφ‚Οyc­=€› ~ uQνͺss_Q{rςΫC”Ό €ιš­–₯έ½νΆσζΛ c)e*KρΟγŠ*gRSw“ΉP„`­c–ρ‚l5Tjks{c|T#Λi.Βΰp3ΑνΕ[ΦΌ+¦λ:e­π™šΩTCp! ξυ8ηŠή’ŸΆžšν°½”5Σs“< ¦ΨjQίάά_jWQͺkΩΌΑΈΧYE§RSw“ΈαΑZ(ʟB΅›ΔVϊΣΌΒκšPΓaF3ŸΖhVΎ!±ŽυζHγ™f&ξ\γ¨Έ γπΕM£xMΣuH΅ΊΤ/o"VχSξΫτΦΊΪ+_¬UjάΖ^οΚ`x—ΒšvΏ$3άνο!Wslϋ$QιŸJ‡Γή Σ΄kγζ]^κmryŽ£ΡxβΊZ*}΄Τy/‘^Κ\ΦΤΔρ/†tοGΫ–Dž˜!m’Gτ5GDπF¦j+¨K=ζ‘|ƒΛy/˜cwŠκh‘Vš*z₯.f΅<£\ŽΗğ/lωΗς―VΥ΄-/W*u; {–^€@HόzΡ₯h:V’Ε΄έ>ΪΩΘΑxγˆϊυ¨β”RZθΆθsK ΫoMχκGƒk‰.u΅yΎΧ™-ΛΜ­§Κ&‹c οdr>˜­z):Υ»`¨Α+$cψ—ΓšwˆνRJ&&3Ί9cm―υ±΄ίYΩίΫέMͺj׍nΑγŽ{Œ #§WcE­8Η•=*0”ΉšΤΙ›A΅—ΔΠk¬σ}²slͺlΫ’rF3Ÿ˜χ£Δš―ˆ-`‚υζD†eLL,:g ρΝkQRͺI4ο°ά"ΣVάΗρ7‡4Ϊ$Š>θΫtRΖΫ^3κ¦Ήχψi€ά[Ιύζ§xμ6€³Ξ’μρωξ(ͺ…zV‹&TiΝήHΑρ7…΄Αn—†x₯·9†xk§γŠΙt‡Œ}γP»Ή.g˜4‹΄ηhΘΐΌWiE―R*Ι„¨Σ“»FN© ZjZΖ™©Nσ τςΖ ŒΨΞαŽzv"­k:lΎ™=ήρ Γ cm¬9Οπ«”TsΛMv/’:ιΉΓ§Γ‹Ψ—Ϊ¦±{j€o=ΞPγΤώwΕήόO>‰%ά—6Ωω-»…|Ώ)γ§Κ?_ZκθͺYΤψ˜‘N0ψPQE™aEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP^Gρ4|MOO/„&4d…XgΚΘ`>oΌ3^ΉU΅?ωέΧΠM|Αΰο|Uρ„—) κ+;[2nŽΐ9ΗQμkέΌ+βx­m4ΝΕZ₯ͺψ©‘V{rΐ39ι€8δc₯yμ—Ύ#p6₯ύ£μδΠόsαΟΫ‘πΐlόΤγ΄ξZο‹4ζ;}gU΅³žDσ%lΉ#?˜5cYΧτ­Ξ+­Zώ [yH $€Ηγπ―–ώ$¬Ύ>ρΏŠ5 V-m£Ψ« ‹΄}3šg΅ωόe ό<ΠνΫ}ΛB°Έ'“&%IϊνΟγ@«ρzkOPπνލγ+=&ΞDή©$ΞhέχΧξτζΊOŠ_‘π'‡νδ‰­οuIJ*@ο‚ΛŽ\ΘW“ώΡφQiΊΟƒ¬­Ζ!Ά΅ φV*³ϋNh–iϊ&³u’!–]μw"ΗΐۜΐP²ψ_Ηz»§C,z₯ΊΛqsΙΔ9ΆIμ ΕqώψΡ₯j^+Φ,u¬μt»RE­ΣΘs>Oz»ΰ―…ώ„NΦ_μΆί©ιπ‹£φ™y‹˜gŒWό πn…βλΆZε™ΉΆ΅BbA+¦ΣΏT‚xυ ©.5}>ΫK•ΕδX'wH=kGρη…΅‹Υ΄Σu»)ξXαc‚ίLυ―ύ₯nΪΧ\π†­„©€ΪΪ€‹lIbX―~€*ΰgΤΧ!γtλΛ]<ψOΑϊή‘{nFω˜Hώ`ƒμΩη"€>ΈΧGφΕό~y+šΨήG§ηUΫΕΊ λ±θίΪ–ΗTsn­–Ξ3Ž+ΐΏhΛ«οxξό2ήΝoζLvŸ0Ζ…ΈνΞkΌψWπ£Iΰ|Gw=έΦ³$Bΰ³Iς"tΖ2xnΉλ@‰£ψ£DΦoξl΄½NΪκκΫύlqΆJση[5Βψ'αŽ‹α ~χVΣ₯»’βδ 3‚¨ ΙΖΟ>΅Τψ’κK/κ—P­‚ΦYSκ¨HώT»°›²ΉΜίxWΦ5Iτ Cn"Άb—…Ο1£wU©όκ°_ΔΕ¬ΌS€κW Ι΅xC{eN•`Μ’Yό?πΆ—k)5{…K©“‚C‘Ÿ~?*Πρ…£θ~(π…Ά—kΌ]1vRK2€>ρ=y5θ¨F>κ]ϊ_nπ=ΚRχŸ—[oΫώ ΨxKΔK―[N²ΐ֚…«ωW6ΜrQ½p{W£OβΟκ:ηΨ5θ­"²½’έ#{en8η•Ή€ν…©|lϋ"ltσ;gίn+•π~©­Xκž'GΡN’―©ΚZO9P!άx9©„ζpKdυΆ—υ*so•I½ΪϊΫΠι|'β b?\xsΔΒ //:˜FΡ"χΘλ†Ί™΅½2f–kϋtŽ1HΕΗΚίέ>υΜxW@Υdρ=ψόEδΕvρy0ΫΒwΧάϊρϊšη<αλ-gΕή'ΈΥ"0Ϋ^ΈŽ 9s3eŠτ'TΝ97+ΪΙ^έόŠ…J‘J6έ»_·™ιπκVSiβϊ;¨™„Ϋ€\g~΅ZΓΔ:F‘qδYκ6³MΩA“τυ+ΖφPήxŸΓD[}&RσI #b°P[nnηV~"ψ[JΆπ­Εφ›gε€C5ΊΫƒΠ‘Χρ¬γFŸΊ›~φί}΅.U§ο4—»Ώη‘άέ]ΫΪy_iš8ΌΦΨ›Ξ77 χͺPψ‡Hšσμ‘jVsΎXdŸJσοˆ’Ι¬ψ7+2IyufY'υ«|-£ιΎž}>Β {›?-£š5Lξ–κzχͺ†κ“Υ» Uηο8­ΉΫ]ψƒH³Ίϋ5Φ£kωΖƐΏ₯i«PΚAR2<ΰμό#£Ιΰ0nl‘šξ{?>K™4¦F]Ϋ·žzšΕ:ΕΥ§ΐψc‘„εσΘφυϊTϋΛH>Ά·”ušιsΠ[Ě*έύ™΅KA>vμσG_J‹Εώ ·πζ‰q{3FfT>L,Ψ27@η^l!…Ώ³“ΑΊ»\xΊϋ 21χχγ= TΪΜ3ό’]rΡΖ£k²4{˜±*/œƒ‚FG}+U†‚”o΅μfρ3q•·΅ΞφίΔZ‰3Z]ΐΧfΝ¦h£|²|ΌώDβ±>x†ΞΧΐΊTšΞ₯O/›Μς|ΝϋΧ―=«WL΄ϋ? ‹KX.$Σ°ςΕ «6c䁓Ο5Λό#πΆ•qα8u BΚ ΙξYΐ7$ͺΕp τδψΤςΣφrήΧ_©W©ν#΅μCm. Όf΄š9’nρͺš–Ή₯ι’,z…ύ½Ό‡ΰΚΈί‡π¦•βiΆΉ[+yVHβΞBdgσWΑΊ…άWΊž―α½CY»Ό™‰˜ZyρͺφUΘΐΕ%…MΎ©[ρ‰v]έΪ-ξ`ΉΆ[‹y£–#dυ¦Ω^[_AηYΟρdθr2:לό9KΛ[ί[ ?P²ΡLΦ±έDΘœδ ž+OΰΗό‰)_θU(();νoΔΊuάάU·Ώΰvq^[Ku-΄sΖΧdŒ™Aι‘T/|G£Xά.υ+X¦iGΦΉίΌTͺpL ϊq\ξ˜,Ό&Χ6ž1πϊΝΣ³ Lΐ&Wπ‘Η8x·mτZuΤ™b$•φΥλθw~4Φ^ΧΑWϊžst@c™qχ€>ή΄ΒDšo€¬υ½MŒŽlβ•π0d‘”p>€ΦGŒ—M_…7ίΨb§ƒEδύήdώΉ¬/‡? <4Gϊ°-7ύ<ͺͺT£5Ώζ·™5*Κ.R_Λ#ONΆρ·ˆmWP“XƒHŠaΎhΰήBφΙ5cDρ΅€x–Ε†ΝΘ&φ!΄IŽΔŸΗ5έΑ³ΘΚΗ—΄mΗLcŠΰ~)νKžYHώΡ]Ύ»xΟτ©§5V\Ž*Ξύ6ΰιGIέ[η ΡEΖvQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@A}Kcqc.ρ²¨υ$TτPŠώΟρ„nu§ρŸφ5ΈHΔGΎMΔΟάcŽ£­uό'uβKe¦@'Τa™'·BΚΉ# Œ±|¬zšοθ ψ'πηTΡ|?βX|Qkφk½Q~Ξͺ€‡ΛΨrΩRG%ΎΏ-rίώx—HρνŽ₯βM7μφ6Jοˆ€Λΰ…V'Ή?…}'Ex§Η―x‡Ε^!Πt?νP[!·m;σјΗ₯mόnπ>₯γΨA€ͺ6‘bβA Έ_0mΑPOύx―P’€<›αψ‰os‹l’ΆΡ­-D111—f\ΞΦ$π:βΈ;oόFπ7Œυ;ΏΩCyovΜ©)xΚ”-ΈV`Aτ­γ~k>1Ρ΄]V!‹Ε6P*L…‚¬œξΐaΐ!³ŽάΦT7Ώn-γ°e₯³έαΘk;θ {Ν㟴ƒ­ΣFΌΦΏ™ŸανΟB†e΄σ^Yί̚iŸ|’7©&±Ό£ίi7^!{ψ<₯»Τ$ž½[rpx'uτVΦM4ϊ›ϋ(έ5Π+π&₯κž$šώ*;ΛΓ,zΆυΛsΑ8κ:ΧaE(ΝΖ.+¨ε))>‡'γ―ήκRiϊž‹$iͺιοΎ!' ξ€φΝbλ1x»Εvk₯\ι1i6r0ϋLν:ΘYG8P <Χ£QZCβ’²vΫΘΞt›wjϋωœ_|?uuaαλ]&6;ΨdWlj0O$gπ­ˆzmή―ΰύBΗN‹ΞΊ”&Δά8u'’@θ ttTͺN/Ά₯:1|ΛΉ•mi:xZ6L\­šΔS#οΖ3Σ­sZ?„ηΉψgͺ§ΩJΆFΰϋq*r ΅wTP«J+NχJ2ί΅>ΣυiVqΨOαψ΅…B%Μw(ͺΰ …lλΪV₯β?\iχλΎ§q%Q²ŠΚα”gώuSuΤ”RiάJŽŽ-ΆΆ8ΏMβ9΄©t½[D«›D“‰Ρ„ŽUάgžœU‡eޏΰέ>ΗQ‡ΙΊ‹Μή›ƒc21‚GB+₯’‰ΦrMY+»_xαK•§{ΫOλξ9?hχΆž1ρ%υΤ-/3 οSΌπGγXšvŸβ_\][hϊtzΆ4†X”J±Ό$φδτόλΡ覱[€Σ·ΰK ΄³i«ώ&†ξu»τ»mN†Β3΄CJ$b9έΈƒL~5Θθ6ž+π|W:eŽ©fΣ4N'Tΐ=˜šτΊ)*ΦΏΊ¬ϊLnν«Ίκp> Π΅έ?Δϊή₯¬$&KΨ‘•γpW?.3ž8Ε>γUρ|ΦσΩ\xV Τ§˜.“Κ`{Oι]έNΏ4Ή₯φοΣζ%C–<±“_w_‘ηƒΒZŸΒ»½0—ŒΉq0 pv‚ΨW@Ύ]Gΐvš&¨›YEΰ‚c‘Prγ‚+£’¦UζώϋόǏέo‘ηš|ώ5πυΊιν€Γ¬AΩ Μsͺ½ƒsVt]XΥ|C»β± /l΅±ˆξηψ‰ιšξ¨ͺx‡­’Mυ ΄»m.EW9ΈQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEUmNώΣK±šχQΈŽΪΦέ$²6EY―Ÿ?jνbβ(t]"'+o6ωεύβΈ ŸΜΠIρΒvχ&;x―ξy‰P}ΖNkΆπOŽ4―iWWΪ2ά”Ά;dIcΪCc8α\%Ά›πϋᆁ¦Ωx’ήΦkΫ¨·ΌΣY™ΜΖμ|§ΐ―αζΉα-GIΥΐ‘#‚έΌΙ• x€v χ{zPO†?‡Ž5]RΜisYύˆgΜfά݌85ΨΕ―ιRλ²θ±_ΐΪ¬Iζ=¨oWŽHόGη^-πWΕΎ(ρ%χŠmžώ9ξa€΅¨B’ΙΈ€[hΝyΧ„mΌg«|UΦc5[h*ΦO‹tίψE‘‡TΊˆά\]Μ»–ή.zη‚/Zτš+Η5έ_Ε ξ4ύC_ΥβΧt ζXn›μβ) 'ψ† ΘλωW±©  ©EqΚώ$r3•eCϊzΧͺP)ΰOO―FmEΏφeϋΩvύΏΕν]]|χπξκ^$ρŸαΛϋ}*ΝuiεžςH|Χ,X€ŠΉ9ΣΒ^$ρ‘ρΌβϋˆoή{sse}{ €g!‡όΏο@‘Ey€ΌE©jΎ;ρž{0{M:αc·M l=ϋψ—Δ:—ΕΟ θ–σΣ―αηh;Š£‘Οn@ ώŠςέW\ρ‰~$_ψcΓϊŒZE–›n%ΈΉς„’H͌―ιY^Όρ‚|UΈπΞ«βA=½€+tm—χθqς·χO'ς g’ΌgGΦx€ψΛΒ°k l-L’:ya·ckc­mλzΆ€]κWΜVΪΪ3+2p==λΟfσŸ…v'ώ›Ο‘š±ρκΫR›αφ₯-Ž‘΅€P“s ‡{N7.lό½ϋŸΑ^2ρ‰lO…ΪΣA» Ιy%Κ– ƒƒ³ σΝzyΓ―ν? |<΅Χ5έio4x΄x"΄K` ˆΓݟ˜γŽΩ5“’άxχΕΊ'ό$6ώ#±}Ziή@pPg؜σJφj+ˆψoβ»Οx.{ ‘[λ6Ο%€ σ@ΑtδΞΉΪ|@Π΄Νj_ΨΝsi\=’ڍ•FXNOν@±yu•€ΧWr€6π‘’IαQ@Ι$ϊbm£­6ΎΆ²Τ¬Όuey»HΎΘ¦"§… η¦{W=ρ>Η_—βη„aƒ\H~Σ2-»Pn$gη''ΣξTW”ψχ]ρ'‚<)¦Α6­ow¨ίί vΤζ·ςγ·FξTӞ~΅©‘h~2†ώΚμψΞΧSΣΩΑž6΄rwΨΐšτ*(’€ +ψIβGΔψ‰΅I„¦ΣTšΪ(Qz)Ώπ‘j_π»ημΏμΑqεm'œΠ Q^1€λ^'ρψυλ{Ϋh §]=΄VbάI+$nl‘ιΪ»GΤ΅OxRΤόY₯=𳬐ΗεοR=I ~4ΩΡ^3lί΅/ΒFΎ%°΅γ71ιb)³ [9Ιθ όPΎ0πž­εy3>θζ‹9Ω"œ{£ΨΠξ₯k¦XΛy¨O½¬C/,‡ £8δύMC¬κ+a‘έκ1¨•a¦Qœg­y—ν'€|Ϋ_¬:x–$žΫΚΙ”—Nμπγ«N+_Σό¬I­λΙ©Α&šDQ-¨‹Λ;=rsΗΦψ#]>&π¬ξ=ώXlν䎿…nWƒ|(°ρΖ»ΰ=6M7[ΆΡ4Θ’ΆAmζΌϋIΛ±'»#πίαW‹5-^Σ\±ρ0…u-ε­ξ&Œa$?6?ϊP‘Q^3‘jή/ψƒή±€λφΊ”%hμαh(SχŸ$bΊ„ώ/½ρ :Ά—,cZΡη\Ό_rPs΅Ηύςxφχ ϊΈ|Uπώ‘«>•n/5]I Ÿ ”‘A#ΏΣ8­ŠϊΔϊΓΝnώΝΚ\€#qΥYˆ\qœώŸπ{@°πίΓύ:ιUβςΩo.|ΝΉwr}4ί |Q΅­z M;VΣυΑ1ΗwlS8?Λ·ίΔΡ―“ΓŸb»2΅―ΪΎΣ³χXΙΟ―VΓΗΎΤοννlυΛ ‹Ήd(―–,{ ΙΈρ§ ™|?œΪWΪna»?€β€;h΅9u¬#Ή‰―aE’HC|Θ­œ=πk']ρ]†‹β GΊIΦͺ̐PTŒξ9γ­x†tέόWρ…΅ΏŠ#‚ώή8<ϋŸ±©PTέςŸSZ_5Π\ŒŠφz+Šψ9_ψΐV:–­(šξFpΞ α°8SΑ^"Τ΅?‰2―&e§˜…ΊmnνΩηΏA@~ρqρYց΅ΩΧ―iΓnί·Ώ΅u΅σΏΓ|S©λ>.Σό9¨[ιVi©Λ,χošε‹FG`Nk»πwˆΌA₯ψς_ψΊβι%·76WΡG³Νͺ°μqŸΚ€=6Ήοxž?Η¨ΌVWvŸcΊkR.nς1Θόλ‘―,π/Œυk― ψΛTΏ"ςm.ςt‚0ΈωQβ€=NŠρ―Βiγ nΗΖφPΟ8/φ8ν.~γsΞ΅~%ψ£]πυΏ…τ˜―m-o΅I<›RXurBϋ–οιωz…ΒψsDρ}–­mqyβΫ}WJl™ckPŒxγkGZ‹Βή!ΤoΎ+x»FΉ˜6Ÿa oΠ6–E'žό“@ύηώ9ρ₯₯όBπn™g0K=FYα6ƒΈΗ=«?Ζ>(Φ΅/Gΰο ][ΨKi½Ώ™CωJq…Uυε?jυ +ΙτŸxƒΒή;Σ|?βmR jΗVVϋ-δqˆή9ͺ°ρΣσ―U]‘‘ap’!XŒ…8ΰγ½Ao¨Ωάί]YAs—v‘ ρ+e£έ’Ή³ƒωUͺωΐΊGŠο~ xκ+O₯΅εΌΦιs9²'βMΈ]ί(‘γέAπω†β[ϋ1*α»ˆσ|3Šυͺ+’π֏β;OΤΏ΅ΌA§}4gμΔΫωqΒψ8ΞHΞ+Žρ-―Δ B»Φ₯ρuŒχ6‘™ήΕmΖκ9* 9ιν@½Eyζ½ρ ιΏ ,ΌO°’ςϊ(Δgƒ+φϊMP΄‰71Zίήψ²Ϊi6Ι%’Ω†DμυΫΤ\x°ΓρΣΒeOhΧ^~ξ˜νŠκ«Ι΅Ϋ¨,~>ιχWr€6πθσ<’9ΐUΙ5‘ΰέ{_ρ·‰%ΥlάΨxBܘΰVŒy—¬:·=Υλ€I’ΌŽ_x‹ΖΎ/Φ4ί κΆϊ&‘€?‘%ΫΔ$’yyΞ c ώή΄~ψŸX‹Ζ:ƒόQqυμ‹«kΨWhš.ΘμyώtιtWˆθ~ ρΟ‹ΌCβ HΎΆ°Ά°½pϊŒ‘o(%^η†9τύ}A΅Ό²-mυ;ί·^Ƙ–γfΟ0ϊγ΅_’ΌΫΗΎ&Χ&ρ†ŸΰΌϊ…Δ&ζζςeά ‹8ΘΟΛλXΪή±γ‡ϊ]ήΏͺΕ―h7s‹iίμβ) cЌcωc€;―ˆ>/ƒΑϊL7/m%έΥΜΛommYAžέ)ώΥ|A©}§ώ-t›LD\,ΎfzτιŠσ?φ:Τώ#π¬±k0­₯Ζ «gΆΆœœόN+Φό1cͺiϊg“­κk©έο-η¬"/—Œ  žœΠ½GR²ΣVΏΉŠέg™`ˆΘΨί#}Υζ²|β#αO _k"ά\`§Λ-·vXΏy—ΗΛ]aόAα/#UXm'ΤbKxDςebBsσuιΕhόOΣ΅;ΰˆcΧ΅…Υgf’E·μ]ΛΖ9ζ€=SLΉϋnku·oΙ·Σ#8«5㺝ρU𡞫k―YιΔΫ+ΫiΒΫx*ΚΙκF;qšίπ_Δ5ΤΎOβZ%I,’Ap±τwAό>›²?@‡ExΖ—/Δhπ‘CβK 5ζS5Άš ₯;bs“τλαŠΟŒ|'£4BΈδk{˜Τπ$\gΔλhγWˆ5 ψ}KH”Et“F‘Іΰžx5SΒPxΧW½±ρ±«ΫΨis~ϋϋ"87hi~A€š΅^'ϋ@¦©scα»»]QbΣu xγΆςrVB„…³ΘϋΈ―Lπ–™i±άki«3•1Άω`g= Ξxό¨ˆ΅‹}GŸRΌ4νάdςΑGκk–ttχVšΌ/ŒK%± Ο|ζ¬ό_’yͺύbΡ©Q7‰Ό?kΰ»x――ν$?bD0Μv£ž΅ΧJœ]5'ΫvΣδrΥ©%QΕI$•υω}…ε½ύœWVr¬ΆςδuθEO^Yαι΅όΈΌ0Nζ€0ΞΔfγσ?kψhψ§_[ bγP†ΓOr’-šΕΉ₯ŒwfνΈ:™αωyΥ“°αˆ½•΅jηyEyϋjšοŠϊo!Η’#1±ιŽOΏεZ^1ΧuΧl)-υ‡‡|?φ‰…υτ:‚6ύ›Œ1ž; ΅­'Œτ}jMbΦW<ιl…Ύ/RgœSφ P‹M&οσnγ9&•ΎG’Ρ\v·γ!cΰ{]j(AΉΌTH"'1½}† ό+R“ΕΊ.”u™΅«K³Ocε»{€Ωκ*#‡”·vΦΕΛ²ΏS¨Ε>'Έ] Γڎ”ώR_άB0νn’Ί\ΛeανNκέΆΝ ¬²!ΖpΑI”•―Τ΅V.φθhΡ^}{β­FΟα–Ÿ«‚}q±W_•7σθ1W4Ν7ΔΦ·qx’ήξeiμγi^ϋH>•NƒIΉ4΅·άB›J)ΎΏyΪΡEyΞ――x†o^xFh@xQΦYW"έq–o~ ~5©:₯ΣRκTTo©θΤW«κzŸƒό*ςj«ͺκsΞ#·cŒe€Βγ=°Meκ²ψ·AΆfΦ­/ΌœIqd" »sΘVΞx­#‡rΩ­vσ"UΤwOMόJ’ΈψΆκΟš.±£|Ώkž<£€r₯X•?ˆΕG©Aγk-.M_ϋZΪIcO9μ(^₯Cg’ΓΆ“m+θ'ˆI΄“v=Šγ―ΌmβρQ’d"=<Μ•#θ?•gύƒΗ?Ω‡Q:ΝΈΌΩζύƒΘzgfο^ί_Ξ’ ώΣK[kάnΊϋ*ϊ_CΠhoΝ/Γ‰5λX^!:V7ά“μ3š]2ΓΔχp[^ΪψͺΦαdΪΟg0z€A£κν&δν­ƒΫ¦ŠΎ—:[ύm,υν;Kkiδ{ΐΔJ‹”M£<šΎΧ–Λ|ΆFdM”EŸ˜¨8'™g]Φ/m|{αέ6@΄»ILΙ·οRG?…r—:ά§‚e"Ήϋ:KφpBΖX|›sξ9φ«$›v‰2βέ•υ·ΰzΕΕx―ZΤτ+ #K΄–;Νvύό€™ΣjρŒΉ_ΔVnΆή.π­‡φΌΪ¬:­ΌD‹sΜ)8ʜΤΗεmV»y•*κ7ΡιΏ‘θτW γίάiώΡυ}ό·SΖJ2ΘTΎΗŒS$²ρ›iΧ”ΪΌ1M䴉c…8ȏ…‡|ͺRi\uΜγݎϊŠηΌ#βυoΫκ·.ͺΙϋIι΅“ο,ώ5KαΎ«¨λΊeΦ§¨Ά!žvϋ4{@Ω?―§αPθΙ)7ΣB•X·ΊκuΥΜψοΖz‚μm.΅8e[™ΌˆΦέ71lΣ>ΥΣW’~Π·Z[ψ>βαΔpC­Γ$Žz*€I?•dj]τ²δβ?ό?γ^\}·ΔΟάάE ³y₯`ˆ£vY‰ΐ+ŸρGˆόExυό#ΰωఐ ο―εΜΨ0ͺ=y―₯z…δrkž*πŠt{?j0λ:«'ΩμB"’{ιΣυτ©>"x―ΔΪΔ}3@πΠ‚FΤ,ŽΕ˜|‘ΉcϋΖ=p½?ˆ-5)!„Λq§›mŠ£μ`z―^@Ξ)GŒuŸψg―ψIώ?Ά<½ήvΑŒύ§gNŸwŠυΪ+'Γ7“^ψ[KΌΈmΧΩΗ+Ά1–( ?pόmu?€5ύ{ΔyίΩχ— ¨_‘ν_Μώ΄ιΤWŒθό@ρV†Ύ!·ρŸ₯€e΄ΣL!”§;C±"ψΞCt-8ζρ΄ΛΏ˜>Dΰnsψ°γίΪ€=Šροˆ> Ώ6Ώm­ΑnCέΩ5°ŒΟ;[9β―όPρεΦ›πϋDρ'‡\ΌžΪκθΩK>‡Œυ*+Θ΅«O‰~Έρ x†Ν.aˆάΆ–Ά£b¨)Όœ’·ψΥο|A½ƒα‡‰΄θbŽςτD…€ŽΗ°4ιτWšhΪ7%{ϋoΩκΞΘσGφEΨΘHέ°‚yΖq^—@ΘψΏLρ^‘¨Δ4=zΟIΣ_Όf·σ&2dτΞ1ŽυΞψ+^Χτˆw^ρ‘oͺ©΄v·‘ F+œΐ}ε@‘ExίφŒυ‰%πΞ‰megfθζξXw΄(TaU{’Iλθj捭x£Γ4ο x—Q‡W±Υ!w·ΊA8 }1ψŠυŠεwQ‡#Πƒ^‡¬x‡Q·ψΗ hQL›ug4²Η΄|ΜͺΔώ€;κ+Θ.υοψŸβ· iΪύ·‡ Σ6,hΠ‰&ΊΞrΓ$p0?1]Ž‹ύ·αVΌρ~±§ ²’’<ΆͺIz“€:κ+ΖΌ1/ΔiίΫΦΪ墁§ΜνφKeΆ–Pq–$Žΰώ]+[ΖΊηˆ<5=œ·ρMw{z-οeH€YGn΄ιτW5ρ'TΊΡ| ¬κ:|‚;»x Ζδg#΅q^+ρΖ―¦ό9πuέΌΠA}­%²O:ώξάΊ)gaψ“ψυͺ+Ο΄-ΖPj6WOγ+]SM. ΔmhrwΨΐšΒΤux‹β>―αΝ;^Άπτz§–ςά’9+’8ΤP­]Kφ{if(ξ#BϋPeŽp­cψ3Δ1ψ§@‡T†βΡ%fQλ†8Νgh6~%ΡτTψƒY·ΤΩ#/k,pylΈRNαυΕsΎ ρΥΒ|“Ε^ “νΐ²3`ήCmEόIρ O’Ό‡G³ψ‘β-=u|Ei§KpžuΎœΆ‘“iεC1=ΗΦ΅|γ«Ώ|=Χ―.b[]wHŽx”HˆY\Cικ zMβžΊψγί Ϋκk―Ϋhπ.cBΆ’GΈe<»rγΠΧCπχΕϊΕΦ‘βkm~8ξ5}Fš0 Jœ{β€=*ŠρMγ/θ©­YxΚΞiYˆ±ŠΥ]aΑϋ―Ξsψ~uλz"Ρόmα­'Γm }J9€Λ•ߐ¦s@©Ex‹΅Ÿ|9}>ώUΆρ ₯ά†·ϋ?’VB>P€gŒΥIρžo]kφW_g(χ:rZβ5V`VΞN3׏Zφj+ŸΎΈΥu―AuαΉν¬υ Έb–7ΉR聰N@κpOγ^qβ­CΖ>ŽΛWΎρ5Ά³dn«VΆ•V8Κΰ“@ΟEyΖ/λ~ΌπΚx}RY―ξLJΔ£=Ή"²ΌZ>!ψGC“ΔsxŽΟQ[b―sb-B&Β@;[98Ο·•{ζ-ρ~₯€κώ Φ#˜κ›`»„¨>[ΈΚΆzχ?χΟ½hόcρ=‡ό?i‚ΓϋgRΊKkQ€y'ž?!ψΠ}EAaΠΨΫΗu/p‘ͺΙ.1½€δγάΤτQEQEQEQEQEQEQEQEW†ώΤ>»Τ΄;Y²‰εuA’¨Ψ;±θύkά©C)VƒΑ½|ޟόβOZΕγ=<Ι­Ϊ[QŒ%ΤΆάR:gσή¬ώΚίςρwύ±Πd―dΉπ'….nLχd™ŽYͺ|ΗΤρΝliϊ]†›lmτλ+kXXΰ‰QOΰ|ωϋ.ΘΥβoϊζ?τa¬/ ψ‚Λΐ|Iyβ6 vžξ=Λb7ΛΉN8 ~΅τΦ• hϊDΛ€ιVRΚ1#Ϋ[€eϋς@ͺϊΗ…4 jεn5mOΌF“@¬ΨτΙΕx—ν!¬Zxƒΐ^Υ4ζf΄ΉΉwŒ²ν$m#§α^§ΰ H›Α:’ιv/#ZFYš$£’q[χ~Πο,-μnτ}:{;υ0Ilξ©…hΫA ­Όp[DΓ…HγPͺ t‚€>kύΥS⧈UT”:ζU 5¨| ϋCκ:–·±Ω΄²ξuBNΗNγ8ύkιM;ΓΪ6™w%Φ›€ΨZ]KσAnˆν““’O4έkÚ.ΈPλ:Uσ' ΣΒWθHΘ •Ύ!ψΫΖ?tKNŽQ`’ΫΫΓ$ŠWΜΫ $γκΥΤ~Υ%ΧΕ~1.ι»\g'ο­αoΊZ#θšc%‘ΝΈ6¨D' όΌ|ΌΣ¬ίθΊ^‘yow¦Ωάέ[œΓ4Π+Ό|ηεb29τ ›Ύ5|PΨL!^q¦Xάί[ήάY[Kym‘ ο³Εž»XŒŒϋRήiΆ7³[Νygoq-³o…εŒ3DήͺHΰϋŠσmcώNA°dίΦΈ½OGπυΖ=~,°Ϊj.,n|χŠ<ŽIR3ΧΏL{ΧΎΎ›bϊŒzƒΩΫ΅όhcK“2*ž 62΅G«θϊn³oδjΦ·°η!."Wώ4ηžπΓ‹oΩ6…qϊxBήΙ1N ½F±τ_ θZ¦]G°²”Œ QˆτΘ­ŠπΏ„~)τoψΪΓVΉŽΝ§Υfš&;RL9C28όκκjPxΗγή™q‘ΈΉΣτk&[‹”ε7ΆξοΤΞ½>οΒϊ έΌ]hΊt°Ι#LθφΘC;usΗή>½jΦ‘£ιΊ5·Ωτ›k(3’Dκq@Oα-^ΗΓ?όqk\ΗdΧ²GqΜv¬‹ŒπOCTοΌKaβ/ΪΒ_Ω3 ›kHn"3 ωŒ2οŽ+Χu―θΪζΟν*Κψ§ n!W+τ$dS­MjϊφΓΔΓ_ρ β=ΔΞν•{―Jδτωμ<3γMρ @»ΏΊΊΊ/g|Φfζ?'².rπ©ν,’ρgďjžπΤϊ>›¦³=Νμ–Ώf8PΏΕίσ  ΏiΌU5Ζ‘ύ±m§jΡ ykp!™Yx;ϋ܏JΣψ­jzΟ….N«tχ«mw%½½γ. ΔkŒ5t·~π΅εγ]]x{J–αŽζw΅BXϊž9όkvΦήH Xc†XγPͺ£Π@qροVΤ4Ώ iβΒξ[+{«θΰΌΊ‹οEΞH=«Ξ~)XxMπ<Ι‘έΎ₯¬LΗ'ΪήvYΨgcΫ½}{gmk%΅υΌ76ς ƒΖΏήa ?1ψמ|9~κ>·]rW²ΥνΑŽξο儇’pϊWΠ–ΦπΪΫEokpΑγŽ5 ¨ `Ϊ±uOxoVΊϋN₯‘i·W¬’Ϋ«1ϊœs@mβ94Ώ ό!Φ/>ˈdΉdρJlͺ»Ğ€W?βKΩό?ΉΈ‡S›YΦξ-XBΝxςΘς²ύν€ΰyιΠWΎ[i–ΊΨm¬­’²Α_³€J±ΰυ@Εfιήπζ›<“XhZeΌ²¬ΡΫ"’QΣ§΅yy‚KΩgΛ… ΏΨ7` œ,Ω? 5Ωx?\υίZΨi—φσή6›ε˜UΑu"=§#―S]₯₯’YΪ[A’.Υ‚8Β’@£ŒVv“α}GΎ’σJΡμ,ξ€ZX TbQ:Pš|ρv‡€|<‡LΥ΅+{+έ:iγž)Ϋc ΘΜϋί₯3ΰΎ―½ρΗZ°qorρ4EΧidδ+cάτ«xsPΎϋeφ…¦\]ηq–Kdf'άγŸΖ΄­tΛ ;™m,­ Έ˜*Ι,q*³…2p:Pšόo9ώݟω Δψα₯ΨΕγ k~!†i<>Π›;—‰Ω|¦άΕX• σ~•μΊ~›c¦ωΩφvΦΎ|†Y|˜•<Η=Y°9>ζ₯Ό΅·½·{{Θ"žhε@ΚΓάρι<-π’f΅―"$T†1¨Κ坎w©―gOπW†4λ΅Ί°Π4Έ.ξYΩ)φ8γπ‚€<šΐϋIjdŽš:cσZŸφŠn5€φΠ=ΒΨά€ςΔ„ε£7JτuΣ,S}Il­† ιε΅Θ‰|Ÿέ-ŒγŽ•l€ΐ†ƒΤρ α‘€%ι½Α"nhζΤ¦ Όr¬»ϊԟτλ'ΑήΥ|? I’θχ±Ν…bψ…Ώ‹žO ~uιxΒ’έ›™<9€΄δξ.mS“λΣ­oh ·ΩΜ1›}»<’£nίLtΕy§Δˆ>—αξ€,u+{»‹ΫVŽ"mΞwγΆIΟ₯s—SίώΛEj$«h’νQ’BΞώ€šξΌYα-Lπ‡ˆgt=>ΪνμfΓΑlͺω(x ώ€ψ3Gπ·ΓρM+ r`ύφκ ei|5mπκΚα΅Ks4v)ΩΥ³! BυΞkŠπ6›u―~Ο:ν­€lnζΈΈuΉ!•±υ⽆ίΑΎ·Ττ—Ψ;„«jυzΥΣτϋ=6‡N΄·΅…œΘRΒ)cΤΰw>΄ΰήώκž²“S¬υ(bXξα›P–"²(Γ»Ί ―CΠǁ4Κl%Ά_ άΞbw•ΪHέΟΩτƒRπg†u;³u¨h:eΕΑε€’Ω 7ΤγŸΖ―Ύ‹₯Ύ—ύšϊu›iΨΗٌ+εί8ΕxOŒντ/]cαΖΎaΏ’εϋ*ή:+€O /π*ιΎ(^Η¦όIψw«jl-μ’3¬·έFd~΅θZ_ƒΌ7€ά‹7BΣmΘ–;u >‡₯«iVΕ‘΅Υl­ο-ΙΟ—Έ4Οψ\π}ώ“εξq§^9‰LŒ6u‘žΔdW•έ ?Αž4πϊ|>ΧδΊ·Τ.„WBΝηΖυaύΡυζ½”xKΓΓJgφ&œtπΕΕΉ·Rρc}ιΪ7…΄S.‘£ΨYΚF ΐͺΨτΘ ΒS₯Ÿ d:¨‡Ο(#%U=Ϋ ­ΚγΌ9αlΥλΗ…΄ju›VΡ΄ϋΙ—€“Ϋ«·Σ$gΥfΧEν.’Ή΅ΣlḊ/"9cU’<“°2$œtζ€<ίΕ|Wqq|ϊ½ΆŸ«BΜ­ymp!™x9―N⹝=΅Ο|ρNŸ-̚œΆ·,ξΚΰέGŠωΎBœ}Ezνη‚™γ%†Ώe3Ηπφ‘0›KΡ4ΫI‡I!ΆEoΜ Υσ¦ΨLj&Ξάκ?(\ωcΝΩύέΨΞ9nXΌρΗ ͺΚΗ©`$ϊšρ?ιή ²/|IΰίE£κρ‘š%±Έω.¨C©ι‘ŒgœΧfΊΖ…­x#Aƒβ!³ŽηRΆωwCfζXα<ƒΫ­t–ήπ­΅ΠΈ·πζ“ΐξΆ©ςŸQΗ…ik:•­ΐκϊm₯μIχVxUΒύ28ό(Ζ4–·π§ΔΝ KπF½6₯€κΕޞeσΩGF Ψ~£Nk[LΥ,Ό7ρίΕΫWΩΕ©[A%΄²ͺϋQAR½sž+©΅³Ά΄³ŽΦήmc]‰ h}ެUπG…’χν‹αν(\†ίζ TΞο^}θΜ>"xjΫΕΏtΝ*ώiβ΅“Lw“Ιm₯ΐ$…Ο¦qωV―ΒέjλΒϊΤΎρ+b{|Ά™rFβΛυβ;sκ-¦ΨΆ€šƒYΫ›τCܘǘͺz¨lgΥφ¦κVΧ7ϊ}₯ΝΝ±ΜΝ »DΩ$dt(ηΏθ±ρη‰τŸ mndΊ7s΅Μ€±±'ͺQϊϊW¦xCπ —‰₯›Β³$ϊ΄pεnδ›ldŽΉ$uΪkZ“F©¬iΆwΚΏt\D―·ι‘Ε&‹αύCV6—ecΏοxU }HΠŸόϋWΗGl?ς―SͺΆ:mŽžχ cgolΧζLaŒ!‘ΌΨŸsV¨ΗόQw„Ύ8XλΊ©1i•‡ΨώGΛ δn=‡OΞ«όkρŸβm?JπΏ‡n"Τ΅+λ؜­»’δ–$tη†kΧυ MJΥ­΅ X.­ΫοEk²ιw°]Ζ’0Ν †—SΞ+Ρυ MFK]BΪ«i):·Τ+6ΣΒΊ¦›>m’ιρΨNΫ₯·λ²CΨ²γ§z±α‡t°ΆAαΏ4‹wφsΧ΄λ%-s,Σ4j:±]·ρۏƾ‚Š4Š5Ž$TUUΐUm/L°m~Ν₯Y[Y[ξ/ε[Δ±OS€1šπoi_ 5? ZΎ«3YκP§—u χςΔΚγƒςξ}+ΦώiήΣΌ<ΓΑ₯[Kšαδ.²4€αXε‰?ΒαV΅/xkT»7Z†ƒ¦\άL’[)fϊœsψΦō΅…ͺ[XΫΓmnœ,Q E_ Pšώ?ςKξΏλβ/η^kύ*ΗΒ{|΄jzmŽ«hmu;;{ΛbA1\F$BGCƒΕYPB¨€jω³ΐ:ƒ ΏΦt_y–ZΝ½γ²4—rB’Δ~ι`3Χτ―Tψy£xΗXΏ›Ας€ΧΒ5K‡[—› O–$v«Zπή‰:Ζ•czΛΒ΄π«‘τ$f¦ΡτM/E…’ΡτλKΫ–[x–0ί\hΕ~iSλ|a§Ϊ Χ\܈ΧϋΜ0@όqΖ©ό=~κ^ΆώΩ•¬΅XΛ»†{ωb*γpγι^χ¦ι–:\/›gmi±vH"XΑcԐ_zΜΤόα½Vμάκ:›spzΙ%Ί–?SŽΓπŸ†Ό%qΰ­ONπΆΧΡυ‘%u‘€M‘I‰ιωWψ}―ΌI/‡>κJω5 ZΈ0Dr£>ω*>’Ύ–°²΅ΣνRΪΒΪktϋ±B~€qPΑ£ιΆϊœΪŒ}€z„Γά€*%qΗ ΨΙθ?*ςΏŒϊŒΛβο h—Ί”ΪW†―7©α/q·aΣώϊφ3β-―ƒl5/ ZψQΝΥπΤ yζ[‡œ"nΐ Δ‘’Hό}«i:~±kφmZΖΪφί9ςξ"ΉυΑοTν<+ YΪ []MŠάH²ωkl›w―!±Ž£± Η _σύΫ―ύjχν $³RΦϊ9+ΌΈΣlno­―n,ν₯ΌΆΟ‘;Δ¬ρgƒ΅ˆΘΟ΅;Q°³ΤνΧR΅‚ξΩΘ-ρ‡BAΘΘEή‘‹€NwΪΗ-ρDΰ-T€#ΐ…lxX፠€,αΠ^»Ά‚ςέໆ9ΰq†ŽE ­υŸi IH©ͺͺ0€ —?έςyά₯ήsωXσ_ΫxkΔή!΅yVΥ.šξ %8Y½ -έμ>'ψ€ )Όϋm*7’iΣξnnΩοΠ~΅ήjZVŸͺ"£emt«ΣΌ6>™ιRXXYιΠω6°[EΧd(~•³―ΉΫήjή]b¨JΚχSΏŸsŠπψ‹½βϊφƒ@J5Οω,―YΏτΪ;+X―%»ŽΪΊ˜’e@ΐθ u=YZΙyά–Π΅ά@¬sΠ 7QΦ—·\Χ·Ω·αb½‹ε΅ϊίρΉΖ|VϋΎ°€Ι«β…Œ?΄ϋύ}$:EΝ·eWeΘ ΖJτŠτϋ»+[Ο+νvΠΟε8’?1laάg‘χ₯»΅·Ό‘»‚)αn©"†Sψtρ‰.ΧόESΟwή߁ΐA‘ψ νφBˆεΉiWΘQxξKηŽ7RxŽξ 3βޏu ‚Ωμή1+π»Ύn3ω~uΨΨxsEΣηYiVPL::B‘‡Π㊡©i–:€"-FΞ ¨ΑΘY£ ƒκ3Ÿ·\ڢ՚ΧΜ^Αςθ’wOO#ˆψŸqεŸ†¦Ά•&…υX°θrPy—Ης%λŸυη/ώ‚jςθϊjΪΫΫ _³ΫΆψc1)XΫϋΚ1Αη­\Έ†+ˆ$†β4–«£¨*ΐυ’³φ«έK£ύKTŸΌίSΘόG§M{πΓσΕJ–l“J‹œ˜πΐ‘¨«φϊgΓΛ­9nZεV&\²I{&G±«ΰ·‚ήέmΰ†8 A΅cE@τV[xW@kƒ;hΪy”œ–0/_^•²ΕifΪΥ½<̞Ξι'’ZωwΔKk[θsiˆΗM²Ή†UΫ–Δ}AΙζ΄|oβύψFύ,οbΉžξέ’Š8Žζ;”ŒγΆΟα]«Α $hJν1•HτΗ₯gZxwE³‘䡬bwX€ 2QΣ₯DkB˝=αΛ•ές5ͺ±Ξx^λKΆψk£.Έπ­œρ,GΞ)'$ωζ5˜το j}Χƒ5f2Οp¨ϊtrω±Θ€σΪ½NM+O’Αld²Άk%X K°}ͺϊ‡΄}6_6ΓK³·—ϋρΒ‘ΏРǜtm<˜ξϋ:υυι[SΔrΑAΆ­ΨΖ₯iΉ€ϋœ'ΕXν,Ό  -sd—q< Ω]ŒG^MtVπΥΜ7±I$°HAωχ0Ζ1ψΥ_‹3iZ"AšŒ_*/@½;WSζ‹φί΅dΨύ§;ΌΟ!sŸ^}λG8{89έκΘPŸ΄’…ΆG›ίθΡό°…bcwnίkhρΘRμέ>Œ8ϊΧf|u Ύ€u·D‹w’Xy›±χvϊηŠκ°1ŒqY'Γz!»ϋQ,>ѝήgΉΟ―NΎυ›―ŸΔ][ΣΜΡQ•?αΎ‰kδr^Km'ΐM?ˆDp[^Ξ2Μ>\9ΐ{Φ‰βΌ8°κ^ Ռw*c Ύdsdς6φ―[Ί΅·»·h. ŠhƒŠOΰj…‡‡4]>q5–•eΓ£€*}8ͺŽ%)9»λΣ‘2Γ·m:υ9oί<X`˜§$z|†«κΆϊWΖΈΤ%[x'ΣΜi#œ)lŽ3ψο₯²΅šξ©m‘{˜AJΘ ¦zΰυ¨΅='OΥQSR²·ΊUεDΡ†ΫτΟJ˜Χމ­-oΔ©Q–­=oΐαώ Ξ–ϊΗ†„(h.^dύέΏ=BT§οYό[ώZyγ› 4οψRΚΰbX WpvΆEz΅W½±΄ΎDKΫhn:‰P8VΟCοQκϊŒ:VŸ-εΚΚΡD2Β4άί€¨GU(Ϋ]αMSn]4όρ ]ψv]π½’6ΝfXδ³Η@α‡τό+Σo/΄ŸψF5 Œ:}’$EΒ–$τθ:’ysGYό]γx΅Ιl§Ά΄ψŠZωι΅₯sΥ°{sϊWs«i–Z½„–Z₯¬7v’c|S(e89zΧ;¨ΑοΧΧώΛ 7%·OAϊ}䅍½ε£‰-ηA$n;©είΡ%OG"‡FΧ VVδυ[x"Ά·Ž x(cPˆˆ0ͺ@₯A¨i–:‘ύ‘gmuδH%‹Ξ‰_ΛqΡ—#ƒξ+Œλ+Gαέ9γ¬UΤ‚¬ PAϊW˜G¨Ϋψ/γ~±.Έίf°ΧmΫέ?ϊ½ιό$φοϊW±Υ=WK°ΥνΎΟͺY[^Aœωw >Έ"€<β†±cγ/ψSޝ/ξ"ΏKλ‰ ;’$@G,=r*ΥΦΐ†„Π2:i2cώϊjτ @44eΡτΛ;{μπͺϊ9«¦ΨΙ¨Η¨IgnΧρ‘.L`Θͺz¨ldj·^[ϋA[L<;£κΠΔ¦•©Es:¨Ξ#ΑγΨγσ―R¦ΛKG*+£ 2°Θ#άP›xοβ†ζψ©=–₯os5ν›Η Άι t#•κ1œŸ₯rΪe”Ϊ‡μ©φ{T//Ωd($%Λ9ΐϊ)―@ρ'„t ;Γ Ήτ=>ήρμ.1$Κ―“t gςͺίβxΎh1O#„—(λ‚?|ύA  ψ‡α«O‡tςjΆβX,’#μΘ]SBυΞEqŸ τϋŸ|ρe₯ͺ7ΪonŽKm±^1^Γƒ|5 /’Π4΄Όp™mP0>ΉΗ_zΤΣτϋ-6)#Σν-νc‘Μ°Ζ3ž¬@κN4ΰ4Ώ†Ϊ§…μΆ&{=Zή1δ3ίΛ/…ά3Σ8―Gπθπ'‡όw6—5ΈπμӘη’IXΩΙ A-Ÿjθu?xoU»7ZŽ…¦άά²Kn¬ΗκqΟγWΖ‹₯,ι£N³qϋ/’ΎV?έΖ(Β„? ΡΤ΄Λ R‹S²ΆΌ‰H©€q@YπsΗZΏ€μ4ΝRώ ?PӐΑ<Λa΅8>ίjZ…΄ϊ‚όKi(Έm΅5‘ζŒβϊ|€~UθΊ§ƒό9ͺέ›­KBΣnOYe·Vcυ8洎›btα§›;cbgΩό₯ςφϊmΖ1@]ρ›ΗZ u-;Q‚ςξϊ ‘Εo8$Η΅΄«Ώ §Βί XψΆKAiy¦Ϋ’-Χέf)λΨΧQeΰο X‰Εžƒ₯Β'R’l΅A½OPxινVο΄ "M‡O½μ§±…BΕo$ Ι*γ€%ά]0Kxγyτ ³^‘§ΨΪiΆqΪiΦΠZΪǝΐrrp’MG•§ΫΛw$6±ΙvspΙƒ1ισœ|ߍxΏtΟ6σΔ~ρ :>¬ˆeŽKŒ Xr£χ>˜λ]–…γΨτΟ†:Ώγ&’ ξ”#νˆ–vΙ ΫGχ€ ψΦό^π€W_iΓšJ͜†©ΑυpjŸΌ"ώ&Τό:^X“MΣnΎΥ4$ΚT|ͺ;c#Ÿjλ”ξPΐ‘žkΚΌzψΫΰ<Œώκzυj©q¦Xάί[ήάYΫKyn†w‰YγΦ##>ΤηδαΏϋ A‘VΟΗω%>"+£ΊύCM±Τ–%Τ,νξ–'F'Œ8GdpG­>ώΞΧP΄’Φώή›iF:0λΘ<ρj·Ά~ψw§‹ω΄έPHγΤ.α;YT"`nμ0XώΥΝ|^²πNαλ{ LΧΊ£Ν΄«tσ”ŒY‰$ τ―£.τ:σM}έ…¬ΦB‹y"VŒΠ#UOxrΞ[Km LŽΪR ‘‹dΪψιΈcŸΖ€8O‹`|6ΘΟόMώ«]Ɵω%Ύ"―oύ˜WUy¦XήΟm5ε•΄σZΏ™Λ³DήͺHΰϋŠ’ϊΞΪώK[λxm₯^)P:0τ πh€ΥΌ<Š( Š( ŠΚ΄ρ™w―]θΆχJϊ•€bY‘ΑΚ©θsΣΈ­Z(’Š(’Š(’ͺκš…•§\__Μ°Ϊΐ…δ‘Ί(jŠβΌ1ρIρψ·±³Υc‰£iVκβΤΗ *Œ’?Ξ‘Ύ(θzΎ΅Ÿ₯Ϋj—I,g[ΈνIƒvqχ³ΣίέΡEQEQUu=FΟJ΄k­Jκλ$~΅ΚGρOΑO?”Ύ ³έœd’ηŒPkEdk%t} kΧ‘¦švνrΑ·tΖ:ζ΄’ΈŠKxηIΓ"†FΞ₯KEA}w…œΧw’¬Vπ©y$nŠsMΣo­΅;/l&IνgPρΘ‡†’€,ΡYΧZޝk¬ZiWqG¨έ«4σH$‘ωΚ΄h’ŠΓΥ|Qa¦x“IΡ.DίlΤχωW+ς‚Nγž:PεQ@V/‹ΌIcα]κZ˜˜Ϋ‰/έ.ζΛ2(jŠΗΦχΕΪ—‡!hiρ$³@k#<ύαΪ€7¨’Š(’‘έcRΞΑTu$ΰPΡUu[θtΝ2κϊηw‘mJϋFNΥ8¨<9¬[xƒD³Υl‚Ϊι‘ωƒ q@4QEQEQER#+¨d`Κzr+ Βώ)ΣόI>«œ' ¦ά΅€ήbωԐqΟ#Šή’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’Š(’ŠΟΧυ›JŸRΥ§YÍξA8Ιΐΰsή€4(¨-o-ξ¬aΌ‚Uki£YRLΰ2°Θ?ŽEO@Q@Q@ƒαΏιώ!ΏΦm,β]*δΪ\yˆή o<”ΦυQEQEQEQEV>'°›ΕΧA7φ„-Γ’Ώ&ΣΣ= ά Š+Ζ$±πž‡.«ͺ ¬lͺDKΉ²N΅Eck&΄eӎ§t-΄$X­Γ);ΨγŽElΠEΥ™•X½@=(h’Š(’°΅―ιϊFΏ€hχbswͺ3,ΘλΈηŠέ’ŠΑ°ρNŸ{βνOЉ΄4ψ’Y‹ ΅‚‘ƒž~πν@ΤQEQEQEQEQEQEQX>5ρVŸΰνϋSV›o5bύΚlœγŒJή’Š(’Š(’ŠBκ)`ςy4΄QEQEQY6>"ο΅ΫνΦιdΤl”4πΰειΟC@ΤR+«3`Jπ@=)h’Š(’°υΨi^ tk‘7Ϊυ2Β‹•ωFNγž+r€ )7ύ›†όgnyΗ­-QEQEQERo]ϋ7 ΨΞ3Ξ)h’Š(’Š(’Š(’Š(’Š(’Š N ŠEeu „2žA ΠEPEPEƒβOiώΤ΄[+ρ9›VΈϋ5Ώ–€€ωQσsΐω…oQY7>"νΌGk‘Mt«ͺ\ΔfŠ ² 󞝏εZΤQEQEQEQEQEQEQEQEQEQEQLšE†‘σ΅±Η ¬ŸxŽΛΕz:Ά–&²–UΦΰΰρ“@4QY>ρ—β8.&Ρξ–ζ;yLӚ֒Š(’Š(’‚@“€)ƒ(e ©δx4΄QEQEVVŸβ 3PΦ΅ &ιdΏ°Ϋφˆ€9MΓ#žυ«@Q@Q@Q@Q@Q@Q@Q@Q@pΌ|ήΈΡ·Y}ͺ Ω&|Ξε ;’p+Ό―*ψ½Λγo‡« ΏΪYΑυ#ωP…υΟLΧwή,,4";v6Μ^TΗ$?8ΰg΅sΆ~:ρ―ˆ,εΥό/α«'ΡU›Κ7s2Νp£©P8­vŸmg½ψβ+{E-<–3UκΗiΰ}zW—|*πΥξ·ΰ}6γLρζ­i'–Φ°μΫΚϊΠy¦|@ƒWψuβ]> \YG šΦSώT(O§#Ÿzη4?ψΫΕ:<Ÿ†Ό3bm61ξη+ζΘΞ#€δ}*Vπm·ƒ~xΒήΧR—P7QΛ<’H!φ`Ž+Sΰ>£guπ³F[y# lΚ(αΙ9ϊδΖ€4ώxήθ·wWνa{a#E{nη>S/^}:Χ3aγΟx©ξnΌαϋ4xdhζώb¦r:•Œ~΅‹πύ[\»ψ§y₯Άϋ;Ω VξΒ8$zη"ΊŸ€φ· 4ϋxVβΝ€‚β.†'‘ξ?hx Η©β;}RNΙτΝ_J$^Z±έ΄ όΚ{Ž+žΡ|mγΨΆ­αIώΙgeˆ]ά°–@3ΑTž S㍡KWΣ’‚+y&qέUUΉιΑSωSυ/_x^;½[αήΎΪ| 4ο§Ξήe«ΰgŒύί―λ@>=ρή—πΪ=S[Πμ€»ibYl'o65%ΐλŽqΦΉŸΪΏ η„‘Σν-–ΖmBΩ‘c1YΑFΓψS§5WΗΎ$“ΕΏν΅‰αΝ5Μ"D^›–\=Έ­_,±§ΓΩ…5›ff=qΙ «ώW@𢧬ψκΚΞΙmpcK9LžfxžεˆΝGγ?ˆSι?ېxSOώΙ)η, pίhhϊδvΞ9ιVΏh«iΎάInΦΪζε3ς‚~ƒ ώΪiΊή›/„`ΥVβμﲉKξωB…δ~(|yo}πηΕzTAό¨YΜœmu8(ΨΓ^;ρo‹£°Όπχ‡¬ΣJo-nnnε*Kqζω`§pυΕr^·’?€>1Ίee‚φζζ⠌e0‹‘ψ©ό«ΥΎF‘|4πΖ‘A±‰°=HΙύI  zΉΧΕi#M΄ŠK[X€7ˆΏ½”>V>‚²n|wβo^ΤtοhΦ—iΟε\^ήΚR6“ϋͺ3ωΤ>Ύ:xΘ)Α6ωŠβ~hΊŒΎ"°ƒΕΊ–‰m¨ΚΣY@ζIΟ\ΰΐzΠ¨xΗo­I«iΪνφfΉ€δέ[«nR˜Θu>„1X:/Όoβ›Υ|1 i_Ω%Ωbw %Œπ@³αΗαίkwž ΉΥo ΜnBƒ΄`qθ+ Qψ{α„»ΥΎλν§C†τωΫΜ΅~3Ζ~οΧυ LΠ./ξτ‹iυ{4²ΎuΜ°$›ΒLχ¬Oˆž1‡ΑΪT3›gΌΎΊ”Aij‡YAžΒŸπΟΔ²x·Α–ΕΔ"¦ ²*τά€‚G·Ζόi‘4ψWΌ;tΫ[ζI‡Κ…€ΓΫ4ΊŸŽ1xŸGΦ]m ΦΪ;«9€ωQ˜nωsӝΔ}W·ρcΐΎΥτg_½·i58lœΗ(™€Κ)+ΐ8  ‰ΪŸ…ώΌφΪeυ•Ή†ν%‹n࣏nίJγ~8κϊςiΎŽΒΪ-:βξέΥΔΔ3Λ΄‘^Ιομ+Y“XΣ>±θσ]ΖΖψWΐς9Ϋκvۘτ»jίρψξ~x ψ’ΒΖΚE΅o$ZLd 0sœτνTώψΧΓV4 [έnΒ ˜­Udε”ϊ]WΔΆ πϋ_*Ac~‡ΪΉ_…Ύ πΕΓΝκχ@ξ.e΅V’Y-‘™Ο©$s@ΊΞΉ₯λŸό.‘}oyvχ ν ξ |Ή85άΕβλ‡ψ§7… ΄BΪ;v'ΙήNGιŽk†Φt=+Cψχΰˆ΄m>ΦΖ9-ξΦή —'' dK_ΪMΎΠΛΪtp"άqΌη·ύς*κώ!x² Ναδ·ΆŠq©κ1Ω9rFΕcΓλ‡ψΛͺΆ‰ρ/Α7ρΪΛy,BaΌzG`UT}K Ÿγ¦£o €τε• ΙΦ!œ 9!ŸΜΣ~-^Ϊι<s~Κ–ι+v8 Iΐ'ΠA  Ί§|_α#Pρo†μ‘Ρ$‘c’[K‚ς[ξΰΟŸ₯zΌΙqsBΑ£‘C«ΰς+ΟΎ=_Ϊ[|0ΥcžD2\„†ΞKΉaŒύ3ψW[ΰψe·π¦ Ξ|䴉_>»EsΌo7‡otέ#FΣ΄υνEˆ‚άΎΥUY§_ΚΌΛγΏβ‘αX΄ίh––Λuu‚κΚbιΉ[%AΖqτ«ΔsG§~Π^ΈΏa½Φžφπ;πΎnOυ=??i+λHΌgk,ˆngΏ„Β™ηεΙ-LqψŠΪρφ»‹iα%“M΄Ύϋ]μ0pΉςI_ΎΏν w‹Όg«[xΊίΓΣm―5W·ϋTw)HγLΰtδž+ γό{ψώΒΠθψγΐΊwŠu/‘ΏΈΣ5λDΫε€›dUδ€G§_ΜΠ―j-Έ½ΈƒΕzE…€)hξ-',sΣiδqΟZεΫβ‰\zη ­rϊOΔ―3α<ž2Τμ•7³ΒΗ·μQ“Σ$ІΣΔf‚ήτxoE’`!KΆ…=2ztφͺτΫ _ΰΎŸ«’=•ΛKŠΝ·9~0}sŒ{Φoˆlνw:n±BKk«i6Ka‘‘Xž ΧΌE£ό@ρ-τ:²ΙjΧΧ¨»dvlστυ  ‡~"ƒS»ρa:}žžš}σG$ŒyΈ—~+Oρο‹ΌVχ7^ πύ‹ιΘΡ%ΝόΕLδuΪύk3αυ΄·–­νΑ3Ky2 I(ΨΠ~Οz…­ΗΓ :ΦEΈ²yaΈ‹8(ώc7?PΐΠΏΓΟΒPΊ…₯υ‹iΪ֚ώ]Υ£6ν§³άW)‘όHρWŠ%Ώ΄πΧ‡m$Ή²Έx§ΈΈ˜¬* w,@Ιτ₯π$±κ|i¨ιδ=”pGl§*ςŒgŸQ‚*ΟμψŠΊˆ˜[ZΈ$ϊύΡ@ήρΎ‘¬xƒTπο‰4ΘτνjΑVB!rΡΘ‡©?QλY69ρoŠ.u |’i¦Z\5Έ–ϊv+/\Œ~4YΙΕκϊDΟ«|;’ίQ»Χ|―Ι£ή\±šXC -¦n§+Ӟ}qž1@Χ…nυkέ!%ρŸŸΈ«CΎbΰ>υ―\/ΓΙ―ψF}G^k[Y¬¦{{™ƒ…„•ώ OWoo4W$Φς$°Θ#£V‘uζu]A4½#ΓΪ<Ζ ½vνm ͺpU σψŒϋfΊ?ψΓ>cΆ‡O΄!T ..Yεnε˜ϊϊW'ρξ+‹Ό7β{xZhτ]A&Ts°‘ώόk±½·πχΔO Δ²Θ—ΪUΑYG—!S‘ΘΞ9wCt=6βκMΖή[¦slͺ γ8'SωΧ'œΜW/§|Oρ½}¨ι^πύ½Ξ©gu$r<²‚8†³»˜ξγΪΊ|?ŒgΧΌCy«j2Ϊ›wAΨJxτΪ+#ΰhŒ₯ 7Ά³"“κŒ3ωΠWͺj~+΄πξ›%ž‰iy­Ο…ΉˆO²999$vrΫΗ^$ΡόW€i5Ρ¬m‘Υ_ΙΆΉ²˜°q…`}ȍ;ǚώ»qγύ/Β: τzPΉΆ7S^΄aΫ‘΅qž?Zβ> i“i>π­η‰―΅›ΆΤ£‘’Ή+ˆ†τ‚Ž™ης «Δ_ςr>°LŸϋZ Ρžζ??{K΅Σ`1#œ+8Š,μMOβ/ω9 Ψ&Oύ­Nπ§όœGΏλΖΫEΕ@WΓŸψau  [kΘεxn RvΐϋσΣƒ|asβ_ψŠΚ XWIδ%ΘbZY{L ΜWŸkZΒό0ρΗ‹Ka,΅‹6Τ-±ΊθWρcšξ>ι Ꮗv³j2,S\+_]Λ) ‚όε‰τ φΌsφ–Τu‹O$6pΔΊdσF“\y€I»$… ιςη>Υλz}υ¦₯gޟs Υ¬™)4.ΑδW–ώΣ€Ÿ†ρό$ϋpτ³¨έxžηΑ^(„§NΣμ•ldς>Ι9“wΘΫ³žΏ:γ>ψΖw>α𯇬汳‹Κk‹ΩΚ˜uΨnΩ―SρΜ‰/5Η‰ΥΡ¬% ©Θ#a¬―‚Θ±ό/πψA€mΓ©$š“α׍γρf{=ε©Σο΄ιZΨ²#aœœϊp#\՟<_βeΉΎπ_‡¬¦Ρ‘€s^ΜΘχκT cυ¬?ZΟzŸν,Τ›™―.’‰GRΗΞ~uKΰη‡―5ΟZ>›γSO0³G-”1 n'<σΦ€=cαη‹αρ†%Θ·kKΫiM½έ³˜€F{ŠΥρ.΅iαέσUΤ­΅²olu>€{“Εs|„[Vh΅iυ9―¦Yf’P ‡ϊw;«7φ€΄žσαv¨-•˜ΔRV 2v†ζ€2νθ[•8=bΰTj5HΜΪΤ Ÿ`ο@~ ρΆ₯β«Ώ ψ§K‹OΦ ƒν`ΌS&@$ΠσPλώ:ΥηρeΗ†ό₯A¨_Z {»‹© Cz/“ψΥ ―ω8»ϋΏσ7Βϊ-έίΕ_iγΔ·Ϊ ϋά,θmIL±Ο>›‡ύτh<γ{ϋί\ψkΕZlZn»bxΔ.^)γώς“ώx5… 3_Τ|I­xΓΪ7šΣΔ²I!XR%γ{ŸRxΐ­mαΩΣόek―j>'ΎΥoΰ…‘EΉ ’‡άΠ’xzMRmέυθ-ΰԈύτvμYη±5Ν|DρΓψfγNΣt»ΤυΝEˆ·΅ ΄`uf=‡^»jςM™ϋBψfχQeŽγMkhds…σwΏυω—σΤxSRρΤϊ²Eβ}KΆ°tf3ZΞΜΘG@A'5'|G―λz…—€τ[;»]>C Χ·²•FuUΞ½5έYJ‡]ΜzΧ”~Ο3Εm‘k<μR²Τ%Ζά?'†#ΠΰώT½ΰO\k:εχ‡ΌC¦/_³]νΎθεOο!όEaΒΗρ£βΝwΓΎΠ-―l. k4²•‰cn|φ\Λ­ϋJE.œΒDΣt£Ϋ§!\—ΰŸ_EYψL‹ β3γζϋx\ϋe¨ Š!XŸΓWήFρ^ες!‚oά:Ivcχ@ή΄΄ŸxŠΗƚ‡όi£YΩΆ’¬mn,ε.…‡U9ό?1λUνΥOν#rHA ¦|Y’πΓώΏ.?φ_ρΏΔ-KBρΥ―†τ½u‹Λ5š 9Sζaσ@\ζ²oώ&ψΒΊœ~4πτ oΎΘΪt₯όΙ;FAξI>υgSEoΪGIά3·Cb>Ύd•ΖtWρ―Γ`Γ#ϋ]τ8θΪ―|cα·²ΎρG†μ ΡnfHY­ Λn›»~•ΣψΓΕΣhzχ…μm­βš-bΰΔξδ‚€r?:Ηύ‘δ™έΧΝΏώŒZΚψ’λmό5Ί‚[₯ΰFv8².(»ψ‰β |+ΰΝKZΆ‚9ε΄TeŽBBΆ]Wœ}k Ζ~=ŸΓΏτŸ­œSIvmόΘK(‘7};U_ΪRΆ΄ψ[ͺA,¨&»1Εg–>b±Ηΰ¦ΉΏŠ`7ΐ Π½€Θt―γOΕ₯>»…¬Š©ηyR\΄˜Ίξ p9Ζ+WΕ~2΄ΈψC'‰ΰΣΰΎΆš²] ‘%Β•o‘Οε]?‰/‚΅E§ΚΆfΌY?δΣ#uτ­¨_γv³¬‡CiφvΠi—’ΤΜλ) Œpλ―χr>Υ³­xΗƞπΫκΪή…₯‹Xe…XApΞή[d3}GΛωšΙψΓ$KΓΝΩ^Δ“θ6W©κΊu·ˆ<1q§ΚUΰΌΆςς9+Α λ^ ΅Σ<'s―3+ΪΕmφ…η‡γ*3ξHTψw­ίψ“Β6:Ύ©k€ΧjdX£$€™ωO>£ŸΔW„Ε«ήk~>J̚¬z‘ΣξpyќξόπϊVή+KXm­G(±Ζ‹ΡT ?@‡Δo/„ΦΒΚΙυkQ.ΦΡ7z³Γ‘PψcTρτϊΌψ‹B­τω--΅ΓŽœΧ+ρ hτΏŽώ Τ΅&Ψ=Ό,Β‰>qΧκιωΧ±y‰7ONzΠΟΎΧ5λ/ψϋNπΎύμϊΌ΄·l†%8δŽI$τ―CπυK―Ναipιϊ²Αφˆ^ήBρLƒ3Ё¬o‚¨Ώπ—όI||ίΫR.}·ΙRλ_ςq^°\ίΙθ€ρF«γ΅ƒgαΚβΨFo/. ©'ͺ…δcΧ½Uπ5 c_Υ|?β=2=?YΣΥda …γ‘ Ÿ¨kGΤΌKγοψ‚5φΠ΄½.γμΛ ΄jfσσ1n@γ·τͺ Ρ!ψγβ+tΥ5s’DχS°f,6εr8ΰρψPΙψβ CΕzί‡|= [έίXΞTM,Ε"Xρχœϊ“ΐ―ψWΗ:ΛxΤxWΖM½Ž₯4βΪ[Y Η*Œδsτnύͺ—Β΄_ψXΏί7ΫPgΫ™βοω8bŸω=K­|GΦ!ψ…ͺψOEΠβΏΌ…"kw2”_š5v2ΐnνSi>8ρ‡Œ4νΖΊ=£jA…­Νœ₯°ΪAΝPπ²ƒϋFx͈εl-ρ~α©ώ-ΘύπηώΒGe  ―xήλHΦμ±`¨Ώ˜₯‡Ζώ+ρ©ͺΗΰΝM’ΗNΈkWšϊfV‘Χc&™'¬Ψ*/ζ*]oαΫ Zο]π>½6©\1’dFo3ηΛΣ}h΄πζ³{€ωΎ"Σ‘ΣοΓ²˜‘—ΜR££οι\_ν$Ίϋώ»E‘V―Β?^ψ«Γχo«G ίΨ]½œΟܐ¨pόλ+φŒ’]}]’Π¨׏υθτXόšeΫ/aZαra'hήΏν Ԟ2ρ©eβΫO xcL·½Υ§€ά³έJR(Π}9'ŠηΎ2}ο‡φƒω₯u~:π6™β»Ϋ{Ε½ŸNΧ,ΧήZΛΆDτδώ΄h:§Ž^[ΘuΝLFH Α-½Ρ #φCœ‘ŸZσ‡:ώ νυ BΪ1%ΤΧ2ŠςΗ$ς;Χ¬kZΞ‘ρΑ^%£Συ i³›β•YNO^NJθ~Κ–?όa|Α/gΈ[ˆƒπ^#’1λΓ-CρφΦoήΆ‰Ρξagiœ•ωφ:πKkS~?ψ- KώΤnν­γφF˜Š"YΟ§οuδΎEoΪ+ƌGΜΆ6ψ>Ÿ»Š€44λφ>.ΣτθφΆrj ύ–ζΞRρ³α τ«ή5ρΕζβ+O ψcMMO^ΈŒΜΛ#μŠΌζ±Ύ,ΙBψsa²Χ/ι³ΝϋA_ΐϊνή…-ν‚ύšζ flmύί?ξ“υZν΄/λVΎ,΅πχτ«k «δ-gqi!x₯#ͺσΠώ=ΕWρGčKLρΥΧ†4½j7Ν ohΚξfε‹ž@₯O†’Ώˆ4KWρ~₯¨Λ§ΝζAΐLdυλωTTjί΄F²δΛ₯FτΙ  ›κΎπeή±γ‹K{΄”G΅“–σIϋ«’O=X7Ύ:ρƍ§Gkž±CωZU‚v7‘ώ"τ¨Ώi›i₯π~•p¦EΆΆΤ£yέLjU€ΐ?V%ψyθ€Kρ W»ΣnβΙ!GB3@¦_A©ιΦ·Φn$ΆΉ‰e‡uaZΝρuώ±§ι©'‡΄€Το^Q”σyj€ƒσ“θ1ϊΤΎ"Π|5§ivσ΅Δ6°¬i+c.CΕq?|G­§ŒΌ?αMκ-6MM^I/€@εA8PxΞώ$P2xηΕ^Χ4›oθš|6”Βή;›)™Ό·=Χτ­ˆ¦πwˆ4{τΣ|5δΪ‘“ζ4€€ͺ;rOZσϊϊ\ϊ5ο…-υ_κχ“jqH-ξ …U ½9`?]ΔΦO>ή3΅n}p(Dρ‰-4νSTρΝ§ιzu΄tg”Θψ$7=zcλœƒΗ>:Τt–Χ΄― XDŽiΨ\Iώ ₯oόs΄Έ½ψS―Εh¬’R]‰"³γͺOα\—Ό+}ψ;MΊΣώ jιk%Ί‘†0›b `§α€=;ΑΎ#΄ρ_‡m5{ Β)Αͺ08e?C\ν9$ΟώίbώM]Γ Ϋψ?ΓΝ¦ΩίI}Nσy98qξ+Žύ§?δ™Ϋμ_Ι¨KŸψλϋ1΅ΛO Ϊ'œ"’δύ₯’뻀qΞ0k¨ΗšK|?-,ΒΓΚσ μγgΧ΅π­ύΛ^Y£΄N\$ςNWΖMn«ρu+EΥ|?£›\,mrΑαSԜη83ĚΏŒ?αxX[ΪiΦβ>V΄·{“±βf`dcَޞ­ί\ψ—α~§£E6·ύΉαλΫ₯³XΉΈ‡=0zώC½hλ.±ώZ!‘‚†ΠΩTž2|Ιx HΠ%Τ¦mδΧ-ΰΆΤH>lP9t_˜γυγΘxΟƚŠ¬Ό3α2 έ^βpΝs.Θ£Aτδž+Ύ=+‹ρׁ΄Ο]Ϋέ}²}?[³_ά^ZΛΆHΑΝh_ j>1ŸT’ΫΕ:6Ÿml#.—V“–²>]§'υνLψsβ돢Ί.m’ƒϋ:ωνΛ$ο HΙΟ~+πgˆ ρ5μ¨{_΅[ήΖ»\(Οίε?§­Aπ"D‡QρŜ¬«s±+4dςζύ(«>,œ|PO }š/³›wηδοΘ c1Νfι!–ηβ‹΄Ϋ Δ^ΨΑ$ΰμ{’G νŽ‚°,΅{ΪRt΅‘$ΪSDεNpΩRGᚷΰ_ω.>:P1πΗXρΕΖΏβΩl΄έ6κGΤ±v'Ήe°Θڞ ϊW xΗΖΧφ~$·πΧ…tΘυ-nHόι<ι6E~¬E`ό‘Δ?"fA«Ή*O8άυΟκZ]ΝΟΗ½fΤψ‚οBšφΦ7Ά– f`2~„γΪ€;_ψλW‹Ε±xkΖΪ]ΎŸu’Ξ{Y Ε6:―=γMρuiΌ_?†|₯A¨ίΪ {Ήξd+ 9Ηu<І†n|O£κΪΏ‹΅JγO—Μ‚;€œχ*>Έύ+7α\ΡΨόYψ‡azα/n.Rx•ψ-Xρψ:šΕΤu­gPψΗΰ›/ιQιϊ…΄’œΓ&ψ₯VFΑSΧΆ1^ςΩ vŒœp+Θ<}yk7Η?[Dθχ0ω¦@J†Vΐ?‘―` ³Φ¦ͺ‘ΨΓ'Θ$ΐίσtΦΉο:ΗϋIψ€HΑLš\A3Ζξ!ιωΚ—Η’Η¦|kπn₯~Α,f†[U•ώκHsŽ{g P—ώ=ρo…$΄Ήρ·‡μc'”DΧ63˜ ιΈητ―T†Tš–& ¨eaΠƒΘ5η΄%ύ€ 5Yβυβ†ή,όΞώb·@€ϊλ΅πΌΆžmξGkΈ=A 2(›ρ·Œ―΄ΟιΎπξŸφ΅{ŸΙ²8£ΝŽzƒωW3/Ž[›Z+K[”p ±'’pMXρ_Ž5(\ŸNΈφ>•ΪXό6xΌW€λ:―‹5 NκΑ‰‚;€œ‚9s@Ž¬ψβ_‹ΊχΩ΄­1οⳊ6΅’θωqΗχ”†ξNξx―qӚεμ-Ϊώ8β»1©•#mΚ―Ž@=ΖkΜΌ:λνβ₯v ΟanTχ°«œWͺΠœλώ7Φζρ₯Ο†<₯Ϊ]^ΩΒ³άΟ{)D@q€δυζ·|%¨ψ¦γν©β­"ΚΘΒ‘’–Φrλ/\ŒF>΅—γ/XψƒYώΩ΅;#Δ0¨ŒέZΙΛ`p{ρϊzΦΓ―k³ψ“]π—‰fΆ½ΎΣbWKΫq"°άς({αW‹'ρ§„£Υξν’Ά•₯xόΈ‰# Žy¦θ>-ΈΤΎ!λώ’Ϊ$ƒN†9e's–Ηtcφkš5ψrmΩΥg·»•eByCΗZ«πΫQ·Τώ6ψββE’ q‡SJ°ˆ  m>%x“YΧυ­ΓΎΆΈΎ°Ί’/:YJΒ±)ΐ,ΌNx΅ΰjw>+“Γ.βΣu+Ξ… “|S¨λ·=ϊώFΉŸ‚wΦ±όBψ…e$ˆ·rί™Iε•^@qτ$~usΔΧκ΄'„νμX<Ϊ}¬ς]ηb²0ώcσgQψ­·υo θzWΪ…ΉS΄₯&2ν!ν‚T uΝZΡΘ<»”œ΄ΝΗΛ•χ―HΏ»†ΖΚ{»§ (dv=€5Λ|!–9~xpΖκΐZ"œς8"­όK΄šϋΐύ΅¨-4–r©8 3MρǍόMm&§α_ Xcna ίNVIΐ8Κ€@­u?–;Ύ1·Ύ`—°A%±~<ΔΉ λŒcπ5[γ5崟>Z$ˆΧQκI#¨<…2Fh©ΥυψΰψΕ’hgL³’K‹˜_2ώϊ0<Ο•O‘ΩϊΥ ψ‹Tρf­’x3H±Ÿϋ,„ΉΈΎ˜¨,{*Œ^jˆδδΌ/`™φ΅jψ§ανΎ©M―ψkYΈΡuζωešέχ$„q‡^ύG·JέπΦ―f_άψΗN΄Σ  /Ύ ΌΔt ’ήΐbΈΝ3Ǟ5ρJIα X9X忘«Μpύj₯¦½―x‹Α^>πφ―δ\k]΄°yφ£εŸ({zρŒ{ΧQπCQ²Όψg’­€‘ζή/&T”pNA ρŒ΅M|%ξoζ―pΆχ1y…„Žvžυ½γ½r_ ψCTΦ …&–/1crB±Θγλ\?ΖΙRWΐ·’:‹hυe &~Q‘Η?…iόyΤν¬Ύk+,±‰.Qa‰KrμXtϊ ŸΒ€Δ&ό!αΝB 9nu]sΛK{o3laΩA9cΨdUTψ‚5kX΅­Hϋ­‰&΅ΉmЏRsU¬<1€x·αo‡4έkτH₯ΡφΙ„2ώ­`›Ο|:ρ‡§_λ#]Π΅+³F.ϊL'λΥ‡Χ4΅ͺxΫΔ:‡‹υ=ΑΊMΓι~Σq})UάΓ8U=ϊΧOΰΫοήCrΎ)­l'‰€ŒΫMζ,£G§η\‹>[λδΊχ‡΅‹_ΐI.-Ÿ+!$^ό? oΒΟλž₯θ>#kyυEFΊ·IƒƒŽ™γšξ5JΫG΅ ηΩmm–FφΌΟOρ―uέ<λ…΄μ†ΛΒ—WO2γ=Έ“γ-€χΏ υθmUš_#~Υ$ « υ[ο‡ϊ-έ¬ρ t΄EsΈUΓι‚ rσόQšοα΅Χ‰΄]5ZξΒQυ•Α;‘η Ӟ2Σ5έ[λφ“xU5ΰΐY΅―Ϊ²OA·$Jσ/ƒ–Άή ›βΚΗΏFΥ΅ ’<–TmΩ#κυ%΅›Λ_\|8N°ua¦ ΟΜmΨξέτνψΠ¦XόM–/†γΕ:Μ±½Τ퍀 wL3„λܐ ©¨xοΖΎ΄‡WρG†¬bΠΩ”Lmg-5Ί±ΐ,―΅e|uΡΧIπƒΰ·’K]?M½Š9'ˆs €ψφΕl_ό8ΌΦτw†χβ­w¦ά ,Λ(λΑ> kόFψ‡…4U΅/,uΡYΉΘˆνΚ;œv«ΦΌa¬jI>―‘ΩiΊ±—2–Έέά3Ÿ₯q?t˜tΏό?’Sso₯ !Ϋ:…Ζx―Zρ6€Ϊ?‡΅E"σ^Φ•SϋΔ”ΖίkŸ^k§Σ|/₯₯¬.Αζθ™&υΐκ*χ…ΌtxΚΧPeŠζφ8δΆgγΜL)Βϊρ šμΌ=}βΫ›MN?ιZ}˜H Š[I‹‡899Ηη^[πcΔ,ΫΨxOB΄ΈŠΥίΝΊΎ˜’3ͺ_­{Φ’κl.Τ2–±ΐ<τ5石œjŸ l6ŒnšV>ηukό8ρ΄Ύ(—UΣυM?ϋ;Zδάΐrσœ?¬ί‡ž*[ x—S·¬¬ZΒζηχVγjΚΘ»·7ΉοT>ΙhψτƒωVGΒOω&Ύ:―«ίύ@ψƒγOhρ_xgΓzxY₯»œͺ3Ž«γ§&ΊŸ‡~6oiϊ§φ—φv₯₯JbΌƒvε^ ά§ςͺ_ΡWα^΄cpr~»Νc|.….>!|S‚Q˜δ»…{04.™γx’ΞοSπ–…¦&^8μΝζάmλ΄ηλZŸόe­xΦΒ}CQ±±΅²V1 …ΨΙΌu AΝyΓ+Ea­ι~Τ΄₯Ρ-―₯†ή]Dνš2y$ ν“‘žω―Wψiα8Όαˆτθξ~Χ3;M4ίvλj«ρ‚WΣΌ ©Ο’Α „Bώ|’I΄ΕΣ–QόGΪ±ώ_x₯ό;‘&§§ιΡθK`….–ബ ₯”ρΟzθΎ,~ψ”Iϋ Ό₯Qπ"οƒzU½«ƒ,Ί@‰JžεγωΠŸόQβ«»Ηπ&‡c>•m)‹ν—ς”0λ΄ c―]Γί?‰nu3U°:n»§0Ϋ·)£)ξ?ϊΥƒϋ9ήΫΏΓΔ° ©yeq,w7 ¬X‘‘τγπͺΎxυ?Ϊ ΔΪ†žΒK;m9m%‘9S)dγ>Ώ#~TšWΔ―ψ‡PΥ4Ώ ψzΦ{λ—ŽI¦˜¬ 8B{–$7‚·Όγ›ϋ]xgΕZ\zf· ~r€ίΙκ€Χ3πP΄ςθ·ΏΪ&}€ΰ²dŽ=pτ*΅ͺάΗ¨ώΡ<6 ²>Ÿ§ΏΪΩ9Ϋ»$)χδΖ€:? kΡί|Eρv˜4ΫKw°nΊŒbIχ)?9φνXρĞ!Φoν<‘ZέΩΨΙδΛ{{)DgBηQx!Yώ.όJTϋΜ–ΐ}vOΩΞξή? κ:[Θ‹©YίΚ.b' ’xb=ό(WYρΖ΅αΟΓ}β Φξ.Ε€O˜άž‹ƒ―­I§jίSQ³]SΓΪ3YM*¬­mtΑαRycœηšθΌa hώ+џKΦvΌ7ΚV@¬;©υ―4Τn|Iπ·Q]lλΎΌΊKQ ί7?ΒέH€=ͺŠͺڍ’κ `Χ–βωΠΘΆζUσGV œγή­PEPEPEPEPEPEPXΪί†τνkQο―γ‘4Ω|λrTχλfŠΘΑι^©|%πΕζ‘5δ1ήXΛ1Μ«gpΡ+Ÿp+Π(  Δ~ΣΌ/π§_Στˆš;²Λ!άε™˜―$“߁\Ÿ€~xw_π&…¨\Ηuosqf’smpΡ »|ΐpkΩn`ŠκήH.cIamtqΓЊK;h,ν£·΄‰!‚1΅#A…QθRπxwK‹NΡν–ήΦ>нΟrOs\Ύ³π³Γ:¦§5“ugq?ϊο±ά4+/ϋΐq]Υ‹ ψ_GΠtW΄»4‚ΞE+"ŽL™%Rk’_ƒžPΡΤΕ‘λkφΧςΎ›s½Šη΅_hΊ—†’Π&΅ςτΈΚŠ)§#‘οSψ›ΓW‰t_μ½^ίΞ΄γhΞHθAμkjŠζό/ΰέ/ΓΊmݍ±ΉΉΆΊβT»˜Μ γyνŽΥΟΏΑο ΄­ˆoVΥ›y΄[§“œύάβ½ŠΛ½ΠtλΏI’5ΈMxΌ*/“ θ1¬hΪmΆ€ΪiΆ*ΛkkΓfΙ £'½\’€1μΌ7§Yx’ϋ]‚9‘{Ε3%J―LՋ⏆ώρ₯ύ£wo5Ύ‘Œ‹YLNίR:ΧeErΎπ‰αΘοVΖ9δ{Τςη’βf‘}2~΅„Ώ<.‘’ ©‹Fλj/_ΚϊmΟJτz(—§ΪiZ|:| ¬+Ά8Π`(¨΅Ν"Γ]Σe°Υm£Ή΄”|Θγυ‡ή―Ρ@aπΒΆ—pLπ]έ$4P]\Ό‘&=œWWβmΓĚϊF©5”Ϋwͺ1Cς°a‚:rjΡ@4ΛkM.UchπvPάμΫ·―£πζ‹gανΧJΣΞΩJΖň“Τϋ“Z4P¬|)πΞ₯©Ν¨$WVW3œΚlξ ηΎ@­½ ΑΊ>‡αϋ½O†E³».ΣΉe IcΞptTPo‡4[?θΆΊV˜Ž–vΐ¬jμX€I'“ξMiQEaψ―š7ŠμΦΫ\±ŽεS%πιώλEr+πcΒϋDrΎ©,€/zε>˜―J’€9»h—ΎΓr[2iνΫnTŒ6αΟ^΅oΔόA cκΆώ} IΓ)Q€AμG­lΡ@މΰ HΡu-.½šύr‰ξΘPIϋ½OJθ4-*ΧCΡν4Ν=Ym-cΖ·£Τχ«ΤP%†4ΫιΊύΔrGOFH9 G~ΥOx#Dρk[Ι«ΫΏΪmΥ\Bζ9zβΊj(‚±ψOα[G·˜ZάKu Β\­Μ³³Θ]W,{g΅nxΑΪ'‰/­΅«AtφρΙ+±Ϋ‡΅7„ό ‘ψ^κk½6 ^φeΩ%ΝΔ­,ŒΎ›ntτP7‡Ό5§hκSi±Θ¨Oφ‰χ9lΏΆzW=¬ό-πΦ©©M}δέYΟ9ΜίcΈhV_]ΐq]Υ“α―i~Σ†‹h–ΦΰδΙcκORiΎπζα«k˜4¨έ#ΈΈ{™Ήl»u<ύ+bŠΖΓzrxͺ_¬riΙΆgήvμ>^•ΙΙπƒΓ&iZ&Τΰ†RYΰ†υΦ3žΌ^‹Esrψ+CKᘭ<*EΪΡΔΨ=AΞ}r+[Cν΄]"ΣM±V[[XΔQ†98¦―Q@άAΜAqK ŠUΡΧ*ΐυ΅η³όπ£\Ι5€wΦ>aΛ%­ΣΖ§π½ŠεΌΰ=ΒWάhφς-Μλ²I₯•€vΞ2}ΕTρ7Γ_ψƒT:•ΔΫj χ-&13ύqΦ»J(›π‚τ -ΧφZNdΉΗ,ς΄ŽψιΙϊΥΟ xwOπ͌ΆšR:C,Ν;rΗsžMlQ@ΆώΣmόUuβγjw0¬9s΄ Ζ>^…ex―αί‡όM~·χΠK £iΆ”Ε!δuΎŠζ<ΰ}Β“άάi‹pΧ7 Y&i€δ š½α― iήΓKŽD· u6χ-— Fz:VΝΜψΗΐϊ/‹MΌš΄2 ‹|ωSΓ!ŽDϊY–? |1g-€λm<—vΧ)v—2ΞΟ)uι–<‘ν]Ν‰uα6λΕ–~#–9©i·‰Γ‘μεzΌj4Πt}#_ΥΌRδΓws[©€μ’ŽqΠ`(ζ·ι“ΓΔC:,‘H₯]d0=Aβ><›Kψγί hz,‘_ZXΘΧ7χq|Θ‘ρςnΞ1υ5ι,5Gΐš¦‘ΐ%ΌΉˆ@ˆ Δ9$'π­Ν/IΣ΄˜Ω4Λ+{Dn’Βης«΄•α="=Γzn•έ΅cϊ9?žjOhΆ gΣuh{I†Bb+FŠγό=πσEΠ΄νFΖΡΎ‡Θ‘&Ήg œŒ.~οή=+‘Π4›M G΅Σ4εe΄ΆM‘†mΔ­_’€1+ž+RΩΦς!„ΉΜrιΈuͺŠδΌ)πDπΖ χφ"ξ[ΦCšζα₯`Ύƒ5©‘xoNΡ/΅KΛδYυ)ΎΡpYΛώΓ΅lΡ@bx³ΒΪG‹4αeZ-ΔJw!Ξ¨#₯mΡ@_…Ύθ^ΥSQ±7²έF†8Ϊβε€§¨ΣΌIπγΓΪώ¦ΪΔ3Ϋ_°ΪσΪLΠ³φΆυʊΑπ—„΄o ZΙ‹h!2ΚΔ΄’φ˜ςj]ΓZn‹ͺjΊ…Œr-Ξ§/rYΛάτΊΦΝŒžΣ“Εoβ%ŽOν7Άϋ)}ηo—q·¦r4šί†tέkWΡυ;ψδk½*F’Υ•Κ…fۜŽtVՍ/†΄ι|Yˆή9?΅"Ά6ŠϋΞί/$γoLδži5ο ιΊξ‘€ήκΘΣιsύ’Ψ«• ω‘ί ­ͺ('Ε°ρ6ϊn¬Žφκδ#•9Rδ{ŠΔ~|G£ /W΅Ϊ.6‚pΚ@ΐ υΆ¨ <‡ΰ…S₯Μw†XΜAnZC±ž‡ήΊ-cΒN―αλ-φ)ZΒΜΔbU‚<±…ΙοΕt4P–‘]ΨOg0& ’h\ƒ΄Œ~†Ήρΰmx$xSΙ›ϋy§w._οuϋΖΊz('Qπξ™©xsϋϊάM¦ωK–ǐͺSŸQΝsΊF‰α†vάΙ©KioqΆ%7Χec$*ιί§₯wOTμuXVN ¨‘·ͺL€o^{σ@KπΎΚ|Nρ'Ž ΆςτΒΪΙΚγΝ!B΄ƒκϊΧ³TvΠCkCmE *"…θI@ώ)πή•β0Ψkv‰soΛžΥOPkΓ_ ΄j°jfϊKˆωχ-"ΖΗΧoEbψΓ:n{«]iΡΘ“j—κδ³– δ’Hτž)n<5§\x¦ΧΔ2G!Τν‘h#pηhCœό½;šΩ’€8mwαw‡5fmRHξνnη\Φ— “κiψ{ΐϊ‡u!}£Ω}šqn-ŽΦ8e [$wlž΅ΣQ@ϊ7†τνTΥ5 δ[JA-Αg$ƒ΅6ϋΓ:mύ~β9£cE !BΆs‘ί©­ͺ(ΛΓmŸŠ΅ΑƒSΎbΛ’₯T(^ƒ…νoΓzv΅©iWχρΘΧdΎ}±W*qΤwι[4P‹Ό#£xΆ;}rΠL#;£‘IWŒ²Γ‘XΊΒθϊ΅Ά₯ΏΉΊΆmΠ΅ΝΣΘ#=2ζŠΖ‡Γzt^(ŸΔ ŸΪSΒΆξϋΞƒ§+—ΊψIαΙοn.υ+qpν$±AxθŽXδπ z ›αέNπξ—Ÿ£Ϋ%΅ͺr{žδžηή’ρW‡thςizΊ;ΪHΑ™QʜŽœŠΧ’€0υο iz鎑ύ›2ά[νrΈuΖ3λΠVgŠΎθΎ%ΥRΌ7_*όλ[†ˆ•ΕuτP1α?h~ΈžηL·‘―'’ζy ²0τάk?^ψcαέg[—V•.ν―f\φ— ›ώφ+·’€9―ψ#CρbCύ±j^h?ΥO‘>Œ9ͺψo ψVSΆϋlχΡ©T–κε₯ΨΑΖk΄’€9OxBρUά7šŒΗ}Ϊ—6ς˜€Σ#­TΎψgKΏ°Ύ΅΅›νΆr΄Ιpσ3;±ωΙϋάvڊ+ΛΓ:mŸŠuAƒRΏ"Λ’₯T(^ƒ…΅Eck~Σ΅­SJΤ/£‘tΙ|λbTγ¨ο«ψΏΑΪ/‹­β‹Z΄΄G1JŒRHώŒ9†Šβ<=πΟ@Πυh5( υΕδςžζε€Ω‘Ž­θ<7§C⋏GƒRžίyΪPtγ₯lΡ@υ +mFΚk;θR{i”€‘ΈΘa^ kΒ‘™Pj)jNM²ή8‹ώωΟJτŠ(+h¬¬ΰ΅ΆM@‹kθ `ΘVŒΌ£xΎYΪKvέΡ9Iϋ0ŽŠα-~ψZ]ΦΣΟp³$išvyw!ʍǜ{WE©xoNΤ|A¦k7QΘo΄ΰβέƒξΉλfŠGUtepX`ƒΠŠσΛ―ƒώ–κi­’ϊΙf;€ŠΦι㍏ϋ’½ŠΝπξ‰cαέίL’1YΑŠX±δ–''Τ’j/xwNρ>Ÿ–±Ml“$αc,½3κ9ιZτPž]| π₯ΝΙv·»Krώa΄K—œύΜβ»”Σ¬ΣMzΫD,D~PƒoΙ³Ζ=*Υη|π©–CκΠHw5Όn‘ŸΓ5»«xAΥ<=c’Οo"YXmΌ©Y3κs]UΓθΏ ό;₯κpj.οnνω…οno,ϊ€NhψΛΐϊ/‹šΪMZEΝΆ|™ΰΗ"{dvžŠΞπώ‘o‘iiΦo;Αv΄ςδ’rΗ“Ι5…βΏ‡Ϊ/‰΅4ΤoMδΘ‚15­ΓDΕ}+’€9 ψCπ΅ΜχZmΌ{0Ϋ%ΝΔ¦Yzn5CΔ_ Ό;κκsΕsm{(Δ²ZNΡyŸοc­vΤP'αί‡ήπξ©‘€Y΄Q@ΠnήNεb -ž§Ž΅₯§xkMΣΌE¨λvΡΘ/υU‹’€/LΥ΅EpϊίΓκΪμΊ»Ηwk{1ΜΝkpΡ O«λή΅|aΰ½ΕΡDΊΥ§™$'1M‘>Œ9ŽŠβ|9πΣ@ΠuxuKΆά_BŠK«–“fFφ«~-πƒβ›Θ―5%Žϊ!΅nm₯1IBGZκθ /Gψgα­&ώΖϊΦo·YΘ₯Δ“3;±ω‰ϋάν(’€9|>ΠΌS¨C¨_ΕέI/ˆρ 9šHΔyηyι^zg5τF§€iΪͺͺκV6ΧAzyΡ†ΗηI¦θΪn—Ÿμλ [Rx&(‚Ÿ€2|aΰΕ’¬Z–žυSΔΕ$O`Β¨ψgαΎ…ανY5;_ΆΟ}”InZR υΖk³’€9ό=ΠΌQ©C¨ίGq όK°\ZΜbrΎ„ŠιtΛ(΄ν>ήΞάΉŠ‘v,ΔŽIκjΝΔψ‡α¦…­λ3j³5ύ΅τΨΙktΡoΐΐΘΥ­α/hή†dΡνŠ<ΝΊY€rςH}Ψςk ’€8[α?†5JβτΓwk%Λn-n$χʎ+gΓ>ΠΌ3¨ά^袟f–xR ΔΥιΗ―©–Šπ?ψ7Gρgˆόwύ«‚km]Œ3Γ!ŽDΙ|α‡nz―ƒό’xMη—J‚Cu?ϊΫ‰δ2HώۍnΩiΦv2\Igk \?™3FLκ}O5j€Ξής{Έ-‘Žκ| eUŸ2{ΥͺηΌ]ΰνΕqΒ5‹bςΐsρΉI#ϊ0ζ©x[αξα½@κpM> FΡsu)šE8'§W]Eb]xcMΉρe§ˆεŽCͺZΐmβpδ(C»9^‡οΧΉ‚+«imξ#Y!•J:0Θe#’Šγψ^ΚβΚε-§’ςεn’ζYΩ€g^Fζ=G+Ί’€1.Ό1¦έx²ΟΔrΗ!Υ- 6ρ8r!ݜ―CχsϊΏΒίκZ½Φ₯ΏQ΅ΉΊs$e»xΦF=IΧwEbxWΒΪG…¬ΣF΅Η#n‘‰,V'“\Ζ£π‡Β·š„ΧqΓwfσœΚ–— ?ΰ+Π¨ zχΑΊ%ο…‘πυ՘—L…#FcΉqΠ†λŸzη`ψ?αDI–β »°ρ΄Kφ›–“ΚR1ςg‘χ―C’€9Moΐ:³’ιΊeάSˆ4Υ jρΜΘρπήΐU]ᧇ΄mRIcΊΌΎ‡ύT·— 1ύάτ֊ᡯ†©¬\κlϊ…­ΥΛo˜ΪέΌBCκ@5»αO ι³’ΫEΆςVFί#³y«1δΦεŽͺθΚΰ2°Αd^}yπ‡Β—3J]ΫE;n–ήήεγ‰ΟΊƒŠτ*(–₯YhΊt6]΄vΦ‘ $h0^±dπ.…'Œ“Ε jΗWAΓο;s·nvτΞZιθ  ši«iσXκ6ράZΜ»^7WΏ|*Ώ ΩsŸ³}±ό―¦άτ―I’€05Ο i:ΥΎ—τ.bΣ%I­•ΦQŸQŠάžξ!’‘^)«« †¨4ϊ(Ξαψ=α8nK¬f/ζCrώA9Ο)œbΊ]+Β:F•€jZeŒ – ςΌΡ†8ύΰΓώθη€:VύανΟΓϊ=Ά—¦«%₯ΊνY‹>΅“γ/θ^/0Ι¬Z±Έ„b;ˆœ€Š:γpν]=ΚψSΐš?† γΨ}ͺInΠG4—΄ŒTgŒžMjx[ΓφΡ’τ”t΄ˆ’ͺξX䜞MkQ@Ί_†tέ3_Τυ›Hδ[νGoΪΉ νιΪ Ρ<€θΊN£¦ΨE*Ϊκ$“†±%Ζ·ΠΡ@žΠμΌ9£[ιzZ:Z@Ev,FNzŸ­s^ ΡWΒΊ/‹υί A)Φ―γσδΛάκWΆ77άPyΠΞήΠώj·Τ|EͺΑ&―pΎmιΈΉςf<ΈΫΖ9Νt£Xυί.„χoαθ,}Ψ-›nyΗZ½6o h3άζΡμbr\ΐΉ?₯kA Vρ,PF‘FΌEΐP][Εum-½Δk$2©GF Q\‡…ώh^ΥΎί€؈ݢΉf‰wuΒτΊβuο†>Φ5Iu†ζξc™žΞv‡Νυά©5»αo ι^ΣώΕ’Ϊ­Ό$ξcœ³ŸV'’kfŠπ_†Ύ ΡΌW DΊ€R­ΥΎ΅0Šβ r(*Όn«Υ|ΰΒ+9ΡνΨO9Μ³Κεδ~ό±­»>ΟOσΎΓm ΏœζI<΅ ½R}MZ  m/Γzv™―κΊΝ€r-φ₯³ν \v Ձβ?…ώΧ΅fΤζ‚{[χϋσZLΡϊ⻊(І~ E’.>ΙζεNή`”υmέsQθΏ ό;¦jVχμ—wΧVηt/{pΣΟb8WsEs—gρ₯ΏŠ$ŽOνH"1#;pA#ΧΧGEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEΩ endstream endobj 227 0 obj 214488 endobj 223 0 obj << /Font << /Font2 12 0 R /Font5 28 0 R >> /Pattern << >> /XObject << /Image28 226 0 R >> /ExtGState << /Alpha0 10 0 R /Alpha1 11 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> endobj 12 0 obj << /Type /Font /Subtype /Type0 /BaseFont /MUFUZY+Comfortaa-Bold /Encoding /Identity-H /DescendantFonts [ 228 0 R ] /ToUnicode 229 0 R >> endobj 13 0 obj << /Type /Font /Subtype /Type0 /BaseFont /MUFUZY+Comfortaa-Regular /Encoding /Identity-H /DescendantFonts [ 232 0 R ] /ToUnicode 233 0 R >> endobj 28 0 obj << /Type /Font /Subtype /Type0 /BaseFont /MUFUZY+ArialMT /Encoding /Identity-H /DescendantFonts [ 236 0 R ] /ToUnicode 237 0 R >> endobj 50 0 obj << /Type /Font /Subtype /Type0 /BaseFont /MUFUZY+Arial-BoldMT /Encoding /Identity-H /DescendantFonts [ 240 0 R ] /ToUnicode 241 0 R >> endobj 229 0 obj << /Filter /FlateDecode /Length 244 0 R >> stream xœ…TˎΫ0 Όϋ+tά–θg€ΐ@±‹9τ¦ύ[’SΫpœCώΎ2Η»M|P$ΘXCŽ8€Ώ^}7«ψΗ4Ψ#Οͺνz7ρeΈN–UΓ§ )ΧΩyEςkΟυΕ>ψx»Μ|>τννχ*ώι/σtSOŸέΠπ§(ώ>9žΊώ€ž~Ώ=>^ΗρΟάΟJGU₯·>ΡΧzόVŸYΕφ|pώΌ›oΟ>ζγΧmdE‚ .cΗ—±Ά<Υύ‰£½φŸJνΏψOqο6ηQM θ ο“χϋ§ž$ρy΄NM΅ γ€ATeRHŒyΜνΟ“Fh‰;―ξi+˜h₯Hψά‚va‰Œ…–΅`»*XS™‚­E’DMjΪA0KΓ‚5” φcMιVΠ&BΛa"#(‡ η@)P τK[‘7zΝ–7z•Kήνt%o€PVnƒς†Δ$Ck^쨑U’‰ΣPθ°D*]1)[˜p…:Zˆ₯&ƒ`!–š\d‚Š¨Λ/VωςA>ίΚ— ­m΄τ—jΌΔ@°;©p5Z™HŸˆ3ΤΐNjο―FΫ«Q# ©Α€4•,Ϊε!icƒv‘΅ Ιƒ%$―΅+’HΦρ όώNΛBYφήΗΆ²Χiς‹J–£l¨e7u=μΟq—(ωώκ‰ endstream endobj 231 0 obj << /Filter /FlateDecode /Length 245 0 R >> stream xœνY{x[Ε•Ÿ™+K²l½₯«η•,]Y/Λ²lY’Ώ?β8ρ#Žp!Δ&%Bΐ u`‘%‘ΊεUeΣRΆΫ„-t-Ω¦d—f P`!lR %Ωπ} v—h,ν™Ρ•#Ι‘$]ΰ―ϊ|?͝Η=sΞ™sΞΜ\#ŒR vDPlΥε[/›ΏΨsZ&β5«ΗWŒρΫGώΟ·@[r54(ξ‘Ν…ϊ~¨ϋV―ΫΌ₯ο…Bύ]„Τ?Έ|ΓΚϋ_ω— θΊ !ωΑu+ΆlδΆ’ƒU-ƒρ7o\-ΏεF¨O²Ye¨!2Θ©‘9υ t₯ןΠΧ'γž:ή¬7ΙΕΤ‘ 5“\αΡ{Œ¬žj%‰zΏθ•C«ΘZθ:FΣΖAƒΝfΐ‡ V«α}“Λe2Ή„£ψ»ι΅Ολy—M/θC‘―Χρ‘ήX՜€5d+ךmz²Go³ι§zτΆsφ΅Ω’nευB3―|w(›Νϊšξ€―#\™¬2©|=J 2ψωhbBV¦E ƒHΜSω\œ“ΛS)₯Λι*Η6­Χ§Ζφ2AΠ:䧜§Ž@ίŒ9ΘχEqjΉ³Z―%«§ξΡι^ΌaԞ9Ižη,(ŠP—7 Š·PΦβ"Tέ€Μ G4&SIf°~zθΦ5MMknYΈ`Cƒ²”sψ •M«"‘ΥMρ₯aƒhU*“_S΅¬»}dΡmλZƒQΉZ]j΄qš olΡ†Άφ ‹jD·š³ρ*£²*rŒ†V¬€Η\όpοrρxΏΕι΄€7b7+αοΠΕ“YoΆΓlv|j7σΰžσǟΰqαΩ»Šx¦_η]tMΞXω|l— $²N§~7Γ’ύ K*J“:φ-*ΫΟ-Ξb›ΪΙΩl©š4=f7™μ‚e­Λq ΏϋŒώ4<Ή‡¬£λ© ˜q-~~Aή•Ž Y ΤΚnZN-e† §ƒ)wτpWrŸζ5ύ>}O’fŒχ卷`Θ’ΒPp*ΗΖ₯ÍΈVOn3ο2₯?Υ;=Ϊτ”IZηΤ­δJgN6b.™:nwEΙΤ{Ή9Ιλ0§³`ΞύΚ»yAΰ­:όxV}•E‘ž/ΙoœΪKĜ₯₯€sκHΦ(οKXtζΩ7—2D~ΰIH*~1λΌΟφmξθΨάw§ άν»£wf§˜}ΥόήMνoπ.Ό!Ψ]λ ƒδυΰgWqu‘NOωqΰsΏ“,ΐQ†ΌΕ(“Σ”3dι”ŠU§ό9•ΕwΚα(st‚μAΣ£ͺS§|Nα0ς¬*Ό‘άο MS;Ι2­I―Ÿz¬ςV SγF‹UOΦOέa΄ΐό­™Σdœr\8»–Σ[‹HFΞEΌrΆz%`·DΚFΓ­½›ητnλοŸμ ΜٜˆF£ƒρΊ‘šš!lΰγ° λέ60pmoο΅ΫzGkGΙ‘ΪΪ‘db€v‰ΐί»Φw”¨ ¨n ²`vΙk¦ηeΩ* Ύ£γ…ƒΫzΊ―hΊ4 Q4^MmoΌ?R=˜ΌΞ«ΦΛ4sιΤCΧφTWC]₯ΠΤΧ,jL.ͺΥΤ\™FΤΜ―`zƒεyδ/œχLπΝΠ/μίΦ;gsoӘW€8μμΟSZ–Υ³6Œ5,C7€κ£΅‹0oν’dbqmNΧ.Π΅Ψ4Σ'< ˆ‘™κΚραλ{»θίΨd7₯Χαο„°Ώ»q(\wA£»Γ€Υz’χŽΛzΆ -άΦΣ΅uΐhtΦ Dλ–€R‹λ,Ϊ2\¦υ©^ΠZBl­ΝHœΞ IƒΝ ZsgΆhΌΛθjΌlΝ>• nηUf»έό1ύqZπsΧ‚nŒ-J₯Fb±‘TjQ ‚f2d)Ϋ%ό¨‘‰‚‚9{N1§κ)v+΅,:ώ/„{’αΞ`[ΛΪΩ]λΪ„τ€Τu@ΰρ2Ώ¨ΰ…gώdγ\ΡΫXΩΆrVΣ¦α“t~ŠuΟζ…LΐήυΙύV ΙΉψΗ~‰ž'βΜνniΰς ΖVŒιvŠΘ€Μ{ΐD'Y\α‚—+!Μ)#/ηVΧVͺ5D›ήΙ;<θκ_uΏ¬ζžνΔθΡϊ4iΏƒ'»ι€©ήQ’ζtœAΊJ*a7όxYTQ σfαsυΫH§ίΙσN'o3ΩόΨp’ximκHeŒΆKkΒ-%AΰβCMΜ{€;ϊN―Ύx XSCc4:t”xvz¨ §F·ηoYΝx¦Y.'τlΆ3 Ε,š–Δ-‚w¬izr~œ—ι΄špντ”n˜1-θ ώϊ& =ΑΌΓΩ©πΓ\ΑΊέά4Φάά€ΰτΌΊύ²¦:«έn΅Ωlxqσς†€C£…0㛣ι]Π΄Οj·ΩV;;%Ζ§@«8Σ)?ε₯’yg€άf—½ήρΉΓ:φtOx΄%zS@£ο‹ΞjΑΈ©|iσΕρΩ—Ή4D§‹hm³ό‘cC²o‰ΏvΉ¬Κ£ ©u%Z£ΗοrE4¦ΑYρ9žp₯N,/Sj¬—`,eΪhK0:/Bm§ΌžΌΒ⌞?Ξ―…ΫφΤ Fi˜F*Ό›Η~‚ξοПψ)ό& δ΄LyϋA™?’Aβ›Ž*l&i―K&β oͺΐ⸝Fα2·Ίj„Λšϋ€@)ΙΗΙ†^Ρ;ΛΧ:6«€0R0*re€e’s:Y½¦s”ά©Τ F›ςZq’Δj6Ωd+΄WkόNSٝ2»^η”­R].s5x―;`Ά₯―Ζ·Σ›qz;ή ΈΣ#tmK]c€Y 4%Jΐχ»JfίΞOΕpsΌœf…ϊTΚ’)&€εΧUε#ΎŸ¨ Ο[5»ν{΅Ψ–^o²hv%Ώ―}«λ₯‘ ‚Z#Wτ½€«΄λ_°ƒ{˜Νg84YψΖa•Ό`ν’ŒŽ„H ξη6Αz1·Πσ©QΞ,Aςύ^•&bΒ΅¦ͺjSϊ₯ς₯Fκw*­Ρθ-}CUrBnͺ"? Œ‘©A7œcΥFό˜QTB™^`A;Ψ—ˆ—3!;μπΙ‚³8Šθ•N23ΞΖβ}«ιΊρXO0iφTψ¬•³CΒfκL§θΟcj»ΜψƒΎuΝΌί1X Βό΄Ρμ:γ]ιž‚]£ΊΜ ΄}~X’χ%eΒ 9…`PΏ‘ΰ !Ψg-0φa"ΚόδΡO7 9y荋:Ψgχ²3­ψD ΘηHδ·)Λ9΄ΗmΒΠ{pOP ΣAΰž€§8…P‘ρΌ―9R&;ϋχœό©θ‰:vΦp·©mwΓXhΩ0―cΌΙΧ΄›œ&A(΄Gΰω¬5-‘ŠΡΧ^Eμ^Ϋ’ZΡΡ°°£Β<ΗΜ {¦ΥΗHΐ!τ~œZj8o²K%Ka6NλΞόή—½M/a_zrWž œB–Ϋ΅vwYϊUΉc^΅ƒ|¨ΡΑEC«ΣΠH3<ϊ˜+Οϊ’”τRl*PβίBηά―³”6464j=₯εkRqΉσΈΦ8ρώΔΔϋ›E7―SϊυΪΧΧ–«Ω­Ω0Ν1QŸ’ΫBΐ`·η܍Ό §ΦΘaWυhsC©εΈ‹W—›_RιΰŠΆ™rŸ0jc8Σ‰žDk V™vΙ€Ϊ§Σ+ J…Κgs{y―  ΑAƒ·{λφΎ*κ1ˆxpˆλ†χ!‡λθ©={ͺ§β±ν³¨e^―ΜγΉ«°Κu Ί`ζ°‰Ω9Šͺˆΐ9ΐƒ+¦gΜϊέ`βulοg΄΅ωT ₯^©ΧιόήϋDa•xD/ϊAPΥΡiΤU3ΨΙN’oq™‚Θ$Vσ£υ8CzθY„zυτ€\n—b^”x;uΗνn“ΕΉέμv›·;ΧCΥ΄έμ’Ofή΅Epuζyšs£Άι3N –$%}ύδ-˜^‹ΰφ]4 ϊY‹m­Ν‰^pΫ%‰e}Γ ŽΗ"I‹ΠΙtιz―/Ά¨>9s4Tx“ξΦ†ζ £·kν:Φή^¦fIKηϊζΩαv―Ώ‘^΄ΧΩΣ³tNxJ\P[‰ΦΪ[|mކ&OCc*vŸN©ΥVθοkκω/&“θ-ΈΪΕՁ€@&Y@4>`―°ϋδw^Ymώqά»Π‚±ΡςMwΟ@&’>*;%;cεΤΧΨΌΗ]q€J™ΘιŸΘN1Nyάjrͺ$ϋPΩ— ξχHKA^Ec\)j?+΄Π§…s½T’½hμ θϊ™s―‚9W! -q Ζޜ-q,σΰ$<« |ΚΕ8@RκžPώžlBΥ ί7aΰ°Ηa˜―΅διω^η«AB«ΛΎ‰ΪɐcCV²žΟ†GQύYAΧv!Όw¬sΈΠχƒCnDCΘ ¨Žμ„ςσπ6JΰAΤϊU@–Κβb”\εΩ°πjε|σΊ/AΌ©>SΞέ ΫξΜΰ=E#€1 2@  GΑχ³} ύd«C?²Γ˜w±;s€ψJΐΤΝp›Tn\‚T°†£€HεW΄Fd?j`Θ­Y΄^Y΄β·Aώ30ζž‰βΰl‘‘fΠΥT ΠkΰK)Θk¨|ͺ‘Ÿ8PΙηΒ‰R8‚T²r€ όf°rβ1π£#(Θςό;“ e1q:Šlω9X–D!r7Jq—CŸς†„HΝςβ*)vJΉ¨TΚ)Oeώ‹‚»κγpΊλΰώ x.\γθψύP…|σ8΄qH-{"›―€<ί&ετχiŽζCZΩCΠ¨‹γα2ΐ‹(ΐrίo‘†lΚΌGž>Y™Ι»Y9Ή‡aΘ(•d“ς “' ΆwP]Ή0κΘί© ΈfΘ΅ΕvrpNG¦'π’v€Ί°~šΫ¨?ήν+ΐΧ4`wŠ2).ςβ›S!/Ρ£ͺθ…q}Θye”όTzo—δאwXμω2Η(89τQ_Y ϋΩ/Πτ pPR_&WΑΈG‰K‘Q.ό^–|?›Ώš²9rω§ΰ€qτw€άoƒΏoχ΄Hds'‘g mψΤJ2ΓΨ‹‡ dδ”ς€)a 0y(vgsΣ•Φσςk.ΗΝ°C.Ύ%θ»V›ΚΖ6‹ΊfΤ—/‚σΡSΘΐόφˆœo²3έίw£ςι½\λIΧi8λ·δ jc~K}γ稉ωμίΓ8κΏ”ήΜrnUf9ψγrξήΜχΘΞL5œΧ~Δό“ϊΤύΜΏZΙ“ Υύ‡π<†/ؙӐ‡&@'šOՏ»₯q‹³:rΉΨΊ„ϊ‡€:–kFΉΩπF"ηο’Ή”žΘό]AΞ₯< ŸΙ@η₯m“€Ω¨Φo>¬ηˆ‹[‘ό‘ƒtD°wjTγŸA~»Ζ‡ηωΘ>!ΰ-/ώκ;‘ޘyŒ» œ°β1e”7΄Θ…ώ·μΏD€Ίqπ«ΫR‘HΫρΤ‹·A~έϋώ‹(‚eβCΘ ΠΏAΏ‰;τϋn ~@Ry‘Ϋ•y‘μΛΌΔκ‡ΐ/g^BΗQ·ΑΉΞc+2§Ρ^eoΆή• ϊiΈΠύ “ΊrΈu‚\L6ϊΙ[Λ4ΖhiŸ›Ύ>Σ‚lΐ ΕYί!°γίBέ‡¬0^Ξ52BδΗΘΞπuXkΨβ4ΌŸ;_ν‚½ |Ο+A›™ώ§™¦ε…Άόφ|H6sηΖCμΩ9K„œH}φπŸ}°ΎϋΐwԐΏh<]ΑκAn)r”ΈΐV‡d ²r7΄οBϊL!λ†\υθ=λOω/…u¦PSω3iΪΖlv Œίξϋχ0Yvd΄”½ΖΞπ°o> /FontDescriptor 230 0 R /CIDToGIDMap /Identity /DW 725 /W [ 0 [ 625 703 ] 2 28 0 29 [ 777 ] 30 38 0 39 [ 700 ] 40 58 0 59 [ 625 777 ] 61 65 0 66 [ 871 0 0 304 ] 70 93 0 94 [ 982 830 ] 96 131 0 132 [ 623 ] 133 140 0 141 [ 688 ] 142 148 0 149 [ 661 ] 150 174 0 175 [ 737 938 ] 177 194 0 195 [ 675 ] 196 223 0 224 [ 601 ] 225 229 0 230 [ 703 ] 231 233 0 234 [ 621 ] 235 254 0 255 [ 367 675 ] 257 261 0 262 [ 683 0 0 302 302 ] 267 283 0 284 [ 569 0 0 300 ] 288 292 0 293 [ 938 682 ] 295 299 0 300 [ 675 ] 301 330 0 331 [ 703 0 703 486 ] 335 339 0 340 [ 543 ] 341 347 0 348 [ 401 ] 349 352 0 353 [ 682 ] 354 375 0 376 [ 728 ] 377 380 0 381 [ 557 539 ] 383 397 0 398 [ 631 ] 399 678 0 679 [ 238 0 195 0 0 288 0 547 0 195 ] 689 693 0 694 [ 469 0 0 273 273 ] 699 710 0 711 [ 234 0 292 288 0 188 ] 717 727 0 728 [ 293 ] 729 759 0 760 [ 547 ] 761 795 0 796 [ 731 ] 797 819 0 ] >> endobj 230 0 obj << /Type /FontDescriptor /FontName /MUFUZY+Comfortaa-Bold /Flags 4 /FontBBox [ -212 -289 1272 1264 ] /Ascent 881 /Descent -234 /ItalicAngle 0 /CapHeight 781 /StemV 80 /FontFile2 231 0 R >> endobj 233 0 obj << /Filter /FlateDecode /Length 246 0 R >> stream xœ…UM›0½σ+|άVxl)BͺΆͺ”C?Τ΄?l“"5€9δίΧΜx·K*9H‰ςβ™yγyΟ89|: ύ"ςοσh~]?ΈΩ_Ζλl½hύ©2@αz»DDίφάLY’·ΛβΟ‡‘³ύ^δ?Ββe™oβι£[!ΛΏΝΞΟύpOΏ^Ž―Στǟύ°™Υ΅pΎ …Ύ4ΣΧζμENiΟΦϋεφrώEόΌM^ aΰfμθόej¬Ÿ›αδ³½ O-φŸΓSg~pwλ’³ΪŽaxύ ―+φw3Su€,‘ζ0ϊΆωa,…γh¬ίΕϋ’XpXY2ŒTš’h)¬`¦Ro(Š{ŠΠ…UDjΪR%£&M¨<…©Ž£]zO:RtDQ1…’iŠJSXΕP°‘PχOWD±cBΕCά5Œ‘V22„,[?ΠΠρF=ηκzn]3½gzύ@Î(@FŠ­†εΘHA‚ά1" !N·ŒΈum“τ€42ΐX7­(`€ E‘dϋ™΄’P’FP²w $] Ρ‰†Ε„†F šOžΩŒ#4δ0GkΚ5ά…‰]TuκŒC΄ŸIŸdϋαŽέTΘMQsW£= ¦@ψ› &ΔΒ ##ήAA`ΛΒa—n΄₯‚Ψ²'±Jʌ-{QXυzθ“–)μJλΫ/ed΄–ΓΘΊθβξ%‘."2rmϊ=ύϊ_ο™·ΫΑ^η9\ tэ°ήύΰίξ«iœΦ,ϊό θςG endstream endobj 235 0 obj << /Filter /FlateDecode /Length 247 0 R >> stream xœνZy|՝oFΩHš‘43’|J²%ί‡dI–%ŸςΗGœΰ„ΔIHβ„@Ι.ύ΄„–6₯‘%|Ϊ…eJΩJ9Ϊ₯…†(Ma[Z G( eI,νο½Ω²Jh)5οσΣ›7οΝούΞο;„BΤ†TwαƝko}~a ή\ŽP‘{ݚ•«εΟ-= Οα]dΌ0ΤυBϋ9h—¬Ϋ΄ύΪΨ]h/Bζ[7nΎ`eσ‰(΄« Δ=Ώiε₯[؝θy„Bλ`|ρ–©5[Φq_ό΄―’³κP!¦Ÿ5#+ΚCE¨‘m^Xlˆ„Ο‘ηB{Œ-›χ/^΄’֊ƒ]ΤΑΘ―§a|GGηŽρP‰Χ¨s9fC- j…'ΐ 6TmƒB˜ίΒdk΅(Λβύ£Χ‹ΕΦ];Ίoίς}ΓΓπ#‹DΩΨϊkFG―]λ^ΌΌσφ/ ί½ΐ·xnτAdAΌΝ{ ¬ρAQ„Τ"#­ΤSψnVΩK’UNύN9υ†l%ΰοώ}ΐ?ο/ρwp …°¦,gXˊ0λ‚Ά˜υKβcy&«ωB‚G:;?ι ‘=άDzL”ΟΦcSΒV«]5 ,P4k’ήžΜƒšΔ"±5°(γί’_B)§¬ZΜρ4n$υt;υB{ ήͺάΡ}ΐέ<—ϋ ―™οΙw0ΎlΗΐψb9 ΌΘ2 ΩΟ9μLNΆ=UU=εδ©eΨ2ΩA˜UχUTφV3eόAΗd‹* »8—dI’`ž£₯‚‘ΰ(ΔΣ„GΌx$ ’"¦^4).Sκ¨CQ}ο˜^Εάβ “ΡΜ8žΎέξdι§ο€HPm{ζ̟3ηΛpΖ6B ŸAŸς(ͺe,Σ_d–e Δ˜νΣw€‘Τ(c—C”Ω NΟF™šq α&gψGcΧmˆΗ7\76zέΖx|γu£];ΖκκΖvtu«΅1±‘φ% ƒΊΏώάKΊ».9·κn¨3Y>Dq΄θ4€γ|>ψ΅ΟΛτ§ϋ§ΪΪ¦ϊΙς‘ΠpuυpθͺVϋΤ‚Ύ­νΏ‡`Z/ΓΓ5€€Μ€€a„Φό ΡHPQd‡σκ?BCζcΥOJFƒΕZ”c­n«:ΏdqχžΖΞj!O―³X j\Ύd]σ9Όεβ₯ΝγυΎ˜W(Μ1-JΉ'ΫΌ±r£νβ‰Θ’X!‰«ΆζΐzˆV+…ΐ2X…5 Pq  Κ©—‡C`ΚΙ/€ΞλΣnAažtXIΫκ@${'˜gUd’X0“7g@ƒ—ν"ŸμL‹C2ICW έ—γ_Qpʏ‡BγρLkψςnΰ/"|ψ¨€ΦOΨ)vŸ=2σ΅εhž²!xΐ&‹€ϋ‘Α.ρ’ώ;ΚaV2σ2{ς‘HΈgτ’Ίοvή₯—lζߝΕfqϊrf›Ιb6O_Γ\εφ(Σ‚]—M_i΅AT5§O2λ™2€˜μ4ΔSi΅™8ςrΤ›z°c8ͺ€ρ‚…»zϊφ νξΓEΙmνMΛΒαeM±ε‘Θr\&ΚφΈ¬‡ήα=}}{†½Ϋ’έ‘ρΔD4:‘ˆ―ˆ΄Kβ·†¬oΑ€ϋΏ]»ΞξΫζˁ7ΒΌ’M”<›’Tα¦εαπr ‘aΉΎwχ >f“$[κ₯ژ*F·:³*؞hξΝKηh­EοΜߘ_J| Ήˆ§@o ωf°KΫ·Σ©!…Ψ9)z‹U›θ€KiΌ@ΊT°Ϋ¬'Ώ’ ŸμžŒΓξΑQήW›Β6 ?c·Xνv«ΕŽhD—i]–A«9mπfΠKKb5œ9vΎΩ νκκέ3 6ΐΥ-›C—L¬Ω\œ[°,Ρ8.¨ν½|Q|YCΓ²xœ†±Βžžž=‹œύΫΪρωΉΉ_RYΥq°)χ™‘+`Wx’ΉyE8Lμ&²Žƒi–½‰5 tɜύ‰žΆ4|tFί{挺‚x]”$|³(׎„κ‡j’LΫd{Ο–v9Υ‘υ‡νΠ/it‹ςqYΐΊ–α2GEλ±ψΤ’Τ)8αθ€ QJ§‰\θ)ζ}ΏπΔ±‘S$Š&αωΖwϊNjΏ6ΈζεRi“ˆvι¬!1 θ%‘ω…η|\ΚikΦ ΅xςΘ„ωΤ~`&₯VšσΗ#―™B8 =W)‡$2‘Σ­’€Ÿ`[]κ->$μ14»ˆ„ΩxbνΉ²VaνΛsYm.GΥ`ˆi’Όž¬ŒχšWΨ ˜rΰR‚βΪB“Κ‡zΑ33&ΫSl³(χ7΅ α.άΈͺ%Ύ,$M‡2ξ€]ΓQ0‹τ€Š{/ξJml\Ϋ•ϊ% Ώ@‹ Qλio» ΣKp“DΘι$X²ς¬’…©ύπ(ω¨ΈΘ δ–ufEΜdΦ™ zρπž^H αέ½Έo7ΐ3dIi=I+7#Ί#‰«@%] dζJ˜ƒ"δ‘^SΖ‘‚ …}ήL0Γΰ° “›<+YkΑ›•Η38™z FWf/Fˆj&SΝ2Έιl³ ’=ΔΌiΨι{6ͺ«Ο,GŒœFYΘL&φgVXRe§ML}ˆοZΙyc1ΥT= ΑμΧνbγ+šj‚œΞž'6Ž…ό6‡Γ„GZV5Ί]V#ƒυžΞΪΤa‡ %}©rέΓΔΣ'ρ Π,DυΚ†ΎhφΎ-³π©Χ&2ΩΫ‹cW|{‰IgΆCuύΈspΝDd<’\YhΤYψ"“«£2ΪαjŽ.+Τ—•ρ…&£Ξ”_*)©5 ΓΡP§·&`ΞΟ5θω‚Όj―βuης΅­₯΅=e =p3σši$‚Ο”±xφ@JZuαΕu¨r’6Op8m©?YkšόΗρ4a”P;¬”sΦ -τrΞ¬Όσws! crάKD˜IΆuςFŠLpŒ†Α:r&KšI<ώͺΫR2ωŒŸθΉKΆwΔφt{GVX–Γ’“g΄Zά†#εΟs‹‘{™wγ£f·Α`4§BψG–\ΐǧΚά„ΩΫίΞjΏψ‚Ω‘»‰³Hf‡ώjω έΊΛΔ«Œy²s“Ξn6Kμ~Ξa1៹ ,VXηΏaKjώZGJU™,Πu[j‚7l„“>ΨPΩ9ΟjA ˜΅ˆ•96ώhT1pφ@”Š`Œ·ζάUx· ΫD‘FήCf”Z/Ψ±ιΑΚΓΉΗκο2ˆΉ’ sŒ?wΏbΞ—ψ£ς„|Α‘o~=φ λ‚/s€bH$€mLSƒLΘE!@.ΡΩ€Ή(ηŸ1Μ=˜cτZqκρZS—[έ9Η F«Υmx9‡ϋƒΞκaž.ΆX<ӍJڐkΕ?†¨SA«›ξ@Ώ@?|§Π5KΑήpμJ$‡oφio+ήސΪξσαm>_κσjνφβ«RŠώαWΘ/ΘΑsY«Š˜+ηξ½NGΜ‚ώΙht²`}4Ί~ νυu‡Γ]>_ΧΔαΛvή3±βžKw^18rΝ²ρ}‹F_Ύob’$–Y ‘–ΚνΚ3ͺz€Δρe΅)W”M–―κM:Q"W_πιewθΓ «ΣmδDQ;HKxUͺΌΐΐYžv—Š΅½ΪE‚bΒ΅ΒdeEW€ά $.lo_“J€4Β1υϊΛΚγ΅yIΨ6•WφV“ΔINΆ$&»<‰¨3uΤi₯w/QX_ςYj=Γέ‹*‡ϊŽJυ!BiΈUΥ½ΉΝ!ŠŽͺ…΅ƒηT¨3ϊβ%½‰ŠŽRI±UmMηE=‘βPgqλEϊζΙ€θtŠ5}•c]υ}ε ƒμkς…{1υΤηϋ¦’Ι©δΆ^ςRν‡_Eΐ6β5Aω>tΑα ςA 3δ²Že–B`κœln†C1ύ­ι«¨θ«©ι­¨θύڟͲUΦηάN:747oHΒΐފώΪΪώΚJς[έψzΙ–oN½ƒt¨5}б±Ώ–διœ“ΜιΗ&{¦;RdTO:NΖεTždr2›ΧwTu——uWWΓoOuτœ`πœ(όβΠXΔ.ΖEo(‰q§ucgΗΊDb]GηΖΦξκ:U™Ίj<†GƒΈ~, &=1Ÿ7\˜ †{IVΣ'Πh ΰέΟdώ^±Ριυ)N―Gπ:]^ŸSρ©c'Π=h-ΩΑͺc#δŠ)σ…1šlv‹έβqϊ…|οm¦\«+ίasΪΡUX[‘ί.†ύ{Μx=S σ3χ|°qΜΧO ‹ΠEf‚ŸsΟ†lΉˆηEΩiuz½N {±@ˆΣ”{Ua^ΰ«>Ι‘»²¬ΏΌ|Xj—ΩSaXJΎ’FŸΏ«&Ψ λϊ†°qY{ RΒε |Ύ{e[ΩrOA€#hχ—χΦ’%Άk}"vA[γ`{I~wžM¦ry] F₯8†nΐw{/Κμ|§x<8ζqi:`δIί‡ο|6S{kΉ K ·PRrq“ΞΑΛCκI½cΠ#³Vοsœ:Α‰§Βi½Φ€k‘Ά‘ŠͺSH*dΞgy›!ήΤη]‚Μ]Τεδ7yΛΞ·wξΙτ‘ɚ™?Ήh¦“²,ςΝΔκ77έL ³Ό~Ϊ$Δ7SoT§ω&+g­žΡhf₯$‰Ι­NΟAMƒ\^ΣΣ€vοC.~PϋDΓπΘ’ΚΚΖPuάεƏρ:ήνJ5—Φ CΓ5Έ β_\qυ&CK«ς²™gΜ6j—DΫ6΅vx{όεΝ1Q؝j3Λf·?YΌ°@ΏjAΏ=^ΨζmMEΪκρzήδ6Š΅“ψŸ`FΝΌ??oΘΕYς3W+‚—RŒΘhΨ­Ή_ύΚU«‹VXο"–ύ-ΌA/”v‘ϊ•’ž‘tUκΈξ}έ rƒ±¦ώΓδo0gHŸ—:u·ξ}Κ)λ»ŽΩŠΜ#Θςχ&φQ$b@«Y„ZΞH τμ™šΉ­ώDi+ςθά0η’IeϋO΄>Λι?ύžY¨υ•οB]―υΏΟ2Τ―3kQ5₯k‘”ΞΣκΥL?ΠAΔ³G`ΎΨ\bžΡžoy> ΪŽΒ”΄Άξ ΤΒ¬9V«20“π|&Ί5‘ˆo»α»k‘u>±!θϋ„ μeeοDΒ|bG5ΜUFE?CusθvΤόiW%sœY υ™θq Q3 œϊΌφ§2|’‚œγΜνιi _cšZΔι€r±'ύΦ”> u”τ3-ττ£|x;\Ύ-CLψj„έ¨¨―£u7>ŸΟ~›Μ=Ν<*>bBQJŸukώϊψδŸ%sζ™ΙCρ3’5ΰ0Jΰλc>αΏ •#3σ+ΘΏωT‚Κ€„€RΠ9›~ψ8 τΔΝΠgσ^†8:όΞrς?(­…<νDl ΦιP³EΨAθӈ9¬Ρχ`8BqXΕΐ ‹†)•ώ!v΄IŽ-d‡€g5Π"GΖύήΚ„wYtTΌ’Ο’V‚νΗ F³«Uχeθκ&g=θ·²· |Š}OΒ|«Σo3ί>nUfͺΘΙ^γ@Fέ(<³06ƒ' Ft !ΊΒn{aφHx°qΐΪωvΠ08£#%Β‹θPλ'ΨFβρΛ¨Y ±¦Gυ„π»Z^dε7kC>†A•sβ!γ  b8[Ž3wΝδΣx‹hξΥ₯Cιmθ#±λΩchϊ†Ωgφ 0ξ r°gΐοa-φ—ΐ7KP\Γ„·iΞίkϊθοΉρ~.ΠqΜ] Ήσhf°e¨˜Κάc›Ύ οAFφb '%ˆη~MB·«BuUΫ3ψšΑΈ3ΨAΝ„Θ·ͺ'ΊP¬%9B|Fbω<δgώΩ©οaΘΔ&έ#υύN-fΙϊύΐƒψ)ͺΕ£°&’Έ…Ψ`χ£‰Yφ 0v5ψ™πΏ?½…HoxάΒή§‘«Uμκτ=4>IΆ bϊ¬Ϋ]ΤQ¨+ΐ'‘ƒSόk@Γιαiδ›°ζ6‚mI ϊΰ\σ8œ€χ’AΌxξEAπQIΏˆ P=ύ…L KȌkP;‚ρ~•?cοL„y$ύ­"·C>­j‡!R‡€Κ€ΰ΄Jn|θxςΎ¨ δ[Jε!†Eα|πχ^*‰3φ[c¨(€~καΫB„1xέ—fΝK¨z^»’ݞC ˆ"Λτ/UyΛY₯C+SgYnΒοΜΖKKΣ_,ž‘bž-lξίT‘\Ι>1[tξy₯m¦lωεή³*οόuE_£_ŸUώU+Ώ>ΫΒΉΉ-YεaZžβŽt18i‰g•k Og•ώ–’†²5ηΆ¬rbnΙυΟ”σ?FΉ*χ™b4c§••((ZΉΞψ ρ}Ӑ鳦'yΚgQvς7ρ_§εYώYs”ϊ¬2HΛ%ζ[gΚƒYε9('Μ',ε–UP6όΚW>‘ςηS¬ζO«hχ’λΠ8£Θ0οNR‡πƒ8ύΉ{tϋΠΟΗΐ endstream endobj 232 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /MUFUZY+Comfortaa-Regular /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> /FontDescriptor 234 0 R /CIDToGIDMap /Identity /DW 699 /W [ 0 [ 625 703 ] 2 27 0 28 [ 695 768 ] 30 34 0 35 [ 770 ] 36 38 0 39 [ 692 ] 40 58 0 59 [ 625 768 ] 61 65 0 66 [ 844 0 0 278 ] 70 83 0 84 [ 614 ] 85 93 0 94 [ 981 825 ] 96 100 0 101 [ 921 ] 102 131 0 132 [ 612 0 921 618 ] 136 140 0 141 [ 662 ] 142 148 0 149 [ 655 ] 150 153 0 154 [ 819 ] 155 175 0 176 [ 938 ] 177 194 0 195 [ 677 ] 196 222 0 223 [ 707 595 ] 225 229 0 230 [ 707 ] 231 233 0 234 [ 614 ] 235 254 0 255 [ 366 677 ] 257 261 0 262 [ 677 0 0 289 289 ] 267 283 0 284 [ 572 0 0 282 ] 288 292 0 293 [ 947 677 ] 295 299 0 300 [ 677 ] 301 330 0 331 [ 707 0 707 458 ] 335 339 0 340 [ 539 ] 341 347 0 348 [ 402 ] 349 352 0 353 [ 677 ] 354 374 0 375 [ 553 740 ] 377 380 0 381 382 548 383 390 0 391 [ 549 ] 392 652 0 653 [ 571 378 581 585 647 627 579 0 593 ] 662 678 0 679 [ 216 226 195 0 0 266 0 547 0 195 ] 689 693 0 694 [ 469 0 0 256 256 ] 699 702 0 703 [ 391 ] 704 708 0 709 [ 469 0 234 0 281 279 0 167 ] 717 727 0 728 [ 293 ] 729 759 0 760 [ 547 ] 761 795 0 796 [ 720 ] 797 819 0 ] >> endobj 234 0 obj << /Type /FontDescriptor /FontName /MUFUZY+Comfortaa-Regular /Flags 4 /FontBBox [ -212 -289 1272 1264 ] /Ascent 881 /Descent -234 /ItalicAngle 0 /CapHeight 781 /StemV 80 /FontFile2 235 0 R >> endobj 237 0 obj << /Filter /FlateDecode /Length 248 0 R >> stream xœ}SΫjΓ0 }ΟWψ±{(±τ2†Ρ1ΘΓ.,Ϋ$ΆΗ8ιC~ŽΤvλ 6δ"ιθKHι|,m7±τΝΊ‚‰΅5Ζαΰ5°φM„d¦ΣΣΙΒ·ξk—€!Ή:Žτ₯m‡€(Xϊ‚γδlρ`†ξ’τΥπέ³Εη vupξz°γ‰RΜ@ˆžkχRχΐRL[–&Δ»ιΈ 9Ώˆ£&Ρt=]­ΑΧvIΑΓQ¬x G%`ΝΏ8§¬¦%3ΞΏςΡ_΅Gž,πp.ΉB랬΅’$D‰kΆΦ ŒkBoΥ_ q#ΡLΗI…@˜„†8©0Λκ8©ΜΟΪσ'*ڌ а›‘Ρ…rψ+!o$2κ`FJ+jdΆ&η–œYΌ˜PΒ6q₯œ$r*f-P)§ξNNWΪnLr)γmk¨¦&G΄Έ&ηm^‹Λ0λƒχaŽqwp€ηΡν,\ΦΛ nΞΒηI€ endstream endobj 239 0 obj << /Filter /FlateDecode /Length 249 0 R >> stream xœœ½ |TΥυ8~ο}λΌy3σf_“L2™Ι2 „@4OVΩ· ²ƒa+*j( ˆ¨hwΑ₯Š’%@ΐ€φkj­Φ*…Ά’«Π—(_›R2σ?χΎy!`ϋτϋ›Ι}χΌϋΆ{Ο~Ξ½o‚0BΘ‚š‡΄™+—GŸŒ|π΄<†8qΞ’Ή‹ή½±ώ€OCΉaξυ7ΞΉϋ„l M:oφŒY' WνBP ϊ-ς£!0Υ贉h*΄ά‰ΖΓW€φp0Σ‚ΚΡ“€‡'Ρ!8w ΊD>Θ|nCwp‚«ξ@6T€@cΡbt7Ύ:³MGΗω΅¨ ]n@KpS¦.sOζώΜ3θηθχΫL'²’š ίC™o„?gώ‚zΐ[ΠΓθ8Ύί²ιπ”&8σq΄=Β₯xœ™›9 =ΘG?>πh:„ΫHξ>}Žx57ξςt¦9σœA)4=‚βΎx8Ι¦gFe!ŠmττWΒεx žLJΘbς·ΙπΔήπ…ζΎ‚»‚“x?QΙaξi~'NΜIŸΘ؁" τ(zύ Ϋ`€QΌ ΏN“kΙ£δoάόσό₯0κkΠ"t7Ϊ‰ώ…]Έ?‡§αyx5^οΓγCψ>E ΙBς-7kδ~Ι‚ο~ΏVX'ά%žJΧ₯ίH!ύ―LŸΜ:4ψa τ~ zFvFΒχ8ϊ°ΫαΕωxΎΎ·β»ρSx~·ΐSŽΰΏα/πwψŸψAπI˜δ“ψΖΘRςςyŒ†ος5ωσs\’λΛΥpυάbθΥzn3|χqεCόa>xξ#lΆ ;„ΒλΒiQ•~*#ωέσOw–v~’Fι ι­ι=ι–Μ_‘h,δ‘θύ ψ.zoŽΫ…ώ„Uΐ]—βΛρΥ€™kρ܈W&oΗΰŸ³ΎΏ Xϊ }Ά‘λsO— "cΰ{ ™MΙfr?i!ο“³œΔY9ηεJΉα\Š›Ν-ηnδΆrΝά»άΗάίΈ3άyψfx…Ογ ψŸδ‡σΧς+ψ'ψΟωΟ…ιΒ;Β§’".Χ‰­βJύ€Λ₯±8)%έ+ν—ή“€;φ‘—Q·>Α­α†rϋΠ=€‚’ί“ί?_‹fq£p*ف7[p )V‰Ι@<ζ€λ7Ι6r† δFα‘xZ@zw=ό PΥπΏFνό«0ΆίÝW‰*Ύ•|+ͺhF€žωŸδήAΗΈγXβŸDρ φγvς7Έΰ—όεBΚηCΏΰρ-hАrNή|<Ώza"ξƒΏη2ˆ#£‹ͺΈΏ£΅h!ω3j9ή€Δ³ψΉθTW£ΟΡ³ %Β b©θΕo“ωόFβΖ-ˆπΟΓθͺq!ζΊ§ΈGΔoΙ‡h:Μ+θξEθύaς nZηά‚Φ‘ΖΜt£PΗΟEžŒβό Πn«Ή>|>Τ·V™:m?HχAΠWp£ %œs5πΕ$Џΐχ!Πΰα^ΐ‚ΨZϊηN}π€‰Wθ΅—_V3p@uͺΎ•}zχ*οΩ£,YZR\”ˆΖ ς£yΉ9‘p(πϋΌ·Λ©9μ6ΥͺXdIxŽ`T646¬!ڜhhζ±+―μAχc3 aF·††ζ(4 »ψœζh;-zρ™:œ9η’3uγL½λL¬EkPM²θΠX΄ωАX΄OWπέCbυΡζvbπfΫΞΟ‡ ’Cσ†D›qCthσ°•σ6m·ΫmUΗΟVz”‘݊@+@ΝώΨ’έΨ9fρ°› ٝjΕ† mΖ†Π4sρ‘3f5W7tH8?ΏΎGY3<3v]3Š jv$Ω)h0{L³8ΈYb‰Ξ§£AwEw—΅mάΤͺ‘λ’κ¬Ψ¬Σ뚹υτΞ$rBlδΈ©uΡ‘²Έ9ρ’=γxcY¨Ω=ΈŽ “,DΒ; L9½λdΊS§6σqψSΟj•dΰJΦ‚£Γš΅†+m½’Ÿ_^Ԛ9M―bΥ…Λ²έlΌxΰEϋuOέΘA‡ΑTŽœ8uγFε’cΐjΖGd+ΰx4±.?:ΈMɌΓ_k¦­?-υαfP6˜žόg4ew/:1œ…λαCΉ³GΩ0Pt7‹E‡mlΨ8£5Σt],ͺΕ6 ―“Χ7.Ϊ`2Nkζΰ]αζa›κWσπ ‚νŽα γvλxΓ„©u4ˆ6L¬ΫC0ά0¨~w!«;EHg­„ΆFΊ₯;h$†Aξ!2;?|@G¨‰εY۟يk“Ν6ŒfΆ£M3Ϋ΄ρF›ΞΪθ‡κ˜ΑλΊsΙϊΐ3[@ΰ±Kε;σqΨ`0Ίη£\Ϋy]@ηP”o£Ηλ2ŸEŸΐB—‘~ψ2ύ·7y—ϊ–ϊoκySω:ί³ε#ykΞΣ>rgωΪ~dmδφ|βΓ ώωΔηΥ} χBξ1YY–CV„–†Ι t³lτ― “η½Ώπ‘΅Ή£d£²6Bή‰ΎYDω^“ƒ‘7=d~Ώƒ>2ί?»‚Μ.Η“+¦χ#Γ*¦ζ‘QΎAa+TGαΒ(A=zδφθ©((μσεx£>_4zPιαQ”‰ W–δΰ¬αu9±kάKάΫέ\Ή[wχ_rξ ΰ@+™ͺG‚—η.ζΰœώύKΩnΓΆν½―‰JXZPΥψP ©I΅w€Ϊ΅ŽΤɎφTŸD΅'ΫkΫΧΫ{&ν·hoHφšυvZi5 θέ §~όAΩ:.б‚’DίΚ~U Ί­θΖ\ΐύͺό’δσK ά―_ίΚD¬@τz|~ŒEZWτιΗͺγM½}α_Μtψρ­―₯ΏΒRΰ+½ΖΟnΊqQ:wΕΠk‡˜‹αQιύχΟΉη§γ^ziζΜ‡V?Όα£ Kοtϋ―[ΧόατξΊεΕm«ΧM»wwΗΠy΅#―½fHΑΘΞΎψα)[FΤ·ΝΞZG€ΊLWŠi.IΦ΄V\±m³ΛPλNi›ύΔi\”㸝obHκ<ӝiG΅5΅5tό8Aœ•Uύͺ*D Ύ^ γγ[~?jκ«kn,Ί,–ΔΙτΈWρχΨώΝ±ΞsGκ7n}ε—ιΌtτ’ηΟΦΥbR¬‹’aδ²Π(Ϋ8 u ΪΖ]cέΣ’idί·8 8Ωb³1ΰkέ‘(d’Γžg'φ]Ω>&αsI?έ1δ¬,Jΐ·Β^•F:Χΰd²ΰ²’›ΦΌ:uΤατ8|υΥ[7NύγΉΞcί€ΏKΛΠΛŸΰ΅ +hτ>Δg§ΨŠΗκ ΜΥ‚\ƒΒΑϋKΖ@”°|ήν jΫ­OR–κHuœΤΪk΄TK·Z»Φَκή½*ϊVx=’TΤ―_ΥώCc§τ©ΊjΌ+1*8c<χ x©λαΉŠλBScά|β·Γρνό“Λ¦`„νΖν:tQϋ“ωœTf94αβ2ŸμρT“ΦΜ'zΤSύ ‡ ·ΫΕn%Β8”‡ξ"§γΟοo{οMpη­£]3°·^θ™Lέbp{2ιΕ?Ώ9]Ύ> w ³"ΌŽO0ν_ς% kx‹<τΌΥ"Biώ€œΕJ#άΉξOqQ ½{Ήa”0ώΠ‘σΟΑ`H¦4W½pξl'9PΥA“”ΦΜyXZ³-‚ πθ~ Ι2݊<έJrφ€³ΊΥj…c"έΒΉΖ>QιΣύ+($*t+ωθ±cV‘=Xaχa[‹έŸΑƒ±έ| Θώ% ||*R C―WUq’E₯[mΛ΅^Ϊ\yž₯AΫΐmΦήή۴ӚUκρd2V›gmΦώ‘ώΓφ»…Wyoη x^΅ΩeQ’T€eˆήtΔU%“PTR=pˆpmσ6.Κ«ΈΚ’+rΘ‰­d‰nA²ϊ…Φ‹ΔV„±Uw©Q4[βƏεσΗyn3ωVŒuλX΅M:r›U¬}Ν!–ΘmR“D€Ÿ9ήΐ f ό€’‘ Φގ΅5‘φΪ“5”χΫ)$Φχ °šέY]½^{γ ϋo¬ŒΨkd³uΒΘζ\0a-Όƒ“₯ƒ™ΣΐΝίχ‡O=^ΪΘΔϊ?}bΐ—1.Ÿsηs‰"QβHΕHέΗ;;}ςCόΏ+ˆTΟΓ―¦‡©x끟ά}΅w[ίΏώr’TŠο8€x T‰Υ*Nβωa±Ι±9±e–Ϋ-βόΠ a‰e™u­°Φ*ω,\ ¨4Χ—άwΚdΓS-”K( ‡m6€,nWniiI Šδδ¦σrsH΄fμŠezgt› W’JυœΨšωLSE'Ί¨–EJGQ¦½ηˆΚUβΔΈy·Έy·8½››ή-žP#τnͺBο‘R,’wPCeΠzQ^‘«Π³s£˜ h”^όt†ιYΠ«8ΫΒΜD œΦΪ ”JœNU‘A†TM'lkF³ύQν°ιΘˆΒ O:khqU—Χh5ΥεΠ謆ΐ.5U0p» g~ŸjGΊ΅“ΞοSΕle"~KŸͺΛ‰o%‰ο,›3χŽ{§4ύjSϊgψ²5ύ―9μ§O€?Β‹I ž:`β–Mι—„ƒυf_σlEΡ«Msw7τζΖ;}sFX\rn»€φ_8lό½©Φœ“ω\X Z3}»o&YC°AS6ΦSϊ΅Š’>Ά™h ZžΣ„nΟٌvr?·ΰZloَ “9ΘqΪ]9ΜT,v–F’yΓm“=SΌ“ƒσ„…97»ξr=Β=l$²?Cv8ΪέΘƒBšG ρTAο)†gΆιC‹«5Β|؝«rα\ή’%W‘DcΚσ3ωιόŒtώDTΖ ή”UΪK9˜;(2ZΜ§ €tPSQΫξdˆ†C©F@v/Ε~‘R]…}xπL¨SBΌuGψ–Χ/KϊΣφτξΒƒ_ .ψZΕλ?{ώοΣ}ΆξιΏϋΫsΏΒ7όρSΟνγΔ0ηΟΗ.;lr$ϋg>Μ'“₯πYƒS”γύΰ•ΈΌόΟοΣΟ`ψ"ΰς'π;§ήZΏ|Ωθ›ξ;tGz7Ύο罇ŽzπϊΡ/₯ίzsΎ.}ψηιηgτy©_ο‘_<ϋΩΏJsaμOn£3VΤ’{E!W–% qT§Κ™ͺΔ`ΨA Δ`ϋΜλδμλ―wŠΒΑΞgΙΤ³ΓΘήΞQΠΣΧ}ks.Πƒ„‡c["ΡQqRΦM‘ Ίχƒξdώ»@‡Λ±->ΧB8|Ngx Κ€€χίΆ·e•¬¨4κ½ŒΊΈΔ¨cq£ΞΙ5κ@ˆΥz©M«Œ ›…]ˆψάχB˜ΧŒψr€£±θ8:W7#ŽΞˆ…Ytm’ϋέT0™ΓΞΠύ~}7‹3xzݞ&πΚSυKk:»Ό^@g-³άζ‡βσ΅Χ©[ ˜OVOyŽΈυ\ ͺZΆ (RϊŠύ”αΚnχ'­T>δ>³DεœΡbaΏQxRχείη‰…²–Ε•_ΙEιά’½j΅‹Άξ…}9[σ΄ΞauΫ^—Ά’_„gΖγ—Ι–`π2.‹b‘γω¨ xφ€©EˆODEAα1ΠTF²Β+F|+ ;z x»Π,΄ '^ΈJ¦mΦ^ŽBΌΡ,qR+Y§ηώ;.Ώϊί]°J;h“Ό`ά;!8₯*Υ$5”ƒkjhνEγš‚:δi:HΦjδˆZ΅„!j‘αßϋΧοi2Žξœή«:)OCDκ¬5»³RΦμZ₯…BŠ<…ŒGΧ_ ,P_wZ ™eΑjž–‚p50Υ'ϋ}ϊͺEŠk««Z.πT󺧚β~_@ou·p¨žή7.M%›(«ΰ| ’sλλδΟXκ|˜ό4ƒ:Ϝ ,!tώβόCδ³/Σ<Υ_/εQ»Š_έΟ²κΤ> Έ¬¦2‘ͺΒKκηPH†¨3*Ι@_™H'[xB,’ΜsL© ›ZŽΆ€–£MQQLωΊ΄œΰ’ƒύι * B*jΕQλXkƒu‰΅Ι*Xε.C2CΞ4œ :υίYtώΗJΛ’wΔd*IΥh΅ΖŽK΅„°˜Ζ°|Οδϊ[ή0)ΞeNΌ „–£°AŒͺΤ*E[d}X5Œ»m°jYοc€}ͺ% 3uύχμc€΄5fdl¬±jΙξβ¦ϋϋέζ`€^ ~Ώ»‹ξYB&ύθ˜ͺ[μ|μ-Ž|λ|Z8xn ΫΩa|ΣΉ&Γ;η;Ξ6@§υάΩΞ…2R陦MσπV5Χa·#ΐπ₯\¦±r™dΰϋύΤγv%˜έrRXf᦬±@„*šΕr(Βπ ؘτΪωlLzmW?μΗΎe°»Γ~!m4¬Ρ(Γg7Kf‹ΐ/`Nw.„9$?ί p—ΏMJξuύύυί€ίNoΐ7ΏϊDκκή·§οΪ]³χ/z%έΩω"‡7έ6}­ΧF#œΊΜ=Β7Β{tή?­oΉ6±-A‚*/±Fψ<κΪxς<1±TθαO& 5ώ‰«…«ύ#)aR¬.±XΈ™»IΨΔmΆ GΈgΠNξ(:κϋ}κ4ŠIT* ψ”p`kβh‚ϋJ•ΎκĈΐˆΘΠΌ‘±‘‰Ιrs’wjdjΞδΌ)Ρ)σ…9ή…‰›χDξI|ψK"h `okζ½=αjΐΨ{z―p5πJ…O8_1''>‰ωœ;$Ίƒ„Βά\GδΒ\Ι2Ι2ΙκJX„ξ%–Ϋ4ln#Β€Σ,v ƒ₯ΐ( _F 羊„’₯M₯€4ŸρB>γ…|Ζ ω t+s0­z=ΝΊΑ6XΡv…΄©3£:ΊgΪkYl›υ-ύΥΘY‘½­½Κ»hic §—Ζiκ½Hμζ¨ Zϋ9+ ΎΘ©‘Š>U‰"ώŸλ—V?ρψΣΏy+ύκf<τνwπ°7t~ΆcΡΞΏΈοΓτίpψ/σ¦O›ύx*ΉΎϊζimxϊ±ρ¬ƒΏJόΨΎτρ»ΛSακ=XωYϊƒ4œœώ}Ρΐ Υ­Σ3Ÿσ_Ÿί‹όζ*b ΒA“­Y Ξ²— h9AΆ ±­ΝL2©&`5ˆ „©:ΎŒ)Ωσ‹Ψ³νLn&ΏŒ[Ξσρ’Ύ\ud07BΊ:ghސΒaEΈzizΞ”β;έφ₯3•ΕBˆ›@ΒŠL ΖΔΤ8Ωβ&0"Κ/Γ(TlK’B(ήΟQZ>5:96)~½um‘}ŽgvΰFλMΆ›·h+ —ΕΧq­wΪ6:ξΦξ(\ΏίΆΥ±Υ›kθY½G~ΒN„,‰œ@¨$δβϋτN Ω Ά7†ο “pάgλ‘[ΗqΑ'PΞ3Ή=,ΉΉ>Ž…#Iΰ’”ŒΠ*\γ―.o7Ύa½GΌΠn³ ω‘œά°,‰œ³NιVfΗδ¬ϋΞt=fZ³σ¦υJ3½ˆθεύwO8΅ΐΥ8™ϊLc3G΅Ωπ©λ“οΜοKσĝΞα7¦Γ‚ν₯—ΞώƒΞ―d>gq§«Ί’pΤρuςΫ2οkΝF •ό@y•Όρ¬pΚ!©ˆ8[Ι+{D‹ΗTς“+8³ŸŽή“ ¦FΊό3’eσ'τžTK“TΤ‡£Ύ±>ΰ[βkςqΎcζYξΐtfξΣά+&*]ζ^aNšb:iJ—“¦€ΌΤI»v1όφQZ*ΥΨέή·σ~I”ΒN12ΰy|4­ιδ^Ÿ•>χήοΣg—Ό>ό₯[ήί/<Ώϋγτω§οΑΆ/Έ1ηχΌΆοΊΧ±‡ΚBJΐj€¬>€™4νhV6B»αŽ šδhΝtfp]θθ­ΖŒΒ I<›sβΨΜa˜α™XslKΤμeΜ8¨Θ†Ζ­^‹ΥΖf±ήƒθ ”p–ΈjΤΟYνꁆ;GΈ†κΠgkJ@{H~ΘA²J³BΓ‘`[)TͺC„!κHοDa’:Ν;K˜₯.τ.–«7{‚WεvATζ 2uϋjι‡κ„›΅ ChΙ %BFΕfw8TΫεςϊόx5{ˆZu9i­OυΚ–(|όtΖ( Θr7ΰρz.ΥbΙυΊt9U‡#ͺ9=šζtYT9ΰN XΊ$pΝα°@όH O—ΛιDrΘοiWXπ8E*l½Pt$ΰqϋ£4S Άβ»vο0t_(8ͺ3θμ ;£‡ΞςΈπTΆŒ-ύΒ1•2 xφ£˜gO'­~TΡι7`Sσ† uί@Lθ€˜Π 1α—B§xθ ΦΘζ84–²@Ρ•)Șπ²CΛ^Ut8‰‚KS¨Λ™ο&υΈΒ ^JT.¨ά8†ιLΖO€o~λxa¨Ώ‚ύ_ώqL,γ³_§ox%ύN‘δχ€ίΎ}pΛW…ά'‘τΧΈ«…ϋ©MΡΩΓΟ=M=Ψ«2§ψ9*FUd‡^f±YJƒΆPi‰­΄΄ΪΦΟ[P:’4eK•.°Ν/mθ΅ΡΆδί£‘ηmήbsŠ€ˆjΎ …ž ΎPΌ?ψJρΑΓΕτ~\,ρα\*N*Ε.Χ…ιΟΎT}Œ‘Pž?/,+­¬ζ«ΛFπW–M–λ“sδωΙ•κzυmυΫIgU₯σZya₯ΏOΎ'pmΙβR)·ΧΪο΅o³gμΒ6ϋ.ϋ·vΞή5ΑkW³+Ύ4Χtθωš&ΒͺDμ’ΓΫ•0;‹pνφηo%/θΆ@›—Ϋβ‰D$ΤΥu4΄Hια¬%3΄,:ΙcΦ™*vέNο†D¦θγω…Tof©― ½YΘSΝVHS°V+:ϊψ 5±~šf’°•LΣνE:Jh‰h’WbWB¨Κl>8Xο›@‹Γ½«Yœ«μUέVMΆWγj?ΐBzk?›χΗεΜƒ(g §œ)’ςΒΧΔΓ"ΙkE"z˜QτΠsDc έΞ’*K@XR₯ύYD&ΪΩd$Λ‹½ϋ_Θ ‚bn4|ŒdBθδ¦ͺ»΄6‹’Ÿ~J5υΙdm{gς$Νw»ΆΡpΟͺ™kFζΠtjd‹k˜―QΕΎ}+‹¨·!]N˜σασU5±'Jvb,¬“ΈšYμzuψ²+ϋ.<6W έpۍ9́ŽάΉα…±šΕ_πjΔέ‹§χY4ήS‰œ΅“†νΌcτšΡ»-TWnθqY}c ρ‘ϊŒ«z:}ξŽΛϊ㏋#Zρ¨ς+¦Ήμ'TšΦ4Ρά‰†rπΫϊΝXP…B_a¨ Τζ5η‘ΌΌ‚HEdPdIήζΪ=`“#l‚s‡W]δ)PΆZjΜL°6π‰YN§·d-›”¦Œs°ς"&kv=^xύ―τώλ?3 xιΈ±ŠΏ¦―Vo‹Ϋ*mClB_OίΘ2Qο™™Kf ³-3= ‘ΆΌχ„£ξƒŸΊ?υ|λ*ψ)Σ-ΎΌΌdˆ*€‘!ͺ€ž€ΠΦΣ7€τ΅$CmΓ<#"S”ΙΆΉΆOΕΟ}gq‡]Γ^ΞnΥ s¬’α.R:ίΏΜ”N₯ηw/3*Ɲσ„‹™ ˆ1A\ӎ8±ζԝ Ξ&'θ%ΚΉ†vrΊ¨Jp2sLυ”S€|ξdΪΚΙJG§ΡIσQ””Nsτ&HΛ]Œ\ŒΎ.Ζ B‰%X$yM:,—2OωcŒΔIΉL~˜έ“r Ήb<Γ )Δx&˜[9Ά›¦‘Q2 CΊ” k¬aα7hœš“Ω…– ͺ¦1š¦/5l`Ω Ξ y{ΟUΓυŸύΖmGW,xomΓΦς½ΡW¬όωŽ›W=Ήξ‰Mηžή†Ήγ φ³ΓˆλέίύκΝcοΎA-H°HΉ iΌΐOθώ<ρ’I\JHY&Ygs …Ε–ΩVΩk¬©d¨:©§PN„n‹\ g=gB|oΧ€`οΘQ‘+"γ\Σƒγ#3\‹B3"«ΔUή3δL@C>μ°ωύc}4δ|Ηfm»F4G $/P)15{›ΞH₯@oqƒZπSCsιB#½μΧmΰ±πΠfdE |ΙHl£·²•V6Ϋ°-”Gη£β‰JZΏLέ <œη£Άa:½‘―ΒP¦ΩΥ"Œ΄BI/,­4imH½‘’έθat7tE„QœΝŠRΊ_laRIΆΰ$΄œi쐩Ό“L/€j:k²‹³«žΨl©h 9=R>‹Uq~‚97ά5ΛΎ9πEϊ[μωΛQlΗηO){©σ§φŸ|ηκηρdΣ-8l¨Š‹ΣŸ€Π’»ΞΓ[Φ žχ,΅9n`‡&αOȏKτ\;‚εΑ^A=Έ$ψ¨ϊ˜νy›²ۚƒmA>HΡͺ‡ς*sd§:" φ’€ΗΝs"RΆy°'γf8tλ|v)C¦_5\Lqδ~Μfeφφξ_Ιfg’‘ΌΚΝu*½Aέ‹<,WRΜr%TžQY6Kς]6ηοΙζόΏdf€Ο˜Bg^f^ωӁΰ«ψ ΚGg°‚Ιδ™ξG§l: ΊcRמlOΡdJ ]h![}ΰќ’Eeπ{5‹+Œœ’#Œ!ψ*]³'A—V8c}+ϊVVΡ€θiͺ¦½ޘsΟΆmξΠΪ•WOχο3~ΘαΓά#›V›βz\Φpέ¦σs@ς₯Ηq_‚δε’Rό½Αjƒ—ί²!`Η+›?:}Γξ~υ¦gg΄ύΎ|ψΩ[Vοxι¦U;κBγβ}fM­jΎ Χ|όΖ›j:ΏΰϋΓ«vr₯h{νέ_Ώωk*΅λβN±¬ή–Θ"ευΣ9ε: Όβ|_n(wΠΖ³&―?X闝ͺΣΓ 9"‚δ±*ͺisU“άl9h)Λ*Ε-zEΏΚŒ·Y°\ŸΞΫ³­‡ΦB#X'[vΗΌyKˆžg‘‰}Fh‹‡še²­΄Ot‘Ϋ?³Ÿ­ΠΝR%•ύ*›}§}d‰o»―Ω—ρρ>βa€φ0’zρ=qc6Wƒ^¦«Ω£ΐ½'Ο&ώ²s„gu?ΣΌΉd₯ۜξY#@„©ΒŽΡήαcέ·Ζ€Ή^₯1Ωq1˜λT€f…˜ž°‹v)nΥ0ΆΙ !ΝΟ¬A bŒe-,γνuƜŒτ’ΧΉΎεΦΆ•ΏΩ²bαΨ»k ψξώΤ3u^Kž\σ„{nι|΄Γ n ]λ‚$όœ$Κ…τ`vωΉ’ΝXŸ7“  ˜Ο"$–Od©GŽmEΆ•Ψ.ξ4]ιNs‘|§ΉPΎSΟa©G¨ql+²­ΔΆΨΨμ“mΆμ“)ΐž<€ΝZτ£θcΩlΩniΆ΄YŽ[N[$dΙ³,±4YΆe›NX2%Οώ»ΔΞ"ιo½{κ­‰‚Θ+’ΏίΞ7σmό ^lγOσρQώμρΌκϊδ,ωyF~^‘Οη™‘ΰMCΑ›ιuΦO…²?ZΎ” –‚% ‘Ά=‰ΝΜτ₯έη8.ώ°Χ€ήZZZψ―>ηεηŽQ)] ›*Άri”nλNΛ‹θ—]­ΤZQˆ¦š.¦ΗE4 D`g«“ͺϊ«”*ϋu―ήF]`¬bγ *Bž°M8.πc`sZΰς„%B“x-…p†ΈΡ;1±σ‚­Ϋ†pDn€»μ}AφrΊΙC~ΦJΛYmNld2ζTG–h41 ( h"(»²‰ν]ϊ‘΅Ά…-r2t‘˜‹#;€άYm¦u[‘`NΘ1Ρ1° „L Η|™$ba™€jΐΨLΐnp›6T3— 8MΐmͺbΝ\&ΰ4›9g.›h?룬ΆΚ8’?iω«Σ¨pT8%~9³ΒQ ΗΕr#’—? ‹±PPSŽΔρζψφ8‰ϋύ!{|³;yB±){'ΛI²ΚC ι€ \?%¦“°@JeΛF:Ν%έΒ)œsΜ™0­`Μˆoγ0{@Έλaφ€0 ετa¦©Γ,β†Φ΄a2Β*}TΨL|†ιŠ©ˆ±Ϋǘ™ˆ13‹γ#ΣτΙC΅h θOzƒ+5ζ?jζzΨϊ²vαΌιAvθf –d6 γ­xΥήόα{ FΆˆ9έrH©ξo5ΠύN6§ΠΈΤX,V[3JkΧθR„n‹\νͺǝπ¨Ξ0vΩΌ¦ω0ύώ€l€υ½l.ΥΟήdΦ…9 ένΜ“}ž]°ςΑΌ[χΔ {cΣ/_ς@Kέ¬«Χ ΰ[F_{]έΑ]ϋ;‹ΘγΧ_;`Λ3’=«V}δΎΞ³^Εg I>Ό[w œθ&;΄VνοάηξΣά·ΘΣε5ΐr7jψ!νHΰD ΰ£²ΗξρΉΐ«ΐ’Ο¦ΨμͺέdZ»)qφμΌ5@…ζI˜Waeώ„•ωΦ.ΒΚԈ΅€‘}K„³(­¬t†–1‡UΙfΟθ,Ece.‹ßut€ͺ­2κ[NΘ’ΐφ@s -ΐ8Rαυ1Ύρ1ς1ξρ1}w¦ΕιΜό·.…r‰KαμζRπYνΦ¦».uQFϋ΅3έ'Θ '£ƒΉH‹VΨτn ]·εgψD§E‘IαD-ανaμP\Y†‘λ™ΑηhdŒ‘MswγŠυO­ψΈαΙ±šRΊπΚeΟρ‰w ]2ͺΟ-ΛΘΊ]q»μŒ!™S|Pή†‚ψ΅ύή@vyΞ)&ΪͺfS(ΘΈ$%¨―”'‹υς\qΎ,Wj\|}C΅‘‘Ύ‘ιΒtΛx-εJωΖ ‹,³΄EEΎYŸ`―ElΣΈ‰ΒDešz=7[˜­\―*ώ/9AQuŸkξ0gŸΏΧέΜ!, ³8#ΜXG’‹3$–οΙf4ΝΤ4X4NJ)ΙH&0 M·Ζ+{IIš₯‹HΛΨz ©χqΠVτŒE4U°±‹έ˜‰eLc/Dͺ†§μM,Δͺ(ΒΈƒ%²ϊƒiKδcό‘Γγ¨b"ˆ₯»›ρ!κ’ιfSq‚Φ˜LI¦RσK#‚a€y!Ί,Τ2A˜`ΉNΈΞΒγ[ΰ™tkUΐΘX\Ί‡CžΉσ7aίΝ_έu<έ~`Οϊu{φή±~qγ’{V¦Ϊy諟β\l{χwπ›w~]ŸžΟηWΈP.ήͺ/W΅ΪeΪH―6GI^΄DετρφΙ”³$Ί9*π_εΏ*\/OS§ϋ§‡Θ ΥωΪ"Βp[τOž‡ώ”{s2χD4υΕψ€–τφεhΓψ«΄©Ϊ§Φ―ršΥiη|:]!ϊ"v+²M†š € ‘G±,<’`MΡ•₯Iᣌ-’zvΕΐgΊ•-"˜+ΨΤ…BγΞμcκB‘Όέ—­&XŽέ€"› 4’€FB0ŽΠΏŸ“0§"΄nSΪESg.Š`Ӝ πΩTDήπͺΎh.’k*"ΩqςΗ³ΖzΆκξ“nΣψΌBΓΝ"'׍βλŸpΌ G¬8~σΤ{{:Ÿ]ΉjηsΛ—νNΟ~ΉqάΈM™‡žNŸ»λκηΈg½ρΞΡw~χΥW¦ηs'€ξŠΰUϊυV’$₯d$ΉQk½΅Α‘ΑΝΉΫs…JweΈ6wˆ{Hx‚{Bx¦{fΈ!·)χ=ρ¨λ3ρ υΛ€VB Τ€·šτUGaκT2Ÿ|¨~ψ»ο‹ΰgασāy›'±JvΡαΨ~{2ιέ=ߟM> š v`Ν‘;M>—%rΕ,ωΰθJ>8XςΑΑ’ŽVc}έ§Τp+EγτΣp˝ŒμNFp'#Ύ³πGYίξ³…Lί°,ƒΔ² u)dδsr/Ν/dΣ έr ff‘£ζΗ€EΨ™θ—M'\”σ-+}p/Σί.ώΣ­Ώi|ͺ3ΕU˞ݡrΕΣιωD8χΔφτΪgο9;˜{ιΠ‘_ΏυήϋoQOω ξ›@W'ϊDUξƏc|%?˜ŸΐΟα—σ’Ε)[d‹Νν΄Ψ'c+D€XŠ7ΛX.ˆΊ±›d‘Σ]9:οŠΎΧέL©Θ”εEώ— ³•H6tΧπ7ώ]€~RKu,₯oRQ|ΡU,NCΪΫλν·ΌA±·”ΎFϊpbƒl[lrc‘ $L n…&3Θ7(κm,.π °\eR8Ή`vΑjΛ=–Ϋ Ÿuο,{³Yό‘€ΏΧΘ²χύB˜L"D냕ΐtyΊeΊ2έ:]n[ /°,PX¨ l-‰–"]dWX―pͺRo•˜UΌ<ΆΌ°©πgΚcκύΕ–mιυŒςΌϊtΡ3Ε{ΏIψŠΝ’ΐb&PhΩρŠζDsP’9L‘†HŸθάκ©rQ\UψP4αε­=sB4ΡX,cΣ4ΑΪΰ˜ΰ΅Α]ΑΓAΡΜ .ςyΑ{ƒ$ψKΰ/π#›Π=τt λ˜hψ&k˜½ΧΆΧγ«d3τεŒ{NΟΉ>‡δDΌo¬“`±gf|™ξ¦lΔGzZσB8TΤ݁Κ>τςΎ,Γ0ΆTZƒ>Κ‰Α(½2₯WΩj… ΛαΣ£@ϋƒd’2ίνg‰—ΒRΈΡΎHυ‘R\JŸI―/₯ͺ„ή΄ΤΤ)₯Ζ-tμ§w) ±δ•V6τiλCjϋ4υ!}θ$G! ‘ γχ¨|˜„ˆqKν[”qa΄ΠΑ¬‹ƒυέΝ*·³z‚©<;ΣiF–“ύ0£ΰ8Β4"(Ψ;;'Z¨ϋΛΧ`„“νKG›K1’ΙF:3Ρ-i§σ–PΧΆ7²…4§«BiΥυڞίπSυ’Ή1ΑS–pj.Ν­qb-F–b)Œ…°ΙυΐnΎ=F1›*—(a\\dQΔ$FyZυh—υΨ†…@₯Ι5kΦ n“fbRθIξ*Ÿ‘‹E= ύi•-6…/]ΥΟς±΅{wήΌzUίψΟή|xΜύKο›pΛ/§:›ΥeσW/πωΚΓ·ΏφΰδωoήrψC|YdαΩC.‹β}F¬=όΖβΌδ•7Ο ŒŸ>Ύ*Ιq+…W¬ž>uΫ”©n-Μ|GJ…‡‘η@j6ό·v{›Ο$M@a―˜%*-”K&ΠΔ«6sΘ§Y’|!ΞκΠ PΆ]δž(†{’βŒ$΅ m–HMf‰GΰΤn—š₯6ιˆ$JΤη‘jX2||ΗV IF€–˜)3ΒΓ]¦.@bΦk6‚ι Y€Έίξ9—dmΨ―šΤ“Τ’΅Σ5ͺΤ’9+*΄· aŸΈί˜Ν€“(Ξ*'8aλ/‰ΊΊζΊλΛnΏ}οΎ}ξdqξ“Ϋ΄Λg?EfnΒυι»7uώlTYˆfΥ@WŸ ΏΌŠΧ@!:ΥηυW’¨ΫW頝Ί<•I7.”έ>»}V0`Nΐͺπ™q©Οt2|]q©/πΣ2Δ’S?‹Kύ.6Ρ΅RΛό—Ώ+"υ{²SΩ ·Ÿ₯+όΖ«€²Œ·ω±tˆΆˆ£‘Σ!²$΄=ΤΚ„xΊ‚ζί)U5›xο2€Œ,QΛΛ o1 ©₯ːfsξ Λ΄Σ'2ϋiaΡ¨…%Έ-£ƒ%Φ²Y쇝†QeK\j cΚ„9Δkv›ΓF—uΩ!τδΥ0²ΙΞ0’giιπSΰΚμάtQ‚­£υ3QμGavυΡkž£Y[¬Ξƍ»g`Λc-W.ΣwΉΏsοέ½‡›pοR}ξP4Dg3€’ ιwΙΖΔ½Ή™‹^e6‡D!βΛ&?;LΩ:­3Q Z·1~AFŠ,bQA‚E0 Ωeεɏi€>mψεΎFΞj…š4›³ΪβsE*eΊ!πΠ½Pγl­Π¬›%7ΏΓ†–‚x%ςΑφŽι·χ¬DQΨ8ΤTlI(Υ¨―r%LΖ“I½\g™ƒηως|Λ*τόr£ΌΚςe=^OΦqwJ䍖ΗΡC–ϋ”ΡSΚ/ΡΛnεmτε:ͺ|ώœCJ G ŸRŒJ•2ιŠEΠ]ΎJS™]ΧkρΠ‘#ηθΆD1Λ@qAΫXB±ΒZ‰ ¨VΊξγ$ΰΚ‘δ‘$*§Λ|)~τ*E’εΈEρX, ≫vEAбW” ‡°Pb΅@Φuέd!–Vή§ M-Q’γλ—€lΩ v¦:S‘@ϋΙTφΊVΰ:«ι{•ΦΦ7²«ό.|PͺΎ+KfƒuW`ό‹τυs2žH~} }ŸθΌ}ξβ‰+Ι##/"$Ό œζ₯λm³œfΔυl,‡K'μm#ε/c „­eγΊ%ήΏ4ήmӘ₯ΕμϋgΝ<πYcα·aˆ]ζΉλ€$fSΘίΡ«Ιμ[.ςΩ—@Ξ_Ȟ±~:ΤlF»Γ|3<{@R³ΆζLL‡!*Ξ‚μSζδΠ)cΊΑ5g-Π'ζτΟ'{/ˆΠδ’ρ3Ζ V1MΏΧ’ڈq7+…œQΥ8ΠΦb7ζcΪτr 9uΆ―89ŒTpΔ±θ–±©μηkT'&ΌΒ;•lΆΩ°ENπ2ή?€½—΄_GqΨ£ΏvJrTrΊ\IAς‚d:ΗmvΝf—!HO*².§/dΥ "Xrρ²Γ©Ϊm¬{.°£τJ¨~q9θ›§ŠηŒfΓτηšlœ­?§+Ρ1 ^¬ά¦₯•L-cœx±σ6'}e’nΥάΐζΆ8Π@ΟνΓgάgζ0?88ͺ#• € T₯ώ€¬jr²ν±ώŸώ -¦edsή„Ί[T’W3' Φ9μ™#-¨—# r|χΟ~κG6WN¨£ΦοΘn©f ωF6W°₯„rζΔn)j΄Ί²?‡u€ήh?DpoΠGφH½θχ ώδ ρ€›w]ηgΧ93'φ*Q>Šϊg_.<έν½ύjTζb/…ξvΣ7ˆλΝ€Tx±‹Ύ.Y±χύŸ>T%3μφ³χΈ"LΏrπωZΎβωΫϊ^ΆWΊε•ηK>ύθIηοΘ ½sˆΜ9wŒ¬ήwώ0θjx ΊZ#˜ώbFVW ΅,μ}}6‘Κφ³6ίλΐV‘'‘ˆ6`l ψεIΖΫμGŽΒ/;\ΨQ4^™¬žκΨΚo•Ά?βhΪΔ6ι‡Ε‘ϋͺCœΫβ΅…΄Ύx€u ΎΗ*—»¦πυR½΅Ξώ ~HyΘϊ2iUkύύ]νwΤςΫGΪ§ŠΛ”Q«Š\NGΐώ‘H•€BR"²·Ε)g%“ΩWhζˆ"'Ι E‹ΐsΰξ;ΐύ²a‡Γ¦YΑ$6+§jŠθ E{½i!ZY<Y8b{Σ†mq•σ¨*§X,GDˆ(U)c\Ψ5Βv«Z 8fˆ–[u¬πΛΊ8VlbΏω6X·GΉ[IΑ@φηj–mIu†μ²φ©ΦΡώYκ"±`Ώϋ—ezϊϋˆvίαX/3f7ΆP±_Γ”k²ΌΥbδT[ΩΛλ9ΥjΏšƒBχχδWkμν/o5.Θ―Άθ‘Ÿ+¨g³τεBΖƒ`Χ+όΤΒWΌ„ψφτΓ}Ίg€,Ύχƒτ}ψ HAŠqϊ‡α½UœK«ΏΗWΥ§SΤκη§Ηqί'…ΘBˆ§Ζςcύ/‹ΨΦΑg§^;τr#εΟ&^ΩV5Ξ0&ΨΦf8μͺ9₯k0£Ϊsƒ³r‘ Γ%ZE·ξrD­ΊΝ2e°<ϊ88 j΄bω,fζΒ{Ίϊ}Q€ΊΨ3Ω±Kαt›”χͺΤθFR-.Ÿ-ΰ*²©EΆ~j?[_ϋΓNk±«Ψ}₯―ήUοχΞwΝwΟχή(΄έθΌΙs“χΫFη&Χ&χž‡”ΦW΅Wœ=_*Ÿ{ώiλΤ~πd"Ή&λϊάΦH˜w qάξΰΑξω6WΧ;_U‡ͺnw0θq»γ.Ε;”wάͺx¬VΕM_챊τ(’EHy䡉΄’Ϊ}ΐ…ξi%uk­Kw‘k]―Ήˆ«ΪοΐhhX‘‡Άτ¨ΪK£rcՌJT8co9]*Nj[ΒΡΥ ΘyτW[ι ΄Ž“Aνdͺ±=ΠΪ„45YW6ͺÞεέυŒQAKΫA;@;Ύ±ϋ)d͜Βέu£'σΙώͺj₯ ͺΪNτΒ[ν,0~a‘ž†RτΧ4²|ΪΝ=MΊ‹ŒUaUμύ¬¬{ ¦β₯Ϋ<Λjτ;‚5½θυ“yΙΏ·€―Ώ’°ΧκΙ•ιΉΟkΕ…α…ŽΎΈσαkV―$ ΟύvΧ ϊ μ7‘π2{YQήΔα Ίέ"ΎKΧυ΄Bςœρ›΅¨Ό½w/wφηei|ΆhΛΌω[ΆΜŸ·…ό~ώΜ˜ζω'p S…?Α½όθΟϊτmΑ]Aς­τ­›—Ž»Ιaι°›Ό&½ζ&»€]n²MΪζ&χJχΊΙ­­nrN>η!ΧΛΧ{ΘTyͺ‡¨²κ!·,AlEœγ;χ±ΫVkl¨Ζ†ιO€–»K·IχJœ„έύ=5v›ZF]χ‡*ν+°Τ_!Υpά½“` ρ9#_E§Cθ›―ΘΦͺMΥtΦ΄kμηX΄μ/†Β’―φƒ›Έ΄±±7f?8…½1ΊT³Κ/ŠR~7{~-VVUΙαLˆγ?_W3Άd˜Ϊ” `j8χ-ΌΝ0υ‘>šaκ΄|ΪC°Œ=δ„tΒMŽHGά€Mjs“f©ΩMž’žr“ϋ₯ϋέδ§Oέd‰΄ΔMfΛ³=d‚E-ΐyOŸ@ΉŒŸ…FΓ>†~NZΠ#tΚ(V–e:ωΗΠvυ‡c7‰[a³ί½‘œAεδkΤCŒ£Ϋ€Ώ†ΐύΧ@yξyŠρΓ,4žίκ ώSΖCλ l‚g}kβ‰βφΧ]ΗΓ³ΞS‰€λ'@ti‚r=ν<ΏœβœONWΓΉ'αœι΄@»Ÿ;εIz ½ξΟςαSjτœs7ΰυΤ</νƒYŸe {ξ„"BɁΚ§Pž‚²Κ(#‘Γ³<—cό €Ž†²ΞΰΧΜΩ.ώ|ύκ»LώΌ„O^Ÿκ₯|yiΝl θwSN‘wšγ§ϊ‘κ8ͺ#©ž£zΖ<ΊΫυΙ ΐΗTBS³r]-WA–•}ΠΓ@ο)™Œ8,σœΨ’ΩΑΉ2;Δ>АyΖ½ͺΛ¦ΦeY{ZbΪR£YM;*T EY}φ Σ7ί‘˜Μϊgw‘Ϋ„s@wЁ¬ΏΫ³2ψ„~/δ珠M0Ž ·δΪ‘L§8a΄@(@ν΅‰άΐ3΅Ew£΅άGΰ/Πk+“Ω‹Z4ϊώ6k›JkΪ&LAO‰_‘>ό$Π΅mh₯ν₯½ΌΩd/艣¨7<œγE œ·α@GΟ1Ύ Χ.— p!ΝDπμh8‡ήοIvŽ\Y|<ΓpΑ_„ς0ΕάSτ’ρ̟ψ m&‘) COJMθIqȜν€{ό›DϋΧ…˜½ή‚¦|mέ΄tbό?5sŽΫ γYz Χ8Ϊ‰Bΰp!ϋήΠ±λ©όp/ εq θaκOlAω$*.DwCΫέθIxξ]Πv;Θo/έ;αϊΌ¬ήFπμ;‘^[K}κ#Py‘tδ›˜€X¨ŸΟηΎ@OrW‘ ΐΗWΘ[w ΐΤiΜ…Ϋ(lΦlΩdΦ¦5Ξη4t m'θπ+BjCπkΠ|~2κΓυΩu’ό@V@rt-;τ(ߊώΏφΞΌͺβΪγk?Ξ#Α!8Ι9δπŒςœ„$<‚ $₯%Pπ…5ˆΦλ…c}RQ¬τ³*΅ —C’‚_ƒ₯’ ‚νZ•*Ukk­E©Ϊ"’}kfφΙa“±ήο~½ί!ώφš™=³gφμy¬Y31+Ωoφ Fο4tKίO•ώ©Φ‡τwΡ5f5[ΡφP’Ήίι\χ’δ"ύ1n=ΙρDO[³s ιbe΅q”Y―ΐ[MΑ7EyΩ}JyQΦh9ν2vP>ρžό\€γ8ζC4υtδIΩ6]Ώ‡6ƒυϊ4ΑΈˆΎ§=a΅ ^ΛLŠυ›#΄›Α0s= n{δ/ΐι‡ξ6‚ή·γΩΟC6ΉΕ֎Fz d‰°΅ΰAπ²}/Ξ§£πX\}­–SόΟ`Ϊ§V ㌏z‰όFšZ- ΪβΖ½œ=K)έ€πl€sψ]}џž‘\ƒ¬tU¦3Γcκ1ϋŽφχ€Μψ Ž‘–jnψΪeϋΊΰϋ.ίυϋ7κ)ΫuΧY‡!gi‡(ΕΈmΐ?ώv}Ϊί α«EΈγϋ‘­ΧΉ3άιw~ΧόzΥΕb·ƒh{ΈŸΖ3fβ§ί»‡Ζ3ξpο…ΣύζΟΊ –kΈLhƒNχ»§ΡFΟEYϋpτ9υοΗ8HŸDώ4Φk z•11υ:’λΥX#οΫίΗώ.Ξοƒς…Μ}429² rŠ-cϋ¬³ί:Γμ±€£8ŽΎ1Ό³gώ}g/xμώίΞK#΄Uά‡‘‡A<ύδ[ό{p'1–|Y6bšω[„aφn’ΰNEΨw !:ράΧ!ό ΔΝΎ΄^ι•½ΆM₯υͺηUΙτ'^"ϊβS°E¦?± \χ'σω‰ίC>ω βιnƒό₯Ό²ώ₯ΰ9ψ?„*P χ}=!‡€ ι`X9mϊΛŽΧ_UBg™‡rϊΩζy³s ρ•₯ύ=»Ξ΅†ύύ»’16‡”υ€5Σ;Πϋ"±kŸ3­ql‰οΩ‹9Σ: ςΦ£Y—eύYθJŠυ›Πc‘/QΊ-Ywfύ•ugΦ_!6—(ΟL^η‹r©y#vlΥ>₯΅ τUςJΔ9°φaμIFϋώ k£Ηψ»ƒYk?ζdΜu­w?ƒ|ώ,ΘΟμ9Ν[Oc»˜ΣΎiΩΞ‘_cN-TΤ9θ,άζΕdΖ9Ÿ-]Νέ_{.οdŽŽ§UΏ=ΟΫ$Œ§BΖ²Z§^zšΠ…Ώ+=χlύN½γ¬ύ½Δφ;9νΎ³νΩϊLκΕΡοΞ^[˜Ο΄λώvœύ8Ϊί”uT Ɓjέ€ρϊΏ•0GYχ#l™χK*τ>E…π?0oΆ}YΟχ Χiχ°}›’^ΫχαO1_q«υ]΅gg»eύ\臨31ήΗε§0€­ΰjϋ[σyΏcΦεuYk}fξ°K9‚Ύ ž‚?ώdŒΕιξTŒΫ!ϊΫγ!!1ΎOo·ρY'έ7‰8S„my MΒ8ym_Φ―„M―ψ‰Λϋ(·bυΫv:ψ{²mΘ`{‰Υ¬μssέΗ0ΞΖ|˜ΐsς%φ„4َ{Œ~dt£ReCN·mΙlŸβωΚ=ŒR„#֎ό.kΞ‘RPdΚ}ͺ™l1ώ(φjξd»»q1=§φ·"‰›hmΒ‹΄Φ[OεήεbΏιγaΊa{ξ₯‡έωbe¦=―ςœΨνm™}’6MυΞN@”oMe{LlΎv:o9ζcΒ%ν˜]θ6˜γκε~…υyΗφNλeχ\¨ζψ₯Ρ9ίi§ŸCӍeXχΩ6ٍ‡θRσ κΨY;/ΤΛΙΞt![7{Ά°υΙύΆAυˆΩ‡+υόψ^“ω›Ή’Π‡“ωϋ[ΫMΉ?Wbވψ:υ6i{ϋsl³υΧ-ϊθ5θ+hƒζj±‡w›q­"έUrίΜ]ŠPH·‰χŽlθφv¬χΜ™τ°«Yτtk;δuϊΛb1Yνφ6W aΣlίΜ4 »υ@sΐχίƒ?WΌ»’’BH—ŒuΏ#Ϋζ†αžΧ«l€*ηY*χ„Π^»QΉ«‰rΕΠ_vb¬σαΫMΑwM¦[w(ΫΌ€ζ©TΟhεΦ>νCHhκŒώ„ΏωCρ7RkyOΨήW“φi:!Ψ ]¨½\f>£oϊ©}ΒεΞ’n„¦mϋ›hc ˆg½Nθ?Bή%T―7#υ( ς1RΠ Ν劁*Ÿ‰ζlτ±S™ΰiY8A8Λ<'*Ό„³,q‚π’ΚΡYΌΞΚΡYxΠ Βƒί@9:{nŽ„ηœ‘|N^qε謞s <χ εΈΨ Β/v–γΦ±m»±6}ςwjΎr*$Z_Ϋ―ΰΖϊΒZ όΏSρ~ °ώ΅~°VΆJσ,^ί ωW€u΅5½Ά=>yΓΞΗZ ƒY2/NΫΆCζ-PyΆ5Ιτ'Ÿ‚|ΙαΟοΛόDή<φΆ@ζ€5κύξRωFdΩΫV·ΗoσΙwι"νXΈιύUν΄=#±vAώ`»θ‹ͺ\μΞVυΑοό,?«}\ /Μ53ζaNχl’όš*Ζάύ§ΜU׊ρπ]zBŒwΖΎqTθN‚ς•°ήΐcΈkΎˆ·«sA?™%φσ4Λ|z»ώHuζ5Tjlƒ^<γ-ςϋ2x6Ϋ¬s+θ" φ*ŞοάHw&>-τ—ΔI7„ςώ„Z±f»ΛUM»=ΓΰΏσϊ£t£λ?θ&οΥΤκώe=H 0_ωέu4Ϊυ}šd―mέWS‚λθJz€yž!ίDσ}ς%ά ½ξ5ͺD²σŽξέ{(α₯}E΄?πe>˜*ʌςB3±ΆN·Ο ΈΎ:©εΉXμ9ύœL¬ΡΙusχdθI€ξU@w%dzχηx7τΤ|±/Ώ@Υύpής|‡ΞuέIA{νξ~υ<ƒmΙϋqΆ=ΊΫ£ζB‘/¦‰}-eˆJϋΌί¦•|VΒ©ΧΨzTT§P6‚¨ΝΑ~Hž?£ο―dŒΎ!m ;‘Ÿφ€|ήΗ6§Teϋx;Ρ–”>λi₯)r#-pίAU‹P/=¨Κ³‹<)“υ3GθuWσν:]΄Š‚ψ6TΏp_š¨ϊψ„<)ϋ#χ/}a'Χ¨π+ΐΝ`‘ΌΟχ¬ε}ς¨|ΎΈw³ŒύΠβ=8=ΖVσΆD¬C±zͺ:KuΗi²}οžΫOy—ς+ΪΠΈσ™ͺφψr5δBΫ=οmτΡϋ‘6άΆ픦<Ÿ²LJ‘²|\ɟr[c]Ο)ηW:;Οr=Vφ3[žzξΕ–—*ŒžΛιBƞ“i—–₯όέΏͺνNΩάϊΨ²ƒσ&Χ.έ§­Ÿb₯ψ&d(=–υχ)bŸŸΟ朁θο£ œΚ,†Οt„3 γΉκT”žί)ξUHΌ~'Φί”ω‰υβCΕΖΠ°–ζXt|ΎΤύςή‘Ο‰ΠΟκ€<θΑή4!έ<žhŒη¨βnΛbμz·λΡΌΫϋxο…Ρ2Ϋω«ηώ«ίρ_ύ.ίΤ{Ÿ©μ±¨3zΆδ³{ξˍο#ψ»Dœ₯ΩD=nΤλ°μU¬fΠWϊπY%c>ΪΣ|q^1šζ΄vpΦ¦Œς«σ7n74;O¦μ|φGB5ՏgΎlž²žΔΉ©{ύο‘€ΞΨ.Pc_nB%=ͺΞΙϊylΑΌΛύ|Έω<-8Uη³ͺδzΪΪ€y…ψ©%TΏlύΤuΖ„­—\Λ‘ δu›bb½Τύ¬-κ€[œήD?kΫl†γ ΏπΈ·Y½Nφ'ή^.{μ5ώ‰χ8A½ΕωX_Wš‹°¦_D½qϊο7—Q1ΟΖHθV|ζζFu^–moAJ’P/•Ζ1ύ›ΟΧπΉ Ξδπwڍ9€γοινυύ@a_Ίγψ›δgpOœιΑ3ψ¬λEVihΣwΊυkγAΘIŠ‚kPήY΄HΏ† °~ ϊNO„,†;2Τ€‡ΑR:W„Ÿ@;ωρaΒ € k{Ž+VJψΎXoo£zθΔυxžŒwP€‘Έ©^ϋ₯Θ«ή(ΑσOΗJΙ€FaτTn7ξߎt­rύΞvŽ/ξΩqΪγΈ>’ςΔTξξVX-b«Eϋ€Ζ™΅”ŠošFΰ[οSλΦ£φΤ–΅ώ½Ίσ\€½O€λ)Z亐†ΊNB?8Œvp„ΖΉ>§‡\E4Π]‰yμIβΆ4πΪnŸ'g‰ZϋlΫ·»šz&Ό@ρ ‰ΟoΨRίΜΏώχ)ζ#q–^cνm³ΤΘΔωiΩΧ„žλ)₯[яΛΑ$uξ{άƒŠΎgΚsͺΝΗ)KκqΌ†jCmYάͺ06Dm―,ωL·-₯ "©υ€ώ^ΧZ£x―B―δσZ"ν·δΊΤb{υΫ,ŽΩz€ωΏήίϋPνuu6£«³§ωΟrOΕyv£«³]ϊ{.]ν—‘­²Ž\Žy₯Υ½Ι:³ΰ‡_cL²,a•ϊΪ £ϊφ¬A'S²‰²4γWΆΉRΨτοΟ£›J€mήϊRύžƒ°§²mŽυR#SόDυ{ όό)Κ~+~o"j§=ŸfςXΛcͺ˜3ψl7ΦioκylΡχΠyϊ—r  ˆΗ"a—,AK„n}°SJ(A?ο²Zb$[{ĘΤ]ŽYαyΝ<žaώ•γU–ΡGŽ_ϊ9ιo!ŽΝ§ΰ/ΌWΓλi±¦ζσ?sΣrœc!Ϋ!῏"ΧOΙάωχ`Ί—”nΉΩ!wΨ²+½P₯Ω¬œ_νέ`.ι!ζδiŸν»ˆΞg£ίλ•IΈΟ:H»žoΫΫΕwΒ7’{ϋšs]ΐϋ9όmν5½΄›΅ˆ‘u1Os=ώ zY"ζέ©"ŒqbΏ§ΑϊT•“Χ'½ΡNοŽύ졜½Φ k₯njο@Ξg’Δ|\Μϊφ1Fœ!ΩC‹³Μ{ρ&ΙyCΜ!/€Χΐ―Αίΐ!i§:ω:ξΧKt=΄ŽΟ΄mwF}ν¦οTκνn‘ϊЦλΨ.Ξπο0βw§l6‘_ρ8ήΐφρopΧθι ŒΛƘ(―yιYΠ9ž>D ΉD‰7uϋœθθVIxίδk‰R6₯Ύ'IήNF¦€Χ’ή+%>h€Y&ς—τΟώjδaε6ο9θQ>Ύί0L£7ϋ 4SΜ[#κΫΉ—h κe\w’ρ(sΘGTό)Ρψ'’~'α}¦ ,Sρ—l šρW’ΩΝ>T›^Τ #ͺ­'Nœ8qβΔ‰'Nœ8qβΔ‰'Nœ8qβΔ‰'Nœ8qβΔ‰'Nœ8qβΔ‰'Nœ8qβΔ‰η¬Πψ/ZΡ1G‡tJ‘ώΏΎšOvϋΉHίN3ŒMΑLkΟƒθЍAωYώνΖ#«q¬?Τlδ4₯υ,L.jπ΄q ΰΊl­ΐ€:#α)Έ.a°΄‚Χ€›WΎ‹Α:p„οY†―1ΰO)`τFΪή(c²Ρ‹Ž δΗ΅Lu`Xά"‡,ΛA+ψXά ½ο?eοΥx·MW\U(Ό—Iοœo oΣμ)/š.eιdmŒŒvξω2xX‰”†H™–Wf™˜TΈ³8ΓΘΐKf ΰΧβͺιΏ’dM#?­7zRθ†[…„Œ΄¦ά`αΊVΓ$ΝΠ κΙoν4΄Ζ€ΤΒβDݏRωυΏιΙ;ϊGMέS ΧOΡί‘- ϊ;ψωƒώZα:Η΅¬­`?8 άϊόΌŸ·τ·(Y=€"PցVpxτί㚒ζΦ"μ.Ί~ΧύMΌΦ›Έ&λoΐυ†ώŠφߍ£FnŽόεπη)G―ΎΚ‘–QΨ¬¦ρψ ΄¨ Ύ4ZΤ£?§σŒώyηϊ›ΜΖq‹όΝϊ»M|ϊβαϊŠ%9€œPT‚ΉΰZΰ†λ\‡( ξλA •αšϊ^π 8DΓAT―ώZ#²iΦχ7KόΕϊ>ύEκ…UIΘWτέBΎ¬Ώ δΘlΘ½ϊξΖl?wΓ}BšΘΘάwιΟ7ε¦ω­βT½uηΗ΅i ¬n½UοίXοOΓCvΠ^/!f#} δFΪΰ₯ΠώPp`€/Α1Β…ΛΊΐΊ  >πxωΌχ~ΈψΌm%\| ήt \| ^΅.Ύλ―€‹/ΑΪ:Έψœ6.\šυ΅Οζπšv₯(NΦo@-έ€ZΊ΅t™ϊ όCΗM.ΫCƒ£ΖΦ„ς φ‡[΄πsZψ-ΌA ΟΧΒΛ΄π-ZxœΎT ηkaŸΞΦΒ!-ΌC»UΦBOŸβΚΤΒ{΅πSZΈA ΅pžΞΥΒmT¨YοΧ8ωΙz?Τh?΄ω~Zqέ,α !R ΏŒά;›e¦ΑE?lLαββIϊ.$ά…Ο°‹ή&>Π.4£]xΘ.< Χ"Pv‚£ΐnΔ―Χd\ @¨ΛΑQΰΕ9 tZ¬ŠΈE¬@zϋτ]ψ鏟~zΏPVŠ/%?e’±Κ§%gkΣ²­l}edQZͺ7΅YKΪφ€ώ#‰Šτ{υU”…qŸ’«gω›΅ƒ;όΕ=΅SΆ‰V§¦ –y5ςyYžO>}3da£o’%7‡ψ[΄ξœj›Έο=ΎfΞ?ϋvψh6΅FA„lήζ?ΰ[αίSΠμEΘsΑf ’% ’nχ]ΰj―ˆz n¬iτ/c±ΝŸΎ‰ώ+}βΖ|yγψBΙώK‚΅ώIx^©οr¨Οάζ/ς]κ'cΰ4ΫόΓQ„|ιŒΒς‰Ls²ΕgŽjΦ††xπT{¦yFz =C<ύ<~O–§―'έ›ζMρvχžγMτz½n―ιΥ½δMoΆŽ„ςω/<¦»Εzδ_ιΦΘβOΑά«ΣŠτ0*τŠͺ­"²sU\ˆ|^•Σ¬%N―ΈrJ΄HZUΜ(‰\_Ρμ±.‰ŒΚ―ˆx*ΏU½UΣξ­AhDΏ«Y£Υ͚ΕA·χ€M¨ήNš–zϋ=}YΌύžšΚΜXZ”Y”6>utyi—Ήκσg^3OqgE¨¨ͺŽlΚͺ‰²ΓΚͺ©ˆ¬ Μ©ήΣ>.+έ}Β’¦z»1^;Vv ‡γKkj*š΅Y"΄O-ζΟ‹‰™γQΐ›-γ­‘ρςρrY ^Bε‰xy "ž©qΌ­ Ήe₯[ssEœ^jqzbγμΝCœΌ<'#L{Eœ½aŽ/’ψ|ˆ’νQ΄>δQ|ZeV{”eE4Κ ‘“‘΅ΗρΙ8IGμ8IGη KόΤσKς󡦱5σζ”ΝΟ)››S6̍ܽtaf$|y °u^ ίDŒΰάΛη-dyΩόHMΞόΘΌœΐΦ±s:Έ=‡oΝ)έJsΚfToš_Ϊ864Ά,粚¦‰•η:%―ΡΌΞ―μΰa•ό°σ9―‰£:Έ=ŠoOδΌFq^£8―‰‘‰"/mΌ²z«—Jj&Μ‘²Iο–ˆφ:·oΏš’Œ”kΗ‹Ζ;Ά_ζ²Ύ-ΠVž nω5‘srJ"I€o -ZΜ·Π§ψVw'«[™ΛΖφλΫ’=‘n₯ 85§„ς—\ίp=e–-*•5ΰ‚–\Ο.―ω ύΓ½²H貆%D‘ΑU‘’ι΅Υ[=„ΞεWŠŒ±ΓΊu+kΆvΚΐaÁ†Θaγ8,!AE<ύϋ_―€ψΛΜa}G“ΚΦ–PCɘ‘c(˜Q‹wS[έ]Ч‡†Ό`ƒ–―5ΨΟPΕ–՞Ώ³Ν’λ•KΥΕ%eJ$i°«$ϊ++?ZcKπ@ϊ_:Εp endstream endobj 236 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /MUFUZY+ArialMT /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> /FontDescriptor 238 0 R /CIDToGIDMap /Identity /DW 556 /W [ 0 [ 750 0 0 277 ] 4 8 0 9 [ 666 0 333 333 0 0 277 0 277 277 ] 19 28 0 29 [ 277 ] 30 35 0 36 37 666 38 39 722 40 [ 666 610 777 722 277 0 666 0 0 722 0 666 777 0 666 610 722 0 943 ] 59 67 0 68 69 556 70 [ 500 556 556 277 556 556 222 0 0 222 833 ] 81 84 556 85 [ 333 500 277 556 500 722 500 500 ] 93 134 0 135 [ 350 ] 136 178 0 179 180 333 ] >> endobj 238 0 obj << /Type /FontDescriptor /FontName /MUFUZY+ArialMT /Flags 4 /FontBBox [ -664 -324 2000 1005 ] /Ascent 728 /Descent -210 /ItalicAngle 0 /CapHeight 716 /StemV 80 /FontFile2 239 0 R >> endobj 241 0 obj << /Filter /FlateDecode /Length 250 0 R >> stream xœ]PΑjΔ ½ϋsά=,κ^z BΩRΘ‘Ϋ΄`t’ ΚΔςχ˜ξ: ΜσΝ{> stream xœν}y`TEΆχ©Ί·ϋvΒ’f Y€ξΠ$,!&D lBgC1#„Υ\άΘ“Eee„ . Š`Δ@ιtΓβGAΑQτ©“qWΰΣ}@rΏί©{;4Ν6ΞΌχύρ½ξπλSΫ©:UuͺκΤB‚ˆbh>iδž4{¦χδΰ§?@ΘDΖψ*~y‹λ«έΰώ‰Θρ—_ή|η w7LΊ‘¨Ε€Y9uJωδϊλή»•¨εTψϋNE@λΉρα―‚ΏΛΤ[fή‘·}w{ψ_%κ3ωζι“ΚΙxφQςμ3υ–ς;*Ϊε鳉ξ\ŽτފۦTόύΚΟγα΅ϊ³cuPx–:θiԁΘό,„ΖiζgΗT~C$:Z°?AΪLέ„—jΔ jO?‰DΡ‹†‘N?’¦[¨₯Ά4†VŠΦΤ…βi, :€ΣR±Ϊœm~M—ΡC΄Ξ|Q,07"ώAϊ#ύ >ΦεΠp€KSθkνs*5'έOΝh ρTNοαηΘπ0=BΏw™?‘ΤΆ΄ω ’\Κ5_6OQZͺ/wŠyVΠNα4'™Σ¨u¦J™nΎgώ•¨”ž¦Ν)]ΤιWP έD i•HΤώΧ£τ[jΝε΅ZΎc7JFγθVΊ*i#½!Z‹bΗ!Ηwζ―Μ/ΙIm¨dšF_‹>β*ωŒήάl~@h;νA}ω§NŸ ?λ˜Π8Δ\cώΪΡ‹"Vμ/;²4άc>e>OΝ!O/΄Θp”3‘ξ₯—i/ύŽΙyζ<Ί‚F£δΧDGαihρχd’œ+ηjοΠ%¨ν΅v=IτΘΪI/‘mώ“κιsΡV$‹+ΕD±B“ΝεdΉ_[­mΥήΥ…ώ;΄·RΡF3ιΪF’}΄_8–(7Šιβ7b¨—yDώ¨»τ{υ“zƒ#­±Ύρ€9άό(‰~AshΪφiͺ‘­τ€ctœώ!ά’Ÿ˜*žQ/ŽΘΩYސr₯|F>§ ΧVh/λ}τ<ύ&}Ÿώγ׎%FΉΡxj}γÍΟ5ΎmΎhΎ έi‰όΣh(ZτhΕ3΄›ήAξοΣGτ λς(Ζ‹λPΚ ±H<"ž―‰·Ε7¨%©ŸΞr ,@©Σεmh§ςaωJߏŸςω‘<,ΠZg­―φΪSZ@«Υh_θn=MΏDο₯ΠΗλ&z&ΫqΉc΄cƒc“γŽοœƒœ“Ξ―ŒΖ}?5τhψΈ‘§6k ».h΄ΔZZ½ίŠ>x-ϊ$§οΡ I"Et…άύΕPQ$W‹kΔ±@ά/«Δj±N< €μι2WŽ–εrŠΌOή/—Ι­ψΩ!χΚχδ!y’·Χ|ZΊΦK¦Χ&h·’3΅ΉΪ}hΩΪFmΏφŽφ₯φ•v½Φ^ο€ΟηθιΟκ[υ·Ώpά‚ŸuŽέŽ:ΗێSŽSNιLrvpf:otnp~b8ΎF±±ΨxΧ8ξͺDHξ₯°LΔμ$7ΚΆϊθsθϋτˆΈIΜ Mβ¨ ξ9b½+γ΅Ρβ>d“ΊˆΓΔw θ}2]Gόˆώτ!}έΈVo‘ί…ω©–V’G7Σ_Εοθ„p˜G0»i˜Κ1Λ,…Ύ/$žυΕ8›‡ρ˜ˆδfη~Ϊ*œ˜Εsœƒυ9τύ}ν؍ΚΓLϊeγ4}­ώ©™cf`„a”ΡŒ»©t9FΜηΠ’—ΰgί5鱘K²1ͺ‹iEhηλ‘z=zπ^QƒΙ˜΅{ΠaΤ»₯θ'g’’z67ϋΙiΪKXcL„WaυJ¦ΛΔ@Š8Τ£Ϊ‰Τ§qdxGhz@όYIρ˜œbή―έήx3½IΏCŸψυΩF‘?wŒΘΰΛ ΠΏ_NŸή—fχΚΚΌ$£gzξέΊ¦₯vρuNρz:u쐜”˜Π>Ύ]Ϋ6­[ΉγZΆhή,6Ζe8Ί&υ,τ -σΚzšοŠ+2Ψο+G@yX@Yΐ‹ ‘g¦ xΛT2ο™)ύHyCDJΏ•ί”RΈ½ƒhPFOo‘ΟΨWΰσ֊ρ#Kΰ^Vΰ+υŽ*χUΚ½\Ή[ΐ’oaΒΤo@”y CgO­,,+@vΥΝbσ}ωSb3zRul38›Αh﫨ν εν TKr΅€P$_Aa ΡWΐ΄ΤΒςɁβ‘%…Ι))₯="’ob€|yΈt•„ςU1g~ΐPΕx§qmh‰·Ίg]εZ7M,Ko>Ω7Ήόš’€V^Κe΄JGΉφs>K8νEζ­σKξMΦ* ¦yΩ[YyΏ7P7²$<6…ΏKK‘xeκΠ²Κ‘(z)±h΄₯Ι…₯%±EzΉ&\+«~S|…Rv£7γΛσM­Ό± ]“T Qw¦“’όΫΝzJ*τVŽ)ρ₯†$ϋJΛ :T·₯ΚQwΦ$ϊ½‰gΖdτ¬v·²ΆΊeœνhή"ά1₯)NΉTrvjjYΑω†A!ήI^HRβCϊρΧ”~T9©’αS*ΐ˜Œ™ˆΙ/«tΰpζ8Rέ>oε π=rfHΉβLu@μd=iR5ć܁ττ@¬"F>ϊ2Vώ>=gΧΚΎΎ ·ΝGΕhΫς™hώ”ξΰ%΅~šO`ώΘΛο₯‰ΙAςg¦—dΗΤ…bڍε˜ω‘˜&φ24y+±Ρή.ΰJkϊηŽoS8u@@Δ_ zŠ_4ΪW4r|‰·°²ΜnΫ’1gψ¬ψ~MqΆ+Π&ΏDK–ΆK&k*JyMSbφ”4θ©ψηTJ=9 A)U€π ΈΛ°ΎKcSRΞΛSkΈΒ˜jΝο˜K‘ΣlΆ”ιgϊžα?CΊζ•δΥΣdјρ••±gΔ ΕTY9ΤηZYVY^kΟθσΊ}•Ϋε³ςΩʊ²P‡Φš;–$†.-E%¦ŠPVIyΥ>±hd΅_,=Ύd»;™EcJ‚RΘό²Όκ.ˆ+ΩSΕ―BeS(ϋΌμ£"EJ—ŠJήξ'š―bu ό“j©0W(LΠ€Zi…ΉU>0cΈσψU`PήV)F­βoC½Q£XCo”θr:₯ΆK€Q ŒαJHwcPΓ αξο]Υ0ˆ†ΐν>…―^Y)­RZ₯βKΐΐ8εΥκNωt’ΌzLΪ#/ΣΖ‘¬ΈdΙ~D™GEζΡ^Ymΐ†βΏd3†Εjϋ«ω™6Ώ>nΠD—ZέΧ}:HνΪή,ΈνΔ‰S nruAΪ@Xζμ–ΑΓ)ίM'Nœ˜γ&;ΌιΣ’ΤiΙώ66R­φ&Uθ3¨50ΤθH₯ŽΧiΌψ’AάM@ΎΦ{ΚΝ4ιgΑ?τaΩίl@ϊqΐ:ΰRΰ* ˜\mc4 ž½ΐFδq=η£θ§t£±.CY¬ʁGγθQΔύΖٟ&r8ΚZŠ<|p?†π5΍΄ξUˆ/崊28Ίρ=α~Ψ1Ξ4ed Œΰn@x<ΚˆeMCω3τζQΈ{ οaˆΏt,θ[ήεώ”yT]ΉŽ‹Ωφ™‹πΐ(` 0νΓόYΰσΐΏ ξf+΄9ΠR'κŒ4ƒ`@3P~Ύ]oRυF=šκω•LηΖX–/‰λυ5°8&[$–°’.UύΗun ”ϋ(νΘυr|nώΘ€ζB½vΨί½\dn„œC[iόΩΐ …$τ'hΊφ=ϊ`+Νq€§N²πJ•G(Ι™J9hΏδ50yΎ’τa2Λ`υθŸSς*nDΩ{CνΔmθΧ€=Ε#νz0 m° ΈεCω™άζθχΕΈΖί!m=Κ)b Lκnυ+Ν /‘Κ±ϊΑ’βoD›>μ^fBPzfCε΅‘4ΉΡ<ΪHφ+Xί€2 ?§Aω±H«τ:ΓΊΙϊΑΊαx]ικh–έͺƒ Kμ1s ψ'‰@7ηfΊΖF7€εφ™Θ:Λγ%”7λλLˆ*ΎIιύ'λT}ΔQG#YU.t+Dyά!ί;™bΖ2=Tu_Εϊ’ά.¬k<yLΨ΄8¬=ν1ό”CC4ΤMt?=Ž<Η9W@OΣpύΛΈγNΠ‡PΏνC}tμ ΄tαͺ£ξθΛΰ},‚bō(λA}Ϊβ ­QνzPvΦ ‡c“ω΅ƒΔ^Η&9WΉΟ’‘uVSFxάΟ W ίsl’ΰώΖqΠ4QŸ‡xL‡Eΰ Q„ω@WΊXεΊIΤcɍ-ξχΐtέO~ΚΑ5Do‡Q*ΒΗ:/WσξrδΊ8LΛΠ_Ώ6Ϊ‘Oϋs#Κ’οa}8Π«Βτθ ‹Τ₯ ιk$eαyΤšˆq·Ψ |`γoΐ'ΠΗ+€ΛymΰωY­˜£e–ΎšG›τs/=ϊ@H?#τ΄G„~‘zIymαω]­-§cY¨ώn„cNηψfΪr?J?N³υξpo]M­œΝvώyΜ}*μS+ŽΓγι7Π»L}1ύΦQM%άW\ΩΗ|ƒϋc>Ι5ŸΦώ„ΧO ΞΨΙ«6¨£ΥJŸ˜·Ζ<Αυ3R{‡†ϊq€ykΘk·ΗJΥuͺU:ŒΆΰ<ο*{ƒ‡ώIΊΫK»Ίb~ϊ’ Μ%ͺ¬jΊΪεWν«υϊcci‘£­ω_J7›¦vcθ0Ζ¦ͺ£%:ΣjŒ₯Eͺ},Ί„Ǐv˜Ϊ±Ž ~c”=q:ώ έζάDKuΠ»ƒX ’ί£.7Q?ΈWθ›Μ“H[ˆ<ˆΛFψHeŸπ:ε7πx1κ(Απ£|€a”ύ‡r΅Ο!οΓ΄sIλ0=ντR–G6;½,(<`.°Τ‚ s[T€ »9\N‘=B™‚Η‚ώ;Œ½Υ”«=K±ϊ °Ύ‘2“ξΧ†CοŽbΝΠθnφλ=©›v”Š΄ŸΤϊsΏ#–rTΊx¬γ_Q±^ ώ:š¬i²f< }Ÿ£–Ζ;&ΑΞΊωؐ}ΑCΕΞ%pgš›9*γ'3ž‘ίIي/ JΦXζua2?ŠZέ}`yα——em’Σ–ρ\ς©zrΎΰSiώ“rΡN©m)—Ρ& J~;ΌŽζŠ•ζ΄λΠ\ξΧηŠE@1 λsi-hθ7ΐAΰ `πτ>΄yΏ ZΓϋ†ό=ζ.PΔ?Ό|Š —sπpθ_˜;ΒύŽlκϐ=1§χ<3N₯_K½υ;0g™;ΪlŠe8[RwΓEέε'ΎΏ£ύFŸŽ΄£H»˜L>Yaνθ―c¨?@γ |F½L1Ύ2x}ώwδϋW€ώόR΅]’tθ+Ψδ†ωŠΨEΧ‰zσζs'ΓςS’jΟ΅Τ*ΤO_€Β#ϊΊ—Ϋ<2ξAŒ?²_/ζGΎΣΒƒŒlς3τ‘ˆτc=π3œ¬c=Οφ7•{>Œ‘ήh§‘ϊΘςΙΩ~§›2²ώUˆ‚Ί2šόc¨;ƒΣ2ΠΆ>ΪzC~B) mβF©τƒaνZΒνͺΥ1―βWύσΘώ/ι―b>ϊ 6σJŠ€αc6rάF†…ζ’s₯‰YηΛσ'`μΌΌόρ΄θΉ θ*ΰ&ΨtοΐήΐV}ϋ¬7iQΓ"’“/ΊσΦΰSΟ!l,άi 6 «ΡΙzΈ+χ.°¨“ιΫL„ΏΠβmXoη—jρ3ί X;'ϋZό'οVΓύ-;ω θ# ? }|₯ °N-ν 1}8υ6όƒ¬ϋ§_σ̘S™ΰ_ Μf{δϋΠ^zžύΗ?K­3ΊVٜ7rρOΣP^„Fξ5Bύ1ΪKœEνv€Νχ#lοsΑ=Nˆ’?ΛΖχΐ·ϊb³6₯‘μhΨ²ΚζfϋΡ¦Κή>¨μIaŸ)*ΚΆ3Ϋ―l;³ύ ϊ„Ϊην‡<3θΌΟWr…Φ‘°ΉUφ€)@Ό Μ{”4†<ίaξ‰ΓϊϊlΛε ϋ σ: ζ›X»β0ηξ»Μ@χΑίkYLhM Ν­gΝ±g―i£ώŸ»Fώ kκΣ" ΏΑFd|¦ΞŒΘ΅ψηβbkχΏΌ–Ÿg_§]h!f0e3 ?δφŸm—FΪσ_ΜΞύΉώH»#Μ_ΝΈ@ΌςGΪ%!$Ί?[χ,{& γ-„ˆqχsqš§O7ߍא ‘γΈiΌΩ~η<* CTl n˜GΊKν}—n¬ζ^ί\§(ΫυeΓ‚z ζ³ΤZϋΜ₯b+lιΥΫ‹…πϊ>•ΆΔFιΕτ9RoΩ>Wφ!ΪLΙΎ}ρ=eΦ@5pKS_c‰²χhXyyŸ«}fώ€Ό~8Ÿ-x>Š}ήmΌίƒ?ώ8ΜΕΙΞjκΔηj]‡ύ맘_§i§ΟψΜgJs:[ώ€†cžΏ{βιϊ§ζfu‡“€­Ζm‘{uΆφ˜}—’ΜgCΖ·|χc>gŸΟ3°§±Ξ\κ€ξ!¬³ψΙH;‰Ο¦δίψέ’:CN°iŸOρzεμ֘–aηΘ€R½/υϊΫχT΄Θ{β]’ξdNR@ŽΖρ]XμFz$ζuzΔ…ϊČ£5FZ£ίFΗ U.>Cξ@+x½ ­«hϋΖsœύρYf—°3MUηH›@ΙΧσjs]xΉ!>W>Ϊf”u7dŸ³_ΠΆA>9@π=πΕΉΟ;Ν}φΉη|{eӚyNΏ–.Ρ»«ς¬3Y¬ΩŽζΘ§Ή’]΅q€,‘²Π. η³…BΆ‰}FΕχl μ;Έή@[;lŒ² rιθ―|f渟τJ%7š―6₯Ν€ΞίR:[ΙrκΦ½]2p“6˜ δŒΡχ©­:“|Wέα-΄1zΊ^έ™Vga£œ›>w4iΪκ‹ΣΐΨj‚ω…Ύ e1Τ½ŸωͺΥϊH₯Ÿ‰Άn&λ?Q‘ΎAιLkϋN0N_pΫU@GϋژΑwoκ~OQΥV‡Ρξ•4BΥ‘Οζ6AoΡ>ΪZu>8!”Φ5„Ζ‹‘―[ ; PξPς8WίS‚³μΓJΤ»Ό h‘ό;e3Δζ'R‡‚04’l–9ζβ»_ΎΆοΥf >|·uœΣ©΄Φ].£Cn)φ=aΘέΖr«°7l·±> Hgώ 8)ςΙ!ς—λX2inθjΐ3Ρ†tδ;@ύj΄Υ™Θx™fFαLS#a‡'EαLσ"πΌsΘqΎtη“γ|αi‘@xΪƒηΛΧ „ϋ. _Q$^τ3δ8_;w‰Β»\@Žα‘@ψπH90?mvcϊ―ŸX«οε7†—Nž‡ϋ^σΫΏΗN7υ4ψczlΌ—ΖzlžFž—eΆ³ίiΪε˜7Α} τr«,ζmάi•­`—ΩΈή–υEΠί‡ωYv”έψ‰Už*r4ξ°μσq€Ω@»άg-ΉΫƒΞ΄Λ#«ŽŠοΩΣ01όLΜγ \·Ρ§Α²7bοo>eΩL΅v[³Κmΐ>ΡL2μψE§ηΪƒ}β/1ΖςZν’DLyUsξ4jΆVέnίY†η;'€ΡQG'l8δΛvΟαj?‰y_ν'’ξΥ'+tΑ:ς.όCUΠΓ–˜7ο£n\†Ί—™ΑοYΜulshοH†²5κΤZΛλAμeTκ™Ύ§$δŸlΌEKΧρϋ΅ζ53¦ΒKΨ|GfΠlΧZZjBΌFC±^ε‡ΒC{[ηBΣtτ€f!κϊ•o"ό>ς9’ΘΗε}ˆΟtrBe7έέoζ}κw֝eN₯ΏP2C^ΠV Ι‘wͺMφbOQOuητ β΅pΆΗΈ:E݌ΨΫhQŒ€ΗŒλΥή} ώ$υ{/ΑχOΞ?SOΗ½Τ.΄ww~€v½}hS> 8ΦΠγϊ䡆Όκ^Λ>h’‘<ψΎν0­ζ·‘vMȎj²oμ3‚¦2μϊ0ε΅3¬ώІΩΦ™B5]Νwc|§μŽ’‰ορψ. ω\§μ―Αt1kλs4Τω*ε;ςa§_Iω$ςΟP"ΫgΖ ΠMΆΧψ ΗKŽΥ„1n棟φ‚ήμρ=Ξs6ΫsΗ(+\M„5lm9σ­I­ϋ~eΓς½a›~dΣ7YΧΨΦ‹€‘οWΞχžεόv¬=ΞBτΜw/‘΄΄ι]ΞE¨φNζ\τŸ=»Sχυ˜§Bτμχφ™\΅νςΘw8§ιC°Σ>ΆνΨ–ΦΉ"-Sos.€¦7\ΗΝcΞγαs$ΐozΞg'€λDd»α7Άεφά—³λΧ2u&γε΅ή€nζŸ—ι†3m>s΄=σ;X~SΤΪYCc΄FΊϋεzsΜIο™_0PΦ}6φΪXaΩ~ζkΐ+φI]8΄K¨ξ(₯˜kl{›νΨΫ,πλh?-WΣIXΒΨλκVŽώŽSφΛcν1μΑ-e{A­q4Œί%Α¦l©ήάΨϋ~uφπwP )h—1ϊCκΝθh…―‘ŽίΥκMŽυNi€³ ΤλΥϋλΝ/Ώυύ+p ΌG`sŽ=ύΆ†σ`{ν"νS΄#ζmφΈ°œ΅§AΗZΠ5Π»°GΏ 6κΗp€Nο z;pάi s€ ΐf;όW”νh‹Όp3°—Φ·YT³χΥjo½ί‚ζE—o έ}Τ[CΨ@,0ُ̧γςTΊlω5ΚψΕjΙΆ;q.kΞŽΩq‘4y§Σ8ŽΠΨU°©Ϊ‹ΝŽ\s‡ψš:ιcψύΩ@O6ς~θEێΒh5Gkωόυ¬w‘{r›:φPΗC”νŒ§ŽD*Β^ Χ‡uΈ„ΊaώαχΧc­=Q#ον¦ς{b~K¬΄Ξ½νσqεv Kb`Ÿ#žμ7NJΚM?Ή«ΦNυ–^°υΆΙ²ΘΤϋiŒ΅k”Ρ2γ)Ψ’OΡ{.*·ΟΊZρΊwu&ԝς¬7T&hγs <Fcnh:{eΚoΪX·l[ΣoΦβωΝ•™ΓwΪeό^Kρ^ ζΪmx%ς]v΄ωfγυύVδύΤωξ‹.φ6γbo5ΞςΜ;•Θ·{Λq1Yw0Ή/Σ?5_fšηQ£#»Νƒΐkά θ²‰Έ K)Hw―όcφC¬'ΙcŸ‰&#Ό-ζ―ΆϊOJξ·ςƒ}žͺΞ\ωlΎ"μχ–ΐv½νRm‡ω*Οsκ"©3Λaag΅ΉM紃i€šk1§Ϊg΅ΛxŸ¦ζ X'Ο3<‰ο( žgΤΉδLψS¬y‰έr6FΓp#~˜5Oρ€]žλvš³ΤœΙsCΜWšΈώol`’ŸΪο-9δW|WΣψ^sŸδ΅I͝ΚWCΒm> ―}όn½ιr/f/ΩφeΘΖ|51»iφ†#2Ύιη―όΦφΒλoύΞ‹½ο²ίF;/Uϋ5ο /“ΓΞί{ΫgΞ½U-¦V˜S’ΟΪh4ϋ6΄§G;ύΡ~[’Χ[Pλ4·γ—jt­*sœ­wNeΧπώŽχ­»{οΪΛΕΫΊΥ u[‰upΏσ·Χϋ]|ίbγ· υ†d/=‘ή2οε‹£±ι²lΉuΐΰΠ™hψ£½›Π΄ΪNX‘W;“ώ>9]ώ19•Nt ±|.Ξΰί+`π}Q4{O·ί άEQό―ΖΚ(’ˆ"Š(’ˆ"Š(’ˆ"Š(’ˆ"Š(’ˆ"Š(’ˆ"Š(’ˆ"Š(’ˆ"Š(’ˆ"Š(’ˆ"Š(’ˆ"Š(’ˆ"ŠΥό­θ ’ΙI’ά”ΙΏΩk ’ Ικ1σs[h›i €H|{*@#ΏΆΉΖh‘ν―mέVΡ`|zφv³Ž—ͺπŒG²ηο6Ρυt)‚7Ηrπ¦AΆ’—΄hf/Eƒ.+Ϊh›νΙM[& )ΞvžvN΄‰ώ ˜€¦mΠΦ‡zΓ3Θ(.·­φ ͺηΗχ~ΐ4H κς }k‡θκ隘ζ\όӊ+Y{\qψvσ-ΐ~ΐAΣρύ$`\λ·Ž€ΆN{*θφΈsc΅΅4Ϊγ'yϋͺ·j›ΗjβΪdϋsέΪ£T H hWQ ‘ν °­ ‰δEΑŒ^ͺ ‹jb[f»‘~ „^A– Θ*| εχœ~IM›xΞώή`\+Εχ«`VoΛQγNΘ.F+άAB›’έJ>ςhsA;Nν:Q›L-”œώš8wφ|”7Ι‡hν¨;’s΅xΚ-Π’(Y%›li•3+Ψ­G6jœ―%¨$qZ κ κŒ`ΆΗ»Sσ«Ζ_Tӌε[t·Λ~I[¨Τ©ζ#U{OάKZ,z6VΥdLML‹μεΉΝ΅1¨ζ4‹2 ΄ς­*£[ƒΘ(·•V¨u xΔέ€u€v C΅NŠ>«=ECAΧΤ€uπΤνΤV\q¦(~°₯ZƒkZ΄ΜˍΡ#6 =€x@ΎΌ&­_6ε¦iέ( hγypΝSJ_ W%z­=U‰žͺ„P•Π>#f1djs¨B»–OΒΝjΥ.ˆέ]ΊeoΧ΅4Œ{'šR 4©&¦%K–lέF%K¨iή2{ΘKΪ θω διΧfΦ΄OȞΎSλ‘ͺ³&!™*‚PΧ—΄φVΧ€1ž»δ%­‚¦£Φ)ΨΞΘυΐϊμ!!ߐΈ‘δ;ς w7υgEί΄ι>›ΎeQ³N°…ό3Σϊάςsdv½όˆž„KʝςΚΓ²–₯οΛν4τό“A·ƒ^ Ί#˜²ΗS+kk@ ϋκ`‹x¬|%˜ži;<©Ά£}²νhŸ›* _¦Θβ/ ]@_–uΤt7hhœI{@_}h θV›Ύ*w±ŠΛε6κZlΙ"‚“-A'“ηƒdωŠ3=»δσr%!ιsΑ΄$„n¨Iλβ‰Ϋ‰ό„|FΞ vτ΄Ξ•O‰ρ=UΡ!¦ΤZ ζp&Λƒ»ΌžνrΉ\ξOΘρ§ϊ3ό롬ԬŒ¬υš7Υ›αΝρχζΊε˜@ž”Ώr ΎsΘ+‘=€X.υœ@nκΔυ’4ίUΚU†ο ε"|»›bΏS!r!$ς˜ ΜζχŽο9ΐ―€»€»UΘL`p;f“ pT€£Š£ΰ¨G…β¨P₯Ο˜£ eΰ(G™β(G8ΚΐQ¦8Xή2p”)Žbpƒ£Ŋ£Εΰ(G±β(G18Ї~pψΑαW~pψΑα‡_qψΑα‡_qd# YΰΘRYΰΘG8²G8²ΐ‘₯8Όΰπ‚Γ ―βπ‚Γ /8ΌŠΓ /8ΌŠΓ 78άΰp+78άΰpƒΓ­8άͺfΜQŽzpΤƒ£^qΤƒ£υΰ¨Wυΰ¨G½Ό½Z;ϋX€εX(–`9–`9 X€εXΨUŸ©CBmζσ€ωσց·Όuΰ­SΌuJ½fΜGpGpΐPpΐPUΰ¨G8ͺG8ͺΐQŽ*ΕQ₯wΐ?_)vΧΘ{D‰ k­œ/Ί+:Ž(:—)z7U+z­WτW΄@Ρ9”£θ픦(ςSt&y\"θɉˍΗ0Έ˜< lv†rνώ ˜²Ώ³gŒ0ž4Ά» ǣސqΞΞ'[œ»Ž-Ξz§τζ&ΛjΕΤBͺοyψώΐ"‚ο!Κ5DφFΉ½1ΟφΑOoΩΫίκ¨χΫb±»‡ΨC<ΨCδΖΘΛ…f:/εH.JόΝΣ{9i]cfz`Ϋ‘φž`Z_O­Ψe‘ξώtΠ#@5°XδΩ@ xTX€/ρwΆ³άtR/Aρρ° [·rω·Λb}Νk-(†ΛιΪ |;ƒ]³@jƒ]G€Όμ:Ρ“#ΆQWΆŠΔ θΉM [‚žΟύœE6=;A6=½A v½dB°λ>On 1–<:³Ž±ιhΤ›ι¨ g’ zΊƒ€»¦qκ((±έE }šjsu±Jς=A:=ύ9΅‹ΊrΗ 'e(ρS­}»]”θΒίΜsΤσ°ηΨ£a‘ο{kuύ©΅bœ?Φ³+c-ηz‚Ή±œλC΅ML_π¬O]μYΌDκ6ΟcžK<dΤΊΌ r/VE= Ό΅r“ΏgΎ'Λ33γ3Ο Ο•žrΟ(Ο΅©zρμb1©T”ΘMΫ<ΕΘpj‘τ\žZ«DκΉΣγχtυτχξβφ₯~VΎ9»Έ(Ϋ*½'Ϊ·Gj-λψ؜ZΡΚίΓψΞXnL0ςŒ†Οθlt2:m]­]nWKWsW¬ΛεrΊt—t‘«m­YοOηΏ‰ΫΦ©ώ4Sηo]Ήέ’ΏΥθΓΨ%ιJ ΄ΡŠdΡθMIϊ¨²4q:ΗJΣΆ[(MΫnH“ώo~¦δ₯‹š^³ζΎΒΎΜW8( ,™=5!0’Χ[=w–ύΧαΣΚ&NšΚ΄|J`–oJA`―ΐ[έλ•sDΏΒΡ½|ΥτJα˜’κWόS ‚½ό½ }ε₯5C•δžQΦ⦲J#³AœY —5$χΡΉ=„ΛΚε²rΉ¬!ώ!ͺ¬Βi¬χΕ%Υ.Κ+ΝΏΖ’5²Y,tΈ,9₯4/ή]1˜zϋΐ”„ΉΙ;t¨Yzi Ή//Π਌܌\ŽΒ8γ¨–޳£ζLIή!6ΨQn·ςεQ¨i‰ϊŒ, €Œ_Βͺπ—Ÿ»ΟfπGE'Pα΄όƒ¦~ΒSŒs~fžλ3kΦ¬ό5+}QQ Ηθ’@ί‘Δ0PTYA)Β. …iš «Ž‰)¬5λ™!ΔL.Ž]ι"-θΕːUΞ*CςVafMRΗμι/aŸ`'ofͺν³Ό½¦s*ο_fΦdφ±(Ά«LƒI)Ω(‘&¬LS-κo•ΗςΤεΛsͺR«2ͺrœέΆžυΌ”3Χk43}F¨!ΰœYŠΖ†X\ήSΑUΑUμHO/MŸ!T{έΨ"ΤθM ;ΓΞu†Κ~f¨C¬πv&θ «τY!ΆY6“Šœ₯˜¬L,_ΣΧι|DΙ># endstream endobj 240 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /MUFUZY+Arial-BoldMT /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> /FontDescriptor 242 0 R /CIDToGIDMap /Identity /DW 556 /W [ 0 [ 750 ] 1 256 0 257 [ 333 ] ] >> endobj 242 0 obj << /Type /FontDescriptor /FontName /MUFUZY+Arial-BoldMT /Flags 4 /FontBBox [ -627 -376 2000 1017 ] /Ascent 728 /Descent -210 /ItalicAngle 0 /CapHeight 715 /StemV 80 /FontFile2 243 0 R >> endobj 244 0 obj 508 endobj 245 0 obj 5226 endobj 246 0 obj 583 endobj 247 0 obj 6581 endobj 248 0 obj 363 endobj 249 0 obj 25128 endobj 250 0 obj 234 endobj 251 0 obj 10948 endobj 1 0 obj << /Type /Pages /Kids [ 5 0 R 18 0 R 23 0 R 29 0 R 34 0 R 39 0 R 44 0 R 58 0 R 63 0 R 68 0 R 73 0 R 78 0 R 83 0 R 90 0 R 95 0 R 100 0 R 107 0 R 112 0 R 117 0 R 126 0 R 135 0 R 144 0 R 151 0 R 160 0 R 167 0 R 174 0 R 183 0 R 190 0 R 199 0 R 206 0 R 211 0 R 216 0 R 221 0 R ] /Count 33 >> endobj xref 0 252 0000000002 65535 f 0001001232 00000 n 0000000000 00000 f 0000000016 00000 n 0000000142 00000 n 0000000279 00000 n 0000000444 00000 n 0000025244 00000 n 0000001104 00000 n 0000001123 00000 n 0000001142 00000 n 0000001180 00000 n 0000946402 00000 n 0000946555 00000 n 0000001214 00000 n 0000017372 00000 n 0000025201 00000 n 0000025223 00000 n 0000025445 00000 n 0000025614 00000 n 0000026324 00000 n 0000026284 00000 n 0000026304 00000 n 0000026511 00000 n 0000026680 00000 n 0000027624 00000 n 0000027584 00000 n 0000027604 00000 n 0000946711 00000 n 0000027825 00000 n 0000027994 00000 n 0000028415 00000 n 0000028375 00000 n 0000028395 00000 n 0000028588 00000 n 0000028757 00000 n 0000029904 00000 n 0000029863 00000 n 0000029884 00000 n 0000030091 00000 n 0000030260 00000 n 0000032376 00000 n 0000032335 00000 n 0000032356 00000 n 0000032578 00000 n 0000032747 00000 n 0000095186 00000 n 0000035745 00000 n 0000035766 00000 n 0000035786 00000 n 0000946857 00000 n 0000048011 00000 n 0000081454 00000 n 0000086885 00000 n 0000086907 00000 n 0000095122 00000 n 0000095144 00000 n 0000095165 00000 n 0000095432 00000 n 0000095601 00000 n 0000097686 00000 n 0000097645 00000 n 0000097666 00000 n 0000097888 00000 n 0000098057 00000 n 0000100225 00000 n 0000100184 00000 n 0000100205 00000 n 0000100427 00000 n 0000100596 00000 n 0000103064 00000 n 0000103023 00000 n 0000103044 00000 n 0000103266 00000 n 0000103435 00000 n 0000106189 00000 n 0000106148 00000 n 0000106169 00000 n 0000106391 00000 n 0000106560 00000 n 0000109494 00000 n 0000109453 00000 n 0000109474 00000 n 0000109696 00000 n 0000109865 00000 n 0000141035 00000 n 0000111152 00000 n 0000111173 00000 n 0000111193 00000 n 0000141013 00000 n 0000141252 00000 n 0000141421 00000 n 0000143138 00000 n 0000143097 00000 n 0000143118 00000 n 0000143354 00000 n 0000143523 00000 n 0000145690 00000 n 0000145649 00000 n 0000145670 00000 n 0000145906 00000 n 0000146079 00000 n 0000159868 00000 n 0000148038 00000 n 0000148060 00000 n 0000148263 00000 n 0000159845 00000 n 0000160102 00000 n 0000160275 00000 n 0000160708 00000 n 0000160666 00000 n 0000160687 00000 n 0000160882 00000 n 0000161055 00000 n 0000162225 00000 n 0000161995 00000 n 0000162016 00000 n 0000162413 00000 n 0000162586 00000 n 0000179426 00000 n 0000163195 00000 n 0000163216 00000 n 0000163237 00000 n 0000176689 00000 n 0000179381 00000 n 0000179404 00000 n 0000179648 00000 n 0000179821 00000 n 0000219812 00000 n 0000180611 00000 n 0000180632 00000 n 0000180653 00000 n 0000209619 00000 n 0000219767 00000 n 0000219790 00000 n 0000220051 00000 n 0000220224 00000 n 0000243585 00000 n 0000220875 00000 n 0000220896 00000 n 0000220917 00000 n 0000236102 00000 n 0000243540 00000 n 0000243563 00000 n 0000243821 00000 n 0000243994 00000 n 0000274582 00000 n 0000244591 00000 n 0000244612 00000 n 0000244633 00000 n 0000274559 00000 n 0000274787 00000 n 0000274960 00000 n 0000312940 00000 n 0000275606 00000 n 0000275627 00000 n 0000275648 00000 n 0000305039 00000 n 0000312895 00000 n 0000312918 00000 n 0000313162 00000 n 0000313335 00000 n 0000331115 00000 n 0000314138 00000 n 0000314159 00000 n 0000314180 00000 n 0000331092 00000 n 0000331337 00000 n 0000331510 00000 n 0000363649 00000 n 0000332003 00000 n 0000332024 00000 n 0000332045 00000 n 0000363626 00000 n 0000363840 00000 n 0000364013 00000 n 0000526925 00000 n 0000364562 00000 n 0000364583 00000 n 0000364604 00000 n 0000428126 00000 n 0000526879 00000 n 0000526902 00000 n 0000527133 00000 n 0000527306 00000 n 0000632060 00000 n 0000528015 00000 n 0000528036 00000 n 0000528224 00000 n 0000632036 00000 n 0000632265 00000 n 0000632438 00000 n 0000671682 00000 n 0000632959 00000 n 0000632980 00000 n 0000633001 00000 n 0000641981 00000 n 0000671637 00000 n 0000671659 00000 n 0000671890 00000 n 0000672063 00000 n 0000726630 00000 n 0000673389 00000 n 0000673411 00000 n 0000673616 00000 n 0000726607 00000 n 0000726835 00000 n 0000727008 00000 n 0000728099 00000 n 0000728057 00000 n 0000728078 00000 n 0000728287 00000 n 0000728460 00000 n 0000729221 00000 n 0000729179 00000 n 0000729200 00000 n 0000729426 00000 n 0000729599 00000 n 0000730240 00000 n 0000730198 00000 n 0000730219 00000 n 0000730428 00000 n 0000730601 00000 n 0000946197 00000 n 0000731296 00000 n 0000731317 00000 n 0000731507 00000 n 0000946173 00000 n 0000952898 00000 n 0000947008 00000 n 0000953925 00000 n 0000947594 00000 n 0000961451 00000 n 0000954131 00000 n 0000962659 00000 n 0000954792 00000 n 0000988515 00000 n 0000962868 00000 n 0000989067 00000 n 0000963309 00000 n 0001000604 00000 n 0000989266 00000 n 0001000854 00000 n 0000989578 00000 n 0001001058 00000 n 0001001079 00000 n 0001001101 00000 n 0001001122 00000 n 0001001144 00000 n 0001001165 00000 n 0001001188 00000 n 0001001209 00000 n trailer << /Size 252 /Root 3 0 R /Info 4 0 R >> startxref 1001534 %%EOF client_golang-1.21.1/tutorials/whatsup/Makefile000066400000000000000000000015501476160432400215720ustar00rootroot00000000000000.PHONY: help help: ## Displays help. @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n\nTargets:\n"} /^[a-z0-9A-Z_-]+:.*?##/ { printf " \033[36m%-10s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST) .PHONY: init init: ## init $(MAKE) stop go test -count 1 -v -tags=interactive -run ^TestPlayground ./internal & # count 1 is to avoid cache. .PHONY: stop stop: ## stop init @curl -s http://localhost:19920 || true .PHONY: run run: ## run whatsup @go run main.go -config-file=./whatsup.yaml -address=:99 .PHONY: metrics metrics: ## get metrics from whatsup @curl -H 'Accept: application/openmetrics-text' localhost:99/metrics .PHONY: whatsup whatsup: ## ask what's up @curl localhost:99/whatsup .PHONY: test test: ## run acceptance tests go test -count 1 -v -tags=interactive -run ^TestAcceptance ./internal & # count 1 is to avoid cache.client_golang-1.21.1/tutorials/whatsup/README.md000066400000000000000000000001051476160432400214040ustar00rootroot00000000000000# client_golang Tutorial: "WhatsUp" See [slides](./ContribFest.pdf) client_golang-1.21.1/tutorials/whatsup/go.mod000066400000000000000000000052471476160432400212470ustar00rootroot00000000000000module github.com/prometheus/client_golang/tutorials/whatsup go 1.22.0 toolchain go1.22.6 require ( github.com/bwplotka/tracing-go v0.0.0-20230421061608-abdf862ceccd github.com/efficientgo/core v1.0.0-rc.3 github.com/efficientgo/e2e v0.14.1-0.20230421070206-d72d43f3b937 github.com/oklog/run v1.1.0 github.com/prometheus/client_golang v1.20.5 github.com/prometheus/client_model v0.6.1 github.com/prometheus/common v0.62.0 github.com/stretchr/testify v1.10.0 gopkg.in/yaml.v2 v2.4.0 ) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/efficientgo/tools/core v0.0.0-20230505153745-6b7392939a60 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.34.0 // indirect go.opentelemetry.io/otel/metric v1.34.0 // indirect go.opentelemetry.io/otel/sdk v1.34.0 // indirect go.opentelemetry.io/otel/trace v1.34.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect golang.org/x/net v0.34.0 // indirect golang.org/x/oauth2 v0.25.0 // indirect golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect google.golang.org/grpc v1.69.4 // indirect google.golang.org/protobuf v1.36.3 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) client_golang-1.21.1/tutorials/whatsup/go.sum000066400000000000000000000344651476160432400213000ustar00rootroot00000000000000github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bwplotka/tracing-go v0.0.0-20230421061608-abdf862ceccd h1:WukrqDL9VxKSoSC6HkEoAwQNuj5N49CPIEFsYtNBEKM= github.com/bwplotka/tracing-go v0.0.0-20230421061608-abdf862ceccd/go.mod h1:tZEa2D7ZMVaxzB8RoMdvASCwSHWb5kyb8G7mRbJcIMA= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.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/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/efficientgo/core v1.0.0-rc.3 h1:X6CdgycYWDcbYiJr1H1+lQGzx13o7bq3EUkbB9DsSPc= github.com/efficientgo/core v1.0.0-rc.3/go.mod h1:FfGdkzWarkuzOlY04VY+bGfb1lWrjaL6x/GLcQ4vJps= github.com/efficientgo/e2e v0.14.1-0.20230421070206-d72d43f3b937 h1:id4ofFoEdjDgOvGhRi24PozN2kzsIriHDKc+HP6ipHo= github.com/efficientgo/e2e v0.14.1-0.20230421070206-d72d43f3b937/go.mod h1:plsKU0YHE9uX+7utvr7SiDtVBSHJyEfHRO4UnUgDmts= github.com/efficientgo/tools/core v0.0.0-20230505153745-6b7392939a60 h1:2tYT4FnRj0hAAkGpDVmIU2/PndCwhfSnI0onr9tvv7k= github.com/efficientgo/tools/core v0.0.0-20230505153745-6b7392939a60/go.mod h1:OmVcnJopJL8d3X3sSXTiypGoUSgFq1aDGmlrdi9dn/M= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0 h1:VD1gqscl4nYs1YxVuSdemTrSgTKrwOWDK0FVFMqm+Cg= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0/go.mod h1:4EgsQoS4TOhJizV+JTFg40qx1Ofh3XmXEQNBpgvNT40= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0= github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/minio-go/v7 v7.0.45 h1:g4IeM9M9pW/Lo8AGGNOjBZYlvmtlE1N5TQEYWXRWzIs= github.com/minio/minio-go/v7 v7.0.45/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I= go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= go.opentelemetry.io/otel/exporters/jaeger v1.6.3 h1:7tvBU1Ydbzq080efuepYYqC1Pv3/vOFBgCSrxLb24d0= go.opentelemetry.io/otel/exporters/jaeger v1.6.3/go.mod h1:YgX3eZWbJzgrNyNHCK0otGreAMBTIAcObtZS2VRi6sU= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.34.0 h1:jBpDk4HAUsrnVO1FsfCfCOTEc/MkInJmvfCHYLFiT80= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.34.0/go.mod h1:H9LUIM1daaeZaz91vZcfeM0fejXPmgCYE8ZhzqfJuiU= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:gap6+3Gk41EItBuyi4XX/bp4oqJ3UwuIMl25yGinuAA= google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:Ic02D47M+zbarjYYUlK57y316f2MoN0gjAwI3f2S95o= google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI= google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A= google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= client_golang-1.21.1/tutorials/whatsup/internal/000077500000000000000000000000001476160432400217455ustar00rootroot00000000000000client_golang-1.21.1/tutorials/whatsup/internal/acceptance_test.go000066400000000000000000000041331476160432400254220ustar00rootroot00000000000000// Copyright 2023 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build interactive // +build interactive package internal import ( "fmt" "io" "net/http" "strings" "testing" "github.com/efficientgo/core/testutil" ) func TestAcceptance(t *testing.T) { resp, err := http.Get(whatsupAddr(fmt.Sprintf("http://localhost:%v", WhatsupPort)) + "/metrics") testutil.Ok(t, err) defer resp.Body.Close() b, err := io.ReadAll(resp.Body) testutil.Ok(t, err) metrics := string(b) gotErr := false for _, tcase := range []struct { expectMetricName string expectMetricType string expectExemplar bool // TODO }{ { expectMetricName: "whatsup_queries_handled_total", expectMetricType: "counter", }, { expectMetricName: "whatsup_last_response_elements", expectMetricType: "gauge", }, { expectMetricName: "build_info", expectMetricType: "gauge", }, { expectMetricName: "whatsup_queries_duration_seconds", expectMetricType: "histogram", }, { expectMetricName: "go_goroutines", expectMetricType: "gauge", }, } { if !t.Run(fmt.Sprintf("Metric %v type %v with exemplar %v", tcase.expectMetricName, tcase.expectMetricType, tcase.expectExemplar), func(t *testing.T) { // Yolo. expLine := fmt.Sprintf("# TYPE %v %v", tcase.expectMetricName, tcase.expectMetricType) if strings.Index(metrics, expLine) == -1 { t.Error(expLine, "not found!") } // TODO(bwplotka): Check all properly. }) { gotErr = true } } if gotErr { fmt.Println("Got this response from ", fmt.Sprintf("http://localhost:%v", WhatsupPort), ":", metrics) } } client_golang-1.21.1/tutorials/whatsup/internal/common.go000066400000000000000000000062151476160432400235700ustar00rootroot00000000000000// Copyright 2023 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package internal import ( "flag" "fmt" "net" "os" "strings" "gopkg.in/yaml.v2" ) const WhatsupPort = "99" var ( WhatsAppFlags = flag.NewFlagSet("whatsapp", flag.ExitOnError) prometheusAddr = WhatsAppFlags.String("prometheus-address", "", "The address of Prometheus to query.") traceEndpoint = WhatsAppFlags.String("trace-endpoint", "", "Optional GRPC OTLP endpoint for tracing backend. Set it to 'stdout' to print traces to the output instead.") traceSamplingRatio = WhatsAppFlags.Float64("trace-sampling-ratio", 1.0, "Sampling ratio. Currently 1.0 is the best value to use with exemplars.") configFile = WhatsAppFlags.String("config-file", "./whatsup.yaml", "YAML configuration with same options as flags here. Flags override the configuration items.") ) type Config struct { PrometheusAddr string `yaml:"PrometheusAddress,omitempty"` TraceEndpoint string `yaml:"TraceEndpoint,omitempty"` TraceSamplingRatio float64 `yaml:"TraceSamplingRatio,omitempty"` } func isWSL() bool { b, err := os.ReadFile("/proc/version") if err != nil { return false } if strings.Contains(string(b), "WSL") { return true } return false } func getInterfaceIpv4Addr(interfaceName string) (addr string, err error) { var ( ief *net.Interface addrs []net.Addr ipv4Addr net.IP ) if ief, err = net.InterfaceByName(interfaceName); err != nil { return "", err } if addrs, err = ief.Addrs(); err != nil { return "", err } for _, addr := range addrs { if ipv4Addr = addr.(*net.IPNet).IP.To4(); ipv4Addr != nil { break } } if ipv4Addr == nil { return "", fmt.Errorf("interface %s does not have an ipv4 address", interfaceName) } return ipv4Addr.String(), nil } func whatsupAddr(defAddress string) string { if a := os.Getenv("HOSTADDR"); a != "" { return a + ":" + WhatsupPort } // use eth0 IP address if running WSL, return default if check fails if isWSL() { a, err := getInterfaceIpv4Addr("eth0") if err != nil { return defAddress } return a + ":" + WhatsupPort } return defAddress } func ParseOptions(args []string) (Config, error) { c := Config{} if err := WhatsAppFlags.Parse(args); err != nil { return c, err } if *configFile != "" { b, err := os.ReadFile(*configFile) if err != nil { return c, err } if err := yaml.Unmarshal(b, &c); err != nil { return c, err } } if *prometheusAddr != "" { c.PrometheusAddr = *prometheusAddr } if *traceEndpoint != "" { c.TraceEndpoint = *traceEndpoint } if *traceSamplingRatio > 0 { c.TraceSamplingRatio = *traceSamplingRatio } return c, nil } client_golang-1.21.1/tutorials/whatsup/internal/playground_test.go000066400000000000000000000077541476160432400255340ustar00rootroot00000000000000// Copyright 2023 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build interactive // +build interactive package internal import ( "fmt" "os" "strings" "testing" "time" "github.com/efficientgo/core/testutil" "github.com/efficientgo/e2e" e2edb "github.com/efficientgo/e2e/db" e2einteractive "github.com/efficientgo/e2e/interactive" e2emon "github.com/efficientgo/e2e/monitoring" "github.com/efficientgo/e2e/monitoring/promconfig" sdconfig "github.com/efficientgo/e2e/monitoring/promconfig/discovery/config" "github.com/efficientgo/e2e/monitoring/promconfig/discovery/targetgroup" "github.com/prometheus/common/model" "gopkg.in/yaml.v2" ) func TestPlayground(t *testing.T) { // NOTE: Only one run at the time will work due to static ports used. e, err := e2e.New(e2e.WithVerbose()) testutil.Ok(t, err) t.Cleanup(e.Close) // Setup in-memory Jaeger as our tracing backend. jaeger := e2emon.AsInstrumented(e.Runnable("tracing"). WithPorts( map[string]int{ "http.front": 16686, "grpc.otlp": 4317, "http.metrics": 14269, }). Init(e2e.StartOptions{ Image: "jaegertracing/all-in-one:1.35", EnvVars: map[string]string{"COLLECTOR_OTLP_ENABLED": "true"}, }), "http.metrics") testutil.Ok(t, e2e.StartAndWaitReady(jaeger)) prom := e2edb.NewPrometheus(e, "prometheus", e2edb.WithImage("prom/prometheus:v2.43.0-stringlabels")) testutil.Ok(t, e2e.StartAndWaitReady(prom)) // Write config file for whatsup app. c := Config{ PrometheusAddr: "http://" + prom.Endpoint("http"), TraceEndpoint: jaeger.Endpoint("grpc.otlp"), TraceSamplingRatio: 1, } b, err := yaml.Marshal(c) testutil.Ok(t, err) testutil.Ok(t, os.WriteFile("../whatsup.yaml", b, os.ModePerm)) testutil.Ok(t, prom.SetConfig(prometheusConfig(map[string]string{ "prometheus": prom.InternalEndpoint("http"), "jaeger": jaeger.InternalEndpoint("http.metrics"), "whatsup": whatsupAddr(fmt.Sprintf("host.docker.internal:%v", WhatsupPort)), }))) // Due to VM based docker setups (e.g. MacOS), file sharing can be slower - do more sighups just in case (noops if all good) prom.Exec(e2e.NewCommand("kill", "-SIGHUP", "1")) prom.Exec(e2e.NewCommand("kill", "-SIGHUP", "1")) // Best effort. fmt.Println(e2einteractive.OpenInBrowser(convertToExternal("http://" + jaeger.Endpoint("http.front")))) fmt.Println(e2einteractive.OpenInBrowser(convertToExternal("http://" + prom.Endpoint("http")))) testutil.Ok(t, e2einteractive.RunUntilEndpointHitWithPort(19920)) } func convertToExternal(endpoint string) string { a := os.Getenv("HOSTADDR") if a == "" { return endpoint } // YOLO, fix and test. return fmt.Sprintf("%v:%v", a, strings.Split(endpoint, ":")[2]) } func prometheusConfig(jobToScrapeTargetAddress map[string]string) promconfig.Config { h, _ := os.Hostname() cfg := promconfig.Config{ GlobalConfig: promconfig.GlobalConfig{ ExternalLabels: map[model.LabelName]model.LabelValue{"prometheus": model.LabelValue(h)}, ScrapeInterval: model.Duration(15 * time.Second), }, } for job, s := range jobToScrapeTargetAddress { scfg := &promconfig.ScrapeConfig{ JobName: job, ServiceDiscoveryConfig: sdconfig.ServiceDiscoveryConfig{}, } g := &targetgroup.Group{ Targets: []model.LabelSet{map[model.LabelName]model.LabelValue{ model.AddressLabel: model.LabelValue(s), }}, } scfg.ServiceDiscoveryConfig.StaticConfigs = append(scfg.ServiceDiscoveryConfig.StaticConfigs, g) cfg.ScrapeConfigs = append(cfg.ScrapeConfigs, scfg) } return cfg } client_golang-1.21.1/tutorials/whatsup/main.go000066400000000000000000000132061476160432400214060ustar00rootroot00000000000000// Copyright 2023 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "context" "encoding/json" "flag" "fmt" "log" "net/http" httppprof "net/http/pprof" "os" "syscall" "time" "github.com/bwplotka/tracing-go/tracing" "github.com/bwplotka/tracing-go/tracing/exporters/otlp" tracinghttp "github.com/bwplotka/tracing-go/tracing/http" "github.com/efficientgo/core/errcapture" "github.com/efficientgo/core/errors" "github.com/oklog/run" "github.com/prometheus/common/model" "github.com/prometheus/client_golang/api" v1 "github.com/prometheus/client_golang/api/prometheus/v1" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/tutorials/whatsup/internal" ) func main() { opts, err := internal.ParseOptions(os.Args) if err != nil { log.Fatalf("Error: %v", err) } if err := runMain(opts); err != nil { // Use %+v for github.com/efficientgo/core/errors error to print with stack. log.Fatalf("Error: %+v", errors.Wrapf(err, "%s", flag.Arg(0))) } } func runMain(opts internal.Config) (err error) { // Create tracer, so the application can be instrumented with traces. var exporter tracing.ExporterBuilder switch opts.TraceEndpoint { case "stdout": exporter = tracing.NewWriterExporter(os.Stdout) default: exporter = otlp.Exporter(opts.TraceEndpoint, otlp.WithInsecure()) } tracer, closeFn, err := tracing.NewTracer( exporter, tracing.WithSampler(tracing.TraceIDRatioBasedSampler(opts.TraceSamplingRatio)), tracing.WithServiceName("client_golang-tutorial:whatsup"), ) if err != nil { return err } defer errcapture.Do(&err, closeFn, "close tracers") m := http.NewServeMux() // Create HTTP handler for Prometheus metrics. // TODO //m.Handle("/metrics", ... promClient, err := api.NewClient(api.Config{ Client: &http.Client{Transport: instrumentRoundTripper(nil, "prometheus", http.DefaultTransport)}, Address: opts.PrometheusAddr, }) if err != nil { return err } apiClient := v1.NewAPI(promClient) // Create HTTP handler for our whatsup implementation. m.HandleFunc(instrumentHandlerFunc(tracer, nil, "/whatsup", whatsUpHandler( apiClient, ))) // Debug profiling endpoints. m.HandleFunc("/debug/pprof/", httppprof.Index) m.HandleFunc("/debug/pprof/cmdline", httppprof.Cmdline) m.HandleFunc("/debug/pprof/profile", httppprof.Profile) m.HandleFunc("/debug/pprof/symbol", httppprof.Symbol) srv := http.Server{Addr: fmt.Sprintf(":%v", internal.WhatsupPort), Handler: m} g := &run.Group{} g.Add(func() error { log.Println("Starting HTTP server", "addr", internal.WhatsupPort) if err := srv.ListenAndServe(); err != nil { return errors.Wrap(err, "starting web server") } return nil }, func(error) { if err := srv.Close(); err != nil { log.Println("Error: Failed to stop web server", "err", err) } }) g.Add(run.SignalHandler(context.Background(), syscall.SIGINT, syscall.SIGTERM)) return g.Run() } type response struct { Error error `json:",omitempty"` Instances []string } // whatsUpHandler returns all services that currently monitored by Prometheus. // It uses prometheus client_golang client code to request PromQL query against given Prometheus server // to return answer. func whatsUpHandler( apiClient v1.API, ) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() w.Header().Set("Content-Type", "application/json") var upResponse model.Value if err := tracing.DoInSpan(ctx, "query Prometheus", func(ctx context.Context) error { res, warn, err := apiClient.Query(ctx, "up", time.Now()) if err != nil { return err } if len(warn) > 0 { return errors.Newf("got warnings from Prometheus %v", warn) } upResponse = res return nil }); err != nil { // We return OK status, so browser can render nice result. w.WriteHeader(http.StatusOK) // NOTE: Pass-through error might be not always safe, sanitize on production. b, _ := json.Marshal(response{Error: err}) _, _ = fmt.Fprintln(w, string(b)) return } resp := response{} switch r := upResponse.(type) { case model.Vector: for _, s := range r { resp.Instances = append(resp.Instances, string(s.Metric["instance"])) } } w.WriteHeader(http.StatusOK) b, _ := json.Marshal(resp) _, _ = fmt.Fprintln(w, string(b)) } } func getExemplarFn(ctx context.Context) prometheus.Labels { if spanCtx := tracing.GetSpan(ctx); spanCtx.Context().IsSampled() { return prometheus.Labels{"traceID": spanCtx.Context().TraceID()} } return nil } func instrumentHandlerFunc(tracer *tracing.Tracer, _ prometheus.Registerer, handlerName string, handler http.Handler) (string, http.HandlerFunc) { // Wrap with tracing. This will be visited as a first middleware. base := tracinghttp.NewMiddleware(tracer).WrapHandler(handlerName, http.HandlerFunc(func(writer http.ResponseWriter, r *http.Request) { handler.ServeHTTP(writer, r) })) return handlerName, base.ServeHTTP } func instrumentRoundTripper(_ prometheus.Registerer, clientName string, rt http.RoundTripper) http.RoundTripper { // Wrap with tracing. This will be visited as a first middleware. return tracinghttp.NewTripperware().WrapRoundTipper(clientName, rt) } client_golang-1.21.1/tutorials/whatsup/reference/000077500000000000000000000000001476160432400220675ustar00rootroot00000000000000client_golang-1.21.1/tutorials/whatsup/reference/main.go000066400000000000000000000235151476160432400233500ustar00rootroot00000000000000// Copyright 2023 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "context" "encoding/json" "flag" "fmt" "log" "net/http" httppprof "net/http/pprof" "os" "syscall" "time" "github.com/bwplotka/tracing-go/tracing" "github.com/bwplotka/tracing-go/tracing/exporters/otlp" tracinghttp "github.com/bwplotka/tracing-go/tracing/http" "github.com/efficientgo/core/errcapture" "github.com/efficientgo/core/errors" "github.com/oklog/run" "github.com/prometheus/common/model" "github.com/prometheus/client_golang/api" v1 "github.com/prometheus/client_golang/api/prometheus/v1" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/tutorials/whatsup/internal" ) func main() { opts, err := internal.ParseOptions(os.Args) if err != nil { log.Fatalf("Error: %v", err) } if err := runMain(opts); err != nil { // Use %+v for github.com/efficientgo/core/errors error to print with stack. log.Fatalf("Error: %+v", errors.Wrapf(err, "%s", flag.Arg(0))) } } func runMain(opts internal.Config) (err error) { // Create tracer, so the application can be instrumented with traces. var exporter tracing.ExporterBuilder switch opts.TraceEndpoint { case "stdout": exporter = tracing.NewWriterExporter(os.Stdout) default: exporter = otlp.Exporter(opts.TraceEndpoint, otlp.WithInsecure()) } tracer, closeFn, err := tracing.NewTracer( exporter, tracing.WithSampler(tracing.TraceIDRatioBasedSampler(opts.TraceSamplingRatio)), tracing.WithServiceName("client_golang-tutorial:whatsup"), ) if err != nil { return err } defer errcapture.Do(&err, closeFn, "close tracers") // Create registry for Prometheus metrics. reg := prometheus.NewRegistry() reg.MustRegister( collectors.NewGoCollector(), // Metrics from Go runtime. collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), // Metrics about the current UNIX process. ) handled := promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "whatsup_queries_handled_total", Help: "Number of queries handed.", }) lastNumElems := promauto.With(reg).NewGauge(prometheus.GaugeOpts{ Name: "whatsup_last_response_elements", Help: "Number of elements in response for the last call.", }) _ = promauto.With(reg).NewGaugeFunc(prometheus.GaugeOpts{ Name: "build_info", Help: "Build information.", ConstLabels: map[string]string{ "version": "vYOLO", "language": "Go 1.20", "owner": "@me", }, }, func() float64 { return 1 }) handledDuration := promauto.With(reg).NewHistogram( prometheus.HistogramOpts{ Name: "whatsup_queries_duration_seconds", Help: "Tracks the latencies for calls.", Buckets: []float64{0.1, 0.3, 0.6, 1, 3, 6, 9, 20}, }, ) m := http.NewServeMux() // Create HTTP handler for Prometheus metrics. m.Handle("/metrics", promhttp.HandlerFor( reg, promhttp.HandlerOpts{ // Opt into OpenMetrics e.g. to support exemplars. EnableOpenMetrics: true, }, )) promClient, err := api.NewClient(api.Config{ Client: &http.Client{Transport: instrumentRoundTripper(reg, "prometheus", http.DefaultTransport)}, Address: opts.PrometheusAddr, }) if err != nil { return err } apiClient := v1.NewAPI(promClient) // Create HTTP handler for our whatsup implementation. m.HandleFunc(instrumentHandlerFunc(tracer, reg, "/whatsup", whatsUpHandler( apiClient, handled, lastNumElems, handledDuration, ))) // Debug profiling endpoints. m.HandleFunc("/debug/pprof/", httppprof.Index) m.HandleFunc("/debug/pprof/cmdline", httppprof.Cmdline) m.HandleFunc("/debug/pprof/profile", httppprof.Profile) m.HandleFunc("/debug/pprof/symbol", httppprof.Symbol) srv := http.Server{Addr: fmt.Sprintf(":%v", internal.WhatsupPort), Handler: m} g := &run.Group{} g.Add(func() error { log.Println("Starting HTTP server", "addr", internal.WhatsupPort) if err := srv.ListenAndServe(); err != nil { return errors.Wrap(err, "starting web server") } return nil }, func(error) { if err := srv.Close(); err != nil { log.Println("Error: Failed to stop web server", "err", err) } }) g.Add(run.SignalHandler(context.Background(), syscall.SIGINT, syscall.SIGTERM)) return g.Run() } type response struct { Error error `json:",omitempty"` Instances []string } // whatsUpHandler returns all services that currently monitored by Prometheus. // It uses prometheus client_golang client code to request PromQL query against given Prometheus server // to return answer. func whatsUpHandler( apiClient v1.API, handled prometheus.Counter, lastNumElems prometheus.Gauge, handledDuration prometheus.Histogram, ) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { start := time.Now() ctx := r.Context() w.Header().Set("Content-Type", "application/json") var upResponse model.Value if err := tracing.DoInSpan(ctx, "query Prometheus", func(ctx context.Context) error { res, warn, err := apiClient.Query(ctx, "up", time.Now()) if err != nil { return err } if len(warn) > 0 { return errors.Newf("got warnings from Prometheus %v", warn) } upResponse = res return nil }); err != nil { // We return OK status, so browser can render nice result. w.WriteHeader(http.StatusOK) // NOTE: Pass-through error might be not always safe, sanitize on production. b, _ := json.Marshal(response{Error: err}) _, _ = fmt.Fprintln(w, string(b)) return } resp := response{} switch r := upResponse.(type) { case model.Vector: for _, s := range r { resp.Instances = append(resp.Instances, string(s.Metric["instance"])) } } w.WriteHeader(http.StatusOK) b, _ := json.Marshal(resp) _, _ = fmt.Fprintln(w, string(b)) lastNumElems.Set(float64(len(resp.Instances))) handled.(prometheus.ExemplarAdder). AddWithExemplar(1, getExemplarFn(ctx)) handledDuration.(prometheus.ExemplarObserver). ObserveWithExemplar(time.Since(start).Seconds(), getExemplarFn(ctx)) } } func getExemplarFn(ctx context.Context) prometheus.Labels { if spanCtx := tracing.GetSpan(ctx); spanCtx.Context().IsSampled() { return prometheus.Labels{"traceID": spanCtx.Context().TraceID()} } return nil } func instrumentHandlerFunc(tracer *tracing.Tracer, reg prometheus.Registerer, handlerName string, handler http.Handler) (string, http.HandlerFunc) { reg = prometheus.WrapRegistererWith(prometheus.Labels{"handler": handlerName}, reg) requestDuration := promauto.With(reg).NewHistogramVec( prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "Tracks the latencies for HTTP requests.", Buckets: []float64{0.1, 0.3, 0.6, 1, 3, 6, 9, 20}, }, []string{"method", "code"}, ) requestSize := promauto.With(reg).NewSummaryVec( prometheus.SummaryOpts{ Name: "http_request_size_bytes", Help: "Tracks the size of HTTP requests.", }, []string{"method", "code"}, ) requestsTotal := promauto.With(reg).NewCounterVec( prometheus.CounterOpts{ Name: "http_requests_total", Help: "Tracks the number of HTTP requests.", }, []string{"method", "code"}, ) responseSize := promauto.With(reg).NewSummaryVec( prometheus.SummaryOpts{ Name: "http_response_size_bytes", Help: "Tracks the size of HTTP responses.", }, []string{"method", "code"}, ) base := promhttp.InstrumentHandlerRequestSize( requestSize, promhttp.InstrumentHandlerCounter( requestsTotal, promhttp.InstrumentHandlerResponseSize( responseSize, promhttp.InstrumentHandlerDuration( requestDuration, http.HandlerFunc(func(writer http.ResponseWriter, r *http.Request) { handler.ServeHTTP(writer, r) }), promhttp.WithExemplarFromContext(getExemplarFn), ), ), promhttp.WithExemplarFromContext(getExemplarFn), ), ) // Wrap with tracing. This will be visited as a first middleware. base = tracinghttp.NewMiddleware(tracer).WrapHandler(handlerName, base) return handlerName, base.ServeHTTP } func instrumentRoundTripper(reg prometheus.Registerer, clientName string, rt http.RoundTripper) http.RoundTripper { reg = prometheus.WrapRegistererWith(prometheus.Labels{"client": clientName}, reg) requestDuration := promauto.With(reg).NewHistogramVec( prometheus.HistogramOpts{ Name: "http_client_request_duration_seconds", Help: "Tracks the latencies for HTTP requests.", Buckets: []float64{0.1, 0.3, 0.6, 1, 3, 6, 9, 20}, }, []string{"method", "code"}, ) requestsTotal := promauto.With(reg).NewCounterVec( prometheus.CounterOpts{ Name: "http_client_requests_total", Help: "Tracks the number of HTTP requests.", }, []string{"method", "code"}, ) responseInflight := promauto.With(reg).NewGauge( prometheus.GaugeOpts{ Name: "http_client_requests_inflight", Help: "Tracks the number of client requests currently in progress.", }, ) var base http.RoundTripper base = promhttp.InstrumentRoundTripperCounter( requestsTotal, promhttp.InstrumentRoundTripperInFlight( responseInflight, promhttp.InstrumentRoundTripperDuration(requestDuration, rt, promhttp.WithExemplarFromContext(getExemplarFn)), ), promhttp.WithExemplarFromContext(getExemplarFn), ) // Wrap with tracing. This will be visited as a first middleware. return tracinghttp.NewTripperware().WrapRoundTipper(clientName, base) } client_golang-1.21.1/update-go-version.bash000066400000000000000000000014411476160432400206170ustar00rootroot00000000000000#!/bin/env bash set -e get_latest_versions() { curl -s https://go.dev/VERSION?m=text | sed -E -n 's/go([0-9]+\.[0-9]+|\.[0-9]+).*/\1/p' } current_version=$(cat supported_go_versions.txt | head -n 1) latest_version=$(get_latest_versions) # Check for new version of Go, and generate go collector test files # Add new Go version to supported_go_versions.txt, and remove the oldest version if [[ ! $current_version =~ $latest_version ]]; then echo "New Go version available: $latest_version" echo "Updating supported_go_versions.txt and generating Go Collector test files" sed -i "1i $latest_version" supported_go_versions.txt sed -i '$d' supported_go_versions.txt make generate-go-collector-test-files else echo "No new Go version detected. Current Go version is: $current_version" fi