From c51f2dd12221058aae8607aff2bdc926b5898b7c Mon Sep 17 00:00:00 2001 From: Andrii Bodnar <29282228+andrii-bodnar@users.noreply.github.com> Date: Wed, 25 Jan 2023 11:45:04 +0200 Subject: [PATCH] docs: new documentation site (#1365) --- .eslintignore | 2 +- .github/workflows/deploy-main-docs.yml | 32 - .github/workflows/docs-suite.yml | 36 + .github/workflows/release-docs.yml | 38 + .gitignore | 1 - CODE_OF_CONDUCT.md | 128 + CONTRIBUTING.md | 82 +- LICENSE | 2 +- README.md | 13 +- docs/CNAME | 1 - docs/Makefile | 23 - docs/Pipfile | 16 - docs/Pipfile.lock | 320 - docs/_ext/edit_on_github.py | 28 - docs/_ext/linguidocs.py | 109 - docs/_ext/youtube.py | 104 - docs/_static/pitch.js | 31 - docs/_static/pitch_keys.js | 53 - docs/_static/pitch_keys.png | Bin 365370 -> 0 bytes docs/_static/pitch_messages.js | 52 - docs/_static/pitch_messages.png | Bin 349644 -> 0 bytes docs/_templates/layout.html | 13 - docs/conf.py | 169 - docs/guides/dynamic-loading-catalogs.rst | 129 - docs/guides/excluding-build-files.rst | 32 - docs/guides/monorepo.rst | 26 - docs/guides/optimized-components.rst | 123 - docs/guides/plurals.rst | 112 - docs/guides/pseudolocalization.rst | 57 - docs/guides/testing.rst | 60 - docs/guides/typescript.rst | 106 - docs/index.rst | 152 - docs/misc/react-intl.rst | 290 - docs/misc/showroom.rst | 23 - docs/misc/talks-about-i18n.rst | 45 - docs/misc/tooling.rst | 11 - docs/ref/catalog-formats.rst | 138 - docs/ref/cli.rst | 170 - docs/ref/conf.rst | 533 - docs/ref/core.rst | 404 - docs/ref/loader.rst | 39 - docs/ref/locale-detector.rst | 74 - docs/ref/macro.rst | 840 -- docs/ref/message-format.rst | 54 - docs/ref/react.rst | 267 - docs/ref/snowpack-plugin.rst | 61 - docs/releases/migration-1.rst | 275 - docs/releases/migration-2.rst | 179 - docs/releases/migration-3.rst | 289 - docs/tools/crowdin.rst | 194 - docs/tools/introduction.rst | 114 - docs/tools/translation-io.rst | 252 - docs/tutorials/cli.rst | 202 - docs/tutorials/javascript.rst | 130 - docs/tutorials/react-native.rst | 270 - docs/tutorials/react-patterns.rst | 261 - docs/tutorials/react.rst | 819 -- docs/tutorials/setup-cra.rst | 100 - docs/tutorials/setup-react.rst | 128 - docs/vercel-build.sh | 3 - lerna.json | 4 +- package.json | 2 +- tsconfig.json | 3 +- website/.ecrc | 10 + website/.editorconfig | 18 + website/.eslintrc | 41 + website/.gitattributes | 13 + website/.gitignore | 17 + website/.prettierignore | 6 + website/.prettierrc.json | 8 + website/.remarkrc.mjs | 56 + website/babel.config.js | 3 + .../docs/guides/dynamic-loading-catalogs.md | 114 + website/docs/guides/excluding-build-files.md | 28 + website/docs/guides/monorepo.md | 24 + website/docs/guides/optimized-components.md | 95 + website/docs/guides/plurals.md | 94 + website/docs/guides/pseudolocalization.md | 41 + website/docs/guides/testing.md | 52 + website/docs/guides/typescript.md | 99 + website/docs/introduction.md | 105 + website/docs/misc/community.md | 43 + website/docs/misc/react-intl.md | 242 + website/docs/misc/resources.md | 11 + website/docs/misc/showroom.md | 36 + website/docs/misc/tooling.md | 11 + website/docs/ref/catalog-formats.md | 104 + website/docs/ref/cli.md | 166 + website/docs/ref/conf.md | 451 + website/docs/ref/core.md | 371 + website/docs/ref/loader.md | 29 + website/docs/ref/locale-detector.md | 66 + website/docs/ref/macro.md | 788 ++ website/docs/ref/message-format.md | 59 + website/docs/ref/react.md | 210 + website/docs/ref/snowpack-plugin.md | 56 + website/docs/releases/migration-3.md | 240 + website/docs/tools/crowdin.md | 150 + website/docs/tools/introduction.md | 68 + website/docs/tools/translation-io.md | 158 + website/docs/tutorials/cli.md | 167 + website/docs/tutorials/javascript.md | 107 + website/docs/tutorials/react-native.md | 222 + website/docs/tutorials/react-patterns.md | 230 + website/docs/tutorials/react.md | 719 ++ website/docs/tutorials/setup-cra.md | 75 + website/docs/tutorials/setup-react.md | 102 + website/docusaurus.config.js | 131 + website/linkcheck-ignore.txt | 2 + website/package.json | 71 + website/sidebars.ts | 175 + website/src/components/Button.tsx | 21 + website/src/components/Features.module.scss | 101 + website/src/components/Features.tsx | 197 + website/src/components/Header.module.scss | 73 + website/src/components/Header.tsx | 47 + website/src/components/Users.module.scss | 46 + website/src/components/Users.tsx | 84 + website/src/css/custom.scss | 171 + website/src/definitions.d.ts | 2 + website/src/pages/index.tsx | 22 + website/src/theme/Footer/index.js | 10 + website/src/utils/useScript.ts | 50 + website/static/.nojekyll | 0 .../img/docs}/Crowdin__js-lingui-cli.png | Bin .../img/docs}/Crowdin__js-lingui-vcs.png | Bin .../img/docs}/dynamic-loading-catalogs-1.png | Bin .../img/docs}/dynamic-loading-catalogs-2.png | Bin .../static/img/docs}/rn-component-nesting.png | Bin .../img/docs}/translation-lingui-logo.png | Bin .../docs}/translation-lingui-plural-forms.png | Bin .../img/docs}/with-collaboration-tool.png | Bin .../img/docs}/without-collaboration-tool.png | Bin website/static/img/favicon.ico | Bin 0 -> 15406 bytes website/static/img/features/all-platforms.svg | 6 + .../img/features/clean-and-readable.png | Bin 0 -> 29043 bytes website/static/img/features/fledged.svg | 37 + website/static/img/features/free.svg | 6 + .../static/img/features/pattern-left-big.svg | 28 + .../static/img/features/pattern-right-big.svg | 24 + website/static/img/features/rich-text.svg | 12 + website/static/img/features/time.svg | 26 + website/static/img/features/tooling.png | Bin 0 -> 8118 bytes website/static/img/features/universal.png | Bin 0 -> 25559 bytes website/static/img/features/universal.svg | 9 + website/static/img/features/verified.svg | 5 + website/static/img/header/left-bg.svg | 29 + website/static/img/header/right-bg.svg | 29 + website/static/img/lingui-logo.svg | 11 + website/static/img/logo-small.svg | 11 + website/static/img/users/ansible.png | Bin 0 -> 20327 bytes website/static/img/users/fider.png | Bin 0 -> 17801 bytes website/static/img/users/flood.svg | 7 + website/static/img/users/lenster.svg | 8 + website/static/img/users/linkerd.png | Bin 0 -> 11921 bytes website/static/img/users/remirror.png | Bin 0 -> 3529 bytes website/static/img/users/uniswap.png | Bin 0 -> 13016 bytes website/static/img/users/zipkin.png | Bin 0 -> 8467 bytes website/tools/algolia/config.json | 24 + website/tsconfig.json | 7 + website/yarn.lock | 10712 ++++++++++++++++ 161 files changed, 18159 insertions(+), 7964 deletions(-) delete mode 100644 .github/workflows/deploy-main-docs.yml create mode 100644 .github/workflows/docs-suite.yml create mode 100644 .github/workflows/release-docs.yml create mode 100644 CODE_OF_CONDUCT.md delete mode 100644 docs/CNAME delete mode 100644 docs/Makefile delete mode 100644 docs/Pipfile delete mode 100644 docs/Pipfile.lock delete mode 100644 docs/_ext/edit_on_github.py delete mode 100644 docs/_ext/linguidocs.py delete mode 100644 docs/_ext/youtube.py delete mode 100644 docs/_static/pitch.js delete mode 100644 docs/_static/pitch_keys.js delete mode 100644 docs/_static/pitch_keys.png delete mode 100644 docs/_static/pitch_messages.js delete mode 100644 docs/_static/pitch_messages.png delete mode 100644 docs/_templates/layout.html delete mode 100644 docs/conf.py delete mode 100644 docs/guides/dynamic-loading-catalogs.rst delete mode 100644 docs/guides/excluding-build-files.rst delete mode 100644 docs/guides/monorepo.rst delete mode 100644 docs/guides/optimized-components.rst delete mode 100644 docs/guides/plurals.rst delete mode 100644 docs/guides/pseudolocalization.rst delete mode 100644 docs/guides/testing.rst delete mode 100644 docs/guides/typescript.rst delete mode 100644 docs/index.rst delete mode 100644 docs/misc/react-intl.rst delete mode 100644 docs/misc/showroom.rst delete mode 100644 docs/misc/talks-about-i18n.rst delete mode 100644 docs/misc/tooling.rst delete mode 100644 docs/ref/catalog-formats.rst delete mode 100644 docs/ref/cli.rst delete mode 100644 docs/ref/conf.rst delete mode 100644 docs/ref/core.rst delete mode 100644 docs/ref/loader.rst delete mode 100644 docs/ref/locale-detector.rst delete mode 100644 docs/ref/macro.rst delete mode 100644 docs/ref/message-format.rst delete mode 100644 docs/ref/react.rst delete mode 100644 docs/ref/snowpack-plugin.rst delete mode 100644 docs/releases/migration-1.rst delete mode 100644 docs/releases/migration-2.rst delete mode 100644 docs/releases/migration-3.rst delete mode 100644 docs/tools/crowdin.rst delete mode 100644 docs/tools/introduction.rst delete mode 100644 docs/tools/translation-io.rst delete mode 100644 docs/tutorials/cli.rst delete mode 100644 docs/tutorials/javascript.rst delete mode 100644 docs/tutorials/react-native.rst delete mode 100644 docs/tutorials/react-patterns.rst delete mode 100644 docs/tutorials/react.rst delete mode 100644 docs/tutorials/setup-cra.rst delete mode 100644 docs/tutorials/setup-react.rst delete mode 100755 docs/vercel-build.sh create mode 100644 website/.ecrc create mode 100644 website/.editorconfig create mode 100644 website/.eslintrc create mode 100644 website/.gitattributes create mode 100644 website/.gitignore create mode 100644 website/.prettierignore create mode 100644 website/.prettierrc.json create mode 100644 website/.remarkrc.mjs create mode 100644 website/babel.config.js create mode 100644 website/docs/guides/dynamic-loading-catalogs.md create mode 100644 website/docs/guides/excluding-build-files.md create mode 100644 website/docs/guides/monorepo.md create mode 100644 website/docs/guides/optimized-components.md create mode 100644 website/docs/guides/plurals.md create mode 100644 website/docs/guides/pseudolocalization.md create mode 100644 website/docs/guides/testing.md create mode 100644 website/docs/guides/typescript.md create mode 100644 website/docs/introduction.md create mode 100644 website/docs/misc/community.md create mode 100644 website/docs/misc/react-intl.md create mode 100644 website/docs/misc/resources.md create mode 100644 website/docs/misc/showroom.md create mode 100644 website/docs/misc/tooling.md create mode 100644 website/docs/ref/catalog-formats.md create mode 100644 website/docs/ref/cli.md create mode 100644 website/docs/ref/conf.md create mode 100644 website/docs/ref/core.md create mode 100644 website/docs/ref/loader.md create mode 100644 website/docs/ref/locale-detector.md create mode 100644 website/docs/ref/macro.md create mode 100644 website/docs/ref/message-format.md create mode 100644 website/docs/ref/react.md create mode 100644 website/docs/ref/snowpack-plugin.md create mode 100644 website/docs/releases/migration-3.md create mode 100644 website/docs/tools/crowdin.md create mode 100644 website/docs/tools/introduction.md create mode 100644 website/docs/tools/translation-io.md create mode 100644 website/docs/tutorials/cli.md create mode 100644 website/docs/tutorials/javascript.md create mode 100644 website/docs/tutorials/react-native.md create mode 100644 website/docs/tutorials/react-patterns.md create mode 100644 website/docs/tutorials/react.md create mode 100644 website/docs/tutorials/setup-cra.md create mode 100644 website/docs/tutorials/setup-react.md create mode 100644 website/docusaurus.config.js create mode 100644 website/linkcheck-ignore.txt create mode 100644 website/package.json create mode 100644 website/sidebars.ts create mode 100644 website/src/components/Button.tsx create mode 100644 website/src/components/Features.module.scss create mode 100644 website/src/components/Features.tsx create mode 100644 website/src/components/Header.module.scss create mode 100644 website/src/components/Header.tsx create mode 100644 website/src/components/Users.module.scss create mode 100644 website/src/components/Users.tsx create mode 100644 website/src/css/custom.scss create mode 100644 website/src/definitions.d.ts create mode 100644 website/src/pages/index.tsx create mode 100644 website/src/theme/Footer/index.js create mode 100644 website/src/utils/useScript.ts create mode 100644 website/static/.nojekyll rename {docs/tools => website/static/img/docs}/Crowdin__js-lingui-cli.png (100%) rename {docs/tools => website/static/img/docs}/Crowdin__js-lingui-vcs.png (100%) rename {docs/guides => website/static/img/docs}/dynamic-loading-catalogs-1.png (100%) rename {docs/guides => website/static/img/docs}/dynamic-loading-catalogs-2.png (100%) rename {docs/tutorials => website/static/img/docs}/rn-component-nesting.png (100%) rename {docs/tools => website/static/img/docs}/translation-lingui-logo.png (100%) rename {docs/tools => website/static/img/docs}/translation-lingui-plural-forms.png (100%) rename {docs/tools => website/static/img/docs}/with-collaboration-tool.png (100%) rename {docs/tools => website/static/img/docs}/without-collaboration-tool.png (100%) create mode 100644 website/static/img/favicon.ico create mode 100644 website/static/img/features/all-platforms.svg create mode 100644 website/static/img/features/clean-and-readable.png create mode 100644 website/static/img/features/fledged.svg create mode 100644 website/static/img/features/free.svg create mode 100644 website/static/img/features/pattern-left-big.svg create mode 100644 website/static/img/features/pattern-right-big.svg create mode 100644 website/static/img/features/rich-text.svg create mode 100644 website/static/img/features/time.svg create mode 100644 website/static/img/features/tooling.png create mode 100644 website/static/img/features/universal.png create mode 100644 website/static/img/features/universal.svg create mode 100644 website/static/img/features/verified.svg create mode 100644 website/static/img/header/left-bg.svg create mode 100644 website/static/img/header/right-bg.svg create mode 100644 website/static/img/lingui-logo.svg create mode 100644 website/static/img/logo-small.svg create mode 100644 website/static/img/users/ansible.png create mode 100644 website/static/img/users/fider.png create mode 100644 website/static/img/users/flood.svg create mode 100644 website/static/img/users/lenster.svg create mode 100644 website/static/img/users/linkerd.png create mode 100644 website/static/img/users/remirror.png create mode 100644 website/static/img/users/uniswap.png create mode 100644 website/static/img/users/zipkin.png create mode 100644 website/tools/algolia/config.json create mode 100644 website/tsconfig.json create mode 100644 website/yarn.lock diff --git a/.eslintignore b/.eslintignore index 3e2702ce5..a254f0f8c 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,6 +2,6 @@ **/node_modules/* **/fixtures/* **/locale/* -docs/* +website/* README.md **/npm/* \ No newline at end of file diff --git a/.github/workflows/deploy-main-docs.yml b/.github/workflows/deploy-main-docs.yml deleted file mode 100644 index 794070a5e..000000000 --- a/.github/workflows/deploy-main-docs.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: deploy-main-docs - -on: - push: - branches: - - main - paths: - - docs/** - -jobs: - deploy-docs: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: Setup node - uses: actions/setup-node@v3 - with: - node-version: 16 - - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: '3.9' - cache: 'pip' - - - name: Deploy documentation - run: | - cd docs/ - ./vercel-build.sh - npx vercel --public --yes --prod --token ${{secrets.NOW_TOKEN}} --name lingui-docs _build/html diff --git a/.github/workflows/docs-suite.yml b/.github/workflows/docs-suite.yml new file mode 100644 index 000000000..f2d53d6da --- /dev/null +++ b/.github/workflows/docs-suite.yml @@ -0,0 +1,36 @@ +name: docs-suite + +on: + pull_request: + branches: + - '*' + paths: + - website/** + +jobs: + validate: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Setup node + uses: actions/setup-node@v3 + with: + node-version: 16 + + - name: Install dependencies + working-directory: website + run: yarn install --frozen-lockfile --pure-lockfile + + - name: Build + working-directory: website + run: yarn build + + - name: Lint + working-directory: website + run: yarn lint + + - name: Check Formatting + working-directory: website + run: yarn checkFormat diff --git a/.github/workflows/release-docs.yml b/.github/workflows/release-docs.yml new file mode 100644 index 000000000..d6e465756 --- /dev/null +++ b/.github/workflows/release-docs.yml @@ -0,0 +1,38 @@ +name: release-docs + +on: + workflow_dispatch: + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup node + uses: actions/setup-node@v3 + with: + node-version: 16 + + - name: Install dependencies + working-directory: website + run: yarn install --frozen-lockfile --pure-lockfile + + - name: Build + working-directory: website + run: yarn build + + - name: Deploy documentation + working-directory: website + run: | + npx vercel --public --yes --prod --token ${{ secrets.NOW_TOKEN }} --name lingui-docs build + + - name: Update Algolia index + uses: darrenjennings/algolia-docsearch-action@v0.2.0 + with: + algolia_application_id: ${{ vars.ALGOLIA_APP_ID }} + algolia_api_key: ${{ secrets.ALGOLIA_WRITE_API_KEY }} + file: 'website/tools/algolia/config.json' diff --git a/.gitignore b/.gitignore index f3d1a0073..f07902b7e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ build/packages/ .yalc/ yalc.lock packages/**/build -docs/_build/ npm-debug.log yarn-error.log diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..38be88cf3 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +https://github.com/lingui/js-lingui/discussions. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bfe937a7e..0ccce10f9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,27 +1,48 @@ +# Contributing + +:tada: First off, thanks for taking the time to contribute! :tada: + +The following is a set of guidelines for contributing to Lingui. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. + +This project and everyone participating in it are governed by the [Code of Conduct](/CODE_OF_CONDUCT.md). We expect that all community members adhere to the guidelines within. + **Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) ## Contributing to the docs -Documentation uses Sphinx and reStructuredText. Source inside the -[docs](https://github.com/lingui/js-lingui/tree/main/docs) directory. +The documentation is based on [Docusaurus](https://docusaurus.io/) framework. Source inside the [website](https://github.com/lingui/js-lingui/tree/main/website) directory. + +- Go to the `website` directory: + + ```sh + cd website + ``` + +- Install dependencies: + + ```sh + yarn install + ``` -1. Go to the `docs` directory +- To build the docs, watch for changes and preview documentation locally at [http://localhost:3000/](http://localhost:3000/): + + ```sh + yarn start + ``` -2. Run `pipenv install` to setup Python environemnt (requires Python 3.6). - If you encounter `ValueError('unknown locale: %s' % localename)`, - run `export LC_ALL=en_US.UTF-8 && export LANG=en_US.UTF-8` and try again. +- It's also possible to run `yarn build` for single build. Incremental builds are much faster than the first one as only changed files are built. -3. Run `pipenv run make livehtml` to build the docs, watch for changes and preview - documentation locally at [http://127.0.0.1:8000](http://127.0.0.1:8000). +- Please lint and validate the documentation before submitting any changes: -4. It's also possible to run `pipenv run make html` for single build. Incremental builds - are much faster than the first one as only changed files are built. + ```sh + yarn lint + yarn checkFormat + ``` ## Contributing the code -This project uses [yarn][yarninstall] package manager. Please follow -[official][yarninstall] docs to install it. +This project uses [yarn][yarninstall] package manager. Please follow [official][yarninstall] docs to install it. ### Setup local environment @@ -32,10 +53,7 @@ This project uses [yarn][yarninstall] package manager. Please follow cd js-lingui ``` -2. Install development packages. This project uses - [yarn workspaces](https://yarnpkg.com/lang/en/docs/workspaces/) instead of Lerna, - so running `yarn` installs all development packages and also dependencies for all - workspaces (inside `packages/*`). +2. Install development packages. This project uses [yarn workspaces](https://yarnpkg.com/lang/en/docs/workspaces/) instead of Lerna, so running `yarn` installs all development packages and also dependencies for all workspaces (inside `packages/*`). ```sh yarn @@ -51,22 +69,20 @@ This project uses [yarn][yarninstall] package manager. Please follow yarn test ``` - NOTE: if you are using an IDE to run test make sure to use the right Jest config. - For unit tests use `-c scripts/jest/config.unit.js`. Integration tests use - build packages (created using `yarn release:build`) and config `-c scripts/jest/config.integration.js`. - See [package.json](./package.json) for more info. - - If you run tests manually instead of using `yarn watch` or `yarn test` commands and your tests - fail due to missing locale data (typically you'll get wrong number and currency formating) - make sure you have `NODE_ICU_DATA` variable set: `NODE_ICU_DATA=node_modules/full-icu`. + > **Note** + > If you are using an IDE to run test make sure to use the right Jest config. + > For unit tests use `-c scripts/jest/config.unit.js`. Integration tests use + > build packages (created using `yarn release:build`) and config `-c scripts/jest/config.integration.js`. + > See [package.json](./package.json) for more info. + > If you run tests manually instead of using `yarn watch` or `yarn test` commands and your tests + > fail due to missing locale data (typically you'll get wrong number and currency formating) + > make sure you have `NODE_ICU_DATA` variable set: `NODE_ICU_DATA=node_modules/full-icu`. ### Using development version in your project -After you successfully fix a bug or add a new feature, you most probably want -to test it in your project as soon as possible. +After you successfully fix a bug or add a new feature, you most probably want to test it in your project as soon as possible. -`jsLingui` uses [verdaccio](https://verdaccio.org/), a lightweight local NPM registry, to install -local build of packages in examples. You can do the same in your project: +`jsLingui` uses [verdaccio](https://verdaccio.org/), a lightweight local NPM registry, to install local build of packages in examples. You can do the same in your project: 1. Run `verdaccio` locally in docker (follow [verdaccio guide](https://verdaccio.org/docs/en/what-is-verdaccio.html) if you don't want to run it in Docker): @@ -106,18 +122,16 @@ local build of packages in examples. You can do the same in your project: ### Finalize changes -Please make sure that all tests pass and linter doesn't report any error before -submitting a PR (Don't worry though! If you can't figure out the problem, create a PR -anyway and we'll help you). +Please make sure that all tests pass and linter doesn't report any error before submitting a PR (Don't worry though! If you can't figure out the problem, create a PR anyway, and we'll help you). - `yarn lint:all` - Linting & Type testing - `yarn test` - Quick test suite (sufficient) - `yarn release:test` - Full test suite (recommended) -`yarn release:test` builds all packages, simulates creating packages for NPM, runs unit -tests and finally runs integration tests using production build. +`yarn release:test` builds all packages, simulates creating packages for NPM, runs unit tests and finally runs integration tests using production build. -**Note**: Don't commit `scripts/build/results.json` created by `yarn release:test`. +> **Note** +> Don't commit `scripts/build/results.json` created by `yarn release:test`. Now you can create PR and let CI service do their work! diff --git a/LICENSE b/LICENSE index 868be5858..c6f6622e2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2017 Tomáš Ehrlich +Copyright (c) 2017-2022 Tomáš Ehrlich, (c) 2022-2023 Crowdin. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 666aa5f04..3581d2e54 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ [![Sponsors on Open Collective][Badge-ocsponsors]][ocsponsors-local] [![Join the community on Discord][Badge-Discord]][Discord] -[**Documentation**][Documentation] · [**Documentation 2.x**](https://js-lingui-git-stable-2x.lingui-js.vercel.app/) · [**Quickstart**](#quickstart) · [**Example**](#example) · [**Support**](#support) · [**Contribute**](#contribute) · [**Licence**](#licence) +[**Documentation**][Documentation] · [**Quickstart**](#quickstart) · [**Example**](#example) · [**Support**](#support) · [**Contribute**](#contribute) · [**License**](#license) > Internationalization is the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language. @@ -111,10 +111,9 @@ documentation to implement features and fixing bugs. - Do you use **Lingui** in production site? Let us know! - Have you seen any interesting talk or article about **i18n**? - [Share it](https://github.com/lingui/js-lingui/edit/main/docs/misc/talks-about-i18n.rst)! + [Share it](https://github.com/lingui/js-lingui/edit/main/website/docs/misc/resources.md)! - Have you found a bug or do you want to suggest a new feature? [Create an issue][Issues]! -- Do you want to improve the docs and write some code? - Read the [contributors guide][Contributing] and send a PR! +- Do you want to improve the docs and write some code? Read the [contributors guide][Contributing] and send a PR! ### Contributors @@ -147,7 +146,6 @@ Support this project by becoming a sponsor. Your logo will show up here with a l The project is licensed under the [MIT][License] license. -[ReactIntl]: https://github.com/yahoo/react-intl [Documentation]: https://lingui.js.org/ [TutorialReact]: https://lingui.js.org/tutorials/react.html [TutorialReactNative]: https://lingui.js.org/tutorials/react-native.html @@ -159,8 +157,6 @@ The project is licensed under the [MIT][License] license. [Badge-MainSuite-GithubCI]: https://github.com/lingui/js-lingui/workflows/main-suite/badge.svg [Badge-ReleaseWorkflowTesting-GithubCI]: https://github.com/lingui/js-lingui/workflows/release-workflow-test/badge.svg -[Badge-CI]: https://img.shields.io/circleci/project/github/lingui/js-lingui/main.svg -[Badge-AppVeyor]: https://ci.appveyor.com/api/projects/status/0wjdm3qofrjo2c4n/branch/main?svg=true [Badge-Coverage]: https://img.shields.io/codecov/c/github/lingui/js-lingui/main.svg [Badge-PRWelcome]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square [Badge-ocbackers]: https://opencollective.com/js-lingui/backers/badge.svg @@ -171,14 +167,11 @@ The project is licensed under the [MIT][License] license. [Img-Backers]: https://opencollective.com/js-lingui/backers.svg?width=890 [Backers]: https://opencollective.com/js-lingui#backers -[CI]: https://circleci.com/gh/lingui/js-lingui/tree/main -[AppVeyor]: https://ci.appveyor.com/project/tricoder42/js-lingui/branch/main [Coverage]: https://codecov.io/gh/lingui/js-lingui [License]: https://github.com/lingui/js-lingui/blob/main/LICENSE [Contributing]: https://github.com/lingui/js-lingui/blob/main/CONTRIBUTING.md [Issues]: https://github.com/lingui/js-lingui/issues/new/choose [PRWelcome]: http://makeapullrequest.com -[Indiegogo]: https://igg.me/at/js-lingui/x/4367619 [ocbackers-local]: #backers [ocsponsors-local]: #sponsors [BundleReact]: https://bundlephobia.com/result?p=@lingui/react diff --git a/docs/CNAME b/docs/CNAME deleted file mode 100644 index 873bf2a35..000000000 --- a/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -lingui.js.org diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 1024afc61..000000000 --- a/docs/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = python -m sphinx -SPHINXPROJ = LinguiJS -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -livehtml: - sphinx-autobuild -b html $(SPHINXOPTS) "$(SOURCEDIR)" "$(BUILDDIR)/html" - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/Pipfile b/docs/Pipfile deleted file mode 100644 index e64acda48..000000000 --- a/docs/Pipfile +++ /dev/null @@ -1,16 +0,0 @@ -[[source]] -name = "pypi" -url = "https://pypi.python.org/simple" -verify_ssl = true - -[dev-packages] - -[packages] -sphinx = "*" -sphinx-rtd-theme = "*" -jsx-lexer = "*" -sphinx-autobuild = "*" -sphinx-sitemap = "*" - -[requires] -python_version = "3.9" diff --git a/docs/Pipfile.lock b/docs/Pipfile.lock deleted file mode 100644 index c824fc951..000000000 --- a/docs/Pipfile.lock +++ /dev/null @@ -1,320 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "c60bb627831a8373ea6941482550011bf4d98ea4878f47af7ffae1615e318cab" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.9" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.python.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "alabaster": { - "hashes": [ - "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359", - "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02" - ], - "version": "==0.7.12" - }, - "babel": { - "hashes": [ - "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe", - "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6" - ], - "markers": "python_version >= '3.6'", - "version": "==2.11.0" - }, - "certifi": { - "hashes": [ - "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", - "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" - ], - "markers": "python_version >= '3.6'", - "version": "==2022.12.7" - }, - "charset-normalizer": { - "hashes": [ - "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", - "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f" - ], - "markers": "python_version >= '3.6'", - "version": "==2.1.1" - }, - "colorama": { - "hashes": [ - "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", - "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", - "version": "==0.4.6" - }, - "docutils": { - "hashes": [ - "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125", - "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.17.1" - }, - "idna": { - "hashes": [ - "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", - "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" - ], - "markers": "python_version >= '3.5'", - "version": "==3.4" - }, - "imagesize": { - "hashes": [ - "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", - "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.4.1" - }, - "importlib-metadata": { - "hashes": [ - "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad", - "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d" - ], - "markers": "python_version < '3.10'", - "version": "==6.0.0" - }, - "jinja2": { - "hashes": [ - "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", - "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.2" - }, - "jsx-lexer": { - "hashes": [ - "sha256:bff51c2a2faa2c682cbc9a0f360b8c65e4153eb1df06988e8dad34373d3f9995", - "sha256:ca22483ced80a92e45fa1855da7cf99309852c0637842a79a759e10ea57b904d" - ], - "index": "pypi", - "version": "==2.0.0" - }, - "livereload": { - "hashes": [ - "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869", - "sha256:ad4ac6f53b2d62bb6ce1a5e6e96f1f00976a32348afedcb4b6d68df2a1d346e4" - ], - "version": "==2.6.3" - }, - "markupsafe": { - "hashes": [ - "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003", - "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88", - "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5", - "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7", - "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a", - "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603", - "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1", - "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135", - "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247", - "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6", - "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601", - "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77", - "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02", - "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e", - "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63", - "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f", - "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980", - "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b", - "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812", - "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff", - "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96", - "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1", - "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925", - "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a", - "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6", - "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e", - "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f", - "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4", - "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f", - "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3", - "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c", - "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a", - "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417", - "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a", - "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a", - "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37", - "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452", - "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933", - "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a", - "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7" - ], - "markers": "python_version >= '3.7'", - "version": "==2.1.1" - }, - "packaging": { - "hashes": [ - "sha256:2198ec20bd4c017b8f9717e00f0c8714076fc2fd93816750ab48e2c41de2cfd3", - "sha256:957e2148ba0e1a3b282772e791ef1d8083648bc131c8ab0c1feba110ce1146c3" - ], - "markers": "python_version >= '3.7'", - "version": "==22.0" - }, - "pygments": { - "hashes": [ - "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297", - "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717" - ], - "markers": "python_version >= '3.6'", - "version": "==2.14.0" - }, - "pytz": { - "hashes": [ - "sha256:7ccfae7b4b2c067464a6733c6261673fdb8fd1be905460396b97a073e9fa683a", - "sha256:93007def75ae22f7cd991c84e02d434876818661f8df9ad5df9e950ff4e52cfd" - ], - "version": "==2022.7" - }, - "requests": { - "hashes": [ - "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", - "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" - ], - "markers": "python_version >= '3.7' and python_version < '4'", - "version": "==2.28.1" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, - "snowballstemmer": { - "hashes": [ - "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", - "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a" - ], - "version": "==2.2.0" - }, - "sphinx": { - "hashes": [ - "sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d", - "sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5" - ], - "index": "pypi", - "version": "==5.3.0" - }, - "sphinx-autobuild": { - "hashes": [ - "sha256:8fe8cbfdb75db04475232f05187c776f46f6e9e04cacf1e49ce81bdac649ccac", - "sha256:de1ca3b66e271d2b5b5140c35034c89e47f263f2cd5db302c9217065f7443f05" - ], - "index": "pypi", - "version": "==2021.3.14" - }, - "sphinx-rtd-theme": { - "hashes": [ - "sha256:31faa07d3e97c8955637fc3f1423a5ab2c44b74b8cc558a51498c202ce5cbda7", - "sha256:6146c845f1e1947b3c3dd4432c28998a1693ccc742b4f9ad7c63129f0757c103" - ], - "index": "pypi", - "version": "==1.1.1" - }, - "sphinx-sitemap": { - "hashes": [ - "sha256:3e19cff281974c00dfdc72d2d6ac71b737805dbd5666019997a4ac062a6406c0", - "sha256:94a1dab73789558e28e5ccfbc2a758194765707f9eeb06b59725a3bb244f323b" - ], - "index": "pypi", - "version": "==2.4.0" - }, - "sphinxcontrib-applehelp": { - "hashes": [ - "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a", - "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58" - ], - "markers": "python_version >= '3.5'", - "version": "==1.0.2" - }, - "sphinxcontrib-devhelp": { - "hashes": [ - "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e", - "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4" - ], - "markers": "python_version >= '3.5'", - "version": "==1.0.2" - }, - "sphinxcontrib-htmlhelp": { - "hashes": [ - "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07", - "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2" - ], - "markers": "python_version >= '3.6'", - "version": "==2.0.0" - }, - "sphinxcontrib-jsmath": { - "hashes": [ - "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", - "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8" - ], - "markers": "python_version >= '3.5'", - "version": "==1.0.1" - }, - "sphinxcontrib-qthelp": { - "hashes": [ - "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72", - "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6" - ], - "markers": "python_version >= '3.5'", - "version": "==1.0.3" - }, - "sphinxcontrib-serializinghtml": { - "hashes": [ - "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd", - "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952" - ], - "markers": "python_version >= '3.5'", - "version": "==1.1.5" - }, - "tornado": { - "hashes": [ - "sha256:1d54d13ab8414ed44de07efecb97d4ef7c39f7438cf5e976ccd356bebb1b5fca", - "sha256:20f638fd8cc85f3cbae3c732326e96addff0a15e22d80f049e00121651e82e72", - "sha256:5c87076709343557ef8032934ce5f637dbb552efa7b21d08e89ae7619ed0eb23", - "sha256:5f8c52d219d4995388119af7ccaa0bcec289535747620116a58d830e7c25d8a8", - "sha256:6fdfabffd8dfcb6cf887428849d30cf19a3ea34c2c248461e1f7d718ad30b66b", - "sha256:87dcafae3e884462f90c90ecc200defe5e580a7fbbb4365eda7c7c1eb809ebc9", - "sha256:9b630419bde84ec666bfd7ea0a4cb2a8a651c2d5cccdbdd1972a0c859dfc3c13", - "sha256:b8150f721c101abdef99073bf66d3903e292d851bee51910839831caba341a75", - "sha256:ba09ef14ca9893954244fd872798b4ccb2367c165946ce2dd7376aebdde8e3ac", - "sha256:d3a2f5999215a3a06a4fc218026cd84c61b8b2b40ac5296a6db1f1451ef04c1e", - "sha256:e5f923aa6a47e133d1cf87d60700889d7eae68988704e20c75fb2d65677a8e4b" - ], - "markers": "python_version > '2.7'", - "version": "==6.2" - }, - "urllib3": { - "hashes": [ - "sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc", - "sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.26.13" - }, - "zipp": { - "hashes": [ - "sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa", - "sha256:a7a22e05929290a67401440b39690ae6563279bced5f314609d9d03798f56766" - ], - "markers": "python_version >= '3.7'", - "version": "==3.11.0" - } - }, - "develop": {} -} diff --git a/docs/_ext/edit_on_github.py b/docs/_ext/edit_on_github.py deleted file mode 100644 index f9949daa5..000000000 --- a/docs/_ext/edit_on_github.py +++ /dev/null @@ -1,28 +0,0 @@ -""" -Sphinx extension to add ReadTheDocs-style "Edit on GitHub" links to the -sidebar. -""" - -import warnings - - -def html_page_context(app, pagename, templatename, context, doctree): - if templatename != 'page.html': - return - - if not app.config.edit_on_github_project: - warnings.warn("edit_on_github_project not specified") - return - - # For sphinx_rtd_theme. - context['display_github'] = True - context['github_user'] = app.config.edit_on_github_project.split('/')[0] - context['github_version'] = app.config.edit_on_github_branch + '/' - context['github_repo'] = app.config.edit_on_github_project.split('/')[1] - context['conf_py_path'] = 'docs/' - - -def setup(app): - app.add_config_value('edit_on_github_project', 'lingui/js-lingui', True) - app.add_config_value('edit_on_github_branch', 'main', True) - app.connect('html-page-context', html_page_context) diff --git a/docs/_ext/linguidocs.py b/docs/_ext/linguidocs.py deleted file mode 100644 index c3fdb7e65..000000000 --- a/docs/_ext/linguidocs.py +++ /dev/null @@ -1,109 +0,0 @@ -""" -Lingui docs extensions - -Inspired by Django Docs -https://github.com/django/django/blob/main/docs/_ext/djangodocs.py -""" - -from docutils import nodes -from sphinx import addnodes -from sphinx.domains.std import Cmdoption -from sphinx.locale import _ -from sphinx.util.docfields import TypedField - - -class jsxmacro(nodes.Inline, nodes.TextElement): - pass - - -def visit_react_macro_html(self, node): - self.body.append('<') - - -def depart_react_macro_html(self, node): - self.body.append('>') - - -class react_component(nodes.Inline, nodes.TextElement): - pass - - -def visit_react_component_html(self, node): - self.body.append('<') - - -def depart_react_component_html(self, node): - self.body.append('>') - - -class jsmacro(nodes.Inline, nodes.TextElement): - pass - - -def visit_jsmacro_html(self, node): - pass - - -def depart_jsmacro_html(self, node): - pass - - -def parse_lingui_cli_node(env, sig, signode): - command = sig.split(' ')[0] - env.ref_context['std:program'] = command - title = "lingui %s" % sig - signode += addnodes.desc_name(title, title) - return command - - -def setup(app): - app.add_object_type( - directivename='jsxmacro', - rolename='jsxmacro', - indextemplate="pair: %s; jsxmacro", - ref_nodeclass=jsxmacro, - objname='React macro', - doc_field_types=[ - TypedField('props', label=_('Props'), - names=('prop',), - typerolename='jsxmacro', - typenames=('proptype', 'type')), - ] - ) - app.add_node(jsxmacro, - html=(visit_react_macro_html, depart_react_macro_html)) - - app.add_object_type( - directivename='component', - rolename='component', - indextemplate="pair: %s; component", - ref_nodeclass=react_component, - objname='Component', - doc_field_types=[ - TypedField('props', label=_('Props'), - names=('prop',), - typerolename='component', - typenames=('proptype', 'type')), - ] - ) - app.add_node(react_component, - html=(visit_react_component_html, depart_react_component_html)) - app.add_object_type( - directivename='jsmacro', - rolename='jsmacro', - indextemplate="pair: %s; jsmacro", - ref_nodeclass=jsmacro, - objname='JS Macro' - ) - app.add_node(jsmacro, - html=(visit_jsmacro_html, depart_jsmacro_html)) - app.add_crossref_type('config', 'conf') - app.add_crossref_type('icu', 'icu') - - app.add_object_type( - directivename="lingui-cli", - rolename="cli", - indextemplate="pair: %s; lingui-cli command", - parse_node=parse_lingui_cli_node, - ) - app.add_directive('lingui-cli-option', Cmdoption) diff --git a/docs/_ext/youtube.py b/docs/_ext/youtube.py deleted file mode 100644 index efe6901c2..000000000 --- a/docs/_ext/youtube.py +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from __future__ import division - -import re -from docutils import nodes -from docutils.parsers.rst import directives, Directive - -CONTROL_HEIGHT = 30 - -def get_size(d, key): - if key not in d: - return None - m = re.match("(\d+)(|%|px)$", d[key]) - if not m: - raise ValueError("invalid size %r" % d[key]) - return int(m.group(1)), m.group(2) or "px" - -def css(d): - return "; ".join(sorted("%s: %s" % kv for kv in d.items())) - -class youtube(nodes.General, nodes.Element): pass - -def visit_youtube_node(self, node): - aspect = node["aspect"] - width = node["width"] - height = node["height"] - - if aspect is None: - aspect = 16, 9 - - if (height is None) and (width is not None) and (width[1] == "%"): - style = { - "padding-top": "%dpx" % CONTROL_HEIGHT, - "padding-bottom": "%f%%" % (width[0] * aspect[1] / aspect[0]), - "width": "%d%s" % width, - "position": "relative", - } - self.body.append(self.starttag(node, "div", style=css(style))) - style = { - "position": "absolute", - "top": "0", - "left": "0", - "width": "100%", - "height": "100%", - "border": "0", - } - attrs = { - "src": "https://www.youtube.com/embed/%s" % node["id"], - "style": css(style), - } - self.body.append(self.starttag(node, "iframe", **attrs)) - self.body.append("") - else: - if width is None: - if height is None: - width = 560, "px" - else: - width = height[0] * aspect[0] / aspect[1], "px" - if height is None: - height = width[0] * aspect[1] / aspect[0], "px" - style = { - "width": "%d%s" % width, - "height": "%d%s" % (height[0] + CONTROL_HEIGHT, height[1]), - "border": "0", - } - attrs = { - "src": "https://www.youtube.com/embed/%s" % node["id"], - "style": css(style), - } - self.body.append(self.starttag(node, "iframe", **attrs)) - self.body.append("") - -def depart_youtube_node(self, node): - pass - -class YouTube(Directive): - has_content = True - required_arguments = 1 - optional_arguments = 0 - final_argument_whitespace = False - option_spec = { - "width": directives.unchanged, - "height": directives.unchanged, - "aspect": directives.unchanged, - } - - def run(self): - if "aspect" in self.options: - aspect = self.options.get("aspect") - m = re.match("(\d+):(\d+)", aspect) - if m is None: - raise ValueError("invalid aspect ratio %r" % aspect) - aspect = tuple(int(x) for x in m.groups()) - else: - aspect = None - width = get_size(self.options, "width") - height = get_size(self.options, "height") - return [youtube(id=self.arguments[0], aspect=aspect, width=width, height=height)] - -def setup(app): - app.add_node(youtube, html=(visit_youtube_node, depart_youtube_node)) - app.add_directive("youtube", YouTube) diff --git a/docs/_static/pitch.js b/docs/_static/pitch.js deleted file mode 100644 index a0c116088..000000000 --- a/docs/_static/pitch.js +++ /dev/null @@ -1,31 +0,0 @@ -import React from "react" - -export default function Lingui({ numUsers, name = "You" }) { - return ( -
- Hello {name}, LinguiJS is a readable, automated, and optimized (5 kb) - internationalization for JavaScript. -
- -- Read the documentation - for more info. -
- - {numUsers === 1 ? ( - - Only one user is using this library! - - ) : ( - - {numUsers} users are using this library! - - )} -
- {/* Variables are passed to messages in the same way as in JSX */}
-
-
$9Z8)_!YUZY?sDaB|T{ z8-LjX;#XF3x(s{(NpmAnQ;8dsTN1+ekY?wv@^$V12BiZFgGP cNI7y`n|84_V|6-b2~|00#?#;UM^VWR?sz;iaupyh0Iw?~a+Id}D`WD; z($wwnMytzyfQ~O*_RA_H+;BE8>_(mTExJ4XM{kD06|EU-&v(AY<3}pGi%e4G^MDY) z!m&R9{XIJ#a91>Rpnf{%t6D(G?4@yq-_l>{VtlqBBYa?f4?X2uWhh0Zsf&jpY}(qc zyC@HPTl&p-PP0)S764L4?oWC|7ecS{Z10eP=d%9 5ik80OVyjSljf;4tNNV*_e~=BW60?nNJXkm9eUO*;l* z #9WN`srcD3}i? zAqG|apJ$-J)uZI$&}s{gvXpL*(5bgad}RJ$0t)!cYXo9tC`(@34^rb$Fh5{7U beDt&4)p%|3jhxj8R3V8pHe!0-BUpIN~L!cRIZ$0O{eVkg}gZ;zsZIk3i6a#H)AV zN@XL0S#VM>5T6x$cajId> R--Dl17j|m&`C~1um+@B5sK66R&(J$}EuBmJv z>uq%l-Urkso`nM0(By1wM*6h4#q4 I2cEP1*#}~lOz}fK{ za~}0rltN%#&Y$#<(@gjqUr8$^4D@@Nx-=d!0ws4NX_wnF?%)xlv*SvjvP9BamMrc6 z9}8D#NO@RDtk_9jl%cqnr!J~M+{AFu I_Y);Ps7t(! zgf7rgbq`XMBRxp_(Bfu1hjh1}|0gs=ZY^5^3XvPlT|m@#RG#csM+Xf_B_Z=>HgYnS z{kV6MCQf%-qr)&HZ0f0g!_&h?n$(LXp>l-=Yctp)2;q_?+LE4|2 z*Bm$L#2HR9T2=9n%s@d6U=<{Abpo#4A;$4{tpjg2suoXO|FZ*N>OLjNzze-59>B4u zye3A2xUmoMM!AdsP|J3B>d3Mm9Rxij%`fy1MzVnmEni4nC`~kucI z!WKfe5<%_~vEXrR*VK01O=0auDP+9(FEy 0T&Jo(?a0)+_8`a8zt}9Dv;Xs#kh|SzY?O=m9&W;}~ zAjsEQe^`3Yd13GGI-EttNiD4SnGCp6xRf=j;;-ARiOKsa0*_l6?Mtiv%u1e^ CWQ3kLDjsHx)3l1`nt=B}C1i4$qzhM{UWp69yvk3eWD|T%sz)&QeC`9P& z_@McpK?|VlA#+|#L|evyKe1xnFaWH4l1F_XBS3I!K?F`ITu@ ^{7BcCdAieZw zCP-dFx}qsxk*)@muPXl9WU6Od25&5`G*$Vz{ztC~V5JRND8_}S20BU>q;a6^T@;rK zPX9^3jqNp_wdc#E`7my68Qzl+aHHw8IS(7yn=D<|cjEVvv~>Xcr*q=wPnq-dm!`C2 ziT+9M@5JI|;P+Mhr7!ih)(TS7)IkTZWm*12);(x-GGYpux3D2DjW-%tBy2b+O#aut zo|%6OBpLMqoYEog$47)_q4F@W1to205Nx5sNj@xeDhZrJDMK<3|Lesqd(an3LB%Y? zSadD9h^pdG0<6A2(L@On?Ym`p7X+aK!o}VeVT e+$6pPv*RC>~Lki=x68U zNs|z8(T}mvU6gwuxrh*1Pbu{A6ZOw11mF1|*m#dJhgE<|_F`K`i$Af(j5nGel+m;k zkkbZm3q1AJQsOOS65tKL;}P4T)jZ+O3Mo2_gbF6(`(K7?2AlnOCwT};u2S(|nS= yQYkGl+mlu>KoJIam#-H#yQz(JlNks;Q7{1&ztwC zqYXO#79eIkNbOdHglI=mPe9a9DWoVsq64=QNy~okZqH3k%l{|$F9oE0gOcUFCa!7` zsIri8aKsHIhHDYPl|bkO9Ytp)&n^-iK!9T KoFtoljb%9BU+iv&;pms+I;4i|lBn}Xy2^?(j zmSsQjT@;Y;;SjdJw=7pefdS*bhN@@o>@*WtR;sSEIxs7n=R?8LH+Pu4s_c s5z8zUPoOb0m2rTkTnOg;R`O zPt3})w?~?Iak7{H2Zbn0#{5+(9k(Kr&6>polh gWOF>VDYQBq zPhF;?bauh}CV6W4+v(s)KBZe7qWwu}mqHHRS2_hq?T*OP;V84>90TM z*SK?fHz6R*yyj@z{k|5J ;#RHt+)5*%i`F4n!7=%A(YE419X zW@uKGS8yci0p)XVQ;*+Qt5lH}IH}yp6`hWt>=}hd`Q)ahWr-xPumgiuhrLz?;fC^e znm*r=?aSU?YVsQYn6H#dx11k~8i{|!=za0>-1+elv48e3zkLsblxG90YC+OgL@4KW zlDioxfi|X&28dyrpbu(ER-GsY5d!Rk@ VJ2YKcpE#v|K z!xkXdv352cYZqS-A!cNwaNs`p`d^1t@l-XcOcE0Jc_U{7j|i*Hz`*=KP+nWI41$?t zi*{*1eDR-Dh4F|Fdnr$lPtNC#cPy>Q_`7cRFAm{HzlKbo!D?LKo8}|VMO;i5nf`jq zvC+chwEpH8pAC?~bvJx `T#HC9$`Iox5`nO#6xMbA4EU+)WE_+sXCcnB)zqisf@!F+ax0WPdCDr7_ zv)WaT)VFD#sl$m$u9xN`4mtH~)*iZh!hYrHO>$)$zZ*Jm;@c1ooBiXbobiy$Zpx5# z<0+kYJ8!kuNvrw+V6o1Bb4U^1iQv(G+_CX&q1b<6c;ZT$j8a`h>=T`5dUv!RS)VVD z!rh9SyNzEiWt+FCZ*KBi&A=#);|Y0VU*!Boo))?_-T9{EG9=;G*Gey|ujf_P$n&OO z>)QIh|8(`Gl%wHG#>Gy4^$ylO7dIC(>P@BOPM!VaKk5b|%;AHpa~+poe3`h?zEutA ztQ+Nv@0B~!y;!8%oU{CO%Syc;)s{Y5yhF`nJ3{N7NSzokXtziBpSXBO;7s-%wgfGi zeMfq!ftA(^!-bj!?c`5x_w#{J6|OBo9!{0!1|6r5ZpwbU_NC}Fr(4%m0YB@p Qm3DU+&8s `9-2$ikFY7TdFLI@8AL(-3iUnG8z7n4x^pdPlV#N}OltNE~t+e*wAzwPz` z*Z$std^(=2^zhYM(C#Xn@wv{+-B%l9?k0G3Z{{iurvPc*J+)|EUuOF7)VJ@&=5}5a zueAt8mat|b8eG%L@h4J*h&mfTQrdT7R|I9C#G`#J>U+`h?F?{oRXqw25A@Kj_ovs9 zuDH`ftetbkF0F~=vg(}gn6|$2Lx)F>B2qG~8yPXF?dJx2nsjqlL739;%0RrIM_D J!sMnPq{6<&D90f46qxRq_P~v&xOX+W&5upHw|GUUAOvi*eTGrQGp!w(%}? zmplfS< XZ)q$g;Cz!#n+EX{l`W<$7k_<6$qdAJ=AH zu*kdvn)vJZjHE7x)JHy@IlRigptU|cS6epM`1#K1r&VsIdcsF`rD#`oFPsR lBfBe)U4%G-}xO316>pwzO@+ESrJ-${K2W)Kb~Hj)Nl)5 zzl9X-uE^8HyZ1jGVB~`kcc0*AMfE;UM5<4nA1?dyy+KDQPi1xa{?XK11NJ4Zi#d4p zY=1_ksXisu-8&=`anbhjN~wEN<3*jmhuiwj9wC3bzM9XEvbokeqV-{6OAKTr!t*ui z)i#u$PI=%rN5*P074}iXbeW)Ps%;Ot-)lmN6}ysF&C)Iot`nUFgvGGzU 7Kho08ez6(f2r&=bEbzNkD3K!>(`4$NSMk)* 69wP?B#m_WTHH{jOy XZG76)8pzYqeCb82a`JwiHP`k@`Thz=+lvv+Pv)1@8D^sCd|77fTMSuQ zaQA{%`r1pBu=52&3tE5hM9ui-GsTXvv%4tqges%%%@O4erB8m}i?kjt3isD+Km4le z@5G&^>vF3V;>o!~YTTKLv=I=}07blnhd@%@Ac{Sk4k!^ceb>)6U$h}I6*M72B}_NFhd z+a5oEJ%v4Z1pY07D_MA!&{9!a)#5){rZ_UPQmc8XKH=a&FSo`Yv#kjcGx<9z{2DJQ zE#}M(gnWI!&u^(msek45vU;|r@7CpNpT@tsbJ@L*`&?+7JEJrl48T*@4 BEz0sO^Fe~$^riEkE7q%+s<&x~*OOSE1-uGJxV3%E?L4o)Xs)3mHrSlp$gL|LaG zszOiHJqzY?zuV5-&77U9wB(!iwW6l;ell15vody3&Pa6}m-br8xO}>-I3r_G5jF5> z{5{>AVH-T!i{a)EpVfJnJQ(S&mAbTgvM?_yaE?^pk~Rd)Q@>$ORemweYG4fGvssdl(Y5s z6ToE$`@Lw>xBHrV1 yN|UpzW+$jSUw9`gE m?yi@=rf{puY z{{V30cW_nl%Y)R#NN(~7p6UncZDf)UiCTqp<&Oolnt8hz$sSgr8AWx3ajb0Q05U{w zCpIDNQ!|CNv(qDZ)#2F1Brm?@1s`q2$=G6-Hh&)jT+iJq?c+z@gK~1^ow4>LEiY6- zU+Td4xbP6a`t~4JUe)Hqh44s6N4JUVmhi=O*^|ec0VZ2?$?`hnvaT(Rp8{EMp`qri zAF5(_W4QU&&DvGD)Rm~))y@hMko>u(kf`}fYwL@xf<$0EN5?*;Q27Z7sbbdkqk1g^ ziUr15+JVo*o;QY@hSm3-k?u&^IVpd4w!tr|szNONL8DCnL6I!A@YaRMC#C)F!+kLV zUZFm!>npcpluv!!j7&LvKzS$DNSFWq`lGM0hlcP|4Yzw&-{`?+; +Eoc zUa{~i?K1jS6#J`=J!nSl^tf<6m>?zHL3cGde@WEa+Y9i^dHNfjEB&dQtyvU?xNJ&ee-gpNzx~PR1=SN-lc!${)^7Oy39>ZXE0a@cDNWI7tLWNnzSbGTE?XT&sqoj ze-OJ3Y+($Lp|j)MnKj_9;!E>Kc=tlytG8riz-}po**?@(3%N>vq )o2w79)b~`c64tF+JWqo+U#8p`~>t3>??r zPm{8D<_i2f$KTx^a^{w7_zKy%YiH+TVMlY>m^33FRZPBZ5x&s=RXfnYGo|$D#@22X zGgV#h_L#P=h)#|5uy2tAZ#u-1Br+W<{08J(8nxydXz1LdmzVbXYfxugo{DIBmR+B< zBTp)-%3l$@9L`}5iFWP3t+`+UQU58*?R*&%Q`z>I`^^4?ZWWuhiTRfxZC#A4vR3kq zoS(NGT4=p;H*z<2ZSm!)9cttFVav;oW^o~!sDk#rQ;(j+hMA)bl$0Tr4@9SD)VDvJ z+(~1go2Ab;&%HYoH_}p_9<#iw$m?iiFz3dWl$9UqQfY`-VOf)7clGB-;u9f;RaLl; zjpl@o+n?NAly;H_vg3NjoTt`*-A~O?4_MIm^_tKEIOPy=A(L?&5&F-8Q!pR|-oPLs zTxcKXKry1ynB^7{_kANL_(6vlIP9379d}@dvrqDzE=`GZfra`te|%D<+T8K!#kCGn zQ|(#W^Cw80V|vJd0W8#KWzPWT^W2g!=__;DT8d*4h68hVeD)``Y|kM&4nneg4oNTo zZd7Iz!QpnRV?FLpD;HYgzE|8<`B2~ q%1neCI*+{d9Hu`6n5x#{re5XI>cZ*L`X;H&Qq7r1C=AGyswSvsow|UhfDh ze|=` Vqc=YiqGt z>LK>=0YS!| WNH+U)Xrq})1OFsUzuf|<9p-E44m2kFmB1i9M)tT99N2EW9oUvV8yzoFQ zYcXVYb$GCLV(vqw)!!WLuU5e?MSdNJmoD$7JW%l$?GSGkB!2w|TnY|9zoiOsW57xV zCk2wV1Yfchs5wwM?3B@VF(puJgjNHd4IF}LK-?ary!aXaEwuV8U_mx=)OJ(ktd;CU zBNTn^GMK43Gfs& Cgrx(Hiy-RKOb$$nd9BN zhj*5-c0LQK{ZigLakOwQ`^ 4F-@Vl^ovejtY2}owp)AN89aVt+f$%(cFBqM`ac4Mbh9okKSgW$#>AkeU85=xH^ z4hZmztk?-arX!*6=_rD^6VVM8swEBC*Cs}sDc#xG`Siu5dfR&RH9CDAVC|aunT#(B zZCCy1e+A7&ozC|DMvI-eWLi?GgBaR_*3DG?&@C%@2oN@(%+%+_G*_L}FPB*Z+iQAP zyDsPB(z|A;)cZmG5eQl8RgeE(ygl*lqV5`{)nS$RK`snAms;;2)$T0CKdEp#c_1iN zth*e 9L{OH@Q zRqCm*P`3%AfpV2+CBc{>7r9jDaxa6`&7Vy*IU)1&y)rIs140g`FVGbYU~A`wEiJYW z*NNiYa|0}f@{Er+XY5OFOE8vyt}uCG=1%E}k*G6^M+wfFi;tdrO@uF=xO1^zKH{Q| z&kvU~VLP$CyE 99RB-1B#w*g)D3 zodIOP>$|X-+Myydh<4c80lN fF1S zv>Lqo0B2v*qmynG^!G?-QGVvN^&hqfh`Kfb+{XZR*}{eH1$McMk_CRS4{HwQ#$Mcs z%>idId(gGM)NEu@1cMNJ&@Kj!UtR-R?DO7;ome+BA6S}|PehJV<_LbOIfM79vsd^h zVRZki2BOBc(l+;W`XuZ87mp#a)%1A3X=RyhVYD-pXcq0xOYFVax_K9!>tHtk@5s^^ zQttQHx==Yleez7XF2Z;Mzevv;GH97up6J)#=~<9>$kHeLVpU*R*5gcYBk*{$ze4u6 z)I0s(TE?uK@$QzM&*`T+s2XPwLzmhfcSRCTxYj7F;HeFh%f`p4Iay7a0H6AAX*H!; zfg>Lc(L @R3Iq#4Oh ziAs$k40 ~!g(X!g^(c8!b6Cr>m_YCBJ|`^OBJbKJ!jX|KW`98{GG zlg<*&&=P-=efAYH$<+8X1zS)$ #o z%4Ia X0T7o zPx_zWR@N;WBa2thk9=6)3fmvQx^dUkUTwIh_G|Lxe}W!tZDBX18v|&HW03w#6ipV8 zt#BJWbsCCQWKb3j%8&?K9IV1#0noC)tV*f3#W7s^{URZN8yz97LiN#jp8GE6>FXo6 zH@MM^bbeE=T2OTzU~*8!(HLlZdhl$QLaO?va!rLnq-Op4qJ^25TZr=o70I^pM`a=U zpYcUUI}r?s$LPLUD&K1nLOTv|wCjd *0aQ;Io$h$Jlp3HMO 7&w;@4wkw&;~&W`oAyXlWfb*IgP z#;v#7!@=FH?F1i@7-c;_Q(~oPYh>&HDrp)xXZXbg`v}K1iIXm@f6j$S7Rcn3JlHo~ zvhz#H(wI!$;TILwNoFjY@3`)&_Ga&8=78@<0sDvFPQ5C+zj*&WKQs+s>_>}`EL>Q= z8wxb4gigktbg0_NTOyEopaAWawE%EXaX`oO`#U)3A(`VJF2B1YBE-ldmg?= 9}F7Dnz$?gKEFfmP8 zF)j6lAavwW(W?_H_e(JBivi)>yYqZb*OAyi^ z;FgI!dt<68@68WN0w0^t(S@e;xaichJpj)dXppeh=AgobpMuE1EUcopSb(l`-&Rem z*&rElKg|Sr2|DZR(Z3?SX*H3$I0vRCcd$H#%1QQym<1va)YSs63qIZLF6%|sy-@}= zz6nG<1n@vDK?}@6VJXOQxQuDGb|Oht1C7gD@5Tti@?@XdeJ28m(ObeEwC)!AhIL2h zmxQ(F0#f=d&d)8Rhwu dT#jxBI+?3zGr&>v0+K@pfP@qhSTOjeRJu3xN!)hV!z0^=AC)}J zycYbKHa(!Vw`X~eEF2FO&+C12>qWg^`bak&teU=cNgz`EvG{IUGu|d{JMUqQfc49x zlBQ*jgafOn*J%|8etcNaWhA1r{u<_l5*5R#^h2k!sjrE7mj5)*9CcdTep6(1x89in zMLVDUN<`dwzaC4{I8bUM%olj$0a=q&(YI*K_78zvtQ~63=s0r(rCR;@ 0uE7twpje?67Q;BZkw+4`C7Ra7dDo_4U@-3W*lV69Q zGiaQ~eyufb0KtUj=k^`I7GkrcU?072g=C(T*Dv`I?|s^xb!^ug>JaF5r^)9@kY{`} zi3O ;jrZ7efV8p4clXzVouyrk>lwdtLsHzoX~-=YW(3njS!c%i)5a2tq-J z3N;c05^4(X8`1FrOY8Yh0498N&kCw+h?N7>Nc(e`0$VtLJs7}|7*mQ+b}TN4js3nE z54zsWAPUqCRXUz8Tz2yy*I4^ZOg)S128@6g+gtk?b+q@WjnmlM@LY@M{`+_|hT0C^ z43VGvWp%*Ty9f_#e=FC-M%wMM$et4&lPo}+jW@MMIS9)%dUc-BL|KFURFt0rQ>j{e z?Q7j 2q|CWStXV|E~9x#6x`?0wUSadpWSAw6>lRH*nT$VfK)(h z9 $kIH1Af&uHDmh _T&-k;GDB-sRXk%Z#ymTUO8~ zb%p>t`X-9u5U$YuHYui*_vDu4ixOU5({ZJ`sUa3R3m^B29*1`<6%}t>wdH(A+sTj5 zCm4k`cT3iiZQ=qty=e3?h5ea-JrEg@UU)W@zs3I`%3*X2EVAp^T%v0~(o(C;;*F|} zDGbEJZU4g5Dr3_zt_&-l*ML>AFl!g6>C|71KNDW}6ETRIjkxY0@T|}5gK_0UwrAX{ z(%v1Ie%^zV`pQ~^t3S#+UL;X2>rL E_#rV2< zcNa{$C9b8~-H~3bnAvNzlzt#8@}mO)Mp=$WHcH&I?DK^b-`Wqw4bLJEeEg &CA7~Av;G`Ft*k}#YPHB3?{Bl**KEmP%J+$hI x2X3?v+-RkSI 0x!UPX#nUVH!;Wnno~y1)grAdKAg;Lc0tE7X`42p~--bjnj1KmFR(^ zdkmK~+m7yy1a!=trpJJb-!@h~Py$N8 3h={YAoEj7#s<>ak>(EO8#`G`Cy&R~m5qYa?@sA`kk +)k9Se>w&JhaREhGsg}o8DaoeKOc4P|)BDK@3ts6W0}S536u$Frp6VSUCln zFUvF;F!&?@6f%Gjlks0d(m!8*2lSQ`e^>JW;-tT3B9R~px#=l>DEs4P2t5wEYW<4l zkT(dT;NB`59MMFGwg9EpRGB$mi0=YGHqvB(?|RAHf;0eyIYEjH0I}3PDDV)A_y|hg zzG{^_Nz!*2>}YaM8-FjtUw_HIbH9eh+S_u`X+Z8Lal~N2QbU34ZsVe?1sJ6!Kmg_& z= b^^WDC%eIB0#jA!!K+85YE1t{r4TQ{=!ox z$3`WfVgjQMW;Cc$r}DTf(IxF)fjRu{f$uI7kKn@088eK5FNpuQ7>z3n=#PZmYQP@$ z0)YnDmT0wqEDr%K4MEg`N~HJ|-9OH>6AX00`8&bexaj&t;*=VFpza`a{h8(V-*PJf zklDtuLM_l&b=|>U5U6ZA4E|}fG!?O!Q!5)JYbyP(E74m&Nm2hTFxvw~81}~iE-3|f z=<86!W X^nN zT)C2@zOTV`#bVbK4{_tNX5*f#A1+Mr1}7eZW|0_|9#smK^#-<7{%_S;EeAO`%p_10 zIF@pc+yYt)ra&zNI2P&Ae_aMc6|PjMQW>#V0UW*!M(R+nF{Qt4=_+jYJ@;jjUl$|Z z-!IroCD#onUsz4m2a4K<>yCnS3Q{qG~ej3c9(K@?(fZ x+Wi#bbK; z=c)8-NCh;8HCl?Vm=ZCi&WG|t^P$+93~-PfvZTEsP_52%XB @0vpdeJ85=^3sBt{RbtfRUM6t<7l{sF%4II;yagOI;NdB*WdJV zIBpKIOuB~&E5#^O@eJyTw3hR-iX^YxIheXhQ*B`Qa?eU(e5@1d`LX3;P(kf8d)u8V z&7=x}jXl`+vh*(GOr(|?j7Lz()m$aHD!iXQgkOHP^H|x5Zc#+prI_%~+7Z$iKs;GB z-$Rq|ND+Bb2wJ3KJYu`PmK$Y);6nMtppZ77@zJJ1e5lJi#JG4c&xy~~c<8FnNJaH= z;WS*#NM51Y-NJF(NN-=t%lW Z8`M>I1dvf_ Fe+<&MVK1I>JxHdD$H6^^xGem1(=C z$tOh)pAO?L)@ZCFRzt=~Q6yc||tIZT*0Xz$Bg9kGp?ahK}DWikf zQGR!-kcvFPe(81fMm;#uP9Nog!D?K^hl!WyJvvWEP$DFyEf1?Ixlb#32wNYhjIRo& zb(RjdzO<-fZ$#RddVa`N$!^_9mU2J2h=AYpx?1$u-pthmAFaC~G46G)92@PycuLm5 zXJY55?f27Wygy)Rc65~rQI*=zGO(3XEpbkMZ?^yTvEyCV&{t^ <9dqhpib;j zEasoyUlkhnOd%L*Je03ty)2y|I@7nRL*&;;)T#9pM{~B*2<+Ie=K}b4-GweP?X5Vt zBv`LkoPqUgUn787GQgO?s`aU3tyT&r+LZJRHYebwNr8|_vqmoEG#wtiMk=~_*4#%b zI<|bojrKcd;(=#&$z(zht}}V!B#6fO`8W^>dMMuc+nj^g*NJSEjc-l6!aPZWxH8a+ z=2bDP&wSV8Lykyivwwpj>8@xAn8Qy}WC;lpKz5A!-rqAR{XieYQ+NCJF~a`4hl73w zeU+&^^~A8B4?iKy9jxKTAwK$r*Bkx98HV9Ck+v)bcZFkq5&jUcLG>8ROY3rQas~_p z;n{0R?Nh5-AvGR&z)5}fHuHGwTbZ1>zk8Z+%DV<|>*EK`^oR!OZw2b(zR97$0QZf@ zKJ_n9--Cl#{}K{Y{gN3(I7sKtG#uGc)iZ8{H8)%W7*j|yB_e$Xf{PCeVj)m~1ckz4 z&IoZaQV>MHj2{mUrYwXJ{7n4P5RwA%t{{|_3r@a>hyG041Py(D*)G1v5T5yEnkfkC z`eVt7Zqp4~i-QltI5BjT`efxZc$hS90e;^8hQR`w5^;%zh718wVwf{HBS}edAw|^j z5gl&^yn7${c7y=Uvz|qr@{3pa*?L%(^Jc$-Rm4k{47$!3!ewDL`q~=GS?#M*$8TR= z*G*^cL&H#U-$IC2aOD2#tE}&8^ojn?Q8w7}Kd%>Y4}!bE6tno<@^{_>nX8%*CO)lO zfE)eprwS`7wK3%6x~x)2@2jf` >r}ANX1(YGL$++;T;_#* (Q zsSaj$U8}Pd%OVowZI|Pg@8hFOhw0ti%&EF+y>Qu`CfbKvST^c?3cZZk>WX+ahMHAD zVtc$%m2HG)^p6%GtB}spxItg9#<)IysQd~~PG81B*Y&3<4McjIBopsMuXY9s&tLzz zx0}A)V(`?oKGZjG2;;slU@z_aeULT3=sI}!@c1xp;GFSQ?wrP(y1wim7q=lRQK|BN z-y=WvTl-p) =S`|q*s8__oJlUZwin+()Zu^d0)B+jRT$u*)JhQ zBv*OlZ3a|P9DM3)fFFEf9psuQMY~MhR%FN=D*x1&LwwWv>Q`xJiZ|DyGCo>TY4wcG zeujF!o+`hBU9b6~_S&v>8?k4!lKrOekw}wh>-@}yYbn-z>4g`t?c`^Dwsn2-kV5AX zIfkV3Yx%zt?`=u9FKLDZrgqcu-?99JF|@lk$gTx19|fhKwGxCzc;VxIf1c>)>N1?< z c98XSc%L%lROYDHlH <#@6)*gxKYJCX2R)BCC5psv20zwXVhFR7m+a;4&eSs$F)tO?IQ7(Sp(uaUVX zo$$TH-$oi_u$Q2ah?i_W;mxBj8+#V_eq)$z_l9FjqaEGX=K@qT73n)Kvki>U*AqtH zp?P}h8oIeQ7)M`J3XZ&fMx~MLeXC)R$lHkt#P`SjZz6If;)0t89Tf2eWyt>t%-g?~ zlcDg;zI)`7@VPe#a`4b3M{N3$D?@zA+(7+!s*HdO8ELby^~LGbW~XHy=Gh9~akqSw zYencc7N0eGao>{DtE=jR$w?#gl{bAq87sCMbMh+Dqqfay5`n8b#wr`-F*(Clt^E&O zh58qxZqh6jzP%H(_}G{Udm1!9F);p#dCNmLYp?sBQyx~2!g`w`8!(O-DMt VV zzX~sv9$XA2*+WO%DBJv?HQ%L)(&}y|(#GbLrj3nF(_>eNDCU|sFR^W9`>&k@_z7Eb zm#)%AMfJr357&wM5`%xcc=4K;n-h6wwkv&2`h*5>z+kB;ayN01ho> wT-!KdrGYPFWV z3yqIo*B?YKkS+c?{G!l%);G@BnzVhj*Y{*I@{zq6X^QpL+ox+;Pnz-?$(;8XG#f;Y z9WS%4Pq+;hfx0ebvFzop5`W#PR>#tf(1!*a<>nSJ8go 7Q)YzYPGnr!TSqQQ8@iQ8oA^!Nco#dnL-DIhGM;)BCiKHZ#fixzMt)S3ky(x_tBJ zVj8wAy(c=f9Pj`0*bC%y=d&ZN35Pk?%lHHP(~riqS-QAvCbKzFp`(={mbiu**7=eC zv#q2Bg&$|0e2RH_cA$qF^2Q>Tj*6l1s}yl!Fk_6SyBJ?VZQVZA&(A016Q#$S#dnh; za~~QyQjE H>frOprlHUGOGNxReQycYduyWK=#$CcVJCoL8?V +^Y5}h%eg@ptca|%Jo94%7g!%SyB$O2o<3q?R0PPd(`KsKpA(z*vx>$wFl?=HJO zyN63%%=f8%-O~@A$>e(ZD9<)__}u*-!*RayudoNj?~k-|^w8l$R6kX9@z0AjF8kVy z)9XZXqZ%FhS{Wq-ele~mQs>|Lbd+aS?=&9XbcoZtIa=nP725jv^Tjg@0+PK-e&R)N zuH2>i?rx S(mCgh;iz+N^=P6vP5RC!;qRG+6%Yr=!HL9d9g=!i{>vC*^G%ebxPz dbkZN$82Pp&!5oF`XNC%^p>fl|V0ra-6>ESpbd@K{^G$Pg!|$lOX@x8#U{ zUOzbbYd$4;PE?nKw~MpQ@U82nO|6M18K5(u(_@I51rA4F=gDVt!Bbd=t*qJ^@60rJ zn6J^*M`q7jV|=#hZ eW;$={y~zsbrsY)ZKI*<@RR+iJs|68a}c7J PLeF-xysNIG z1-|;#!!6~t1SpnBXfothX__E4dtBE+YC+FG6#<^m4EhoFjUviTNiRa=KI5rRq6TDH z;b9OnN}|s)r1E}fxQ_OmCs{0uXwhMpgk-6fhiyB$Qp=^j&Pf~N!*$L3nrLoj->+^~ z8>#5PK+(aYR+ZR?BJ9cIGY#q1DlX5T^NjXerEei_>>G`syf?L4Pu$x@f(i~uf_~K< z@Ztss5225AZh%xHdl9H>me@kUyM8Sv4%tzif#VB)9g&;3Xep_}t0A*rJC@WZ-(HY; z4BEt}7kt^XR>Am+-z>~2b2 F6B1As&`6WiWL ~tDoP0zR^jHM+Uai-z!*@mWArTD(tf)!$a;O%;6>yI#D>f2@ zj8m_CDW5=VCdX{Mnjg)NrTAYTZe6(;iw |5x+gEH@7HzG`XZ~%TpFk;-{dsn! z6Xm?#wT{B;l D8H%HAkzw~*}8Zma)Tc-e&1QBZs g(-0gv0(pWt2B_ z_^z%eb9;UjeX622&RwB9J07TDM(STvCSpSeI&X};Tw$Hg=Ay8BNbdVDqK ;qby z7N5`aMcr4m+<)PGv--$lP=K!hVO3(lWSf)4b~r5I87veqqjqsL-)KRW Q+gi$fk^|!yoQHK2n#Bn)_BJ6 z^dqkrftfnqlE3)MqCC#Qr;%|{0>ft^eqvrbj`wxayr(o>dOhqAu3aPuz4o+F{)P`F z+7!MlPIlv%TMRgFJ6&H2G64;xRUv+21siwCF=MG>@qS}vGfh2F5`6p7;tRc8`uY-+ zH>>QeYj+oqxWj#yqryQWgmaR5mp_DOeH3k&hH``8b`TsL3Q{1pGcV#RwFXW=--PaA zmgt@<+#i0aNK0+Vz(PkGxtIr&FUO6hhYLx g6rWT1#6|hswm8Rv+Conv7a6RoydauaZA8?t! z(Tg`Hcr7?Wce`R)CQ6v$7I>Y$9*IOd)o%zZ(GZD?@ivAF?JM7dG+d`dl(K}XLVS}U zNJZ8V4%9*b^jPUB4u&ubnsm7J4i6^2rFWMA#wb!J4ukJzHp;42XVRt|=4&h%<&D5% z8W*`-Wi4>=XtSVCJQ9xLeYXzTd%_*-pX|!doi;@h6%f3=?JRb>*Z5GopvGSHLoZil zjh u- zX8c7&@>LHZwiT@)T2FS4N?vl9*Sw(nk=@nwX6)pE@5u;HSHiOmLauw9sD~OU#A5MP z^qwO%hW#eCsrMWM{avf=6`W)RwqBg8{`5;xhp;AhVMhJo_HH|2RNo1T5hMs;!MWl- z0*`#uVt0*4tn<86FE+Eu&Ue0(zE&m$#do;lX{^%`W>Zq&k;lt~Ma#-|ozlga1BU0b z%RQR`AdJ7O-I3*q5RT+jppIxv#si%%E~fGGsu_LeTPd@e+QIXknZs4CQ%!q2sR*~B zqV)6P?~$&V-3#lM_x<)$YZoJ4(|{1Aq7gqk*Dz3hA%d&n_Xwh?G{|taNmNFP2=#j# z0evEwlI6*lkdRWhBcWDC LXV=*4`2qxsu(naRS(d%Nw&NBFLp4fQW$VXMU&u z?tX+8#GznYE eqgR7+R7!=Wzu`#){O%qN1_ewt*Soj@)`YX n<=C zuwu4l5-^Z0ShLZl;j4*gavVr|p-F%aoX;91^LTvvu~!SP#Ib+3CJH?iObI&T)|wSk zsSkXRqj%?pJcM!&*4fp}KbMmrcESNt01`N?u1L+0d`11IH#r$%bd#@Y2<4^ANYE#j zNsge)PZDmg J_xh ziFZc FUTC$m1@$ylG!7gj(f7>R6b zFJ`;0^L=e%5B7SC0AT)D@%PtO&t9E*zJB5o!b(hRWLoS!H9V*bi<};(f(dA^j=n1@ z{GELjRq Tq55 BM=jzO0~Ji1myRvjIB+#N9Ho3O8ETm7#~J|h04GE}_W|*!q|l8Iz#s@L3?lPf zJDkt5FA14_lc`&Y1J2_4==J#PHOkX^VaX*1&&<-NeNl|p;X>a}+Fs?cVXjpKYb 9H4xwf8E(RLXPz|k z?K`GoI&jH?CsBGXw;4fj8263M8*Mr(5Zzv}K%I(%G?}~Bt#C5Jy#^Y3P}j}=jM!VM z+vtBxUX4hBZ@)i(doezwtDoI8`2~VF3En-?3yT=ADsh^?sMVenZ5{5=3#Sp>q54f( z#T@qNLmE<5pTk+uD9RVmZ*d4sGDKG>LJ5K|9`^~^aVyx5Ywk4!(Fm6?1Tet8Fm1?n zo&1E(L*rzR%Z^od!@2n- +O`m2N|r+rc~?eUm#e zfMiP=OF1`ug>EXtg@n$D78#|QkFG^I?| &yx zmhWCW*qi)(9kz1IU=g0}e4hXvf4)ZJ%RpXr;wCzBu%d7^>um};1+)nWBfa0&Kq>=T zw^Ej*3h1^H%+tgKTfhL45Ktbu1n9q%%HQKgo8FKE^b-DuyZEqT`cNcvd!A8?0KFwD zgHnY^`<6j*F|AN|9K}P3cm=LzF1 8ri8e<*ck9FXNo($as9 zQ_OXRxHJBk5@`{*6TlJ*-CmQV9W2>faao+V17ItT$0kXf`(EgluK#Yi>0jj=Hw;YB z_~?VNofc`&_qEjBab*4c9f2gjqrxlC9Dk)xr9} glFZ1DI zf-|G7X~G9kbCK`8owQ3@M0|J4l_80zzDwe-86QHVbqLYdbty^Q_iY65ue}<~DCHy0 zo@fP89_e7r$}u)=dbda}qd02HWVZ06?uUWzHC+Pq_LU>S(V_Y}#WlNens@9 =0^&QKn&Vw?o$`Xzoht7~d$RrR;B1w{vBqaw7UCiu zClX7*SqoJG6W<&ywGy_a7KLZ_^#3$}Qdi}BUcplzl2h~Ix4+l lr^sE@hqjc1*0AnyK?46%#L*Ta6;e+ivI_q R!i6@>P& zjJ4HdQyCL2(kA;L;&fdS!C37@yy}=>wa0h8YPFeSz`GW?R6`G+;}g|nMs53&AgCC4 zsES!>jLlrVeS`K7Zi*9Y-X%m=an_DK-=|t4K Xr}?&;3;y zpR6Ey7tuSGFT9%?jg-qITAtPMWhwlZx9;LZbB9 xogNA;Jd~uMH?l` M5elmY>q}LG|n&HFuED(ZMvLJiMWQ=viidB|57cK zv))%(@>J6_nN~umYGia$`X2nLh5TM$ksZ}Z{Ihk<4uPn -+5&mDn3D0w_rz+b+!Nj=r$b{h zf&nPA>@P2R6qUt#CI5y4<)-xy)r 3{T)fWq7dp#xac*e?C*w`KhAwx987(OE_3u z@W~M-N Zp; z|AuP2d`d@ZVCej`)QyVzm11s9Zqpo|N-Y*qzgfw?{)fA1TolM$-)9(+TdWr^=cYpo zUDk*4Lpwe=XV9Y60Eh?j)6Ds5RT)=KuBGUW>l1AN_v*+UjI2cAmQW&Y8K1Lk&tHpN zj+|N`JI9OP|4tP+8C467k$TPE7^f+>$Z)3_&|7`d&*MIxNl+m>N^&&fYDSG22k(dz zh-(jiXdu$>O^g=ZRta+g)=de|~szSOr}O#M1fJ5hbUD-NP&$;r$k)nlC~seA|d zGzT}h6pm)8P9zq%6q)We%`8i?PP<4F-5f3Ua$>@R1!8#EHf7wzTI?u%Jwa*w6A;W6 zgGWu0nQx7U-7GWSp59 K)0B?Hq6gD!& zdkNqZyqQpmnXuAYq5Z^#^AA>38%=77(a_R8@=)_4!U7Mxc*%7bmwkIs&qr2gAwY;# z`FA#lHu_AMSM6GdtxNP-U2QNOuhiZ0n ! zE%%;j(>0CDfTHAc(o8iWx+}1~wPkvAyA9Q)zmZGgDS%B@d!1A+cHi|0(JY;5%oYc@ z>z(^=io8lxhry243bV~;Frl=1DAHG-Je@t(-t^ozX^j58$+_=Gnlcj#*%2npmQCVk z-Iq6{{Kc2fEVOHE`a#SE?%dKynNm5Nhk8m-)vG??`E&jIR*qsQJZ&X92eq{Jl#c;! zal005yDr9hgjPix&@ub~qc$g-9M@JUc$0TP6$<2C!*s1NQ)` (Ayc$Rz<&^M-m)*voId-koDP)ZktyMdu&$Oou$%=le(_f_ty%5M(s zUx+(r^nrfisza>B(~uGgiRf^5isNrCiC+SAQY@E1xCQOB7w<_zZFf-uvQkN;#^or) z!}Ig+v@KDl$oHqPrk2vj!6KaGh{t%aH}uMn;JaH+7q)H4rCvRm6d=2q>rHr!hd$U* z2H}liyqKpMY_iW(bbv3#*vGax*`&F<;E(brt($I4sK(6>*_?I`M4MJ8Yy7K|AM=IU zzoPuAau2|Jhz9IGlLjI3o+ka8y0f)+vd_((u$vGNk_|mxQVBiJ=_7jjyz65#`H|Ol z8JrdMG=4DI4s 7FyqVXxzlJw<)Gu_oV<##Gl@&(pV4Tk1>~L7($h zs#@e67kiG=HP*^ q&=8ILuT#BtS2)Sx(WB9<*g2&r;B +hEI2Yg$CG#Zv z1PEW^4drM!X-T0#npV>@32HkB>(Xcwb8tE`pwcosw4~htcgp5O#l g>9fTrT zI !IPWbBkWA=)GYDlJ{OZ68MSb{33sBp#(9+;xl3ukrdUb+B zkq2GTVg#V~yZ4pq2ByN?=va*oBFGF#Q|jv;mT8DMiH4ruKbXvJt}a8cUI#KL#kw&5 zT_4T|)oV$MLWc12qGp(@_=I0db__zrK^*{{In@tDT75dz|J3?7%W*L$wz!~z0P&_i z#>NV%sEEd)0wq5hO5ovHBTj*s!h`Q_cQ=KE0%e(S1JvuVb<7in8t=G0wzWy{IAhK; z@L0hLoF=%f_b}nXW+Nc4f}E1vwsO=jwq%4H+q5zS4}+U95kz4(rz++`9WI8W1F%0o zd3I5A>ZHJyG@;eOSPB}>m}~OMxc*zL@_K{Q{yv$j+&NSZSMyGh96T@SlUGaJ504$* z;86RD23&KRoc^5bF`P~!p04|fJ{oF1TH&;@S_JRGjmAWTuTX~9? S_@+squ4rw%=uY|H}C3Oi-Rv 4D@dR~!!#mcTH|TJ-k8=$k)=0V8^?ti3Z9O9EEx^YN=Gw?J5qbZ zKU!0%cof4aLv3=Nz>+~|t?=MUd^&3YniT~^1pJ3b)=BLR2O<=#H_uu7>1j!{l;lN= zIQIRe5?|(PB;ezhE_TVU{TdK9`W=!T6ha{60Xhs_grhktA3bV5VdaNqZ9>eCNhshJ zPnk2?GDE9t&wV)6W%OBHr9GJ|N-^H LrlSm?>A@U>G+oygnX&W%|9;=}`T1pFJ3r6-O203c#3~JbG*0e91G4Q?P zHwDfz>_>+R$1c}4N}9aC|S2mMB$Zn%JEBLL)27ni3*9;S_&YLp(P^|TLYKEx{n zIm_o|?@6WZZ;`g!?|VqLP*4FyNBhaikT7NqB-@yi-_~8!6~hDgme->@X*PIhV43u^ zwX7|0Xq9Qb{Q9)E;`g`q>Y08Z5wMU(drSj _pX>=TvkWAmoxr~m~31Z6NIop z%sEkO&%&y&)zXi8t}G-S;=}lGc_dvNP7Ur)-Fd#lpvK+@8__B9Y~UrwE(GSefS&4F z7>daB#KwWogqX9|cgV+$hF9ugIw=m=#5hJg4Xmkyh`1z{5Hy`&n )H6U zp|V_k{FEm3^wSH;;_uGCj=k)kaNqN)P>Opzu31oX!BusA@$%dt$g0DF)g+y4Q~(r9 zDgix&ZJ*4;0L%-K!ZmF|G Z8rM1 zOcdho{Vuh4;&cCKh2s%r6o|W^xn+%nlDcBsT{ e)Uc5!(p+Vt(sn@^FoTaj z6cT)h|LW;*xw~3S;uRpA?F*iSUexqh^r(9Ds(PpbU0t>-kVL&ND5C;kS4mCDcNxv% zdinB5CKEyzpN3VDpA{C`;sU;VA2*l3R2E5h u< z*j$hATfX7tzFRGa-)PFVr@Ge$&^!-nR?NP(o2cJHbBG$wuy+QwO%R>1&A8+(1ydAB z*xQa>w_Utrufx0d;oyiitN*Cl{3&zq3^{BX2ua=h=soSPP2PKh=Fqu7*-b_aFeF3Q z#<}4`q4(lSx(cI%*=P@3U5qZKR0`Awyp=s;4Cvm4$rpLV%(b;W5mc=UE%EfGiK%F; z>YZ!M%pH2_@MLq3FyYjy&=U1!NoK36%~yx{iE-I_t93cua)lMON8G1x#xLvFEzd2t zvQNSX#V&xU8Mu>jPsn}TC4a1Ko_N>!)skNCPO>dy$H8^U(6OrK@_cH#eAUs#d%p|# zg`3~;VNEO#Tab!OA)w>dB5hTG;5wFf;9!D_o08=rzLJ7)p{-fyZ>4aU3Q$d65P$!~ z=nMB>t!Fs&`zhju%x#oiY+oQ^x7}r{_>%H9{F&j(fXp|>b-_8o&Y+7`yV<6v*|Tcq zcV0cI{AuKlua!l;z(N}9KpXvNx-tk80g!5-t!SwUj+znWCn1KDKapw3nfQ`2{B4!6 z0e|*>sqR33$at}vSYl!Q#+PLo%ev(TkqH(%AvT )se=P@-Wsh-D-#Uhd=b@fCF zw^X*O8}B2W&VAi@V ;kdWK`O4k6}+=ye-Nc<*p>%+ zrSThN=bF(ON>+(|+bks?60F-C02+)hn%ekjmY7j D#X1PN5P?)pg7AwNqp)=5QQ3hL1hZoxHeKvbSJT D4z!kkU }et1jL z&I+0+RTfM7y&?$Bu*y|1?8|u*pgGJySIFPyRxXoqr9Dlp<*IKW7N4`YL>3M8 zlBOwvdcomBQDA6<>^|gdT?VKiw!6}Sq<<5g?1ALC3RJwLmi00VvEhz!Biy+jN=ux4 zt(dMt#Slvz4EG1A=ky?ZeFoP*y&{dwRW~Brzh!XSLVvB=K>MYeF6*$KNvLv8XY!Xw zvg8)g&Qz9~$LpNU)6*5zTRuwnBj2>gDt$b1ZR57UO2e|)yET2E3xeWvMlkqFnm9d& z{lu%Cs0WWgr(FW>rdS}%#I)JVWf1dX@6VJ9O8^O$Wdd-q0V!(%7Ni1*i;O80G`|)h zNHEe-^d1^|$xGv1Uq Tuc|>U^>b?z{f+`7{o5Y@5+XJy#2U|^zKZrl;3l+!Nr^E zbuD$Nzth#r*SQ(2*s7coxpYR%iCRd89xwBq`vQ++yl5x_2EcS3K1cVC9I<5;t=93n zV;V8g{PIj0kEulAe1la%HKd7i1OK-u!C EP0NPfHG-%laT+fwdAzcEG_>J-f1ppYCdp-HD~`^cq{mM9oGf{YyT z=j;BNeY#7U^b5#)5ZFtnCO~&OaiGk2QGVO~qd>K =OaHg%V*RPTmOhI^VMU*Gmag!7!5nY0xczq5y!i12?)uChi4tsWX`mkX)Obf7C^P z02ij0Eab;v*~+o)H;`Q*7{CV;pn(j5xaqmdACdh(m&w8eMyRkI4;rfc97J)^i?_Ey z2|Cb&i#h8zZ9lvEn|uG~)fO(U7du0OlnC=;QUw5(V^;(`{_BFUYk^OOz0Uu2tzksJ z52D2(h$s`E_fXjXT(_8yK=S|h0tbMutoVXS1i8fXM~VB-MZG>!`+ n^oPSnO5hwcfJz8W3UodcuNuND! zwLh(1A#~f={$KB!2~oxxPyyBwF5^b)k+y0;II)9TF|0spSq~WDe;JO!50*&i@hhx* zr-B=B$NuYl3lyN>!X70@ged^l=z!v1SBm?^2oIgJ*@)eiq;{muOgjmdZbJWS)ed`f zz$VzVVFL^Y3fLM9HF@^${lJ*t!2_cc94N|Q=<(+&8Q@HJ&evr$|I^f&${wX-U-rB8 zz@F>xw&b71=l1$@a6u8`IS+m*&Tr59`{{Lyxx{bm78n^W56Yw`9ZKuDANiklp?Ei) z9qZ4IK>qW8HIS`9ta|}?NDsR%|I<3|&Jf{Z_;mY_NE wt(}4nV~ac(4d2tND`odvcd0= zxG58u(|`CKDLV(sj|M 5UECv&y8g}zpFb#z| zU#p1S_!uIp!YVk|8fvH7S3Sg+v}jvt*is`-U&2VYlLBUb9E0&G)CC_TQ}qp_*jKr# zGO8QsYObfa6sy!L#Yk~HnFyNMcl24v4XJ+DugWV%Z#8_=iiL(bSx0cJ_Yh2E`mA)_ zFR{Ng0r2scENs}3(z3-SNdf1wO1#zHXr;KUmB}|ub&*&>ik-EWYSh>=|BT1_2s}1aV})>LlFds; zTn)bW#-;x*nx$*__6W~mrMT$QIG9+VIH+w+(&-H1DSQ1!J;$JYs&!?iI!&XX({A(< z7!d_pk5G!D+T1wLmA-pe@? 2WtNIAR6_`n~M^az=ggD`w!zK6Sr3 zMeUn{;YOe&;2-oKFQ;L4$HkUiI?TA3r_~3Z#U!(llds3b_vw+=7n*N9)}y>r@D0}N z3q&%Ag@r@n&-O+KsJI zh0b@3GVNwxR$ob-=Gu}0U90fw6j>*r5bU=6s5W?~D2FP2wM?OXi`G2i&w*-ZdK5-( zK;|I@96Pb;kB7?XLexMsr|4EyAJ5}yzIbZUb{71Kk}5CMoEP=PIOg#GF!z>mQ8wYf zxG0E m&*y*MoOg%& z@x^m*&CXnN%{AYct=|WTGLXs;c}~X%)>(BorL8erTRq}$H^;9wZ6%;fiVcBa(e#as z7(2|=xy#XA0?9|6@n8A8d4mnKrpLMS#QN)2-Il^~EC62ssorlhqAaF44rZj1fu-LGTqX$i2pATb z3VrZb*0Y(M&JA#y(;q&5tnnokS(|ec2=owC5xh-vcdXWo=oxSvWV&WA*J1?p#L|SJ z^$_hfE%*6Kz@R~->=i*L1Cbx6OAX%pwBbcNXuY@b-*+1Pn*YUcZkZ8y6S&_Qelq^_ zuTb~|?flFXsO46_eFRF50C(h2; Q8i`&CR8;x)d8h zM_#QlVn?EiU!YEWXu^udrE}#LYQRjI^Yhq(?+qI4OGZQme2(0b-_wUNq$M=|*79Sy zzU(*z><;ds3{N#;NA8x?!}a(2!E&6x>%N#aM;c{P2yeHBU&(ltN$EEbK=R!`8S`z~ zKh-ZxVTOXUn^JdUtn3;`HOR|Mcp{1R0PZ^EZ-EwDPIGWv@EHpd(32@UO;3cE8~CQVxBh z8(nE8a}Q+zexNhYktfUbsk%a1S^;#St;q6oLBambd|>|Uyh5X=br!3m7J|1xf$4TI z _7Ug%~;T*8V(miQ&{3Doy?#iEm>`zNR&9Z!J&bGdNW zGvcj&s9?-vJYnjtN2}c8ox$X91!;)4ZG%{giF8!lvAwUxqJmS4TE}e)npvS?LAz?c zMgpLcYdxo;M2OLzRfbM$J}q0X$hoM21I&aXbSOgO(Iu}M*hIB?^JNS2)Y;;HGLBrp z!Ynyd{(Z^olG|VRIlJS1fUDpmk$Y+ U*2yK9h#s_T0z0jK6)daM&xTbI=OE z?BmDbp|jiv|Czl`PNK}Si~Tbb_Ga Vg@Z)#$YZ{{S%JN4&nd@Mj_e}Nx+UK-$$ix;OsUI4raJWbsiE>YB{HqGG^<0y zz$T!~_=Duik@+K?9Y3=G#qBnx$R!6|W+j{C29sBwO7}^J@L=V-aS|VR9tq>Nji_2E zmy3t!N>b(?-BX`>EgZY>squX?nC%FT%gG&ybO3Me^`P>%bms>GGB(NWCL)pjxHb=e zk{E)dPFJ=%ENb`zF?n8D{Ib5R>53b1G=(pH=TS7(%m#!gWj4B!>?1y&Z6az+HfD$3 zE%oI&hi| 5k3stR+im6+{I)R07u4#XG5`Y)2nTP#H%;T(`iyu0Yz{OS zkYkS>4`BNnG#f8HpLEywHM#Z|f&&&T5?p(2*7#iVHO2S+Z6)$eJ_6N!WEH6xb5-c@ z0A9)T|7PCQV=h$ow@|KF=O_p2$zk)rptYeVrK@iN@MPR`z?$#^ZS)5Y#Gnux(z`MY zKHYe`bTOEsMMu&Vlg(_ aHf7zt%)*bd? zEZ7jpQ1bvx&{_LaMKYd`-Nn%bS8FmG73`nEGho1(nHkl-)9eR+;%IX+gWv6eD+_uu zP;N@_9>4b~b{KOXj^O&9lTDz(>+;*IV`J)Q)PDBCk@nG$_&U#h>N*oz;Ad^lLsR)M zv-ZpZm|$ZY(+e^SU*xO{CbkZnnk EmlRN%Z7sFk!JL9>Y*|M^^3G3jbp-crHf+Ga~pQ?V)A^lP~)#-#m_n-Ro zq#?RzWjjuk_5MqO4CK%kdlEXJ)~43Hscw)#k>#--M~uDzPMQF XHw6Nd)tx)e)c|y z6$_+T`C~zN)Pnq;yV2b;I{i=ojFksZ<5TK+ith-TkEJ?KZ0%XRM}tYU_?q}`?gEEG zalCAZe9&|LTGKJ61(-5#>o`fypDW?>sv~nm)@-a?O%XR_fZ~{#pC?nD^ME4{q>F=Q zV<{02dOGN@ks9UC#rE{A#Ce+U=IweERz4=`#K5jeSpY@fpOqm}9jP3QK 3eY?(PW-1?ebx!dEXqS@w(LuFQUpUaZ5ISH >bmplaytJhX*E>DNN#$9hv(tO#2C=uWA geE_V50I~YuIv`pQMPZBY_S`@MYSuhyr3V@~ zc*JSvl~($XM?kh15=AccJUYc_CYDYv5J+1oy9m{B@X8(aPDZ7>F1CSr9EVgL#PDx> z;0q1gn944XU931J>1EQBalUi5{beN)VKSGUs3Z$7#HZgYJp=S4VA k)9p}HlSws0MC&_ zU;Z9=M?v{STvhX`I$GCZc8s6{Q3(YvOMf+W5MdQzA6 N@7B@!H~38-ZMmcyymAXE^p!Ez7JK^dt<8k}AjWXWE6uA>iU@TQ$XGv|Dc z4bKtKv3)Crk2TG?Jcmg# YeR_bL`Patj(`(s8##_C7#mYSDH25tfKbF%!y&zKZjV&`LUmh!N^_$m!E>lgy z*Z5-we^i9t%6=_-p2eX->}d)&e5gpEmzsC0&Z471ho^rxm-W6GoiKY`VPRXAWk__u z(TRErzl*)iZY$+FXxjcy9S!JZJC0`V)F(3YX{Pq`;WG1_VW_dX(caZNzCinh?i($D zDyaxoX;%WdRBGXFfvkJ{)o$=2IL8Kg@IB(hfrk{(G12>!S0U?6(mNq$YFIVqtu26J zpA#H^v6~}6Hk?&H)A7o)?h;`WdWg+$n_8qeL3TN?+LdNk>VgIq@ZCxZIfw*@8T1D# zkHv1ska?Ft;TmM-n}s3py53tbGyKlr_QW=$kL>+1IQ$o3k*&zWsWxvVI4%`*{IUMv zMTHztZxUgyKiG8_zbgR9eo(OTnYF4&9!o@tJ&ZQK4+E01LaUv-N9a?(fJ3g1oGntW zYWsnB@JQ``=dG<8m%!v*qm?H=eMy#C=J)2UcRj8qu_tYYoCtmB5NwD4_%XupiSS{A zDTN4LV1`DgfF7Nq$mcqg^fa#-){(Cbec>FP_(MOYJ3WKWce&Hc2$k)Ajit3KnE;wO z|H8z<*?Vi)MUWOq53q|3u3)|S?Q9Gfpo;AQMy%ap-79dyOopHX;e{hv*3+$?DbLSm zR2MIgXF{Ern{r6YK_+Qmw*Z(l@I8quP2XoH<`2H`=CZyDR_R-5yXUPQd{nBHd^vh&*Ady^+ z!62ysUWsQwg-FRT&?+PRw&Nj5VuSUMj0K!ATKu->fFoA(u`@AZcDI{pNBILeyT~vw zG1!_&*bAEQSSuF?0r}O)(pWg_2jdm|u`|~1vm+*;5qNqc`OJ~?yRE_Fh+`6lo0IN; z(aX52_-OAood4|Jf6z^*4$Fv z@%5f47!bdx%Nfldcq`2vB7{zPA{rY&9Ksnv-mY?w@&Z)>M+VCv?qd2F&QR8!mBXxj z<*mj4yc=(9_Q=yS(J~Slv77-}_dgKmefH$jrz&;k6G7-mk2b(jO>Ps3w6Ob8D6#{D z{Ldaw{* fJ>Dx%HUjNoDWTyKUg;t^eKGS<-jo?A-GUKSR}unv*QEtRW+?WiNCn zGR=N@w99Z9l6q)}TDyPf-w7IbSg}Yqrl(Rd6z)D|(W_C5-ojX}o7-*Uz-*a9=lDj? z{4+Cj>Dk|k^Ib)egj=fp6p#Hq#!sy&LF9b|kfchs9k9D=<;>1+n~%JF?xwoz=TST8 zyUklOel9Itw#4QG%Fb@3$nWxueatiGKe~idhiQ?HO9Xq~VCAxLi!J GYEAaY*BP%WRDD}b(_D(PKL1ToVGa6@q|7{pg0lu)pa^*UNS zHVJ4=0Y@2NO#ft_>dCYkW-@9y?a*x)8+27YoKlzb{$@8w013DUq^F9&hsG10gETK4 zg$AfP&;E^Ix{Io))o9jOjMJ&B^`Q-L)RqLC!(5nM2Duk3IbfQ;`^qQ5p#n9I0fNnf z0rf@xsAA; (H&dyz^RxyQ7dGLlt62&) zS1~DfX)XUAlmeVw1Hq6Y`(u9x?yH^WTeU9UMR`--H>IkMewEnj{8 zojCfk=E5M)sL!xhg0sZc!@rz>!bhR6hQ zUGZHL<-=o3U>Xf_f5OuvuZj(UqXBU=QFirmO~dL{cTuyR7;w<8Gc0*Xj(<06T)~<4 zZa8Hj3s?X<>Lk`Vj~rQ7AMXm-^zpk1pz<>hus*;6a6;4lYj801D?^=C&)zGYlg}Yn zI$SnP4!Z{xOOV{&VD>g2E4SNA%ekYfvmFGfxZ #E!*7-eQ$jb-1-0pOkY|?q)sL zf#4!9&3|~=xpt32?7{$?cT?C^qrTY+a@xPhttvBTijEKXJY(rONgd)c$1>x@aDQeL z|KL)Srcj5W0>ToR)NW>kO6}~(bN)$G4y(( DOB^sy~>f;Gq3o32304u7c8do z#>FP(DON$$(I)ZIzZ@8Z*~10yKMn`cX@n~>T&1r!Q#gqIN?m%A9;FvxP;2n?d_Lex z1xQR!*GL$Q9(um4 F#d@ys!%Tzv$d=QGtjZUIVbX+@ge-$BjbsG&Oa%67_EGg!4 z_#|OHA%PO=mQR|``iHFJ{TtKb2csv{zK@K+rU |h+oc!K@*Se{OplyJ+l_ cr5E= NeQJzrolG;JTOq zNmDEB2f1X^Q^Ot`abCl5861!KTT9ROvH9~@A-TG%72bGhNROgS0X?C!8KcTz0(tU; z-&h$Ez>W;L^H34~$dEwQqEc{fffbJMoRR|r3&L|6j`RNfR{L9O>CL0xmd>~1D5rzD zmSsOohPP{G#k1P-aJprn^gbNZQ~$Wo+%-mt&5eEHA#x9f{DesTGswaev7c4|WL7!+ zEnalpPbTiuk&cB!z+Mfu;MNS>cVV{%f9m%faI3y&QxHBV-RAS`kMhAyL8~9mK{ccH zgGTkOF{Y6-6sU8I@4G1#Vwq<4O)Lca$CAGV4$l(LogbcW70l;f73nr8nq|^TA0x>( z0|^eH``oL53Svk1M<=!n(A!W5RxbN#K0!?y)ggfFU#hDG*bdS-0VEdEUsr07Oy?`d zC7z-K2w#>j0`l&dh;#CoR@2-r=2{ l^k7d_6-^i7~BDQ$s@V3813rYS^;A0M{gX-TiMLOyhyORip;gnu!0i?+{(r3I)v znjEWT*mAfOOl*<04Ehb|zKZdd;KpC1<61oGFjs=bzZRRyGyW0`9k)5gKhT_dsmIf8 zx-1)nK{zdL#PH00ysb#waJlK>XPo0q{ODF*J8%|E!nO>l`8or(0nagtrwX)^{DEnR zN%OX*?!mh%4V>xv%f6T|1n4L)->L;Tlw&);IIU)@eBS$wmNX(Ro5x6P1JNaySvV89 zj5wGl7Zoo^m@V~Mp9=#*1M-h8gNd;~`2r-j2-81<(V-9Hg({|?rP!k&cCuEn-c;b2 zAMtY` j)FXbfHQ~IzvTaQwCdu3gVunt09aol3iDv{aMf4k z5>Jy>J{cE_oFyd*TQYes)H^rXaIxudS?n#|37T9`Vn5?h|Fi-WgjvIw+ExCA{#Qvg zaC58q_Wf$iumI&E12mY8tdG!b2vR4vH@7sknE!(aNI-ji7@o;!6tkNDkoolRf%&%i zbX9Q`|M+BoF+YDlZ~u#giAfjvEB9O9-=N^)+{Z~hao?#h|EPqDCySJ^pKaT%u^RGt z&0@pj9bG{{a{rIz56YsQ+yN!-HOF(M1Bs8rC-&~PN$ojpWn&(TaF2}8kCy#9=L)si z5Lk` Jq0ps;Bi7) zy_mD*6KWZe#l>TSwDx+ P)mHfT~n`#i17nFMB&qeRP;$IkNFzef%G;DSMA!_sts%6H<1F^xpZ*mE_ z!~94j+{3Rk2s(Nmb^2kse7Z~!JmP~Sd#$i`#p$0iJ>Bb8y!Sn+%0Mphl)4mOERwf! zpMBZBk#pb6IHrs0Q5w9o@E16-ImyS1uJ$!5q=!MT$L~=k_m!Hv9hG<>mp?hXSj;`B z@(ABv^vvFI$I)-}pQ8L(9`D&8nk(_=Kdfy#*(z)N<`cv1RE?43dxe6qgaAsM-t$`Y zR$v#S#WHOvn{L;%uDs%t2i?xaf9_CTd>&5^z(}<_=eMkiXPIJ+mOAd(&(c!Axb! zE*ivk6{xe5ZgG}T5lT&JY0}-7nobk)c0X=1^BwN-z`qAIrE+ 1F@mr6Az*M8wErh9s(0Cgcd^g3)?@n!gM=53AC$=eX4sP7Ee z(z^)!IOZoGi;1>+OfjoN#MLpLMY8u(SMI~h`Gt-L{I>|4b_^|Dw5;qGI#%Z{*tCmu zNL4mMJ<-1W-i1HSj`%6F)Qx=W9R?N_Hn^B~y(Gw@&RrF3E-NU6xm?8}v(w-uHlFHr zVnfusDLlAXO>sTs;#{XIHPGgbD?DP`v#b1ILD_=>mXnurY;~*mQ6N`+UwN}BaM-x~Be(O^b|HMmhK=RE@ep-dMf$i&>&W24&qu|{xaiBDz33{i$YsC&vE7Y* zEmIdMo}XUoKh<@hQ(HlI8x}%hxjCUj@2}GXgKX6GZ$9*kEsnp(hqwAN-vkZ1^^^#U z{~_mG$P;bP6NXYR W4cTS#%9OBfyU{^c(i22 zVd?3%io1|LN1O_68_$oDgVwh3B$JjFEFnHm3RFVg<=on?&$F>|4CDc|OI-Ma#>;#4 z*<5|DtChG%A<&vqISdZRw&W!i?v3pSs1Vv yD)a9hO=i`sj z zUN&P%g9M F=qtW20?Dwta!}=SY58c?vgCZ4!~DJI;85{e%%d-X1Yb4G zwNK>>Pck~AB6P_OxwveTlFVqXbieh)@$7tYABEjgTs9s ztVO!nL{m(hfnwucxs|K$F5;b2=C(8>%N(O@zylWg!;5afyLCj>^Qy@#CiV+y7K l1wqrSJ%1eu{K&3Sp>P!Q9pZKb~C|La{-V@Zm$GUfQP87rZT% zclRPsX^P5gW!7Hxv_ sY^z4 D*ZTV(;y#2|u{*QD~&W|GYo56h=)_uTt&z1$z8 z>ANmr@s+lM_1wF!4uw9H9Gbk>y;_WuU*E{F972&GDLzZ&x(j)+BAlA7@$uqbom|-@ zZC7Ov-UTranheiv*qiO-<`?tWEdq9$ij5V4#8NCINb)@E&9AYsp17~rn!;7x*^X-Z zn&) 0K*Ne&wt$_ITG-;9PJ@Gm7EWS+c0PdaNBk zzI7`#zzYg4V}Dc#(T3%wWHv;Uh^A;_Df9}*t@0uoy<#u9kr^z(e)X?X1vxdutedvF za2`M}2dX6n{CkUygoa-<6FpyU&4lexk4-&JmiQtwSh;zXYH8LPcbA#mG=4I?*UVy; zD6;->{cp{Y^@m*XIzhccHGNB=)5wi{#a?s?_Eh>$k$N}Z^?cXiT57KD9e>CAY@>tF z^>?*=KvtIyu9*(5ij&6|{oAnIO0RTz{vzWw-x!b!ynSZViH5~Ux4%bM{;_1a4I3=G zeOk-?=5l(d*^)`JDa7o~_<_aZ2H_u1^>UiiM8W_DEAN`;9>XPSL(MM}UH2R8xB81} z t-x6oNc^unevT4Qn^a1^cMY4p@g!!3zk?s z?S(fv<6c0ip1feJW)HX3bOCXlv-r8*qawCCeeJas^E IYci?wY$P69=NvWq^+*X^O3#14=u6)zcfUodbx2?`aF97aJ#R8#7O+W z$|tOzWNcccqHDYS%k)$M-5pp$<+LR8)PQH)x_bs%TyuazT)9 cu$@i&bg?4FI?&Ain}dpiQ?+w_HMs* z8a3(5mD%8*a+w3V-%QT8&P1BGmu0O9_fVHcoVZhO7F4ap>tY=vl>2 z;-_*EwLM6o0y);}OFd8;E#Zcd8lm~K&HSV|46{M&S(^zjV+&!Y#~DMm1S#ujleELN zZm~8(>^6+gkOv1@6Qvw*M7MnG)_mP35(KOE^XrcAHH6qtPtamwJs1hdJSo(kt{=bF zj@$RjIGhmM rDA`af#jF^W`$FWGum!1vU?pCfA8uN3}EA(3}&Sskw zMm2ArhFcuBp>DnHuj}F@52#`dP!V9r>1#i>!+grLEu@!Tb`GM@r0#>szffX|Q`tiC zBQqDYs_io4$J-kX+;LMN!G=eDK}=Jyi#V$&f-ad$(jW%JPJ1F1g-e6M{OPiAWMEQ$ z6s=%E>tu9?zL@sGHtB`tt1m|@em?~0ty>3l)bNdjQeB<0o$q2=twy>Wh)VWYtr$Oq z;>*q4zolAz4~n>=+=Osf==au}g 1EAJ?ST7;} zQR|Xw rFtC>W;21Zy|6?USNGAf%74_>2PT2yqUaJ=<(xmUBV(X<+1$v2GY=#Y2f zHFQ$fuoSxAgt`DX%vKf;kG0d ;6uec6H{jDHYlJQ{x)fWly!+>?=zu3p=R`y5tp4C7=C1uciOP$b4`bt*5XE zk$*|&u29-of@Dr{7h>R@0xLOs3Id4CMt{88#)RQn#5mXk>3iy>=d?0L5sN1;ynK*C zc-oIgO>DU})LyZ-z&JWRLeID_t*>B`aME*^@Wje<-=fp26_%ln`326Z)A3%56^8ks zUH_z+q~drpI|9_^AO3jEhMDguo3v0)6;7;uFxkhlZ;lCJe&Xvz*Zd)OH7aV~bYH45 zb6=gCgSNTkthiI2u9UWUVRqfb;&ENY187+Um+|Ft-zvZ5s2WpI6?V4XOH)!ucJQN=K) zdsUydghhqy7Wea)(!TuAgI0tmdHg_mA!U|7Yc W7o9tp zE%%_XqxBS#bUutD%F2sP8&Qc8wmPA^RvxKD+Ll$Tg(trj!@xqlw}6UYab%Zf&VYVp z*qvL@F__M{SRc0`Mu_FJOl*;8fC&q%hx>Y36}3yz9P!U<()CZOxc0HPJiT>m_j-qQ z=+(M}7YGYjD>D<#_aV%=%Cn3+|LG8ipY^%q75j!&kF5zmg@ #k_^CKX#ikP9?%EJ(*U_n8<^u#Kaf G)#Z+FFw!$AXlw@Jop`&I 8XCrBd>>LyyaxiLbt%nJnj4m&ZsAR2u+NQO1652armkd%o*qNCEf~9 z$8Ths$#9dmzg6V6Jx*TboOHgV+_H94z{`mCG++x+VrUL*M3P^qwz8$sTDGrIr@+*% z9cr&Uo{M}fa4AB1*Kfeao;1>5TyBXSk$n|I;yL20!2WcxS!Ehh6E)mxbr#n&HD;!| zH8;)n%}4WZPZwkN13Lu#$-=NG7zF?Cr{sLTkkb zFQW4oCoWpp&Q|#?UjF*pS1(^k-OFgJ FMH5xuBBTgVLZ zaM7_8aQ}hE*<+f-&sFDPNJqttBu}`0S67;z{6S(kC@FkN1-KG(zxwwGKC5 2{aUxkCHsew-P4<*~rJjxvGRSZB1^p0JBM=MYu{H z*ymc#Rp!&xeqY2;W~ZcmkRi9coQ3{EPY|J0bd>ULZE^thKn|JipQ>FbS149aKXV&? z5GPJ_w8<45XOP{Gw{Q3xmazw8c;?oB+@)Mt5yVBD?7N7H=c*srn8q)YkNMIvY770S z6S^y^b^m~~QlWMji@^smk2X4bq+gnt@Z16QLHp%7pR; }bTeO2jOF$?58JnuI$fIDs;eDv`Y5n9xrxEo*iNtjU-AD=1;ul({H7 z*~!&OtA{A_`>*m1{oFP_1ZoY#&9-jCewF1Ex-Q6$YWMS;fd!F|X__jD`tj}Oic{hk z<(kZsw1S!Agi6{9MRKWkLweHsF7`Yr*EDkw`8#agt_?HG(YS{1pykk{iA4?A8%{?{ zf8K#1i#|dL={d?W FBv-a19Y#J?tA#=*+fb#pWs S5-tPrMluhz6UIXh0#;#D#p-fvcy zZ@M+dl9mT9wq757 vC)>u5Q%lQD zO5|cttAjn1(4H2C$q{L2(d{@l-H<|7!(}cfQUJFiO0u;9sv=%ixdwEZv-jBH6J^lj z$(0X*gHOI13;YNg3RYdF8FV4j^ayWcra^I_XDIOVvkc;)HLSPBu@~l2G+?vmmsSyv z8wAIKZO$gc!z$}TYFPySB!nBZVZ6X8yfWKFQJ*}aHq>)*5)>$K{=I4=;hohw%V!jp z t96Ud16 v-tlx!T=E7$SYdMT+Y>?s1wr!lHK8lTPiSk$b$ ;5FQ>F#C9GdHTWt^D$+|BhYt~95dzHtZ a~_xHGJ7z z5jc_Ogl=8fU8hFX@!E1gj{~1&pz?iL?u+}-PQo9Z-NTx9fwXR3>zF<