From da7fd0d3e5a99120800b649472852b7db256b285 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 16:39:54 +0000 Subject: [PATCH] Update docs --- .githooks/pre-push | 8 - .github/actions/gas-compare/action.yml | 11 +- .github/actions/setup/action.yml | 2 +- .github/actions/storage-layout/action.yml | 3 +- .github/workflows/checks.yml | 8 +- .github/workflows/formal-verification.yml | 2 +- .gitignore | 1 + .husky/pre-commit | 2 + CHANGELOG.md | 65 +- FUNDING.json | 3 + GUIDELINES.md | 2 +- LICENSE | 2 +- README.md | 4 +- RELEASING.md | 4 +- SECURITY.md | 2 +- audits/2017-03.md | 10 +- audits/2024-12-v5.2.pdf | Bin 0 -> 242253 bytes audits/README.md | 17 +- certora/README.md | 4 +- certora/run.js | 44 +- .../specs/AccessControlDefaultAdminRules.spec | 4 +- certora/specs/ERC20FlashMint.spec | 6 +- contracts/access/AccessControl.sol | 4 +- contracts/access/IAccessControl.sol | 4 +- contracts/access/manager/AuthorityUtils.sol | 24 +- .../account/utils/draft-ERC4337Utils.sol | 63 +- .../account/utils/draft-ERC7579Utils.sol | 8 +- contracts/finance/VestingWallet.sol | 4 +- contracts/governance/Governor.sol | 49 +- contracts/governance/IGovernor.sol | 27 +- contracts/governance/README.adoc | 20 +- contracts/governance/TimelockController.sol | 4 +- .../extensions/GovernorCountingFractional.sol | 8 +- .../GovernorCountingOverridable.sol | 36 +- .../extensions/GovernorProposalGuardian.sol | 58 + .../GovernorSequentialProposalId.sol | 77 + .../governance/extensions/GovernorStorage.sol | 4 +- .../extensions/GovernorSuperQuorum.sol | 60 + .../extensions/GovernorTimelockAccess.sol | 4 +- .../extensions/GovernorTimelockCompound.sol | 4 +- .../extensions/GovernorTimelockControl.sol | 4 +- .../GovernorVotesQuorumFraction.sol | 31 +- .../GovernorVotesSuperQuorumFraction.sol | 134 ++ contracts/interfaces/IERC1271.sol | 4 +- contracts/interfaces/IERC4626.sol | 4 +- contracts/interfaces/README.adoc | 16 +- contracts/interfaces/draft-IERC4337.sol | 8 +- contracts/interfaces/draft-IERC6909.sol | 125 + contracts/interfaces/draft-IERC7579.sol | 14 +- contracts/metatx/ERC2771Forwarder.sol | 7 +- contracts/mocks/AuthorityMock.sol | 10 +- contracts/mocks/MerkleTreeMock.sol | 8 + .../access-control/AccessControlModified.sol | 4 +- .../docs/token/ERC6909/ERC6909GameItems.sol | 26 + .../GovernorProposalGuardianMock.sol | 27 + .../GovernorSequentialProposalIdMock.sol | 39 + .../governance/GovernorSuperQuorumMock.sol | 95 + .../GovernorVotesSuperQuorumFractionMock.sol | 37 + .../mocks/token/ERC20ForceApproveMock.sol | 2 +- contracts/package.json | 2 +- contracts/proxy/Clones.sol | 8 +- contracts/proxy/utils/Initializable.sol | 16 +- contracts/proxy/utils/UUPSUpgradeable.sol | 3 +- contracts/token/ERC1155/IERC1155.sol | 6 +- .../token/ERC1155/utils/ERC1155Utils.sol | 6 +- contracts/token/ERC20/ERC20.sol | 9 +- contracts/token/ERC20/README.adoc | 10 +- contracts/token/ERC20/extensions/ERC4626.sol | 14 +- .../draft-ERC20TemporaryApproval.sol | 4 +- contracts/token/ERC20/utils/SafeERC20.sol | 16 +- contracts/token/ERC6909/README.adoc | 27 + contracts/token/ERC6909/draft-ERC6909.sol | 224 ++ .../extensions/draft-ERC6909ContentURI.sol | 53 + .../extensions/draft-ERC6909Metadata.sol | 77 + .../extensions/draft-ERC6909TokenSupply.sol | 35 + contracts/token/ERC721/README.adoc | 4 +- .../ERC721/extensions/ERC721Consecutive.sol | 4 +- .../ERC721/extensions/ERC721URIStorage.sol | 4 +- contracts/token/ERC721/utils/ERC721Utils.sol | 4 +- contracts/token/common/ERC2981.sol | 4 +- contracts/utils/Arrays.sol | 8 +- contracts/utils/Calldata.sol | 25 + contracts/utils/Multicall.sol | 6 +- contracts/utils/Pausable.sol | 9 +- contracts/utils/README.adoc | 17 +- contracts/utils/ReentrancyGuardTransient.sol | 4 +- contracts/utils/ShortStrings.sol | 6 +- contracts/utils/SlotDerivation.sol | 4 +- contracts/utils/Strings.sol | 69 +- contracts/utils/TransientSlot.sol | 12 +- contracts/utils/cryptography/EIP712.sol | 6 +- contracts/utils/cryptography/Hashes.sol | 6 +- .../utils/cryptography/MessageHashUtils.sol | 21 +- contracts/utils/cryptography/P256.sol | 44 +- contracts/utils/math/Math.sol | 258 +- contracts/utils/structs/Checkpoints.sol | 8 +- contracts/utils/structs/CircularBuffer.sol | 4 +- contracts/utils/structs/EnumerableMap.sol | 97 +- contracts/utils/structs/EnumerableSet.sol | 49 +- contracts/utils/structs/MerkleTree.sol | 98 +- docs/modules/ROOT/nav.adoc | 1 + docs/modules/ROOT/pages/access-control.adoc | 2 +- docs/modules/ROOT/pages/crowdsales.adoc | 11 - docs/modules/ROOT/pages/drafts.adoc | 19 - docs/modules/ROOT/pages/erc1155.adoc | 2 +- docs/modules/ROOT/pages/erc20-supply.adoc | 2 +- docs/modules/ROOT/pages/erc6909.adoc | 47 + docs/modules/ROOT/pages/governance.adoc | 4 +- docs/modules/ROOT/pages/index.adoc | 2 +- docs/modules/ROOT/pages/utilities.adoc | 8 +- .../access-control/AccessControlModified.sol | 4 +- .../token/ERC6909/ERC6909GameItems.sol | 26 + docs/modules/api/nav.adoc | 1 + docs/modules/api/pages/access.adoc | 197 +- docs/modules/api/pages/account.adoc | 64 +- docs/modules/api/pages/finance.adoc | 19 +- docs/modules/api/pages/governance.adoc | 2092 ++++++++++++++++- docs/modules/api/pages/interfaces.adoc | 599 ++++- docs/modules/api/pages/metatx.adoc | 36 +- docs/modules/api/pages/proxy.adoc | 100 +- docs/modules/api/pages/token/ERC1155.adoc | 85 +- docs/modules/api/pages/token/ERC20.adoc | 189 +- docs/modules/api/pages/token/ERC6909.adoc | 891 +++++++ docs/modules/api/pages/token/ERC721.adoc | 133 +- docs/modules/api/pages/token/common.adoc | 12 +- docs/modules/api/pages/utils.adoc | 1425 ++++++++++- docs/templates/contract.hbs | 4 + docs/templates/properties.js | 16 + fv-requirements.txt | 2 +- hardhat.config.js | 2 +- hardhat/async-test-sanity.js | 9 +- hardhat/common-contracts.js | 63 + hardhat/ignore-unreachable-warnings.js | 2 +- lib/forge-std | 2 +- package-lock.json | 1243 +++++++--- package.json | 30 +- scripts/checks/coverage.sh | 8 +- scripts/checks/inheritance-ordering.js | 2 +- scripts/checks/pragma-consistency.js | 2 +- scripts/fetch-common-contracts.js | 50 + scripts/generate/templates/Arrays.js | 2 +- scripts/generate/templates/Checkpoints.js | 2 +- scripts/generate/templates/Checkpoints.t.js | 4 +- scripts/generate/templates/EnumerableMap.js | 25 + scripts/generate/templates/EnumerableSet.js | 27 + scripts/generate/templates/SlotDerivation.js | 2 +- .../generate/templates/SlotDerivation.t.js | 8 +- scripts/generate/templates/TransientSlot.js | 2 +- scripts/prepare-docs.sh | 2 +- scripts/prepare.sh | 5 - scripts/release/format-changelog.js | 2 +- scripts/set-max-old-space-size.sh | 10 + scripts/solhint-custom/package.json | 5 +- scripts/upgradeable/upgradeable.patch | 22 +- slither.config.json | 3 +- solhint.config.js | 2 +- test/TESTING.md | 2 +- test/access/AccessControl.behavior.js | 2 +- test/access/manager/AuthorityUtils.test.js | 12 +- test/account/utils/draft-ERC4337Utils.test.js | 119 +- test/account/utils/draft-ERC7579Utils.t.sol | 17 +- test/account/utils/draft-ERC7579Utils.test.js | 106 +- test/bin/EntryPoint080.abi | 1 + test/bin/EntryPoint080.bytecode | Bin 0 -> 21738 bytes test/bin/SenderCreator080.abi | 1 + test/bin/SenderCreator080.bytecode | Bin 0 -> 1217 bytes test/governance/Governor.t.sol | 8 +- test/governance/Governor.test.js | 38 +- .../GovernorCountingFractional.test.js | 2 +- .../GovernorCountingOverridable.test.js | 2 +- .../extensions/GovernorERC721.test.js | 2 +- .../GovernorPreventLateQuorum.test.js | 2 +- .../GovernorProposalGuardian.test.js | 132 ++ .../GovernorSequentialProposalId.test.js | 202 ++ .../extensions/GovernorStorage.test.js | 2 +- .../extensions/GovernorSuperQuorum.test.js | 168 ++ ...GovernorSuperQuorumGreaterThanQuorum.t.sol | 79 + .../extensions/GovernorTimelockAccess.test.js | 2 +- .../GovernorTimelockCompound.test.js | 2 +- .../GovernorTimelockControl.test.js | 2 +- .../GovernorVotesQuorumFraction.test.js | 2 +- .../GovernorVotesSuperQuorumFraction.test.js | 160 ++ .../extensions/GovernorWithParams.test.js | 2 +- test/helpers/constants.js | 1 + test/helpers/enums.js | 12 +- test/helpers/erc4337-entrypoint.js | 31 - test/helpers/erc4337.js | 22 +- test/helpers/governance.js | 26 +- test/helpers/iterate.js | 9 +- test/helpers/precompiles.js | 12 + test/helpers/time.js | 7 +- test/metatx/ERC2771Context.test.js | 4 +- test/metatx/ERC2771Forwarder.t.sol | 6 +- test/proxy/Clones.t.sol | 6 +- test/proxy/beacon/BeaconProxy.test.js | 2 +- .../ERC20/extensions/ERC20Wrapper.test.js | 4 +- test/token/ERC20/extensions/ERC4626.test.js | 12 +- test/token/ERC20/utils/SafeERC20.test.js | 36 + test/token/ERC6909/ERC6909.behavior.js | 216 ++ test/token/ERC6909/ERC6909.test.js | 104 + .../extensions/ERC6909ContentURI.test.js | 49 + .../extensions/ERC6909Metadata.test.js | 58 + .../extensions/ERC6909TokenSupply.test.js | 53 + test/token/ERC721/ERC721.behavior.js | 26 - .../extensions/ERC721Consecutive.test.js | 8 - test/utils/Arrays.t.sol | 6 +- test/utils/Base64.t.sol | 4 +- test/utils/Calldata.test.js | 22 + test/utils/Create2.t.sol | 2 +- test/utils/Nonces.behavior.js | 50 +- test/utils/ShortStrings.t.sol | 12 +- test/utils/SlotDerivation.t.sol | 28 +- test/utils/Strings.t.sol | 8 +- test/utils/Strings.test.js | 7 + .../utils/cryptography/MessageHashUtils.t.sol | 33 + .../cryptography/MessageHashUtils.test.js | 39 +- test/utils/cryptography/P256.t.sol | 26 +- test/utils/cryptography/P256.test.js | 86 +- .../cryptography/SignatureChecker.test.js | 28 +- .../SupportsInterface.behavior.js | 87 +- test/utils/math/Math.t.sol | 114 +- test/utils/math/Math.test.js | 445 ++-- test/utils/math/SignedMath.t.sol | 14 +- test/utils/structs/Checkpoints.t.sol | 12 +- test/utils/structs/EnumerableMap.behavior.js | 43 + test/utils/structs/EnumerableMap.test.js | 1 + test/utils/structs/EnumerableSet.behavior.js | 45 +- test/utils/structs/EnumerableSet.test.js | 1 + test/utils/structs/Heap.t.sol | 2 +- test/utils/structs/MerkleTree.test.js | 136 +- 230 files changed, 11375 insertions(+), 1714 deletions(-) delete mode 100755 .githooks/pre-push create mode 100755 .husky/pre-commit create mode 100644 audits/2024-12-v5.2.pdf create mode 100644 contracts/governance/extensions/GovernorProposalGuardian.sol create mode 100644 contracts/governance/extensions/GovernorSequentialProposalId.sol create mode 100644 contracts/governance/extensions/GovernorSuperQuorum.sol create mode 100644 contracts/governance/extensions/GovernorVotesSuperQuorumFraction.sol create mode 100644 contracts/interfaces/draft-IERC6909.sol create mode 100644 contracts/mocks/docs/token/ERC6909/ERC6909GameItems.sol create mode 100644 contracts/mocks/governance/GovernorProposalGuardianMock.sol create mode 100644 contracts/mocks/governance/GovernorSequentialProposalIdMock.sol create mode 100644 contracts/mocks/governance/GovernorSuperQuorumMock.sol create mode 100644 contracts/mocks/governance/GovernorVotesSuperQuorumFractionMock.sol create mode 100644 contracts/token/ERC6909/README.adoc create mode 100644 contracts/token/ERC6909/draft-ERC6909.sol create mode 100644 contracts/token/ERC6909/extensions/draft-ERC6909ContentURI.sol create mode 100644 contracts/token/ERC6909/extensions/draft-ERC6909Metadata.sol create mode 100644 contracts/token/ERC6909/extensions/draft-ERC6909TokenSupply.sol create mode 100644 contracts/utils/Calldata.sol delete mode 100644 docs/modules/ROOT/pages/crowdsales.adoc delete mode 100644 docs/modules/ROOT/pages/drafts.adoc create mode 100644 docs/modules/ROOT/pages/erc6909.adoc create mode 100644 docs/modules/api/examples/token/ERC6909/ERC6909GameItems.sol create mode 100644 docs/modules/api/pages/token/ERC6909.adoc create mode 100644 hardhat/common-contracts.js create mode 100755 scripts/fetch-common-contracts.js delete mode 100755 scripts/prepare.sh create mode 100755 scripts/set-max-old-space-size.sh create mode 100644 test/bin/EntryPoint080.abi create mode 100644 test/bin/EntryPoint080.bytecode create mode 100644 test/bin/SenderCreator080.abi create mode 100644 test/bin/SenderCreator080.bytecode create mode 100644 test/governance/extensions/GovernorProposalGuardian.test.js create mode 100644 test/governance/extensions/GovernorSequentialProposalId.test.js create mode 100644 test/governance/extensions/GovernorSuperQuorum.test.js create mode 100644 test/governance/extensions/GovernorSuperQuorumGreaterThanQuorum.t.sol create mode 100644 test/governance/extensions/GovernorVotesSuperQuorumFraction.test.js delete mode 100644 test/helpers/erc4337-entrypoint.js create mode 100644 test/helpers/precompiles.js create mode 100644 test/token/ERC6909/ERC6909.behavior.js create mode 100644 test/token/ERC6909/ERC6909.test.js create mode 100644 test/token/ERC6909/extensions/ERC6909ContentURI.test.js create mode 100644 test/token/ERC6909/extensions/ERC6909Metadata.test.js create mode 100644 test/token/ERC6909/extensions/ERC6909TokenSupply.test.js create mode 100644 test/utils/Calldata.test.js create mode 100644 test/utils/cryptography/MessageHashUtils.t.sol diff --git a/.githooks/pre-push b/.githooks/pre-push deleted file mode 100755 index f028ce58e..000000000 --- a/.githooks/pre-push +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -if [ "${CI:-"false"}" != "true" ]; then - npm run test:generation - npm run lint -fi diff --git a/.github/actions/gas-compare/action.yml b/.github/actions/gas-compare/action.yml index 23a756f3d..78c286c94 100644 --- a/.github/actions/gas-compare/action.yml +++ b/.github/actions/gas-compare/action.yml @@ -2,18 +2,18 @@ name: Compare gas costs description: Compare gas costs between branches inputs: token: - description: github token + description: GitHub token, required to access GitHub API required: true report: - description: report to read from + description: Path to the report to compare required: false default: gasReporterOutput.json out_report: - description: report to read + description: Path to save the output report required: false default: ${{ github.ref_name }}.gasreport.json ref_report: - description: report to read from + description: Path to the reference report for comparison required: false default: ${{ github.base_ref }}.gasreport.json @@ -44,7 +44,8 @@ runs: shell: bash - name: Save report if: github.event_name != 'pull_request' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: gasreport + overwrite: true path: ${{ inputs.out_report }} diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index b68fec649..3c5fc602e 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -19,4 +19,4 @@ runs: - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: - version: nightly + version: stable diff --git a/.github/actions/storage-layout/action.yml b/.github/actions/storage-layout/action.yml index 573564b67..fb68d5f6b 100644 --- a/.github/actions/storage-layout/action.yml +++ b/.github/actions/storage-layout/action.yml @@ -50,7 +50,8 @@ runs: shell: bash - name: Save artifacts if: github.event_name != 'pull_request' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: layout + overwrite: true path: ${{ inputs.out_layout }} diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 18a38b3c5..6700832b6 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -43,7 +43,7 @@ jobs: run: npm run test:inheritance - name: Check pragma consistency between files run: npm run test:pragma - - name: Check proceduraly generated contracts are up-to-date + - name: Check procedurally generated contracts are up-to-date run: npm run test:generation - name: Compare gas costs uses: ./.github/actions/gas-compare @@ -97,7 +97,7 @@ jobs: uses: ./.github/actions/setup - name: Run coverage run: npm run coverage - - uses: codecov/codecov-action@v4 + - uses: codecov/codecov-action@v5 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} @@ -118,11 +118,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up environment uses: ./.github/actions/setup - - run: rm foundry.toml - uses: crytic/slither-action@v0.4.0 - with: - node-version: 18.15 - slither-version: 0.10.1 codespell: runs-on: ubuntu-latest diff --git a/.github/workflows/formal-verification.yml b/.github/workflows/formal-verification.yml index e0475b195..86acca7f3 100644 --- a/.github/workflows/formal-verification.yml +++ b/.github/workflows/formal-verification.yml @@ -52,7 +52,7 @@ jobs: - name: Install python packages run: pip install -r fv-requirements.txt - name: Install java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: temurin java-version: ${{ env.JAVA_VERSION }} diff --git a/.gitignore b/.gitignore index b2b1eab1e..50f1bf5b7 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ npm-debug.log # docs artifacts docs/modules/api +build/site # only used to package @openzeppelin/contracts contracts/build/ diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 000000000..4738b0555 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,2 @@ +npm run test:generation +npx lint-staged diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b5eb8448..0d6e04e24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,64 @@ # Changelog +## 5.3.0 (2025-04-09) + +### Breaking Changes + +- Replace `GovernorCountingOverridable.VoteReceipt` struct parameter member names `hasOverriden` and `overridenWeight` for `hasOverridden` and `overriddenWeight` respectively. + +#### Custom error changes + +- Replace `AccessControlNonRevokable` with `AccessControlNonRevocable`. +- Replace `GovernorAlreadyOverridenVote` with `GovernorAlreadyOverriddenVote`. +- Replace `GovernorOnlyProposer` with `GovernorUnableToCancel`. + +### Changes by category + +#### Account + +- `ERC4337Utils`: Update the `hash` function to call `getUserOpHash` on the specified entrypoint and add an `ENTRYPOINT_V08` constant. ([#5614](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5614)) +- `ERC7579Utils`: Add ABI decoding checks on calldata bounds within `decodeBatch`. ([#5371](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5371)) +- `ERC7579Utils`: Replace `address(0)` with `address(this)` during execution for calldata compression efficiency. ([#5614](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5614)) + +#### Governance + +- `IGovernor`: Add the `getProposalId` function to the governor interface. ([#5290](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5290)) +- `GovernorProposalGuardian`: Add a governance extension that defines a proposal guardian who can cancel proposals at any stage in their lifecycle. ([#5303](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5303)) +- `GovernorSequentialProposalId`: Adds a `Governor` extension that sequentially numbers proposal ids instead of using the hash. ([#5290](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5290)) +- `GovernorSuperQuorum`: Add a governance extension to support a super quorum. Proposals that meet the super quorum (and have a majority of for votes) advance to the `Succeeded` state before the proposal deadline. ([#5526](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5526)) +- `GovernorVotesSuperQuorumFraction`: Add a variant of the `GovernorSuperQuorum` extensions where the super quorum is expressed as a fraction of the total supply. ([#5526](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5526)) +- `TimelockController`: Receive function is now virtual. ([#5509](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5509)) + +#### Structures + +- `EnumerableSet`: Add `clear` function to EnumerableSets which deletes all values in the set. ([#5486](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5486)) +- `EnumerableMap`: Add `clear` function to EnumerableMaps which deletes all entries in the map. ([#5486](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5486)) +- `MerkleTree`: Add an update function that replaces a previously inserted leaf with a new value, updating the tree root along the way. ([#5526](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5526)) + +#### Tokens + +- `ERC4626`: Use the `asset` getter in `totalAssets`, `_deposit` and `_withdraw`. ([#5322](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5322)) +- `IERC6909`: Add the interface for ERC-6909. ([#5343](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5343)) +- `ERC6909`: Add a standard implementation of ERC6909. ([#5394](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5394)) +- `ERC6909TokenSupply`: Add an extension of ERC6909 which tracks total supply for each token id. ([#5394](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5394)) +- `ERC6909Metadata`: Add an extension of ERC6909 which adds metadata functionality. ([#5394](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5394)) +- `ERC6909ContentURI`: Add an extension of ERC6909 which adds content URI functionality. ([#5394](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5394)) +- `SafeERC20`: Add `trySafeTransfer` and `trySafeTransferFrom` that do not revert and return false if the transfer is not successful. ([#5483](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5483)) + +#### Other + +- `Address`: bubble up revert data on `sendValue` failed call. ([#5379](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5379)) +- `Calldata`: Library with `emptyBytes` and `emptyString` functions to generate empty `bytes` and `string` calldata types. ([#5422](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5422)) +- `ERC2771Forwarder`: Expose the `_isTrustedByTarget` internal function to check whether a target trusts the forwarder. ([#5416](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5416)) +- `Hashes`: Expose `efficientKeccak256` for hashing non-commutative pairs of bytes32 without allocating extra memory. ([#5442](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5442)) +- `Initializable`: Add `_initializableStorageSlot` function that returns a pointer to the storage struct. The function allows customizing with a custom storage slot with an `override`. ([#5526](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5526)) +- `Math`: Add `add512`, `mul512` and `mulShr`. ([#5526](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5526)) +- `Math`: Add saturating arithmetic operations `saturatingAdd`, `saturatingSub` and `saturatingMul`. ([#5526](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5526)) +- `MessageHashUtils`: Add `toDataWithIntendedValidatorHash(address, bytes32)`. ([#5526](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5526)) +- `P256`: Adjust precompile detection in `verifyNative` to consider empty `returndata` on invalid verification. Previously, invalid signatures would've reverted with a `MissingPrecompile` error in chains with RIP-7212 support. ([#5620](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5620)) +- `Pausable`: Stop explicitly setting `paused` to `false` during construction. ([#5448](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5448)) +- `Strings`: Add `espaceJSON` that escapes special characters in JSON strings. ([#5526](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5526)) + ## 5.2.0 (2025-01-08) ### Breaking Changes @@ -37,7 +96,7 @@ This version comes with changes to the custom error identifiers. Contracts previ ### Utils - `Address`: bubble up revert data on `sendValue` failed call ([#5418](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5418)) -- `Bytes`: Add a library of common operation that operate on `bytes` objects. ([#5252](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5252)) +- `Bytes`: Add a library of common operations that operate on `bytes` objects. ([#5252](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5252)) - `CAIP2` and `CAIP10`: Add libraries for formatting and parsing CAIP-2 and CAIP-10 identifiers. ([#5252](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5252)) - `NoncesKeyed`: Add a variant of `Nonces` that implements the ERC-4337 entrypoint nonce system. ([#5272](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5272)) - `Packing`: Add variants for packing `bytes10` and `bytes22` ([#5274](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5274)) @@ -48,7 +107,7 @@ This version comes with changes to the custom error identifiers. Contracts previ ### Breaking changes - `ERC1967Utils`: Removed duplicate declaration of the `Upgraded`, `AdminChanged` and `BeaconUpgraded` events. These events are still available through the `IERC1967` interface located under the `contracts/interfaces/` directory. Minimum pragma version is now 0.8.21. -- `Governor`, `GovernorCountingSimple`: The `_countVote` virtual function now returns an `uint256` with the total votes casted. This change allows for more flexibility for partial and fractional voting. Upgrading users may get a compilation error that can be fixed by adding a return statement to the `_countVote` function. +- `Governor`, `GovernorCountingSimple`: The `_countVote` virtual function now returns an `uint256` with the total votes cast. This change allows for more flexibility for partial and fractional voting. Upgrading users may get a compilation error that can be fixed by adding a return statement to the `_countVote` function. #### Custom error changes @@ -419,7 +478,7 @@ Instead, contracts now revert with custom errors. Systems that interact with sma ##### Relying on storage locations for retrieving data -After 5.0, the storage location of some variables were changed. This is the case for `Initializable` and all the upgradeable contracts since they now use namespaced storaged locations. Any system relying on storage locations for retrieving data or detecting capabilities should be updated to support these new locations. +After 5.0, the storage location of some variables was changed. This is the case for `Initializable` and all the upgradeable contracts since they now use namespaced storage locations. Any system relying on storage locations for retrieving data or detecting capabilities should be updated to support these new locations. ## 4.9.6 (2024-02-29) diff --git a/FUNDING.json b/FUNDING.json index c67286216..0a362ba35 100644 --- a/FUNDING.json +++ b/FUNDING.json @@ -3,5 +3,8 @@ "ethereum": { "ownedBy": "0xAeb37910f93486C85A1F8F994b67E8187554d664" } + }, + "opRetro": { + "projectId": "0x939241afa4c4b9e1dda6b8250baa8f04fa8b0debce738cfd324c0b18f9926d25" } } diff --git a/GUIDELINES.md b/GUIDELINES.md index 2c21e956b..deafed005 100644 --- a/GUIDELINES.md +++ b/GUIDELINES.md @@ -6,7 +6,7 @@ Code must be thoroughly tested with quality unit tests. We defer to the [Moloch Testing Guide](https://github.com/MolochVentures/moloch/tree/master/test#readme) for specific recommendations, though not all of it is relevant here. Note the introduction: -> Tests should be written, not only to verify correctness of the target code, but to be comprehensively reviewed by other programmers. Therefore, for mission critical Solidity code, the quality of the tests are just as important (if not more so) than the code itself, and should be written with the highest standards of clarity and elegance. +> Tests should be written, not only to verify correctness of the target code, but to be comprehensively reviewed by other programmers. Therefore, for mission critical Solidity code, the quality of the tests is just as important (if not more so) than the code itself, and should be written to the highest standards of clarity and elegance. Every addition or change to the code must come with relevant and comprehensive tests. diff --git a/LICENSE b/LICENSE index b2fee8f21..367f411ba 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016-2024 Zeppelin Group Ltd +Copyright (c) 2016-2025 Zeppelin Group Ltd Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/README.md b/README.md index fa7b4e31e..60d0a430a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [](https://codecov.io/gh/OpenZeppelin/openzeppelin-contracts) [](https://www.gitpoap.io/gh/OpenZeppelin/openzeppelin-contracts) [](https://docs.openzeppelin.com/contracts) -[](https://docs.openzeppelin.com/contracts) +[](https://forum.openzeppelin.com/) **A library for secure smart contract development.** Build on a solid foundation of community-vetted code. @@ -70,7 +70,7 @@ The guides in the [documentation site](https://docs.openzeppelin.com/contracts) * [Tokens](https://docs.openzeppelin.com/contracts/tokens): create tradeable assets or collectives, and distribute them via [Crowdsales](https://docs.openzeppelin.com/contracts/crowdsales). * [Utilities](https://docs.openzeppelin.com/contracts/utilities): generic useful tools including non-overflowing math, signature verification, and trustless paying systems. -The [full API](https://docs.openzeppelin.com/contracts/api/token/ERC20) is also thoroughly documented, and serves as a great reference when developing your smart contract application. You can also ask for help or follow Contracts's development in the [community forum](https://forum.openzeppelin.com). +The [full API](https://docs.openzeppelin.com/contracts/api/token/ERC20) is also thoroughly documented, and serves as a great reference when developing your smart contract application. You can also ask for help or follow Contracts' development in the [community forum](https://forum.openzeppelin.com). Finally, you may want to take a look at the [guides on our blog](https://blog.openzeppelin.com/), which cover several common use cases and good practices. The following articles provide great background reading, though please note that some of the referenced tools have changed, as the tooling in the ecosystem continues to rapidly evolve. diff --git a/RELEASING.md b/RELEASING.md index 06dd218e8..6820d403d 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,10 +1,10 @@ # Releasing -OpenZeppelin Contracts uses a fully automated release process that takes care of compiling, packaging, and publishing the library, all of which is carried out in a clean CI environment (GitHub Actions), implemented in the ([`release-cycle`](.github/workflows/release-cycle.yml)) workflow. This helps to reduce the potential for human error and inconsistencies, and ensures that the release process is ongoing and reliable. +OpenZeppelin Contracts uses a fully automated release process that takes care of compiling, packaging, and publishing the library, all of which is carried out in a clean CI environment (GitHub Actions), implemented in the [`release-cycle`](.github/workflows/release-cycle.yml) workflow. This helps to reduce the potential for human error and inconsistencies, and ensures that the release process is consistent and reliable. ## Changesets -[Changesets](https://github.com/changesets/changesets/) is used as part of our release process for `CHANGELOG.md` management. Each change that is relevant for the codebase is expected to include a changeset. +[Changesets](https://github.com/changesets/changesets/) are used as part of our release process for `CHANGELOG.md` management. Each change that is relevant for the codebase is expected to include a changeset. ## Branching model diff --git a/SECURITY.md b/SECURITY.md index 9922c45e7..bea59e1f2 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -40,4 +40,4 @@ Note as well that the Solidity language itself only guarantees security updates ## Legal -Smart contracts are a nascent technology and carry a high level of technical risk and uncertainty. OpenZeppelin Contracts is made available under the MIT License, which disclaims all warranties in relation to the project and which limits the liability of those that contribute and maintain the project, including OpenZeppelin. Your use of the project is also governed by the terms found at www.openzeppelin.com/tos (the "Terms"). As set out in the Terms, you are solely responsible for any use of OpenZeppelin Contracts and you assume all risks associated with any such use. This Security Policy in no way evidences or represents an on-going duty by any contributor, including OpenZeppelin, to correct any flaws or alert you to all or any of the potential risks of utilizing the project. +Smart contracts are a nascent technology and carry a high level of technical risk and uncertainty. OpenZeppelin Contracts is made available under the MIT License, which disclaims all warranties in relation to the project and which limits the liability of those that contribute and maintain the project, including OpenZeppelin. Your use of the project is also governed by the terms found at www.openzeppelin.com/tos (the "Terms"). As set out in the Terms, you are solely responsible for any use of OpenZeppelin Contracts and you assume all risks associated with any such use. This Security Policy in no way evidences or represents an ongoing duty by any contributor, including OpenZeppelin, to correct any flaws or alert you to all or any of the potential risks of utilizing the project. diff --git a/audits/2017-03.md b/audits/2017-03.md index 4cd6dbfd3..d54174ecb 100644 --- a/audits/2017-03.md +++ b/audits/2017-03.md @@ -20,7 +20,7 @@ The git commit hash we evaluated is: # Disclaimer -The audit makes no statements or warrantees about utility of the code, safety of the code, suitability of the business model, regulatory regime for the business model, or any other statements about fitness of the contracts to purpose, or their bugfree status. The audit documentation is for discussion purposes only. +The audit makes no statements or warranties about utility of the code, safety of the code, suitability of the business model, regulatory regime for the business model, or any other statements about fitness of the contracts to purpose, or their bug free status. The audit documentation is for discussion purposes only. # Executive Summary @@ -90,7 +90,7 @@ We are still working through the confirmation protocol in `Shareable.sol`, but w This bug has a number of causes that need to be addressed: 1. `resetSpentToday` and `confirm` together do not limit the days on which the function can be called or (it appears) the number of times it can be called. -1. Once a call has been confirmed and `execute`d it appears that it can be re-executed. This is not good. +1. Once a call has been confirmed and executed it appears that it can be re-executed. This is not good. 3. `confirmandCheck` doesn't seem to have logic about whether or not the function in question has been called. 4. Even if it did, `revoke` would need updates and logic to deal with revocation requests after a function call had been completed. @@ -109,7 +109,7 @@ It would be nice to see how many payments are pending. This would imply a bit of ## Shareable Contract -We do not believe the `Shareable.sol` contract is ready for primetime. It is missing functions, and as written may be vulnerable to a reordering attack -- an attack in which a miner or other party "racing" with a smart contract participant inserts their own information into a list or mapping. +We do not believe the `Shareable.sol` contract is ready for prime time. It is missing functions, and as written may be vulnerable to a reordering attack -- an attack in which a miner or other party "racing" with a smart contract participant inserts their own information into a list or mapping. The confirmation and revocation code needs to be looked over with a very careful eye imagining extraordinarily bad behavior by shared owners before this contract can be called safe. @@ -159,7 +159,7 @@ Allows owner to set a public string of contract information. No issues. This needs some work. Doesn't check if `_required <= len(_owners)` for instance, that would be a bummer. What if _required were like `MAX - 1`? -I have a general concern about the difference between `owners`, `_owners`, and `owner` in `Ownable.sol`. I recommend "Owners" be renamed. In general we do not recomment single character differences in variable names, although a preceding underscore is not uncommon in Solidity code. +I have a general concern about the difference between `owners`, `_owners`, and `owner` in `Ownable.sol`. I recommend "Owners" be renamed. In general we do not recommend single character differences in variable names, although a preceding underscore is not uncommon in Solidity code. Line 34: "this contract only has six types of events"...actually only two. @@ -224,7 +224,7 @@ Transfer() and transferFrom() use SafeMath functions, which will cause them to t ### SimpleToken -Sample instantiation of StandardToken. Note that in this sample, decimals is 18 and supply only 10,000, so the supply is a small fraction of a single nominal token. +Sample instantiation of StandardToken. Note that in this sample, decimals is 18 and supply is only 10,000, so the supply is a small fraction of a single nominal token. ### CrowdsaleToken diff --git a/audits/2024-12-v5.2.pdf b/audits/2024-12-v5.2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ef138f7ec61f268020d139c587118e8b476f4cda GIT binary patch literal 242253 zcma%ib9AI@_I1$d*tU~S$F^
Tk`G0DleSRi#J_??-qJa!^o~#yn6Tq z3x3Z#*UM9m&)eI%&&$}%P!ZeP`NQk$h3@7eb72WmH+NcXt63GKu@!Gxx8$#p2g=Re z+mUw4O>SP^WyjOj{fd32yHj^J+QTQ80k5;nOBkUb~r03j40BvFiGRWGtgr7Xl(~>}2;l3lmSV=vJt*$@s+)vR;0mvRlTDIYufa z7}N(H$d!`Kki^U+TWm>1BAmX)Us(tQo28VJjp)H1m~qo@xSkMI6@|+U)H%%2-SS{Z zI8COPk$uOgbWqVCX(+M_n$BY@7pJFW`XsmqED1BuPB`N`VLgFaVBR|`_5J7YHggr^ zQ6_>}r%8{9*{9F4+sqgmxAf^lmc_!r`M5EFTK7r^swjY-YKT+xF0iHwH0*ah*WSSe zJ=L~Z-y&xC@@85l9qOtOv;w!zL51AO%Vj%ZiC~dj**HrDB&Jf&oy&BIAJq(3uD7HD zS%M@B{fR(MaMUSE30hq9>>HQ9MQK`e>7Of`2K2iO-FlM^>Ne=P^bG0M&M~lR7g4{B zJ|}&qIz50mhJsfuXLXFCxppNDAkbrqQeAmQnrEfCbe&-8CgiwsEmB6q@}rq{B|T bi=Em=Pb3!EV$Ir8vJTt-a4CYQa4%0rDbjz^f{M!j2e|;wsun8yft25 z;p5q@b@mC!DVqAD4 u>34SRx*SjTdkaAfZ_y|W5yCP5J zMs9x^r69a;r#3zI^UVx7bQGT?Hl=#hh(VU2TjyRN=0@W;MQMQ_Fz1c!K{uA2MmXg0 zf!i+3yX{}|l!?EE+f`DkNj}_-aRf3=Vgazzw@#>7nZX1iih<0ED1bD~p?p=+LGpwZ zff{E~fT+_!{Qi+vF@f<>O8ZUcQ=H9d{Mr2|3CKzV_e%Wz@^6|zG-=@JKRRaN&$Wvv z5Fb>zNq>p_)%_6pgXTYQii&HdO}~c`G=A&;Nj3X7%?t`q<$vPrau)v*L2$Q#0{VC- z|IqwT8fnnQ XohHrz&-Fs^{*73{&TIwZ^eJI{4M@_9Un4&!jb$R+<&d(L#FCC_n$2N z7$AQV{xOhW@|*i#X8%ZYlm2ZTA4?)|EecQl*g>)j--(Y6joJss{@6!KbypD^<6npE zR5#WXruDIrH_TiW9zb3lywi0`o~JoU$z&O=yPMX-Lk$YnqoRRmj}X%mJRptnF+f#2 z!~zkXpUg<{fi-rBLH?PJi2ABrA?6A5Y?L(pqdOuRn0 r>++eo*mI{w4BP_YaW|n*YF+cy>-%{2nH19R98Qn~L;r8X|mPwg1Fj@>K2qQ-tUy zF$SpeFU|j;IiJ&TI617^bM2~TFGUwqL}ReIQIs?h&)8r5W_?+PS)c$ 5yM t&={AN1V?S#5&(>nKOlV2)fb5h5B5TvrPi(BNa@azn9f)&WmWx zJJ8Zq= KK~+Tjq~65G@IAM)7y`pXrU B}FAy1-C3t&np*$aeXjE74WjRi6#b=3+ zc698pLOxA(UUkB@(7fTshRQF24VpF(By3!ggP>+X5t7A*${Pq4I4~FFzi7-u(D?Qx z5bbx#|Dy!lSpQckKLj?Y_x}RT>hcKOSAKH|d~o?D!Gg`q1q*zX|H<|LQT!*6``Z^^ zWfl~Hi2n;TEd $1}-4^8v;D@0hvbnm+_4+;L{SznKRhNhJXs1UA@CzHm+mUZ6Yd7wq8DyIf>8E zBdA45)}2yvmZTb)$$ZyAExNVy%Irx_!^B~H eX9y zWNxqHDb)1RP;p_UYsLiHy#xkIUg@)8-YNcJM{Ge~fTDATiIc@Zgv(J_VyJi9$|}Ev z!`gwtxSExq`8^6_rJ{3APE>HvZo4bQ^eAgFz&NV$HceY`9s+@r*zuWzBc@1&^!j_8 zx`Fi#872m)o8(A_PADRb$8+R9zZ*Eq!1^s5P~+9_AZT<22hwo+h)z%lstsUYmA@kp z?Y!4Z!{Z-)H*f@ZcW@xJKW6_7gbxf*)t>=D{SVw97&Q;@f9?G-^H={L{2$yve3XBN zK!giWZi&lJo{FyDeE;9sk2&8Y7ofZWPN3=0-{CvGh1)7?`7d0u=RiRJ;QfRDH}?l7 z_aE^adxe3^S21)z;LalwvJ};5GMKqmq-=}rr~G5zzm+h-Kz*WB^{m~@QTJEHPu`N= zau^z?b94xaYu=ommG05%gyDf#%S-K^tOR_Y3hzK=Zn%`fOtPSwu`#P#{KS+GmsG{+ z^2%~XnF%%vs#j+2A^7d~?&R&FH>8ubWMg*JkO>FER44DuynNrY?dKsTcMlxAtP2*( zrHqwLa1w8{oXr8QQ^WcgYEk4E9x*cr%LJ<^-`g65tsCKt1Hi68wD)?O7>IJ=F8RKu zOLRATd$}*;F=ZZi&E_h7Y2~T_oi;N1>G8PfIaGPfrkq=|+p~ICP@`0xxACcqYvW3< z>^a0S;;K2DW(tuzr7~NRKXn2hqRp1}jmvxO=FMIIO#2I i*?!O!{m2)gC zv3FCae13bW^GOo+XykK~3)|{!!@cvh#au@9L`|2W*ERzF^Te^6(C(rG {e!i1rBzFh zMvqMG&ex^chd0-I-y-(~)aTlt))br`CMKIr#DRx}n#FzqR-T&dyqR_H?vwR{tcjwD z4R)_;7k_oB$LV-ez>o(xmGb>$Q14N(@ w;?|sUhJ+1g&6O(_R5JWb)H; z-BX&%x{`VGQANAVW*=bHr-p^P=~ZFznN>SvOlAM6T%e!U!v6duvToIi>^`aK;YdhX zf6l7uJV+W*<3}+BwZ39#w!UIuaxI0xR4v7)j}VYtLdhfj7Cw!{5_Evc0%nHFB5Vek zLDU#1P3Rsdji~k~><@_0-{Vj-jK3kme?at5e?$KX`$GwVyYIK!Z>0}~eA9nZ5k5d< z0aN=^N#F+Nx7vSOAjrQ%g;`X>D6?kv?TYRz?25h}>iOs*1=oa9wgs{LM55L@5{0?p zw4r79pdWZELXZ)b4sUmH>N>|-(wSsB+r+0kGbfh)Z12O3_buM~yF^o8Q+y)vi5vEp z^fzDcmR;BF@ScUpjIEwROgBxc`yjoC@X#nGVwLiBj~<==to*YrYZvdDj@FGP`OX-8 zTh^`|mjxyF(LO8PL~@V*oyL%7ku^P!k%D6u7gL|cV>44h>jZdR#H+Y!P)Xc~2>T5i zE X}%x#`khU zZFAij?q0&rXbdzBk4vLhPqxqbMQFFVUEbgHTH4hvc*3pfnjS~bc*0{?@R!X9eZD#O zaBq03m93h{OYb(Dd> TJ$Hv?*L6_$geFKVg4B0zM%B94Byh{|$lo15)`X^q;Ull=4e{ ztNm8`P~gA0`8O2^ZY~#~ia(V?v;S24FAEgZ`%fsoE0Ec3FQ~v6C_Dr;JQv@M>rY_6 zT|e-^WN =&s6S4w>F8x@qm097-Al-f8VD?(CCs;5id; zHteKUGzF({+4OUj?E_>xGA8GvCOlHoyW1kChN4ZJg)d+WS3Oi#_TOHDXUA#%vs=J7 zFBHGgT7DI2(|+AN*gwB96i*HkO4*Axa^UnPAWd+6bc>yw$$4M$k@@PY^x3PMcjje_ z*PH$2{IvS oz==}EZuNNO }Nqrgk^8JuFemU)gQuR7RYWKJ#1Davzy+HO|sOR0`V#tTR6Tsog z4DjZ$U(5j)H4J+HhFayD*w8rH(n#7SDb0T@e`fAoeCW#22%}#3;!@ma5c7gw6YYrw zh%X6nXf(f>63kCP#Pz7p31Y0v=E1>i=~C0qn)_uF;;f@FijEf%9oZe{P?%QcPj)5G z%q^qM*oZunMydP$)zS>IoL5p NO;aNrCELU;R?_KB^AdNN+XAWg zT@w$+#|@8SYWA?2eaQmvtW5Q|MT%YVLKEIwSd(ipaRn9jnHhlLwjSKhUtb;Sf~%J` z&t{UZtGx}~Y;Ty9lQheB4;q=2j)0ly%Vr&mvv C`PGf*J4dD$F?ov!PS5Ot2a*Z!$Iq9&t~68L4cD7%}I~)G^NZS`4*# zd$y?km@TzyK)BKQgIDw<8)M^^BI26Gt%X3D>Xf*J@e1R&_fD0B_R10|T+b4nSLX>{ z7V2I`(x>{=Wg_mOY|f|TJ0}i?V2)qzg8(TK>PGQrrKuD%!s}J39WdW77RyTD60w<@ z$1X5~Uey3OK+JJQyzY-o79*1>oU{QaC3}Z^#~c=F)e>0z*p(YI)1$fI$mO_^mz5$G zD-C<8jO=4%(wWg@rRvE|4p1a {{aw^JF)oDH72E@o9rqIgKr pn_ZpAfSbvIHGE=$h+*YuaZQ?;i2|@WceG_-eO_LYcu?;-QLyZ)|0mwt_i8 zE`GHl{~V+&XZfzy(QqrtJgPYui#cVfzV4{$eltG2Sp7>-B&7C7eS?G8Xv~ym0-*ZW zQQ$JO))ZYw@xHrh S)B03E|W^?Gm?+x }^e$a8PH)jp5%o=*$3K*37;3beBrU(BEUXCIrbno9*VpJMC2%Fzc*l2p%b(7v z^&Wilye+cwJ{oWOVtvKN%3&x~R$;bEZkDr)1*j@ErLx)M-UhTkr#1^)ITWv)ea$!~ z`!)D^XyVLZbJL!?gp%>u(Bv7erEEV&<8pY8;HpIHyq8 w~GWJt@`;ntz z=aB`uc*TViwj~uo_l)B~%-t zOWslyP0p(A+fH0;Om6nCHK$n=GD({4x&y3>C~vvFuu96?@H3EGpzYZ;(GNHt@HHQr zff(dxvnZc-E9)t9*7sQ=+Y%PzN{gmBQjQ(8<}H$SQ^m=G=rL(YG0(b9Y%e_{oh0@6 zXVEltm@VRImamU=8I2~Z%P)@@mglwuJ4`~2nMu8KF>AA5B`jWQWy$Lp3WNazSuSVc zt7pO3);{G^5Bt@bYuBd~(Vxm!IS#6o>?3mA4r CaA zP3GVSucf6$)<@%aYT8b{ny*>LBz>AM+*~vx-M5^s{nG)?5t)$NI;(G3!E<-N*q^wv zMqi-qPeoXBrZ$K2H$iG^b_V@kI=Rc-vHNhG-{Hk{wbcLb;R-!H{r_~l!ob8%_ix85 z8rl^kAGi3N>&{F;;~h7U_|db)q6dHyvVOw3s&&b1g1rCyjd$mKKeJpxcIrf16#GQ~ zY*9W%f^?x|1^M203LVkMJuGEIG@)Ksw oDv!#Mm35q?CGlNj zzcx5i+|nqPi$58AIF((By*YRPN=mCk02%cnvxyp0vf3g`8WM`%mSw$R5D|AV^L8Md zv_+)lAf)YFc5mAcZP8#d;^5Byb+B|X49UT=D!~LCcirvaz8_hD)S$N&0Zj&(stbUQ zKb4yv^#uS+(8_Y{27osjZ)Z{5vnaP1neelQIjGYlQz!(Nkh)DT%25r{&ME~ME~2xc z&>8ar5ZIr%*m_vQFc@zqF{Na5LkdqNT{>bWDWe?twj!drS~RUY7E8MAi=5sspAs41 z2r2#aMRJfL4K6|q&vMOnDN#hHK_ 5 `-JGr{tz`2^(A!sT z+GR4+hvQ){>9|iW!qSqKgW`^=iHoG*<7U|_U$`qV$$PbDQX`qSKeba{^~KxG=63u5 zPnrBA5=d6oM2g;T$A`>RY890MM`<;3CjPVLAmJ$94hhP#pCXxbo1i~e%+gI7+3}aK zgrp>1s+`&kb93Xz7Wte~S7VaT>RUov4)W_qv5#nMXMx~44{K~kS>vULRx)oKfaQuO zHw|L1zZ8WKSVp;gb6g^eh+@5}yGh<0t);%%#?EEvW_ga0UCp`tMN0XLK@s~0)|~)r zzqV85OMBLtLdj*ykloGX!36!=mjl;}7MIl?^mBWgF%kaOKpKCpg(1>UOi0G>yE!@2 z7ugwttx&$teVm*0D%%>){w^*eH__;LXeT>>>5(1QIiQgPiF#di* qn rEOe^x}WH-<+^qgO_Y{mQK3Bo((U?N}JG5PRQ;_i+} z^CUay98_VxxUJg?1U(A$+#Bn=L{J4X@!`PN4Nr*>8VsOw%Iih4!K^P)`4{T|5$s zHmTqquHyRwJ2D!>85V}Pkb_S3VQ^}FZQ>mQpuVU%8{UD*mX}&o`3ac!Res!Kacex* z+La}?gM?&-RKCvFq0A0e1nPxV^dTw%sWv<~GiT6!@hvG*zcfCY0iDq2l994C4`(Rk z7=yVn02kE9ZaMf%X+Ebp+Z`n{*Yudsk}?^`o!HHs3X$?&J)#Fq7#g!uJ&(8}TuI(n z*-?c4AIgp(AjlGe@d-*O{MNo+#+%Cg#3dM_6o#9msrUy!$dk;Hu^b)Fri%cesF>B( z*-Wd3)itGaTbXjF7t- ly2d^C-On2+!v;! 8?Xdh zK&HOo4h*&^-WS-ks;t<-8WBFhZ5(Q@#)y_&^Ddl%PFAzwpT&-!AkiVRIWQOw0vrWg zy3+`!$oX>iW-lSq2UE!L7&1|*jnenfVc{lIFd3wy%(j!tWc&80;w2qPlI#-^1o0?v z@8Udi7YYEj#K`Ju67Jkb;O@O{54i4dpu}`Sjj XBwphTAcUd}emHHY7+OKh zO+xF=a#OV&0;EIoqBw55tyc3#5H!dAI-=9gxQCrCUinV_=CnY;jnPY=CTbEBO>qyK z)FBKzzp!5C#)V)AYKRW=?)~vW$%wNa$ZE_mKxx}$0kw#fUx_k0lk2DjZ@ETiE?G8? zqzfR*Pco&M%eTB~91pa>l1clFnVJT-4bv^uWXEaG47*SkVqR*>Eww!yMSpJ|jA;NH zgDJ9kM8RE&sL;T6x^FHvA>hpIDV9ctnS^Lku!2}F9?2zyp^y++P?tBI!N3Hmi-BKq z0TnuFAn*y56MsTM#v_@bP+h|G#_j6sxHJ-|mc(8{UfkM*rO9ei(nPK)`S9G8R{+P* zk<-VqZGT|XlavAq(dk{G`O|DA7(x1Y!*Ssy=QUdHiZ*geeYD|ui9=n$=xbs}?^^Uu z5hJ$;e*({33iRa**y*a2UhLpHJf%1JNIOc5R {DluOBe#8(;^&|hC}s~dfZrW;M0z@nm8 zP}#mNWZMRdWQ-}KYei8<@|sK0^9UXaCKGB3n?4+|cAfZEFgslPqPl~Gdx}rvO 33mW@n=k6tu?N FynonlGpnDp#5vVMy;iTRu` zR%V Z4G55~h_xCGu9rOTNi~OvD_3LSkktOK(-~jC(iS>mrAV@4~0M<-M-J z1)l=@OP8aAAr^&{fGU5sAmk@MMaihKC?rE&-6G-iDJ+`70yFWSLH$V74Z-nC_WF0K zzRoO}aI$lSbBaIv=!YQ?S+8#m)f!IDN0@m%OXge|1!pI&E}YMhYfinlnb!(R-}hhF z$OF-Lw$ttSC+=wvc=C3*pG9pBc-~F%(`-s#Ltud)$;BsayRYGSXZzrJ8GM%fDAn4Y zVtDiCPMNY_MG0Q!&U~m8axQUy9>4X)nLf`zJYKaaVx0BV@qr-pk6zdqEkCj5 z<)WDC-fM_%so < ze{_H>EdS~N2Q)M-aYqonb9Cvag0oJKESahNsRCnzq{S+Y0|fCZiOr>BL6*68&P%$> zkJ^Tl9jU5tBMcV+bK2S|)nhk^6a3!YgpV N z^NUDdGH7i|dVJ6YzM>0}2)WVXLlFWZe8y9FrFwc2U(1xL%{LJ1b_JHadn^mPg~E#( ztTRgQ(41CV&b{wTTzI_ x} Y;xgB;`v^$o7T#&9+eK%1PJ`TjH@O43%$~rtLt*B9w8+d* zP4C$Y`myvRnZ|oxl#>#ua(!Q8=8bl_bv?4b(!i2qctx8$Lr6V$O%WKg|7dA)EhSv& z#uK%6Hu}>nX;?V;GC$|me*8gW%tmz4=jGczge12Vb$k8e f)~DBF%)>ns zmkpcld=IF851#cM?RTvSTe|q{*BzRIiP*lVHm+asD=BwHbFep*riIu%H=MNeyc$E~ zq@H`q(OBYpzs#Z^R#(S*yx$X+%nrf%p|#~6Wq6?HiQO{l@gdx^Xuj}XoqX*)QKyXI z<=l<1IU=62o)zVGGSZMp;31rdua9R!4}+e%pPT&LaoG{FEiA(j7s+eX$n)?xaZ|(S zbz#2IZw0AExvS1lVKzlQ)w97x^vjMV*r4xZm9@I=B)DsQ8C*An%ASb|4*+Z!zlk7* z+}jntd3vM=exkxZ(j~z3t}5aaJH=bV_0G0l4%2hX)l>ffQ+=OcR3t2w;b!h{Kq)hX zgibG93C+2_8oxhhlzZjx;#V&u1U#Xa5XmJ?ftqHqT?EOPrk&+T1Ejp1f;m@U(}BLv z TJ=H%!uSM~ zcBsQI`pDx`){JE_V-`Gx4tT+*@l!!$`lR`#WYXi_{(+S3*kX+md==4r_+;~vi&o-} zlZbfCi3vPmY&bFzrL~EK`jn!==wf 8yuH;B- z3jSaB!8sh% #l&-aM}~jFUhblphY>D14uM`jn(zl=cS2Q0 zc7Y!Txj0;>P;e=cDC@59y&kb~S7sYMjk|#6fsP|0lPbUc>@aXUGKo1w-Bfw?;l}4$ zNFjb5#uijq3&9_R0;zCv5DX0d=s5Lp26#Byu;ztDQ zfA~PVt6K9c@K~g10?{Q5_8)_B;1UVri_T)(s>Hbqg(4^|%<~k`>4R>#r#pmmPiQ1d z1g=MX!(yOi&`bMKFl{YBlT6LU%w`%>mcx3e>cdPEv{*Q5x}w8OPWe&jg*>ns+>+nE z$17cF2*9`%);^Tr`KiFu=o1qc=O)^!AA`3ro7N34!-{Q!yTz_X;RN-^p&^|WL_#Dm zr$OYjqhipAD?*p8@XH1-AVMqyIJSl f`5z+gV~4QI5|QrhFZg?$w&sjJcBsZB``qAx}jq zM|U+xGS`yl`k%nMPx*g)z>9I;BP=RRxWiWek8AUi*xM%dPO$wH6_y01>e}1GS@btd zLpK(%G3>=H^6DMT9~Vta*0Y1>sZ*;5(P{cfy9j=KQ{ohG3X7wJ7CegYW?|85hXhTL ztF4|%NF=$g7l8cg$dg`_c}Ha|){t2JQ{T;ak0y^mv^<(zn>g)sKC+qekSQQLD=;Vd z9QFvS0>BR+LPoY6AsP>ou+mH}J(pra4Xm8tW}n97ExLhJ>J8{GQhY9do}@7;?eAD4 zO;}CubSyHZjSCcgvM0;#5qe@lO0^BRTMyriZm pY%igV z(T=3zdKL+6${<6#d6B2kPIhD^_)^Upvd7#g6X|I4)pq7^(imrHt!&Xh4WLL28BI+` zvK8O)GESa3GDBpwbaRyEDj7)8OiSCe*;*z})~atsma~ap)?`QF!@TD0ewPRFX?SLr zWui)yK3M6gtHSbVBn!nNB-n73HL7&OT*-HdnRUN9io{gIudNP=x^>Wgy#8iWW;c7p z`k<|*&4w`KLHwR|3U< LAI1|>|9Q%4EM2mP4@AmcD%B*vu{5goVz;( zug=?UwWhg4huV%Yz2OX_e3ua4E9$NSP?|TJ=3e5cE|4%KonkkIvX^Y@@(sIkK03Tg zhRr!6_Powa+Tm&ATD#uv`!Ix>UHmtv$M(NDJvQclyVlpFp&o-h^rzDUVK{mQ`UK2^ zL_(JfR0puzB7moK2MF{s6YPKY;nl_Eo)fem&QnF?uPZO ?Q} zw1+a-H+JDhrx^X>_}R79%OX{PqIrG>l@+y5&)!>NGA(w laZ zZph&$ASa|H#+hMz>ireB@Lcnf>jgGvN^m40DzCp$V|Q#vVua;e7(%&SzpE6f8_31+ zm4yE@#b%2D37uL#*SPN(;R-6PE-y^8y4y^`gmd{)c_ch-->Q%2{lzI@Glo!F`Oei9 z@9lOn)ogS10d8|dFo8vdILF@ I3;o?#Ze#rS! zU`EHc<=Rb?5*ehOaU#P&B!6W#mu;QffOo11UiAd)Do6~Ec_;ZBsJZ$#x6F$n^&VC2 zmXv1I4IcC5^4l)zbB^e+ilG5e3~-kR^-dvfgJhxuK%;5RRkYeGN)+`-br)y_xsBDu zU4*M>&jgPbd#FhcDbY9O2Xd^QO^q(PXXh6A# GM%*qE>jm*C3H81P6t#xKobnF^I5LU`L~i}%e}Ttm##~(!#XzkG2OSfDR`e3 zI*qaDdXf!3P7aCQqh1o}X*(ygV;1FIt1SO2vFh^jbZ)7*M`&Z({=F!P)o&T4F^Z8i zN`O#%2=+&RGiiK42A%u@HYRJa)z*xR`QjMZR>`JAm^-ubG6o1HI2qR sg?Ym5CFXvmwWPtrzw`FlJ0cpgxeZaz>DOY z0t;(z<%kyJujOECLqWWV4pL|q>9cf-Nzw&Re9bdJ6dPeRA^Nt#Kmh>pTfN>YfH5 9D!hsj54k^%HG(I+^^u?^ zlv7-Vt3iC&khJOFC#LU}NiE+}NKRzE7`{mLc#zgW4z+GXnojy0cuGtNJ(|)$?v~%o zJdLcOTWN-!*>ZE9C$hDNH}7P(H)iA|oOGn*A#`B*jC_(O_Ve=n*1di!f0!grG-`pjMw@{M=VZ)ZzfylbFW zdlnovsJ!R-B*ni&CwMB=UHGe1ofd6ZNyfTV6oBa>{EU3pR-s;(*opaA!EJ6vE73BP z=hyiT&VINPMMoE=ast6&qy NJCi$+}`FWZtXVaqZ2vO~m^DT@X# ziPJAXLs d}Y>X*(h-{hDs3(7OKk>LL*Pnt)I5VeiOoDN3{r#s%X@0?&cR7^?5AAXkPE zpX#}T+&O3E;SAST!hb*{EwvM|5rlcogB-wSWE_NTE@DqO%Eb$2OiTYB^Z;^D--j}8 zsfQekNF>#=!KBW5qNcw%9oIWyKTwW7;Cg6x!F;P{2eb2;&c%@-s_~OH=VZ80(Dy#y zH+bw3*M2|!Pslp_mR}jmQcI-GyyddMOpDdMzQ^7w)irJTKu_KIGD^nh-GSP%84d;W zf0bRLBG%6d)(bOUS)4_!CyszZ ?R`J{NzV6^fOAOhSw?KrbRrpa~W z!xBT^lLb;AeB`A-3G(q0nFUb&5dp+FFkv1JqTw =~fy%`7iiJCCd?#e=iWEXygwQ6PrZQt`DCh^f4$hhBcMPWp;r8jb z5h2IgujMabHe8NSjc-R?tVN9M3q~`7gwHF~Pp~wHkYEF24~p`o{)RHgH!}RKt&h!{ z9mM{sQYe*LF)KcIgmk=M!D4u){S%~>9+Q*YFiLClLT;WLwcs5VK~8biDGpOxFuRdi zQc~ uNQ(hZ4ugnuE@9uiTih=iZlEY`0h`FwRgQN_~4L^eQ7 z{C=i#uPJIF78D{42}rX*J_dTcf+i+#9DACtj0TicShiw>aUHBj@I0bH{iKr+eHBhb zu7apU{< 0gNmXf6+l{tTZEXPq}Ek`ixWb-c> z!O2VkN|lZccGE8{cJk~Q!AoHc=Alz;86xz|A_ R>y=$w)0#G?EAlDd=Py z$>?S_`I5-&>9}n@Sh+!eS GiUP zgqat6`Z`ckFs>OlI;V9|*_6~!IuALozLhE&MHC(0M)ckGwoV~`F?DyNOAs0zauW)t zY@NKyCdmAWqhJVg0jg!|dN`6CDnO{9--QI4?sMu1rm>(OwF_8y&=*-VFwu-zgH#h^ z3;i4MVw3_(jBImAvW^R=b+2ENC^$uFmQW^2$Ovc(*j CCO>I_=EI24)|ZWAQY4ifdWEg*V~BlF4e1Ey^7(qZAZR%u+(G zH0f)$G+OBmw{%OV6%R^(Uu H43{i9dY;@!bpCEyg;Nw}n2K0_dP9Or z!MIi^Ms5^p!$L^{3x$tGF&ItxgD94E;8Dy5 lZxalusP7V);dt-wA}^5??X-IW0MM?b4N65xL|A%Lf-7 zL$L1D?<6NJ@Z0A`92o>>Zx45zt+!XsMw! ^iVOaW(`I1!pPV)m3**22X|V}sIhv&9w5umS z2e!5H83+w@Ni4S47j#KyC@g^MhMC3R*_RFe@ii8ORDMC3d!cI^cf5M|YaGgeq-fO! z<-?;^pYF&ZMG;QGYL55%t7%E`!J)Y&Li YnV#kYkEg2hw e@chS|hk&0DxObCb zcg>opRKAM<1^AxJ;klls=JzRQOsy>62)S`f9~blb sAfRl+(06F2~ zh>>ZoI{B|3Aej~Sou1X(;K{ibH`DCxuqM_2kFj$K79|X>^*P(NZQHhO+qP| S6=D!x&pnvolLoD`s9V!CB{x1uh#jIzw(!qCgd4iR)}Nqr{+ Gl~%6!hjI |$jr5COt2u2dX8g$Xj;st0=Ta)^TS>(xd{kRfa^qm z%{a7F9NeLEn4?DFwoJAn(xkC0+CYAfEiznTnImV#hjz`K2VTdjSDXCohgWdXJFKKE zMM|ipfwsW^vUq=(5SR4lMNU%ntl&L{Qn^w~rELNfm >=j5A8VKA k+*7^%gBG6m_fG*dnn3Q8)T_!1axI zbPCA5KF8f6W
m27@`0p8bBVJvM^}F*J0)j1YC<=;&^7L#~5>>Iw z$r#ck&3DKynKlsEXI!8* )4jT)nQbV+;WZ!LXLtg6(Ej;oA8ZfG+c0#zEw(%q3nPg2hKgd(jf`a74bSo zDxv7;v@C(5YzV;Chy(Vl^=^Rr%3OUh>k;Kx;nO0XNUh&u%h`Dz46!D+;$Q?k^m2E) zC{?nhT6VC(^&v={qu8mBNfg Fheywvd89~X!!CFd @?WL*&>^|5Qfh3L y;J@r{sr|8VAa_`cK0>~tP~25n zELI?nBPuX^q|5Tfsz`Y&hR*Dp-M!*QG$%Yf4kiZ#tr@SA)R=9~lnI_HttVifV!KTw zuvIW5M+`{gGE9T7=Z#v#r3_%7W?9oaA151bhb3Q mJkLROboBfqZ}YY!Ky7Z_&J!(_=5oU!bdMpLp+G}P?VgG5K6B^ci0zyu zCNI%|s<`IfCrbC7KGiML7t`qbT?>3)lWk>F7bi)fFUpHs_H8fN3 aOG9?U$-r2b7Qj-H$2bC)}Bsq_KBxyr&p{*m2tgc-(H2SqW zC>dKosP7N!EKSC`wSRF|a0jRq|M*W8Wf=x9TkSh!xAi1mCWchjr$9Djs!alKMvS(a zh7Fritc3QnGhmRx+`BT9#oMqqi`@y3KN_D-X~V0eIk%}SL5OHD$0Dw#VcdflSX%c+ zZ~j`!X9hWI--bz>JEjv`s888ZS=^Y!9a@4{4ohFVAm7m8{46x6s>odH5Fb^JyVPX4 zJ`rWok!yBQ%*q^{Ttt^&Hn7>_vdm003Ae|&plo|##0Vbt^ 9=@2&z-IG Lf{iNJ^38IO%X-3n&u;19IDPoJA}xMr z{%F-jx-g`oeD&2OI}>wspJmG4=eUiBzE9Q%%6P(NyHglPmRAWabC9Uhh72g0R?fu- z?oLz%@V@@?e5@q3?_dk9nT^do>tb6ZGlRM#MWw$5n0ol(NnPB0e4=P$Dj3I*1UjFj zN7l{5 qd@r>+`&aYbv8jIPGQ#9QA{;#$F%|ToAE00H?yqSgk&c?JT zQO5F81-N2k4CDx5jMHlnCbxkYxGbKun7N4n_RnV$&X~yh%ljEvYm$BEp6LhA9N`3? zc>>{zCn=tx6nZovH&MM`3jwGrBabu$ke$5~>jC5P!@&g|4P9h_)iFt2{|b;sd%6&7 z2kK;dq}W(t!C0J_DC4*cA5ClDU+Bu>CKD@Dvbz2`A{~x(zZ*hStl)SQ=B}|h5SA@l zgfQ%;r }(u+7X73RZ|kc@`)_LHo ;4robaHlljmO5|BQ5a3*}%;|=rL%m_%#d<1FCuB{#fvwE3ncRlAl-P zg*A!z1h=AP0AxEA3W_jb+M-uIAv?ZTo8OoYy)V8oykXvc6x+DBh^5O# * zRY)g|AI7Su7Lf3O!OYeC%OXf}pqIi|66t=au?$_fSdpk=-$4%i3qpW3y`D|#pkjXz zLcnBb83pkn!chntohA{raY(}2bzE6M*Meq4qtq~ow6{6&z_gK|dd&+3rWU5z!4m(y zz}e^p2eua#tE2@PjS?Vw?bJ mtz~QgPFpVQqrQ%PRr{)E9fz0lt9;gGg)&@%N2E>M?dVt?DIA;^525B|}>oZ*+G!2lxxzIn+7><`%_3;-pi!D}h)OKRoXgzAfb` z9-D}R)kZh|Ln(Oq2j`w2 UkX82Y0W3ctgfQ* L$0F~9wD?L?1Kmr zZ*tpULzT8Rh+XD#jYAajTbm{= y*%UH}36`ssYsLoGG67IXp)gKqK*d#S=C@rK_(dSI#c@qGGKdY9 zG=W`C_Gw~w!I^*`q2~;7Bz3#oAv_M4;t1+QU=-Cwu>f@?M5#G+0Eyi3s$J%{$Wp{( zEuVjve3gCrXSg6^k=wzD M{wf+}av^M(t z0IWNQ(hwhETAGEs%`l^cpkvlh^RF30ePma7UEndWYh>g%ptNaPN~W?i#Ae5^nuvHy z Y%xg3BKX+sLgUyNkBXN(yEJsf!Ny{4X16r7AQ!rGrm=wo8L(^`nwD>p3r#Sb zG-Qi<4sgCXIiz+XOArU~T0tl>m2wahanYI>QdlujOFu}si@u#iBZV>{C^^`1xBsq^ z+M8VBKFhBh$S3CGlv!kl-6fg Mbj?(ou-O zz?W|7_=89cu8D|Mz6COE8*a8Q>ItQTIf`x*`ydej>J;dwmWat~N( _PWJqbgrZJEWyd=a1!=OPD-IxEM<1 zk&LgHw j>Y=-2<}NTGtCE38QkkTI%DV_~>Mqq;A#L!-t%1Ck}gA__zi zM`%o?PoaT6NEnkzxoX|7>dg3;)@8XhEMT}dJf+d5Tze*73jEY)onT tsQDq`CuhyK~eD_MUsTtCc-9Pjh&Xw%3aJSGJ|e$mTG^a6{6H=;3@f(yE!eS!Nq zsDK~IryjZxvndLWN}SyKVKh%&dUh-O+R2jc|2l)Kp&Pc^lB_#8H|!i0W-e!{;9TKi zx`Khru~|=5g0OUZ*77_*d0hsgh>#N-)V2ja>08ZnLbfy+e^jnrKXE&)d=B!T-kyCi z8O@*H1lI1NNPTQzy&k^tXf!$Rdg8`tYiA5V-x=oTPV_-jeZFBm_tb9wmjM&w|BcMb z!p!zRR=G>s>J>y|&OSA|@-u+r;okmv{QbisbRd=*@zi^vUZV@;&}K#m`Wm5^VG>;d6LWgzav`ySbryHCU*ddvnPbKrbPHb#tN{+}`Y;celC( zvJ6xBf(k^e_VH)Bi0avRaoLKPO+dJU459 0E$4I6ed%uBDga)5z$tfIpw1 zzCU-kKAlN`(W{G$knJ2-JxD5blOf6TPg!0GY+LI4)p{iw;46o%Yz19=YeLSD>?M3x z%lOn3XjcULs{IcL`L5!G)r3*@)uoyS?ZV>3jphMv`7-Cmgf_{s<7$9Ihwo5+@6e9{ zQ|Px(v0w2@@I8PaX %Wd#l4nw_Y?g!2T=pUp?qs>ZO+6h`){7p^7@C @ z3oa_B##&F)k#*5L88GE>;R$Vi+(&REQFR=y*!k@*e}?SVTy(yCLK#Zb18=ytvOy-y z+y=p`uw#=<8}_4NXFBrOq!Q(3QNiy_%j!T?{jo6$R5((_v`PU492S#7@oHLiRVCWF z&3u=-txnL*Li|V4OsO1;aX{gU^ttFK%u{2FnO<@AI23RW5#A(&cx@?~(_FSZb27?7 zQO|0|ZOs@YQCaJk7eNSP0!9cX|Iu027Ko!Vs2WbVRU(QF7Epjtvt3$FI7IZr9PM8N zoiOmD8Xt2f&;wT`9`HKrk{qM1$w_~E{;P(LyUGk@uX(g=Rcpl`Sv=F}f@W%qS!6gN zMj@WHyh9=S> CTD>x`{M=LuexjPyh?|%&gCe-rFOP=t;9-xMF9Mjd z#%^niLnzV>?>F!cr%nCpOe^Q;h_Ay^!jh)eMSenNb&`pmTLc`|sr7QpCR&Wj1qDMY zv_s>VD#zW0;g|i=#}pFrKq~MOD4ZE(tjlxl0eaL`Q-ZjmLKazgCbra(AY~boTefV0 zYi-KM u*(vEioz}!Ix(CyLn0HJX^?hp{)E=$s`~QST|Aps$gMqkw zU6>s-8)*rVAfBFqHNwms29~~I7Oh+=>Zq#%d>H P Fr;Ok(ae#4t9W#oX`P6_kFI9Yxj)~ znT2&U^_g8(IL;LP%Exwqk{zm+%}EC>2>r7&q_Jc|_3TLV=YW#zMI$be7`D*wF)+sI z@_(%}_W1m|ay_q3k;6m(l!N^-xvk>BTbN>ItMH6zi>ZIQN4uv>Q;X+2IG*>rgaG9l7;| zRTck&lXPwo^o}Q+T1^QjBMSxF+onf9=7&a aviBB{ zuYg})ffy7-vV6Ra6%mb^V}-}18bG})$K#CNdfWnaq_1R*F-umYG2W&ak}@WNV&%mM zkQTS&;|P#gXGOM+RX?zZ&t_J17wrRsLYTJtEcy$y&0C$AvY6^Isr1jK)S(;ER(2Zu zZ!uC6|9lK<2y0rp;ktJWxq6TtUWyr3XI8;B4vDh7B4ux{6%k;^^4dsIUR0O0G5Tq< z^#sy71Z1)KuvwkLzhHA>N?h5tdz#XfEEJ0m)qo0uzh77je0uE8Ix_GGN3kLEeXIXc zzL{Fc(z3WEU|NGuzk@P_m)zLo8o95do*Lk`LXXwJ;$huk=q6|QVfe#h0lCs0vUay^ z@L1Z-8gg=!aAF^Hye`V1dU|Dm;{A5BezXTP*@BNXxSRSTqo0jOW`xIHwksv{s4l2$ zINVZ9rX3D3j {eO!1>LnfJWQ35WWS)p!r7tYGVt zpAOOF%hm~PxZ_xnuaHQQS|RO?YQS%*L?a4Hnm<19VKPP^D_xu4xsvvbVFpmRM-6%= zO>%SqGg)P87ls{f2}35Vq@cPsQi@b3Sn7RnRXBC&S&sYSEM+#_cf|6{nMYb{V@0(# zxe1NYP;wfVdHF7`!BV9qcl{x(XohRHreiA8wz|4I6D8{T8{ohQdy%njI+*7)25W*c zf &mivRvM>I Qt4c=42fLq9>WJC{AxT!(F~T(NouE_C&lZom$zd1smJeaG`Mm)x_B1CMQL1O5Bx z)3mg3LV@1ozI35`C>#0%Q%)11e?I()HYg1e(`@RS=AzugMmfVSeSb3QAR?oGkf@)5 zg7v$>7l=pNI^%8q3u8Q-J&gS}_L&wx=n#0+fRcb$;|a$>*OQq2 0L zkvzvd*Y@_un_bAt8%~B0lHmAq#}X38>x5Si0psxxqSsHriNB*m{(F_CCEc)hLlImG zzJ1p_lSbqAJljxQzaf4+HRIJVM?30?P8Ec~sY#b?(}^oC4OVL=3NI~|mG!tc=0$^d zxI *C{1 #QIy zi1RQ*o4MN4?kW4-?6H{ozpRlJ8(5&iHC8Eq3Vi%@YPtOqw5A`sNKeEFZ5)V5^YgRz zgUa>e{=!_fO}p80%LQexU*C+dAmXQGKk1Zyw_(+A2F@0nFaPxX%Ri{h(tMCW>awjB ztJoqtiQ1w>VfmMfw4TDSZTH8}0gAt0YR`_@c0u*xis>xSSZp=-lpjkL6Oj(UYkk$U zsgD1Hu*Y7uaOYaBtq1qwY@lAt&M(@@+IRM2Yf5vw?uEIE)Gxqtyn?oHoM5!%)TgyV z3Sb0=8y8`nU7>3GIYuc*Cg MSQNth7gk&otjM`G}eJ=!x;0O|nKI(B&hYfnFUheQ`d6wNg;h)(26Xzoj zD9c6L+>|nIz>@kgb-cLC1tl={ULq+Vtj9l>Ne2O(T 3_r;p}vbq!^Qr-TvFzfW`{NO_ZnBc7nA3{+lt!zV^{<`4h6*l!w!mM17 z maBD7w00p`wQ~BkOkEliZ*k@z1QXW5bmX*Kkj&--XY4kJ+^;HWv$9iD>PK4aZ z8E?M@#7?`AMyw`H!oA;_C=$};C@wnaPCgYH5swaUGuNws)-1JhSNbR?foP-Y1x6+! z96_YgxB@#1*$jGn;s3%#E YRgR8&Hs*t6@#mh%RHp&p34?PR 4!sESOkc5rWu1fg&F*7gLIBcD6tm4*J9XrcURX(5h2(#>D`;Ot0nr=>+#8nUt zU KggJ-6od+fa|3iBA3jSMqNCac0X3C|D%i7V8yeI}P z7=S#n+>L!lBymJ4D_D+_dq(byZaBeffT;9&q?tQ9Iv@I?Q(#?V_R9x-W=T1sRiq|5 z$t35!mhIMGJhvei_xd6yLPFa}u~gvaGPpS}m=S^Dhaak3E4ErM@;_iCh#z>OJ+Fk- zY*{#K3ZIl 3V>Y6x=QB6U;7zP ze$O?(2M_~)+|^uk1p^u5=~{w|+OGm$2=*4VvmZ*U)5F_g L9a{hM6$oyZwM)ZiU=Vo>5)IIDeaj?Bwb$$(lp?PCqJhp){|w{!RKIC 1VCZs~)|#SC==O~Q5^Bzz8Mg7S6Ewx*krx}e6%j2qz9|@P{>GGP$2n!$ zZ5JtL0p*G%l?#Ahu+BoVnD#0)9(8~;PTNxqBJeBD@x#r^bJKY27O?;Jmr=j{rMza> z*Xp!vA;b8_&d-xli0$eNyM_={s^Hdl@B!oPN{hFQ5=h2PC_dMw_uc;dER!s0`A$7k zWA_N(;L~|>yuF*1?q*!QlnHj8uTzy7c9-uUfi3CWmId#C#!MybdhQJ%bV~h)%u>f5 zn47OoxP@BFxlX@m_E7ni=8Lthw&(u2GU;^{%NAdR7vofXy2***;!eP2&ph;%i|R#nYk+wfo4$ 9 z{N`>1tg#pDNdvNxr}m;JGT#=%T`N#ordii;s1j4}C7$rpU1=qS&THC?W 8!AW!gA_caGVI1(j0gvT5lSHt#|^!<6*jpmJz_&MsS=yA9cD$|AaI)HSp zl9W7*+M8Q374(6(9RimupYi%k{PGqLYFs7s?n)&L?LXW{)5M{5$ndXV(`D+{4SiRW z+!Ko3@6wXgr% ^GHYLvlY{qN(qqxE_nZM~wSW!D$*-7)!603hHrfn!!?!?)u2wpR2%@BoU|T zapjwl*FY%Spw$}4Zf{0vl2}gj#AJVR1ebtRr>1=7%KzQocG7dPpELe|0IdipC{g8T z9zzYLJ}sKNA4VV~qy$afJ11Hg&@&55aE@MqH2)UNyIMEms0ze&;vGerLk;bX?521v z;v~00_CVS!U5WBQ0T5@&+jNi)y2Z1jxC%8FKgkGJ=KKDDM$ CCpZZ>`W>YtVLa;V;Ek#xjLd?I~1{7JaO zP(rt{Kn%o0YN-BcL%p2R{r ^wFl1!q2m5Im8 z{KOGTbsHHVls}KiPgaTH`=a9%?jyJ%&gIK+7b8zmbJX1p(vQU@`P2>Z9UVNX&E(|z znA32Oo{8}k8$#QbItYdRX=7>DE-_fvJ34@B*A|mK!qGGo%LfzJ<92%i9~Dj z)K!zi-RZy)<&>T1CWzA4+ZmvJSBQw7|IC<^RB (P*oYM0mj;?|$ahNhR`A zwVKY6S_KL-gbN7_IU_45Bq<_9$)+Oa|1Nh9=59$VCE{=135RGJ5SAEIgpPGx$s-E6 zScDZ6^TiZwEP^1;`h&*71^eu7TfX&X<1XSmaP}mQt3@r!Eu!aU^F IKbF!f6jVx(CF+a4UT zAzTC|Gh_QkX`)4wu^DJCD-yq988VHv98{vnSLOB9NhDghTH?&b(J`jyL5LJ(7C=cq zR&VEz7?`xMcS1uh&OT-rm9YOUPczW5BmE-Jq@tx8jt#)ZY8Ow|bBKut`g0^t6v?f{ z7;tB+OVxrHh>q$| LYogwcW(0DY{BY%ED_j#FBKCK30Ly zl7_2hgx~nb1R^@PoP YkQWmlj-XHAY$}Y$ z7=4k~g34?OB2&`^vpv;`l}p8 P>)x9fb$<$AwfC9Lzp xHBusf0 zpc7|OCT~ypEccIP6_%I+Kl{XS)d^)_Rnb^zq=1R3DnD;T-rk~MCTwjpGw4H~$~4MY zle=>#Z %+BuR%!gLAPYyxv{mIXt z@o1;I|7G{X%=mvZ7c(*c4`4$R)|d@d%N>vIoGGBWqpn{l=&!jL&ku0WC%OSIG;NMd zBo`HL8owu}+#rtXnMspyEshRDg*nCGN=w5-{`P|s+Bbf|Qi2_%MT_o{-32o2E zg{trC#Y?1%Wp7Tamj}<+RiMIiexhf{j50Yg@3;5c
!a;NUrW5Xl&CeWjHg#{&FY&Vdhg#Bb}%*_TVEA1hcBEbdM2$8`YZ9ZZw&T zT9ScPk&IrQBPF13;9Hxf<#(bv49+>=wc&(O5iA$2Id2MDgbkCe(DTc+quZy)fiqpA z_se<)yjv~eoV^Vpq%O3)m*UBE$48LYTov0p)3-B`t*)Z)hqIX5NT6S%tN?_S9Xwl= z-oDI5qu0mALW*wPJ-HmiNtMnwXZ>2`u<^xKDFeWd!#m6{JDPFv{s3KI^w0J0WqZdf zJC~=eD&v^1y)BTp;&LIjjtBQmULDmxp~<9W=#LNhk&5sl9H gBp*?PUK6G#K#geZ;B*?dyQw?H(Ov%J=Z$!@#% Z+%61O6&;i5}oXBEGs-?9%-+dQ*ajnw$dIfxZ>se9hgR`D~-drO46VgJ1TXdc&Q# zyrSTtJI_l~9uGWMT2?n(Mvz3vsi1Bpz|HbEP}Ur>>YcW}sU2#bK%)!?Gf`D^R#7Bf z)l?Tl=L@b8u&$Y(X8H0k`I27bWJsV(4>xGnLZA776&{=iDx-;P9lGI|DY5BhK4yLJ zL^*aN$7Lryhg6=L4vvKy3_G6_152c`Bb80M^&CdfUzr9n$QI+m5F}D0wolpqO;2X^ zMct*$z09)J$3!_`ftQ#Qe`NWO!4g>rB^=4><** @>A+o)z&dP)ZzmG&;=)yvFxs zJ}7=nr7H7%cc!hp%^IU8(1FL%Sd#cLW_Yj16ka=&0FP~o%tX`VwS%6~M6k?+L)j<5 zs8M=N6qVY^;TC+%GV5VPGdrOw2I+O6)vTaZ7VScm-JClzi0A7Q+df&~bu0@y8$uIh z{0nwAXdl^E$Z^yUheh9ayy!R}6sfFV!V~#dd?Ueh&vDN&S$v?+jN4yc;D}HWsF^^j zg;{yPp}%T5^laWKW|iT9Tf%6XGZ149|A?<4cuL(%fi=JMfgLbX@$(NFfF7IbJog_C za&f^<4=-IbfkN_{N3S2SS}h|Y8~VV_znz;^*jNk =w-E9oEs=PZ0{|YS1*7;j9%^_ygORb(C+c0 z*wA;FCUQEK%Iz(~h4Ko`ST{AKmo4aUP!o=FTG7dFjIP2O! ?5-O6z&`GE>JpH^ zQCKIFAL;RZqX>;dd4`Dre_dQ*PW0~@h=jr5lyhpmY_w`scgv$ 6__>yl#oN*T*5Ji%=DIPm zb8KktnDJuz@VQ2eGs%g?#p%oBa)0UNgPS#nJ6pCRe6r`pGks!5)FGHwBG@*Kw7ORY z<|c+}X{H1^?!hMJfxCz5JX^w}viw5!7PpTLj(N;#Odv#@p|jIjVJd vQ~!K(A11x_U=^|lPqn+ z;tKj+FV@NiUcsq4NLkLAln6T4?;%{>(t^G#?1bY+*S6t^D6|%b@7=b+%1|0ZcDsLS z<;m5e9DQZ4W2~^1ylGMr<*#DpU7m%#9e!Ild+yWE5=@G}!4UdY^zC(h i%3b3f;yGxoYUV04EZh9b z+EMPH*swOO`PDalZL7@PmWi!I1pbj-Hq}; x#3l%rLW+F%dP~ zL6{41QT^d#`^B3vSinKeetplTmSDo^1(&zm-jL&ia$(JHq^`8c{37O5k?>1Stq}lR zLki$og>s*oJYPGztG1MLj|x0tG$$>#l{H=EhV{I=CmFfCCGKiQ3Ba}IyQ}r^*hVfd zesGE%;R4Tb*cgk#0aKpOdewwg4Sd+#j5gnH%}yK&d 9T| zscf`!?3O)zmZ`(BKaIhu#xgfr%uusx5q(X`x>P~1OLSYTq;sN9BSv$T*@>WQo$K#M z+MBhF8G2!PCff5HH8|fsU3TSh<5(U^hXjr=45}(-G_o^rbY^o)2A?bl9|v6Ln1X7# zridmNH9Ryjw?pl_*_<7A<+b~(XF;7un_yIbmd#??GQj_(Bqv`Y&156$BHJ$u?B4F{ zyS-L muV%Oec9{2arjpl0xR|<`_`V6!&H-(lU@JhODB$+vMRM z#XL*Kwq*16{-48iS+0kaEaV#&SdP)zmuNg(`DE>rW@n*{g1JCTdHN#ef7`ldF2s7r zPuDB~ouitA^QSZ~t^eQ$u7aOSrtVD#P76HsHY}xVB?!;^)ft$<|Bf2#pw)P=93@(} zWI%YXbiu4QB^H4>lZ+Nlm5)G^yLWr8S>;@BktSdq4PIr_?GU>~5?_(eP+2K#Z3yiZ zr+f|_ 5k-Z1i0^rlwNBQvxO1%`y}$y08%Mst*)wm$ zuemJZeBKV7>B4sNHtn#w?I;()HEJs8=sS>ea7}HM*i}Z6acOpEW%ul&516s3$Peyi z7X|b}R0a+|E!Aj*?|>-II))69^^lPG-GiVb9|hf>s!{iZ&hX0GyoJEz`o4L5Myz9c ze0c?2ngcJlH;PO)=AYExnE L9@*xlB6;9XSNf z=f&5~+r)WLt3kN{0`H9;P@s753qT^E79l%JRrLza=UaR{GIER^GAf0$^e>%=41~!8 zKkSKIScOEcAw9uMG3MHq*YpFM5Uyf?AA`dgr&ZgbpUITBG|W*X<2JFHzEur0*>GUT z!4TE^Kqj}El?>KXaigxDfzQL0g@JW9Q
v =tvQyWn56#}J|IHOf%H%$TuPc}AD>IOA`_1A3ap9{)Wtiu4H zLl^}fh3aWn6m}y&q~H{8Q7r5tCIuTUg?9Ec35V$y>J}^VhY;wm2!Iik{@t2^A#eit zI0|5&rQqv!pefgyo&bBYflT2TFdqdSAFvqdCQ1Mf<{uo~5Wea;E3e`;L- bU6n{W7@;+k+qhLZPbz!Q|QYh*`(m=yrc(_iT(E7+lT_Dk85xiVL zKaJisv50+6BV_J@2z^NU;CP-wR*{x>6PCFQ5Mj+mgtaMSmJEQnHN8N!$%4m06GX@I zKS6d(4on#el_mplm=ZuUD8NF`k|=P2#3TW$1jA(pO!RFbQ|Zzq$2LT4eg-T4Bnf;? z%$U&26*vkGf1EKwm#54OT&9d_lW0f~$9iJz^*-dJN#fxkw+k)^8{)M0;lMK^Eb$BZ ztjNI+5k>s+MeoZ|p;h|i;=Lkq$ysue{HC@1DrberViOIZiJ;{1#M?sPPYc-*Pe~vD zBy r(O`m6VTEVwcUT6Ke!Wf_M@qk(3d(v{)CeA)*`I z27fQO-Qu@U+;1W{!W#iHEIKc&O@RAI5W9}-MA4BZHML12soyzo`9su}aFAc#Hl=-A zL^n>d*OBXBH65u@{{kSP;H LZ_FIU=?HHX)2AL{qNqNjaARqG@-IQ#-h? zo5(S#52zk6AS6{JMlPq`OubktT;V37cYRfkfLkCl^DhzzS&A0)Cx7J_MydJbTKaH{ zrI$B?*3?StBsiuZv*Q$u;|H$B^ zMPj7Luzauv=9ShtE2%)!%}_vl9j3h6At@XsFIJA?gB4?NO7U|oKe fP=F+PFpCcI%7A}%C-FlU;A#QB0y&yLetJTYC z>E mBd`8Gh`OKK{)t5$wie1}S(7QvTi-zK9b&7`}=@S@%yG%ssn=+Ixd zeGF;;v6aZnLwZQdfw20+u7B#(zRZa;*H}rGdgqBd^$9-5i(pMwNBQ0O%oQMK_i|K< zt4Ryy)sZ0!?)$~F&rR_9A97tMcH%>FqPkcq^PA?E;?C8?7yEY_yNnPY9G2X(7vK7X zD5(EsUc>T#^XjrPGBf=DfXyjw&6wXHm(PD7) et8V1Ob&Ii9JgtYHZg}I-6WyOEwZl2v<++S}@ zvVCJUR|325qEqGy(;_D`r`&-L8GLIlb+AJ$Ekw!;|JUy(;}Oc<1tI_4ZG!rY_IvTk_TNK6*Z?Z z8IIxH%c-lH9=0#B%t1ZuG4uOR-CRiH02dp*!wy ~kdd^7F(5!?yv>_rvE=i)2=5RaShA3g&N+ zhBOkJ4YALCo}(8RCEdeaY=U=+c2H95 9zHR)k4gHg+DPGw$NN&J@$ zgMs{&eSBKGj ?(S$J&hat|&5@sD{b4A`YJ)FSNkFUOVu1G7&_IQn7 z?JQ|m5yQ>HbK0~ss-OaVsp`9q*SuX%tsyIF)I&^RxV+Js$BqfT0XIU7qi_G~<&9R> zMY
UDeLFkR{aTpm;ic4UD94b JEFL6<< z=OK4o9+U3FEI=^LqL)j?s1!|&pGYM^JdO?7Kqd_-%hgXm&}5n~dYR6oCGCx3NMu@U zhcD5?IP}RiOU!YiFf)ejg=_|~E7#ZvXAndU}O;gwUE77R36m{fN!e*-x}&;gZUixu;n4;>55C2q;qn)W1bIzGQ{`$=NB!wvRd zvhTa;=JkH4h>unTRloSh@#BotlnziNpaC5L_&cdfDE#aI!4(W(R`@IZGu89`0qgrS z5K!zno(}lstiF+Da3cKk4tR!baY)0NkyfAA<0Q__p~%3sk@`bCe1GG(cU`wBskL6x ze`VM`!eiRG^`eyhfL`$eem&uQ+W7inb&-`#$#f~1m*l5I)tK#}?zaDqc(Rbyqw&&f z*(UnhkkxYT7!;~>yPgeH@237@H!M>qn@%HXg@XoRi{6N8X6Hr8b;LmU-lV6DH=|4k zE3W80{%4>_U%Hfs^;7!yM#m1$ITN0YfFSwYdGHi1(SjeXb(N$lr_GG%_C(L@+=1FE zVHASE6?j8oc%O}~i>$+arj4{t)r-P%XUl)fJA(T4bZVR )8pdP3e{D>JuX}Pm6rQOq z+J8hdM^|-R2dES39C+m#y#%X)UjZKjuKs4`C)fOi&^xkR{NsTQblkcR^3tpY+REIC z2#8KC>7mO6M9{?}h#-fb-UtVC +Fl0 zhsnw{rh^&v(m9 m1PFCjsG4_tZl|^0GXl&c*SRLE8-5sZ6 z+ji3NiEZ1qZQHhe)6e_dd+V)xe|$f7om0E&RGq!oTyxE}#u#&8-@^O82}pWVn%;?k z!q8#aIrjJlNQ3>|=Jo690T=dwz?7Mk0i@QT$bw~b Qi@_PyQ=Vwk zVTILG;ENXuI6p3eZaMfkcSFj6tkq31uI`?jYaGmfobn$}dWWzZt|j|n)fTp2{xQ*n zEY&3oCMz)23VK%ckD9ZVgQB@AGG#s{uiEt0pXCLx|DtiGYS=_b3;V1PY(vUJwhrIV zsEg7GPIOE+XS2@L8&1JqoV{Zu4K>}1I=ghW8F%XU81o~BGE 9? zCjxCb^6P`}rBw<;iA#;F!WH=0w`Xg3kY_e5VL5lv2c`N+3tEcNKNeaK-+l^|9|#Mr zhSXp7(8?vyij6tU8_hdE+~H0HwMh )o||ep-BU0Vh5vHR z`O1miuT9#K0=s(eCeRa)EUrm#ZLBF#vqp3qvKVn8XyI(AsV`S&Crq1vMUGLgEP_^! zZC8H?eD%$&{ZS(7c2#@mCsSq1o4WDPt#2`iaZ!KBv_b~a9c vOSyA8#8Og_|7QMw rKz&G^AR_5bx##GO45kO3dPq0BQ^K3G&l z5FnvBL+(N$7#4LOg+XqLx<%8SRym45W_8G-5npf3 G$xc1pP-sZ_7_S=ol-8WV)EC`0f9e$-yVf0JU*% zc9#=39&$8cGkl)R?&FdQ1hG!;-^RIZ3~|BQcC #+oBZ@Ry!tUJEX0J-;+iKc;BU&5Jdx*wVsi|ESCnZG=N`XWp+^q3v%A*_K~A;MT3 zlnmdQok5&yjkm6b7l~(Q%Buh-NjvIs#DF&JyYy?K@5+7qSpbc!bL^fkK18@UKYslp z8M>81gTGe_sQf1!vyB;%bL&(}qy?xS7f|w$DryS!&%+G}a3{ZQXV$|gGTJ97&?rY6 zP4?OpmaU(05*1bK()jZ1E8~l{hEpKh{(F`c-odQ7JdjxDO?yb?Qk@6|rSWU)JIYJs zZ}V3JtVOCJ9)?i~D7N@iQn5VfHY5#lb>ZYg644WaB%gkqYCi%t8qI%SO&WCh@>pXS zojEF8J|T`k-cQ^V%CxErC95&zEA;&E_9O!txu(3@_;I xr({=?Z)gFI)(fY@tX#LM4?j-mcK2d8SX>)Jf +$rMm6^(zmydx% z*`OF!fAm)D2$YYR{+@jkI}pfEn_tX+&xGV-AP*t`{?(DEKQe+L-vAW9lT6fV`__*q zYrEdSw(&*OM``rVpbxQ|4^MRVn1*y<=BJ>PF0HFurnEfZi}l2npY$r!(Ub!exP`}7 zOc-`XZr$1n{J$SCBInkH2)A|mAe8#4b`yf=vn4XysJ-_p4f=#|x4*AN;1~F5VU<2P z?QRc?N|Mbr1T;ap@Y+t794jOqW(n%{mg&b&(5#y2!{_&@H|4ugJgntBV>lJIqhZ^$ zaU(p}t~T?6$X&Bv1Oo8JIWIDVH@gp}Sn*J@VOn-LaAG0D=BYD ~_rgP?NW6Z)JMso^!voh+dOlZD}*7kV|<7UUKc=@I!JMf~ec z_iQMDM*LG}kkNOJ-AK;tJoDRw9izPQB7gNeIS~}+n_(G)_-Kv&YDrxlbd+P^$qo+M z=X%hf;z%~Hn9H)4|G0quX5D4#A4mQ17R@7sC@r6e^#_I~T?AfULUpp>`x(s;IaUmu zug?M_ysqG1=_EK(y^G5dgWTw()14PmL%Pc{O-<7(z*txql+l5p6TIk{URr3K;Sdbw zM9DS@=WGw;j`zjZ%zp5fp}q|j6q$C^ZHoatw4TC^5ElMR!ecW^>8kmwdIbR>Cc7!Y z^;;D2d`GMSi_!`KOt($2!{mo~@CsgN;Zv1rd6mbuV4-Dv^DuWDQZCHnAQZ2>s{(z5 zwi~Y-L5p(m4&JT~l~SHRo0SM!1(IETFR+cVA6gqYk&kKcG69QlQu2x^WZ41!+NyE& zj4;wTk{*k&uScIB*0AaKDz!_2WF~J7_xWAnJ@3* 1{xsglcYbQ}t MLk{ zIbBJh0dDh4et8qfeI9pXHugZwad;+EnVt-aeQALJd7>yb^Ixlf*Mo%Cr>}n|`?Im) zD^x4?&xk>`r@(z@kf8UR*zXJ?@gk8aKNyvufW=G{kU`+9mjhI`<7*z`(Z|ggGn1R| zQi qv>!D?Oq+Jpf3U3{XhB_3Y~Z*i;Z z=Dr<|Wy|{HgN`(gv0N&u&N6c2BUi{1m&D_Y$FEU~kQ?
z@CkaQIMBgF-4fEWxLbPW{7joWW!xeplhGO*%J s8Ovvobp@LB!` z(njbKD5FA)ff3p-X{X{LPz0E?&ZZ&DW0~do=pW&gDx#mi IJd>`-aGo2Vsb&CEGQ*!Xh)k1c z?$pq}6|bT26O3u~DAS#-LN*4D{UZJapH)J+U=YS=WGz_D1&zJ!@~XZ!hTaIq-T6t) z;-`cn@V6{)&2rXCIq_FLx-^-p8=i0hi{foM=jiMx?EJzh0S4=M{#~FZlxN^vL9r2N zLYjXrW2sQO%kYiZhCtr0{uex$Fp@kw`$u@3-{2^b2u4rZL#TwjR!*Ro6tfVWgjD3- zg1-g1eegTrE>1Y;`KPbRuOdOypPaC@r^W09aDCiNbO-)d8RTFGI$ST#&c5@XDZn9c z7*Oi-a`Wc%{>h&8^#^zP6@t2MY;;;`AMa$&6#txIKlA9a+p31xI02FwV3Y6`*sw$Z z7p(O$_%bh|2B8w5x>-28;WmApt_yZ4r2FnkOEj2tGF^mXo!Pop=ZZ48aNm;ExN#5N zt{O6x3s_YIEzFJs!y|$174(2*FyklWS)4zFstz;EZ1i;}hF mbZvkYSSK;mwd1iEq(o`Hc&7JV>Pdv6fhk^lo;tLO{sfeR? zA*nWSSZ-+?AyF)*UYUPX@`(Z#-vm&? b-r_5QtkUtA=sS zdF#OvHb>O3rmomP(qA)5Crv3hvb9f;#R>?oSMBqc4C_e`GU(ZWQDlSIQ99ZPp1Z?k zH9Ytv54JeLfUizLWLJzpIBb&VIwH}=NHfF3bQ;iT;?YKuNG}`4rFw^LgEOoyg2<(* z)Me{z3%8NUEzUycd+pUrstQe%nm|%3DN3Dsn{O1wT5QCIs|3zkuJ1IW;La{uQ(7n*3l zUt5LA; Dqcc32-T-3e~%c@M)-%Qr)9Kq#}{9} zQc#3azHHeWUkpk!6N_m_)4uEzo{~(Z)IL4zsNGyda4Rs#dNZ! u9Gd2Z_-QR%A z&VC4Jm5Gf}i_7LOSB(JsPc+%Bj3qsR8E2UJ)ThO4=Ya~8mn=f9=SO3q7w}u+2H&Dg zXbG0GlrivQkx-2j;|l{4`-SntkK!Qg(c7z^f0X )B9-%IbO27ZBtZ1rxpfq!+;67^5?^q(zI z)|cqNO<92K_dHn#6%L2s)_mx0TC3HISVh+>H=mNQTfp5cr~W%JPlAl2hKTQ)P*h+y z7aWqqXl)zMd|x31qvLVFE{5Fp;mqj~w3zl=@kqB&a!N#dAv%q~EqbLB)9h{O2LFd! z)&-;3rdQWYB_{DtyZDyZyD&Vkt~6RDIRQ7n6iU^<0NGw~S>UeC-6$5_o3|e}H0J#A zQ*D=K2lgB9JB6I?v#-pA7%8A#JODWRl)fA5;APHun>PFKuvAaUMn|Z{KVi|`h)amu zi)o|mb|$5qZuXEb1}zH1+Eht>N9I#LWcN+?PhE14?*Y#-Q(g35Ek%n}6n(!PH|G-( zXOk@KRZxA<#^r0Y?p)AZ1tnlIYv O96 escvL~Lk-c^iPaHl(GaLv* zx0V;r&o(3$tGX#=H^xf)aQz }OYAZG8DR5Wm6mkowC=@&HA(>`t0?$}qW~ zWkH25MUm-NYuhQo6$9eVsG=~Q1)R^VqM; x0I`tqPs! zrJZ-T(auq-R1rs>dC%`cg5P$xWObCnD_TnBy*%(}BGKklwd5m5&Ta!VVQ&~XjJk)w z76T<2>l)T=aUsnIy`ijsIJI&kMkkq6#$8@!mEwWN0)I=^a`kT<_7^*ZnQtR5&oo=^ z5)t2Ft+=*8q|v)^((g;tkTi!;^t%TUJK78crhHWusKEI~uMO37Bj*xKU4b(~_&AST z_c5~$PLbnEd}a=(a}OR_9U96gbNboIDY9^4Cc~zrDQJxUp;U~l5Fp5ssGiSf_2f}F zkoGPB8aVQYO`A75kP5p^XhMi*(}jetE^zhcmWq?0O8G4!2R+u$O#8>SK(AmsBQ@9p zH@{OLYCH;j3c*)BiG_x#t1~ajRaduVW-AdUWSH;{*FQsxIc?jK20X3-FrZx-zOoNU zhUZ7Bb=yz HbV|xnL?(4=-Dq zEF-ZYk=(7N1(_y8x}Y{-`rLU+qzF ! z+8;LDa)6`=pTL}u1Rc6`*gU`YPl@|b>&v86n;iud?QlXymMnBPcwWreadKimQr$%X zB`Fk%Kc)JC)Mk@`r#HOaBHrA>VIsbz}S%OPGVU>ly=9)%bM7SFM(L}8ip6%GJc^eN(` zN_}UoGn~V@hDxe}S?q?476Vf)^1)c{;3?aKvv^dZlSF&%{S@h0TF*A9EOD0tX;*}t zTmZ6E(*Bs5D4k?de&VuiK?e3E3hPmM4F{F|VI}%VF~=P;y=rB6(kR)D(yd52AZb)8 zsW?StbV(QR%YIx#d5(?~PUG(Yx1twHr-x$Z$c;P30n(62{U0YKtuVxoq#u{k?HFBQ zn&~Z6JYgSdU815VE_Pb>7UouvErx 9r=tZjqM4NQ+`7NJ=_njjyOn+-gmzgB TLjj%v8L#meV%qe1dqw65MO_ zscbEebe~y~&vVHnM^dKo4i3U!xVIa%bj?+jS`pBXAX2az?0Cc_zmEIo3gUAET{P~) z*~ceurG}FilDW+)F@11~M2zU1?W7#zq!iY@ICuVd+@qkl3IOnFJ>XmR+0|;Fl0XXT zn4#p?4O=SFH$(l3oZ`BK;ojUInXh_RTDnP??OO-8#wROe)~sauHq@L9y{!xE$GD5& z;1wn~1e<#IUEk8MTi+-|N>)c&wvFX%M!trvKRCuiPZOeRn(9hnI#=;u)w8e32;DEn zK-lSt7@<3folfYfd*}_zq`f7RsUh8*&LM@*U}c~XlWyB;t|e1i(nA_P0_OMBdp+ 2lQLT}{SO7$6Fx#E?xc1AVgsYb0QUNNaU_Rfa`n~{j z%HO ?uM>tq>|OaHmWgii(N&h{wV5 zy^hSa6M5bAPsr8p?l~g@xR$nx;LZQKB2W6fot=z@XU@M=eKjdHO_{?CQesXi%IX}T zoxj*r(a_$n$dVTnZ#>_J(93NJb1OL#;ae`-#_ (w@2#9)VZTFoU1LDoL5SmZ{F5cD>TDeYB0lc+VCviWV@+j+))i z1}eK61Zm2*TJc Ezj}V0~0g0BM$g{k*Ob`Mn=(_&=#erV%Km?p_(}@NWDR|3>+tVq}Oq{&D5tucU}k 33PgS6g`U^<;^`ANozptgWxrE zc}9}D@;?6a5UAznwY}@)OUG$Dx~PorFvK6Sc|VlW4C6w^Ml|0M9ni|JaxnP> EYIzUo=iU)@_kMvy+t@8ILFxAgjoRC|o_eqA-&&pZqYnN#n4yEivlX4A*o!KKyc z^y|cyC*YspdqL9X(0`uc63!k{?YL1XiUPzg;s!6e!6F1(^Xx#|lxwj+ ^BbViRgj4L9y;mINi(C~Vsmjd=kJ*c_2lLA7WaLBnvCxV5oCtwAApfa z3$>xZ7c&rrNu%Oi7fu8IsC%#QnF#?1&4gHXA65%?+z|0&X!9a>ePK`m%`7> AF_Ux*VIR7wu_X0b0gF*z#&?&Xv#EDMPj=+LQoui{u&bK zSBm^CiGxn-0+kh-8z@W4EMz8UXpxPyac38($Evp^w#94uL5iB}^Si#ef9jRvO)Ur) zH*9;Rtopg1GIHbRbK9ScvH>z43pB$_B*!O05U<0qAy(2-p3{AhmS^2?$ A!^!}YtmDv40?%{Q8gx&dno~>-?Ed@2etRwc;rW(Mx%s=PHCSg|9WIA z*9)hew(tj?z^rXHzY~)H&y|BmWj@+9cjSkz$D`P&aeHlzCqXs&nA(6%HNrr?kWdce z^t~?UpdSMtm^~7^!CJ2#q%3Q9!5ZWczkXe46U}pzmu?dxy()$1ua(v&Yh2MZJsF8U zcOv4Z3I+APDTU0|fdss&1zm2SX>yoF`53Ivx_dgE*OIuEO% FXOEY}qa>su@d4{*OP0MbilEUll$^ZFp@COOHNjG0wB3<`%l+FPfiBFY3NJj3} zn+`b%Joappu?^`OK9jhB1yj2`_$d56?YX`__7gG$qWqo%`w4CVOv`r35JXET{5)CA zG1&br82pkf>W@(L8wF$YD7;d4C`>-8c 2OH1wWh{JU4bKxfer8Xj2rEU|i>4 ziF4=gT9rxJ%KADUUDoe}e(7Q%H-!}k$#_$BK%MfzuO!@xAVVie9X@R4G(91RHEj5q z30vW02riaogwl~jQH=-{Z=9+;F~R5)@P3H0+_n ?F6igjWTb;>u4Qi`xTsl!u0Lb+w}xUIwA08Zu(bBG&(4SF zaHJQ&1mhLH+Drw#3v~h{S#dQxr%1e&)@yJQNDlKQyR`m3OM>sp!Nti63ZsMY 0UzKc_?Q8xXGSVlP3Qk1i^&B@ah9*3_p~Ybk zOR0< &@^>Z+S;3PCrJU&L9TR zVq|bheaYOp+P%o!%hwYrgW(wk3hqC+kF$|3j45y?3+@ey=h+4xokDu46(|y;m`dIv zY!EE~;-cXxhh+=7p?m1aC0ev5(q@_^Pz50L6W#|q3l$K+4Z{tgOP%>XQ5~pn?*`{@ zLbh3l{VVh@%dz8r$2m-su>pbmo^3krcbq?C5*|ZD;%anaAMZ|M9@?tL;}D@y$+y@~u{>Pu>g$dDpX8+1oq$c^K5}x$-tgAzp58u3 z*BFciA~)Z0mKjFZ>u#^>{qhNxZxWrFrF80i3yz-0m5vT5i|EV0B=0RhaO)SdsHhjF zV&L{OBWRAkDNGMo7~$j-Spu(6@f>`AGZoxhzuap|k_s;@QH=tcmW9j%Qx$Rxo&xpA z>n4Fi4SVkaL4t%j-@Hc_2N@P4F3e1n_5q*|T*?5^yEh^`yEepQUVK7Z@Q)9zPqZwA zvl;=Qz0CPW66KLgj!P5t8wG$2??hb>eEUgEF#K-07!&ooultRD7$ 7(u4oeb4|TR-@=NZdl(l)+~9DMRR+9##A?Ro}1Jm zLJ$wK`*bf^L QL1lC}3r7GY>eo-0p1FicRU|dfzXIEEQBpa3C0xX5(7(iLAmT&g;{_0u ze>1xoQfI79P|!8#?Mfa{FxkG#sIO|uE3Y*i(v-@+Q5jBgo8I2e;E>Jdz({zZ!z|IW ziPXWdpQA(25aoQU7lNy+KO}{tVnO$Fx_y~Z;jk$q2d9=0hV}5QY+qU{e+&u_;16CU zEHau>SX>G~;=|bd{%q8-3suWeUEj&3FgUi8L?EtoiFj;uy638%y}{l7L7WsJi4t;@ zZ7qf?8rFEIzkq+azAn~YOZQ(CLkCncPc ?tY9!$(at@0uSg^Rd{tIT@HIYy-BI%=P1S7@#Qy_3zcu{h_kr|a|J1`pTJ z{?iV}m24L;d-soy1+FUV4;}AK*DELNEshQ%p-1HFfGS;Hgke56k7JJPg*b8@e$UN2 zUt8rQ|9Hv^y`g>sNRSf}$W$Iet_OoNhGfV6^yG> 5tBCY z0ln)Av_o!eriEhK{G!#?;qWTJP$WJ|h#xszkp4Y$pSDa~)O&pzPba5v4;?FSIOu-V z9-HLGDMqs&3xA>pm#BoRz!dE2+R}H%l^?R9NMk0&GY?)%Czs%bS*1iUwb=UJ+)RE~ znYd4Y+?ekw)5XXLH06;xLIgh$ejPdtx7b3g@oi^M*t%!r*s1gDuFB_WV<`_+n;$S# zo&{qx@mleaH+bG-
$MC(sB0KV^)St-%914zW=p<_m? *lQ5i*v&Hb`ko0snfryv8{63$|DxAEcY=8veXE~e!F_`a%aT3R@M zU|5d_ym^7QrXl5g^3A-HeX%#Q!*Qt%?U*y7f6Vh}TtWc(wOZCuNNV2L^VxD$Y-aJ) z4`Pp_IEp?*k8e|3O!3-YX-RAEwDM?~w0T!awmdQofnuX{RxG_lO*o)a^n!A(5_0n= z^2MkTUXh_Qzo))sv$Mu{+MH)zNSMn(j#{PY^=4l?72pi&&h56&1|-+R73P7s)5G|; z=96GzTPoryIav}f-SE;0cKy4nx2KL$U_4QRhWi u@y8yZioaEOX^AKST05l2CNKw`^E$EniVWK z0U_tU 1@-PGPooaQ!?+0e1 zd!W!F#wId{>@p-H*fa?gc7{mlK9+siyNIcr2}#!|cvJMmxoWq0^EHVIC~vljwttD? z_5h ff~GK4$(N*>E)IvL$X{Q)_x{h9wAfGf18&Enf~v&Xx9hkZKIYQ ziqbT_j0C$%g lYWMMVV zuEnpxnO_Zp+P$AhyD!{i1)w~$Jhkx-)8*QO8X=N$yk-?!VcHSS&d=D 1{PlsE((Mn_RGZRg$M{cly5V;p); zuAxwugArP>!n_JCrSjlPe=|A$y^%fg&qbQe&3~$xj{lA)+&WFf4qH!4qTevC-c0#y zZiPJf{GBzTfY`*EQ+H3Kqm3Z%n5~%)?tn>u`8q=qHSq{?DvvNilR9PWmUqq}AVASa z#WE{Ibx&SUK8FLV+|H!%YAItg4iX0GR$j}t^#KyJ#UVMvjtLj_Mub4xj0@KW?=YJr z1&LdX+~6+#eE<2zwxK0MaxrH846eeCAt_zPxG#Gp*#KRZ5%$#>4`~Xo++hx8)Dgaa zp4XraU!Pl HM zb_2a! +&9HJ#&&m>8}t$blY5ad zmc5yGl7jc!i>?ohcz#oAJt@Nzob_RE(YKY)8rc;BGS7Vjf2q{l2o;TaQto=XwMjl( zeI&a3%oWz KiDB%43cR;Glss_)~N8WN2)y*2-Q+9o-7)9ORRrpV brN;K-2vr+%qiQW9-hQ#B9W>#f0(fTzU+Qj3L`=ee*ZjASif7o~9+HrKM44k6wP- zoB!vIe0%y0xNe}X`L5iJ>pkBdLJ5URx_y{z{#H5_StK=_8_dm|G&E}%M)OXlje_